vlambda博客
学习文章列表

【K8S】如何基于kubeadm搭建离线K8S集群

背景:

因为需要在处于安全网络内(与外界网络不通)的机器上搭建kubernetes集群, 故而部分需要network validate的开源K8S包(例如microk8s)无法正常安装。本文将详细介绍基于开源工具kubeadm的稳定的offline installation方法。


你将需要:

  1. 一台可以联网的机器,用于下载需要的安装包。

  2. 两台或更多台无法连接公网的机器,用于安装Kubernetes。其中一台作为主节点primary node, 其他一台或几台作为secondary nodes,离线机器间网络互通。


注意:

本文中工具包下载的路径为联网机器可读写,离线机器可读,故不涉及联网/离线机器间的文件传输。如果不符合该条件,则需手动将联网机器上下载的包通过移动介质拷贝至离线机器。


环境:

CentOS 7

gcc 4.8.5




一、在联网机器上下载相关安装包

1. 下载docker相关包

mkdir -p $download_dir/dockersudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.reposudo yumdownloader --destdir=$download_dir/docker --resolve docker-cesudo yumdownloader --destdir=$download_dir/docker --resolve docker-ce-clisudo yumdownloader --destdir=$download_dir/docker --resolve containerd.iosudo yumdownloader --destdir=$download_dir/docker --resolve container-selinuxsudo yumdownloader --destdir=$download_dir/docker --resolve docker-ce-rootless-extrassudo yumdownloader --destdir=$download_dir/docker --resolve docker-scan-pluginsudo yumdownloader --destdir=$download_dir/docker --resolve slirp4netnssudo yumdownloader --destdir=$download_dir/docker --resolve fuse-overlayfssudo yumdownloader --destdir=$download_dir/docker --resolve libcgroup


2. 下载Kubernetes相关包

mkdir -p $download_dir/kubernetes_utilitiescd $download_dir/kubernetes_utilities
sudo yumdownloader --destdir=$download_dir/kubernetes_utilities --resolve libnetfilter_cttimeoutsudo yumdownloader --destdir=$download_dir/kubernetes_utilities --resolve libnetfilter_cthelpersudo yumdownloader --destdir=$download_dir/kubernetes_utilities --resolve kubeletsudo yumdownloader --destdir=$download_dir/kubernetes_utilities --resolve kubeadmsudo yumdownloader --destdir=$download_dir/kubernetes_utilities --resolve kubectlwget 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.4k8s.gcr.io/kube-controller-manager:v1.22.4k8s.gcr.io/kube-scheduler:v1.22.4k8s.gcr.io/kube-proxy:v1.22.4k8s.gcr.io/pause:3.5k8s.gcr.io/etcd:3.5.0-0k8s.gcr.io/coredns/coredns:v1.8.4

(2)根据得到的镜像列表下载kubernetes镜像

mkdir -p $download_dir/kubernetes_imagescd $download_dir/kubernetes_imagesdocker 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.5docker save k8s.gcr.io/pause:3.5 > pause_3.5.tar


4. 下载Kubernetes网络相关包

mkdir -p $download_dir/kubernetes_networkcd $download_dir/kubernetes_networkwget 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.1image:rancher/mirrored_flannelcni-flannel-cni-plugin:v1.0.0


找到flannel版本号后下载对应的flannel和mirrored_flannelcni-flannel-cni-plugin镜像

docker pull quay.io/coreos/flannel:v0.15.1docker 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.0docker save rancher/mirrored_flannelcni-flannel-cni-plugin:v1.0.0 > $download_dir/kubernetes_network/mirrored_flannelcni-flannel-cni-plugin_v1.0.0.tar




二、在离线机器上安装之前下载的相关包

  1. 在离线集群的所有机器上安装docker包并启动docker

    sudo yum localinstall -y --disablerepo=* $download_dir/docker/*
    #enable&start dockersudo systemctl enable dockersudo systenctl start docker


2. 在离线集群的所有机器上安装Kubernetes utilities并启动kubelet

sudo yum localinstall -y --disablerepo=* $download_dir/kubernetes_utilities/*.rpm
#enable and start kubeletsudo systemctl enable kubeletsudo systemctl start kubelet


3. 在离线集群的所有机器上加载kubeadm所需的Kubernetes镜像并重启docker

sudo docker load < kube-apiserver_v1.22.4.tarsudo docker load < kube-controller-manager_v1.22.4.tarsudo docker load < kube-scheduler_v1.22.4.tarsudo docker load < kube-proxy_v1.22.4.tarsudo docker load < pause_3.5.tarsudo docker load < etcd_3.5.0-0.tarsudo docker load < coredns_v1.8.4.tarsudo systemctl restart docker


4. 在离线集群的所有机器上加载Kubernetes network镜像并重启docker

cd $download_dir/kubernetes_networksudo docker load < flannel_v0.15.1.tarsudo docker load < mirrored_flannelcni-flannel-cni-plugin_v1.0.0.tarsudo 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.confnet.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1EOF

sysctl --system


3. 在离线集群的primary node上执行如下命令以创建一个新的kubernetes集群

kubeadm init --pod-network-cidr=10.244.0.0/16


4. 在离线集群的所有机器上执行如下指令以配置kubectl管理集群


mkdir -p $HOME/.kubesudo chmod 606 /etc/kubernetes/admin.confcp -i /etc/kubernetes/admin.conf $HOME/.kube/configchown $(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