Kubernetes api-server源码阅读1(源码环境安装篇)

发布时间:2023年12月23日

本文是 Kubernetes api-server源码阅读 系列第一篇,主要讲述如何进行kubernetes源码阅读环境的搭建

1.准备环境

1.1.搭建目标

2.安装工具包

2.1.安装虚拟机

2.1.1.安装Ubuntu虚拟机

  • Ubuntu下载地址:
    • https://ubuntu.com/download/alternative-downloads
    • 镜像比较大,资源里我放了种子,如果下不了,直接给我留言,我发给大家
  • 如果安装完发现虚拟机屏幕太小,可以安装或重新安装VM Tools
  • 本地ssh连接ubuntu,发现22端口拒绝访问
  • 现在用的是普通用户登陆,root密码每一次开机都会刷新,我们现在修改root密码,以后用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"
      
    • 将我们修改后的配置文件,移动到containerd目录下
      mv ~/config.toml /etc/containerd/config.toml
      
    • 重启containerd,让配置文件生效
      systemctl restart containerd
      
    • 查看containerd状态,确保已经active了
      systemctl containerd status
      

2.4.安装rsync

2.4.1.rsync是什么

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是什么

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

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
      

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
    vim /etc/sudoers
    
    在secure_path中添加:
    :/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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。