美文网首页高效运维
k8s高可用集群搭建

k8s高可用集群搭建

作者: 非典型_程序员 | 来源:发表于2021-01-10 16:39 被阅读0次

    在之前的文章使用kubeadm搭建k8s集群介绍了如何搭建一个简单的单master的k8s集群,但是在实际应用中很少使用单个master的集群。毕竟单一master节点挂掉整个集群也就挂掉了,因此今天就来尝试一下搭建一个高可用的k8s集群。
    官方提供了2种高可用的部署方式,一种是外部ETCD的方式,即部署一个单独的ETCD集群,另一种就是混合部署,ETCDapiserver一起部署。我们采用第二种方式部署,一是部署简单,不需要在单独部署ETCD,另一个因素就是节约服务器。

    方式1.png
    方式2.png

    高可用的可参考官方文档。另外在LB的选择上可以看文档High Availability Considerations。我选择的是keepalivedhaproxy,下面正式开始。

    一、 服务器规划

    首先准备几台服务器,计划部署3台master,3台keepalivedhaproxy,为了节约服务器,我将keepalivedhaproxymaster一起部署,另外准备一台服务器作为VIP。服务器规划如下:

    角色 ip地址
    k8s-vip 172.27.0.15
    k8s-master01 172.27.0.17
    k8s-master02 172.27.0.9
    k8s-master03 172.27.0.8

    二、 环境准备

    这部分在每台服务器上都执行,当然有部分是没必要的,不过为了统一就都处理了。

    1 设置hostname

    hostnamectl set-hostname <hostname>
    

    2 修改hosts文件

    vi /etc/hosts
    ## 添加内容
    172.27.0.17     k8s-master01
    172.27.0.9      k8s-master02
    172.27.0.8    k8s-master03
    172.27.0.15     k8s-vip
    

    3 关闭防火墙等

    ## 配置内核参数,将桥接的IPv4流量传递到iptables的链
    cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    EOF
    ## 手动加载配置文件
    sysctl --system
    ## 防火墙关闭
    systemctl stop firewalld
    systemctl disable firewalld
    ## 将 SELinux 设置为 permissive 模式(相当于将其禁用)
    setenforce 0
    sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
    ## 关闭交换空间
    swapoff -a
    sed -i 's/.*swap.*/#&/' /etc/fstab
    ## ip转发
    echo '1' > /proc/sys/net/ipv4/ip_forward
    

    三、 安装keepalived 和 haproxy

    1 安装keepalived 和 haproxy

    yum install keepalived haproxy -y
    

    2 配置 keepalived

    cat <<EOF > /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"
      interval 3
      weight -2
      fall 10
      rise 2
    }
    
    vrrp_instance VI_1 {
        state  ${STATE} 
        interface ${INTERFACE}
        virtual_router_id  ${ROUTER_ID}
        priority ${PRIORITY}
        authentication {
            auth_type PASS
            auth_pass ${AUTH_PASS}
        }
        virtual_ipaddress {
            ${APISERVER_VIP}
        }
        track_script {
            check_apiserver
        }
    }
    
    EOF
    

    在上面的文件中替换自己相应的内容:
    ${STATE}如果是主节点 则为MASTER 其他则为 BACKUP。我这里选择k8s-master01MASTERk8s-master02k8s-master03BACKUP
    ${INTERFACE}是网络接口,即服务器网卡的,我的服务器均为eth0
    ${ROUTER_ID} 这个值只要在keepalived集群中保持一致即可,我使用的是默认值51;
    ${PRIORITY} 优先级,在master上比在备份服务器上高就行了。我的master设为100,备份服务50;
    ${AUTH_PASS} 这个值只要在keepalived集群中保持一致即可;
    ${APISERVER_VIP} 就是VIP的地址,我的为:172.27.0.15。

    3 配置 keepalived健康检查

    在上面的配置中我们也配置健康检查的参数,比如检查间隔时间,权重等等。
    创建脚本

    vi /etc/keepalived/check_apiserver.sh
    ### 添加内容
    #!/bin/sh
    
    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
    

    ${APISERVER_VIP} 就是VIP的地址,172.27.0.15;
    ${APISERVER_DEST_PORT} 这个是和apiserver交互的端口号,其实就是HAProxy绑定的端口号,因为HAProxy和k8s一起部署,这里做一个区分,我使用了16443,这个下面会说到。

    4 配置haproxy

    # /etc/haproxy/haproxy.cfg
    #---------------------------------------------------------------------
    # Global settings
    #---------------------------------------------------------------------
    global
        log /dev/log local0
        log /dev/log local1 notice
        daemon
    
    #---------------------------------------------------------------------
    # common defaults that all the 'listen' and 'backend' sections will
    # use if not designated in their block
    #---------------------------------------------------------------------
    defaults
        mode                    http
        log                     global
        option                  httplog
        option                  dontlognull
        option http-server-close
        option forwardfor       except 127.0.0.0/8
        option                  redispatch
        retries                 1
        timeout http-request    10s
        timeout queue           20s
        timeout connect         5s
        timeout client          20s
        timeout server          20s
        timeout http-keep-alive 10s
        timeout check           10s
    
    #---------------------------------------------------------------------
    # apiserver frontend which proxys to the masters
    #---------------------------------------------------------------------
    frontend apiserver
        bind *:${APISERVER_DEST_PORT}
        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 ${HOST1_ID} ${HOST1_ADDRESS}:${APISERVER_SRC_PORT} check
    

    上面的配置需要修改为自己的配置:
    ${APISERVER_DEST_PORT} 这个值同上面的健康检查脚本里面的值一样,我这里使用16443;
    ${HOST1_ID} ${HOST1_ADDRESS}:${APISERVER_SRC_PORT} 其实就是你的k8s主节点的配置,比如我的配置是:

       ### server ${HOST1_ID} ${HOST1_ADDRESS}:${APISERVER_SRC_PORT} check
        server k8s-master01 172.27.0.17:6443 check
        server k8s-master02 172.27.0.9:6443 check
        server k8s-master03 172.27.0.8:6443 check
    

    上面的配置完成后启动keepalivedhaproxy,并设置为自动启动。

    systemctl enable haproxy --now
    systemctl enable keepalived --now
    

    四、安装k8s

    1 安装docker

    安装所需的包

    yum install -y yum-utils device-mapper-persistent-data lvm2
    

    添加docker国内仓库

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

    安装docker

    # 最新版版本
    yum install docker-ce docker-ce-cli containerd.io
    # 指定版本
    yum install -y  containerd.io-1.2.13 docker-ce-19.03.11 docker-ce-cli-19.03.11  
    

    2 配置docker

    创建docker目录

    mkdir /etc/docker
    

    添加配置

    cat > /etc/docker/daemon.json <<EOF
    {
      "exec-opts": ["native.cgroupdriver=systemd"],
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "100m"
      },
      "registry-mirrors": ["https://0gbs116j.mirror.aliyuncs.com","https://registry.docker-cn.com","https://mirror.ccs.tencentyun.com","https://docker.mirrors.ustc.edu.cn"],
      "storage-driver": "overlay2",
      "storage-opts": [
        "overlay2.override_kernel_check=true"
      ]
    }
    EOF
    

    设置docker自启动

    mkdir -p /etc/systemd/system/docker.service.d
    
    systemctl enable docker
    systemctl daemon-reload
    systemctl restart docker
    

    3 安装kubelet、kubeadm、kubectl

    配置阿里云仓库

    cat <<EOF > /etc/yum.repos.d/kubernetes.repo
    [kubernetes]
    name=Kubernetes
    baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
    enabled=1
    gpgcheck=1
    repo_gpgcheck=1
    gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
    EOF
    

    安装kubeletkubeadmkubectl

    ## 最新版本
    yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
    ## 指定版本
    yum install -y kubelet-1.18.6  kubeadm-1.18.6  kubectl-1.18.6 --disableexcludes=kubernetes
    

    kubelet设置自启动

    systemctl enable --now kubelet
    

    以上内容在3台master服务器上均需要执行。

    五、master初始化

    关于master初始化我选择在k8s-master01上执行:

    kubeadm init  --control-plane-endpoint "k8s-vip:16443" \
    --image-repository registry.aliyuncs.com/google_containers \
    --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16 \
    --upload-certs | tee kubeadm-init.log
    

    待初始完成后有一部分日志输出,这其中有两部分内容需要我们记住:

    初始化日志.png
    根据日志内容我们可以看到有两个join的输出,其中最面上的是control-plane node,即主节点的join命令,下面的则是worker node的join命令,一定别弄错了。
    k8s-master01配置环境变量:
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    

    k8s-master02k8s-master03执行join命令,如下:

    kubeadm join k8s-vip:16443 --token j3vjyp.9namdndnyigysdp2 \
        --discovery-token-ca-cert-hash sha256:ad6b80c857adc41cb585f5fab771a064b13c2d069090365fa1f6d4cbefb5c257 \
        --control-plane --certificate-key a2828d4279238f976ce580977e5e113dddacd4ae0dd00903d4ebef8627ba33d1
    

    这时候在k8s-master01执行:

    kubectl get node
    

    会发现都是NotReay,接下里就配置网络组建,我这里依然使用calico,在k8s-master01执行:

    kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
    

    然后在看就发现节点全部正常了,如下图:

    节点图.png
    在看下系统的其他组件,在k8s-master01执行:
    kubectl get pod -n kube-system -o wide
    

    如下图:


    集群组件.png

    六、最后

    接下来我们需要把k8s-master01/etc/kubernetes/admin.conf配置文件拷贝的其他主节点上去,当然也可以复制到普通的worker节点,这都没什么问题,也可以加入接普通的worker节点,因为我没买那么多服务器就没有做这一步了,理论上应该没什么问题的。需要注意的是初始化生成的证书只有两个小时的有效时间,如果证书过期的话需要在master重新生成证书。
    其实相对来讲高可用的k8s集群和之前部署的单master部署没有很大的区别,关键其实在于keepalivedhaproxy的安装配置,还有就是master节点和worker节点加入的命令稍微有一点区别。整体来看其实不复杂,但是因为自己对keepalived、haproxy都不熟悉,所以中间还是走了一些弯路,好在文档还是比较详细的,所以最终还是顺利完成了高可用集群部署。今天的学习就到这里,最后希望大家能够关注一下我的VX个人号超超学堂,如果各位小伙伴有什么问题都可以找我交流哦,谢谢大家~~~

    相关文章

      网友评论

        本文标题:k8s高可用集群搭建

        本文链接:https://www.haomeiwen.com/subject/oewkaktx.html