首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何通过抓包来查看Kubernetes API流量

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

原创
作者头像
Robert Lu
修改于 2021-11-25 02:47:42
修改于 2021-11-25 02:47:42
3.8K1
举报
文章被收录于专栏:JVM以及其他JVM以及其他

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

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

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

capture-architecture.png
capture-architecture.png

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

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

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

代码语言:txt
AI代码解释
复制
# 提取出客户端证书
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
ssl-proxy-settings.png

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

client-cert-config.png
client-cert-config.png

配置kubectl

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

代码语言:txt
AI代码解释
复制
# 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
kubectl-get-pod.png

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

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

代码语言:txt
AI代码解释
复制
$ 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
kubectl-apply-pod.png

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

配置kubenetes client

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

代码语言:txt
AI代码解释
复制
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!")
}

然后编译执行:

代码语言:txt
AI代码解释
复制
$ 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
go-client-get-pod.png

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


本文首发于 https://robberphex.com/lambda-causes-arthas-cant-redefine

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
1 条评论
热度
最新
好好看看,学学习习了!
好好看看,学学习习了!
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
client-go实战之二:RESTClient
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 系列文章链接 client-go实战之一:准备工作 client-go实战之二:RESTClient client-go实战之三:Clientset client-go实战之四:dynamicClient client-go实战之五:DiscoveryClient 本篇概览 本文是《client-go实战》系列的第二篇,前文咱们提到过client-go一共有
程序员欣宸
2022/05/06
9140
client-go实战之二:RESTClient
Kubernetes之Informer机制详解
本文尝试从Informer中的Lister、Watcher、Indexer、Store及Controller 5个组件展开对其进行详细阐述。希望对您有所帮助!
锅总
2024/06/28
2.2K0
Kubernetes之Informer机制详解
client-go实战之六:时隔两年,刷新版本继续实战
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 系列文章链接 client-go实战之一:准备工作 client-go实战之二:RESTClient client-go实战之三:Clientset client-go实战之四:dynamicClient client-go实战之五:DiscoveryClient 时隔两年,《client-go实战》被激活,更多内容将会继续更新 时间过得真快,《clien
程序员欣宸
2023/02/03
5080
client-go实战之七:准备一个工程管理后续实战的代码
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 系列文章链接 client-go实战之一:准备工作 client-go实战之二:RESTClient client-go实战之三:Clientset client-go实战之四:dynamicClient client-go实战之五:DiscoveryClient client-go实战之六:时隔两年,刷新版本继续实战 本篇概览 本文是《client-go
程序员欣宸
2023/02/13
5320
client-go实战之七:准备一个工程管理后续实战的代码
client-go实战之十二:选主(leader-election)
程序员欣宸
2023/08/14
1.4K0
client-go实战之十二:选主(leader-election)
client-go实战之四:dynamicClient
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 系列文章链接 client-go实战之一:准备工作 client-go实战之二:RESTClient client-go实战之三:Clientset client-go实战之四:dynamicClient client-go实战之五:DiscoveryClient 本篇概览 本文是《client-go实战》系列的第四篇,前文咱们学习了Clientset客户端
程序员欣宸
2022/05/06
6340
client-go实战之四:dynamicClient
下篇(开始写代码):运维开发人员不得不看的K8S API实战
可参考:https://kubernetes.io/zh-cn/docs/reference/using-api/client-libraries/
不背锅运维
2023/04/24
6780
下篇(开始写代码):运维开发人员不得不看的K8S API实战
零基础学K8s开发:Pod增删改查从入门到…嗯,基本掌握!
哈喽,各位小伙伴好啊,上周希里安介绍了开源项目CILIKUBE如何部署运行,收到很多从事传统运维、SRE、云原生爱好者、甚至前后端开发小伙伴的热情反馈,希望能得到更多的交流。如果你正在开发一个K8s资源管理平台,或者只是想了解K8s的核心操作,那这次希里安就给大家介绍下,在准备好开发环境后,如何开发实现一个pod的简单的增删改查的功能。通过这个示例,其他k8s资源对象的增删改查也就一道掌握了。
希里安
2025/05/19
2150
零基础学K8s开发:Pod增删改查从入门到…嗯,基本掌握!
client-go实战之三:Clientset
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 系列文章链接 client-go实战之一:准备工作 client-go实战之二:RESTClient client-go实战之三:Clientset client-go实战之四:dynamicClient client-go实战之五:DiscoveryClient 关于Clientset 本篇是《client-go实战》系列的第三篇,前文学习了最基础的客户
程序员欣宸
2022/05/06
5360
client-go实战之三:Clientset
使用 client-go 对 Kubernetes 进行自定义开发及源码分析
注意:这里 Kubernetes 集群搭建使用 Minikube 来完成,Minikube 启动的单节点 k8s Node 实例是需要运行在本机的 VM 虚拟机里面,所以需要提前安装好 VM,这里我选择 Oracle VirtualBox。k8s 运行底层使用 Docker 容器,所以本机需要安装好 Docker 环境,这里忽略 Docker、VirtualBox、Minikube、Kubectl 的安装过程,可以参考之前文章 Minikube & kubectl 升级并配置, 这里着重介绍下 client-go 安装以及如何自定义操作 k8s 各资源类型。
哎_小羊
2019/05/25
6.5K0
kubernetes 中 informer 的使用
在实际开发过程中,若想要获取 kubernetes 中某个资源(比如 pod)的所有对象,可以使用 kubectl、k8s REST API、client-go(ClientSet、Dynamic Client、RESTClient 三种方式) 等多种方式访问 k8s 集群获取资源。在笔者的开发过程中,最初都是直接调用 k8s 的 REST API 来获取的,使用 kubectl get pod -v=9 可以直接看到调用 k8s 的接口,然后在程序中直接访问还是比较方便的。但是随着集群规模的增长或者从国内获取海外 k8s 集群的数据,直接调用 k8s 接口获取所有 pod 还是比较耗时,这个问题有多种解决方法,最初是直接使用 k8s 原生的 watch 接口来获取的,下面是一个伪代码:
田飞雨
2019/12/13
4.6K0
kubernetes 中 informer 的使用
手把手教你用Go语言实现Kubernetes管理
Kubernetes是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。本文将指导你如何使用Go语言通过Kubernetes API实现自动化运维。计划是先实现一个简单的,后续感兴趣可以在基础上再进行提升
大盘鸡拌面
2024/01/08
2.2K0
AIOps系列 | 开发一个 K8s Chat 命令行工具
作者:乔克 公众号:运维开发故事 博客:https://jokerbai.com
没有故事的陈师傅
2025/08/06
2190
AIOps系列 | 开发一个 K8s Chat 命令行工具
client-go客户端自定义开发Kubernetes及源码分析
client-go 是一种能够与 Kubernetes 集群通信的客户端,通过它可以对 Kubernetes 集群中各资源类型进行 CRUD 操作,它有三大 client 类,分别为:Clientset、DynamicClient、RESTClient。通过它,我们可以很方便的对 Kubernetes 集群 API 进行自定义开发,来满足个性化需求。
程序员同行者
2019/06/01
2.7K0
client-go初级篇,从操作kubernetes到编写单元测试
程序员欣宸
2023/07/10
7460
client-go初级篇,从操作kubernetes到编写单元测试
client-go连接kubernetes集群-update相关操作
紧接client-go连接kubernetes集群-connect and list,client-go连接kubernetes集群-create相关操作。实例都是拿namespace 和deployment两个为代表进行展开延伸的(个人环境中deployment还是具有代表性的),前面创建了namespace deployment,正常的流程下一步就是修改namespace and deployment 了!
对你无可奈何
2022/05/04
6020
Kubernetes 中 Informer 的使用
前面我们在使用 Clientset 的时候了解到我们可以使用 Clientset 来获取所有的原生资源对象,那么如果我们想要去一直获取集群的资源对象数据呢?岂不是需要用一个轮询去不断执行 List() 操作?这显然是不合理的,实际上除了常用的 CRUD 操作之外,我们还可以进行 Watch 操作,可以监听资源对象的增、删、改、查操作,这样我们就可以根据自己的业务逻辑去处理这些数据了。
我是阳明
2020/08/04
2.2K0
Kubernetes 中 Informer 的使用
软件工程师视角的Kubernetes管理前端的内部机制
在这篇博文中,我们回顾了Kubernetes管理前端,并讨论了这些工具是如何被构建的。
云云众生s
2024/03/28
2030
Kubernetes任务调度实践-Go语言实现Job和CronJob对比分析
本文详细介绍了如何通过Kubernetes中的Go语言调用API Server来实现创建Job任务。该功能需要实现创建Job执行任务、任务完成后提取日志中的JSON并解析入库,以及支持周期执行等步骤。这些都得益于client-go包的支持才能轻松实现,但在实践中也遇到了一些值得记录的问题。
莲子心
2025/07/14
1260
client-go连接kubernetes集群
kubernetes的基本应用的算是能入门了。但是基于各种客户端操作kubernetes集群还是没有深入玩过,最近一段时间入门了一下goland,就拿client-go深入体验一下kubernetes集群的基本操作,当然了最后能更深入一下跟gin框架结合了就好了......算是练手入门
对你无可奈何
2022/05/01
2.6K0
相关推荐
client-go实战之二:RESTClient
更多 >
领券
一站式MCP教程库,解锁AI应用新玩法
涵盖代码开发、场景应用、自动测试全流程,助你从零构建专属AI助手
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档