如何使用 Kubeadm 在 HA 中设置 Kubernetes(k8s) 集群

[ad_1]

当我们设置 Kubernetes (k8s) 生产环境的本地集群,那么建议以高可用性部署它。 这里的高可用性意味着在 HA 中安装 Kubernetes master 或 control plane。 在本文中,我将演示如何使用 kubeadm 实用程序在 HA(高可用性)中设置 Kubernetes(k8s) 集群。

为了演示,我使用了五个 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。

搭建Highly K8s集群的最低要求

  • 安装 kubeadm, kubeletkubectl 在所有主节点和工作节点上
  • 主节点和工作节点之间的网络连接
  • 所有节点上的互联网连接
  • 根凭据或 sudo 所有节点上的特权用户

让我们进入安装和配置步骤

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

主机名 命令在每个节点上设置主机名,示例显示为 k8s-master-1 节点,

$ 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 和 keepalived 时使用此 IP 和主机名。 此 IP 将用作 立方体apiserver 负载均衡器ip. 所有的 kube-apiserver 请求都会到达这个 IP,然后请求会被分发到后端实际的 kube-apiservers 中。

步骤 2) 在所有主/控制平面节点上安装和配置 Keepalive 和 HAProxy

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

$ sudo yum install haproxy keepalived -y

先在k8s-master-1上配置Keepalived,创建 check_apiserver.sh 脚本将包含以下内容,

[[email protected]r-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 文件,然后截断该文件。

[[email protected] ~]$ sudo cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf-org
[[email protected] ~]$ sudo sh -c '> /etc/keepalived/keepalived.conf'

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

[[email protected] ~]$ 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 [email protected]##D321!
    }
    virtual_ipaddress {
        192.168.1.45/24
    }
    track_script {
        check_apiserver
    }
}

Save 和 close 文件。

笔记: 对于 master-2 和 3 节点,只需更改此文件的两个参数。 状态 会变成 奴隶 对于 master 2 和 3,优先级将分别为 254 和 253。

在k8s-master-1节点上配置HAProxy,编辑其配置文件,添加如下内容:

[[email protected] ~]$ sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg-org

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

[[email protected] ~]$ 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

Save 并退出文件

现在复制这三个文件(check_apiserver.sh , 保持连接文件haproxy.cfg) 从 k8s-master-1 到 k8s-master-2 & 3

运行以下 for 循环将这些文件 scp 到 master 2 和 3

[[email protected] ~]$ for f in k8s-master-2 k8s-master-3; do scp /etc/keepalived/check_apiserver.sh /etc/keepalived/keepalived.conf [email protected]$f:/etc/keepalived; scp /etc/haproxy/haproxy.cfg [email protected]$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 节点。

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

步骤 3) 禁用 Swap,将 SELinux 设置为 Master 和 worker 节点的许可和防火墙规则

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

$ 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"

Worker 节点的防火墙规则:

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

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

$ 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(Container Run Time),运行以下命令,

$ 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) 安装 Beadm、kubelet 和 kubectl

安装 珠子, kubeletkubectl 在所有主节点以及工作节点上。 在首先安装这些包之前,我们必须配置 Kubernetes 存储库,在每个 master 和 worker 节点上运行以下命令,

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 集群

现在移动到第一个主节点/控制平面并发出以下命令,

[[email protected] ~]$ sudo kubeadm init --control-plane-endpoint "vip-k8s-master:8443" --upload-certs

在上面的命令中, –控制平面端点 为负载均衡器 (kube-apiserver) 设置 dns 名称和端口,在我的情况下,dns 名称是“vip-k8s-master”,端口是“8443”,除此之外’– 上传证书‘ 选项将自动在主节点之间共享证书,

kubeadm 命令的输出如下所示:

太好了,上面的输出确认 Kubernetes 集群已成功初始化。 在输出中,我们还获得了其他主节点和工作节点加入集群的命令。

笔记: 建议将此输出复制到文本文件以供将来参考。

运行以下命令允许本地用户使用 kubectl 命令与集群交互,

[[email protected] ~]$ mkdir -p $HOME/.kube
[[email protected] ~]$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[[email protected] ~]$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
[[email protected] ~]$

现在,让我们部署 pod 网络(CNI – 容器网络接口),在我的例子中,我将 calico 插件部署为 pod 网络,运行以下 kubectl 命令

[[email protected] ~]$ kubectl apply -f https://docs.projectcalico.org/v3.14/manifests/calico.yaml

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

[[email protected] ~]$ 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 上运行相同的命令,

[[email protected] ~]$ 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 节点并执行以下命令,

[[email protected] ~]$ 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
[[email protected] ~]$

完美,我们所有的三个主节点或控制平面节点都已准备就绪并加入集群。

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

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

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

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

输出将类似于以下内容:

现在前往 k8s-master-1 节点并在 kubectl 命令下运行以获取状态工作节点,

[[email protected] ~]$ 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
[[email protected] ~]$

以上输出确认两个工作人员也已加入集群并处于就绪状态。

运行以下命令以验证部署在的状态 infra pod 立方体系统 命名空间。

[[email protected] ~]$ 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 [email protected]:/etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

现在运行“kubectl 获取节点“ 命令,

[[email protected] ~]$ 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
[[email protected] ~]$

让我们创建一个具有名称的部署 nginx实验室 带有图像 ‘nginx‘ 然后将此部署公开为类型为“的服务”节点端口

[[email protected] ~]$ kubectl create deployment nginx-lab --image=nginx
deployment.apps/nginx-lab created
[[email protected] ~]$
[[email protected] ~]$ kubectl get deployments.apps nginx-lab
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
nginx-lab   1/1     1            1           59s
[[email protected] ~]$ 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
[[email protected] ~]$

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

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

现在将部署公开为服务,运行

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

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

[[email protected] ~]$ 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
[[email protected] ~]$

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

[[email protected] ~]$ curl https://192.168.1.44:31766

输出将类似于以下内容:

完美,这证实了我们已经在 CentOS 7 服务器上成功部署了带有 kubeadm 的高可用 Kubernetes 集群。 请不要犹豫,分享您宝贵的反馈和意见。

还阅读如何在 Kubernetes 中设置 NGINX 入口控制器

[ad_2]

Related Posts