Kubernetes api-server源码阅读1(源码环境安装篇)
2023-12-24 05:35:19
本文是 Kubernetes api-server源码阅读 系列第一篇,主要讲述如何进行kubernetes源码阅读环境的搭建
1.准备环境
1.1.搭建目标
- Debug Kubernetes源码
- 开发组件,贡献源码
- 做扩展开发
- 实验Kubernetes功能
- 我们使用的环境:Kubernetes版本 1.24.0
- kubernetes各组件版本依赖关系,在源码中有:https://github.com/kubernetes/kubernetes/blob/v1.24.0/build/dependencies.yaml
2.安装工具包
- 需要安装8大工具
- 参考文档:https://github.com/kubernetes/community/blob/master/contributors/devel/running-locally.md
- 我下面会提供每个工具的安装过程
2.1.安装虚拟机
2.1.1.安装Ubuntu虚拟机
- Ubuntu下载地址:
- https://ubuntu.com/download/alternative-downloads
- 镜像比较大,资源里我放了种子,如果下不了,直接给我留言,我发给大家
- 如果安装完发现虚拟机屏幕太小,可以安装或重新安装VM Tools
- 本地ssh连接ubuntu,发现22端口拒绝访问
- 现在用的是普通用户登陆,root密码每一次开机都会刷新,我们现在修改root密码,以后用root操作
- 参考文章
- 改完root密码后,发现想要使用root远程连接又失败了
- 先安装vim:apt-get install vim
- 然后修改一个配置文件:https://blog.csdn.net/testcs_dn/article/details/69498797
- 这样就可以使用xshell等远程连接工具,使用root账户连接了
- 使用root账户登陆后,很多命令就不用写sudo了
2.1.2.修改Linux镜像源
- sudo lsb_release -a:查看自己的ubuntu版本。我的输出如下:
No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focal
- 先备份原本的镜像源文件,以备不时之需
cp /etc/apt/sources.list /etc/apt/sources.list.bak
- 从第一步看到我的Codename为focal,所以我将/etc/apt/sources.list文件,改成如下内容(如果你们Codename是其他的,就把下面的focal换成自己的):
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
- 然后从新的镜像源 更新一下软件包:sudo apt-get update
2.2.安装GNU
sudo apt-get update
sudo apt install build-essential
2.3.安装Docker
2.3.1.安装Docker-CE
- 以下命令,一条条执行
sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
2.3.2.修改Containerd 镜像源地址
- 为什么修改containerd的镜像源,而不是修改docker的?
- 因为我们使用的是kubernetes1.24,此版本已经不再支持container-shim,而是让kubelet直接对接containerd,所以对镜像的管理工作由containerd负责,因此我们直接修改containerd镜像源即可
- containerd默认没有产生配置文件,而是直接使用默认配置,我们先让containerd把默认配置写入一个文件中,然后我们再修改这个配置文件让它生效
- containerd 根据默认配置生成配置文件
containerd config default > ~/config.toml
- 编辑 ~/config.toml,加入这两行:
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] endpoint = ["https://hub-mirror.c.163.com","https://registry-1.docker.io"]
- 加完之后是这样的,大家对照一下就知道加在哪里了:
[plugins."io.containerd.grpc.v1.cri".image_decryption] key_model = "node" [plugins."io.containerd.grpc.v1.cri".registry] config_path = "" [plugins."io.containerd.grpc.v1.cri".registry.auths] [plugins."io.containerd.grpc.v1.cri".registry.configs] [plugins."io.containerd.grpc.v1.cri".registry.headers] [plugins."io.containerd.grpc.v1.cri".registry.mirrors] [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] endpoint = ["https://hub-mirror.c.163.com","https://registry-1.docker.io"] [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming] tls_cert_file = "" tls_key_file = ""
- 另外,还要修改一个地方,就是sandbox_image的镜像
- 找到 sandbox_image 这个配置项,将value改成
registry.aliyuncs.com/google_containers/pause:3.6
- 原镜像
registry.k8s.io/pause:3.6
我们拉取不到,创建的pod会报错 拉取pause镜像失败,一直处于 ContainerCreating 状态。
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"
- 找到 sandbox_image 这个配置项,将value改成
- 将我们修改后的配置文件,移动到containerd目录下
mv ~/config.toml /etc/containerd/config.toml
- 重启containerd,让配置文件生效
systemctl restart containerd
- 查看containerd状态,确保已经active了
systemctl containerd status
- containerd 根据默认配置生成配置文件
2.4.安装rsync
2.4.1.rsync是什么
- rsync 是一个常用的 Linux 应用程序,用于文件同步。
- 它可以在本地计算机与远程计算机之间,或者两个本地目录之间同步文件
- 用法学习教程:https://www.ruanyifeng.com/blog/2020/08/rsync.html
2.4.2.安装rsync
- 进入下载目录,纯粹是为了规范,自己随便下载到哪里都可以
cd ~/Downloads 或者 mkdir ~/Downloads
- 安装rsync
wget https://github.com/WayneD/rsync/archive/refs/tags/v3.2.4.tar.gz tar -xf v3.2.4.tar.gz cd rsync-3.2.4
- 安装一些工具
sudo apt install -y gcc g++ gawk autoconf automake python3-cmarkgfm sudo apt install -y acl libacl1-dev sudo apt install -y attr libattr1-dev sudo apt install -y libxxhash-dev sudo apt install -y libzstd-dev sudo apt install -y liblz4-dev sudo apt install -y libssl-dev
- 编译,安装
./configure make sudo cp ./rsync /usr/local/bin/ sudo cp ./rsync-ssl /usr/local/bin/
2.5.安装jq
2.5.1.jq是什么
- jq 是 stedolan 开发的一个开源的、轻量级的和灵活的命令行JSON处理器
- 在处理命令行json的时候,我们会用到它
- 学习博客:https://wangchujiang.com/linux-command/c/jq.html
2.5.2.安装jq
sudo apt-get install jq
2.6.安装pyyaml
2.6.1.什么是pyyaml
- PyYAML 是一个用于解析和生成YAML 数据的Python 库。 它提供了简单易用的接口,用于读取和写入YAML 格式的文件、字符串或流。
- 学习博客:https://juejin.cn/post/7252684950276784183
2.6.2.什么是python3-pip
- pip 是 Python 包管理工具,该工具提供了对Python 包的查找、下载、安装、卸载的功能。
- 学习博客:https://www.runoob.com/python3/python3-pip.html
2.6.3.安装pyyaml
- 先安装pip,再安装pyyaml
sudo apt install python3-pip pip install pyyaml
2.7.安装Etcd
- etcd版本:kubernetes1.24.0,至少需要3.5.3版本的etcd,我们这里装3.5.4的etcd
- 命令如下:
- 其中,ETCD_VER=v3.5.4是定义一个变量,在当前shell会话中有效
cd ~/Downloads ETCD_VER=v3.5.4 curl -L https://storage.googleapis.com/etcd/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o etcd-${ETCD_VER}-linux-amd64.tar.gz mkdir ~/etcd tar xzvf etcd-${ETCD_VER}-linux-amd64.tar.gz -C ~/etcd --strip-components=1 vim ~/.bashrc # 在~/.bashrc最后添加一句:export PATH="/root/etcd:${PATH}" source ~/.bashrc # 检查etcd是否安装成功 etcd --version
- 其中,ETCD_VER=v3.5.4是定义一个变量,在当前shell会话中有效
2.8.安装golang
- golang版本:kubernetes1.24.0,至少需要1.18.1版本的etcd,我们这里装1.18.2的golang
- 安装 golang
cd ~/Downloads wget https://golang.google.cn/dl/go1.18.2.linux-amd64.tar.gz sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.18.2.linux-amd64.tar.gz # 创建gopath mkdir ~/go mkdir ~/go/src mkdir ~/go/bin vim ~/.bashrc # 在文件最后添加环境变量 export GOPATH="/root/go" export GOBIN="/root/go/bin" export PATH="/usr/local/go/bin:$GOPATH/bin:${PATH}" source ~/.bashrc
- 为了防止运行etcd时找不到命令,将etcd、gopath等加入/etc/sudoers
在secure_path中添加:vim /etc/sudoers
:/usr/local/go/bin:/root/etcd:/root/go/bin
- 设置golang代理
- go 的 很多库,都在国外或google上,所以需要在go的环境变量中设置代理,下载会更快
go env -w GO111MODULE="on" go env -w GOPROXY="https://goproxy.cn,direct"
2.9.安装CFSSL
2.9.1.CFSSL是什么
- cfssl 是 CloudFlare 开源的一款 PKI/TLS 工具。 cfssl 包含一个命令行工具 和一个用于签名,验证并且捆绑TLS证书的 HTTP API 服务。 使用Go语言编写。
- cfssl 目前常被用做 k8s 集群生成证书
- 学习博客:https://zhuanlan.zhihu.com/p/596891203
2.9.2.CFSSL安装
go install github.com/cloudflare/cfssl/cmd/...@latest
2.9.3.验证CFSSL是否安装成功
root@graham-virtual-machine:~/go# cfssl
No command is given.
Usage:
Available commands:
bundle
certinfo
ocsprefresh
scan
info
revoke
version
gencrl
ocspdump
print-defaults
crl
sign
serve
genkey
gencert
gencsr
ocspsign
ocspserve
selfsign
Top-level flags:
3.下载源码
- 源码存放目录:$GOPATH/src/k8s.io
- 原因:虽然后来go已经有了go mod去管理包,但是kubernetes历史比较悠久了,实验证明,还是放在 $GOPATH/src/k8s.io 下,不容易出各种问题
- 执行命令
mkdir $GOPATH/src/k8s.io && cd $GOPATH/src/k8s.io git clone https://github.com/kubernetes/kubernetes.git # 从 tag:v1.24.0 中,切出来一个分支 kube1.24,用于我们的学习 git checkout -b kube1.24 v1.24.0
4.编译+运行
4.1.直接一条命令完成编译+运行
- 执行这两条命令后,就可以完成kubernetes的编译,并运行起来一个单节点kubernetes
cd $GOPATH/src/k8s.io/kubernetes sudo ./hack/local-up-cluster.sh
- 这是kubernetes官方给我们提供的,可以用来学习使用
./hack/local-up-cluster.sh
- 编译过程,可能会在Installing CNI plugin binaries …上卡的比较久,不用急,耐心等待,20min+很正常
- 安装过程中,出现这段,是在提示我们,各个组件的日志位置,有问题可以去看日志
Logs: /tmp/kube-apiserver.log /tmp/kube-controller-manager.log /tmp/kube-proxy.log /tmp/kube-scheduler.log /tmp/kubelet.log
- 当最终出现这段的时候,就代表安装成功了
- 提示我们:想要使用集群,可以开启另一个端口,执行下面的两条命令
export KUBECONFIG=/var/run/kubernetes/admin.kubeconfig
是在指定kubeconfig文件cluster/kubectl.sh
就是kubectl命令的位置,我们使用它就是在使用kubectl
To start using your cluster, you can open up another terminal/tab and run: export KUBECONFIG=/var/run/kubernetes/admin.kubeconfig cluster/kubectl.sh Alternatively, you can write to the default kubeconfig: export KUBERNETES_PROVIDER=local cluster/kubectl.sh config set-cluster local --server=https://localhost:6443 --certificate-authority=/var/run/kubernetes/server-ca.crt cluster/kubectl.sh config set-credentials myself --client-key=/var/run/kubernetes/client-admin.key --client-certificate=/var/run/kubernetes/client-admin.crt cluster/kubectl.sh config set-context local --cluster=local --user=myself cluster/kubectl.sh config use-context local cluster/kubectl.sh
- 安装完成后,不要关闭当前终端,也不要ctrl+c,我们需要开启另一个终端,验证一下集群是否可以正常使用
- 先执行一下:
export KUBECONFIG=/var/run/kubernetes/admin.kubeconfig
- 然后使用cluster/kubectl.sh,查看一下集群的node
root@graham-virtual-machine:~/go/src/k8s.io/kubernetes# cluster/kubectl.sh get nodes NAME STATUS ROLES AGE VERSION 127.0.0.1 Ready <none> 119m v1.24.0
- 注意:一定要在$GOPATH/src/k8s.io/kubernetes目录下执行,因为cluster/kubectl.sh就是kubernetes/cluster目录下的一个sh脚本工具。在别的目录下,相对路径找不到kubectl.sh
- 先执行一下:
4.2.如果不想一键编译运行,如何进行组件的自行编译?
- 编译单个组件
make WHAT="cmd/kube-apiserver"
- 执行之后,kubernetes的目录中,会出现一个目录_output,该目录中就是刚才编译构件产生的结果
- _output/bin 目录下,有一些临时文件,其中就包含kube-apiserver的可执行文件
- 编译所有组件
- 一个个组件的make太麻烦了,可以直接执行 make all,会将当前目录下所有的可构建可编译模块,都进行编译。
- 不过这样比较慢,我们还是推荐4.1中的方式,快速编译并启动一个单节点kubernetes
- 最后,我们再说一个注意点
- 如果使用make all这种方式,编译完所有的组件,启动的集群,是没办法使用remote的方式debug的。因为编译的时候,debug有一些不同的处理
- 我们可以通过修改 kubernetes/hack/lib/golang.sh 文件,让所有的编译在任何情况下都使用 debug方式
- 找到下面这段,可以看到,两个 if语句,第一个是debug下会干什么、第二个是非debug下会干什么
gogcflags="all=-trimpath=${trimroot} ${GOGCFLAGS:-}" if [[ "${DBG:-}" == 1 ]]; then # Debugging - disable optimizations and inlining. gogcflags="${gogcflags} -N -l" fi goldflags="all=$(kube::version::ldflags) ${GOLDFLAGS:-}" if [[ "${DBG:-}" != 1 ]]; then # Not debugging - disable symbols and DWARF. goldflags="${goldflags} -s -w" fi
- 我们改成下面这样就好了
- 把debug执行的语句,从if中取出,这样不管怎么样,都会执行
- 非debug执行的代码注掉,这样就不会执行到了
gogcflags="all=-trimpath=${trimroot} ${GOGCFLAGS:-}" # if [[ "${DBG:-}" == 1 ]]; then # # Debugging - disable optimizations and inlining. # gogcflags="${gogcflags} -N -l" # fi gogcflags="${gogcflags} -N -l" goldflags="all=$(kube::version::ldflags) ${GOLDFLAGS:-}" # if [[ "${DBG:-}" != 1 ]]; then # # Not debugging - disable symbols and DWARF. # goldflags="${goldflags} -s -w" # fi
- 这样以后再执行 make all,编译出来的东西,就可以debug
4.3.如何停止启动的集群
- 我们来到之前进行编译的那个终端页面,直接ctrl+c就可以完成集群停止
4.4.修改代码后,如何重新编译
- 下次再执行
sudo ./hack/local-up-cluster.sh
,不会再去编译生成可执行文件,会使用上次的编译结果。 - 如果我们已经修改了源码,需要先执行
make clean
清理掉之前的编译结果,然后再执行sudo ./hack/local-up-cluster.sh
才会生成新的可执行文件。
5.kubernetes工程目录结构速览
- cmd目录:所有组件的入口。cmd下的每一个文件夹,最终基本上都会编译成一个可执行文件
- pkg目录:大量核心代码都在这里
- hack目录:很多脚本工具,比如我们快速编译+启动本地集群,使用的local-up-cluster.sh就在这里
- staging目录:
- kubernetes项目越来越大,社区希望把已有的很多功能模块化,作为单独的项目进行维护和演进。
- 但是这些模块也不是一下就能剥离出来的,所以先把这些模块,作为一个独立的目录,放在staging下。
- 一旦有哪一个模块剥离成功,就会从staging下移除,以引用外部工具的方式,导入到vendor目录下进行使用。
参考资料
文章来源:https://blog.csdn.net/a1369760658/article/details/135118415
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!