介绍
虽然是一篇 k8s 的部署文,但也充满了曲折。归其原因也是基础一般。 本文并未涉及 k8s 多主高可用,可参考其它文章通过 ipvs 来实现。
首先通过上次的文章组网 通过 Netmaker 配置 WireGuard 跨 VPC 组网,组网完成部署 k8s、k3s 都可以,我这三台小弱鸡更适合 k3s。
| hostname | 外网ip | 内网ip | wg ip | os |
|---|---|---|---|---|
| ten-1 | 62.234.xxx.xxx | 172.21.0.1 | 10.1.0.1 | Ubuntu 20.04 |
| ten-2 | 82.156.xxx.xxx | 10.0.8.1 | 10.1.0.2 | Ubuntu 20.04 |
| ten-3 | 81.70.xxx.xxx | 10.0.24.1 | 10.1.0.3 | Ubuntu 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.04 的 5.4 内核已经包含了 WireGuard,而且也没见人说 Debian 系有 memory.kmem.limit_in_bytes 的问题。
memory.kmem.limit_in_bytes 报错参考
- https://kubesphere.com.cn/forum/d/6677-310516ks
- https://en.pingcap.com/blog/try-to-fix-two-linux-kernel-bugs-while-testing-tidb-operator-in-k8s/
安装部署
- k8s 版本 为 v1.22.7
- 容器运行时采用
containerd - 网络组件采用
calico
所有节点
修改各个节点 hostname
$ hostnamectl set-hostname xxx
安装脚本,可以保存为 .sh 脚本直接跑。
# 配置各节点 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 配置如下,注意修改 controlPlaneEndpoint、advertiseAddress
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 配置直接下载
$ wget https://projectcalico.docs.tigera.io/manifests/calico.yaml
# --- 集群初始化 ---
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 执行成功时输出的。
# --- 加入集群 ---
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 大量报错
"Error getting node" err="node \"ten-1\" not found"
"Error getting node" err="node \"ten-1\" not found"
但本机上 hostname 能 ping 通。再看容器日志 journalctl -xeu containerd
有个镜像没下下来超时,奇怪不是改了仓库地址。
看下需要的镜像
$ 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.toml 中 sandbox_image 用到了。
sandbox_image = "k8s.gcr.io/pause:3.5"
直接改成 registry.aliyuncs.com/google_containers/pause:3.5 也可以手动从阿里云下载,打 tag。
下载 nerdctl 让 containerd 用起来像 docker 一样。
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"
其它命令
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"