一、准备工作

1.1 部署 K8S 集群的两种方式

目前部署 K8S 集群主要有两种方式:

  • kubeadm

Kubeadm 是一个 K8S 半官方部署工具,提供 kubeadm init 和 kubeadm join,用于快速部署 K8S 集群。
官方地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/

  • 二进制包

从 github 下载发行版的二进制包,手动部署每个组件,组成 K8S 集群。
Kubeadm 虽然降低了部署门槛,但屏蔽了很多细节,遇到问题很难排查。若要整个系统更可控,建议使用二进制包部署 K8S 集群,虽然手动部署麻烦点,期间可以学习其很多工作原理,也利于后期维护。

1.2 安装要求

部署 K8S 集群机器需要满足以下几个条件:

  • 一台或多台机器(虚拟机),操作系统 CentOS7.x-86_x64;
  • 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多(我主要是用于搭建demo环境,且手头资源有限,每台虚拟机CPU只有1个);
  • 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点;
  • 禁止swap分区。

    1.3 准备环境

    为了节省费用,我升级了家里的一台PC做宿主机搭建虚拟机环境,CPU从原来的 i5-4590 换成了 E3 1230V3(4核四4程 变 4核8线程),淘宝置换的加了90块(含来回40元的顺丰加急快递费),内存由16G 加到 32G,一共花了410元。
    image.png
    由于我这台PC机平时家里其他人还要用,所以 OS 就沿用原来的 Win10 不准备换 ESXi 了,原本准备用 VitrualBox ,但后来发现 Win10(专业版) 本身自带有 Hyper-V ,我想还是用 Windows 原生的虚拟平台可能性能更好,自从7年前把工作平台换成Apple OSX 后对 Windwos 比较生疏了,这次正好再熟悉一下。

  • 宿主机环境 | 电脑型号 | 技嘉 B85M-D3H 台式电脑 | | —- | —- | | 处理器 | 英特尔 Xeon(至强) E3-1230 v3 @ 3.30GHz 四核八线程 | | 内存 | 32 GB ( 金士顿 DDR3 1600MHz / 金士顿 DDR3 1866MHz ) | | 主硬盘 | 七彩虹 SL500 512GB DDR ( 512 GB / 固态硬盘 ) | | 操作系统 | Windows 10 专业版 64位(Version 1909 / DirectX 12) | | 虚拟平台 | Hyper-V 10.0.18362.11110 |

  • 部署环境:
    | 软件 | 版本 | | —- | —- | | VM OS | CentOS Linux release 7.9.2009 (3.10.0-1160.el7.x86_64) | | Docker | 20.10.1, build 831ebea | | K8S | 1.18 |

  • 服务器整体规划:
    | 角色 | IP | 组件 | | —- | —- | —- | | k8s-master1.rjtest | 192.168.3.106 | kube-apiserver,kube-controller-manager,kube-scheduler,etcd | | k8s-master2.rjtest | 192.168.3.107 | kube-apiserver,kube-controller-manager,kube-scheduler | | k8s-node1.rjtest | 192.168.3.108 | kubelet,kube-proxy,docker,etcd | | k8s-node2.rjtest | 192.168.3.109 | kubelet,kube-proxy,docker,etcd | | k8s-node3.rjtest | 192.168.3.110 | kubelet,kube-proxy,docker | | Load Balancer(Master) | 192.168.3.104,192.168.3.111 (VIP) | Nginx L4 | | Load Balancer(Backup) | 192.168.3.103,192.168.3.111(VIP) | Nginx L4 |

有点担心单体宿主机跑不动这么多虚拟机,所以这一套高可用集群分两部分实施,先部署一套单Master架构(192.168.3.106/108/109),再逐步扩容为多Master架构(上述规划),顺便熟悉下Master扩容流程。

单Master架构图:
二进制部署 K8S 高可用集群 - 图2

单Master服务器规划:

角色 IP 组件
k8s-master / etcd-1 192.168.3.106 kube-apiserver,kube-controller-manager,kube-scheduler,etcd
k8s-node1 / etcd-2 192.168.3.108 kubelet,kube-proxy,docker etcd
k8s-node2 /etcd-3 192.168.3.109 kubelet,kube-proxy,docker,etcd
k8s-node3 192.168.3.110 kubelet,kube-proxy,docker

1.4 操作系统初始化配置

  • 关闭防火墙

    1. systemctl stop firewalld
    2. systemctl disable firewalld
  • 关闭selinux

    1. sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
    2. setenforce 0 # 临时
  • 关闭swap

    1. swapoff -a # 临时
    2. sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久
  • 根据规划设置主机名

    1. hostnamectl set-hostname <hostname>
  • 在master添加hosts

    1. cat >> /etc/hosts << EOF
    2. 192.168.3.106 master01 k8s-master01 etcd-1 k8s-master01-2-106.rjtest
    3. 192.168.3.107 master02 k8s-master02 k8s-master02-3-107.rjtest
    4. 192.168.3.108 node01 etcd-2 k8s-node01 k8s-node01-4-108.rjtest
    5. 192.168.3.109 node02 etcd-3 k8s-node02 k8s-node02-5-109.rjtest
    6. 192.168.3.110 node03 k8s-node03 k8s-node03-6-110.rjtest
    7. EOF
  • 将桥接的IPv4流量传递到iptables的链

    cat > /etc/sysctl.d/k8s.conf << EOF
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    EOF
    sysctl --system  # 生效
    

    image.png

  • 时间同步

    yum install ntpdate -y
    ntpdate ntp.aliyun.com
    

    image.png

    二、部署Etcd集群

    Etcd 是一个分布式键值存储系统, K8S 使用Etcd进行数据存储,所以先准备一个Etcd数据库,为解决Etcd单点故障,应采用集群方式部署,这里使用3台组建集群,可容忍1台机器故障,也可以使用5台组建集群,可容忍2台机器故障。

节点名称 复用节点 IP
etcd-1 master01 192.168.3.106
etcd-2 node01 192.168.3.108
etcd-3 node02 192.168.3.109

:为了节省机器,这里与K8s节点机器复用。也可以独立于k8s集群之外部署,只要apiserver能连接到就行。

2.1 准备cfssl证书生成工具

cfssl (https://github.com/cloudflare/cfssl) 是一个开源的证书管理工具,使用json文件生成证书,相比openssl更方便使用。
找任意一台服务器操作,这里用Master节点。

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

2.2 生成Etcd证书

2.2.1 自签证书颁发机构(CA)

  • 创建工作目录:

    mkdir -p ~/TLS/{etcd,k8s}
    cd ~/TLS/etcd
    

    image.png

  • 创建CA配置文件和证书签名请求:

CA 配置文件

cat > ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "www": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF

CA 证书签名请求

cat > ca-csr.json << EOF
{
    "CN": "etcd CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "ShangHai",
            "ST": "ShangHai"
        }
    ]
}
EOF
  • 生成证书:

    cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
    

    image.png
    openssl 查看刚刚生成的CA信息
    image.png

    2.2.2 签发Etcd HTTPS证书

  • 创建证书申请文件(csr):

    cat > server-csr.json << EOF
    {
      "CN": "etcd",
      "hosts": [
      "192.168.3.106",
      "192.168.3.108",
      "192.168.3.109"
      ],
      "key": {
          "algo": "rsa",
          "size": 2048
      },
      "names": [
          {
              "C": "CN",
              "L": "ShangHai",
              "ST": "ShangHai"
          }
      ]
    }
    EOF
    

    :上述文件hosts字段中IP为所有etcd节点的集群内部通信IP,一个都不能少!为了方便后期扩容可以多写几个预留的IP。

  • 生成证书:

    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
    ls server*pem
    server-key.pem  server.pem
    

    openssl 查看刚刚签发的 etcd server 证书信息
    image.png

    2.3 从Github下载二进制文件

    下载地址(当前最新release ):https://github.com/etcd-io/etcd/releases/download/v3.4.14/etcd-v3.4.14-linux-amd64.tar.gz

    2.4 部署Etcd集群

    以下在节点1上操作,为简化操作,后面会将节点1生成的所有文件拷贝到节点2和节点3。(实际操作中我是直接复制虚拟机)

    2.4.1 安装etcd

    mkdir /opt/etcd/{bin,cfg,ssl} -p
    tar zxvf etcd-v3.4.14-linux-amd64.tar.gz
    mv etcd-v3.4.14-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/
    

    2.4.2 创建etcd配置文件

    cat > /opt/etcd/cfg/etcd.conf << EOF
    #[Member]
    ETCD_NAME="etcd-1"
    ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
    ETCD_LISTEN_PEER_URLS="https://192.168.31.106:2380"
    ETCD_LISTEN_CLIENT_URLS="https://192.168.31.106:2379"
    #[Clustering]
    ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.31.106:2380"
    ETCD_ADVERTISE_CLIENT_URLS="https://192.168.31.106:2379"
    ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.31.106:2380,etcd-2=https://192.168.31.108:2380,etcd-3=https://192.168.31.109:2380"
    ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
    ETCD_INITIAL_CLUSTER_STATE="new"
    EOF
    

    | ETCD_NAME | 节点名称,集群中唯一 | | —- | —- | | ETCD_DATA_DIR | 数据目录 | | ETCD_LISTEN_PEER_URLS | 集群通信监听地址 | | ETCD_LISTEN_CLIENT_URLS | 客户端访问监听地址 | | ETCD_INITIAL_ADVERTISE_PEER_URLS | 客户端通告地址 | | ETCD_ADVERTISE_CLIENT_URLS | 集群通告地址 | | ETCD_INITIAL_CLUSTER | 集群节点地址 | | ETCD_INITIAL_CLUSTER_TOKEN | 集群Token | | ETCD_INITIAL_CLUSTER_STATE | 加入集群的当前状态,new是新集群,existing表示加入已有集群 |

2.4.3 systemd管理etcd

cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--peer-cert-file=/opt/etcd/ssl/server.pem \
--peer-key-file=/opt/etcd/ssl/server-key.pem \
--trusted-ca-file=/opt/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
--logger=zap
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

2.4.4 拷贝刚才生成的证书

把刚才生成的证书拷贝到配置文件中的路径:
cp ~/TLS/etcd/ca*pem ~/TLS/etcd/server*pem /opt/etcd/ssl/
image.png

2.4.5 启动并设置开机启动

systemctl daemon-reload
systemctl start etcd
systemctl enable etcd

2.4.6 部署节点2和节点3

scp -r /opt/etcd/ root@192.168.3.108:/opt/
scp /usr/lib/systemd/system/etcd.service root@192.168.3.108:/usr/lib/systemd/system/
scp -r /opt/etcd/ root@192.168.3.109:/opt/
scp /usr/lib/systemd/system/etcd.service root@192.168.3.109:/usr/lib/systemd/system/

在节点2和节点3分别修改etcd.conf配置文件中的节点名称和当前服务器IP:

vi /opt/etcd/cfg/etcd.conf
#[Member]
ETCD_NAME="etcd-1"# 修改此处,节点2改为etcd-2,节点3改为etcd-3
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.3.106:2380"# 修改此处为当前服务器IP
ETCD_LISTEN_CLIENT_URLS="https://192.168.3.106:2379"# 修改此处为当前服务器IP
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.3.106:2380"# 修改此处为当前服务器IP
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.3.106:2379"# 修改此处为当前服务器IP
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.3.106:2380,etcd-2=https://192.168.3.108:2380,etcd-3=https://192.168.3.109:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

最后启动etcd并设置开机启动,同上。

2.4.7 查看集群状态

/opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.3.106:2379,https://192.168.3.108:2379,https://192.168.3.109:2379" endpoint health

image.png
如果输出上面信息,就说明集群部署成功。
如果有问题第一步先看日志:/var/log/message 或 journalctl -u etcd

三、部署 Docker

docker 部署比较简单,直接yum安装即可,可参考我之前写的文档《CentOS 7 安装 Docker》
https://www.yuque.com/docs/share/6827647d-00b1-436e-afb6-a4c4eb79e78e
image.png

四、部署Master Node

4.1 生成kube-apiserver证书

4.1.1 自签证书颁发机构(CA)

  • 创建CA配置文件和证书签名请求:

cd ~/TLS/k8s
#CA 配置文件

cat > ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF

CA 证书签名请求

cat > ca-csr.json << EOF
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "ShangHai",
            "ST": "ShangHai",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF
  • 生成证书:

    cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
    

    4.1.2 签发kube-apiserver HTTPS证书

  • 创建证书申请文件:

    cd ~/TLS/k8s
    cat > server-csr.json << EOF
    {
      "CN": "kubernetes",
      "hosts": [
        "10.0.0.1",
        "127.0.0.1",
        "192.168.3.105",
        "192.168.3.106",
        "192.168.3.107",
        "192.168.3.111",
        "192.168.3.112",
        "192.168.3.113",
        "kubernetes",
        "kubernetes.default",
        "kubernetes.default.svc",
        "kubernetes.default.svc.cluster",
        "kubernetes.default.svc.cluster.local"
      ],
      "key": {
          "algo": "rsa",
          "size": 2048
      },
      "names": [
          {
              "C": "CN",
              "L": "ShangHai",
              "ST": "ShangHai",
              "O": "k8s",
              "OU": "System"
          }
      ]
    }
    EOF
    

    :上述文件hosts字段中IP为所有Master/LB/VIP IP,一个都不能少!为了方便后期扩容可以多写几个预留的IP。

  • 生成证书:

    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
    

    image.png

  • openssl 查看刚刚签发的证书文件

image.png

4.2 从Github下载二进制文件

下载地址:https://dl.k8s.io/v1.18.14/kubernetes-server-linux-amd64.tar.gz
注:打开链接你会发现里面有很多包,下载一个server包就够了,包含了Master和Worker Node二进制文件。

4.3 解压二进制包

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
tar zxvf kubernetes-server-linux-amd64.tar.gz
cd kubernetes/server/bin
cp kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin
cp kubectl /usr/bin/

4.4 部署kube-apiserver

4.4.1 创建配置文件

cat > /opt/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--etcd-servers=https://192.168.3.106:2379,https://192.168.3.108:2379,https://192.168.3.109:2379 \\
--bind-address=192.168.3.106 \\
--secure-port=6443 \\
--advertise-address=192.168.3.106 \\
--allow-privileged=true \\
--service-cluster-ip-range=10.0.0.0/24 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/opt/kubernetes/cfg/token.csv \\
--service-node-port-range=30000-32767 \\
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \\
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \\
--tls-cert-file=/opt/kubernetes/ssl/server.pem  \\
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \\
--client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--etcd-cafile=/opt/etcd/ssl/ca.pem \\
--etcd-certfile=/opt/etcd/ssl/server.pem \\
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"
EOF

:上面两个 \ 第一个是转义符,第二个是换行符,使用转义符是为了使用EOF保留换行符。

—logtostderr 启用log
—v log登记
—log-dir log目录
—etcd-servers etcd 集群地址
—bind-address 监听地址
—secure-port https 安全端口
—advertise-address 集群通告地址
—allow-privileged 启用授权
—service-cluster-ip-range Service 虚拟IP地址段
—enable-admission-plugins 准入控制模块
—authorization-mode 认证授权,启用RBAC授权和节点制管理
—enable-bootstrap-token-auth 启用TLS bootstrap 机制
—token-auth-file bootstrap token文件
—service-node-port-range Service nodeport 类型默认分配端口范围
—kubelet-client-XXX apiserver 访问kubelet客户端证书
—tls-xxx-file apiserver https证书
—etcd-xxxfile 链接etcd集群证书
—audit-log-xxx 审计日志

4.4.2 拷贝刚才生成的证书

把刚才生成的证书拷贝到配置文件中的路径:

cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/

4.4.3 启用 TLS Bootstrapping 机制

TLS Bootstraping:Master apiserver 启用TLS认证后,Node节点kubelet和kube-proxy要与kube-apiserver进行通信,必须使用CA签发的有效证书才可以,当Node节点很多时,这种客户端证书颁发需要大量工作,同样也会增加集群扩展复杂度。为了简化流程, K8S 引入了TLS bootstraping机制来自动颁发客户端证书,kubelet会以一个低权限用户自动向apiserver申请证书,kubelet的证书由apiserver动态签署。所以强烈建议在Node上使用这种方式,目前主要用于kubelet,kube-proxy 还是统一颁发一个证书。
TLS bootstraping 工作流程:
二进制部署 K8S 高可用集群 - 图14
创建上述配置文件中token文件:

cat > /opt/kubernetes/cfg/token.csv << EOF
2e044c1e37b7773bb88d3343949651c4,kubelet-bootstrap,10001,"system:node-bootstrapper"
EOF

格式:token,用户名,UID,用户组
token也可自行生成替换:

head -c 16 /dev/urandom | od -An -t x | tr -d ' '

4.4.4 systemd管理apiserver

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description= K8S  API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

4.4.5 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-apiserver
systemctl enable kube-apiserver

4.4.6 授权kubelet-bootstrap用户 允许请求证书

kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap

image.png

4.5 部署kube-controller-manager

4.5.1 创建配置文件

cat > /opt/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect=true \\
--master=127.0.0.1:8080 \\
--bind-address=127.0.0.1 \\
--allocate-node-cidrs=true \\
--cluster-cidr=10.244.0.0/16 \\
--service-cluster-ip-range=10.0.0.0/24 \\
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem  \\
--root-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--experimental-cluster-signing-duration=87600h0m0s"
EOF
—master 通过本地非安全本地端口8080连接apiserver
—leader-elect 当该组件启动多个时,自动选举(HA)
—cluster-signing-cert-file / —cluster-signing-key-file 自动为kubelet颁发证书的CA,与apiserver保持一致

4.5.2 systemd管理controller-manager

cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description= K8S  Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

4.5.3 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-controller-manager
systemctl enable kube-controller-manager

4.6 部署kube-scheduler

4.6.1 创建配置文件

cat > /opt/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--leader-elect \
--master=127.0.0.1:8080 \
--bind-address=127.0.0.1"
EOF
—master 通过本地非安全本地端口8080连接apiserver
—leader-elect 当该组件启动多个时,自动选举(HA)

4.6.2. systemd管理scheduler

cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description= K8S  Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-scheduler.conf
ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

4.6.3 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler

4.7 查看集群状态

所有组件都已经启动成功,通过kubectl工具查看当前集群组件状态:

kubectl get cs

image.png
如上输出说明Master节点组件运行正常。

五、部署Worker Node

5.1 创建工作目录并拷贝二进制文件

在所有worker node创建工作目录:

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}

拷贝kubelet 和kube-proxy:
image.png
注:**下面还是在Master Node上操作,即同时作为Worker Node**。

5.2 部署kubelet

5.2.1 创建配置文件

cat > /opt/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=k8s-master01 \\
--network-plugin=cni \\
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \\
--config=/opt/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/opt/kubernetes/ssl \\
--pod-infra-container-image=rjwang/pause-amd64:3.0"
EOF
—hostname-override 显示名称,集群中唯一
—network-plugin 启用CNI
—kubeconfig 空路径,会自动生成,后面用于链接apiserver
—bootstrap-kubeconfig 首次启动时向 apiserver 申请证书
—config 配置参数文件
—cert-dir kubelet证书生成目录
—pord-infra-container-image 管理pod网络容器的镜像

5.2.2 配置参数文件

cat > /opt/kubernetes/cfg/kubelet-config.yml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.0.0.2
clusterDomain: cluster.local 
failSwapOn: false
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 2m0s
    enabled: true
  x509:
    clientCAFile: /opt/kubernetes/ssl/ca.pem 
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s
evictionHard:
  imagefs.available: 15%
  memory.available: 100Mi
  nodefs.available: 10%
  nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110
EOF

5.2.3 生成bootstrap.kubeconfig文件

KUBE_APISERVER="https://192.168.3.106:6443"# apiserver IP:PORT
TOKEN="2e044c1e37b7773bb88d3343949651c4"# 与token.csv里保持一致

生成 kubelet bootstrap kubeconfig 配置文件

kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=https://192.168.3.106:6443 \
  --kubeconfig=bootstrap.kubeconfig
kubectl config set-credentials "kubelet-bootstrap"\
  --token=2e044c1e37b7773bb88d3343949651c4 \
  --kubeconfig=bootstrap.kubeconfig
kubectl config set-context default \
  --cluster=kubernetes \
  --user="kubelet-bootstrap"\
  --kubeconfig=bootstrap.kubeconfig
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

拷贝到配置文件路径:

cp bootstrap.kubeconfig /opt/kubernetes/cfg

5.2.4 systemd管理kubelet

cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description= K8S  Kubelet
After=docker.service
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kubelet.conf
ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

5.2.5. 启动并设置开机启动

systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet

5.3 批准kubelet证书申请并加入集群

# 查看kubelet证书请求
kubectl get csr
# 批准申请
kubectl certificate approve node-csr-uCEGPOIiDdlLODKts8J658HrFq9CZ--K6M4G7bjhk8A
# 查看节点
kubectl get node

image.png
:由于网络插件还没有部署,节点会没有准备就绪 NotReady

5.4 部署kube-proxy

5.4.1 创建配置文件

cat > /opt/kubernetes/cfg/kube-proxy.conf << EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--config=/opt/kubernetes/cfg/kube-proxy-config.yml"
EOF

5.4.2 配置参数文件

cat > /opt/kubernetes/cfg/kube-proxy-config.yml << EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
metricsBindAddress: 0.0.0.0:10249
clientConnection:
  kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: k8s-master01
clusterCIDR: 10.0.0.0/24
EOF

5.4.3 生成kube-proxy.kubeconfig文件

  • 生成kube-proxy证书:

切换工作目录

cd ~/TLS/k8s

创建证书请求文件

cat > kube-proxy-csr.json << EOF
{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "ShangHai",
      "ST": "ShangHai",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF

生成证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy

image.png

  • 生成kubeconfig文件:

    kubectl config set-cluster kubernetes \
    --certificate-authority=/opt/kubernetes/ssl/ca.pem \
    --embed-certs=true \
    --server=https://192.168.3.106:6443 \
    --kubeconfig=kube-proxy.kubeconfig
    kubectl config set-credentials kube-proxy \
    --client-certificate=./kube-proxy.pem \
    --client-key=./kube-proxy-key.pem \
    --embed-certs=true \
    --kubeconfig=kube-proxy.kubeconfig
    kubectl config set-context default \
    --cluster=kubernetes \
    --user=kube-proxy \
    --kubeconfig=kube-proxy.kubeconfig
    kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
    
  • 拷贝到配置文件指定路径:

    cp kube-proxy.kubeconfig /opt/kubernetes/cfg/
    

    5.4.4 systemd管理kube-proxy

    cat > /usr/lib/systemd/system/kube-proxy.service << EOF
    [Unit]
    Description= K8S  Proxy
    After=network.target
    [Service]
    EnvironmentFile=/opt/kubernetes/cfg/kube-proxy.conf
    ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
    Restart=on-failure
    LimitNOFILE=65536
    [Install]
    WantedBy=multi-user.target
    EOF
    

    5.4.5 启动并设置开机启动

    systemctl daemon-reload
    systemctl start kube-proxy
    systemctl enable kube-proxy
    

    5.5 部署CNI网络

  • 下载并安装 CNI 二进制文件:

下载地址:
解压二进制包并移动到默认工作目录:

mkdir /opt/cni/bin
tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin
  • 部署CNI网络:
    wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
    sed -i -r "s#quay.io/coreos/flannel:.*-rc1#rjwang/flannel:v0.12.0-amd64#g" kube-flannel.yml
    
    注:默认镜像地址无法访问,修改为docker hub镜像仓库。
    kubectl apply -f kube-flannel.yml
    kubectl get pods -n kube-system
    
    image.png
    kubectl get node
    
    image.png
    部署好网络插件,Node准备就绪。

    5.6 授权apiserver访问kubelet

    ```bash cat > apiserver-to-kubelet-rbac.yaml << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: “true” labels: kubernetes.io/bootstrapping: rbac-defaults name: system:kube-apiserver-to-kubelet rules:
    • apiGroups:
      • “” resources:
      • nodes/proxy
      • nodes/stats
      • nodes/log
      • nodes/spec
      • nodes/metrics
      • pods/log verbs:
      • “*”

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: system:kube-apiserver namespace: “” roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:kube-apiserver-to-kubelet subjects:

  • apiGroup: rbac.authorization.k8s.io kind: User name: kubernetes EOF
    ```bash
    kubectl apply -f apiserver-to-kubelet-rbac.yaml
    
    image.png

    5.7 新增加Worker Node

    5.7.1 拷贝已部署好的Node相关文件到新节点

    在Master节点将Worker Node涉及的文件拷贝到新节点 192.168.3.108/109/110
    scp -r /opt/kubernetes root@192.168.3.108:/opt/
    scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service root@192.168.3.108:/usr/lib/systemd/system
    scp -r /opt/cni/ root@192.168.3.108:/opt/
    scp /opt/kubernetes/ssl/ca.pem root@192.168.3.108:/opt/kubernetes/ssl
    

    5.7.2 删除kubelet证书和kubeconfig文件

    rm /opt/kubernetes/cfg/kubelet.kubeconfig 
    rm -f /opt/kubernetes/ssl/kubelet*
    
    :这几个文件是证书申请审批后自动生成的,每个Node不同,必须删除重新生成。

    5.7.3 修改主机名

    vi /opt/kubernetes/cfg/kubelet.conf
    --hostname-override=k8s-node1
    vi /opt/kubernetes/cfg/kube-proxy-config.yml
    --hostnameOverride: k8s-node1
    

    5.7.4 启动并设置开机启动

    systemctl daemon-reload
    systemctl start kubelet
    systemctl enable kubelet
    systemctl start kube-proxy
    systemctl enable kube-proxy
    

    5.7.5. 在Master上批准新Node kubelet证书申请

    kubectl get csr
    kubectl certificate approve node-csr-UsRhfXCIaVp1SxnOySPkmkxKE2tuxa14HDqmoEX-mnM
    certificatesigningrequest.certificates.k8s.io/node-csr-UsRhfXCIaVp1SxnOySPkmkxKE2tuxa14HDqmoEX-mnM approved
    

    5.7.6 查看Node状态

    kubectl get node
    
    image.png

六、部署Dashboard和CoreDNS

6.1 部署Dashboard

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:

vi recommended.yaml
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30001
  type: NodePort
  selector:
    k8s-app: kubernetes-dashboard
kubectl apply -f recommended.yaml
kubectl get pods,svc -n kubernetes-dashboard

image.png
访问地址:**https://192.168.3.106:30001**
创建service account并绑定默认cluster-admin管理员集群角色:

kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

image.png
使用输出的token登录Dashboard。
由于证书是自签发的,目前chrome 和 safari 均会报证书错误而无法打开 Dashboard页面,Firefox可以打开的。(注:该issue 后面已解,请移步至 解决 Safari & Chrome 无法打开 K8S Dashboard 的问题
image.png

6.2 部署CoreDNS

CoreDNS用于集群内部Service名称解析。

6.2.1 下载部署脚本

git clone https://github.com/coredns/deployment.git
cd deployment/kubernetes
ls
CoreDNS-k8s_version.md  FAQs.md  README.md  Scaling_CoreDNS.md  Upgrading_CoreDNS.md  coredns.yaml.sed  corefile-tool  deploy.sh  migration  rollback.sh

6.2.2 部署脚本用法

查看 help:

./deploy.sh -h
usage: ./deploy.sh [ -r REVERSE-CIDR ] [ -i DNS-IP ] [ -d CLUSTER-DOMAIN ] [ -t YAML-TEMPLATE ]
    -r : Define a reverse zone for the given CIDR. You may specifcy this option more
         than once to add multiple reverse zones. If no reverse CIDRs are defined,
         then the default is to handle all reverse zones (i.e. in-addr.arpa and ip6.arpa)
    -i : Specify the cluster DNS IP address. If not specificed, the IP address of
         the existing "kube-dns" service is used, if present.
    -s : Skips the translation of kube-dns configmap to the corresponding CoreDNS Corefile configuration.

6.2.3 部署

总体流程是使用 deploy.sh 生成 yaml 并保存成 coredns.yaml 文件,并执行 kubectl apply -f coredns.yaml 进行部署 ,如果要卸载,执行 kubectl delete -f coredns.yaml。
deploy.sh 脚本依赖 jq 命令,所以先确保 jq 已安装:

yum install -y jq

6.2.4 全新部署

如果集群中没有 kube-dns 或低版本 coredns,我们直接用 -i 参数指定集群 DNS 的 CLUSTER IP,这个 IP 是安装集群时就确定好的,示例:

./deploy.sh -i 10.0.0.2 > coredns.yaml
kubectl apply -f coredns.yaml
kubectl get pods -n kube-system
# DNS解析测试:
kubectl run -it --rm dns-test --image=busybox:1.28.4 sh

image.pngimage.png
解析没问题。

七、高可用架构(扩容多Master架构)

K8S 作为容器集群系统,通过健康检查+重启策略实现了Pod故障自我修复能力,通过调度算法实现将Pod分布式部署,并保持预期副本数,根据Node失效状态自动在其他Node拉起Pod,实现了应用层的高可用性。
针对 K8S 集群,高可用性还应包含以下两个层面的考虑:Etcd数据库的高可用性 和 K8S Master组件的高可用性。 而Etcd我们已经采用3个节点组建集群实现高可用,本节将对Master节点高可用进行说明和实施。
Master节点扮演着总控中心的角色,通过不断与工作节点上的Kubelet和kube-proxy进行通信来维护整个集群的健康工作状态。如果Master节点故障,将无法使用kubectl工具或者API做任何集群管理。
Master节点主要有三个服务kube-apiserver、kube-controller-manager和kube-scheduler,其中kube-controller-manager和kube-scheduler组件自身通过选择机制已经实现了高可用,所以Master高可用主要针对kube-apiserver组件,而该组件是以HTTP API提供服务,因此对他高可用与Web服务器类似,增加负载均衡器对其负载均衡即可,并且可水平扩容。

多Master架构图:
二进制部署 K8S 高可用集群 - 图29

7.1 安装Docker

同上,不再赘述。

7.2 部署Master02 Node(192.168.3.107)

Master02 与已部署的Master01所有操作一致。所以我们只需将Master01所有K8s文件拷贝过来,再修改下服务器IP和主机名启动即可。

7.2.1 拷贝文件(Master01操作)

拷贝Master01上所有K8s文件和etcd证书到Master02:

scp -r /opt/kubernetes root@192.168.3.107:/opt
scp -r /opt/cni/ root@192.168.3.107:/opt
scp -r /opt/etcd/ssl root@192.168.3.107:/opt/etcd  #已经部署了3个etcd节点,该步可省略。
scp /usr/lib/systemd/system/kube* root@192.168.3.107:/usr/lib/systemd/system

7.2.2 删除证书文件

删除kubelet证书和kubeconfig文件:

rm -f /opt/kubernetes/cfg/kubelet.kubeconfig 
rm -f /opt/kubernetes/ssl/kubelet*

7.2.3 修改配置文件IP和主机名

修改apiserver、kubelet和kube-proxy配置文件为本地IP:

vi /opt/kubernetes/cfg/kube-apiserver.conf 
...
--bind-address=192.168.3.107 \
--advertise-address=192.168.3.107 \
...
vi /opt/kubernetes/cfg/kubelet.conf
--hostname-override=k8s-master02
...
vi /opt/kubernetes/cfg/kube-proxy-config.yml
hostnameOverride: k8s-master02

7.2.4 启动设置开机启动

systemctl daemon-reload
systemctl start kube-apiserver
systemctl start kube-controller-manager
systemctl start kube-scheduler
systemctl start kubelet
systemctl start kube-proxy
systemctl enable kube-apiserver
systemctl enable kube-controller-manager
systemctl enable kube-scheduler
systemctl enable kubelet
systemctl enable kube-proxy

7.2.5 查看集群状态

kubectl get cs

7.2.6 批准kubelet证书申请

kubectl get csr
kubectl certificate approve node-csr-JYNknakEa_YpHz797oKaN-ZTk43nD51Zc9CJkBLcASU
kubectl get node

image.png

7.3 部署Nginx负载均衡器

kube-apiserver高可用架构图:
二进制部署 K8S 高可用集群 - 图31

  • Nginx是一个主流Web服务和反向代理服务器,这里用四层实现对apiserver实现负载均衡。
  • Keepalived是一个主流高可用软件,基于VIP绑定实现服务器双机热备,在上述拓扑中,Keepalived主要根据Nginx运行状态判断是否需要故障转移(偏移VIP),例如当Nginx主节点挂掉,VIP会自动绑定在Nginx备节点,从而保证VIP一直可用,实现Nginx高可用。

    7.3.1 安装软件包(主/备)

    yum install epel-release -y
    yum install nginx keepalived -y
    

    7.3.2 Nginx配置文件(主/备一样)

    cat > /etc/nginx/nginx.conf << "EOF"
    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;
    }
    # 四层负载均衡,为两台Master 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.3.106:6443;   # Master1 APISERVER IP:PORT
         server 192.168.3.107:6443;   # Master2 APISERVER IP:PORT
    }
      server {
         listen 6443;
         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  _;
          location / {
    }
    }
    }
    EOF
    

    7.3.3 keepalived配置文件(Nginx Master)

    ```bash cat > /etc/keepalived/keepalived.conf << EOF global_defs { notification_email { admin@rjtest.cc } notification_email_from Alexandre.Cassen@firewall.loc
    smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id NGINX_MASTER } vrrp_script check_nginx { script “/etc/keepalived/check_nginx.sh” } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的 priority 100 # 优先级,备服务器设置 90 advert_int 1 # 指定VRRP 心跳包通告间隔时间,默认1秒 authentication {
      auth_type PASS      
      auth_pass 1111 
    
    }

    虚拟IP

    virtual_ipaddress {
      192.168.3.111/24
    
    } track_script {
      check_nginx
    
    } } EOF
• vrrp_script:指定检查nginx工作状态脚本(根据nginx状态判断是否故障转移)<br />• virtual_ipaddress:虚拟IP(VIP)

<a name="5tjX9"></a>
### 7.3.4 keepalived配置文件(Nginx Backup)
```bash
cat > /etc/keepalived/keepalived.conf << EOF
global_defs { 
   notification_email { 
      admin@rjtest.cc
   } 
   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 # VRRP 路由 ID实例,每个实例是唯一的 
    priority 90
    advert_int 1
    authentication { 
        auth_type PASS      
        auth_pass 1111 
    }  
    virtual_ipaddress { 
        192.168.3.111/24
    } 
    track_script {
        check_nginx
    } 
}
EOF

上述配置文件中检查nginx运行状态脚本:

cat > /etc/keepalived/check_nginx.sh  << "EOF"
#!/bin/bash
count=$(ps -ef |grep nginx |egrep -cv "grep|$$")
if["$count" -eq 0];then
    exit 1
else
    exit 0
fi
EOF
chmod +x /etc/keepalived/check_nginx.sh

:keepalived根据脚本返回状态码(0为工作正常,非0不正常)判断是否故障转移。

7.3.5 启动并设置开机启动

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

7.3.6 查看keepalived工作状态

ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:04:f7:2c brd ff:ff:ff:ff:ff:ff
    inet 192.168.3.104/24 brd 192.168.3.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.3.111/24 scope global secondary ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe04:f72c/64 scope link 
       valid_lft forever preferred_lft forever

可以看到,在ens33网卡绑定了192.168.3.111 虚拟IP,说明工作正常。

7.3.7 Nginx+Keepalived高可用测试

关闭主节点Nginx,测试VIP是否漂移到备节点服务器。
在Nginx Master执行 pkill nginx
在Nginx Backup,ip addr命令查看已成功绑定VIP。

7.3.8 访问负载均衡器测试

找K8s集群中任意一个节点,使用curl查看K8s版本测试,使用VIP访问:

curl -k https://192.168.3.111:6443/version

image.png
可以正确获取到K8s版本信息,说明负载均衡器搭建正常。该请求数据流程:
curl -> vip(nginx) -> apiserver

7.4 修改所有Worker Node连接LB VIP

虽然我们增加了Master02和负载均衡器,但是我们是从单Master架构扩容的,也就是说目前所有的Node组件连接都还是Master01,如果不改为连接VIP走负载均衡器,那么Master还是单点故障。
因此接下来就是要改所有Node组件配置文件,由原来 192.168.3.106 修改为 192.168.3.111(VIP):

角色 IP
k8s-master01 192.168.3.106
k8s-master02 192.168.3.107
k8s-node01 192.168.3.108
k8s-node02 192.168.3.109
k8s-node03 192.168.3.110

也就是通过kubectl get node命令查看到的节点。
在上述所有Worker Node执行:

sed -i 's#192.168.3.106:6443#192.168.3.111:6443#' /opt/kubernetes/cfg/*
systemctl restart kubelet
systemctl restart kube-proxy

检查节点状态:

kubectl get node

image.png
至此,一套完整的 K8S 高可用集群就部署完成了!
- END -