「云原生」稳定性和可扩展性更强的k8s高可用方案讲解与实战操作

    作者:匿名更新于: 2022-11-29 21:14:15

      在前面我的文章里或者网上其它资料讲高可用方案,基本上大多数使用Keepalived VIP的方案,但是这种方案并不是最佳的,还有更优的高可用方案,下面将详细介绍。

      一、概述

      在前面我的文章里或者网上其它资料讲高可用方案,基本上大多数使用Keepalived VIP的方案,但是这种方案并不是最佳的,还有更优的高可用方案,下面将详细介绍。

      二、架构

      三、开始部署

      (1)节点信息

    hostname IP 隗定牡
    local-168-182-110 192.168.182.110 master
    local-168-182-111 192.168.182.110 node
    local-168-182-112 192.168.182.110 node
    local-168-182-113 192.168.182.113 master
    local-168-182-130 192.168.182.130 master

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

      1)配置hosts

      复制

      1.  192.168.182.110 local-168-182-110

      2.  192.168.182.111 local-168-182-111

      3.  192.168.182.112 local-168-182-112

      4.  192.168.182.113 local-168-182-113

      5.  192.168.182.130 local-168-182-130

      2)配置互信

      复制

      1.  # 直接一直回车就行

      2.  ssh-keygen

          3.

      4.  ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-110

      5.  ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-111

      6.  ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-112

      7.  ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-113

      8.  ssh-copy-id -i ~/.ssh/id_rsa.pub root@local-168-182-130

      3)时间同步

      复制

      1.  yum install chrony -y

      2.  systemctl start chronyd

      3.  systemctl enable chronyd

      4.  systemctl status chronyd

      5.  chronyc sources

      4)关闭防火墙

      复制

      1.  systemctl stop firewalld

      2.  systemctl disable firewalld

      5)禁用SELinux

      复制

      1.  # 临时关闭

      2.  setenforce 0

      3.  # 永久禁用

      4.  sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

      6)关闭swap

      复制

      1.  # 临时关闭;关闭swap主要是为了性能考虑

      2.  swapoff -a

      3.  # 可以通过这个命令查看swap是否关闭了

      4.  free

      5.  # 永久关闭

      6.  sed -ri 's/.*swap.*/#&/' /etc/fstab

      7)设置bridge-nf-call-iptables

      复制

      1.  cat <

      2.  overlay

      3.  br_netfilter

      4.  EOF

          5.

      6.  sudo modprobe overlay

      7.  sudo modprobe br_netfilter

          8.

      9.  # 设置所需的 sysctl 参数,参数在重新启动后保持不变

      10.  cat <

      11.  net.bridge.bridge-nf-call-iptables = 1

      12.  net.bridge.bridge-nf-call-ip6tables = 1

      13.  net.ipv4.ip_forward = 1

      14.  EOF

          15.

      16.  # 应用 sysctl 参数而不重新启动

      17.  sudo sysctl --system

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

      复制

      1.  # 配置yum源

      2.  cd /etc/yum.repos.d ; mkdir bak; mv CentOS-Linux-* bak/

      3.  # centos7

      4. wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

          5.

      6.  # 安装yum-config-manager配置工具

      7.  yum -y install yum-utils

      8.  # 设置yum源

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

      10.  # 安装docker-ce版本

      11.  yum install -y docker-ce

      12.  # 启动并设置开机自启

      13.  # 设置为开机自启并现在立刻启动服务 --now:立刻启动服务

      14.  systemctl enable --now docker

          15.

      16.  # 查看版本号

      17.  docker --version

      18.  # 查看版本具体信息

      19.  docker version

          20.

      21.  # Docker镜像源设置

      22.  # 修改文件 /etc/docker/daemon.json,没有这个文件就创建

      23.  # 配置docker cgroup 驱动程序systemd

      24.  # 添加以下内容后,重启docker服务:

      25.  cat >/etc/docker/daemon.json<

      26.  {

      27.  "registry-mirrors": ["http://hub-mirror.c.163.com"],

      28.  "exec-opts": ["native.cgroupdriver=systemd"]

      29.  }

      30.  EOF

      31.  # 加载

      32.  systemctl restart docker

          33.

      34.  # 查看

      35.   systemctl status docker

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

      复制

      1.  cat > /etc/yum.repos.d/kubernetes.repo << EOF

      2.  [k8s]

      3.  name=k8s

      4.  enabled=1

      5.  gpgcheck=0

      6.  baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/

      7.  EOF

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

      复制

      1.  # 查找所有的版本,这里选择1.23.x版本

      2.  yum --showduplicates list kubelet

          3.

      4.  # disableexcludes=kubernetes:禁掉除了这个kubernetes之外的别的仓库

      5.  yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6 --disableexcludes=kubernetes

          6.

      7.  # 设置为开机自启并现在立刻启动服务 --now:立刻启动服务

      8.  systemctl enable --now kubelet

          9.

      10.  # 查看状态,这里需要等待一段时间再查看服务状态,启动会有点慢

      11.  systemctl status kubelet

          12.

      13.  # 查看版本

      14.  kubectl version

      15.  yum info kubeadm

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

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

      复制

      1.  docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.23.6

      2.  docker pull registry.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6

      3.  docker pull registry.aliyuncs.com/google_containers/kube-scheduler:v1.23.6

      4.  docker pull registry.aliyuncs.com/google_containers/kube-proxy:v1.23.6

      5.  docker pull registry.aliyuncs.com/google_containers/pause:3.6

      6.  docker pull registry.aliyuncs.com/google_containers/etcd:3.5.1-0

      7.  docker pull registry.aliyuncs.com/google_containers/coredns:v1.8.6

      集群初始化

      复制

      1.  kubeadm init \\

      2.  --apiserver-advertise-address=192.168.182.110 \\

      3.  --image-repository registry.aliyuncs.com/google_containers \\

      4.  --kubernetes-version v1.23.6 \\

      5.  --control-plane-endpoint=192.168.182.110 \\

      6.  --service-cidr=10.1.0.0/16 \\

      7.  --pod-network-cidr=10.244.0.0/16 \\

      8.  --v=5

      9.  # –image-repository string: 这个用于指定从什么位置来拉取镜像(1.13版本才有的),默认值是k8s.gcr.io,我们将其指定为国内镜像地址:registry.aliyuncs.com/google_containers

      10.  # –kubernetes-version string: 指定kubenets版本号,默认值是stable-1,会导致从https://dl.k8s.io/release/stable-1.txt下载最新的版本号,我们可以将其指定为固定版本(v1.22.1)来跳过网络请求。

      11.  # –apiserver-advertise-address 指明用 Master 的哪个 interface 与 Cluster 的其他节点通信。如果 Master 有多个 interface,建议明确指定,如果不指定,kubeadm 会自动选择有默认网关的 interface。这里的ip为master节点ip,记得更换。

      12.  # –pod-network-cidr 指定 Pod 网络的范围。Kubernetes 支持多种网络方案,而且不同网络方案对 –pod-network-cidr有自己的要求,这里设置为10.244.0.0/16 是因为我们将使用 flannel 网络方案,必须设置成这个 CIDR。

      13.  # --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.  mkdir -p $HOME/.kube

      2.  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

      3.  sudo chown $(id -u):$(id -g) $HOME/.kube/config

      查看节点信息

      复制

      1.  kubectl get nodes

      

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

      (7)安装Calico网络插件

      复制

      1.  wget https://docs.projectcalico.org/manifests/calico.yaml

      2.  kubectl apply -f calico.yaml

          3.

      4.  # 查看

      5.  kubectl get all -n kube-system|grep calico

          6.

      7.  # 等calico pod都正常了,再查看节点状态

      8.  kubectl get pods -A

      9.  kubectl get nodes

      (8)配置IPVS(所有节点)

      1)加载ip_vs相关内核模块

      复制

      1.  modprobe -- ip_vs

      2.  modprobe -- ip_vs_sh

      3.  modprobe -- ip_vs_rr

      4.  modprobe -- ip_vs_wrr

      所有节点验证开启了ipvs:

      复制

      1.  lsmod |grep ip_vs

      2)安装ipvsadm工具

      复制

      1.  yum install ipset ipvsadm -y

      3)编辑kube-proxy配置文件,mode修改成ipvs

      复制

      1.  kubectl edit configmap -n kube-system kube-proxy

      4)重启kube-proxy

      复制

      1.  # 先查看

      2.  kubectl get pod -n kube-system | grep kube-proxy

      3.  # 再delete让它自拉起

      4.  kubectl get pod -n kube-system | grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'

      5.  # 再查看

      6.  kubectl get pod -n kube-system | grep kube-proxy

      (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

      【解决】添加如下配置:

      复制

      1.  # controlPlaneEndpoint: 192.192.168.110

      2.  kubectl edit cm kubeadm-config -n kube-system

      开始执行下面的命令将master节点加入集群

      复制

      1.  # 在第一个master节点上执行以下获取执行命令

      2.  # 证如果过期了,可以使用下面命令生成新证书上传,这里会打印出certificate key,后面会用到

      3.  CERT_KEY=`kubeadm init phase upload-certs --upload-certs|tail -1`

          4.

      5.  # 其中 --ttl=0 表示生成的 token 永不失效. 如果不带 --ttl 参数, 那么默认有效时间为24小时. 在24小时内, 可以无数量限制添加 worker.

      6.  echo `kubeadm token create --print-join-command --ttl=0` " --control-plane --certificate-key $CERT_KEY --v=5"

          7.

      8.  # 拿到上面打印的命令在需要添加的节点上执行

          9.

      10.  # --control-plane 标志通知 kubeadm join 创建一个新的控制平面。加入master必须加这个标记

      11.  # --certificate-key ... 将导致从集群中的 kubeadm-certs Secret 下载控制平面证书并使用给定的密钥进行解密。这里的值就是上面这个命令(kubeadm init phase upload-certs --upload-certs)打印出的key。

          12.

      13.  mkdir -p $HOME/.kube

      14.  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

      15.  sudo chown $(id -u):$(id -g) $HOME/.kube/config

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

      复制

      1.  kubectl get nodes

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

      1)修改配置

      复制

      1.  cd /etc/kubernetes

      2.  # 修改/etc/kubernetes/admin.conf,/etc/kubernetes/kubelet.conf文件中的server ip改成127.0.0.1

      3.  vi /etc/kubernetes/admin.conf

      4.  vi /etc/kubernetes/kubelet.conf

          5.

      6.  # 覆盖配置

      7.  cp /etc/kubernetes/admin.conf ~/.kube/config

      2)删除旧的证书,生成新证书

      复制

      1.  cd /etc/kubernetes/pki

          2.

      3.  # 先备份

      4.  mv apiserver.key apiserver.key.bak

      5.  mv apiserver.crt apiserver.crt.bak

          6.

      7.  # 使用如下命令生成,分别在三个master节点上执行

      8.  kubeadm init phase certs apiserver --apiserver-advertise-address 192.168.182.110 --apiserver-cert-extra-sans "127.0.0.1,10.1.0.1"

          9.

      10.  kubeadm init phase certs apiserver --apiserver-advertise-address 192.168.182.113 --apiserver-cert-extra-sans "127.0.0.1,10.1.0.1"

          11.

      12.  kubeadm init phase certs apiserver --apiserver-advertise-address 192.168.182.130 --apiserver-cert-extra-sans "127.0.0.1,10.1.0.1"

      13.  # --apiserver-cert-extra-sans "127.0.0.1":设置了这个,之后加入节点验证证书阶段就不会报错了。

      3)修改apiserver

      复制

      1.  kubectl -n kube-system edit cm kubeadm-config -o yaml

      4)修改kube-prxoy配置

      复制

      1.  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}'`

      5)重启docker和kubelet

      复制

      1.  systemctl restart docker kubelet

      (11)node节点上安装nginx

      这里使用nginx四层代理

      复制

      1.  mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

      2.  wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

      3.  yum makecache

      4.  yum install epel-release

      5.  yum -y install nginx

      6.  yum -y install nginx-all-modules.noarch

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

      复制

      1.  stream { #实现四层代理功能

      2.  upstream kube_apiserver { #定义集群,kube_apiserver是集群名称,可自行定义

      3.  least_conn;# 默认调度策略是轮询,在轮询中,如果服务器down掉了,会自动剔除该服务器。

      4.  server local-168-182-110:6443 max_fails=3 fail_timeout=30s; #集群组是三台服务器k8s apiserver组成

      5.  server local-168-182-113:6443 max_fails=3 fail_timeout=30s;

      6.  server local-168-182-130:6443 max_fails=3 fail_timeout=30s;

      7.  }

      8.  server { #定义一个服务

      9.  listen 127.0.0.1:6443; #需要监听的端口

      10.  proxy_pass kube_apiserver; #调用集群

      11.  proxy_connect_timeout 10s; # 连接超时时间

      12.  proxy_timeout 300s; # 端口保持时间

      13.  }

      14.  }

      (12)node节点加入集群

      复制

      1.  # 在第一个master节点上执行以下获取执行命令

      2.  # 证如果过期了,可以使用下面命令生成新证书上传,这里会打印出certificate key,后面会用到

      3.  CERT_KEY=`kubeadm init phase upload-certs --upload-certs|tail -1`

          4.

      5.  # 其中 --ttl=0 表示生成的 token 永不失效. 如果不带 --ttl 参数, 那么默认有效时间为24小时. 在24小时内, 可以无数量限制添加 worker.

      6.  echo `kubeadm token create --print-join-command --ttl=0` " --certificate-key $CERT_KEY --v=5"

      7.  # 示例如下:

      8.  kubeadm join 127.0.0.1:6443 --token esczfh.6ckynzi6wfj8jhnk --discovery-token-ca-cert-hash sha256:bc8fb85184ed235b88afdba38f0a17976d353abb10d0739d25df452745d1eed8 --certificate-key a126867ad4d91721f157660df77cdea7862ebda8371280c3025c4cc45c23b85f --v=5

      修改/etc/kubernetes/kubelet.conf配置

      重启

      复制

      1.  systemctl restart kubelet

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

      复制

      1.  kubectl get nodes

      2.  kubectl get pods -A

      (13)卸载

      复制

      1.  kubeadm reset

      2.  rm -rf /etc/kubernetes/*

      3.  rm -fr ~/.kube

      4.  rm -fr /var/lib/etcd

      四、高可用故障模式测试

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

      复制

      1.  # 关机192.168.182.110

      2.  showdown -h now

      3.  # 在其它master节点上查看节点状态

      4.  kubectl get nodes

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

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

      复制

      1.  # 关机192.168.182.113

      2.  showdown -h now

      3.  # 在其它master节点上查看节点状态

      4.  kubectl get nodes

      【结论】如上图可知,挂两个master节点,整个集群不可用,还是之前说的,三个master节点只允许挂一个master节点,这里就不细说了。

      来源: 今日头条

        >>>>>>点击进入计算专题

云计算 更多推荐

课课家教育

未登录