1 集群逻辑架构
这里主要基于k8s集群高可用负载均衡方案进行介绍,过程包含基于keepalived的高可用方案。
2 环境
2.1 物理环境
主机 | IP | 配置 | OS | 角色 |
---|---|---|---|---|
node1 | 192.168.1.7 | 2core 2GB | Centos7.9 | master1 |
node2 | 192.168.1.8 | 2core 2GB | Centos7.9 | master2 |
node3 | 192.168.1.9 | 2core 2GB | Centos7.9 | master3 |
node4 | 192.168.1.10 | 2core 2GB | Centos7.9 | 工作节点 |
2.2 软件环境
软件 | 版本 |
---|---|
docker | v20.10.12 |
kubeadmin | v1.23.3 |
kubelet | v1.23.3 |
kubectl | v1.23.3 |
keeplalived | 1.3.5 |
haproxy | 2.5 |
2.3 镜像
镜像 | 版本 |
---|---|
conformance | v1.23.3 |
kube-apiserver | v1.23.3 |
kube-controller-manager | v1.23.3 |
kube-proxy | v1.23.3 |
kube-scheduler | v1.23.3 |
flannel | v1.0.1 |
3 步骤
3.1 准备工作
3.1.1 确保各节点MAC和product_uuid的唯一性
- 你可以使用命令
ip link
或ifconfig -a
来获取网络接口的 MAC 地址 - 可以使用
sudo cat /sys/class/dmi/id/product_uuid
命令对 product_uuid 校验
一般来讲,硬件设备会拥有唯一的地址,但是有些虚拟机的地址可能会重复。
3.1.2 运行iptables检查桥接流量
确保 br_netfilter
模块被加载。这一操作可以通过运行 lsmod | grep br_netfilter
来完成。若要显式加载该模块,可执行 sudo modprobe br_netfilter
。
为了让你的 Linux 节点上的 iptables 能够正确地查看桥接流量,你需要确保在你的 sysctl
配置中将 net.bridge.bridge-nf-call-iptables
设置为 1。例如:
1 | cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf |
3.1.3 关闭防火墙
1 | systemctl stop firewalld |
如果各个主机启用了防火墙,需要开放Kubernetes各个组件所需要的端口。如下图所示,详细信息请看官网。
3.1.4 永久关闭swap
vim /etc/fstab
如果不修改,kubelet启动报错:
3.1.5 关闭selinux
1 | 将 SELinux 设置为 permissive 或 disabled模式(相当于将其禁用) |
3.2 安装docker
卸载旧版本
1 | yum remove docker \ |
源安装
执行以下命令安装依赖包:
1 | $ sudo yum install -y yum-utils |
鉴于国内网络问题,强烈建议使用国内源,官方源请在注释中查看。
执行下面的命令添加 yum
软件源:
1 | $ sudo yum-config-manager \ |
安装docker-ce
1 | $ sudo yum install docker-ce docker-ce-cli containerd.io |
开机自启
1 | 启动 Docker |
3.3 安装 kubeadm、kubelet 和 kubectl
你需要在每台机器上安装以下的软件包:
kubeadm
:用来初始化集群的指令。kubelet
:在集群中的每个节点上用来启动 Pod 和容器等。kubectl
:用来与集群通信的命令行工具。
1 | cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo |
3.4 配置cgroup驱动程序
需保证容器服务和kubelet的cgroup驱动一致,否则kubelet启动报错:
由于 kubeadm 把 kubelet 视为一个系统服务来管理,所以对基于 kubeadm 的安装, 我们推荐使用 systemd
驱动,不推荐 cgroupfs
驱动。
3.4.1 Cgroup 驱动程序说明
警告:
你需要确保容器(docker)和 kubelet 所使用的是相同的 cgroup 驱动,否则 kubelet 进程会失败。
相关细节可参见kubelet配置 cgroup 驱动。容器配置cgroup驱动
3.4.2 查看kubelet和docker的驱动程序
- kubelet
1 | [root@node1 ~]# cat /var/lib/kubelet/kubeadm-flags.env |
- docker
1 | [root@node1 ~]# docker info |grep Cgroup |
3.4.4 Docker配置cgroup驱动
1 | sudo mkdir /etc/docker |
3.4.5 kubelet配置cgroup驱动(可选)
kubelet不配置默认即使用systemd
1 | # 将kubelet和docker 的驱动程序改成一致。 |
以上步骤和《kubernetes学习二:kubeadm安装kubernetes集群(单master)》完全一致,主要区别在集群负载均衡及集群初始化方式上。
3.5 keepalived 和 haproxy
keepalived
: 高可用软件,通过vrrp协议,vip地址的漂移,实现服务的高可用。
haproxy
: haproxy是一个开源的,高性能的,负载均衡软件。
haproxy
主要用来实现kube-apiserver的负载,实际操作中非必选。
3.5.1 请求架构
3.5.2 keepalived
1 | yum install -y keepalived |
主mastet
1 | ! Configuration File for keepalived |
备master
1 | ! Configuration File for keepalived |
1 | # 重启 |
3.5.3 haproxy
示例:https://www.haproxy.org/download/2.5/src/haproxy-2.5.1.tar.gz
想偷懒也可以直接 yum install haproxy -y 使用默认仓库的版本,相对版本较低。
安装依赖
1 | yum install -y make gcc gcc-c++ pcre-devel zlib-devel openssl-devel |
创建安装目录
1 | mkdri /usr/local/haproxy/ |
编译安装
1 | tar -zxvf haproxy-2.5.1.tar.gz |
创建配置文件目录
1 | mkdir -p /etc/haproxy/ |
从配置文件名模板复制配置文件
1 | cp examples/option-http_proxy.cfg /usr/local/haproxy/conf/haproxy.cfg |
拷贝开机启动文件
1 | cp haproxy-2.5.1/examples/haproxy.init /etc/init.d/haproxy |
添加haproxy命令脚本软连接
1 | ln -s /usr/local/haproxy/sbin/haproxy /usr/sbin |
设置开机自启
1 | chkconfig --add haproxy |
创建用户
1 | groupadd haproxy |
修改配置/etc/haproxy/haproxy.cfg
1 | #--------------------------------------------------------------------- |
各节点配置文件一致。
3.6 kubeadm创建集群
3.5.1 kubeadm config
kubeadm已经进入GA阶段,其控制面初始化和加入节点步骤都支持大量的可定制内容,因此kubeadm还提供了配置文件功能用于复杂定制。同时,kubeadm将配置文件以ConfigMap的形式保存到集群之中,便于后续的查询和升级工作。kubeadm config子命令提供了对这一组功能的支持:
◎ kubeadm config upload from-file:由配置文件上传到集群中生成ConfigMap。
◎ kubeadm config upload from-flags:由配置参数生成ConfigMap。
◎ kubeadm config view:查看当前集群中的配置值。
◎ kubeadm config print init-defaults:输出kubeadm init默认参数文件的内容。
◎ kubeadm config print join-defaults:输出kubeadm join默认参数文件的内容。
◎ kubeadm config migrate:在新旧版本之间进行配置转换。
◎ kubeadm config images list:列出所需的镜像列表。
◎ kubeadm config images pull:拉取镜像到本地。例如,执行kubeadm config print init-defaults,可以取得默认的初始化参数文件:
1 | kubeadm config print init-defaults > init.default.yaml |
3.5.2 导出kubeadm集群默认配置文件
1 | kubeadm config print init-defaults > init.default.yaml |
3.5.3 修改默认配置文件
修改如下内容:
- 主节点IP——advertiseAddress
- 国内阿里镜像地址imageRepository——registry.cn-hangzhou.aliyuncs.com/k8s-images-kx(通过阿里镜像仓库拉取的国外镜像)
- pod网段配置——不同网络插件网段不一样详细见官网(配置网络插件subnet地址段)
- 高可用集群api请求地址——controlPlaneEndpoint(这里设置为keepalived的VIP地址+haproxy负载均衡监听端口)
纠正:
podSubent
的值设置为flannel的默认网段,FLANNEL_NETWORK
的默认值(可通过flannel.yaml文件查看);podSubent=10.244.0.0/16
原因:
后面配置NFS存储类的时候,pod无法正常访问kube-apiserver。
参考:
k8s 1.20.x版本NFS动态存储配置 - 巽逸 - 博客园 (cnblogs.com)
(71条消息) Kubeadm 部署 使用flannel无法连接service/kubernetes_weixin_40455124的博客-CSDN博客
3.5.4 下载kubernetes相关镜像
使用config images list 子命令查询所需的镜像,例如
1 | [root@node1 home]# kubeadm config images list --config=init.default.yaml |
使用config images pull 子命令下载所需的镜像,例如(国内无法下载,只做演示)
预拉取镜像
通过阿里云镜像仓库构建下载镜像,具体方法不做细说。
镜像使用方式有2种:
- 修改镜像名为国外镜像名,例如
k8s.gcr.io/kube-apiserver:v1.23.0
k8s.gcr.io/kube-controller-manager:v1.23.0
k8s.gcr.io/kube-scheduler:v1.23.0
k8s.gcr.io/kube-proxy:v1.23.0
k8s.gcr.io/pause:3.6
k8s.gcr.io/etcd:3.5.1-0
k8s.gcr.io/coredns/coredns:v1.8.6
- 修改初始化配置文件,修改国外仓库为阿里云仓库
imageRepository: registry.cn-hangzhou.aliyuncs.com/k8s-images-kx
kind: ClusterConfiguration
kubernetesVersion: 1.23.3
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
1 | [root@node1 home]# kubeadm config images pull --config=init.default.yaml |
3.5.5 初始化集群
1 | # --upload-certs根据情况可选 |
3.5.6 加入master节点
1 | kubeadm join 192.168.1.133:6443 --token abcdef.0123456789abcdef \ |
1 | # 执行以下步骤,才能使用kubectl命令 |
3.5.7 加入工作节点
1 | kubeadm join 192.168.1.133:6443 --token abcdef.0123456789abcdef \ |
3.5.8 检查节点
1 | kubectl get node |
3.5.9 验证
关闭master1节点,通过master2或master3节点尝试集群命令。
vip转移到node2即master2节点,node2和node4执行管理权限不受影像
到此简单验证成功。其他问题参考《kubenetes学习二》