如何通过抓包来查看Kubernetes API流量

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 当我们通过kubectl来查看、修改Kubernetes资源时,有没有想过后面的接口到底是怎样的?

当我们通过kubectl来查看、修改Kubernetes资源时,有没有想过后面的接口到底是怎样的?有没有办法探查这些交互数据呢?

Kuberenetes客户端和服务端交互的接口,是基于http协议的。所以只需要能够捕捉并解析https流量,我们就能看到kubernetes的API流量。

但是由于kubenetes使用了客户端私钥来实现对客户端的认证,所以抓包配置要复杂一点。具体是如下的结构:

capture-architecture.png

如果想了解更多Kubernetes证书的知识,可以看下这篇Kubernetes证书解析的文章

从kubeconfig中提取出客户端证书和私钥

kubeconfig中包含了客户端的证书和私钥,我们首先要把它们提取出来:

# 提取出客户端证书
grep client-certificate-data ~/.kube/config | \
  awk '{ print $2 }' | \
  base64 --decode > client-cert.pem
# 提取出客户端私钥
grep client-key-data ~/.kube/config | \
  awk '{ print $2 }' | \
  base64 --decode > client-key.pem
# 提取出服务端CA证书
grep certificate-authority-data ~/.kube/config | \
  awk '{ print $2 }' | \
  base64 --decode > cluster-ca-cert.pem

参考自Reddit

配置Charles代理软件

从第一张图可以看出,代理软件的作用有两个:一是接收https流量并转发,二是转发到kubernetes apiserver的时候,使用指定的客户端私钥。

首先配置Charles,让他拦截所有的https流量:

ssl-proxy-settings.png

然后配置客户端私钥,即对于发送到apiserver的请求,统一使用指定的客户端私钥进行认证:

client-cert-config.png

配置kubectl

需要抓包kubectl的流量,需要两个条件:1. kubectl使用Charles作为代理,2. kubectl需要信任Charles的证书。

# Charles的代理端口是8888,设置https_proxy环境变量,让kubectl使用Charles代理
$ export https_proxy=http://127.0.0.1:8888/
# insecure-skip-tls-verify表示不校验服务端证书
$ kubectl --insecure-skip-tls-verify get pod
NAME                    READY   STATUS    RESTARTS   AGE
sc-b-7f5dfb694b-xtfrz   2/2     Running   0          2d20h

我们就可以看到get pod的网络请求了:

kubectl-get-pod.png

可以看到,get pod的endpoint是GET /api/v1/namespaces/<namespace>/pods

让我们再尝试下创建pod的请求:

$ cat <<EOF >pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-robberphex
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
EOF
$ kubectl --insecure-skip-tls-verify apply -f pod.yaml
pod/nginx-robberphex created

也同样可以抓到包:

kubectl-apply-pod.png

创建pod的endpoint是POST /api/v1/namespaces/<namespace>/pods

配置kubenetes client

我们先从写一个用kubernetes go client来获取pod的例子(注意,代码中已经信任所有的证书,所以可以抓到包):

package main

/*
require (
    k8s.io/api v0.18.19
    k8s.io/apimachinery v0.18.19
    k8s.io/client-go v0.18.19
)
*/
import (
    "context"
    "flag"
    "fmt"
    "path/filepath"

    apiv1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"
)

func main() {
    ctx := context.Background()
    var kubeconfig *string
    if home := homedir.HomeDir(); home != "" {
        kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    } else {
        kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
    }
    flag.Parse()

    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
        panic(err)
    }
    // 让clientset信任所有证书
    config.TLSClientConfig.CAData = nil
    config.TLSClientConfig.Insecure = true
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err)
    }
    podClient := clientset.CoreV1().Pods(apiv1.NamespaceDefault)
    podList, err := podClient.List(ctx, metav1.ListOptions{})
    if err != nil {
        panic(err)
    }

    for _, pod := range podList.Items {
        fmt.Printf("podName: %s\n", pod.Name)
    }

    fmt.Println("done!")
}

然后编译执行:

$ go build -o kube-client
$ export https_proxy=http://127.0.0.1:8888/
$ ./kube-client
podName: nginx-robberphex
podName: sc-b-7f5dfb694b-xtfrz
done!

这时也可以抓到同样的结果:

go-client-get-pod.png

基于此,我们就可以分析一个Kubernetes到底干了什么,也是我们分析Kubernetes​实现的入口。


本文首发于 https://robberphex.com/how-to-inspect-kubernetes-api/

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
Kubernetes 负载均衡 应用服务中间件
深入理解 Kubernetes Ingress:路由流量、负载均衡和安全性配置
深入理解 Kubernetes Ingress:路由流量、负载均衡和安全性配置
109 1
|
9天前
|
Kubernetes 安全 Cloud Native
云上攻防-云原生篇&Kubernetes&K8s安全&API&Kubelet未授权访问&容器执行
云上攻防-云原生篇&Kubernetes&K8s安全&API&Kubelet未授权访问&容器执行
|
1月前
|
Kubernetes 安全 API
Kubernetes学习-集群搭建篇(三) Node配置完善和API概述
Kubernetes学习-集群搭建篇(三) Node配置完善和API概述
Kubernetes学习-集群搭建篇(三) Node配置完善和API概述
|
12天前
|
Kubernetes Oracle 关系型数据库
实时计算 Flink版操作报错合集之用dinky在k8s上提交作业,会报错:Caused by: org.apache.flink.table.api.ValidationException:,是什么原因
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
102 0
|
1月前
|
人工智能 监控 安全
百万并发,API 网关抗住了亚运会流量高峰
本文主要介绍作为亚运会所有核心流量的入口,阿里云推出了一款百万并发规格的 API 网关,抗住了亚运会流量高峰,为亚运会提供强大的技术支持。
|
1月前
|
Kubernetes 容器
Kubernetes高可用集群二进制部署(三)部署api-server
Kubernetes高可用集群二进制部署(三)部署api-server
|
1月前
|
Kubernetes API 网络架构
k8s学习-CKS真题-启用API Server认证,禁止匿名访问
k8s学习-CKS真题-启用API Server认证,禁止匿名访问
113 0
|
28天前
|
Kubernetes 微服务 容器
Aspire项目发布到远程k8s集群
Aspire项目发布到远程k8s集群
379 2
Aspire项目发布到远程k8s集群
|
16天前
|
Kubernetes Cloud Native 微服务
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
202 3
|
1天前
|
Kubernetes 网络协议 Docker
k8s 开船记-故障公告:自建 k8s 集群在阿里云上大翻船
k8s 开船记-故障公告:自建 k8s 集群在阿里云上大翻船