当我们通过kubectl来查看、修改Kubernetes资源时 , 有没有想过后面的接口到底是怎样的?有没有办法探查这些交互数据呢?
Kuberenetes客户端和服务端交互的接口 , 是基于http协议的 。所以只需要能够捕捉并解析https流量 , 我们就能看到kubernetes的API流量 。
但是由于kubenetes使用了客户端私钥来实现对客户端的认证 , 所以抓包配置要复杂一点 。具体是如下的结构:
文章插图
如果想了解更多Kubernetes证书的知识 , 可以看下这篇Kubernetes证书解析的文章 [1]
从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 [2]配置Charles代理软件【如何通过抓包来查看Kubernetes API流量?】从第一张图可以看出 , 代理软件的作用有两个:一是接收https流量并转发 , 二是转发到kubernetes apiserver的时候 , 使用指定的客户端私钥 。
首先配置Charles , 让它拦截所有的https流量:
文章插图
然后配置客户端私钥 , 即对于发送到apiserver的请求 , 统一使用指定的客户端私钥进行认证:
文章插图
配置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 podNAMEREADYSTATUSRESTARTSAGEsc-b-7f5dfb694b-xtfrz2/2Running02d20h
我们就可以看到 get pod 的网络请求了:文章插图
可以看到 , get pod的endpoint是 GET /api/v1/namespaces/<namespace>/pods 。
让我们再尝试下创建pod的请求:
$ cat <<EOF >pod.yamlapiVersion: v1kind: Podmetadata:name: Nginx-robberphexspec:containers:- name: nginximage: nginx:1.14.2EOF$ kubectl --insecure-skip-tls-verify Apply -f pod.yamlpod/nginx-robberphex created
也同样可以抓到包:文章插图
创建pod的endpoint是 POST /api/v1/namespaces/<namespace>/pods
配置kubenetes client我们先从写一个用kubernetes go client来获取pod的例子(注意 , 代码中已经信任所有的证书 , 所以可以抓到包):
package main/*require (k8s.io/api v0.18.19k8s.io/apimachinery v0.18.19k8s.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 *stringif 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 = https://www.isolves.com/it/wl/js/2021-11-23/nilconfig.TLSClientConfig.Insecure = trueclientset, 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: %sn", pod.Name)}fmt.Println("done!")}
然后编译执行:$ go build -o kube-client$ export https_proxy=http://127.0.0.1:8888/$ ./kube-clientpodName: nginx-robberphexpodName: sc-b-7f5dfb694b-xtfrzdone!
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 如何使用高德地图ADAS预警导航?
- win10优化设置,win10系统如何优化
- 如何定义SpringBoot项目配置文件中密码的加密
- 枸杞治失眠多梦吗,女人失眠吃什么好足浴疗法有经常用的吗效果如何
- 起重机|写给正面临职业选择的人,如何才能选到适合自己的职业呢?
- 金智妮|如何才能不“油腻”?成为南柱赫这样的清爽大帅哥原来这么简单!
- 自制金桔饼的做法,自制金桔饼
- 内分泌失调的症状如何调节内分泌失调
- 三亚有什么茶叶值得买,值得收藏
- 如何挑选猪大肠