前言:
上一篇文章云原生|kubernetes|kubeadm部署高可用集群(一)使用外部etcd集群_晚风_END的博客-CSDN博客讲述了如何利用kubeadm部署集群的时候使用外部扩展etcd集群,使得集群的整体结构做了一些解耦,提高了集群的负载能力,那么,本文将讲述如何在此基础上做到kube-apiserver的高可用,从而部署一个可完全用于生产的kubernetes集群。
下面就直接上干货。
一,集群环境简介
本次实践计划使用haproxy+keepalived针对kube-apiserver搭建一个负载均衡。为什么不使用nginx+keepalived的技术栈呢?主要是考虑到主机性能不太够,因此虚拟机不够多,其次nginx做负载均衡的时候,会占用集群的默认6443端口,会有一些不必要的麻烦,而haproxy是一个更为专业的代理软件。
kubernetes集群内部使用三个kube-apiserver+外部扩展etcd集群,各个组件都是高可用的,完全可以应用在实际的生产活动中。
kubernetes集群是由三个master节点和一个node工作节点组成,master节点使用三个是出于集群的奇数要求,两个或者四个提现不出高可用的特点。工作节点的扩展是比较简单的,如果在实际生产中可以很简单的就扩展工作节点,因此工作节点设置为一个。
下面是整个集群的大体配置:
服务器IP地址 | 集群角色 | 服务器硬件配置 | 安装的组件 | 组件版本 | 部署方式 |
192.168.217.19 | control-plane,master | CPU:2c2u 内存:4G 硬盘:100G 单分区 / |
kubelet,kubeadm,kubernetes集群其它关键组件为静态pod形式。 负载均衡:haproxy和keepalived etcd集群 docker环境 |
kubernetes-1.22.2 docker-ce-20.10.5 haproxy-1.5.18-9 keepalived-1.3.5 etcd Version: 3.4.9 |
docker和etcd:二进制方式 其它:yum安装 |
192.168.217.20 | control-plane,master | CPU:2c2u 内存:4G 硬盘:100G 单分区 / |
kubelet,kubeadm,kubernetes集群其它关键组件为静态pod形式。 负载均衡:haproxy和keepalived etcd集群 docker环境 |
kubernetes-1.22.2 docker-ce-20.10.5 haproxy-1.5.18-9 keepalived-1.3.5 etcd Version: 3.4.9 |
docker和etcd:二进制方式 其它:yum安装 |
192.168.217.21 | control-plane,master | CPU:2c2u 内存:4G 硬盘:100G 单分区 / |
kubelet,kubeadm,kubernetes集群其它关键组件为静态pod形式。 负载均衡:haproxy和keepalived etcd集群 docker环境 |
kubernetes-1.22.2 docker-ce-20.10.5 haproxy-1.5.18-9 keepalived-1.3.5 etcd Version: 3.4.9 |
docker和etcd:二进制方式 其它:yum安装 |
192.168.217.22 | node,工作节点 | CPU:2c2u 内存:4G 硬盘:100G 单分区 / |
kubelet,kubeadm,kubernetes集群其它关键组件为静态pod形式。 docker环境 |
kubernetes-1.22.2 docker-ce-20.10.5 etcd Version: 3.4.9 |
docker:二进制方式 其它:yum安装 注意:etcd集群是三节点形式,因此,本节点不安装 |
VIP:192.168.217.100 | 负载均衡节点 | 无 | 无 | keepalived产生 |
[root@master1 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.217.19 master1 k8s-master1
192.168.217.20 master2 k8s-master2
192.168.217.21 master3 k8s-master3
192.168.217.22 node1 k8s-node1
二,
集群基础环境搭建
(1)配置主机名称:
k8s-master1
[root@master1 ~]# cat /etc/hostname
master1
k8s-master2
[root@master2 manifests]# cat /etc/hostname
master2
k8s-master3
[root@master3 ~]# cat /etc/hostname
master3
node1
[root@node1 ~]# cat /etc/hostname
node1
所有服务器统一hosts:
[root@master1 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.217.19 master1 k8s-master1
192.168.217.20 master2 k8s-master2
192.168.217.21 master3 k8s-master3
192.168.217.22 node1 k8s-node1
(2)时间服务器
所有节点安装ntp并启动ntpd服务:
yum install ntp -y
systemctl enable ntpd && systemctl start ntpd
192.168.217.19作为时间服务器,配置文件主要的地方:
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 127.127.1.0 prefer
fudge 127.127.1.0 stratum 10
其它节点的时间服务器配置:
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 192.168.217.19
任意一个节点输出如下表示时间服务器正常:
[root@master2 ~]# ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
*master1 LOCAL(0) 11 u 26 128 377 0.390 0.014 0.053
[root@master2 ~]# ntpstat
synchronised to NTP server (192.168.217.19) at stratum 12
time correct to within 23 ms
polling server every 128 s
(3)关闭防火墙
systemctl disable firewalld && systemctl stop firewalld
(4)关闭selinux
编辑/etc/selinux/config文件:
[root@master2 ~]# cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
输出如下表示关闭:
[root@master2 ~]# getenforce
Disabled
(5)关闭swap
这个就不说了,太基础的东西。
(6)服务器之间的免密码
也不在这详细说了,免密的原理和如何免密见我的博客:科普扫盲---ssh免密登陆(ssh的一些小秘密)_晚风_END的博客-CSDN博客_ssh免密不带端口号
这里配置免密的原因是由于后面初始化集群的时候需要服务器自动传输证书。
(7)docker环境的搭建
docker的离线安装以及本地化配置_晚风_END的博客-CSDN博客 务必要做好本地化的配置,否则后面的下载镜像会成为噩梦。
部署完成后按教程做好docker环境的测试工作。
(8)etcd集群的搭建
centos7操作系统 ---ansible剧本离线快速部署etcd集群_晚风_END的博客-CSDN博客_etcd离线安装 务必按此教程部署etcd集群,后面的集群初始化工作会基于此etcd集群开始。
部署完成后,按教程做好etcd集群的测试工作。
(9)
安装kubelet,kubectl,kubeadm
云原生|kubernetes|kubeadm五分钟内部署完成集群(完全离线部署---适用于centos7全系列)_晚风_END的博客-CSDN博客
其实集群搭建也就麻烦在基础环境的搭建,费时费力,不过有一个良好的开端的话,后面会比较轻松一些。
三,创建负载均衡器(HAProxy+Keepalived)
当存在多个控制平面时,kube-apiserver也存在多个,可以使用Nginx+Keepalived、HAProxy+Keepalived等工具实现多个kube-apiserver的负载均衡和高可用。
推荐使用HAProxy+Keepalived这个组合,因为HAProxy可以提高更高性能的四层负载均衡功能,这也是大多数人的选择。
四,
kubeadm部署集群可以使用两种形式,第一,命令行初始化,第二,config配置文件初始化。本文选择使用config配置文件的方式:
在192.168.217.19服务器上生成模板文件;
kubeadm config print init-defaults >kubeadm-init1-ha.yaml
编辑此模板文件,最终的内容应该如下:
[root@master1 ~]# cat kubeadm-init-ha.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: "0"
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.217.19
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
imagePullPolicy: IfNotPresent
name: master1
taints: null
---
controlPlaneEndpoint: "192.168.217.100"
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
external:
endpoints: #下面为自定义etcd集群地址
- https://192.168.217.19:2379
- https://192.168.217.20:2379
- https://192.168.217.21:2379
caFile: /etc/kubernetes/pki/etcd/ca.pem
certFile: /etc/kubernetes/pki/etcd/apiserver-etcd-client.pem
keyFile: /etc/kubernetes/pki/etcd/apiserver-etcd-client-key.pem
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.22.2
networking:
dnsDomain: cluster.local
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
scheduler: {}