• 【云原生】无VIP稳定性和可扩展性更强的k8s高可用方案讲解与实战操作


    一、概述

    在前面我的文章里或者网上其它资料讲高可用方案,基本上大多数使用Keepalived VIP的方案,但是这种方案并不是最佳的,还有更优的高可用方案,下面将详细介绍。如果小伙伴对k8s master Keepalived VIP的方案不了解的,可以参考我这篇文章:Kubernetes(k8s)最新版最完整版环境部署+master高可用实现(k8sV1.24.1+dashboard+harbor)

    二、架构

    在这里插入图片描述

    在这里插入图片描述

    三、开始部署

    1)节点信息

    hostnameIP角色
    local-168-182-110192.168.182.110master
    local-168-182-111192.168.182.110node
    local-168-182-112192.168.182.110node
    local-168-182-113192.168.182.113master
    local-168-182-130192.168.182.130master

    2)前期准备(所有节点)

    1、配置hosts
    192.168.182.110 local-168-182-110
    192.168.182.111 local-168-182-111
    192.168.182.112 local-168-182-112
    192.168.182.113 local-168-182-113
    192.168.182.130 local-168-182-130
    
    • 1
    • 2
    • 3
    • 4
    • 5
    2、配置互信
    # 直接一直回车就行
    ssh-keygen
    
    ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-110
    ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-111
    ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-112
    ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-113
    ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-130
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    3、时间同步
    yum install chrony -y
    systemctl start chronyd
    systemctl enable chronyd
    systemctl status chronyd
    chronyc sources
    
    • 1
    • 2
    • 3
    • 4
    • 5
    4、关闭防火墙
    systemctl stop firewalld
    systemctl disable firewalld
    
    • 1
    • 2
    5、禁用SELinux
    # 临时关闭
    setenforce 0
    # 永久禁用
    sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
    
    • 1
    • 2
    • 3
    • 4
    6、关闭swap
    # 临时关闭;关闭swap主要是为了性能考虑
    swapoff -a
    # 可以通过这个命令查看swap是否关闭了
    free
    # 永久关闭        
    sed -ri 's/.*swap.*/#&/' /etc/fstab
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    7、设置bridge-nf-call-iptables
    cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
    overlay
    br_netfilter
    EOF
    
    sudo modprobe overlay
    sudo modprobe br_netfilter
    
    # 设置所需的 sysctl 参数,参数在重新启动后保持不变
    cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
    net.bridge.bridge-nf-call-iptables  = 1
    net.bridge.bridge-nf-call-ip6tables = 1
    net.ipv4.ip_forward                 = 1
    EOF
    
    # 应用 sysctl 参数而不重新启动
    sudo sysctl --system
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3)安装容器docker(所有节点)

    # 配置yum源
    cd /etc/yum.repos.d ; mkdir bak; mv CentOS-Linux-* bak/
    # centos7
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    
    # 安装yum-config-manager配置工具
    yum -y install yum-utils
    # 设置yum源
    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    # 安装docker-ce版本
    yum install -y docker-ce
    # 启动并设置开机自启
    # 设置为开机自启并现在立刻启动服务 --now:立刻启动服务
    systemctl enable --now docker
    
    # 查看版本号
    docker --version
    # 查看版本具体信息
    docker version
    
    # Docker镜像源设置
    # 修改文件 /etc/docker/daemon.json,没有这个文件就创建
    # 配置docker cgroup 驱动程序systemd
    # 添加以下内容后,重启docker服务:
    cat >/etc/docker/daemon.json<<EOF
    {
       "registry-mirrors": ["http://hub-mirror.c.163.com"],
        "exec-opts": ["native.cgroupdriver=systemd"]
    }
    EOF
    # 加载
    systemctl restart docker
    
    # 查看
    systemctl status docker
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    4)配置k8s yum源(所有节点)

    cat > /etc/yum.repos.d/kubernetes.repo << EOF
    [k8s]
    name=k8s
    enabled=1
    gpgcheck=0
    baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5)开始安装kubeadm,kubelet和kubectl(所有节点)

    # 查找所有的版本,这里选择1.23.x版本
    yum --showduplicates list kubelet
    
    # disableexcludes=kubernetes:禁掉除了这个kubernetes之外的别的仓库
    yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6 --disableexcludes=kubernetes
    
    # 设置为开机自启并现在立刻启动服务 --now:立刻启动服务
    systemctl enable --now kubelet
    
    # 查看状态,这里需要等待一段时间再查看服务状态,启动会有点慢
    systemctl status kubelet
    
    # 查看版本
    kubectl version
    yum info kubeadm
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    6)使用 kubeadm 初始化集群(第一个master节点)

    最好提前把镜像下载好,这样安装快

    docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.23.6
    docker pull registry.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6
    docker pull registry.aliyuncs.com/google_containers/kube-scheduler:v1.23.6
    docker pull registry.aliyuncs.com/google_containers/kube-proxy:v1.23.6
    docker pull registry.aliyuncs.com/google_containers/pause:3.6
    docker pull registry.aliyuncs.com/google_containers/etcd:3.5.1-0
    docker pull registry.aliyuncs.com/google_containers/coredns:v1.8.6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    集群初始化

    kubeadm init \
      --apiserver-advertise-address=192.168.182.110 \
      --image-repository registry.aliyuncs.com/google_containers \
      --kubernetes-version v1.23.6 \
      --control-plane-endpoint=192.168.182.110 \
      --service-cidr=10.1.0.0/16 \
      --pod-network-cidr=10.244.0.0/16 \
      --v=5
    # –image-repository string:    这个用于指定从什么位置来拉取镜像(1.13版本才有的),默认值是k8s.gcr.io,我们将其指定为国内镜像地址:registry.aliyuncs.com/google_containers
    # –kubernetes-version string:  指定kubenets版本号,默认值是stable-1,会导致从https://dl.k8s.io/release/stable-1.txt下载最新的版本号,我们可以将其指定为固定版本(v1.22.1)来跳过网络请求。
    # –apiserver-advertise-address  指明用 Master 的哪个 interface 与 Cluster 的其他节点通信。如果 Master 有多个 interface,建议明确指定,如果不指定,kubeadm 会自动选择有默认网关的 interface。这里的ip为master节点ip,记得更换。
    # –pod-network-cidr             指定 Pod 网络的范围。Kubernetes 支持多种网络方案,而且不同网络方案对  –pod-network-cidr有自己的要求,这里设置为10.244.0.0/16 是因为我们将使用 flannel 网络方案,必须设置成这个 CIDR。
    # --control-plane-endpoint     cluster-endpoint 是映射到该 IP 的自定义 DNS 名称,这里配置hosts映射:127.0.0.1   cluster-endpoint。 这将允许你将 --control-plane-endpoint=cluster-endpoint 传递给 kubeadm init,并将相同的 DNS 名称传递给 kubeadm join。 稍后你可以修改 cluster-endpoint 以指向高可用性方案中的负载均衡器的地址。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

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

    查看节点信息

    kubectl get nodes
    
    • 1

    在这里插入图片描述
    发现节点是NotReady状态,查看日志是因为没有装CNI网络插件,接下来就开始安装Calico 网络插件,当然也可以选择其它网络插件。

    7)安装Calico网络插件

    wget https://docs.projectcalico.org/manifests/calico.yaml
    kubectl apply -f calico.yaml
    
    # 查看
    kubectl get all -n kube-system|grep calico
    
    # 等calico pod都正常了,再查看节点状态
    kubectl get pods -A
    kubectl get nodes
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    8)配置IPVS(所有节点)

    1、加载ip_vs相关内核模块
    modprobe -- ip_vs
    modprobe -- ip_vs_sh
    modprobe -- ip_vs_rr
    modprobe -- ip_vs_wrr
    
    • 1
    • 2
    • 3
    • 4

    所有节点验证开启了ipvs:

    lsmod |grep ip_vs
    
    • 1
    2、安装ipvsadm工具
    yum install ipset ipvsadm -y
    
    • 1
    3、编辑kube-proxy配置文件,mode修改成ipvs
    kubectl edit  configmap -n kube-system  kube-proxy
    
    • 1
    4、重启kube-proxy
    # 先查看
    kubectl get pod -n kube-system | grep kube-proxy
    # 再delete让它自拉起
    kubectl get pod -n kube-system | grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'
    # 再查看
    kubectl get pod -n kube-system | grep kube-proxy
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    9)master节点加入集群

    【问题】

    One or more conditions for hosting a new control plane instance is not satisfied. unable to add a new control plane instance to a cluster that doesn't have a stable controlPlaneEndpoint address

    【解决】添加如下配置:

    # controlPlaneEndpoint: 192.192.168.110
    kubectl edit cm kubeadm-config -n kube-system
    
    • 1
    • 2

    在这里插入图片描述
    开始执行下面的命令将master节点加入集群

    # 在第一个master节点上执行以下获取执行命令
    # 证如果过期了,可以使用下面命令生成新证书上传,这里会打印出certificate key,后面会用到
    CERT_KEY=`kubeadm init phase upload-certs --upload-certs|tail -1`
    
    # 其中 --ttl=0 表示生成的 token 永不失效. 如果不带 --ttl 参数, 那么默认有效时间为24小时. 在24小时内, 可以无数量限制添加 worker.
    echo `kubeadm token create --print-join-command --ttl=0` " --control-plane --certificate-key $CERT_KEY --v=5"
    
    # 拿到上面打印的命令在需要添加的节点上执行
    
    # --control-plane 标志通知 kubeadm join 创建一个新的控制平面。加入master必须加这个标记
    # --certificate-key ... 将导致从集群中的 kubeadm-certs Secret 下载控制平面证书并使用给定的密钥进行解密。这里的值就是上面这个命令(kubeadm init phase upload-certs --upload-certs)打印出的key。
    
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    等网络插件自动安装完后,再查看节点状态

    kubectl get nodes
    
    • 1

    在这里插入图片描述

    10)修改master节点指向自己apiserver

    1、修改配置
    cd /etc/kubernetes
    # 修改/etc/kubernetes/admin.conf,/etc/kubernetes/kubelet.conf文件中的server ip改成127.0.0.1
    vi /etc/kubernetes/admin.conf
    vi /etc/kubernetes/kubelet.conf
    
    # 覆盖配置
    cp /etc/kubernetes/admin.conf ~/.kube/config
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    2、删除旧的证书,生成新证书
    cd /etc/kubernetes/pki
    
    # 先备份
    mv apiserver.key apiserver.key.bak
    mv apiserver.crt apiserver.crt.bak
    
    # 使用如下命令生成,分别在三个master节点上执行
    kubeadm init phase certs apiserver --apiserver-advertise-address 192.168.182.110 --apiserver-cert-extra-sans "127.0.0.1,10.1.0.1"
    
    kubeadm init phase certs apiserver --apiserver-advertise-address 192.168.182.113 --apiserver-cert-extra-sans "127.0.0.1,10.1.0.1"
    
    kubeadm init phase certs apiserver --apiserver-advertise-address 192.168.182.130 --apiserver-cert-extra-sans "127.0.0.1,10.1.0.1"
    #  --apiserver-cert-extra-sans "127.0.0.1":设置了这个,之后加入节点验证证书阶段就不会报错了。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    3、修改apiserver
    kubectl -n kube-system edit cm kubeadm-config -o yaml
    
    • 1

    在这里插入图片描述

    4、修改kube-prxoy配置
    kubectl edit cm kube-proxy -oyaml -n kube-system
    
    • 1

    在这里插入图片描述
    重启

    kubectl delete pod -n kube-system `kubectl get pods  -n kube-system|grep kube-proxy|awk '{print $1}'`
    
    • 1
    5、重启docker和kubelet
    systemctl restart docker kubelet
    
    • 1

    11)node节点上安装nginx

    这里使用nginx四层代理

    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    yum makecache
    yum install epel-release
    yum -y install nginx
    yum -y install nginx-all-modules.noarch
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    配置nginx,在nginx.conf添加如下配置:

    stream {                          #实现四层代理功能
        upstream kube_apiserver {            #定义集群,kube_apiserver是集群名称,可自行定义
            least_conn;# 默认调度策略是轮询,在轮询中,如果服务器down掉了,会自动剔除该服务器。
            server local-168-182-110:6443 max_fails=3 fail_timeout=30s;   #集群组是三台服务器k8s apiserver组成
            server local-168-182-113:6443 max_fails=3 fail_timeout=30s;
            server local-168-182-130:6443 max_fails=3 fail_timeout=30s;
        }
        server {                            #定义一个服务
            listen 127.0.0.1:6443;             #需要监听的端口
            proxy_pass kube_apiserver;       #调用集群
            proxy_connect_timeout 10s;					# 连接超时时间
            proxy_timeout 300s;							# 端口保持时间
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    12)node节点加入集群

    
    # 在第一个master节点上执行以下获取执行命令
    # 证如果过期了,可以使用下面命令生成新证书上传,这里会打印出certificate key,后面会用到
    CERT_KEY=`kubeadm init phase upload-certs --upload-certs|tail -1`
    
    # 其中 --ttl=0 表示生成的 token 永不失效. 如果不带 --ttl 参数, 那么默认有效时间为24小时. 在24小时内, 可以无数量限制添加 worker.
    echo `kubeadm token create --print-join-command --ttl=0` " --certificate-key $CERT_KEY --v=5"
    # 示例如下:
    kubeadm join 127.0.0.1:6443 --token esczfh.6ckynzi6wfj8jhnk --discovery-token-ca-cert-hash sha256:bc8fb85184ed235b88afdba38f0a17976d353abb10d0739d25df452745d1eed8  --certificate-key a126867ad4d91721f157660df77cdea7862ebda8371280c3025c4cc45c23b85f --v=5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    修改/etc/kubernetes/kubelet.conf配置

    在这里插入图片描述
    重启

    systemctl restart kubelet
    
    • 1

    等网络插件自动安装完后,再查看节点状态

    kubectl get nodes
    kubectl get pods -A
    
    • 1
    • 2

    在这里插入图片描述

    13)卸载

    kubeadm reset
    rm -rf /etc/kubernetes/*
    rm -fr ~/.kube
    rm -fr /var/lib/etcd
    
    • 1
    • 2
    • 3
    • 4

    四、高可用故障模式测试

    1)master节点故障模拟(一个master故障)

    # 关机192.168.182.110
    showdown -h now
    # 在其它master节点上查看节点状态
    kubectl get nodes
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    【结论】如上图可知,挂一个master节点不影响集群。

    2)master节点故障模拟(两个master故障)

    # 关机192.168.182.113
    showdown -h now
    # 在其它master节点上查看节点状态
    kubectl get nodes
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    【结论】如上图可知,挂两个master节点,整个集群不可用,还是之前说的,三个master节点只允许挂一个master节点,这里就不细说了,可以参考我之前的文章:【云原生】K8S master节点更换IP以及master高可用故障模拟测试

    无VIP稳定性更强的k8s高可用方案讲解就先到这里了,也是我们目前生成环境中使用的方案,小伙伴有任何疑问,欢迎给我留言,后续会持续更新【云原生+大数据】相关的文章,请小伙伴耐心等待~

  • 相关阅读:
    ICDE‘22推荐系统论文之Research篇
    基于ZYNQ-7000的AI加速器设计之Python网络编程(TCP协议)
    springboot(ssm邮件过滤系统 在线邮箱平台Java(code&LW)
    火车卖票---Ticketer类
    Lambda表达式
    docker学习(十三)docker安装dejavu
    CSS3之多列布局columns学习
    玩转数组高级技法,成为JS高手
    南京邮电大学高级语言程序设计实验六(结构体与文件实验)
    leetcode - 双周赛114
  • 原文地址:https://blog.csdn.net/qq_35745940/article/details/128054456