云原生··By/蜜汁炒酸奶

使用 Kubeadm 安装基于 containerd 的 Kubernetes 集群

本次直接使用了 containerd 作为运行时,且为一主二从,与之前《使用 Kubeadm 安装 Kubernetes 集群》中使用docker作为运行时的Master单节点部署稍微有些不同。

1 环境

服务器要求:

  • 建议最小硬件配置:2核CPU、2G内存、20G硬盘
  • 服务器可以访问外网,不然需要提前导入所需依赖以及相关镜像,操作会比较麻烦,这里不再提供导入方式。

本文中的服务器配置是经过pve虚拟化后的,具体配置见下面【服务器规划】。本系列文章中的实验均基于本文中的环境,由于后续会涉及关于 flannel 、 calico 、 cilium 等相关网络模型的讨论,本文不会涉及最后的 cni 的安装。

1.1 软件环境

软件 版本
服务器系统 Ubuntu 22.04.2 LTS 服务器版
Kubernetes 1.26.3-00
containerd 1.7.0-linux-amd64
runc v1.1.4
cni-plugins linux-amd64-v1.2.0

1.2 服务器规划

本系列中将主节点称为 Master 节点,子节点称为 Worker 节点。

主机名 IP 类型 说明
k8s-master 192.168.100.9 Master 节点 2核CPU、4G内存、32G硬盘
k8s-node1 192.168.100.17 Worker 节点 2核CPU、4G内存、32G硬盘
k8s-node2 192.168.100.10 Worker 节点 4核CPU、4G内存、40G硬盘

2 准备工作【所有节点】

为了方便环境搭建,直接通过 su 进入管理员模式,如果不知道密码,可通过 sudo passwd root 重置 root 密码。

如果需要查看相关端口,可安装 net-tools 并使用其命令查看。

# 安装
$ apt install net-tools
# 查看端口
$ netstat -tunlp
1
2
3
4

2.1 转发 IPv4 并让 iptables 看到桥接流量

  1. 执行如下命令进行配置:
$ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

$ sudo modprobe overlay
$ sudo modprobe br_netfilter

# 设置所需的 sysctl 参数,参数在重新启动后保持不变
$ 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

# 应用 sysctl 参数而不重新启动
$ sudo sysctl --system
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  1. 执行如下命令进行验证:
# 确认 br_netfilter 和 overlay 模块被加载
$ lsmod | grep br_netfilter
$ lsmod | grep overlay

# 确认 net.bridge.bridge-nf-call-iptables、net.bridge.bridge-nf-call-ip6tables 和 net.ipv4.ip_forward 系统变量在你的 sysctl 配置中被设置为 1
$ sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
1
2
3
4
5
6

lsmodlsmod

sysctl 配置中被设置为 1

2.2 关闭swap

# 修改后需要重新使其生效
$ vim /etc/fstab 
# 检测效果
$ sudo free -m
1
2
3
4

更多实现可见之前文章《Linux关闭swap》

2.3 服务器时间校准

统一时间,保证三台服务器时间一致

# 修改timezone
$ cp -a /usr/share/zoneinfo/Etc/GMT-8  /etc/localtime
# 展示当前的timezone
$ date -R
# 安装 ntpdate
$ apt-get install ntpdate
# 时间校准
$ ntpdate ntp1.nim.ac.cn
1
2
3
4
5
6
7
8

2.4 添加本地映射

$ cat >> /etc/hosts << EOF
192.168.100.9 k8s-master
192.168.100.17 k8s-node1
192.168.100.10 k8s-node2
EOF
1
2
3
4
5

3 安装容器进行时 containerd 【所有节点】

3.1 安装 containerd

可通过 https://github.com/containerd/containerd/releases 获取最新版本以及历史版本。

# 下载
$ wget https://github.com/containerd/containerd/releases/download/v1.7.0/containerd-1.7.0-linux-amd64.tar.gz
# 解压
$ tar Cxzvf /usr/local containerd-1.7.0-linux-amd64.tar.gz
1
2
3
4

3.2 配置 systemd

# 创建目录
$ mkdir -p /usr/local/lib/systemd/system/
# 进入新目录
$ cd /usr/local/lib/systemd/system/
# 下载
$ wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
# 验证
$ systemctl status containerd
1
2
3
4
5
6
7
8

可能出现如下异常:

Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|::|:443… failed: Connection refused.

使用网址 https://www.ipaddress.com/ 获得raw.githubusercontent.com网站的ip地址 185.199.108.133,执行如下命令即可:

$ cat >> /etc/hosts << EOF
185.199.108.133 raw.githubusercontent.com
EOF
1
2
3

3.3 安装 runc

可通过 https://github.com/opencontainers/runc/releases 获取最新版本以及历史版本。

# 下载
$ wget https://github.com/opencontainers/runc/releases/download/v1.1.4/runc.amd64
# 安装
$ install -m 755 runc.amd64 /usr/local/sbin/runc
1
2
3
4

3.4 安装 CNI plugins

可通过 https://github.com/containernetworking/plugins/releases 获取最新版本以及历史版本。

# 下载
$ wget https://github.com/containernetworking/plugins/releases/download/v1.2.0/cni-plugins-linux-amd64-v1.2.0.tgz
# 创建目录
$ mkdir -p /opt/cni/bin
# 解压至新目录
$ tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.2.0.tgz
1
2
3
4
5
6

3.5 containerd 配置

containerd 需要在默认配置文件/etc/containerd/config.toml 中做一些调整,在修改之前需要先生成该文件,具体过程见下文。

3.5.1 生成默认配置

# 创建新目录
$ mkdir -p  /etc/containerd/
# 生成默认配置
$ containerd config default > /etc/containerd/config.toml
1
2
3
4

3.3.2 配置 systemd cgroup 驱动

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    ...
    SystemdCgroup = true
1
2
3
4
5

配置 systemd cgroup 驱动

3.3.3 重载沙箱(pause)镜像

[plugins."io.containerd.grpc.v1.cri"]
  sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9" 
1
2

以上配置完成后,执行 systemctl restart containerd 使其生效。

重载沙箱(pause)镜像

3.6 设置 crictl 默认连接

crictl 默认连接到 unix:///var/run/dockershim.sock,改为 containerd

$ cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10
# debug: true
debug: false
EOF
1
2
3
4
5
6
7

4 安装 kubeadm 【所有节点】

这里简单记录,更多详细说明可参考之前文章《使用 Kubeadm 安装 Kubernetes-docker版》

  1. 更新apt包索引并安装使用 Kubernetes apt 仓库所需要的包
# 更新
$ sudo apt-get update
# 安装
$ sudo apt-get install -y apt-transport-https ca-certificates curl
1
2
3
4
  1. 下载 阿里云 公开签名秘钥
$ curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
1
  1. 添加 Kubernetes apt 仓库:
$ sudo tee /etc/apt/sources.list.d/kubernetes.list <<-'EOF'
deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
EOF
1
2
3
  1. 更新 apt 包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本:
# 更新
$ sudo apt-get update
# 安装
$ apt-get install -y kubelet=1.26.3-00 kubeadm=1.26.3-00 kubectl=1.26.3-00
# 锁定版本
$ sudo apt-mark hold kubelet kubeadm kubectl
1
2
3
4
5
6

5 初始化控制平面节点【Master 节点】

在 192.168.100.90(Master节点)执行 kubeadm init

$ kubeadm init \
  --apiserver-advertise-address=192.168.100.9 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.26.3 \
  --service-cidr=10.33.0.0/12 \
  --pod-network-cidr=10.222.0.0/16 \
  --cri-socket=unix:///var/run/containerd/containerd.sock
1
2
3
4
5
6
7

5.1 参数说明

  • --apiserver-advertise-address 集群通告地址
  • --image-repository 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址
  • --kubernetes-version K8s版本,与上面安装的一致
  • --service-cidr 集群内部虚拟网络,Pod统一访问入口
  • --pod-network-cidr Pod网络,与后续部署的CNI网络组件yaml中保持一致
  • --cri-socket 指定cri-dockerd接口
  • --ignore-preflight-errors=all 可选,忽略运行时的错误,例如执行时存在[ERROR NumCPU]和[ERROR Swap]

5.2 token 生成

初始化完成后,最后会输出一个join命令,该命令将在子节点使用,但默认生成的这个 token 只有24小时有效期,过期后需要重新生成。

可以通过 kubeadm token create --print-join-command --ttl 0 重新生成一个永久的 token,通过 kubeadm token list 可列出服务器上的引导令牌。

kubeadm token list

5.3 配置非 root 用户运行

要使非 root 用户可以运行 kubectl,运行以下命令:

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

5.3 查看node

当所有 Worker 节点增加后,可在 Master 节点通过 kubectl get nodes,查看当前集群中所有节点。

查看节点

截图中处于 NotRedy 是由于尚未安装 cni,可根据需要自行安装。

6 加入工作节点 【Worker 节点】

在 192.168.7.17 和 192.168.100.10(Node1和Node2)执行之前的 kubeadm join 命令,从而加入主节点。

kubeadm join 192.168.100.9:6443 --token mgxcnk.gcufxeoarkh13vix --discovery-token-ca-cert-hash sha256:1b820c999065d19c363591a098f3ee0f201b4722c3b1d837bf490348c654e2c6 
1

kubeadm join

如果子节点曾经执行过 kubeadm join 命令,再次执行时会因文件已经成和端口已占用报 Port 10250 is in use相关异常,此时需要先执行 kubeadm reset,再执行 kubeadm join

kubeadm join多次执行且未reset导致报错

7 参考资料

  1. containerd-getting-started.md
  2. 容器运行时#containerd
  3. 使用 crictl 对 Kubernetes 节点进行调试
  4. 安装 kubeadm
  5. K8s Token 过期解决方案(Kubeadm)
预览
Loading comments...
2 条评论
  • W

    k8s非常好资源,3台机器就不少钱

    • W

      回复 @harries: 是的,所以一直感觉对中小型公司来说不一定是最优解,根据自己实际情况量力而行。

example
预览