z-k8s高可用Kubernetes集群准备

KVM虚拟机运行环境已经按照 构建Kubernetes云计算环境 准备就绪,现在具备服务器列表如下:

z-k8s高可用Kubernetes集群服务器列表

IP

主机名

说明

192.168.6.204

z-b-data-1

etcd+haproxy+keeplived

192.168.6.205

z-b-data-2

etcd+haproxy+keeplived

192.168.6.206

z-b-data-3

etcd+haproxy+keeplived

192.168.6.101

z-k8s-m-1

管控节点1

192.168.6.102

z-k8s-m-2

管控节点2

192.168.6.103

z-k8s-m-3

管控节点3

192.168.6.111

z-k8s-n-1

工作节点1(sr-iov)

192.168.6.112

z-k8s-n-2

工作节点2(sr-iov)

192.168.6.113

z-k8s-n-3

工作节点3(vgpu)

192.168.6.114

z-k8s-n-4

工作节点4(vgpu)

192.168.6.115

z-k8s-n-5

工作节点5

z-k8s 集群的管控节点和工作节点,全面安装 Docker containerd运行时(runtime) 运行时

  • 基础数据存储服务器 z-b-data-X :

    • 直接运行软件,不安装Docker容器化,也不运行Kubelet

    • 独立运行,不纳入K8s,仅作为基础服务提供( etcd - 分布式kv存储 )

  • 管控节点 z-k8s-m-X :

    • 安装containerd/Kubelet/Kubeadm

  • 工作节点 z-k8s-n-X :

    • 安装containerd/Kubelet/Kubeadm

备注

Kubernetes 1.24 移除了Docker直接支持,推荐使用 containerd运行时(runtime) 作为运行时,不仅可以节约资源而且更为安全(减少攻击面)。不过 containerd 文档资料较少,不如 Docker Atlas 有较为丰富的文档。例如,我 Docker btrfs 存储驱动 存储容器镜像,但是 containerd的btrfs 支持非常有限(不成熟),无法充分发挥 Btrfs 的优秀特性(实际依然是 OverlayFS文件系统 on btrfs),性能和稳定性不佳。

备注

我原先在 Kubernetes集群引导(单master) 部署 kubeadm 有详细步骤,本文是再次实践,以完成 Kubernetes集群引导(高可用)

安装 containerd运行时(runtime) 运行时(最新部署)

首先采用 containerd存储xfs文件系统 将containerd所使用的存储目录文件系统,由之前 Docker btrfs 存储驱动 切换为 XFS文件系统 :

  • 卸载 docker :

卸载docker.io
sudo systemctl stop docker
sudo systemctl stop docker.socket
sudo apt purge docker.io
sudo apt autoremove
将btrfs磁盘转换成xfs
sudo umount /var/lib/docker
sudo sed -i 's/^\/dev\/vdb1/#\/dev\/vdb1/g' /etc/fstab
sudo mkfs.xfs -f -n ftype=1 /dev/vdb1
echo "/dev/vdb1  /var/lib/containerd  xfs  defaults,uquota,pquota  0 1" | sudo tee -a /etc/fstab

sudo systemctl stop containerd
sudo mv /var/lib/containerd /var/lib/containerd.bak

sudo mkdir /var/lib/containerd
sudo mount /var/lib/containerd

sudo su -
(cd /var/lib/containerd.bak && tar cf - .) | (cd /var/lib/containerd && tar xf -)

sudo systemctl start containerd

然后采用 安装containerd官方执行程序 完成以下 containerd 安装:

安装最新v1.6.6 containerd官方二进制程序
wget https://github.com/containerd/containerd/releases/download/v1.6.6/containerd-1.6.6-linux-amd64.tar.gz
sudo tar Cxzvf /usr/local containerd-1.6.6-linux-amd64.tar.gz
安装containerd的systemd配置文件
sudo mkdir -p /usr/local/lib/systemd/system
sudo curl https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -o /usr/local/lib/systemd/system/containerd.service
sudo systemctl daemon-reload
sudo unlink /etc/systemd/system/containerd.service
sudo systemctl enable containerd

然后安装 runc :

安装runc
wget https://github.com/opencontainers/runc/releases/download/v1.1.3/runc.amd64
sudo install -m 755 runc.amd64 /usr/local/sbin/runc
安装cni-plugins
wget https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz
sudo mkdir -p /opt/cni/bin
tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.1.1.tgz
  • 执行以下命令创建containerd的默认网络配置(该步骤可以提供kubernetes集群节点自举所依赖的网络):

生成Kuberntes自举所需的默认containerd网络配置
sudo mkdir /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

备注

完成了 容器运行时(Container Runtimes) 安装后,需要进一步完成 kubeadm 中网络和cgroup配置,见下文

安装Docker运行时(归档)

  • 安装 容器运行时(Container Runtimes) Docker

    sudo apt update
    sudo apt upgrade -y
    
    sudo apt install docker.io -y
    
  • 将个人用户账号 huatai 添加到 docker 用户组方便执行docker命令:

    sudo usermod -aG docker $USER
    

docker存储驱动btrfs

VM数据盘( /var/lib/docker )准备

为了提升性能和存储效率,采用 Docker btrfs 存储驱动 ,所以执行:

备注

数据磁盘用于docker,所以命名是 <vm-name>.<disk-name> ,这里案例是用于 z-k8s-m-1 虚拟机的 docker 磁盘,所以命名为 z-k8s-m-1.docker

  • 创建磁盘完成后检查:

    virsh vol-list images_rbd
    

可以看到:

Name               Path
---------------------------------------------------
z-k8s-m-1          libvirt-pool/z-k8s-m-1
z-k8s-m-1.docker   libvirt-pool/z-k8s-m-1.docker
...
  • 准备设备XML文件

rbd磁盘设备XML
 1<disk type='network' device='disk'>
 2  <driver name='qemu' type='raw' cache='none' io='native'/>
 3  <auth username='libvirt'>
 4    <secret type='ceph' uuid='3f203352-fcfc-4329-b870-34783e13493a'/>
 5  </auth>
 6  <source protocol='rbd' name='libvirt-pool/z-k8s-m-1.docker'>
 7    <host name='192.168.6.204' port='6789'/>
 8    <host name='192.168.6.205' port='6789'/>
 9    <host name='192.168.6.206' port='6789'/>
10  </source>
11  <target dev='vdb' bus='virtio'/>
12</disk>
  • 添加磁盘文件:

    virsh attach-device z-k8s-m-1 z-k8s-m-1.docker-disk.xml --live --config
    
  • 此时在虚拟机 z-k8s-m-1 内部可以看到新磁盘设备 fdisk -l

    Disk /dev/vdb: 9.32 GiB, 10000000000 bytes, 19531250 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    

这个磁盘设备将用于docker

  • 脚本 vm_docker-disk.sh 帮助完成上述自动化过程

rbd磁盘(用于docker)注入脚本
 1#!/bin/env bash
 2
 3. /etc/profile
 4
 5vm=$1
 6suffix=docker #表示磁盘用途
 7rbd_pool="libvirt-pool"
 8hosts_csv=/home/huatai/github.com/cloud-atlas/source/real/private_cloud/priv_cloud_infra/hosts.csv
 9
10
11function init {
12
13    if [ ! -f docker-disk.xml ]; then
14
15cat > ${suffix}-disk.xml <<__XML__
16<disk type='network' device='disk'>
17  <driver name='qemu' type='raw' cache='none' io='native'/>
18  <auth username='libvirt'>
19    <secret type='ceph' uuid='3f203352-fcfc-4329-b870-34783e13493a'/>
20  </auth>
21  <source protocol='rbd' name='libvirt-pool/RBD_DISK'>
22    <host name='192.168.6.204' port='6789'/>
23    <host name='192.168.6.205' port='6789'/>
24    <host name='192.168.6.206' port='6789'/>
25  </source>
26  <target dev='vdb' bus='virtio'/>
27</disk>
28__XML__
29
30     fi
31
32     ip=`grep ",${vm}," $hosts_csv | awk -F, '{print $2}'`
33
34     if [ -z $ip ]; then
35         echo "You input vm name is invalid, can't find vm IP"
36         echo "Please check $hosts_csv"
37         exit 1
38     fi
39}
40
41function inject_vm_disk {
42    virsh vol-create-as --pool images_rbd --name ${vm}.${suffix} --capacity 10GB --allocation 10GB --format raw
43    cat ${suffix}-disk.xml | sed "s/RBD_DISK/${vm}.${suffix}/g" > ${vm}.${suffix}-disk.xml
44    virsh attach-device $vm ${vm}.${suffix}-disk.xml --live --config
45}
46
47init
48inject_vm_disk
  • 执行方法:

    ./vm_docker-disk.sh z-k8s-m-2
    

btrfs存储驱动

在虚拟机内部配置 Docker btrfs 存储驱动 :

  • 在虚拟机内部安装 btrfs 管理软件包 btrfs-progs

    sudo apt install btrfs-progs -y
    
  • 磁盘分区:

    sudo parted /dev/vdb mklabel gpt
    sudo parted -a optimal /dev/vdb mkpart primary 0% 100%
    
  • 创建 btrfs

    sudo mkfs.btrfs -f -L docker /dev/vdb1
    
  • 添加 /etc/fstab 配置:

    echo "/dev/vdb1    /var/lib/docker    btrfs   defaults,compress=lzo    0 1" | sudo tee -a /etc/fstab
    
  • 停止Docker:

    sudo systemctl stop docker.socket
    sudo systemctl stop docker
    
  • 备份 /var/lib/docker 目录内容,并清空该目录:

    sudo cp -au /var/lib/docker /var/lib/docker.bk
    sudo rm -rf /var/lib/docker/*
    
  • 挂载btrfs文件系统:

    sudo mount /var/lib/docker
    
  • 检查挂载:

    mount | grep vdb1
    
  • /var/lib/docker.bk 内容恢复回 /var/lib/docker/

    sudo su -
    cp -au /var/lib/docker.bk/* /var/lib/docker/
    
  • 创建 /etc/docker/daemon.json :

创建Docker btrfs配置脚本
 1cat > /etc/docker/daemon.json << EOF
 2{
 3  "exec-opts": ["native.cgroupdriver=systemd"],
 4  "log-driver": "json-file",
 5  "log-opts": {
 6    "max-size": "100m"
 7  },
 8  "storage-driver": "btrfs"
 9}
10EOF
  • 启动docker:

    sudo systemctl start docker
    
  • 检查docker 是否使用btrfs:

    docker info
    

转发IPv4和允许iptables查看bridged流量

  • 执行以下脚本配置 sysctl :

配置k8s节点iptalbes
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# sysctl params required by setup, params persist across reboots
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# Apply sysctl params without reboot
sudo sysctl --system

配置Cgroup v2

容器运行环境快速起步 详细说明了 Kubernetes 可以使用 Control Group v2 来更精细化管控资源。配置方法是在内核参数传递 systemd.unified_cgroup_hierarchy=1 。当时我配置采用修订 /etc/default/grubGRUB_CMDLINE_LINUX 行添加上述参数,然后再执行 sudo update-grub 更新启动。

另外一种常用的修订内核参数方法是使用 grubby修改内核参数 工具:

配置k8s节点cgroup v2
sudo apt install grubby -y
sudo grubby --update-kernel=ALL \
    --args="systemd.unified_cgroup_hierarchy=1"

配置 Systemd进程管理器 cgroup驱动

配置containerd的runc使用systemd cgroup驱动
[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    [plugins."io.containerd.grpc.v1.cri".containerd]
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          ...
          runtime_type = "io.containerd.runc.v2"
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            ...
            SystemdCgroup = true

重启 containerd

sudo systemctl restart containerd

参考