k8s官宣要把内置的docker支持剥离出去,所以本次集群部署采用的容器技术是containerd,毕竟相对于docker来说containerd的调用链更为简洁,如果不是k8s内置docker的支持,我觉得以后越来越多业务会倾向与使用后者吧,过程遇到了不少的坑,总结一下(我全程使用root操作的,如果你不是,最好执行的时候加上sudo)。
系统版本:centos7.6
k8s版本:1.23.4
containerd版本: 1.4.12
*** 可以直接跟着以下步骤直接复制命令执行,我的机器上面试过是没问题的
更换源
将默认的yum源更换为国内的,我用的是阿里的
# 1、安装wget
yum install -y wget
# 2、下载CentOS 7的repo文件
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
或者
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# 3、更新镜像源
清除缓存:yum clean all
生成缓存:yum makecache
关闭SElinux
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
禁用防火墙
sudo systemctl stop firewalld
sudo systemctl disable --now firewalld
添加 kubernetes.repo 文件和一些必要工具
sudo echo -e "[kubernetes] \nname=Kubernetes \nbaseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ \nenabled=1 \ngpgcheck=1 \nrepo_gpgcheck=1 \ngpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg \nexclude=kubelet kubeadm kubectl" > /etc/yum.repos.d/kubernetes.repo
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install centos-release-openstack-rocky -y
安装 kubelet kubeadm kubectl
sudo yum install -y kubeadm-1.23.4 kubectl-1.23.4 kubelet-1.23.4 --disableexcludes=kubernetes
安装containerd
sudo yum install -y wget containerd.io openvswitch* certbot
mkdir -p /etc/containerd
cd /home
wget https://mirror.ghproxy.com/https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.23.0/crictl-v1.23.0-linux-amd64.tar.gz
tar zxf crictl-v1.23.0-linux-amd64.tar.gz
mv crictl /usr/local/bin/
rm -rf crictl-v1.23.0-linux-amd64.tar.gz
# 安装前配置
echo "overlay" > /etc/modules-load.d/containerd.conf
echo "br_netfilter" >> /etc/modules-load.d/containerd.conf
sudo modprobe overlay
sudo modprobe br_netfilter
# 设置必需的 sysctl 参数,这些参数在重新启动后仍然存在。
echo "net.bridge.bridge-nf-call-iptables = 1" > /etc/sysctl.d/99-kubernetes-cri.conf
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.d/99-kubernetes-cri.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.d/99-kubernetes-cri.conf
# Apply sysctl params without reboot
sudo sysctl --system
sudo containerd config default > /etc/containerd/config.toml
sed -i "s/k8s.gcr.io/registry.cn-hangzhou.aliyuncs.com\/google_containers/g" /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
echo "KUBELET_EXTRA_ARGS=--cgroup-driver=systemd" > /etc/sysconfig/kubelet
echo "runtime-endpoint: unix:///run/containerd/containerd.sock" > /etc/crictl.yaml
echo "image-endpoint: unix:///run/containerd/containerd.sock" >> /etc/crictl.yaml
echo "timeout: 10" >> /etc/crictl.yaml
echo "debug: false" >> /etc/crictl.yaml
初始化kubeadm配置文件
mkdir /etc/kubernetes
echo -e "apiVersion: kubeadm.k8s.io/v1beta3" > /etc/kubernetes/kubeadm.yaml
echo -e "kind: InitConfiguration" >> /etc/kubernetes/kubeadm.yaml
echo -e "bootstrapTokens:" >> /etc/kubernetes/kubeadm.yaml
echo -e " - ttl: \"0\"" >> /etc/kubernetes/kubeadm.yaml
echo -e "---" >> /etc/kubernetes/kubeadm.yaml
echo -e "apiVersion: kubeadm.k8s.io/v1beta3" >> /etc/kubernetes/kubeadm.yaml
echo -e "kind: ClusterConfiguration" >> /etc/kubernetes/kubeadm.yaml
echo -e "networking:" >> /etc/kubernetes/kubeadm.yaml
echo -e " podSubnet: \"10.244.0.0/16\"" >> /etc/kubernetes/kubeadm.yaml
echo -e "kubernetesVersion: \"v1.23.4\"" >> /etc/kubernetes/kubeadm.yaml
echo -e "imageRepository: \"registry.cn-hangzhou.aliyuncs.com/google_containers\"" >> /etc/kubernetes/kubeadm.yaml
到这里环境初始化完毕,开始安装kubernetes
开机启动kubelet
sudo systemctl restart kubelet
sudo systemctl enable kubelet
k8s要求关闭swap
sudo swapoff -a && sysctl -w vm.swappiness=0
sudo sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
允许 iptables 检查桥接流量
echo "1" > /proc/sys/net/bridge/bridge-nf-call-iptables
echo "1" > /proc/sys/net/ipv4/ip_forward
根据上面配置的kubeadm.yaml文件启动集群
kubeadm init --config /etc/kubernetes/kubeadm.yaml
等执行完毕后,最后一行会输出一行命令,类似于这样:
kubeadm join xxxxxxxxxxxxxxxxx
这一行要记住,后续的node节点加入集群需要用到,如果没了也可以用kubeadm token create --print-join-command
来重新生成
然后为了正常使用kubectl需要执行
rm -rf $HOME/.kube
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
iptables -P FORWARD ACCEPT
应用cni
kubectl apply -f https://docs.projectcalico.org/archive/v3.17/manifests/calico.yaml
然后看看整个系统正不正常
kubectl get pod -A
写在最后:过程中遇到了一些问题:
kubernetes默认拉取镜像的地址是k8s.gcr.io
,虽然上面我已经把绝大部分的前缀替换成了registry.cn-hangzhou.aliyuncs.com/google_containers
,但是有时候依然会遇到这个相关的错误,如果系统关键性pod启动不了可以看看日志是不是因为从k8s.gcr.io
上面拉镜像拉不下来,如果有的话,可以这么做:
比如现在有个pod需要k8s.gcr.io/pause:3.2
这个镜像,可以执行以下命令(仅列举使用crictl作为运行时)
# 拉取镜像
crictl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
# 修改tag
ctr -n=k8s.io i tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 k8s.gcr.io/pause:3.2
大部分的镜像都可以直接使用 registry.cn-hangzhou.aliyuncs.com/google_containers
来替换 k8s.gcr.io
获取到,如果不行的话,可以试试用下面的去替换:
k8s.gcr.io ---> lank8s.cn
gcr.io --> gcr.lank8s.cn
# 如果启动过程中总是显示 kubelet 有问题,
systemctl status kubelet
如果显示是active,就再接着
journalctl -xeu kubelet
看一下日志里面报的什么错误,保证kubelet正常运行的状态,使用ps命令查看应该是
ps -ef | grep kubelet
/usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf
--kubeconfig=/etc/kubernetes/kubelet.conf
--config=/var/lib/kubelet/config.yaml
--container-runtime=remote
--container-runtime-endpoint=/run/containerd/containerd.sock --cgroup-driver=systemd
有问题的话去看看这里面显示的那几个配置文件和上面要求的是不是一样,还有最后面的那三个参数有没有。
没有的话,去 /etc/sysconfig/kubelet 文件中写入
KUBELET_EXTRA_ARGS=--cgroup-driver=systemd --container-runtime=remote --container-runtime-endpoint=/run/containerd/containerd.sock
然后重启kubelet
如果 kubelet 根本就没有正常启动,首先看看是不是依赖的镜像出了问题,本地有没有,版本对不对,能不能正常启动。