Kubernetes集群部署笔记

发布于最后编辑于全文约3632字,阅读时间约为9分钟。

Kubernetes Debian Helm kubeadm containerd Flannel kube-router MetalLB Spegel Podman Skopeo Docker
更新记录
  • 2021-09-04

    • 服务器操作系统由Debian 10 ("buster")更新至Debian 11 ("bullseye")

    • 使用kube-router代替kube-proxyflannel实现Service ProxyPod Network

    • 修复一些代码错误;

  • 2021-09-08

    • 部署kube-router时添加运行参数--advertise-loadbalancer-ip=true

  • 2021-09-18

    • Kubernetes版本由v1.22.1更新至v1.22.2

  • 2021-10-29

    • Kubernetes版本由v1.22.2更新至v1.22.3

    • metallb版本由v0.10.2更新至v0.10.3

  • 2021-11-20

    • Debian版本由v11.0更新至v11.1

    • Kubernetes版本由v1.22.3更新至v1.22.4

    • containerd版本由v1.4.9更新至v1.4.12

    • metallb版本由v0.10.3更新至v0.11.0

    • kube-router版本由v1.3.1更新至v1.3.2

    • metrics-server版本由v0.5.0更新至v0.5.2

  • 2022-04-30

    • Debian版本由v11.1更新至v11.3

    • Kubernetes版本由v1.22.4更新至v1.23.6

    • containerd版本由v1.4.12更新至v1.5.11

    • metallb版本由v0.11.0更新至v0.12.1

    • kube-router版本由v1.3.2更新至v1.4.0

    • local-path-provisioner版本由v0.0.20更新至v0.0.22

    • metrics-server版本由v0.5.2更新至v0.6.1

  • 2022-05-20

    • Kubernetes版本由v1.23.6更新至v1.24.0

    • containerd版本由v1.5.11更新至v1.6.4

  • 2022-05-29

    • Kubernetes版本由v1.24.0更新至v1.24.1

  • 2022-06-23

    • containerd版本由v1.6.4更新至v1.6.6

    • Kubernetes版本由v1.24.1更新至v1.24.2

    • kube-router版本由v1.4.0更新至v1.5.0

  • 2022-07-09

    • Debian版本由v11.3更新至v11.4

  • 2022-07-24

    • Kubernetes版本由v1.24.2更新至v1.24.3

  • 2022-08-14

    • containerd版本由v1.6.6更新至v1.6.7

    • kube-router版本由v1.5.0更新至v1.5.1

  • 2022-08-25

    • Kubernetes版本由v1.24.3更新至v1.25.0

  • 2022-08-27

    • containerd版本由v1.6.7更新至v1.6.8

  • 2022-09-13

    • Debian版本由v11.4更新至v11.5

    • 添加集群日志采集方案文章引用;

  • 2022-09-18

    • 添加使用GitHub Actions同步镜像方法描述;

  • 2022-09-21

    • Kubernetes版本由v1.25.0更新至v1.25.1

  • 2022-09-24

    • Kubernetes版本由v1.25.1更新至v1.25.2

    • 使用quay.io代替registry.cn-beijing.aliyuncs.com作为私有镜像仓库示例;

  • 2022-10-26

    • containerd版本由v1.6.8更新至v1.6.9

    • Kubernetes版本由v1.25.2更新至v1.25.3

  • 2022-11-08

    • kube-router版本由v1.5.1更新至v1.5.2

    • local-path-provisioner版本由v0.0.22更新至v0.0.23

  • 2022-11-12

    • Kubernetes版本由v1.25.3更新至v1.25.4

  • 2022-11-18

    • containerd版本由v1.6.9更新至v1.6.10

  • 2022-12-08

    • containerd版本由v1.6.10更新至v1.6.12

  • 2022-12-09

    • Kubernetes版本由v1.25.4更新至v1.25.5

    • kube-router版本由v1.5.2更新至v1.5.3

    • metrics-server版本由v0.6.1更新至v0.6.2

  • 2022-12-17

    • Kubernetes版本由v1.25.5更新至v1.26.0

  • 2022-12-30

    • Debian版本由v11.5更新至v11.6

    • containerd版本由v1.6.12更新至v1.6.14

  • 2023-01-10

    • containerd版本由v1.6.14更新至v1.6.15

  • 2023-01-28

    • Kubernetes版本由v1.26.0更新至v1.26.1

  • 2023-02-01

    • containerd版本由v1.6.15更新至v1.6.16

  • 2023-02-18

    • containerd版本由v1.6.16更新至v1.6.18

  • 2023-03-03

    • Kubernetes版本由v1.26.1更新至v1.26.2

  • 2023-03-20

    • Kubernetes版本由v1.26.2更新至v1.26.3

  • 2023-03-27

    • containerd版本由v1.6.18更新至v1.6.19

  • 2023-04-12

    • containerd版本由v1.6.19更新至v1.6.20

    • Kubernetes版本由v1.26.3更新至v1.27.0

    • metrics-server版本由v0.6.2更新至v0.6.3

    • local-path-provisioner版本由v0.0.23更新至v0.0.24

  • 2023-04-15

    • Kubernetes版本由v1.27.0更新至v1.27.1

  • 2023-05-03

    • Debian版本由v11.6更新至v11.7

    • kube-router版本由v1.5.3更新至v1.5.4

  • 2023-06-02

    • containerd版本由v1.6.20更新至v1.6.21

    • Kubernetes版本由v1.27.1更新至v1.27.2

  • 2023-06-22

    • Kubernetes版本由v1.27.2更新至v1.27.3

  • 2023-07-24

    • Kubernetes版本由v1.27.3更新至v1.27.4

    • kube-router版本由v1.5.4更新至v1.6.0

  • 2023-07-31

    • metallb版本由v0.12.1更新至v0.13.10

  • 2023-08-08

    • containerd版本由v1.6.21更新至v1.6.22

    • metrics-server版本由v0.6.3更新至v0.6.4

  • 2023-08-17

    • Kubernetes版本由v1.27.4更新至v1.28.0

  • 2023-09-01

    • Kubernetes版本由v1.28.0更新至v1.28.1

  • 2023-09-11

    • Debian版本由v11.7更新至v12.1

  • 2023-09-14

    • Kubernetes版本由v1.28.1更新至v1.28.2

    • metallb版本由v0.13.10更新至v0.13.11

  • 2023-09-26

    • containerd版本由v1.6.22更新至v1.6.24

  • 2023-10-19

    • Debian版本由v12.1更新至v12.2

    • Kubernetes版本由v1.28.2更新至v1.28.3

  • 2023-10-28

    • 更新用于同步镜像的GitHub Actions定义文件;

  • 2023-11-16

    • Kubernetes版本由v1.28.3更新至v1.28.4

  • 2023-11-18

    • kube-router版本由v1.6.0更新至v2.0.1

    • 配置kube-router支持发卡模式(Hairpin-Mode)流量;

    • metallb版本由v0.13.11更新至v0.13.12

  • 2023-11-27

    • containerd版本由v1.6.24更新至v1.6.25

    • local-path-provisioner版本由v0.0.24更新至v0.0.25

  • 2023-12-14

    • Debian版本由v12.2更新至v12.4

    • containerd版本由v1.6.25更新至v1.6.26

    • Kubernetes版本由v1.28.4更新至v1.29.0

    • local-path-provisioner版本由v0.0.25更新至v0.0.26

  • 2024-01-18

    • containerd版本由v1.6.26更新至v1.6.27

    • Kubernetes版本由v1.29.0更新至v1.29.1

  • 2024-02-10

    • containerd版本由v1.6.27更新至v1.6.28

    • metallb版本由v0.13.12更新至v0.14.3

    • metrics-server版本由v0.6.4更新至v0.7.0

  • 2024-02-15

    • Kubernetes版本由v1.29.1更新至v1.29.2

  • 2024-03-22

    • Debian版本由v12.4更新至v12.5

    • Kubernetes版本由v1.29.2更新至v1.29.3

  • 2024-03-31

    • kube-router版本由v2.0.1更新至v2.1.0

    • metallb版本由v0.14.3更新至v0.14.4

    • metrics-server版本由v0.7.0更新至v0.7.1

  • 2024-04-17

    • containerd版本由v1.6.28更新至v1.6.31

    • Kubernetes版本由v1.29.3更新至v1.29.4

  • 2024-04-18

    • Kubernetes版本由v1.29.4更新至v1.30.0

  • 2024-04-20

    • metallb版本由v0.14.4更新至v0.14.5

  • 2024-04-28

    • kube-router版本由v2.1.0更新至v2.1.1

  • 2024-05-14

    • kube-router版本由v2.1.1更新至v2.1.2

  • 2024-05-16

    • Kubernetes版本由v1.30.0更新至v1.30.1

  • 2024-05-24

    • containerd版本由v1.6.31更新至v1.6.32

  • 2024-07-24

    • Debian版本由v12.5更新至v12.6

    • containerd版本由v1.6.32更新至v1.7.19

    • Kubernetes版本由v1.30.1更新至v1.30.3

    • kube-router版本由v2.1.2更新至v2.1.3

    • metallb版本由v0.14.5更新至v0.14.8

    • local-path-provisioner版本由v0.0.26更新至v0.0.28

  • 2024-08-04

    • kube-router版本由v2.1.3更新至v2.2.0

  • 2024-09-02

    • Debian版本由v12.6更新至v12.7

    • containerd版本由v1.7.19更新至v1.7.21

    • Kubernetes版本由v1.30.3更新至v1.31.0

    • kube-router版本由v2.2.0更新至v2.2.1

    • metrics-server版本由v0.7.1更新至v0.7.2

  • 2024-09-14

    • containerd版本由v1.7.21更新至v1.7.22

    • Kubernetes版本由v1.31.0更新至v1.31.1

  • 2024-09-28

    • local-path-provisioner版本由v0.0.28更新至v0.0.29

  • 2024-10-22

    • kube-router版本由v2.2.1更新至v2.2.2

    • local-path-provisioner版本由v0.0.29更新至v0.0.30

  • 2024-10-25

    • Kubernetes版本由v1.31.1更新至v1.31.2

  • 2024-12-05

    • containerd版本由v1.7.22更新至v1.7.24

    • Kubernetes版本由v1.31.2更新至v1.31.3

    • kube-router版本由v2.2.2更新至v2.4.0

  • 2025-01-26

    • Debian版本由v12.7更新至v12.9

    • containerd版本由v1.7.24更新至v1.7.25

    • Kubernetes版本由v1.31.3更新至v1.32.1

    • kube-router版本由v2.4.0更新至v2.4.1

    • metallb版本由v0.14.8更新至v0.14.9

    • local-path-provisioner版本由v0.0.30更新至v0.0.31

  • 2025-03-08

    • Kubernetes版本由v1.32.1更新至v1.32.2

    • kube-router版本由v2.4.1更新至v2.5.0

  • 2025-03-16

    • Debian版本由v12.9更新至v12.10

    • Kubernetes版本由v1.32.2更新至v1.32.3

  • 2025-03-29

    • containerd版本由v1.7.25更新至v1.7.26

  • 2025-04-24

    • containerd版本由v1.7.26更新至v1.7.27

    • Kubernetes版本由v1.32.3更新至v1.33.0

  • 2025-05-13

    • 添加spegel镜像注册表服务;

  • 2025-05-25

    • Debian版本由v12.10更新至v12.11

    • Kubernetes版本由v1.33.0更新至v1.33.1

  • 2025-06-05

    • metallb版本由v0.14.9更新至v0.15.2

    • spegel版本由v0.2.0更新至v0.3.0

  • 2025-07-04

    • Kubernetes版本由v1.33.1更新至v1.33.2

    • metrics-server版本由v0.7.2更新至v0.8.0

  • 2025-07-22

    • Kubernetes版本由v1.33.2更新至v1.33.3

  • 2025-08-14

    • Kubernetes版本由v1.33.3更新至v1.33.4

    • local-path-provisioner版本由v0.0.31更新至v0.0.32

  • 2025-09-02

    • Kubernetes版本由v1.33.4更新至v1.34.0

  • 2025-09-03

    • Debian版本由v12.11更新至v13.0

  • 2025-09-07

    • Debian版本由v13.0更新至v13.1

  • 2025-09-14

    • Kubernetes版本由v1.34.0更新至v1.34.1

  • 2025-09-15

    • spegel版本由v0.3.0更新至v0.4.0

  • 2025-09-23

    • kube-router版本由v2.5.0更新至v2.6.0

  • 2026-03-07

    • Debian版本由v13.1更新至v13.3

    • containerd版本由v1.7.27更新至v2.2.1

    • Kubernetes版本由v1.34.1更新至v1.35.2

    • kube-router版本由v2.6.0更新至v2.7.1

    • metallb版本由v0.15.2更新至v0.15.3

    • local-path-provisioner版本由v0.0.32更新至v0.0.34

    • metrics-server版本由v0.8.0更新至v0.8.1

    • spegel版本由v0.4.0更新至v0.6.0

  • 2026-04-05

    • Debian版本由v13.3更新至v13.4

    • containerd版本由v2.2.1更新至v2.2.2

    • Kubernetes版本由v1.35.2更新至v1.35.3

    • kube-router版本由v2.7.1更新至v2.8.0

    • local-path-provisioner版本由v0.0.34更新至v0.0.35

概述

本文用于整理基于Debian操作系统使用kubeadm工具部署Kubernetes集群的操作过程。该集群部署于一组本地虚拟服务器上,用于学习Kubernetes的基础概念和基本操作,并作为今后其他学习内容的实践部署提供环境。

考虑到不同的网络环境,本文中一些步骤会记录两种操作方式,通过镜像等方式加快部署效率、避免部署错误。有关镜像同步的方案,可参考附件内容中的同步所需镜像

随着操作系统和各相关组件版本的更新,笔者将在验证通过后对本文进行补充和更新,请参考更新记录

本文未包含集群日志采集相关演练内容,可参考笔者的另一篇笔记《Kubernetes环境OpenSearch部署与应用》中的演练内容。

服务器

受限于本地物理服务器的配置,虚拟服务器配置规划如下表。

HostOSIPCPURAMK8sRoles
k8s-n0Debian 13.410.0.0.502 vCPUs4 GBv1.35.3control-plane
k8s-n1Debian 13.410.0.0.514 vCPUs8 GBv1.35.3
k8s-n2Debian 13.410.0.0.524 vCPUs8 GBv1.35.3
k8s-n3Debian 13.410.0.0.534 vCPUs8 GBv1.35.3

所有虚拟服务器CPU均为amd64架构。

截止本文发布时,笔者基于最新Debian 11 (“bullseye”)部署的集群仍然存在一些问题,故暂且发布基于Debian 10 (“buster”)的笔记。

网络环境

本地网络IP地址范围为10.0.0.0/24,其中:

  • 10.0.0.2-10.0.0.99为静态分配,供虚拟服务器使用。
  • 10.0.0.100-10.0.0.200用于DHCP自动分配。
  • 10.0.0.201-10.0.0.254为静态分配,供负载均衡器使用。

其他组件

准备工作

服务器配置

本文假设服务器硬件和操作系统已经配置完毕,所有服务器上都已经正确配置了ssh服务和sudo权限。

作为参考,这里记录笔者配置sudo权限和ssh服务的过程。

  • 配置sudo权限

    如操作人员的登录用户已经被正确配置了sudo权限,可跳过此步骤。

    本示例中,操作人员的登录用户名为tiscs,需要实际环境情况进行替换。

    # 使用root用户登录系统
    # 安装sudo,并配置sudo权限
    apt update
    apt install sudo
    echo "tiscs ALL=(ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/tiscs # 这在生产环境绝不是个好主意,仅仅是为了演练环境操作方便
  • 配置ssh服务

    # sudo sed -i 's/http:/https:/g' /etc/apt/sources.list
    # 安装openssh-server,并配置ssh服务为自动启动
    sudo apt update
    sudo apt install openssh-server
    sudo systemctl enable ssh --now

也可以参考笔者的原创视频:《演练环境准备——部署虚拟服务器》。

演练环境准备——部署虚拟服务器

配置过程

安装容器运行时

本文配置的集群选择containerd作为容器运行时。

在所有节点上执行如下操作。

  • 配置模块加载

    cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf > /dev/null
    overlay
    br_netfilter
    EOF
    
    sudo modprobe overlay
    sudo modprobe br_netfilter
  • 配置sysctl参数

    cat <<EOF | sudo tee /etc/sysctl.d/99-k8s.conf > /dev/null
    net.ipv4.ip_forward           = 1
    fs.inotify.max_user_instances = 8192
    EOF
    
    sudo sysctl --system
  • 配置APT源

    # 安装依赖项
    sudo apt install -y ca-certificates curl gnupg
    curl -fsSL https://download.docker.com/linux/debian/gpg \
      | sudo gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
      | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  • 安装containerd

    sudo apt update
    sudo apt install -y containerd.io
  • 初始化配置

    sudo mkdir -p /etc/containerd
    containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
    # 配置systemd cgroup驱动
    sudo sed -i -e 's|SystemdCgroup = false|SystemdCgroup = true|g' /etc/containerd/config.toml
    # (可选)配置sandbox image地址
    # 为了方便,这里配置为与kubelet所需相同的版本(可以使用kubeadm config images list命令查看)
    sudo sed -i -e "s|'registry.k8s.io/pause:.\+'|'quay.io/choral-k8s/pause:3.10.1'|g" /etc/containerd/config.toml
    # 重启containerd服务,使上述配置修改生效
    sudo systemctl restart containerd

安装kubeadm

在所有节点上执行如下操作。

  • 配置APT源

    curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key \
      | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
    echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /" \
      | sudo tee /etc/apt/sources.list.d/kubernetes.list > /dev/null
  • 安装kubeadmkubeletkubectl

    # apt-cache madison kubeadm | head -1 # check latest release
    sudo apt update
    sudo apt install -y kubeadm=1.35.3-1.1 kubelet=1.35.3-1.1 kubectl=1.35.3-1.1 # --allow-change-held-packages
    sudo apt-mark hold kubelet kubeadm kubectl
    # sudo kubeadm upgrade apply v1.35.3 --skip-phases=addon/kube-proxy # upgrade control plane nodes
  • 安装并配置crictl(可选)

    可以安装并配置crictl,便于在k8s节点上管理容器运行时。

    # 安装crictl工具
    sudo apt install -y cri-tools
    
    # 配置crictl使用containerd运行时
    cat <<EOF | sudo tee /etc/crictl.yaml > /dev/null
    runtime-endpoint: unix:///run/containerd/containerd.sock
    image-endpoint: unix:///run/containerd/containerd.sock
    timeout: 10
    debug: false
    EOF
    
    # 验证crictl配置
    sudo crictl images # 列出所有镜像

配置控制平面节点

k8s-n0节点上执行如下操作。

  • 预先下载所需镜像

    # 查看所需的镜像列表
    kubeadm config images list --kubernetes-version=v1.35.3 # --image-repository quay.io/choral-k8s
    
    # 1. 使用默认容器镜像仓库
    sudo kubeadm config images pull --kubernetes-version=v1.35.3
    
    # 2. 使用指定容器镜像仓库
    sudo kubeadm config images pull --kubernetes-version=v1.35.3 --image-repository quay.io/choral-k8s
  • 初始化控制平面节点

    # --apiserver-advertise-address   当前节点IP地址
    # --pod-network-cidr              Pod网络地址段(CIDR: https://datatracker.ietf.org/doc/html/rfc4632)
    # --skip-phases=addon/kube-proxy  跳过安装kube-proxy组件(使用`kube-router`作为网络组件)
    
    # 1. 使用默认容器镜像仓库
    sudo kubeadm init --apiserver-advertise-address 10.0.0.50 \
      --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.35.3 \
      --skip-phases=addon/kube-proxy
    
    # 2. 使用指定容器镜像仓库
    sudo kubeadm init --apiserver-advertise-address 10.0.0.50 \
      --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.35.3 \
      --skip-phases=addon/kube-proxy \
      --image-repository quay.io/choral-k8s

    执行完上述操作后,kubeadm init命令会输出用于添加节点到集群中的说明,请保存该说明中的内容。示例如下:

    sudo kubeadm join 10.0.0.50:6443 \
      --token vafq03.5dl6j1cbcd1yzf3c \
      --discovery-token-ca-cert-hash sha256:6a725d98e0f6bda713c9f93b8441a735cc60e8ec7454fbe960c74ab80683f938
  • 添加kubectl配置(可选)

    mkdir -p ~/.kube
    sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
    sudo chown $(id -u):$(id -g) ~/.kube/config

安装网络组件

  • 安装flannel(已废弃,使用kube-router代替)

    # 1. 使用默认镜像仓库(quay.io/coreos)安装
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
    
    # 2 如果访问raw.githubusercontent.com上的文件存在网络问题
    #   可以使用jsdelivr提供的GitHub CDN地址(https://www.jsdelivr.com/github)
    kubectl apply -f https://cdn.jsdelivr.net/gh/coreos/flannel@master/Documentation/kube-flannel.yml
  • 安装kube-router

    curl -s https://cdn.jsdelivr.net/gh/cloudnativelabs/kube-router@v2.8.0/daemonset/generic-kuberouter-all-features.yaml \
      | sed \
        -e "s|%APISERVER%|$(kubectl get cm -n kube-public -o yaml cluster-info | sed -n 's/^ \+server: \(.\+\)/\1/p')|g" \
        -e "s|%CLUSTERCIDR%|$(kubectl get cm -n kube-system -o yaml kubeadm-config | sed -n 's/^ \+podSubnet: \(.\+\)/\1/p')|g" \
        -e "s|\(\s\+\)args:|\1args:\n\1- \"--advertise-loadbalancer-ip=true\"\n\1- \"--hairpin-mode=true\"|g" \
        -e "s|docker.io/cloudnativelabs/kube-router\$|quay.io/choral-k8s/kube-router:v2.8.0|g" \
      | kubectl apply -f -
    # 检查组件部署成功
    kubectl get pods -n kube-system

添加工作节点

k8s-n1k8s-n2k8s-n3节点上执行如下操作。该操作中需要的token值和hash值通过上述步骤中的kubeadm init操作获取。

  • 添加工作节点

    sudo kubeadm join 10.0.0.50:6443 \
      --token vafq03.5dl6j1cbcd1yzf3c \
      --discovery-token-ca-cert-hash sha256:6a725d98e0f6bda713c9f93b8441a735cc60e8ec7454fbe960c74ab80683f938
  • 查看节点状态

    k8s-n0节点上执行如下操作。

    kubectl get nodes

安装Helm工具(可选)

本文暂不涉及使用helm执行的操作,该步骤可选。

  • 安装Helm工具

    # 下载并安装
    curl -sL https://get.helm.sh/helm-v4.0.0-linux-amd64.tar.gz | tar xzf - linux-amd64/helm
    sudo cp ./linux-amd64/helm /usr/local/bin/helm
    rm -rf ./linux-amd64
    sudo chown root:root /usr/local/bin/helm
    sudo chmod 755 /usr/local/bin/helm
    
    # 验证helm安装
    helm version

安装Metrics Server(可选)

部署metrics server以启用指标服务,未安装metrics server前,kubectl top命令无法正常执行。

k8s-n0节点上执行如下操作。

  • 执行清单文件

    这里需要注意,为解决证书错误,需要添加metrics-server容器的参数--kubelet-insecure-tls,这里选择通过sed命令修改清单文件后再使用kubectl执行。

    # 1. 使用官方镜像地址直接安装
    curl -sL https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.8.1/components.yaml \
      | sed -e "s|\(\s\+\)- args:|\1- args:\n\1  - --kubelet-insecure-tls|" | kubectl apply -f -
    
    # 2. 使用自定义镜像地址安装
    curl -sL https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.8.1/components.yaml \
      | sed \
        -e "s|\(\s\+\)- args:|\1- args:\n\1  - --kubelet-insecure-tls|" \
        -e "s|registry.k8s.io/metrics-server|quay.io/choral-k8s|g" \
      | kubectl apply -f -
    
    # 3. 查看集群指标信息
    kubectl top nodes
    kubectl top pods -n kube-system

安装Spegel OCI Registry(可选)

Spegel是一个无状态、点对点的集群级本地镜像缓存与分发系统,实现透明拦截并加速集群中的镜像拉取请求。

部署Spegel OCI Registry需要在初始化containerd配置文件后,更新配置文件中的registry配置路径,请参考本文中安装容器运行时一节中初始化配置部分的可选配置说明。

  • 部署Spegel组件

    helm upgrade --install --namespace kube-system spegel oci://ghcr.io/spegel-org/helm-charts/spegel --version 0.6.0

安装负载均衡组件

由云服务商提供的Kubernetes服务,通常会提供内置的负载均衡实现,而笔者部署环境为私有环境,需要一个轻量的负载均衡实现以支撑LoadBalancer类型的服务。

笔者选择MetalLB作为负载均衡实现,配置为二层网络模式。LoadBalancer地址范围配置为10.0.0.201-10.0.0.254,需根据具体网络环境进行修改。

k8s-n0节点上执行如下操作。

  • 安装MetalLB

    # 创建用于部署MetalLB的命名空间
    kubectl create namespace metallb-system
    
    # 1. 直接执行清单文件
    kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-frr.yaml
    
    # 2. 为避免特殊网络环境中的清单文件加载问题,可以使用jsdelivr提供的加速方案
    kubectl apply -f https://cdn.jsdelivr.net/gh/metallb/metallb@v0.15.3/config/manifests/metallb-frr.yaml
    
    # 创建地址池配置文件
    cat <<EOF | kubectl apply -f - > /dev/null
    apiVersion: metallb.io/v1beta1
    kind: IPAddressPool
    metadata:
      name: default-pool
      namespace: metallb-system
    spec:
      addresses:
        - 10.0.0.201-10.0.0.254
    EOF
    
    # 创建二层广播配置文件
    cat <<EOF | kubectl apply -f - > /dev/null
    apiVersion: metallb.io/v1beta1
    kind: L2Advertisement
    metadata:
      name: default-l2ad
      namespace: metallb-system
    spec:
      ipAddressPools:
        - default-pool
    EOF

安装持久卷供应程序

Kubernetes内置的local-storage存储类无法动态供应卷,为便于基于该环境演练时自动创建持久卷,选择使用local-path-provisioner作为持久卷供应程序。

  • 创建所需的目录

    在所有节点上执行如下操作。

    sudo mkdir -p /opt/local-path-provisioner
  • 安装local-path-provisioner

    k8s-n0节点上执行如下操作。

    # 1. 使用官方清单文件地址直接安装
    kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.35/deploy/local-path-storage.yaml
    #   1.1 同样可以使用jsdelivr提供的加速方案
    kubectl apply -f https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@v0.0.35/deploy/local-path-storage.yaml
    
    # 2. 替换命名空间
    curl -s https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@v0.0.35/deploy/local-path-storage.yaml \
      | sed \
        -e "1,6d" \
        -e "s|namespace: local-path-storage|namespace: kube-system|" \
        -e "s|image: rancher|image: quay.io/choral-k8s|" \
        -e "s|image: busybox|image: quay.io/choral-k8s/busybox|" \
      | kubectl apply -f -
  • 配置默认存储类

    kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

检查集群工作状态

k8s-n0节点上执行如下操作。

  • 查看节点状态

    kubectl get nodes
    kubectl top nodes
  • 查看Pod状态

    kubectl get pods -A
    kubectl top pods -A

附加内容

同步所需镜像

由于特殊网络环境问题,需要同步kubelet所需镜像至其他镜像仓库的,可参考如下操作。

笔者开发环境中使用podman管理容器和镜像,已将docker设置为podman的别名(alias docker=podman)。

  • 同步kubelet所需镜像

    首先,需要创建自定义镜像仓库认证凭据。

    # 根据需要将`quay.io`替换为自定义镜像仓库地址
    docker login quay.io

    创建一个脚本k8s_mirror_sync.sh,内容如下。

    # k8s_mirror_sync.sh
    # 根据需要将`quay.io/choral-k8s/`替换为自定义镜像仓库地址
    while read o
      do {
          t=$(echo $o | sed -e 's|registry.k8s.io.*/|quay.io/choral-k8s/|g' -e 's|registry.k8s.io.*/|quay.io/choral-k8s/|g')
          docker pull $o
          docker tag $o $t
          docker push $t
          docker rmi $o
          docker rmi $t
      }
    done < "${1:-/dev/stdin}"

    该脚本有两种使用方法。

    kubeadm config images list --kubernetes-version=v1.35.3 | bash k8s_mirror_sync.sh
    # 列出所需镜像列表并保存到文件
    kubeadm config images list --kubernetes-version=v1.35.3 > k8s-image-list
    # 拷贝该文件至k8s_mirror_sync.sh所在主机,然后执行该脚本
    bash k8s_mirror_sync.sh k8s-image-list
  • 同步附加组件镜像

    # 根据需要将`quay.io/choral-k8s/`替换为自定义镜像仓库地址。
    
    # 同步metrics server所需镜像
    docker pull registry.k8s.io/metrics-server/metrics-server:v0.8.1
    docker tag registry.k8s.io/metrics-server/metrics-server:v0.8.1 quay.io/choral-k8s/metrics-server:v0.8.1
    docker push quay.io/choral-k8s/metrics-server:v0.8.1
    docker rmi registry.k8s.io/metrics-server/metrics-server:v0.8.1
    docker rmi quay.io/choral-k8s/metrics-server:v0.8.1
  • 使用GitHub Actions同步镜像

    整理上面步骤中的脚本后,可以使用GitHub Actions执行镜像同步任务,使用skopeo工具同步镜像。

    首先创建GitHub Actions执行时所需的Secrets

    # GitHub Actions Secrets
    CONTAINER_REGISTRY_NAMESPACE: "choral-k8s" # 根据需要将`choral-k8s`替换为自定义命名空间
    CONTAINER_REGISTRY_HOSTNAME: "quay.io" # 根据需要将`quay.io`替换为自定义镜像仓库主机名称
    CONTAINER_REGISTRY_USERNAME: "<REDACTED>"
    CONTAINER_REGISTRY_PASSWORD: "<REDACTED>"

    创建一个GitHub Actions配置文件,例如.github/workflows/sync-kubeadm-images.yml

    name: Sync images required by kubeadm
    
    on:
      push:
        branches: ["main"]
    
    jobs:
      sync-images:
        runs-on: ubuntu-latest
        container:
          image: quay.io/skopeo/stable:latest
          env:
            KUBERNETES_VERSION: v1.35.3 # 需要同步镜像的`kubernetes`版本
            CONTAINER_REGISTRY_NAMESPACE: ${{ secrets.CONTAINER_REGISTRY_NAMESPACE }}
            CONTAINER_REGISTRY_HOSTNAME: ${{ secrets.CONTAINER_REGISTRY_HOSTNAME  }}
            CONTAINER_REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME  }}
            CONTAINER_REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD  }}
    
        steps:
          - run: |
              curl -sL https://dl.k8s.io/release/$KUBERNETES_VERSION/bin/linux/amd64/kubeadm -o /usr/local/bin/kubeadm
              chmod 755 /usr/local/bin/kubeadm
              kubeadm version
              kubeadm config images list --kubernetes-version=$KUBERNETES_VERSION
          - run: |
              echo $CONTAINER_REGISTRY_PASSWORD | skopeo login --username $CONTAINER_REGISTRY_USERNAME --password-stdin $CONTAINER_REGISTRY_HOSTNAME
              for o in $(kubeadm config images list --kubernetes-version=$KUBERNETES_VERSION); do
                t=$(echo $o | sed "s|registry.k8s.io.*/|$CONTAINER_REGISTRY_HOSTNAME/$CONTAINER_REGISTRY_NAMESPACE/|g" | sed "s|registry.k8s.io.*/|$CONTAINER_REGISTRY_HOSTNAME/$CONTAINER_REGISTRY_NAMESPACE/|g")
                echo "Syncing $o"
                skopeo copy --all docker://$o docker://$t
              done

    执行上述配置文件定义的GitHub Actions时,将指定版本Kubernetes所需的镜像同步到指定仓库的指定命名空间中。

参考资料