为了账号安全,请及时绑定邮箱和手机立即绑定

使用Kubeadm设置Kubernetes集群的高可用性

标签:
Kubernetes

当我们为生产环境在本地设置[Kubernetes(k8s)]集群时,建议以高可用性部署它。高可用性意味着在HA中安装Kubernetes主节点或工作节点。在本文中,我将演示如何使用kubeadm实用程序设置高可用性的Kubernetes集群。

为了进行演示,我使用了五个具有以下详细信息的CentOS 7系统:

  • k8s-master-1 –最低CentOS 7 – 192.168.1.40 – 2GB RAM,2vCPU,40 GB磁盘
  • k8s-master-2 –最低CentOS 7 – 192.168.1.41 – 2GB RAM,2vCPU,40 GB磁盘
  • k8s-master-3 –最低CentOS 7 – 192.168.1.42 – 2GB RAM,2vCPU,40 GB磁盘
  • k8s-worker-1 –最低CentOS 7 – 192.168.1.43 – 2GB RAM,2vCPU,40 GB磁盘
  • k8s-worker-2 –最低CentOS 7 – 192.168.1.44 – 2GB RAM,2vCPU,40 GB磁盘

图片描述

注意:etcd集群也可以在主节点之外形成,但是为此我们需要额外的硬件,因此我将etcd安装在主节点内。设置K8s集群高可用的最低要求:

  • 在所有主节点和工作节点上安装Kubeadm,kubelet和kubectl
  • 主节点和工作节点之间的网络连接
  • 所有节点上的Internet连接
  • 根凭证或所有节点上的sudo特权用户

让我们跳过安装和配置步骤。

步骤1. 设置主机名并在/etc/hosts文件中添加条目

运行hostnamectl命令在每个节点上设置主机名,例如,示例显示K8s master节点:

$ hostnamectl set-hostname "k8s-master-1"  
$ exec bash  

同样,在其余节点上运行上述命令并设置它们各自的主机名。在所有主节点和工作节点上都设置了主机名之后,请在所有节点上的/etc/hosts文件中添加以下条目。

192.168.1.40   k8s-master-1  
192.168.1.41   k8s-master-2  
192.168.1.42   k8s-master-3  
192.168.1.43   k8s-worker-1  
192.168.1.44   k8s-worker-2  
192.168.1.45   vip-k8s-master  

我在主机文件中使用了另一个条目“ 192.168.1.45 vip-k8s-master”,因为我将在配置haproxy并在所有主节点上保持连接状态时使用此IP和主机名。该IP将用作kube-apiserver 负载均衡器ip。所有的kube-apiserver请求都将到达此IP,然后请求将分发到后端实际的kube-apiserver节点上。

步骤2.在所有主/工作节点上安装和配置Keepalive和HAProxy

使用以下yum命令在每个主节点上安装keepalived和haproxy:

$ sudo yum install haproxy keepalived -y  

首先在k8s-master-1上配置Keepalived,创建check_apiserver.sh脚本将获得以下内容:

[kadmin@k8s-master-1 ~]$ sudo vi /etc/keepalived/check_apiserver.sh  
#!/bin/sh  
APISERVER_VIP=192.168.1.45  
APISERVER_DEST_PORT=6443  
  
errorExit() {  
    echo "*** $*" 1>&2  
    exit 1  
}  
  
curl --silent --max-time 2 --insecure https://localhost:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://localhost:${APISERVER_DEST_PORT}/"  
if ip addr | grep -q ${APISERVER_VIP}; then  
    curl --silent --max-time 2 --insecure https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/"  
fi  

保存并退出文件,设置可执行权限:

$ sudo chmod + x /etc/keepalived/check_apiserver.sh  

备份keepalived.conf文件,然后清空该文件。

[kadmin@k8s-master-1 ~]$ sudo cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf-org  
[kadmin@k8s-master-1 ~]$ sudo sh -c '> /etc/keepalived/keepalived.conf'  

现在将以下内容粘贴到/etc/keepalived/keepalived.conf文件中

[kadmin@k8s-master-1 ~]$ sudo vi /etc/keepalived/keepalived.conf  
! /etc/keepalived/keepalived.conf  
! Configuration File for keepalived  
global_defs {  
    router_id LVS_DEVEL  
}  
vrrp_script check_apiserver {  
  script "/etc/keepalived/check_apiserver.sh"  
  interval 3  
  weight -2  
  fall 10  
  rise 2  
}  
  
vrrp_instance VI_1 {  
    state MASTER  
    interface enp0s3  
    virtual_router_id 151  
    priority 255  
    authentication {  
        auth_type PASS  
        auth_pass P@##D321!  
    }  
    virtual_ipaddress {  
        192.168.1.45/24  
    }  
    track_script {  
        check_apiserver  
    }  
}  

保存并关闭文件。注意:对于master-2和3节点,仅需要更改此文件的两个参数。主节点2和3的状态将变为SLAVE,优先级分别为254和253。在k8s-master-1节点上配置HAProxy,编辑其配置文件并添加以下内容:

[kadmin@k8s-master-1 ~]$ sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg-org  

删除默认部分之后的所有行,并添加以下行

[kadmin@k8s-master-1 ~]$ sudo vi /etc/haproxy/haproxy.cfg  
#---------------------------------------------------------------------  
# apiserver frontend which proxys to the masters  
#---------------------------------------------------------------------  
frontend apiserver  
    bind *:8443  
    mode tcp  
    option tcplog  
    default_backend apiserver  
#---------------------------------------------------------------------  
# round robin balancing for apiserver  
#---------------------------------------------------------------------  
backend apiserver  
    option httpchk GET /healthz  
    http-check expect status 200  
    mode tcp  
    option ssl-hello-chk  
    balance     roundrobin  
        server k8s-master-1 192.168.1.40:6443 check  
        server k8s-master-2 192.168.1.41:6443 check  
        server k8s-master-3 192.168.1.42:6443 check  

保存并退出文件。

图片描述

现在将这些三个文件(check_apiserver.sh,keepalived.conf和haproxy.cfg)从k8s-master-1复制到k8s-master-2和3运行以下for循环将这些文件scp复制到master 2和3上;

[kadmin@k8s-master-1 ~]$ for f in k8s-master-2 k8s-master-3; do scp /etc/keepalived/check_apiserver.sh /etc/keepalived/keepalived.conf root@$f:/etc/keepalived; scp /etc/haproxy/haproxy.cfg root@$f:/etc/haproxy; done  

注意:别忘了更改我们在上面针对k8s-master-2和3讨论的keepalived.conf文件中的两个参数。如果防火墙在主节点上运行,则在所有三个主节点上添加以下防火墙规则

$ sudo firewall-cmd --add-rich-rule='rule protocol value="vrrp" accept' --permanent  
$ sudo firewall-cmd --permanent --add-port=8443/tcp  
$ sudo firewall-cmd --reload  

现在,使用以下命令在所有三个主节点上启动并启用keepalived和haproxy服务:

$ sudo systemctl enable keepalived --now  
$ sudo systemctl enable haproxy --now  

这些服务成功启动后,请验证是否已在k8s-master-1节点上启用了VIP(虚拟IP),因为我们已在keepalived配置文件中将k8s-master-1标记为MASTER节点。

图片描述

完美,上面的输出确认已在k8s-master-1上启用了VIP。

建议阅读:[阿里云Kubernetes项目实战手册]

步骤3. 禁用Swap分区,将SELinux设置为主节点和辅助节点的许可规则和防火墙规则

在所有节点(包括工作节点)上禁用交换空间,运行以下命令:

$ sudo swapoff -a   
$ sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab  

在所有主节点和工作节点上将SELinux设置为Permissive,运行以下命令,

$ sudo setenforce 0  
$ sudo sed -i's / ^ SELINUX = enforcing $ / SELINUX = permissive /'/ etc / selinux / config  

主节点的防火墙规则:如果防火墙在主节点上运行,则在防火墙中允许以下端口

图片描述

所有主节点上运行以下firewall-cmd命令:

$ sudo firewall-cmd --permanent --add-port=6443/tcp  
$ sudo firewall-cmd --permanent --add-port=2379-2380/tcp  
$ sudo firewall-cmd --permanent --add-port=10250/tcp  
$ sudo firewall-cmd --permanent --add-port=10251/tcp  
$ sudo firewall-cmd --permanent --add-port=10252/tcp  
$ sudo firewall-cmd --permanent --add-port=179/tcp  
$ sudo firewall-cmd --permanent --add-port=4789/udp  
$ sudo firewall-cmd --reload  
$ sudo modprobe br_netfilter  
$ sudo sh -c "echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables"  
$ sudo sh -c "echo '1' > /proc/sys/net/ipv4/ip_forward"  

工作节点的防火墙规则:如果防火墙在工作节点上运行,则在所有工作程序节点上允许防火墙中的以下端口

图片描述

在所有工作节点上运行以下命令:

$ sudo firewall-cmd --permanent --add-port=10250/tcp  
$ sudo firewall-cmd --permanent --add-port=30000-32767/tcp                                                     
$ sudo firewall-cmd --permanent --add-port=179/tcp  
$ sudo firewall-cmd --permanent --add-port=4789/udp  
$ sudo firewall-cmd --reload  
$ sudo modprobe br_netfilter  
$ sudo sh -c "echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables"  
$ sudo sh -c "echo '1' > /proc/sys/net/ipv4/ip_forward"  

步骤4. 在主节点和工作节点上安装容器运行(CRI)[Docker]

在所有主节点和工作节点上安装Docker,运行以下命令

$ sudo yum install -y yum-utils  
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo  
$ sudo yum install docker-ce -y  

运行以下systemctl命令以启动并启用docker服务(在所有主节点和工作节点上也运行此命令)

$ sudo systemctl enable docker --now  

现在,让我们在下一步中安装kubeadm,kubelet和kubectl

步骤5. 安装Kubeadm,kubelet和kubectl

在所有主节点和辅助节点上安装kubeadm,kubelet和kubectl。首先安装这些软件包之前,我们必须配置Kubernetes repo仓库,在每个主节点和工作节点上运行以下命令

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo  
[kubernetes]  
name=Kubernetes  
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch  
enabled=1  
gpgcheck=1  
repo_gpgcheck=1  
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg  
exclude=kubelet kubeadm kubectl  
EOF  

现在,在yum命令下面运行以安装这些软件包

$ sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes  

运行以下systemctl命令以在所有节点(主节点和工作节点)上启用kubelet服务

$ sudo systemctl enable kubelet --now  

步骤6. 从第一个主节点初始化[Kubernetes集群]

现在到第一个主节点终端下执行以下命令

[kadmin@k8s-master-1 ~]$ sudo kubeadm init --control-plane-endpoint "vip-k8s-master:8443" --upload-certs  

在以上命令中, --control-plane-endpoint设置了负载均衡器(kube-apiserver)的dns名称和端口,在我的情况下,dns名称是“vip-k8s-master”,端口是“ 8443”,除了此--upload-certs的选项将自动在主节点之间共享证书。kubeadm命令的输出如下所示:

图片描述

很好,上面的输出确认Kubernetes集群已成功初始化。在输出中,我们还获得了其他主节点和工作节点加入集群的命令。注意:建议将此输出复制到文本文件中,以备将来参考。运行以下命令,以允许本地用户使用kubectl命令与集群进行交互

[kadmin@k8s-master-1 ~]$ mkdir -p $HOME/.kube  
[kadmin@k8s-master-1 ~]$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config  
[kadmin@k8s-master-1 ~]$ sudo chown $(id -u):$(id -g) $HOME/.kube/config  
[kadmin@k8s-master-1 ~]$  

现在,让我们部署Pod网络(CNI –容器网络接口),在我的情况下,我将calico插件部署为Pod网络,请按照kubectl命令运行

[kadmin@k8s-master-1 ~]$ kubectl apply -f https://docs.projectcalico.org/v3.14/manifests/calico.yaml  

成功部署Pod网络后,将其余两个主节点添加到群集中。只需从输出中复制用于主节点的命令以加入集群,然后将其粘贴到k8s-master-2和k8s-master-3上,示例如下所示

[kadmin@k8s-master-2 ~]$ sudo kubeadm join vip-k8s-master:8443 --token tun848.2hlz8uo37jgy5zqt  --discovery-token-ca-cert-hash sha256:d035f143d4bea38d54a3d827729954ab4b1d9620631ee330b8f3fbc70324abc5 --control-plane --certificate-key a0b31bb346e8d819558f8204d940782e497892ec9d3d74f08d1c0376dc3d3ef4  

输出如下:

图片描述

以上输出确认k8s-master-3也已成功加入集群。让我们从kubectl命令验证节点状态,到master-1节点并执行以下命令

[kadmin@k8s-master-1 ~]$ kubectl get nodes  
NAME           STATUS   ROLES    AGE     VERSION  
k8s-master-1   Ready    master   31m     v1.18.6  
k8s-master-2   Ready    master   10m     v1.18.6  
k8s-master-3   Ready    master   3m47s   v1.18.6  
[kadmin@k8s-master-1 ~]$  

完美,我们三个主节点均已准备就绪,并加入了集群。

步骤7. 将Worker节点加入Kubernetes集群

要将工作节点加入集群,请从输出中复制工作程序节点的命令,并将其粘贴到两个工作程序节点上,示例如下所示:

[kadmin@k8s-worker-1 ~]$ sudo kubeadm join vip-k8s-master:8443 --token tun848.2hlz8uo37jgy5zqt --discovery-token-ca-cert-hash sha256:d035f143d4bea38d54a3d827729954ab4b1d9620631ee330b8f3fbc70324abc5  
  
[kadmin@k8s-worker-2 ~]$ sudo kubeadm join vip-k8s-master:8443 --token tun848.2hlz8uo37jgy5zqt --discovery-token-ca-cert-hash sha256:d035f143d4bea38d54a3d827729954ab4b1d9620631ee330b8f3fbc70324abc5  

输出如下所示:

图片描述

现在转到k8s-master-1节点并在kubectl命令下运行以获取状态工作程序节点:

[kadmin@k8s-master-1 ~]$ kubectl get nodes  
NAME           STATUS   ROLES    AGE     VERSION  
k8s-master-1   Ready    master   43m     v1.18.6  
k8s-master-2   Ready    master   21m     v1.18.6  
k8s-master-3   Ready    master   15m     v1.18.6  
k8s-worker-1   Ready    <none>   6m11s   v1.18.6  
k8s-worker-2   Ready    <none>   5m22s   v1.18.6  
[kadmin@k8s-master-1 ~]$  

以上输出确认两个工作节点都已加入集群并处于就绪状态。运行以下命令,以验证在kube-system名称空间中部署的状态。

[kadmin@k8s-master-1 ~]$ kubectl get pods -n kube-system  

图片描述

步骤8. 测试Kubernetes集群的高可用性

让我们尝试使用负载平衡器dns名称和端口从远程计算机(CentOS系统)连接到群集。首先,在远程计算机上,我们必须安装kubectl软件包。运行以下命令来设置kubernetes软件仓库。

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo  
[kubernetes]  
name=Kubernetes  
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch  
enabled=1  
gpgcheck=1  
repo_gpgcheck=1  
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg  
exclude=kubelet kubeadm kubectl  
EOF  
  
$ sudo yum install -y  kubectl --disableexcludes=kubernetes  

现在在/etc/host文件中添加以下条目:

192.168.1.45   vip-k8s-master  

创建kube目录,并将/etc/kubernetes/admin.conf文件从k8s-master-1节点复制到$HOME/.kube/config

$ mkdir -p $HOME/.kube  
$ scp root@192.168.1.40:/etc/kubernetes/admin.conf $HOME/.kube/config  
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config  

现在运行“kubectl get nodes”命令,

[kadmin@localhost ~]$ kubectl get nodes  
NAME           STATUS   ROLES    AGE    VERSION  
k8s-master-1   Ready    master   3h5m   v1.18.6  
k8s-master-2   Ready    master   163m   v1.18.6  
k8s-master-3   Ready    master   157m   v1.18.6  
k8s-worker-1   Ready    <none>   148m   v1.18.6  
k8s-worker-2   Ready    <none>   147m   v1.18.6  
[kadmin@localhost ~]$  

让我们创建一个名为nginx-lab的部署,镜像为“ [nginx ]”,然后将该部署作为类型为“ NodePort ”的服务公开

[kadmin@localhost ~]$ kubectl create deployment nginx-lab --image=nginx  
deployment.apps/nginx-lab created  
[kadmin@localhost ~]$  
[kadmin@localhost ~]$ kubectl get deployments.apps nginx-lab  
NAME        READY   UP-TO-DATE   AVAILABLE   AGE  
nginx-lab   1/1     1            1           59s  
[kadmin@localhost ~]$ kubectl get pods  
NAME                         READY   STATUS    RESTARTS   AGE  
nginx-lab-5df4577d49-rzv9q   1/1     Running   0          68s  
test-844b65666c-pxpkh        1/1     Running   3          154m  
[kadmin@localhost ~]$  

让我们尝试将副本从1扩到4,运行以下命令:

[kadmin@localhost ~]$ kubectl scale deployment nginx-lab --replicas=4  
deployment.apps/nginx-lab scaled  
[kadmin@localhost ~]$  
[kadmin@localhost ~]$ kubectl get deployments.apps nginx-lab  
NAME        READY   UP-TO-DATE   AVAILABLE   AGE  
nginx-lab   4/4     4            4           3m10s  
[kadmin@localhost ~]$  

现在将部署作为服务公开,运行以下命令:

[kadmin@localhost ~]$ kubectl expose deployment nginx-lab --name=nginx-lab --type=NodePort --port=80 --target-port=80  
service/nginx-lab exposed  
[kadmin@localhost ~]$  

获取端口详细信息,并尝试使用curl访问nginx Web服务器

[kadmin@localhost ~]$ kubectl get svc nginx-lab  
NAME        TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE  
nginx-lab   NodePort   10.102.32.29   <none>        80:31766/TCP   60s  
[kadmin@localhost ~]$  

要访问nginx Web服务器,我们可以使用任何主节点或工作节点IP和端口作为“ 31766”

[kadmin@localhost ~]$ curl http://192.168.1.44:31766  

输出如下所示:

图片描述

完美,这严重了我们已经在CentOS 7服务器上使用kubeadm成功部署了高可用性Kubernetes集群。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消