在CentOS7上用kubeadm HAProxy Keepalived 安装多Master节点的高可用Kubernetes集群

漆雕育
2023-12-01

在CentOS7上用kubeadm HAProxy Keepalived 安装多Master节点的高可用Kubernetes集群

前言

之前写过一篇文章使用kubeadm一键部署kubernetes集群 v1.10.3 v1.11.0 v1.13.0 和编写了一个一键部署单Master节点的Kubernetes集群的开源项目k8s-deploy

现在Kubernetes已更新到v1.19,所以重新更新了k8s-deploy项目,支持部署多Master节点的高可用Kubernetes集群。

在正式安装前,推荐先阅读k8s-deploy项目和Troubleshooting中的常见问题。

官方文档

部署规划

资源规划

全部节点都在一个低延迟的子网中:

主机名IP说明
k8s-lb-01192.168.0.151
192.168.0.170
HAProxy + Keepalived (master)
k8s-lb-02192.168.0.161
192.168.0.170
HAProxy + Keepalived (backup)
k8s-master-01192.168.0.152Master节点1
k8s-master-02192.168.0.153Master节点2
k8s-master-03192.168.0.162Master节点3
k8s-worker-01192.168.0.154Worker节点1
k8s-worker-02192.168.0.164Worker节点2
k8s-worker-03192.168.0.165Worker节点3

说明:

  • 采用外部HAProxy作集群负载均衡器;
  • 采用2个 HAProxy + Keepalived 来保证负载均衡的高可用,Keepalived VIP为192.168.0.170;
  • 采用每个Master节点上伴随部署Etcd的方式(Slacked Etcd typology 堆叠Etcd拓扑),而Etcd高可用最少需要3个节点(奇数),因此Master节点至少为3个。
  • 3个worker节点来保证worker节点高可用。
  • 服务器规格都为CentOS7 x86_64 2vCPU/2G 。
  • 全部机器都在192.168.0.0/24网段,且相互连通。

集群规划

计划部署“2负载均衡 + 3 Master节点 + 3 Worker节点”的高可用Kubernetes集群:

  • Docker 19.03.11
  • Kubernetes v1.19.3
  • Calico网络组件
  • HAProxy负载均衡
  • 集群Control-Plane Endpoint:192.168.0.170:6443
  • 集群API Server(s):
    • 192.168.0.152:6443
    • 192.168.0.153:6443
    • 192.168.0.162:6443

部署负载均衡服务器

安装和配置HAProxy

安装HAProxy:

yum install haproxy -y

编辑/etc/haproxy/haproxy.cfg,删掉默认的代理设置,添加负载均衡反向代理到Kubernetes集群Master节点的设置:

#---------------------------------------------------------------------
# apiserver frontend which proxys to the masters
#---------------------------------------------------------------------
frontend apiserver
    bind *:6443
    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-01 192.168.0.152:6443 check
        server k8s-master-02 192.168.0.153:6443 check
        server k8s-master-03 192.168.0.162:6443 check

以服务方式运行HAProxy:

systemctl daemon-reload
systemctl enable haproxy
systemctl start haproxy

查看HAProxy服务状态:

systemctl status haproxy -l

如果HAProxy启动失败,请关闭SELinux再试。

安装和配置Keepalived

安装Keepalived:

yum install keepalived -y

配置Linux系统内核参数:

sudo cat <<EOF >  /etc/sysctl.d/keepalived.conf
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1
EOF

sudo sysctl --system

说明:

  • net.ipv4.ip_forward = 1 允许IP转发
  • net.ipv4.ip_nonlocal_bind = 1 允许绑定浮动IP,即VIP

/etc/keepalived下新建check_apiserver.sh用来Keepalived作健康检查,内容为:

#!/bin/sh


APISERVER_VIP=$1
APISERVER_DEST_PORT=$2

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

为脚本增加可执行文件权限:

chmod +x /etc/keepalived/check_apiserver.sh

在Keepalived master节点和backup节点的配置略有不同。

在Keepalived master节点上的/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 192.168.0.170 6443"
  interval 3
  weight -2
  fall 10
  rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 101
    authentication {
        auth_type PASS
        auth_pass Keep@lived
    }
    virtual_ipaddress {
        192.168.0.170
    }
    track_script {
        check_apiserver
    }
}

说明:

  • script "/etc/keepalived/check_apiserver.sh 192.168.0.170 6443" 声明Keepalived健康检查脚本。
  • state MASTER 声明该节点为Keepalived master节点。
  • interface ens33 声明该网卡名称。
  • priority 101 Keepalived master节点优先级,需要比Keepalived backup节点优先级大。
  • auth_pass Keep@lived Keepalived master和backup节点需要设置一样的auth_pass
  • virtual_ipaddress 为Keepalived VIP。

在Keepalived backup节点上的/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 192.168.0.170 6443"
  interval 3
  weight -2
  fall 10
  rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 100
    authentication {
        auth_type PASS
        auth_pass Keep@lived
    }
    virtual_ipaddress {
        192.168.0.170
    }
    track_script {
        check_apiserver
    }
}

说明:

  • state BACKUP 声明该节点为Keepalived backup节点。
  • priority 100 Keepalived backup节点优先级,需要比Keepalived master节点优先级小。

以服务方式运行Keepalived:

systemctl daemon-reload
systemctl enable keepalived
systemctl start keepalived

查看Keepalived服务状态:

systemctl status keepalived -l

让HAProxy使用Keepalived VIP

修改HAProxy的配置文件,绑定frontend IP为Keepalived VIP:

frontend apiserver
    bind 192.168.0.170:6443

重新启动HAProxy:

systemctl daemon-reload
systemctl restart haproxy

部署第一个节点

拉取k8s-deploy项目

# 安装Git
yum install git -y

# 拉取k8s-deploy项目
mkdir -p ~/k8s
cd ~/k8s
git clone https://github.com/cookcodeblog/k8s-deploy.git

# 增加脚本的可执行文件权限
cd k8s-deploy/kubeadm_v1.19.3
find . -name '*.sh' -exec chmod u+x {} \;

安装Kubernetes

# 安装前检查和配置
bash 01_pre_check_and_configure.sh

# 安装Docker
bash 02_install_docker.sh

# 安装kubeadm, kubectl, kubelet
bash 03_install_kubernetes.sh

# 拉取Kubernetes集群要用到的镜像
bash 04_pull_kubernetes_images_from_aliyun.sh

# 拉取Calico网络组件的镜像
bash 04_pull_calico_images.sh

克隆服务器作为基准镜像

建议克隆这台服务器作为基准镜像,来加快后面的Kubernetes集群节点的部署。

部署第一个Master节点

初始化集群

cd ~/k8s
cd k8s-deploy/kubeadm_v1.19.3

# 05_kubeadm_init.sh <CONTROL_PLANE_ENDPOINT>
bash 05_kubeadm_init.sh 192.168.0.170:6443

复制kubeadm init的输出日志,后面往集群中加入Master节点和Worker节点时需要用到。

安装Calico网络组件

# support eth* and ens* networkd interfaces
bash 06_install_calico.sh eth-ens

部署Worker节点

运行kubeadm init中打印的日志中关于加入“worker node”的命令。

示例:

kubeadm join 192.168.0.170:6443 --token r7w69v.3e1nweyk81h5zj6y \
    --discovery-token-ca-cert-hash sha256:1234a2317d27f0a4c6bcf5f284416a2fb3e8f3bd61aa88bc279a4f6ef18e09a1 

让Worker节点上的kubectl命令生效:

bash enable_kubectl_worker.sh

部署其他Master节点

运行kubeadm init中打印的日志中关于加入“control-plane node"的命令。

示例:

kubeadm join 192.168.0.170:6443 --token r7w69v.3e1nweyk81h5zj6y \
    --discovery-token-ca-cert-hash sha256:1234a2317d27f0a4c6bcf5f284416a2fb3e8f3bd61aa88bc279a4f6ef18e09a1 \
    --control-plane --certificate-key 0e48107fbcd11cda60a5c2b76ae488b4ebf57223a4001acac799996740a6044e

如果忘记了kubeadm join命令的内容,可运行kubeadm token create --print-join-command 重新获取,并可运行kubeadm init phase upload-certs --upload-certs 获取新的certificate-key

Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
“kubeadm init phase upload-certs --upload-certs” to reload certs afterward.

让Master节点上的kubectl命令生效:

bash enable_kubectl_master.sh

查看集群部署情况

# Display cluster info
kubectl cluster-info

# Nodes
kubectl get nodes

# Display pds
kubectl get pods --all-namespaces -o wide

# Check pods status incase any pods are not in running status
kubectl get pods --all-namespaces | grep -v Running

(可选)安装Metrics Server

bash 07_install_metrics_server.sh

参见:

(可选)安装Prometheus和Grafana

bash 08_install_prometheus_grafana.sh

参见:

Troubleshooting

用VMWare试验时怎么设置主机名和IP

参见:

官方Yum源安装太慢,可使用阿里云Yum源

参见:

服务器上不了网,可通过HTTP Proxy正向代理上网

如果节点机器不能上网,可以通过设置代理来上网,这样可以方便在线yum安装、下载文件和拉取镜像。

参见:

如果使用了http proxy,在初始化Kubernetes集群前需要重置全局的http_proxyhttps_proxy,并运行systemctl restart kubelet重启kubelet服务。

设置docker pull proxy

使用docker pull通过代理拉取Docker镜像,参见:

/etc/systemd/system/docker.service.d/http-proxy.conf示例:

[Service]
Environment="HTTP_PROXY=http://172.31.240.127:3128"
Environment="HTTPS_PROXY=http://172.31.240.127:3128"
Environment="NO_PROXY=127.0.0.1,localhost,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"

注意,如果使用Squid作为proxy server,/etc/systemd/system/docker.service.d/http-proxy.conf中的HTTP_PROXY和HTTPS_PROXY应设置成一样,都为http://proxy_server_ip:3128http)。

如果设置了HTTPS_PROXY=https://172.31.240.127:3128 (https),则会报错:

proxyconnect tcp: tls: first record does not look like a TLS handshake

参见:

从Docker Hub拉取镜像太慢,可使用阿里云镜像加速器

参见:

拉取Google镜像太慢,可使用阿里云镜像仓库

重启机器后,集群不可用

问题:
重启机器后,集群不可用,运行kubectl cluster-info返回错误信息,运行kubectl get nodes没有响应,超时后报错“Error from server (InternalError): an error on the server ("") has prevented the request from succeeding (get nodes)“。

在Master节点上,运行systemctl status kubelet -ljournalctl -xefu kubelet 报错“No node found"。

原因:
少于3个Master节点启动时,Etcd高可用条件不满足,API Server退出。

解决方法:

  1. 启动HAProxy机器。
  2. 启动全部Master节点。
  3. (可选)在Master节点上重启kubelet: systemctl restart kubelet

参见:

其他内容

Kubernetes兼容的Docker版本

Kubernetes版本Docker版本
v1.151.13.1, 17.03, 17.06, 17.09, 18.06, 18.09
v1.161.13.1, 17.03, 17.06, 17.09, 18.06, 18.09
v1.171.13.1, 17.03, 17.06, 17.09, 18.06, 18.09, 19.03
v1.181.13.1, 17.03, 17.06, 17.09, 18.06, 18.09, 19.03
v1.191.13.1, 17.03, 17.06, 17.09, 18.06, 18.09, 19.03

本例试验环境

2台笔记本电脑:

  • Windows 10,Intel Core i5 / 16G,VMWare workstation 12 pro。
  • Macbook pro,Intel Core i5 / 16G, VMWare fusion。
  • 虚拟机网络模式为桥接模式,网段为192.168.0.0/24,子网掩码为255.255.255.0,网关为192.168.0.1,网卡名称为ens33。

Kubernetes集群安装和部署难点

Kubernetes集群安装和部署需要掌握:

  • Linux系统管理知识。
  • 网络知识。
  • 部署架构知识,如果有公有云的IaaS经验就比较容易上手。
  • 安全知识。

复杂性:

  • 版本:Kubernetes版本,Linux发行版,CPU arch版本
  • Bug:Kubernetes bug,Docker bug,Linux bug,虚拟机软件 bug
  • 多种网络模式的不同:虚拟机桥接网络模式,虚拟机NAT网络模式,不同公有云的VPC网络模式,不同Kubernetes网络组件的网络模式
  • 网络受限:不能直接拉取Kubernetes镜像、Docker Hub镜像

解决问题思路:

  • 从原理上分析和定位问题
  • Kubernetes 官方文档
  • Kubernetes GitHub issues
  • Stackoverflow

参考文档

 类似资料: