之前写过一篇文章使用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-01 | 192.168.0.151 192.168.0.170 | HAProxy + Keepalived (master) |
k8s-lb-02 | 192.168.0.161 192.168.0.170 | HAProxy + Keepalived (backup) |
k8s-master-01 | 192.168.0.152 | Master节点1 |
k8s-master-02 | 192.168.0.153 | Master节点2 |
k8s-master-03 | 192.168.0.162 | Master节点3 |
k8s-worker-01 | 192.168.0.154 | Worker节点1 |
k8s-worker-02 | 192.168.0.164 | Worker节点2 |
k8s-worker-03 | 192.168.0.165 | Worker节点3 |
说明:
计划部署“2负载均衡 + 3 Master节点 + 3 Worker节点”的高可用Kubernetes集群:
192.168.0.170:6443
192.168.0.152:6443
192.168.0.153:6443
192.168.0.162:6443
安装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:
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的配置文件,绑定frontend IP为Keepalived VIP:
frontend apiserver
bind 192.168.0.170:6443
重新启动HAProxy:
systemctl daemon-reload
systemctl restart haproxy
# 安装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 {} \;
# 安装前检查和配置
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集群节点的部署。
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节点时需要用到。
# support eth* and ens* networkd interfaces
bash 06_install_calico.sh eth-ens
运行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
运行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
bash 07_install_metrics_server.sh
参见:
bash 08_install_prometheus_grafana.sh
参见:
参见:
参见:
如果节点机器不能上网,可以通过设置代理来上网,这样可以方便在线yum安装、下载文件和拉取镜像。
参见:
如果使用了http proxy,在初始化Kubernetes集群前需要重置全局的
http_proxy
和https_proxy
,并运行systemctl restart kubelet
重启kubelet服务。
使用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:3128
(http)。
如果设置了HTTPS_PROXY=https://172.31.240.127:3128
(https),则会报错:
proxyconnect tcp: tls: first record does not look like a TLS handshake
参见:
参见:
如果无法从Google Kubernetes Yum源安装,可以通过阿里云Kubernetes Yum源来安装。
参见:
问题:
重启机器后,集群不可用,运行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 -l
和journalctl -xefu kubelet
报错“No node found"。
原因:
少于3个Master节点启动时,Etcd高可用条件不满足,API Server退出。
解决方法:
systemctl restart kubelet
。参见:
Kubernetes版本 | Docker版本 |
---|---|
v1.15 | 1.13.1 , 17.03 , 17.06 , 17.09 , 18.06 , 18.09 |
v1.16 | 1.13.1 , 17.03 , 17.06 , 17.09 , 18.06 , 18.09 |
v1.17 | 1.13.1 , 17.03 , 17.06 , 17.09 , 18.06 , 18.09 , 19.03 |
v1.18 | 1.13.1 , 17.03 , 17.06 , 17.09 , 18.06 , 18.09 , 19.03 |
v1.19 | 1.13.1 , 17.03 , 17.06 , 17.09 , 18.06 , 18.09 , 19.03 |
2台笔记本电脑:
Kubernetes集群安装和部署需要掌握:
复杂性:
解决问题思路:
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/
https://kubernetes.io/docs/setup/production-environment/container-runtimes/#docker
https://kubernetes.io/docs/concepts/cluster-administration/addons/
https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/
Unable to update cni config: No networks found in /etc/cni/net.d
https://octetz.com/docs/2019/2019-03-26-ha-control-plane-kubeadm/
https://blog.scottlowe.org/2019/08/12/converting-kubernetes-to-ha-control-plane/
https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join/
https://blog.inkubate.io/install-and-configure-a-multi-master-kubernetes-cluster-with-kubeadm/
https://www.unixmen.com/configure-high-available-load-balancer-haproxy-keepalived/
https://snapdev.net/2015/09/08/install-haproxy-and-keepalived-on-centos-7-for-mariadb-cluster/
https://www.unixmen.com/installing-haproxy-for-load-balancing-on-centos-7
https://blog.inkubate.io/install-and-configure-a-multi-master-kubernetes-cluster-with-kubeadm/
https://kifarunix.com/configure-highly-available-haproxy-with-keepalived-on-ubuntu-20-04/