Ubuntu 20.04 下部署 k8s v1.22.7 集群

介绍

虽然是一篇 k8s 的部署文,但也充满了曲折。归其原因也是基础一般。 本文并未涉及 k8s 多主高可用,可参考其它文章通过 ipvs 来实现。

首先通过上次的文章组网 通过 Netmaker 配置 WireGuard 跨 VPC 组网,组网完成部署 k8s、k3s 都可以,我这三台小弱鸡更适合 k3s。

hostname外网ip内网ipwg ipos
ten-162.234.xxx.xxx172.21.0.110.1.0.1Ubuntu 20.04
ten-282.156.xxx.xxx10.0.8.110.1.0.2Ubuntu 20.04
ten-381.70.xxx.xxx10.0.24.110.1.0.3Ubuntu 20.04

先说下为何换到了 Ubuntu,之前在 CentOS 7.6 下已经组网完成且部署完 k8s ,使用中发现容器经常报这个错 failed to write 1 to memory.kmem.limit_in_bytes xxxx memory.kmem.limit_in_bytes: operation not supported,内存指令相关错误。

尝试将容器内存资源限制删除,该错误可消失恢复正常。 这也不是长久之计,网上参考别人经验,我当时内核为 5.16,可以降级内核解决,但是我要用 WireGuard 低版本内核就使不了。

索性换了系统算了,且 Ubuntu 20.045.4 内核已经包含了 WireGuard,而且也没见人说 Debian 系有 memory.kmem.limit_in_bytes 的问题。

memory.kmem.limit_in_bytes 报错参考

安装部署

  • k8s 版本 为 v1.22.7
  • 容器运行时采用 containerd
  • 网络组件采用 calico

所有节点

修改各个节点 hostname

1
$ hostnamectl set-hostname xxx

安装脚本,可以保存为 .sh 脚本直接跑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 配置各节点 host
cat <<EOF | sudo tee -a /etc/hosts
10.1.0.1 ten-1
10.1.0.2 ten-2
10.1.0.3 ten-3
EOF

swapoff -a
rm -f /swap.img

# --- containerd 安装 ---
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/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

cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

sudo sysctl --system

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# sandbox 默认会下 k8s.gcr.io 的,国内网络会有问题,替换下,参考下面问题排查
sed -i 's#sandbox_image = ".*"#sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.5"#g' /etc/containerd/config.toml
systemctl restart containerd


# --- kubeadm 安装 ---
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

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet=1.22.7-00 kubeadm=1.22.7-00 kubectl=1.22.7-00
sudo apt-mark hold kubelet kubeadm kubectl

master 节点

kubeadm.yaml 配置如下,注意修改 controlPlaneEndpointadvertiseAddress

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
networking:
podSubnet: 100.64.0.0/10
kubernetesVersion: v1.22.7
controlPlaneEndpoint: "ten-1:6443"
imageRepository: registry.aliyuncs.com/google_containers
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 10.1.0.1
nodeRegistration:
criSocket: /run/containerd/containerd.sock

calico.yaml 配置直接下载

1
$ wget https://projectcalico.docs.tigera.io/manifests/calico.yaml
1
2
3
4
5
6
7
# --- 集群初始化 ---
kubeadm init --config ./kubeadm.yaml
mkdir ~/.kube
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl taint nodes --all node-role.kubernetes.io/master-
kubectl apply -f ./calico.yaml

work 节点

join 命令替换成 kubeadm init 执行成功时输出的。

1
2
3
4
5
6
7
# --- 加入集群 ---
scp root@ten-1:/etc/kubernetes/admin.conf /etc/kubernetes/admin.conf
mkdir ~/.kube
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubeadm join ten-1:6443 --token 7hepbs.ub5d984rmxc5v3pc \
--discovery-token-ca-cert-hash sha256:981348138871c4eed993db7664a7663ec9b0e9e6fe2d038a266591174570284c

问题处理

集群初始化时,会卡在 This can take up to 4m0s

查看 kubelet 日志 journalctl -xeu kubelet 大量报错

1
2
"Error getting node" err="node \"ten-1\" not found"
"Error getting node" err="node \"ten-1\" not found"

但本机上 hostname 能 ping 通。再看容器日志 journalctl -xeu containerd
journalctl -xeu containerd
有个镜像没下下来超时,奇怪不是改了仓库地址。

看下需要的镜像

1
2
3
4
5
6
7
8
$ kubeadm config images list --kubernetes-version=v1.22.7
k8s.gcr.io/kube-apiserver:v1.22.7
k8s.gcr.io/kube-controller-manager:v1.22.7
k8s.gcr.io/kube-scheduler:v1.22.7
k8s.gcr.io/kube-proxy:v1.22.7
k8s.gcr.io/pause:3.4.1
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns/coredns:v1.8.0

并没有 pause:3.5。看看别的配置文件,发现 /etc/containerd/config.tomlsandbox_image 用到了。

1
sandbox_image = "k8s.gcr.io/pause:3.5"

直接改成 registry.aliyuncs.com/google_containers/pause:3.5 也可以手动从阿里云下载,打 tag。

下载 nerdctl 让 containerd 用起来像 docker 一样。

1
2
nerdctl pull registry.aliyuncs.com/google_containers/pause:3.5 --namespace "k8s.io"
nerdctl tag registry.aliyuncs.com/google_containers/pause:3.5 k8s.gcr.io/pause:3.5 --namespace "k8s.io"

其它命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

kubectl get all --all-namespaces

# 手动下载镜像
kubeadm config images pull --kubernetes-version=v1.22.7 --image-repository registry.aliyuncs.com/google_containers

# 查看配置模版
kubeadm config print init-defaults

# 重置集群
kubeadm reset

# 查看可安装 kube 版本
apt-cache madison kubelet

# 卸载 kube
apt-mark unhold kubeadm kubelet kubectl
apt-get remove -y kubelet=1.22.7-00 kubeadm=1.22.7-00 kubectl=1.22.7-00

# 卸载 docker containerd
apt-get purge docker-ce docker-ce-cli containerd.io

# 查看已有镜像
nerdctl images --namespace "k8s.io"

参考