使用 kubeadm 安装 kubernetes

1,100 阅读4分钟

写在前面

我个人认为首先将集群搭建起来后,再边操作边逐渐深入学习其内涵的方式比较好。
我自己学习的第一步也是搭建集群,所以第一篇笔记就先详细记录了自己几次尝试搭建集群的步骤。
第一次写博客,有什么问题或者错误欢迎留言指出。

安装前的准备工作

  • 禁用 swap
    sudo swapoff -a  
    sudo sed -ri '/\sswap\s/s/^ *#?/#* /' /etc/fstab
    
  • 允许 iptables 检查桥接流量
    cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
    br_netfilter
    EOF
    
    cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    EOF
    sudo sysctl --system
    
  • 安装容器运行时
    这里推荐使用 containerd。
    我使用的 Ubuntu 22.04,而 kubernetes 1.26 版本需要 containerd 1.6+。
    直接使用sudo apt install containerd.io安装的 containerd 版本还是 1.5 的导致初始化集群失败(现在不知道更新到最新版没)。
    所以推荐使用 Docker 源来安装 containerd。
    # 使用 docker 源安装最新版本 containerd / docker
    sudo apt install \
        ca-certificates \
        curl \
        gnupg \
        lsb-release
    
    sudo mkdir -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    sudo apt update
    sudo apt install containerd.io
    
    # sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
    
  • 配置containerd
    • 首先生成默认配置

      sudo mkdir -p /etc/containerd
      containerd config default | sudo tee /etc/containerd/config.toml
      
    • 配置使用 systemd cgroup 驱动并修改 sandbox 镜像地址
      由于墙的关系国内网络无法拉取 gcr 的镜像,所以要修改为国内镜像地址。
      不过 k8s.gcr.io 将在今年四月冻结,迁至 registry.k8s.io。

      sudo vim /etc/containerd/config.toml
      # ---
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]  
        # ...  
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]  
          SystemdCgroup = true
      # ---
      [plugins]
        # ...
        [plugins."io.containerd.grpc.v1.cri"]
          sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"
      # ---
      
      sudo systemctl daemon-reload  
      sudo systemctl restart containerd
      

      如果重启服务时出现错误 Failed to allocate directory watch: Too many open files.
      可以通过修改sysctl.conf解决:

      vim /etc/sysctl.conf
      
      # 设置参数
      # fs.inotify.max_user_instances = 512
      # fs.inotify.max_user_watches = 262144
      
      # 查看验证参数,确认无误充实 systemctl restart
      sysctl -p
      
  • 安装 nerdctl(可选)
    # 二进制安装
    # see https://github.com/containerd/nerdctl/releases for the latest release
    NERDCTL_VERSION=1.2.0 
    
    archType="amd64"
    if test "$(uname -m)" = "aarch64"
    then
        archType="arm64"
    fi
    
    wget "https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-${archType}.tar.gz"
    tar zxvf nerdctl-"${NERDCTL_VERSION}"-linux-amd64.tar.gz
    sudo cp nerdctl /usr/local/bin
    
    sudo mkdir /etc/nerdctl -p
    
    # 配置 nerdctl 接入 containerd
    sudo vim /etc/nerdctl/nerdctl.toml
    # ---
    address = "unix:///run/containerd/containerd.sock"  
    namespace = "k8s.io"  
    hosts_dir = ["/etc/containerd/certs.d", "/etc/docker/certs.d"]
    

安装 kubernetes

  • 安装 kubeadm

    sudo apt install apt-transport-https ca-certificates curl
    
    # 下载阿里云证书 或 谷歌云证书
    # 阿里云
    sudo curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
    # 谷歌云
    curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add
    
    # 配置阿里云镜像 或 kubenetes 仓库
    # 阿里云镜像
    sudo tee /etc/apt/sources.list.d/kubernetes.list <<-'EOF'
    deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
    EOF
    # kubernetes 仓库
    sudo tee /etc/apt/sources.list.d/kubernetes.list <<-'EOF'
    deb http://apt.kubernetes.io/ kubernetes-xenial main
    EOF
    
    # ---
    
    sudo apt update  
    sudo apt install kubelet kubectl kubeadm
    
    # (可选)保留不自动安装升级,通过 apt-mark unhold 取消保留
    
    sudo apt-mark hold kubelet kubeadm kubectl  
    sudo apt-mark unhold kubelet kubeadm kubectl
    
  • 使用 kubeadm 安装 kubernetes
    注意这里需要使用 root 执行。
    我选择使用 cilium 完全替代 kube-proxy。

    # (可选)通过命令手动拉取镜像
    kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers
    
    # 参数 --image-repository registry.aliyuncs.com/google_containers 指定镜像仓库地址
    # 或者配置 containerd 代理
    
    # kubeadm init 官方文档:
    # https://kubernetes.io/zh-cn/docs/reference/setup-tools/kubeadm/kubeadm-init/
    
    # 参数 --cri-socket unix:///run/containerd/containerd.sock 指定以 containerd 作为容器运行时
    # 参数 --skip-phases=addon/kube-proxy 跳过安装 kube-proxy(kube-proxy 可以使用 cilium 替代)
    #         若选择 kube-proxy + calico 的组合则去掉该参数 
    # 注意修改 apiserver-advertise-address 为实际情况的 ip
    kubeadm init \
        --image-repository registry.aliyuncs.com/google_containers \
        --pod-network-cidr=192.168.0.0/16 \
        --cri-socket unix:///run/containerd/containerd.sock \
        --skip-phases=addon/kube-proxy \
        --apiserver-advertise-address=192.168.3.50
    
    # ---
    # copy kube config 
    mkdir -p $HOME/.kube  
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config  
    sudo chown (id -u):(id -g) $HOME/.kube/config
    
    # 单机节点要去掉 master 节点的 taint 才能进行 pod 调度
    # <nodename> 为节点名
    # 通过 kubectl get po 可以查看,一般和主机名一致
    kubectl taint no <nodename> node-role.kubernetes.io/control-plane-
    
  • 安装 cni 插件

    cni 插件是 集群最重要的插件之一,用来配置 pod 的网络,是集群就绪的必备条件。
    helm 的安装可以查看官方文档

    • cilium

      # 使用 helm 安装 cilium
      helm repo add cilium https://helm.cilium.io/
      # your_api_server_ip
      API_SERVER_IP=192.168.3.50
      # your_api_server_port
      # Kubeadm default is 6443
      API_SERVER_PORT=6443
      
      # kubeProxyReplacement=strict 表示完全替代 kube-proxy
      helm install cilium cilium/cilium --version 1.13.0 \
        --set kubeProxyReplacement=strict \
        --set k8sServiceHost=${API_SERVER_IP} \
        --set k8sServicePort=${API_SERVER_PORT} \
        -n kube-system
      
      # 单机环境可以将 cilium-operator replicas 设置为 1(默认 2)或安装时候直接设置 operator.replicas 参数
      helm upgrade cilium cilium/cilium \
        --reuse-values \
        --set operator.replicas=1 \
        -n kube-system
      
      # 开启 DSR
      # 本地环境要设置 --set ipv4NativeRoutingCIDR
      helm upgrade cilium cilium/cilium \
        --reuse-values \
        --set tunnel=disabled \
        --set loadBalancer.mode=dsr \
        --set ipv4NativeRoutingCIDR=192.168.0.0/16 \
        -n kube-system
      
      # 验证
      kubectl -n kube-system exec ds/cilium -- cilium status | grep KubeProxyReplacement
      # ---
      # Defaulted container "cilium-agent" out of: cilium-agent, mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init)
      # KubeProxyReplacement:    Strict   [wlp7s0 192.168.3.50]
      # ---
      # 这里如果开启了 DSR 则会显示
      # KubeProxyReplacement:    Strict   [wlp7s0 192.168.3.50 (Direct Routing)] 
      
      # 查看 cilium 替代 kube-proxy 生成的服务
      kubectl -n kube-system exec ds/cilium -- cilium service list
      
      # 验证 KUBE-SVC 的 iptables 规则(这里应该为空)
      iptables-save | grep KUBE-SVC
      # ---
      # [ empty line ]
      
      
      # 安装 cilium cli
      CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/master/stable.txt)
      CLI_ARCH=amd64
      if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
      curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/"${CILIUM_CLI_VERSION}"/cilium-linux-"${CLI_ARCH}".tar.gz{,.sha256sum}
      sha256sum --check cilium-linux-"${CLI_ARCH}".tar.gz.sha256sum
      sudo tar xzvfC cilium-linux-"${CLI_ARCH}".tar.gz /usr/local/bin
      rm cilium-linux-"${CLI_ARCH}".tar.gz{,.sha256sum}
      
      
      # 查看 cilium 状态
      cilium status
      # ---
      #     /¯¯\
      #  /¯¯\__/¯¯\    Cilium:         OK
      #  \__/¯¯\__/    Operator:       OK
      #  /¯¯\__/¯¯\    Hubble:         disabled
      #  \__/¯¯\__/    ClusterMesh:    disabled
      #     \__/
      # 
      # Deployment        cilium-operator    Desired: 1, Ready: 1/1, Available: 1/1
      # DaemonSet         cilium             Desired: 1, Ready: 1/1, Available: 1/1
      # Containers:       cilium             Running: 1
      #                   cilium-operator    Running: 1
      # Cluster Pods:     7/7 managed by Cilium
      # Image versions    cilium             quay.io/cilium/cilium:v1.12.6@sha256:454134506b0448c756398d3e8df68d474acde2a622ab58d0c7e8b272b5867d0d: 1
      #                   cilium-operator    quay.io/cilium/operator-generic:v1.12.6@sha256:eec4430d222cb2967d42d3b404d2606e66468de47ae85e0a3ca3f58f00a5e017: 1
      
      # 开启 Hubble
      helm upgrade cilium cilium/cilium \
         --reuse-values \
         --set hubble.relay.enabled=true \
         --set hubble.ui.enabled=true \
         -n kube-system
      
      # 安装 Hubble 客户端
      export HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
      HUBBLE_ARCH=amd64
      if [ "$(uname -m)" = "aarch64" ]; then HUBBLE_ARCH=arm64; fi
      curl -L --fail --remote-name-all https://github.com/cilium/hubble/releases/download/"$HUBBLE_VERSION"/hubble-linux-"${HUBBLE_ARCH}".tar.gz{,.sha256sum}
      sha256sum --check hubble-linux-"${HUBBLE_ARCH}".tar.gz.sha256sum
      sudo tar xzvfC hubble-linux-"${HUBBLE_ARCH}".tar.gz /usr/local/bin
      rm hubble-linux-"${HUBBLE_ARCH}".tar.gz{,.sha256sum}
      
    • calico
      在 kubeadm init 中去掉参数--skip-phases=addon/kube-proxy的则需要安装calico
      其实 cilium 和 kube-proxy 搭配使用也可以,安装时使用非strict模式就可以。
      具体可以查看 cilium 官方文档

      # 注意这里需要用 create,使用 apply 会出现如下所示错误
      # ...
      # The CustomResourceDefinition "installations.operator.tigera.io" is invalid: metadata.annotations: Too long: must have at most 262144 bytes
      kubectl create -f https://docs.projectcalico.org/manifests/tigera-operator.yaml
      
      kubectl create -f https://docs.projectcalico.org/manifests/custom-resources.yaml
      # custom-resources.yaml 的中默认 spec.calicoNetwork.ipPools.cidr = 192.168.0.0
      # 该配置项需与 node 的 spec.podCIDR 保持一致(通过命令 kubectl get no -oyaml [Node] 查看)
      # spec.podCIDR 通过 kubeadm init --pod-network-cidr 参数设置
      # 否则会导致 coredns 容器创建失败
      # spec:
      #   calicoNetwork:
      #    ipPools:
      #     - blockSize: 26
      #       cidr: 192.168.0.0/16
      #       encapsulation: VXLANCrossSubnet
      #       natOutgoing: Enabled
      #       nodeSelector: all()
      

节点加入

kubeadm join <master_ip>:<master_port> --token 28zojw.5296fjspocd1kyji \
	--discovery-token-ca-cert-hash sha256:687d748af739de768da5980e74ce0cda245ceb22b8b173c6af1725c4f8321224

注意 token 在 kubeadm init 完成时会输出,有效期为 24 小时。
过期后可以通过命令kubeadm token create --print-join-command生成新的。
master_port 默认情况下为 6443。