生产环境二进制高可用部署kubernetes集群

参考文档: https://www.fdevops.com/2020/09/23/k8s-7052

https://blog.csdn.net/wangshui898/article/details/109119189

生产环境k8s平台规划

  • master节点
# master节点高可用集群至少2台,etcd集群必须为奇数(3台)
生产环境master和etcd公用3台机器
#配置推荐(测试、开发环境可适当降低配置4核8g即可)
8核16G
#关闭所有swap分区
  • node节点
# node>=2台
生产环境根据具体业务服务数,这里推荐2台
#配置推荐(测试、开发环境可适当降低配置4核8g即可)
8核16G
#关闭所有swap分区
  • 安装前准备工作
    • 部署过程以root用户完成
    • 所有服务器网络互通,master1可以通过ssh证书免密登录到其他节点,用于分发文件

环境准备

软件 版本
操作系统 CentOS7.5_x64
Docker 19-ce
Kubernetes 1.18.2

服务器规划(测试环境)

hostname ip 组件 机器配置
k8s-master1 192.168.1.106 kube-apiserver,kube-controller-manager,kube-scheduler,etcd 1c2g
k8s-master2 192.168.1.109 kube-apiserver,kube-controller-manager,kube-scheduler,etcd 1c2g
k8s-node1 192.168.1.182 kubelet,kube-proxy,docker,etcd 1c2g
k8s-node2 192.168.1.184 kubelet,kube-proxy,docker,etcd 1c2g
Load Balancer(master) 192.168.1.197 Nginx L4 1c2g
Load Balancer(backup) 192.168.1.199 Nginx L4 1c2g
vip 192.168.1.200
先部署一套单master集群,在扩容为多master

单master集群部署

单Master服务器规划:(master也可兼做为work节点)

hostname ip 组件
k8s-master 192.168.1.106 kube-apiserver,kube-controller-manager,kube-scheduler,etcd
k8s-node1 192.168.1.182 kubelet,kube-proxy,docker etcd
k8s-node2 192.168.1.184 kubelet,kube-proxy,docker,etcd
初始化配置(所有节点)
  • 关闭防火墙

    systemctl stop firewalld
    systemctl disable firewalld
    
  • 关闭selinux

    setenforce 0
    sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
    
  • 关闭swap分区

    swapoff -a && sysctl -w vm.swappiness=0
    sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
    
  • 配置主机名

    hostnamectl set-hostname <hostname>
    
  • 节点生成ssh免密登陆(选择k8s-master1操作)

    ssh-keygen -t rsa
    for i in 192.168.1.{106,109,182,184} ;do ssh-copy-id -i .ssh/id_rsa.pub $i;done
    
  • 编辑hosts文件

    cat > /etc/hosts <<EOF
    192.168.1.106 k8s-master1
    192.168.1.109 k8s-master2
    192.168.1.182 k8s-node1
    192.168.1.184 k8s-node2
    EOF
    
    #分发到所有节点
    for i in k8s-master{1,2};do scp -r /etc/hosts $i:/etc/hosts;done
    for i in k8s-node{1,2};do scp -r /etc/hosts $i:/etc/hosts;done
    
  • 所有节点同步时间

    安装ntp
    yum -y install ntp
    
    同步时间
    ntpdate pool.ntp.org
    
    将ntp服务设为开机启动
    chkconfig ntpd on
    
    重启ntp服务
    service ntpd restart
    
    查看ntp服务状态
    systemctl status ntpd
    
    #同步时区和时间
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    echo 'Asia/Shanghai' >/etc/timezone
    ntpdate time.windows.com
    
  • 优化内核参数

    cat > kubernetes.conf <<EOF
    net.bridge.bridge-nf-call-iptables=1
    net.bridge.bridge-nf-call-ip6tables=1
    net.ipv4.ip_forward=1
    net.ipv4.tcp_tw_recycle=0
    net.ipv4.neigh.default.gc_thresh1=1024
    net.ipv4.neigh.default.gc_thresh1=2048
    net.ipv4.neigh.default.gc_thresh1=4096
    vm.swappiness=0
    vm.overcommit_memory=1
    vm.panic_on_oom=0
    fs.inotify.max_user_instances=8192
    fs.inotify.max_user_watches=1048576
    fs.file-max=52706963
    fs.nr_open=52706963
    net.ipv6.conf.all.disable_ipv6=1
    net.netfilter.nf_conntrack_max=2310720
    EOF
    cp kubernetes.conf  /etc/sysctl.d/kubernetes.conf
    sysctl -p /etc/sysctl.d/kubernetes.conf
    
  • 加载内核模块

    modprobe ip_vs_rr
    modprobe br_netfilter
    
  • 安装依赖包

    yum install -y epel-release
    yum install -y chrony conntrack ipvsadm ipset jq iptables curl sysstat libseccomp wget socat git
    
    • kube-proxy 使用 ipvs 模式,ipvsadm 为 ipvs 的管理工具
    • etcd 集群各机器需要时间同步,chrony 用于系统时间同步;
  • 升级内核

    # 操作系统内核默认是3,在这里存在bug隐患 建议升级到4
    rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
    yum --enablerepo=elrepo-kernel install -y kernel-lt
    # 设置开机从新内核启动
    grub2-set-default 0
    
    # 重启机器
    reboot
    #验证内核是否升级
    uname -r
    
生成cfssl证书生成工具

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
部署ETCD集群
  • 规划

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

    节点hostname ip
    etcd-1 192.168.1.106
    etcd-2 192.168.1.182
    etcd-3 192.168.1.184

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

  • 生成etcd证书

    # 创建工作目录
    mkdir -p ~/TLS/{etcd,k8s}
    
    cd TLS/etcd
    
  • 自签CA

    cat > ca-config.json << EOF
    {
      "signing": {
        "default": {
          "expiry": "87600h"
        },
        "profiles": {
          "www": {
             "expiry": "87600h",
             "usages": [
                "signing",
                "key encipherment",
                "server auth",
                "client auth"
            ]
          }
        }
      }
    }
    EOF
    
    cat > ca-csr.json << EOF
    {
        "CN": "etcd CA",
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "L": "Beijing",
                "ST": "Beijing"
            }
        ]
    }
    EOF
    
    # 生成证书:
    cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
    ls *pem
    ca-key.pem  ca.pem
    
  • 使用自签CA签发ETCD HTTPS证书

    # 创建证书申请文件:
    cat > server-csr.json << EOF
    {
        "CN": "etcd",
        "hosts": [
        "192.168.1.106",
        "192.168.1.182",
        "192.168.1.184"
        ],
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "L": "BeiJing",
                "ST": "BeiJing"
            }
        ]
    }
    EOF
    
    # 生成证书:
    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
    

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

    • 部署ETCD集群

      # 以下在节点1上操作,为简化操作,待会将节点1生成的所有文件拷贝到节点2和节点3.
      
      # 1. 创建工作目录并解压二进制包
      wget https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz
      mkdir /opt/etcd/{bin,cfg,ssl} -p
      tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
      mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/
      
      # 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.1.106:2380"
      ETCD_LISTEN_CLIENT_URLS="https://192.168.1.106:2379"
      #[Clustering]
      ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.1.106:2380"
      ETCD_ADVERTISE_CLIENT_URLS="https://192.168.1.106:2379"
      ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.1.106:2380,etcd-2=https://192.168.1.182:2380,etcd-3=https://192.168.1.184:2380"
      ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
      ETCD_INITIAL_CLUSTER_STATE="new"
      EOF
      
      # 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
      
      # 4.拷贝刚才生成的证书
      cp ~/TLS/etcd/ca*pem ~/TLS/etcd/server*pem /opt/etcd/ssl/
      
      # 5. 启动并设置开机启动
      systemctl daemon-reload
      systemctl start etcd
      systemctl enable etcd
      
      # 启动时会卡住或失败,等待其他节点加入
      
      # 6. 将上面节点1所有生成的文件拷贝到节点2和节点3
      scp -r /opt/etcd/ k8s-node1:/opt/
      scp /usr/lib/systemd/system/etcd.service k8s-node1:/usr/lib/systemd/system/
      scp -r /opt/etcd/ k8s-node2:/opt/
      scp /usr/lib/systemd/system/etcd.service k8s-node2:/usr/lib/systemd/system/
      
      # 7. 然后在节点2和节点3分别修改etcd.conf配置文件中的节点名称和当前服务器IP:
      vi /opt/etcd/cfg/etcd.conf
      #[Member]
      ETCD_NAME="etcd-2"   # 修改此处,节点2改为etcd-2,节点3改为etcd-3
      ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
      ETCD_LISTEN_PEER_URLS="https://192.168.1.182:2380"   # 修改此处为当前服务器IP
      ETCD_LISTEN_CLIENT_URLS="https://192.168.1.182:2379" # 修改此处为当前服务器IP
      
      #[Clustering]
      ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.1.182:2380" # 修改此处为当前服务器IP
      ETCD_ADVERTISE_CLIENT_URLS="https://192.168.1.182:2379" # 修改此处为当前服务器IP
      ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.1.106:2380,etcd-2=https://192.168.1.182:2380,etcd-3=https://192.168.1.184:2380"
      ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
      ETCD_INITIAL_CLUSTER_STATE="new"
      
      # 启动etcd并设置开机启动,同上。
      
      # 8. 查看集群状态
      ETCDCTL_API=3 /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.1.106:2379,https://192.168.1.182:2379,https://192.168.1.184:2379" endpoint health
      
      # 如果输出上面信息,就说明集群部署成功。如果有问题第一步先看日志:/var/log/message 或 journalctl -u etcd
      
安装docker(所有节点)
# 下载地址
wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.12.tgz

# 以下在所有节点操作。这里采用二进制安装,用yum安装也一样。
tar zxvf docker-19.03.12.tgz
mv docker/* /usr/bin

# systemd管理docker
cat > /usr/lib/systemd/system/docker.service << EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
EOF

# 创建配置文件
mkdir /etc/docker
cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF

# 启动并设置开机启动
systemctl daemon-reload
systemctl start docker
systemctl enable docker
部署master node
  • 生成kube-apiserver证书

    cd k8s
    cat > ca-config.json << EOF
    {
      "signing": {
        "default": {
          "expiry": "87600h"
        },
        "profiles": {
          "kubernetes": {
             "expiry": "87600h",
             "usages": [
                "signing",
                "key encipherment",
                "server auth",
                "client auth"
            ]
          }
        }
      }
    }
    EOF
    cat > ca-csr.json << EOF
    {
        "CN": "kubernetes",
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "L": "Beijing",
                "ST": "Beijing",
                "O": "k8s",
                "OU": "System"
            }
        ]
    }
    EOF
    
    # 生成证书
    cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
    
    ls *pem
    ca-key.pem  ca.pem
    
  • 使用自签CA签发kube-apiserver HTTPS证书

    cd TLS/k8s
    cat > server-csr.json << EOF
    {
        "CN": "kubernetes",
        "hosts": [
          "10.0.0.1",
          "127.0.0.1",
          "192.168.1.106",
          "192.168.1.109",
          "192.168.1.182",
          "192.168.1.184",
          "192.168.1.197",
          "192.168.1.199",
          "192.168.1.200",
          "kubernetes",
          "kubernetes.default",
          "kubernetes.default.svc",
          "kubernetes.default.svc.cluster",
          "kubernetes.default.svc.cluster.local"
        ],
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "L": "BeiJing",
                "ST": "BeiJing",
                "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
    
    ls server*pem
    server-key.pem  server.pem
    
  • 下载二进制文件

    # 下载地址
    wget https://dl.k8s.io/v1.18.2/kubernetes-server-linux-amd64.tar.gz
    
    # 解压二进制包
    mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} 
    tar zxvf kubernetes-server-linux-amd64.tar.gz
    cd kubernetes/server/bin
    ls kube-apiserver kube-scheduler kube-controller-manager
    cp kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin
    cp kubectl /usr/bin/
    
  • 部署kube-apiserver

    # 创建配置文件
    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.1.106:2379,https://192.168.1.182:2379,https://192.168.1.184:2379 \\
    --bind-address=192.168.1.106 \\
    --secure-port=6443 \\
    --advertise-address=192.168.1.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=6000-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
    
    # 拷贝刚才生成的证书
    ls ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem
    cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/
    
    # 创建配置文件中的token文件
    cat > /opt/kubernetes/cfg/token.csv << EOF
    c47ffb939f5ca36231d9e3121a252940,kubelet-bootstrap,10001,"system:node-bootstrapper"
    EOF
    
    # systemd管理apiserver
    cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
    [Unit]
    Description=Kubernetes 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
    
    # 启动并设置开机启动
    systemctl daemon-reload
    systemctl start kube-apiserver
    systemctl enable kube-apiserver
    
    # 授权kubelet-bootstrap用户允许请求证书
    kubectl create clusterrolebinding kubelet-bootstrap \
    --clusterrole=system:node-bootstrapper \
    --user=kubelet-bootstrap
    
  • 部署kube-controller-manager

    # 创建配置文件
    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
    
    # systemd管理controller-manager
    cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
    [Unit]
    Description=Kubernetes 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
    
    # 启动并设置开机启动
    systemctl daemon-reload
    systemctl start kube-controller-manager
    systemctl enable kube-controller-manager
    
  • 部署kube-scheduler

    # 创建配置文件
    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
    
    # systemd管理scheduler
    cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
    [Unit]
    Description=Kubernetes 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
    
    # 启动并设置开机启动
    systemctl daemon-reload
    systemctl start kube-scheduler
    systemctl enable kube-scheduler
    
    # 查看集群状态
    kubectl get cs
    NAME                 STATUS    MESSAGE             ERROR
    scheduler            Healthy   ok                  
    controller-manager   Healthy   ok                  
    etcd-2               Healthy   {"health":"true"}   
    etcd-1               Healthy   {"health":"true"}   
    etcd-0               Healthy   {"health":"true"}
    
    # 这里有个小坑,执行kubectl命令时报错error: no configuration has been provided, try setting KUBERNETES_MASTER environment variable
    解决方法: 
    在/etc/profile末尾增加
    export KUBERNETES_MASTER="127.0.0.1:8080"
    source /etc/profile
    
    
部署worker node
# 下面还是在Master Node上操作,即同时作为Worker Node
# 创建工作目录并拷贝二进制文件,在所有worker node创建工作目录:
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}

# 从master节点拷贝
cd kubernetes/server/bin
cp kubelet kube-proxy /opt/kubernetes/bin   
  • 部署kubelet

    # 创建配置文件
    # 下载镜像
    docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0
    
    cat > /opt/kubernetes/cfg/kubelet.conf << EOF
    KUBELET_OPTS="--logtostderr=false \\
    --v=2 \\
    --log-dir=/opt/kubernetes/logs \\
    --hostname-override=k8s-master \\
    --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=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
    EOF
    
    # 配置参数文件
    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
    
    # 生成bootstrap.kubeconfig文件
    
    KUBE_APISERVER="https://192.168.1.106:6443" # apiserver IP:PORT
    TOKEN="c47ffb939f5ca36231d9e3121a252940" # 与token.csv里保持一致
    
    # 生成 kubelet bootstrap kubeconfig 配置文件
    kubectl config set-cluster kubernetes \
      --certificate-authority=/opt/kubernetes/ssl/ca.pem \
      --embed-certs=true \
      --server=${KUBE_APISERVER} \
      --kubeconfig=bootstrap.kubeconfig
    kubectl config set-credentials "kubelet-bootstrap" \
      --token=${TOKEN} \
      --kubeconfig=bootstrap.kubeconfig
    kubectl config set-context default \
      --cluster=kubernetes \
      --user="kubelet-bootstrap" \
      --kubeconfig=bootstrap.kubeconfig
    kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
    
    # 拷贝到配置文件路径
    ls -lt
    cp bootstrap.kubeconfig /opt/kubernetes/cfg
    
    # systemd管理kubelet
    cat > /usr/lib/systemd/system/kubelet.service << EOF
    [Unit]
    Description=Kubernetes 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
    
    # 启动并设置开机启动
    systemctl daemon-reload
    systemctl start kubelet
    systemctl enable kubelet
    
    # 批准kubelet证书申请并加入集群
    kubectl get csr  # 查看kubelet证书请求
    kubectl certificate approve node-csr-xxxxxxxxxx  # 批准申请
    kubectl get node # 查看节点
    [root@localhost bin]# kubectl get node
    NAME         STATUS     ROLES    AGE   VERSION
    k8s-master   NotReady   <none>   22s   v1.18.2
    # 由于网络插件还没有部署,节点会没有准备就绪 NotReady
    
  • 部署kube-proxy

    #创建配置文件
    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
    
    # 配置参数文件
    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-master
    clusterCIDR: 10.0.0.0/24
    EOF
    
    # 生成kube-proxy.kubeconfig文件
    # 切换工作目录
    cd TLS/k8s
    
    # 创建证书请求文件
    cat > kube-proxy-csr.json << EOF
    {
      "CN": "system:kube-proxy",
      "hosts": [],
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "L": "BeiJing",
          "ST": "BeiJing",
          "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
    
    ls kube-proxy*pem
    kube-proxy-key.pem  kube-proxy.pem
    
    # 生成kubeconfig文件
    KUBE_APISERVER="https://192.168.1.106:6443"
    
    kubectl config set-cluster kubernetes \
      --certificate-authority=/opt/kubernetes/ssl/ca.pem \
      --embed-certs=true \
      --server=${KUBE_APISERVER} \
      --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/
    
    # systemd管理kube-proxy
    cat > /usr/lib/systemd/system/kube-proxy.service << EOF
    [Unit]
    Description=Kubernetes 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
    
    # 启动并设置开机启动
    systemctl daemon-reload
    systemctl start kube-proxy
    systemctl enable kube-proxy
    
    
  • 部署CNI网络

    wget https://github.com/containernetworking/plugins/releases/download/v0.8.6/cni-plugins-linux-amd64-v0.8.6.tgz
    
    # 解压二进制包并移动到默认工作目录
    mkdir -p /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:.*-amd64#lizhenliang/flannel:v0.12.0-amd64#g" kube-flannel.yml
    
    kubectl apply -f kube-flannel.yml
    
    kubectl get pods -n kube-system
    NAME                          READY   STATUS    RESTARTS   AGE
    kube-flannel-ds-amd64-qsp5g   1/1     Running   0          22m
    
    kubectl get node
    NAME         STATUS   ROLES    AGE   VERSION
    k8s-master   Ready    <none>   8h    v1.18.2
    
    # 部署好网络插件,Node准备就绪
    # 授权apiserver访问kubelet
    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
    
    kubectl apply -f apiserver-to-kubelet-rbac.yaml
    
  • 增加worker node

    # 拷贝已部署好的Node相关文件到新节点,182、184
    scp -r /opt/kubernetes k8s-node1:/opt/
    
    scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service k8s-node1:/usr/lib/systemd/system
    
    scp -r /opt/cni/ k8s-node2:/opt/
    
    scp /opt/kubernetes/ssl/ca.pem k8s-node2:/opt/kubernetes/ssl
    
    # 删除kubelet证书和kubeconfig文件
    rm /opt/kubernetes/cfg/kubelet.kubeconfig 
    rm -f /opt/kubernetes/ssl/kubelet*
    
    # 修改主机名
    vi /opt/kubernetes/cfg/kubelet.conf
    --hostname-override=k8s-node1
    
    vi /opt/kubernetes/cfg/kube-proxy-config.yml
    hostnameOverride: k8s-node1
    
    # 启动并设置开机启动
    systemctl daemon-reload
    systemctl start kubelet
    systemctl enable kubelet
    systemctl start kube-proxy
    systemctl enable kube-proxy
    
    # 在Master上批准新Node kubelet证书申请
    [root@localhost soft]# kubectl get csr
    NAME                                                   AGE     SIGNERNAME                                    REQUESTOR           CONDITION
    node-csr-0JQgKZjXgkcc-khUhbPhZ1Hy6EFwCSQ88i4hccdP3aE   97s     kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
    node-csr-33FAfRfrbV9H1NO1AZ58Oby6kf3Ypb0Upu4qvxmZP2c   8h      kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued
    node-csr-5FNWF-KN79zJPGzQLSpaZDx5KpsyHzkviu9ukZVhWgE   5m38s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
    node-csr-QZrb0f5UVaEguizqoWbc_kTaqtHxlEZtOEFngILmTYc   5m43s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
    node-csr-xIUJ6SsDPpVlWHdajRxR-TrqvqVXWLDvSnkrgp4ko3E   72s     kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
    
    [root@localhost soft]# kubectl certificate approve node-csr-0JQgKZjXgkcc-khUhbPhZ1Hy6EFwCSQ88i4hccdP3aE
    certificatesigningrequest.certificates.k8s.io/node-csr-0JQgKZjXgkcc-khUhbPhZ1Hy6EFwCSQ88i4hccdP3aE approved
    [root@localhost soft]# kubectl certificate approve node-csr-5FNWF-KN79zJPGzQLSpaZDx5KpsyHzkviu9ukZVhWgE
    certificatesigningrequest.certificates.k8s.io/node-csr-5FNWF-KN79zJPGzQLSpaZDx5KpsyHzkviu9ukZVhWgE approved
    [root@localhost soft]# kubectl certificate approve node-csr-QZrb0f5UVaEguizqoWbc_kTaqtHxlEZtOEFngILmTYc
    certificatesigningrequest.certificates.k8s.io/node-csr-QZrb0f5UVaEguizqoWbc_kTaqtHxlEZtOEFngILmTYc approved
    [root@localhost soft]#  kubectl certificate approve node-csr-xIUJ6SsDPpVlWHdajRxR-TrqvqVXWLDvSnkrgp4ko3E
    certificatesigningrequest.certificates.k8s.io/node-csr-xIUJ6SsDPpVlWHdajRxR-TrqvqVXWLDvSnkrgp4ko3E approved
    
    # 查看Node状态
    kubectl get node
    NAME         STATUS   ROLES    AGE     VERSION
    k8s-master   Ready    <none>   8h      v1.18.2
    k8s-node1    Ready    <none>   3m33s   v1.18.2
    k8s-node2    Ready    <none>   2m8s    v1.18.2
    
部署Dashboard和CoreDNS
  • 部署dashboard

    wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml
    
    # 默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部
    kind: Service
    apiVersion: v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
      namespace: kubernetes-dashboard
    spec:
      ports:
        - port: 443
          targetPort: 8443
          nodePort: 30000
      type: NodePort
      selector:
        k8s-app: kubernetes-dashboard
        
    # 创建dashboard
    kubectl apply -f kubernetes-dashboard.yaml
    
    # 查看pod 、svc
    kubectl get pods,svc -n kubernetes-dashboard
    
    # 查看pod状态如果是runing即可以访问,通过node ip  ,https://192.168.1.106:30000
    
    # 访问过程中如果谷歌浏览器出现如下提示: 您目前无法访问 yourname.com,因为此网站发送了 Google Chrome 无法处理的杂乱凭据。网络错误和攻击通常是暂时的
    
    #  解决方法: 在当前页,直接键盘敲入 thisisunsafe
    
    # 创建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
    
    # 查看token
    kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
    
    
    • 部署coreDNS

      # CoreDNS用于集群内部Service名称解析。DNS服务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析。
      
      # 获取地址 : https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base
      vim coredns.yaml
      # 修改镜像
      docker pull registry.aliyuncs.com/google_containers/coredns:1.6.7
      
      # 修改yaml文件
      70行左右   kubernetes cluster.local {  	-->大写部分修改成自己的域  一般为 cluster.local.
      135行左右	image: coredns/coredns:1.7.0 	-->image部分墙外的需要修改,coredns/coredns:1.3.1
      140行左右	memory: 170Mi 		 			-->修改成自己适合的值,我这里修改为 170Mi
      200行左右	clusterIP: 10.0.0.2				--> clusterIP 修改成kubelet.config中设置的clusterDNS IP
      
      PS: 结合官方模版修改,比如内存,image镜像地址,版本号
      https://github.com/coredns/deployment/blob/master/kubernetes/coredns.yaml.sed
      
      比如我kubectl create -f coredns.yaml时候报错
      error: error validating "coredns.yaml": error validating data: ValidationError(Deployment.spec.template.spec.securityContext): unknown field "seccompProfile" in io.k8s.api.core.v1.PodSecurityContext; if you choose to ignore these errors, turn validation off with --validate=false
      查看报错信息,问题出在seccompProfile字段,结合官方模版对比,官方模版里已经没有这个字段了,所以删除即可
      #      securityContext:
      #        seccompProfile:
      #          type: RuntimeDefault
      
      # 创建coredns
      kubectl apply -f coredns.yaml
      
      # DNS解析测试
      kubectl run -it --rm dns-test --image=busybox:1.28.4 sh
      If you don't see a command prompt, try pressing enter.
      
      / # nslookup kubernetes
      Server:    10.0.0.2
      Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local
      
      Name:      kubernetes
      Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
      

高可用(扩容多master架构)

具体想了解架构原理可参考文章开头的文档,记载很详细

安装docker(192.168.1.109)

同上,不再赘述

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

# 在Master2创建etcd证书目录
mkdir -p /opt/etcd/ssl

# 拷贝Master1上所有K8s文件和etcd证书到Master2
scp -r /opt/kubernetes k8s-master2:/opt
scp -r /opt/cni/ k8s-master2:/opt
scp -r /opt/etcd/ssl k8s-master2:/opt/etcd
scp /usr/lib/systemd/system/kube* k8s-master2:/usr/lib/systemd/system
scp /usr/bin/kubectl  k8s-master2:/usr/bin

# 删除kubelet证书和kubeconfig文件:(Master2操作)
rm -f /opt/kubernetes/ssl/kubelet*
rm -f /opt/kubernetes/cfg/kubelet.kubeconfig

# 修改apiserver、kubelet和kube-proxy配置文件为本地IP:(Master2操作)
vi /opt/kubernetes/cfg/kube-apiserver.conf 
...
--bind-address=192.168.1.109 \
--advertise-address=192.168.1.109 \
...

vi /opt/kubernetes/cfg/kubelet.conf
--hostname-override=k8s-master2

vi /opt/kubernetes/cfg/kube-proxy-config.yml
hostnameOverride: k8s-master2

# 启动设置开机启动
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

# 这里对master2节点修改在/etc/profile末尾增加
export KUBERNETES_MASTER="127.0.0.1:8080"
source /etc/profile

# 查看集群状态
kubectl get cs
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok
controller-manager   Healthy   ok
etcd-2               Healthy   {"health":"true"}
etcd-1               Healthy   {"health":"true"}
etcd-0               Healthy   {"health":"true"}

# 批准kubelet证书申请
kubectl get csr
kubectl certificate approve node-csr-xxxx

kubectl get node
NAME          STATUS   ROLES    AGE    VERSION
k8s-master    Ready    <none>   31h    v1.18.2
k8s-master2   Ready    <none>   111s   v1.18.2
k8s-node1     Ready    <none>   23h    v1.18.2
k8s-node2     Ready    <none>   23h    v1.18.2

部署nginx负载均衡器

  • 安装软件包(主/备)

     yum install epel-release -y
     yum install nginx keepalived -y
    
  • 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.1.106:6443;   # Master1 APISERVER IP:PORT
           server 192.168.1.109: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
    
  • keepalived配置文件(Nginx Master)

    # 配置VIP:192.168.1.200
    cat > /etc/keepalived/keepalived.conf << EOF
    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
       script_user root
       enable_script_security
    }
    
    vrrp_script check_nginx {
        script "/etc/keepalived/check_nginx.sh"
    }
    
    vrrp_instance VI_1 {
        state MASTER
        interface ens192
        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.1.200/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配置文件(Nginx Backup)

    cat > /etc/keepalived/keepalived.conf << EOF
    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
       script_user root
       enable_script_security
    }
    
    vrrp_script check_nginx {
        script "/etc/keepalived/check_nginx.sh"
    }
    
    vrrp_instance VI_1 {
        state BACKUP
        interface ens192
        virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的
        priority 90
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.1.200/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
    
    # 启动并设置开机启动
    systemctl daemon-reload
    systemctl start nginx
    systemctl start keepalived
    systemctl enable nginx
    systemctl enable keepalived
    
    # 查看keepalived工作状态
    systemctl status keepalived
    
    
  • Nginx+Keepalived高可用测试

    # 关闭主节点Nginx,测试VIP是否漂移到备节点服务器
    pkill nginx
    
    # 测试另外一台主机ip
    
    # 访问负载均衡器测试,找K8s集群中任意一个节点,使用curl查看K8s版本测试,使用VIP访问
    curl -k https://192.168.1.200:6443/version
    
  • 修改所有worker node连接lb vip

    # 所有Worker Node执行
    grep 192.168.1.106:6443 /opt/kubernetes/cfg/*
    sed -i 's#192.168.1.106:6443#192.168.1.200:6443#' /opt/kubernetes/cfg/*
    grep 192.168.1.200:6443 /opt/kubernetes/cfg/*
    systemctl restart kubelet
    systemctl restart kube-proxy
    

kube-proxy修改成ipvs模式

  • 安装ipset及ipvsadm(所有节点)

    yum -y install ipset ipvsadm
    yum install ipvsadm ipset sysstat conntrack libseccomp -y  #上面安装有问题时用这个
    
  • 添加需要加载的模块(所有节点)

    cat >/etc/sysconfig/modules/ipvs.modules <<EOF
    #!/bin/bash
    modprobe -- ip_vs
    modprobe -- ip_vs_rr
    modprobe -- ip_vs_wrr
    modprobe -- ip_vs_sh
    modprobe -- nf_conntrack_ipv4
    EOF
    
    # 授权、运行、检查是否加载
    chmod 755 /etc/sysconfig/modules/ipvs.modules && sh /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
    
    # 检查是否加载
    lsmod | grep -e ipvs -e nf_conntrack_ipv4
    
    # 修改Kube-proxy配置文件kube-proxy-config.yml将mode设置为ipvs
    vi /opt/kubernetes/cfg/kube-proxy-config.yml
    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-master2
    clusterCIDR: 10.0.0.0/24
    mode: "ipvs"
    ipvs: 
      scheduler: "rr"
      
    # 重启服务及验证
    systemctl daemon-reload 
    systemctl restart kube-proxy 
    systemctl status kube-proxy
    ipvsadm -L -n
    
    # 所有机器需要设定/etc/sysctl.d/k8s.conf的系统参数
    cat <<EOF > /etc/sysctl.d/k8s.conf
    # https://github.com/moby/moby/issues/31208 
    # ipvsadm -l --timout
    # 修复ipvs模式下长连接timeout问题 小于900即可
    net.ipv4.tcp_keepalive_time = 600
    net.ipv4.tcp_keepalive_intvl = 30
    net.ipv4.tcp_keepalive_probes = 10
    net.ipv6.conf.all.disable_ipv6 = 1
    net.ipv6.conf.default.disable_ipv6 = 1
    net.ipv6.conf.lo.disable_ipv6 = 1
    net.ipv4.neigh.default.gc_stale_time = 120
    net.ipv4.conf.all.rp_filter = 0
    net.ipv4.conf.default.rp_filter = 0
    net.ipv4.conf.default.arp_announce = 2
    net.ipv4.conf.lo.arp_announce = 2
    net.ipv4.conf.all.arp_announce = 2
    net.ipv4.ip_forward = 1
    net.ipv4.tcp_max_tw_buckets = 5000
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_max_syn_backlog = 1024
    net.ipv4.tcp_synack_retries = 2
    # 要求iptables不对bridge的数据进行处理
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    net.bridge.bridge-nf-call-arptables = 1
    net.netfilter.nf_conntrack_max = 2310720
    fs.inotify.max_user_watches=89100
    fs.may_detach_mounts = 1
    fs.file-max = 52706963
    fs.nr_open = 52706963
    vm.swappiness = 0
    vm.overcommit_memory=1
    vm.panic_on_oom=0
    EOF
    
posted on 2021-01-14 18:23  猛风中碰杯  阅读(496)  评论(0)    收藏  举报