【K8S】如何基于kubeadm搭建离线K8S集群
背景:
因为需要在处于安全网络内(与外界网络不通)的机器上搭建kubernetes集群, 故而部分需要network validate的开源K8S包(例如microk8s)无法正常安装。本文将详细介绍基于开源工具kubeadm的稳定的offline installation方法。
你将需要:
一台可以联网的机器,用于下载需要的安装包。
两台或更多台无法连接公网的机器,用于安装Kubernetes。其中一台作为主节点primary node, 其他一台或几台作为secondary nodes,离线机器间网络互通。
注意:
本文中工具包下载的路径为联网机器可读写,离线机器可读,故不涉及联网/离线机器间的文件传输。如果不符合该条件,则需手动将联网机器上下载的包通过移动介质拷贝至离线机器。
环境:
CentOS 7
gcc 4.8.5
一、在联网机器上下载相关安装包
1. 下载docker相关包
mkdir -p $download_dir/docker
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yumdownloader --destdir=$download_dir/docker --resolve docker-ce
sudo yumdownloader --destdir=$download_dir/docker --resolve docker-ce-cli
sudo yumdownloader --destdir=$download_dir/docker --resolve containerd.io
sudo yumdownloader --destdir=$download_dir/docker --resolve container-selinux
sudo yumdownloader --destdir=$download_dir/docker --resolve docker-ce-rootless-extras
sudo yumdownloader --destdir=$download_dir/docker --resolve docker-scan-plugin
sudo yumdownloader --destdir=$download_dir/docker --resolve slirp4netns
sudo yumdownloader --destdir=$download_dir/docker --resolve fuse-overlayfs
sudo yumdownloader --destdir=$download_dir/docker --resolve libcgroup
2. 下载Kubernetes相关包
mkdir -p $download_dir/kubernetes_utilities
cd $download_dir/kubernetes_utilities
sudo yumdownloader --destdir=$download_dir/kubernetes_utilities --resolve libnetfilter_cttimeout
sudo yumdownloader --destdir=$download_dir/kubernetes_utilities --resolve libnetfilter_cthelper
sudo yumdownloader --destdir=$download_dir/kubernetes_utilities --resolve kubelet
sudo yumdownloader --destdir=$download_dir/kubernetes_utilities --resolve kubeadm
sudo yumdownloader --destdir=$download_dir/kubernetes_utilities --resolve kubectl
wget https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/f/fuse3-libs-3.6.1-2.el7.x86_64.rpm -P download_dir/kubernetes_utilities
3. 下载kubeadm所需Kubernetes 镜像
(1)在联网机器上(已安装kubeadm)运行如下指令,返回需要的镜像列表
kubeadm config images list
返回结果:
k8s.gcr.io/kube-apiserver:v1.22.4
k8s.gcr.io/kube-controller-manager:v1.22.4
k8s.gcr.io/kube-scheduler:v1.22.4
k8s.gcr.io/kube-proxy:v1.22.4
k8s.gcr.io/pause:3.5
k8s.gcr.io/etcd:3.5.0-0
k8s.gcr.io/coredns/coredns:v1.8.4
(2)根据得到的镜像列表下载kubernetes镜像
mkdir -p $download_dir/kubernetes_images
cd $download_dir/kubernetes_images
docker pull k8s.gcr.io/<image_name>
docker save k8s.gcr.io/<image_name> <image_name_without_colon>.tar
例:
docker pull k8s.gcr.io/pause:3.5
docker save k8s.gcr.io/pause:3.5 > pause_3.5.tar
4. 下载Kubernetes网络相关包
mkdir -p $download_dir/kubernetes_network
cd $download_dir/kubernetes_network
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
打开kube-flannel.yml文件,找到flannel和mirrored_flannelcni-flannel-cni-plugin镜像版本。例如,如下字符串表示对应flannel版本为v0.15.1,mirrored_flannelcni-flannel-cni-plugin版本为1.0.0
image:quay.io/coreos/flannel:v0.15.1
image:rancher/mirrored_flannelcni-flannel-cni-plugin:v1.0.0
找到flannel版本号后下载对应的flannel和mirrored_flannelcni-flannel-cni-plugin镜像
docker pull quay.io/coreos/flannel:v0.15.1
docker save quay.io/coreos/flannel:v0.15.1 > $download_dir/kubernetes_network/flannel_v0.15.1.tar
docker pull rancher/mirrored_flannelcni-flannel-cni-plugin:v1.0.0
docker save rancher/mirrored_flannelcni-flannel-cni-plugin:v1.0.0 > $download_dir/kubernetes_network/mirrored_flannelcni-flannel-cni-plugin_v1.0.0.tar
二、在离线机器上安装之前下载的相关包
在离线集群的所有机器上安装docker包并启动docker
sudo yum localinstall -y --disablerepo=* $download_dir/docker/*
#enable&start docker
sudo systemctl enable docker
sudo systenctl start docker
2. 在离线集群的所有机器上安装Kubernetes utilities并启动kubelet
sudo yum localinstall -y --disablerepo=* $download_dir/kubernetes_utilities/*.rpm
#enable and start kubelet
sudo systemctl enable kubelet
sudo systemctl start kubelet
3. 在离线集群的所有机器上加载kubeadm所需的Kubernetes镜像并重启docker
sudo docker load < kube-apiserver_v1.22.4.tar
sudo docker load < kube-controller-manager_v1.22.4.tar
sudo docker load < kube-scheduler_v1.22.4.tar
sudo docker load < kube-proxy_v1.22.4.tar
sudo docker load < pause_3.5.tar
sudo docker load < etcd_3.5.0-0.tar
sudo docker load < coredns_v1.8.4.tar
sudo systemctl restart docker
4. 在离线集群的所有机器上加载Kubernetes network镜像并重启docker
cd $download_dir/kubernetes_network
sudo docker load < flannel_v0.15.1.tar
sudo docker load < mirrored_flannelcni-flannel-cni-plugin_v1.0.0.tar
sudo systemctl restart docker
三、部署Kubernetes集群
1. 关闭离线集群的所有机器的swap
sudo swapoff -a
2. 设置net.bridge.bridge-nf-call-iptables
确保离线集群所有机器的net.bridge.bridge-nf-call-iptables配置选项都设为1
cat << EOF /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
3. 在离线集群的primary node上执行如下命令以创建一个新的kubernetes集群
kubeadm init --pod-network-cidr=10.244.0.0/16
4. 在离线集群的所有机器上执行如下指令以配置kubectl管理集群
mkdir -p $HOME/.kube
sudo chmod 606 /etc/kubernetes/admin.conf
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
5. 在离线集群的primary node上初始化flannel网络
初始化完成后使用'kubectl get pods'指令查看初始化网络后所有pods是否都处于Running状态,全部处于Running状态则初始化网络成功。
kubectl apply -f $download_dir/kubernetes_network/kube-flannel.yml
kubectl get pods --all-namespaces
6. 在离线集群的primary node上打印secondary node加入集群所需带有token的指令
kubeadm token create --print-join-command
7. 在离线集群的所有secondary nodes上运行上一步中得到的结果以将secondary node加入cluster
类似如下指令
kubeadm join --token <token> <primary_ip>:<primary_port> --discovery-token-ca-cert-hash sha256:<hash>
8. 在离线集群的primary node上运行如下指令,以验证secondary nodes已成功加入cluster
如若加入成功,则所有cluster节点应处于Ready状态
kubectl get nodes
至此,离线Kubernetes cluster搭建完成。
常见异常及解决:
1. ‘kubeadm init’抛出错误:The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz" 127.0.0.1:10248: connect: connection refused
解决:在离线集群的所有节点上运行如下指令
sudo mkdir -p /etc/docker
sudo cat << EOF|sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts":{
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
sudo system restart dockers