一、二进制方式 安装部署K8S

目录

一、操作系统初始化

1、关闭防火墙

[2、关闭 SELinu](#2、关闭 SELinu)

[3、 关闭 swap](#3、 关闭 swap)

4、添加hosts

5、同步系统时间

[二、集群搭建 ------ 使用外部Etcd集群](#二、集群搭建 —— 使用外部Etcd集群)

1、自签证书

[2、自签 Etcd SSL 证书](#2、自签 Etcd SSL 证书)

[① 创建 CA 配置文件:ca-config.json](#① 创建 CA 配置文件:ca-config.json)

[② 创建 CA 证书签名请求文件:ca-csr.json](#② 创建 CA 证书签名请求文件:ca-csr.json)

[③ 生成 CA 证书和私钥](#③ 生成 CA 证书和私钥)

[④ 创建证书签名请求文件:etcd-csr.json](#④ 创建证书签名请求文件:etcd-csr.json)

[⑤ 为 etcd 生成证书和私钥](#⑤ 为 etcd 生成证书和私钥)

[3、Etcd 数据库集群部署](#3、Etcd 数据库集群部署)

[① 下载 etcd 到/k8s/etcd/ 并解压](#① 下载 etcd 到/k8s/etcd/ 并解压)

[② 创建 etcd 配置文件:etcd.conf](#② 创建 etcd 配置文件:etcd.conf)

[③ 创建 etcd 服务:etcd.service 将其部署为一个systemd的服务,在/usr/lib/systemd/system/etcd.service](#③ 创建 etcd 服务:etcd.service 将其部署为一个systemd的服务,在/usr/lib/systemd/system/etcd.service)

[④ 将 etcd 目录拷贝到另外两个节点](#④ 将 etcd 目录拷贝到另外两个节点)

[⑤ 修改两个节点配置文件](#⑤ 修改两个节点配置文件)

[⑥ 启动 3个节点的 etcd 服务](#⑥ 启动 3个节点的 etcd 服务)

[三、部署安全的k8s Master 高可用集群](#三、部署安全的k8s Master 高可用集群)

[1、自签ApiServer SSL证书](#1、自签ApiServer SSL证书)

[① 创建 CA 配置文件:ca-config.json](#① 创建 CA 配置文件:ca-config.json)

[② 创建 CA 证书签名请求文件:ca-csr.json](#② 创建 CA 证书签名请求文件:ca-csr.json)

[③ 生成 CA 证书和私钥](#③ 生成 CA 证书和私钥)

[④ 创建证书签名请求文件:kubernetes-csr.json](#④ 创建证书签名请求文件:kubernetes-csr.json)

[⑤ 为 kubernetes 生成证书和私钥](#⑤ 为 kubernetes 生成证书和私钥)

[2、部署 kube-apiserver 组件](#2、部署 kube-apiserver 组件)

[① 下载k8s](#① 下载k8s)

[② 创建 Node 令牌文件:token.csv](#② 创建 Node 令牌文件:token.csv)

[③ 创建 kube-apiserver 配置文件:kube-apiserver.conf](#③ 创建 kube-apiserver 配置文件:kube-apiserver.conf)

[④ 创建 apiserver 服务:kube-apiserver.service](#④ 创建 apiserver 服务:kube-apiserver.service)

[⑤ 启动 kube-apiserver 组件](#⑤ 启动 kube-apiserver 组件)

[⑥ 将 kubelet-bootstrap 用户绑定到系统集群角色,之后便于 Node 使用token请求证书](#⑥ 将 kubelet-bootstrap 用户绑定到系统集群角色,之后便于 Node 使用token请求证书)

3、部署kube-controller-manager组件

[① 创建 kube-controller-manager 配置文件:kube-controller-manager.conf](#① 创建 kube-controller-manager 配置文件:kube-controller-manager.conf)

[② 创建 kube-controller-manager 服务:kube-controller-manager.service](#② 创建 kube-controller-manager 服务:kube-controller-manager.service)

[③ 启动 kube-controller-manager 组件](#③ 启动 kube-controller-manager 组件)

4、部署kube-scheduler组件

[① 创建 kube-scheduler 配置文件:kube-scheduler.conf](#① 创建 kube-scheduler 配置文件:kube-scheduler.conf)

[② 创建 kube-scheduler 服务:kube-scheduler.service](#② 创建 kube-scheduler 服务:kube-scheduler.service)

[③ 启动 kube-scheduler 组件](#③ 启动 kube-scheduler 组件)

5、查看集群状态

[① 查看组件状态](#① 查看组件状态)

四、集群搭建--部署node节点

1、安装docker

[2、Node 节点证书](#2、Node 节点证书)

[① 创建 Node 节点的证书签名请求文件:kube-proxy-csr.json](#① 创建 Node 节点的证书签名请求文件:kube-proxy-csr.json)

[② 为 kube-proxy 生成证书和私钥](#② 为 kube-proxy 生成证书和私钥)

[③ node 节点创建工作目录](#③ node 节点创建工作目录)

[④ 将 k8s-master-1 节点的文件拷贝到 node 节点](#④ 将 k8s-master-1 节点的文件拷贝到 node 节点)

3、安装kubelet

[① 创建请求证书的配置文件:bootstrap.kubeconfig](#① 创建请求证书的配置文件:bootstrap.kubeconfig)

[② 创建 kubelet 配置文件:kubelet-config.yml](#② 创建 kubelet 配置文件:kubelet-config.yml)

[③ 创建 kubelet 服务配置文件:kubelet.conf](#③ 创建 kubelet 服务配置文件:kubelet.conf)

[④ 创建 kubelet 服务:kubelet.service](#④ 创建 kubelet 服务:kubelet.service)

[⑤ 启动 kubelet](#⑤ 启动 kubelet)

[⑥master 给node授权](#⑥master 给node授权)

[⑦授权成功 ,查看集群 node是否加入(此时的 node 还处于未就绪的状态,因为还没有安装 CNI 组件):](#⑦授权成功 ,查看集群 node是否加入(此时的 node 还处于未就绪的状态,因为还没有安装 CNI 组件):)

4、安装kube-proxy

[① 创建 kube-proxy 连接 apiserver 的配置文件:kube-proxy.kubeconfig](#① 创建 kube-proxy 连接 apiserver 的配置文件:kube-proxy.kubeconfig)

[② 创建 kube-proxy 配置文件:kube-proxy-config.yml](#② 创建 kube-proxy 配置文件:kube-proxy-config.yml)

[③ 创建 kube-proxy 配置文件:kube-proxy.conf](#③ 创建 kube-proxy 配置文件:kube-proxy.conf)

[④ 创建 kube-proxy 服务:kube-proxy.service](#④ 创建 kube-proxy 服务:kube-proxy.service)

[⑤ 启动 kube-proxy](#⑤ 启动 kube-proxy)

5、部署其他node节点

6、部署k8s容器集群网络

[① K8S 集群网络](#① K8S 集群网络)

[② 创建 CNI 工作目录](#② 创建 CNI 工作目录)

[③ 装 CNI 插件](#③ 装 CNI 插件)

[④ 部署 Flannel](#④ 部署 Flannel)

[⑤ 检查部署状态](#⑤ 检查部署状态)

[⑥ 测试创建 Pod](#⑥ 测试创建 Pod)

7、部署CoreDNS服务

[① 部署 CoreDNS](#① 部署 CoreDNS)

[​编辑 ② 验证 CoreDNS 服务名的DNS解析](#编辑 ② 验证 CoreDNS 服务名的DNS解析)

遇到的问题1:解析时候报错

CroeDNS的配置说明

8、集群搭建--多master部署

1、部署Master2组件

[① 将 k8s-master-1 上相关文件拷贝到 k8s-master-2 上](#① 将 k8s-master-1 上相关文件拷贝到 k8s-master-2 上)

[② 修改 k8s-master-2 上的配置文件](#② 修改 k8s-master-2 上的配置文件)

[④ 验证](#④ 验证)

2、部署nginx负载均衡

[① gcc等环境安装,后续有些软件安装需要这些基础环境](#① gcc等环境安装,后续有些软件安装需要这些基础环境)

[② 安装nginx](#② 安装nginx)

[③ apiserver 负载配置](#③ apiserver 负载配置)

[④ 启动 nginx](#④ 启动 nginx)

3、部署keepAlive

[① 分别在 k8s-lb-master 和 k8s-lb-backup 这两台机器上安装 keepalive](#① 分别在 k8s-lb-master 和 k8s-lb-backup 这两台机器上安装 keepalive)

[② master 启动 keepalived](#② master 启动 keepalived)

[③ backup 启动 keepalived](#③ backup 启动 keepalived)

[④ 验证负载均衡](#④ 验证负载均衡)


1、集群架构

2、资源规划

|---------------|-----------------|---------------|------------------------------------------------------------|
| 角色 | IP | 主机名 | 组件 |
| k8s-master-1 | 192.168.134.135 | k8s-master-1 | kube_apiserver kube-controller-manager kube-scheduler etcd |
| k8s-master-2 | 192.168.134.136 | k8s-master-2 | kube_apiserver kube-controller-manager kube-scheduler |
| k8s-node-1 | 192.168.134.137 | k8s-node-1 | kubelet kube-proxy docker etcd |
| k8s-node-2 | 192.168.134.138 | k8s-node-2 | kubelet kube-proxy docker etcd |
| k8s-lb-master | 192.168.134.139 | k8s-lb-master | Nginx keepAlive |
| k8s-lb-backup | 192.168.134.140 | k8s-lb-backup | Nginx keepAlive |

一、操作系统初始化

1、关闭防火墙

systemctl stop firewalld
systemctl disable firewalld

2、关闭 SELinu

修改/etc/sysconfig/selinux,将SELINUX=enforcing 修改为 SELINUX=disabled

或者 sed -i 's/enforcing/disabled/' /etc/selinux/config   永久关闭

3、 关闭 swap

# # 永久生效
# vim /etc/fstab
# #将 [UUID=5b59fd54-eaad-41d6-90b2-ce28ac65dd81 swap  swap    defaults        0 0] 这一行注释掉

4、添加hosts

192.168.134.135 k8s-master-1
192.168.134.136 k8s-master-2
192.168.134.137 k8s-node-1
192.168.134.138 k8s-node-2
192.168.134.139 k8s-lb-master
192.168.134.140 k8s-lb-backup

5、同步系统时间

ntpdate time.windows.com   如果不联网 可以使用date -s 修改时间

二、集群搭建 ------ 使用外部Etcd集群

1、自签证书

① k8s-master-1节点上 创建证书

② 使用cfssl工具生成证书,首先下载工具,依次命令

# curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl
# curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson
# curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo
#添加授权
# chmod +x /usr/local/bin/cfssl*

2、自签 Etcd SSL 证书

创建几个目录,ssl 用于存放 etcd 自签证书,cfg 用于存放 etcd 配置文件,bin 用于存放 etcd 执行程序。

cd / 
mkdir -p /k8s/etcd/{ssl,cfg,bin}

进入 etcd ssl目录

① 创建 CA 配置文件:ca-config.json
vim ca-config.json
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "etcd": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}

说明:
- signing:表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE;
- profiles:可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile;
- expiry:证书过期时间
- server auth:表示client可以用该 CA 对server提供的证书进行验证;
- client auth:表示server可以用该CA对client提供的证书进行验证;
② 创建 CA 证书签名请求文件:ca-csr.json
vim ca-csr.json
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}
③ 生成 CA 证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
④ 创建证书签名请求文件:etcd-csr.json
vim etcd-csr.json
{
    "CN": "etcd",
    "hosts": [
      "192.168.134.135",
      "192.168.134.137",
      "192.168.134.138"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    }
}
⑤ 为 etcd 生成证书和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd etcd-csr.json | cfssljson -bare etcd

3、Etcd 数据库集群部署

etcd集群采用一主多从部署,集群通过选举产生leader ,因此需要部署奇数个节点(3/5/7)才能正常工作。etcd使用raft一致性算法保证每个节点的一致性

① 下载 etcd 到/k8s/etcd/ 并解压
wget https://github.com/etcd-io/etcd/releases/download/v3.2.28/etcd-v3.2.28-linux-amd64.tar.gz

解压完之后 将 etcd,etcdctl 移到bin下

cp etcd-v3.2.28-linux-amd64/{etcd,etcdctl} /k8s/etcd/bin/

然后将源目录删除

② 创建 etcd 配置文件:etcd.conf
vim /k8s/etcd/cfg/etcd.conf
# [member]
ETCD_NAME=etcd-1
ETCD_DATA_DIR=/k8s/data/
ETCD_LISTEN_PEER_URLS=https://192.168.134.135:2380
ETCD_LISTEN_CLIENT_URLS=https://192.168.134.135:2379

# [cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS=https://192.168.134.135:2380
ETCD_ADVERTISE_CLIENT_URLS=https://192.168.134.135:2379
ETCD_INITIAL_CLUSTER=etcd-1=https://192.168.134.135:2380,etcd-2=https://192.168.134.137:2380,etcd-3=https://192.168.134.138:2380
ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster
ETCD_INITIAL_CLUSTER_STATE=new

# [security]
ETCD_CERT_FILE=/k8s/etcd/ssl/etcd.pem
ETCD_KEY_FILE=/k8s/etcd/ssl/etcd-key.pem
ETCD_TRUSTED_CA_FILE=/k8s/etcd/ssl/ca.pem
ETCD_PEER_CERT_FILE=/k8s/etcd/ssl/etcd.pem
ETCD_PEER_KEY_FILE=/k8s/etcd/ssl/etcd-key.pem
ETCD_PEER_TRUSTED_CA_FILE=/k8s/etcd/ssl/ca.pem

说明:
- ETCD_NAME:etcd在集群中的唯一名称
- ETCD_DATA_DIR:etcd数据存放目录
- ETCD_LISTEN_PEER_URLS:etcd集群间通讯的地址,设置为本机IP
- ETCD_LISTEN_CLIENT_URLS:客户端访问的地址,设置为本机IP
【集群】
- ETCD_INITIAL_ADVERTISE_PEER_URLS:初始集群通告地址,集群内部通讯地址,设置为本机IP
- ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址,设置为本机IP
- ETCD_INITIAL_CLUSTER:集群节点地址,以 key=value 的形式添加各个 etcd 的地址
- ETCD_INITIAL_CLUSTER_TOKEN:集群令牌,用于集群间做简单的认证
- ETCD_INITIAL_CLUSTER_STATE:集群状态
【安全】
- ETCD_CERT_FILE:客户端 etcd 数字证书路径
- ETCD_KEY_FILE:客户端 etcd 私钥路径
- ETCD_TRUSTED_CA_FILE:客户端 CA 证书路径
- ETCD_PEER_CERT_FILE:集群间通讯etcd数字证书路径
- ETCD_PEER_KEY_FILE:集群间通讯etcd私钥路径
- ETCD_PEER_TRUSTED_CA_FILE:集群间通讯CA证书路径
③ 创建 etcd 服务:etcd.service 将其部署为一个systemd的服务,在/usr/lib/systemd/system/etcd.service

通过EnvironmentFile指定 etcd.conf 作为环境配置文件

vim /usr/lib/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
EnvironmentFile=/k8s/etcd/cfg/etcd.conf
WorkingDirectory=${ETCD_DATA_DIR}

ExecStart=/k8s/etcd/bin/etcd

Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

systemctl daemon-reload 创建完之后 重新加载下后台进程

etcd.service etcd.conf 更多的配置以及说明可以通过如下命令查看:

/k8s/etcd/bin/etcd --help

④ 将 etcd 目录拷贝到另外两个节点
scp -r /k8s root@k8s-node-1:/k8s
scp -r /k8s root@k8s-node-2:/k8s
⑤ 修改两个节点配置文件

/k8s/etcd/cfg/etcd.conf

⑥ 启动 3个节点的 etcd 服务
systemctl start etcd
systemctl status etcd
systemctl enable etcd    设置开机自启动

查看etcd集群的状态

/k8s/etcd/bin/etcdctl \
--ca-file=/k8s/etcd/ssl/ca.pem \
--cert-file=/k8s/etcd/ssl/etcd.pem \

--key-file=/k8s/etcd/ssl/etcd-key.pem \
 --endpoints=https://192.168.134.135:2379,https://192.168.134.137:2379,https://192.168.134.138:2379 \
cluster-health
/k8s/etcd/bin/etcdctl --ca-file=/k8s/etcd/ssl/ca.pem --cert-file=/k8s/etcd/ssl/etcd.pem --key-file=/k8s/etcd/ssl/etcd-key.pem --endpoints=https://192.168.134.135:2379,https://192.168.134.137:2379,https://192.168.134.138:2379 cluster-health

三、部署安全的k8s Master 高可用集群

1、自签ApiServer SSL证书

k8s集群中所有资源的访问和变更都是通过kube-apiserver的REST API来实现的,首先在master 节点上部署kube-apiserver组件

首先我们为apiserver签发一套SSL证书,过程与etcd类似,ssl用于存放自签证书,cfg用于存放配置文件,bin用于存放执行程序,logs用于存放日志文件

cd /
mkdir -p k8s/kubernetes/{ssl,cfg,bin,logs}
cd /k8s/kubernetes/ssl/
① 创建 CA 配置文件:ca-config.json
vim ca-config.json
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
② 创建 CA 证书签名请求文件:ca-csr.json
vim ca-csr.json
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}
③ 生成 CA 证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
④ 创建证书签名请求文件:kubernetes-csr.json
vim kubernetes-csr.json
{
    "CN": "kubernetes",
    "hosts": [
      "127.0.0.1",
      "10.0.0.1",
      "192.168.134.135",
      "192.168.134.136",
      "192.168.134.137",
      "192.168.134.138",
      "192.168.134.139",
      "192.168.134.140",
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    }
}

说明:
- hosts:指定会直接访问 apiserver 的IP列表,一般需指定 etcd 集群、kubernetes master 集群的主机 IP 和 kubernetes 服务的服务 IP,Node 的IP一般不需要加入。
⑤ 为 kubernetes 生成证书和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json |cfssljson -bare kubernetes

2、部署 kube-apiserver 组件

① 下载k8s

将下载好的 kubernetes-v1.16.2-server-linux-amd64.tar.gz 上传到 /usr/local/src下,并解压:

先将 master 节点上部署的组件拷贝到 /k8s/kubernetes/bin 目录

cp {kube-apiserver,kube-controller-manager,kube-scheduler} /k8s/kubernetes/bin/
cp -p /usr/local/src/kubernetes/server/bin/kubectl /usr/local/bin/
② 创建 Node 令牌文件:token.csv

Master apiserver 启用 TLS 认证后,Node节点 kubelet 组件想要加入集群,必须使用CA签发的有效证书才能与apiserver通信,当Node节点很多时,签署证书是一件很繁琐的事情,因此有了 TLS Bootstrap 机制,kubelet 会以一个低权限用户自动向 apiserver 申请证书,kubelet 的证书由 apiserver 动态签署。因此先为 apiserver 生成一个令牌文件,令牌之后会在 Node 中用到。

生成 token,一个随机字符串,可使用如下命令生成 token:apiserver 配置的 token 必须与 Node 节点 bootstrap.kubeconfig 配置保持一致。

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

创建 token.csv,格式:token,用户,UID,用户组

vim /k8s/kubernetes/cfg/token.csv
bfa3cb7f6f21f87e5c0e5f25e6cfedad,kubelet-bootstrap,10001,"system:node-bootstrapper"
EOF
③ 创建 kube-apiserver 配置文件:kube-apiserver.conf

kube-apiserver 有很多配置项,可以参考官方文档查看每个配置项的用途:kube-apiserver

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



重点配置说明:
- --etcd-servers:etcd 集群地址
- --bind-address:apiserver 监听的地址,一般配主机IP
- --secure-port:监听的端口  默认6443
- --advertise-address:集群通告地址,其它Node节点通过这个地址连接 apiserver,不配置则使用 --bind-address
- --tls-cert-file:服务端CA证书文件全路径
- --service-cluster-ip-range:Service 的 虚拟IP范围,以CIDR格式标识,该IP范围不能与物理机的真实IP段有重合。
- --service-node-port-range:Service 可映射的物理机端口范围,默认30000-32767
- --admission-control:集群的准入控制设置,各控制模块以插件的形式依次生效,启用RBAC授权和节点自管理
- --authorization-mode:授权模式,包括:AlwaysAllow,AlwaysDeny,ABAC(基于属性的访问控制),Webhook,RBAC(基于角色的访问控制),Node(专门授权由 kubelet 发出的API请求)。(默认值"AlwaysAllow")。
- --enable-bootstrap-token-auth:启用TLS bootstrap功能
- --token-auth-file:这个文件将被用于通过令牌认证来保护API服务的安全端口。
- --v:指定日志级别,0~8,越大日志越详细
④ 创建 apiserver 服务:kube-apiserver.service
vim /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target

[Service]
EnvironmentFile=-/k8s/kubernetes/cfg/kube-apiserver.conf
ExecStart=/k8s/kubernetes/bin/kube-apiserver $KUBE_APISERVER_OPTS

Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
⑤ 启动 kube-apiserver 组件
# systemctl daemon-reload        重新加载
# systemctl start kube-apiserver      启动
# systemctl enable kube-apiserver      设置开机自启动

检查启动状态

systemctl status kube-apiserver.service

查看启动日志

tail -f kube-apiserver.INFO
⑥ 将 kubelet-bootstrap 用户绑定到系统集群角色,之后便于 Node 使用token请求证书
kubectl create clusterrolebinding kubelet-bootstrap \
  --clusterrole=system:node-bootstrapper \
  --user=kubelet-bootstrap

3、部署kube-controller-manager组件

① 创建 kube-controller-manager 配置文件:kube-controller-manager.conf
vim /k8s/kubernetes/cfg/kube-controller-manager.conf
KUBE_CONTROLLER_MANAGER_OPTS="--leader-elect=true \
  --master=127.0.0.1:8080 \
  --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=/k8s/kubernetes/ssl/ca.pem \
  --cluster-signing-key-file=/k8s/kubernetes/ssl/ca-key.pem \
  --root-ca-file=/k8s/kubernetes/ssl/ca.pem \
  --service-account-private-key-file=/k8s/kubernetes/ssl/ca-key.pem \
  --experimental-cluster-signing-duration=87600h0m0s \
  --v=2 \
  --logtostderr=false \
  --log-dir=/k8s/kubernetes/logs"


重点配置说明:
- --leader-elect:当该组件启动多个时,自动选举,默认true
- --master:连接本地apiserver,apiserver 默认会监听本地8080端口
- --allocate-node-cidrs:是否分配和设置Pod的CDIR
- --service-cluster-ip-range:Service 集群IP段
② 创建 kube-controller-manager 服务:kube-controller-manager.service
vim /usr/lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target

[Service]
EnvironmentFile=/k8s/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/k8s/kubernetes/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS

Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
③ 启动 kube-controller-manager 组件

启动组件

# systemctl daemon-reload
# systemctl start kube-controller-manager
# systemctl enable kube-controller-manager
systemctl status kube-controller-manager
#tail -f /k8s/kubernetes/logs/kube-controller-manager.INFO

4、部署kube-scheduler组件

① 创建 kube-scheduler 配置文件:kube-scheduler.conf
vim /k8s/kubernetes/cfg/kube-scheduler.conf
KUBE_SCHEDULER_OPTS="--leader-elect=true \
  --master=127.0.0.1:8080 \
  --address=127.0.0.1 \
  --v=2 \
  --logtostderr=false \
  --log-dir=/k8s/kubernetes/logs"
② 创建 kube-scheduler 服务:kube-scheduler.service
vim /usr/lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target

[Service]
EnvironmentFile=/k8s/kubernetes/cfg/kube-scheduler.conf
ExecStart=/k8s/kubernetes/bin/kube-scheduler $KUBE_SCHEDULER_OPTS

Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
③ 启动 kube-scheduler 组件
# systemctl daemon-reload
# systemctl start kube-scheduler
# systemctl enable kube-scheduler

查看状态

systemctl status kube-scheduler

查看启动日志

tail -f /k8s/kubernetes/logs/kube-scheduler.INFO

5、查看集群状态

① 查看组件状态
kubectl get cs

四、集群搭建--部署node节点

1、安装docker

① 卸载旧版本
yum remove docker docker-common docker-selinux

② 安装依赖包
# yum install -y yum-utils device-mapper-persistent-data lvm2

③ 安装 Docker 软件包源
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

安装gcc 相关
yum -y install gcc

④ 安装 Docker CE
# yum install docker-ce

⑤ 启动 Docker 服务
# systemctl start docker

⑥ 设置开机启动
# systemctl enable docker

⑦ 验证安装是否成功
# docker -v
# docker info

2、Node 节点证书

① 创建 Node 节点的证书签名请求文件:kube-proxy-csr.json

首先在 k8s-master-1 节点上,通过颁发的 CA 证书先创建好 Node 节点要使用的证书

vim kube-proxy-csr.json
{
    "CN": "system:kube-proxy",
    "hosts": [],
    "key": {
        "algo": "rsa",
        "size": 2048
    }
}
② 为 kube-proxy 生成证书和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
③ node 节点创建工作目录

在 k8s-node-1 节点上创建 k8s 目录

# mkdir -p /k8s/kubernetes/{bin,cfg,logs,ssl}
④ 将 k8s-master-1 节点的文件拷贝到 node 节点

将 kubelet、kube-proxy 拷贝到 node 节点上:

# scp -r /usr/local/src/kubernetes/server/bin/{kubelet,kube-proxy} root@k8s-node-1:/k8s/kubernetes/bin/

将证书拷贝到 k8s-node-1 节点上:

# scp -r /k8s/kubernetes/ssl/{ca.pem,kube-proxy.pem,kube-proxy-key.pem} root@k8s-node-1:/k8s/kubernetes/ssl/

3、安装kubelet

① 创建请求证书的配置文件:bootstrap.kubeconfig

bootstrap.kubeconfig 将用于向 apiserver 请求证书,apiserver 会验证 token、证书 是否有效,验证通过则自动颁发证书。

vim /k8s/kubernetes/cfg/bootstrap.kubeconfig
apiVersion: v1
clusters:
- cluster: 
    certificate-authority: /k8s/kubernetes/ssl/ca.pem
    server: https://192.168.134.135:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubelet-bootstrap
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: kubelet-bootstrap
  user:
    token: d36445ecbeb118755f2c253e4cbcd395


说明:
- certificate-authority:CA 证书
- server:master 地址
- token:master 上 token.csv 中配置的 token
② 创建 kubelet 配置文件:kubelet-config.yml

为了安全性,kubelet 禁止匿名访问,必须授权才可以,通过 kubelet-config.yml 授权 apiserver 访问 kubelet。

vim /k8s/kubernetes/cfg/kubelet-config.yml
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: /k8s/kubernetes/ssl/ca.pem
authorization:
  mode: Webhook
  webhook:
    cacheAuthroizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s
evictionHard:
  imagefs.available: 15%
  memory.available: 100Mi
  nodefs.available: 10%
  nodefs.inodesFree: 5%
maxOpenFiles: 100000
maxPods: 110





说明:
- address:kubelet 监听地址
- port:kubelet 的端口
- cgroupDriver:cgroup 驱动,与 docker 的 cgroup 驱动一致
- clusterDNS:集群DNS服务器IP地址
- clusterDomain:服务DNS域名后缀,例如cluster.local
- authentication:访问 kubelet 的授权信息,设置是否允许匿名访问或者是否使用webhook进行授权
- authorization:认证相关信息
- evictionHard:垃圾回收策略
- maxPods:最大pod数
③ 创建 kubelet 服务配置文件:kubelet.conf
vim /k8s/kubernetes/cfg/kubelet.conf
KUBELET_OPTS="--hostname-override=k8s-node-1 \
  --network-plugin=cni \
  --cni-bin-dir=/opt/cni/bin \
  --cni-conf-dir=/etc/cni/net.d \
  --cgroups-per-qos=false \
  --enforce-node-allocatable="" \
  --kubeconfig=/k8s/kubernetes/cfg/kubelet.kubeconfig \:q
  --bootstrap-kubeconfig=/k8s/kubernetes/cfg/bootstrap.kubeconfig \
  --config=/k8s/kubernetes/cfg/kubelet-config.yml \
  --cert-dir=/k8s/kubernetes/ssl \
  --pod-infra-container-image=kubernetes/pause:latest \
  --v=2 \
  --logtostderr=false \
  --log-dir=/k8s/kubernetes/logs"


说明:
- --hostname-override:当前节点注册到K8S中显示的名称,默认为主机 hostname
- --network-plugin:启用 CNI 网络插件
- --cni-bin-dir:CNI 插件可执行文件位置,默认在 /opt/cni/bin 下
- --cni-conf-dir:CNI 插件配置文件位置,默认在 /etc/cni/net.d 下
- --cgroups-per-qos:必须加上这个参数和--enforce-node-allocatable,否则报错 [Failed to start ContainerManager failed to initialize top level QOS containers.......]
- --kubeconfig:会自动生成 kubelet.kubeconfig,用于连接 apiserver
- --bootstrap-kubeconfig:指定 bootstrap.kubeconfig 文件
- --config:kubelet 配置文件
- --cert-dir:证书目录
- --pod-infra-container-image:管理Pod网络的镜像,基础的 Pause 容器,默认是 k8s.gcr.io/pause:3.1
④ 创建 kubelet 服务:kubelet.service
vim /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
After=docker.service
Before=docker.service

[Service]
EnvironmentFile=/k8s/kubernetes/cfg/kubelet.conf
ExecStart=/k8s/kubernetes/bin/kubelet $KUBELET_OPTS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
⑤ 启动 kubelet
# systemctl daemon-reload
# systemctl start kubelet
# systemctl enable kubelet
# tail -f /k8s/kubernetes/logs/kubelet.INFO
⑥master 给node授权

kubelet启动后,还没加入到集群中,回向apiserver请求证书,需要手动在master-1上对node 授权。

去master-1上查看是否有新的客户端请求颁发证书

kubectl get csr

给客户端颁发证书,允许加入集群

kubectl certificate approve node-csr-WYQh3zST8magLIwnchP9jL_pxRBr2hPVTzhM0Wm-cqk
⑦授权成功 ,查看集群 node是否加入(此时的 node 还处于未就绪的状态,因为还没有安装 CNI 组件):
kubectl get node

颁发证书后,可以在 /k8s/kubenetes/ssl 下看到 master 为 kubelet 颁发的证书:

在 /k8s/kubenetes/cfg 下可以看到自动生成的 kubelet.kubeconfig 配置文件:

4、安装kube-proxy

① 创建 kube-proxy 连接 apiserver 的配置文件:kube-proxy.kubeconfig
vim /k8s/kubernetes/cfg/kube-proxy.kubeconfig
apiVersion: v1
clusters:
- cluster:
    certificate-authority: /k8s/kubernetes/ssl/ca.pem
    server: https://192.168.134.135:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kube-proxy
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: kube-proxy
  user:
    client-certificate: /k8s/kubernetes/ssl/kube-proxy.pem
    client-key: /k8s/kubernetes/ssl/kube-proxy-key.pem
② 创建 kube-proxy 配置文件:kube-proxy-config.yml
vim /k8s/kubernetes/cfg/kube-proxy-config.yml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
address: 0.0.0.0
metrisBindAddress: 0.0.0.0:10249
clientConnection:
  kubeconfig: /k8s/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: k8s-node-1
clusterCIDR: 10.0.0.0/24
mode: ipvs
ipvs:
  scheduler: "rr"
iptables:
  masqueradeAll: true


说明:
- metrisBindAddress:采集指标暴露的地址端口,便于监控系统,采集数据
- clusterCIDR:集群 Service 网段
③ 创建 kube-proxy 配置文件:kube-proxy.conf
vim /k8s/kubernetes/cfg/kube-proxy.conf
KUBE_PROXY_OPTS="--config=/k8s/kubernetes/cfg/kube-proxy-config.yml \
  --v=2 \
  --logtostderr=false \
  --log-dir=/k8s/kubernetes/logs"
④ 创建 kube-proxy 服务:kube-proxy.service
vim /usr/lib/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Proxy
After=network.target

[Service]
EnvironmentFile=/k8s/kubernetes/cfg/kube-proxy.conf
ExecStart=/k8s/kubernetes/bin/kube-proxy $KUBE_PROXY_OPTS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
⑤ 启动 kube-proxy
# systemctl daemon-reload
# systemctl start kube-proxy

开机启动:

# systemctl enable kube-proxy

查看启动日志: 
# tail -f /k8s/kubernetes/logs/kube-proxy.INFO

5、部署其他node节点

跟上述步骤一样,将k8s-node-1改成k8s-node-2即可

在master节点 查看是否加入集群

kubectl get node -o wide

6、部署k8s容器集群网络

① K8S 集群网络

Kubernetes 项目并没有使用 Docker 的网络模型,kubernetes 是通过一个 CNI 接口维护一个单独的网桥来代替 docker0,这个网桥默认叫 cni0。

Flannel 是 CNI 的一个插件,可以看做是 CNI 接口的一种实现。Flannel 是针对 Kubernetes 设计的一个网络规划服务,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。

② 创建 CNI 工作目录

通过给 kubelet 传递 --network-plugin=cni 命令行选项来启用 CNI 插件。 kubelet 从 --cni-conf-dir (默认是 /etc/cni/net.d)读取配置文件并使用该文件中的 CNI 配置来设置每个 pod 的网络。CNI 配置文件必须与 CNI 规约匹配,并且配置引用的任何所需的 CNI 插件都必须存在于 --cni-bin-dir(默认是 /opt/cni/bin)指定的目录。

由于前面部署 kubelet 服务时,指定了 --cni-conf-dir=/etc/cni/net.d,--cni-bin-dir=/opt/cni/bin,因此首先在node节点上创建这两个目录:

# mkdir -p /opt/cni/bin /etc/cni/net.d
③ 装 CNI 插件

可以从 github 上下载 CNI 插件:下载 CNI 插件

解压到 /opt/cni/bin:

# tar zxf cni-plugins-linux-amd64-v0.8.2.tgz -C /opt/cni/bin/
④ 部署 Flannel

可通过此地址下载 flannel 配置文件:下载 kube-flannel.yml

注意如下配置:Network 的地址需与 kube-controller-manager.conf 中的 --cluster-cidr=10.244.0.0/16 保持一致。

在 k8s-master-1 节点上部署 Flannel:

# kubectl apply -f kube-flannel.yml
⑤ 检查部署状态

Flannel 会在 Node 上起一个 Flannel 的 Pod,可以查看 pod 的状态看 flannel 是否启动成功:

# kubectl get pods -n kube-system -o wide

Flannel 部署成功后,就可以看 Node 是否就绪:

# kubectl get nodes -o wide

在 Node 上查看网络配置,可以看到多了一个 flannel.1 的虚拟网卡,这块网卡用于接收 Pod 的流量并转发出去。

注意:此时可能会报错,node节点的状态为:notready,去node节点查看日志

journalctl -f -u kubelet.service

cni config uninitialized

解决办法 :把kubelet.conf中 指定cni的配置删掉 重启kubelet

⑥ 测试创建 Pod

例如创建一个 Nginx 服务:

# kubectl create deployment web --image=nginx

刚创建完事这个状态 过会就是正常了

在对应的节点上 docker ps -a 查看部署的容器

暴露端口并访问 Nginx:

kubectl expose deployment web --port=80 --type=NodePort

7、部署CoreDNS服务

从k8s1.11版本开始,集群的DNS服务便由CoreDNS提供,CoreDNS是CNCF基金会孵化的一个项目,使用go语言开发的高性能、插件式、易扩展的DNS服务端,目前已毕业。CoreDNS解决了KubeDNS的一些问题,支持自定义DNS记录及配置upstream DNS Server,可以统一管理kubernetes基于服务的内部DNS和数据中心的物理DNS。

在kubernetes集群推荐使用Service Name 作为服务的访问地址,因此需要一个kubernetes集群范围的DNS服务实现Service Name 到Cluster IP 的解析,这就是Kubernetes基于DNS的服务发现功能。

① 部署 CoreDNS

首先在两个node节点的kube-config.yml配置文件中 添加

clusterDNS:
- 10.0.0.2 
clusterDomain: cluster.local

部署CoreDNS需要创建3个资源对象:ConfigMap、Deployment、Service

ConfigMap "coredns" 主要设置Coredns的主配置文件Corefile的内容,其中可以定义各种域名的解析方式和使用的插件

Deployment "coredns"主要设置CordDNS容器应用的内容,其中,replicas副本的数量通常应该根据集群的规模和服务数量确定,如果单个CoreDNS进程不足以支撑整个集群的DNS查询,则可以通过水平扩展提高查询能力,由于DNS服务是kubernetes集群的关键核心服务,所以建议为其 Deployment设置自动扩缩容控制器,自动管理副本数量

Service "coredns"是DNS服务的配置,需要设置固定的ClusterIP 地址,也需要将所有node上的kubelet启动参数cluster-dns 都设置成这个clusterip

下载CoreDNS配置文件:coredns.yaml

部署DNS服务

kubectl apply -f coredns.yaml

查看状态

kubectl get pods -n kube-system

ImagePullBackOff 这个错误是拉去不到镜像

查看详细日志

kubectl describe pod coredns-5fb6c888d6-hbbrt -n kube-system                           coredns-686c689586-q7cz9 :是pod name
或者 kubectl logs -n kube-system metrics-server-7dbf6c4558-dmmrs

根据日志 去node-2节点 拉去相应的镜像

docker pull

然后修改镜像的tag 0ad7f9e4a77d :为镜像的ID

docker tag 0ad7f9e4a77d registry.aliyuncs.com/google_containers/coredns/coredns:v1.10.0

完事重启下docker

在master节点再看下状态,如果换是同样的问题,就改一下cordDNS的配置文件,把拉去镜像那里改成你在node上拉去的地址

在重新加载cordDNS配置文件 查看 就OK了。

② 验证 CoreDNS 服务名的DNS解析

使用一个带有nslookup工具的pod 来验证DNS服务能否正常工作

vim busybox.yaml
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  dnsPolicy: ClusterFirst
  containers:
  - name: busybox
    image: busybox:1.28.4
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
  
  运行完成创建
  # kubectl apply -f busybox.yaml

YAML 格式:

apiVersion: v1        #与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Pod        #该配置的类型,我们使用的是 POD
metadata:                #译名为元数据,即 POD 的一些基本属性和信息
name: nginx        #POD 的名称
namedpace    #pod名称空间
labels:            #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组
app: nginx        #设置key为app,value为nginx的标签
spec:            #期望Pod实现的功能(即在pod中部署)
containers:        #生成container,与docker中的container是同一种
- name: nginx        #container的名称
image: nginx:1.7.9        #使用镜像nginx:1.7.9创建container,该container默认80端口可访问
imagePullPolicy: IfNotPresent #设置container的拉取策略,IfNotPresent存在时不进行拉取。

创建成功之后查看容器

kubectl get pod -owide  或者kubectl get pod --all-namespaces -owide   查看容器详细信息

然后去对应的节点上看下有没有镜像存在

查看pod容器日志

kubectl describe pod/podname

进入容器:

kubectl exec -it pod/busybox -- /bin/sh 或者kubectl exec -it busybox sh

报错的话 是权限问题

kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes

进入容器 执行 nslookup web 成功解析

遇到的问题1:解析时候报错

解决:可能是镜像版本的问题,修改配置文件镜像的版本,然后删除pod 重新创建,在进入容器OK。

CroeDNS的配置说明

CoreDNs 的主要功能是通过插件系统实现的。

常用的插件如下:

  • loadbalance: 提供基于 DNS 的负载均衡功能。
  • loop: 检测在 DNS 解析过中出现的简单循环问题
  • cache:提供前端缓存功能。
  • health:对 Endpoint 进行健康检查。
  • kubernetes:从 Kubernetes 中读取 zone 数据。
  • etcd:从 etcd 中读取 zone 数据,可用于自定义域名记录.
  • fle:从 RFC1035 格式文件中读取 zone 数据。
  • reload:定时自动重新加载 Corefile 配置文件的内容
  • prometheus:为 Prometheus 系统提供采集性能指标数据的 URL
  • errors:对错误信息进行日志记录
  • log:对 DNS 查询进行日志记录

在下面的示例中为域名"cluster.local"设置了一系列插件,包括 errors、health readkubernetes、prometheus、forward、cache、loop、reload 和 loadbalance,在进行域名解析时,这些插件将以从上到下的顺序依次执行:

cluster.local {
  errors
  health {
  lameduck 5s
  }
  ready
  kubernetes cluster.local 169.169.0.0/16 {
    fallthrough in-addr.arpa ip6.arpa
  }
  prometheus :9153
  forward . /etc/resolv.conf
  cache 30
  loop
  reload
  loadbalance
}

8、集群搭建--多master部署

1、部署Master2组件
① 将 k8s-master-1 上相关文件拷贝到 k8s-master-2 上

创建k8s工作目录:

# mkdir -p /k8s/kubernetes
# mkdir -p /k8s/etcd

拷贝 k8s 配置文件、执行文件、证书:

# scp -r /k8s/kubernetes/{cfg,ssl,bin} root@k8s-master-2:/k8s/kubernetes
# cp /k8s/kubernetes/bin/kubectl /usr/local/bin/

拷贝 etcd 证书:

# scp -r /k8s/etcd/ssl root@k8s-master-2:/k8s/etcd

拷贝 k8s 服务的service文件:

# scp /usr/lib/systemd/system/kube-* root@k8s-master-2:/usr/lib/systemd/system
② 修改 k8s-master-2 上的配置文件

修改 kube-apiserver.conf,修改IP为本机IP

③ 启动 k8s-master-2 组件

重新加载配置:

systemctl daemon-reload

启动 kube-apiserver:

systemctl start kube-apiserver # systemctl enable kube-apiserver

启动 kube-controller-manager:

systemctl start kube-controller-manager # systemctl enable kube-controller-manager

部署 kube-scheduler:

systemctl start kube-scheduler # systemctl enable kube-scheduler

④ 验证

2、部署nginx负载均衡

为了保证 k8s master 的高可用,将使用 k8s-lb-master 和 k8s-lb-backup 这两台机器来部署负载均衡。这里使用 nginx 做负载均衡器,

下面分别在 k8s-lb-master 和 k8s-lb-backup 这两台机器上部署 nginx。

① gcc等环境安装,后续有些软件安装需要这些基础环境
# gcc安装: 
# yum install gcc-c++ 

# PCRE pcre-devel 安装: 
# yum install -y pcre pcre-devel 

# zlib 安装: 
# yum install -y zlib zlib-devel 

#OpenSSL 安装: 

# yum install -y openssl openssl-devel
② 安装nginx

rpm -ivh https://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.16.1-1.el7.ngx.x86_64.rpm

③ apiserver 负载配置

vim /etc/nginx/nginx.conf

增加如下配置:

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.31.24:6443;
        server 192.168.31.26:6443;
    }
    server {
        listen 6443;
        proxy_pass k8s-apiserver;
    }
}
④ 启动 nginx

systemctl start nginx # systemctl enable nginx

3、部署keepAlive

为了保证 nginx 的高可用,还需要部署 keepalive,keepalive 主要负责 nginx 的健康检查和故障转移。

① 分别在 k8s-lb-master 和 k8s-lb-backup 这两台机器上安装 keepalive

yum install keepalived -y

② master 启动 keepalived

修改 k8s-lb-master keepalived 配置文件

vim /etc/keepalived/keepalived.conf
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
}

vrrp_script check_nginx {
   script "/etc/keepalived/check_nginx.sh" 
}

# vrrp实例
vrrp_instance VI_1 {
    state MASTER 
    interface ens33 
    virtual_router_id 51 
    priority 100
    advert_int 1 
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.134.100/24 
    }
    track_script {
        check_nginx
    }
}

配置说明:

  • vrrp_script:用于健康检查nginx状态,如果nginx没有正常工作,就会进行故障漂移,使备节点接管VIP,这里通过 shell 脚本来检查nginx状态
  • state:keepalived 角色,主节点为 MASTER,备节点为 BACKUP
  • interface:接口,配置本地网卡名,keepalived 会将虚拟IP绑定到这个网卡上
  • virtual_router_id:#VRRP 路由ID实例,每个实例是唯一的
  • priority:优先级,备服务器设置90
  • advert_int:指定VRRP心跳包通告间隔时间,默认1秒
  • virtual_ipaddress:VIP,要与当前机器在同一网段,keepalived 会在网卡上附加这个IP,之后通过这个IP来访问Nginx,当nginx不可用时,会将此虚拟IP漂移到备节点上。

增加 check_nginx.sh 脚本,通过此脚本判断 nginx 是否正常:

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

增加可执行权限:

chmod +x /etc/keepalived/check_nginx.sh

启动 keepalived:

systemctl start keepalived # systemctl enable keepalived

③ backup 启动 keepalived

修改 k8s-lb-backup keepalived 配置文件

vim /etc/keepalived/keepalived.conf
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
}

vrrp_script check_nginx {
   script "/etc/keepalived/check_nginx.sh"
}

# vrrp实例
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.134.100/24
    }
    track_script {
        check_nginx
    }
}

增加 check_nginx.sh 脚本:

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

增加可执行权限:

chmod +x /etc/keepalived/check_nginx.sh

启动 keepalived:

systemctl start keepalived # systemctl enable keepalived

④ 验证负载均衡

keepalived 已经将VIP附加到MASTER所在的网卡上

BACKUP节点上并没有

关闭 k8s-lb-master 上的nginx,可看到VIP已经不在了

可以看到已经漂移到备节点上了,如果再重启 MASTER 上的 Ngnix,VIP又会漂移到主节点上

访问虚拟IP也可以访问

相关推荐
秀儿y18 分钟前
单机服务和微服务
java·开发语言·微服务·云原生·架构
运维&陈同学5 小时前
【Beats01】企业级日志分析系统ELK之Metricbeat与Heartbeat 监控
运维·elk·elasticsearch·云原生·kibana·heartbeat·metricbeat
AKA小徐6 小时前
Debian12使用RKE2离线部署3master2node三主两从的k8s集群详细教程
kubernetes·rancher·rke2
老大白菜13 小时前
Windows 11 安装 Dify 完整指南 非docker环境
windows·docker·容器
tntlbb17 小时前
Ubuntu20.4 VPN+Docker代理配置
运维·ubuntu·docker·容器
Gabriel_liao17 小时前
Docker安装Neo4j
docker·容器·neo4j
有一个好名字18 小时前
zookeeper分布式锁模拟12306买票
分布式·zookeeper·云原生
Anna_Tong20 小时前
云原生大数据计算服务 MaxCompute 是什么?
大数据·阿里云·云原生·maxcompute·odps
豆豆豆豆变21 小时前
Docker轻量级可视化工具Portainer
docker·容器·自动化运维
花晓木21 小时前
k8s etcd 数据损坏处理方式
容器·kubernetes·etcd