搜索结果

×

搜索结果将在这里显示。

🌻 05-kubeadm部署生产级多Master高可用K8s集群

一、集群整体规划

1. 网络网段规划

  • Pod网段(podSubnet):10.244.0.0/16

  • Service网段(serviceSubnet):10.96.0.0/16

  • 高可用虚拟VIP:192.168.40.199

2. 节点角色规划

角色 主机名 IP地址 核心组件
控制节点Master1 zhappymaster1 192.168.40.180 apiserver、controller-manager、scheduler、kubelet、etcd、docker、kube-proxy、keepalived、nginx、calico
控制节点Master2 zhappymaster2 192.168.40.181 apiserver、controller-manager、scheduler、kubelet、etcd、docker、kube-proxy、keepalived、nginx、calico
工作节点Node1 zhappynode1 192.168.40.182 kubelet、kube-proxy、docker、calico、coredns

3. 系统环境要求

  • 操作系统:CentOS 7.6 / 7.9

  • 硬件配置:4GiB内存 / 4vCPU / 60G硬盘

  • 网络:NAT模式,虚拟机开启CPU虚拟化支持

4. kubeadm vs 二进制安装对比

部署方式 核心特点 适用场景
kubeadm 官方自动化工具,组件以Pod运行具备故障自愈能力;部署快捷,屏蔽底层细节,排障门槛稍高 高频部署、自动化要求高的生产环境
二进制 手动逐组件部署,对K8s架构理解更深入,排障清晰;部署流程繁琐 定制化需求高、希望深度掌握原理的场景

两种方式生产环境运行均稳定可靠,可根据团队技术栈与运维能力选择。


二、集群环境初始化(所有节点执行)

1. 配置静态IP

修改网卡配置(网卡名以实际为准,示例为ens33):

vim /etc/sysconfig/network-scripts/ifcfg-ens33

核心配置:

BOOTPROTO=static
IPADDR=192.168.40.180   # 替换为对应节点IP
NETMASK=255.255.255.0
GATEWAY=192.168.40.2
DNS1=192.168.40.2
ONBOOT=yes
NAME=ens33
DEVICE=ens33

重启网络生效:

service network restart

2. 关闭SELinux

# 临时关闭
setenforce 0
# 永久关闭,重启后生效
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# 验证状态,输出 Disabled 即为成功
getenforce

3. 设置主机名

分别在对应节点执行:

# Master1执行
hostnamectl set-hostname zhappymaster1 && bash

# Master2执行
hostnamectl set-hostname zhappymaster2 && bash

# Node1执行
hostnamectl set-hostname zhappynode1 && bash

可选操作:执行 yum update -y 将系统从CentOS7.6升级至7.9。

4. 配置主机名解析

所有节点的/etc/hosts添加节点映射:

cat >> /etc/hosts <<EOF
192.168.40.180   zhappymaster1
192.168.40.181   zhappymaster2
192.168.40.182   zhappynode1
EOF

5. 配置节点间SSH免密登录

分别在三个节点生成密钥并分发至所有节点:

# 生成密钥,一路回车即可
ssh-keygen

# 分发公钥,按提示输入yes与密码
ssh-copy-id zhappymaster1
ssh-copy-id zhappymaster2
ssh-copy-id zhappynode1

6. 关闭Swap交换分区

K8s默认禁用Swap以保证性能,未关闭会导致初始化失败。

# 临时关闭
swapoff -a

# 永久关闭:注释fstab中swap挂载行
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

说明:若必须保留Swap,可在kubeadm命令后追加--ignore-preflight-errors=Swap跳过检测。

7. 配置内核网络参数

加载桥接模块,开启IP转发与网桥iptables支持:

# 加载br_netfilter内核模块
modprobe br_netfilter
echo "modprobe br_netfilter" >> /etc/profile

# 写入内核配置
cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

# 生效配置
sysctl -p /etc/sysctl.d/k8s.conf

参数作用:

  • bridge-nf-call-iptables:让网桥流量经过iptables链,是容器网络插件的基础依赖

  • ip_forward:开启IP数据包转发,实现跨节点容器网络互通

8. 关闭firewalld防火墙

systemctl stop firewalld
systemctl disable firewalld

9. 配置软件源

  1. 备份原有YUM源,替换为阿里云CentOS基础源+epel源

  2. 添加Docker阿里云YUM源:

yum install yum-utils -y
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

10. 配置K8s阿里云YUM源

在Master1创建源文件,再分发到其他节点:

cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
EOF

# 分发至另外两个节点
scp /etc/yum.repos.d/kubernetes.repo zhappymaster2:/etc/yum.repos.d/
scp /etc/yum.repos.d/kubernetes.repo zhappynode1:/etc/yum.repos.d/

11. 配置时间同步

# 安装同步工具
yum install ntpdate -y
# 立即同步时间
ntpdate cn.pool.ntp.org

# 添加定时任务,每小时同步一次
crontab -e
# 写入以下内容
* */1 * * * /usr/sbin/ntpdate cn.pool.ntp.org

# 重启定时任务
service crond restart

12. 安装基础依赖包

yum install -y yum-utils device-mapper-persistent-data lvm2 wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack ntpdate telnet

三、安装Docker服务(所有节点执行)

1. 安装指定版本Docker

yum install docker-ce-20.10.6 docker-ce-cli-20.10.6 containerd.io -y

2. 启动并设置开机自启

systemctl start docker
systemctl enable docker
systemctl status docker

3. 配置镜像加速器与Cgroup驱动

cat > /etc/docker/daemon.json <<EOF
{
 "registry-mirrors":["https://rsbud4vc.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

重要:Kubelet默认使用systemd作为cgroup驱动,Docker默认为cgroupfs,两者必须一致,否则集群启动失败。

重启Docker生效:

systemctl daemon-reload
systemctl restart docker

四、安装K8s核心组件(所有节点执行)

1. 安装指定版本组件

yum install -y kubelet-1.20.6 kubeadm-1.20.6 kubectl-1.20.6

2. 设置kubelet开机自启

systemctl enable kubelet

组件说明:

  • kubeadm:K8s集群自动化初始化工具

  • kubelet:运行在所有节点,负责Pod生命周期管理、与APIServer通信

  • kubectl:K8s命令行客户端,用于集群资源管理与操作


五、Keepalived+Nginx实现APIServer高可用(两个Master节点执行)

方案原理

  • Nginx做四层负载均衡,将请求转发至两台Master的6443端口

  • Keepalived提供虚拟VIP,实现Nginx主备故障自动切换

  • Nginx监听16443端口,避免与宿主机APIServer的6443端口冲突

1. 安装依赖软件

yum install nginx keepalived nginx-mod-stream -y

2. 配置Nginx四层负载(两个Master配置一致)

vim /etc/nginx/nginx.conf

完整配置:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

# 四层负载:转发APIServer请求
stream {
    log_format  main  '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
    access_log  /var/log/nginx/k8s-access.log  main;

    upstream k8s-apiserver {
        server 192.168.40.180:6443 weight=5 max_fails=3 fail_timeout=30s;
        server 192.168.40.181:6443 weight=5 max_fails=3 fail_timeout=30s;
    }

    server {
       listen 16443;
       proxy_pass k8s-apiserver;
    }
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    server {
        listen       80 default_server;
        server_name  _;
    }
}

3. 配置Keepalived

(1)Master1(主节点)配置

vim /etc/keepalived/keepalived.conf
global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id NGINX_MASTER
}

# Nginx健康检查脚本
vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33        # 修改为实际网卡名
    virtual_router_id 51   # 主备节点必须一致
    priority 100           # 优先级,主节点高于备节点
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    # 虚拟VIP地址
    virtual_ipaddress {
        192.168.40.199/24
    }
    track_script {
        check_nginx
    }
}

(2)Master2(备节点)配置

vim /etc/keepalived/keepalived.conf
global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id NGINX_BACKUP
}

vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.40.199/24
    }
    track_script {
        check_nginx
    }
}

4. 创建Nginx健康检查脚本(两个Master都配置)

vim /etc/keepalived/check_nginx.sh
#!/bin/bash
# 检测Nginx进程是否存活
counter=$(ps -ef |grep nginx | grep sbin | egrep -cv "grep|$$" )
if [ $counter -eq 0 ]; then
    # 尝试启动Nginx
    service nginx start
    sleep 2
    counter=$(ps -ef |grep nginx | grep sbin | egrep -cv "grep|$$" )
    # 启动失败则停止Keepalived,触发VIP漂移
    if [ $counter -eq 0 ]; then
        service keepalived stop
    fi
fi

授权可执行:

chmod +x /etc/keepalived/check_nginx.sh

5. 启动服务

systemctl daemon-reload
systemctl start nginx
systemctl start keepalived
systemctl enable nginx keepalived

6. 验证VIP与故障切换

  1. 查看VIP是否绑定在Master1:
ip addr
# ens33网卡下出现 192.168.40.199 即为成功
  1. 故障切换测试:停止Master1的keepalived,观察VIP漂移至Master2
# Master1执行
service keepalived stop

# Master2查看
ip addr
  1. 恢复Master1服务,VIP自动漂移回主节点
systemctl start keepalived

六、kubeadm初始化K8s集群(Master1执行)

1. 导入离线镜像(所有节点)

提前将k8simage-1-20-6.tar.gz上传至所有节点,导入镜像:

docker load -i k8simage-1-20-6.tar.gz

2. 编写初始化配置文件

cd /root/
vim kubeadm-config.yaml

配置内容:

apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.20.6
controlPlaneEndpoint: 192.168.40.199:16443  # 高可用VIP入口
imageRepository: registry.aliyuncs.com/google_containers
apiServer:
  certSANs:
  - 192.168.40.180
  - 192.168.40.181
  - 192.168.40.182
  - 192.168.40.199
networking:
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.96.0.0/16
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind:  KubeProxyConfiguration
mode: ipvs

说明:

  • controlPlaneEndpoint:所有节点统一通过VIP访问APIServer

  • certSANs:APIServer证书信任的IP列表

  • mode: ipvs:kube-proxy采用IPVS模式,性能远高于默认iptables,生产环境推荐

3. 执行集群初始化

kubeadm init --config kubeadm-config.yaml --ignore-preflight-errors=SystemVerification

初始化成功后会输出Master节点加入命令Worker节点加入命令,请务必保存好token和hash值。

4. 配置kubectl管理员权限

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

5. 查看节点初始状态

kubectl get nodes

此时节点状态为NotReady属于正常现象,原因是尚未安装网络插件。


七、扩容集群节点

1. 添加第二个Master控制节点

(1)拷贝集群证书到Master2

Master1执行,将证书分发至Master2:

# 先在Master2创建目录
ssh zhappymaster2 "mkdir -p /etc/kubernetes/pki/etcd && mkdir -p ~/.kube/"

# 批量拷贝证书
scp /etc/kubernetes/pki/ca.crt zhappymaster2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/ca.key zhappymaster2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/sa.key zhappymaster2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/sa.pub zhappymaster2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/front-proxy-ca.crt zhappymaster2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/front-proxy-ca.key zhappymaster2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/etcd/ca.crt zhappymaster2:/etc/kubernetes/pki/etcd/
scp /etc/kubernetes/pki/etcd/ca.key zhappymaster2:/etc/kubernetes/pki/etcd/

(2)生成节点加入命令(Master1执行)

kubeadm token create --print-join-command

(3)Master2执行加入命令

在join命令后追加--control-plane表示加入控制平面:

kubeadm join 192.168.40.199:16443 --token 你的token值 \
    --discovery-token-ca-cert-hash sha256:你的hash值 \
    --control-plane --ignore-preflight-errors=SystemVerification

2. 添加Worker工作节点

(1)生成加入命令(Master1执行)

kubeadm token create --print-join-command

(2)Node1执行加入

kubeadm join 192.168.40.199:16443 --token 你的token值 \
    --discovery-token-ca-cert-hash sha256:你的hash值 \
    --ignore-preflight-errors=SystemVerification

(3)给Worker节点打角色标签

kubectl label node zhappynode1 node-role.kubernetes.io/worker=worker

八、安装Calico网络插件(Master1执行)

1. 部署Calico

上传calico.yaml文件,或在线下载:

# 在线下载(可选)
# wget https://docs.projectcalico.org/manifests/calico.yaml

kubectl apply -f calico.yaml

2. 验证Pod状态

kubectl get pods -n kube-system

等待所有calico相关Pod变为Running,CoreDNS也会从Pending转为正常运行。

3. 验证节点状态

kubectl get nodes

所有节点STATUS变为Ready,说明集群网络正常。


九、集群功能验证

1. 验证Pod外网访问能力

导入busybox测试镜像(node节点):

docker load -i busybox-1-28.tar.gz

启动临时测试Pod(master节点):

kubectl run busybox --image busybox:1.28 --restart=Never --rm -it -- sh

容器内执行ping测试:

ping www.baidu.com

能正常通说明容器外网网络正常。

2. 验证CoreDNS域名解析

在busybox容器内执行:

nslookup kubernetes.default.svc.cluster.local

能正常解析出Service IP则集群DNS服务正常。

注意:必须使用busybox 1.28版本,高版本存在nslookup解析异常问题。


十、延长K8s证书有效期

kubeadm默认签发的APIServer组件证书有效期为1年,CA根证书为10年,可通过脚本将组件证书延长至10年。

1. 查看证书有效期

# 查看CA根证书有效期
openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -text | grep Not

# 查看APIServer证书有效期
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep Not

2. 执行续期脚本(两个Master节点都执行)

上传update-kubeadm-cert.sh脚本至两个Master节点:

# 授权可执行
chmod +x update-kubeadm-cert.sh

# 执行全量证书续期,延长至10年
./update-kubeadm-cert.sh all

3. 验证续期结果

openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep Not

有效期变为10年即为操作成功。