集群证书

集群证书

kubernetes 组件众多,这些组件之间通过 HTTP/GRPC 相互通信,以协同完成集群中应用的部署和管理工 作。尤其是 master 节点,更是掌握着整个集群的操作。其安全就变得尤为重要了,在目前世面上最安全的,使 用最广泛的就是数字证书。kubernetes 正是使用这种认证方式。

4.1、 证书原理(创建根证书)

4.2、 安装 cfssl 证书生成工具

本次我们使用 cfssl 证书生成工具,这是一款把预先的证书机构、使用期等时间写在 json 文件里面会更加高 效和自动化。cfssl 采用 go 语言编写,是一个开源的证书管理工具,cfssljson 用来从 cfssl 程序获取 json 输出, 并将证书,密钥,csr 和 bundle 写入文件中。

https://github.com/cloudflare/cfssl/releases

# 下载
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64

# 将文件复制到master节点中,移动到opt目录下面
[root@kubernetes-master01 ~]# mv cfssl* /opt/
[root@kubernetes-master01 ~]# cd /opt/
[root@kubernetes-master01 opt]# ls
cfssl_linux-amd64      cni         kernel-lt-4.4.245-1.el7.elrepo.x86_64.rpm
cfssljson_linux-amd64  containerd  kernel-lt-devel-4.4.245-1.el7.elrepo.x86_64.rpm
[root@kubernetes-master01 opt]# 

# 设置执行权限
chmod +x cfssljson_linux-amd64
chmod +x cfssl_linux-amd64
# 移动到/usr/local/bin
mv cfssljson_linux-amd64 cfssljson
mv cfssl_linux-amd64 cfssl
mv cfssljson cfssl /usr/local/bin

image-20210125233858958

验证是否安装成功

[root@kubernetes-master01 opt]# cfssl
No command is given.
Usage:
Available commands:
	serve
	ocspsign
	bundle
	gencrl
	print-defaults
	sign
	version
	genkey
	gencert
	ocspdump
	ocsprefresh
	ocspserve
	scan
	certinfo
	info
	revoke
	selfsign
Top-level flags:
  -allow_verification_with_non_compliant_keys
    	Allow a SignatureVerifier to use keys which are technically non-compliant with RFC6962.
  -loglevel int
    	Log level (0 = DEBUG, 5 = FATAL) (default 1)

image-20210125233935589

4.3、创建集群根证书

在mster-01机器上生成证书

从整个架构来看,集群环境中最重要的部分就是 etcd 和 API server。所以集群当中的证书都是针对 etcd 和 api server 来设置的。

所谓根证书,是 CA 认证中心与用户建立信任关系的基础,用户的数字证书必须有一个受信任的根证书,用 户的数字证书才是有效的。从技术上讲,证书其实包含三部分,用户的信息,用户的公钥,以及证书签名。CA 负责数字证书的批审、发放、归档、撤销等功能,CA 颁发的数字证书拥有 CA 的数字签名,所以除了 CA 自身, 其他机构无法不被察觉的改动。

# 创建证书目录
mkdir -p /opt/cert/ca

# 创建证书配置文件(证书配置文件)
cat > /opt/cert/ca/ca-config.json <<EOF
{
    "signing": {
        "default": {
            "expiry": "8760h"  # 证书有效期时间
        },
        "profiles": {
            "kubernetes": {
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ],
                "expiry": "8760h"
            }
        }
    }
}

EOF

image-20210126223817943

证书详解

  1. default 是默认策略,指定证书默认有效期是 1 年

  2. profiles 是定义使用场景,这里只是 kubernetes,其实可以定义多个场景,分别指定不同的过期时间,使用场 景等参数,后续签名证书时使用某个 profile;

  3. signing: 表示该证书可用于签名其它证书,生成的 ca.pem 证书 (生成根证书)

  4. server auth: 表示 client 可以用该 CA 对 server 提供的证书进行校验;

  5. client auth: 表示 server 可以用该 CA 对 client 提供的证书进行验证。

4.4、 创建根 CA 证书签名请求文件

# 创建根请求文件
cat > /opt/cert/ca/ca-csr.json << EOF
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa", # 证书签名长度
        "size": 2048
    },
    "names": [{
        "C": "CN",
        "ST": "ShangHai",
        "L": "ShangHai"
    }]
}
EOF

image-20210126225536070

4.4.1、 证书详解

证书项 解释
C 国家
ST
L 城市
O 组织
OU 组织别名

4.5、 生成证书

# 生成证书(只是根证书生成完了)
[root@kubernetes-master01 ca]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
2021/01/26 23:00:22 [INFO] generating a new CA key and certificate from CSR
2021/01/26 23:00:22 [INFO] generate received request
2021/01/26 23:00:22 [INFO] received CSR
2021/01/26 23:00:22 [INFO] generating key: rsa-2048
2021/01/26 23:00:22 [INFO] encoded CSR
2021/01/26 23:00:22 [INFO] signed certificate with serial number 383982499575709281112198293559184111754857336389

# 生成证书信息
[root@kubernetes-master01 ca]# ll
total 20
-rw-r--r--. 1 root root  410 Jan 26 22:36 ca-config.json
-rw-r--r--. 1 root root  960 Jan 26 23:00 ca.csr # 生成的证书
-rw-r--r--. 1 root root  184 Jan 26 22:55 ca-csr.json
-rw-------. 1 root root 1675 Jan 26 23:00 ca-key.pem # 证书私钥
-rw-r--r--. 1 root root 1281 Jan 26 23:00 ca.pem # 证书密钥

4.5.1、 参数详解

参数项 解释
gencert 生成新的 key(密钥)和签名证书
--initca 初始化一个新 CA 证书

5、 部署 Etcd 集群

开始创建应用证书,生成Etcd证书

Etcd 是基于 Raft 的分布式 key-value 存储系统,由 CoreOS 团队开发,常用于服务发现,共享配置,以及 并发控制(如 leader 选举,分布式锁等等)。Kubernetes 使用 Etcd 进行状态和数据存储!

5.1、 ETCD 集群规划

ETCD 节点 IP
Etcd-01 172.16.0.50
Etcd-02 172.16.0.51
Etcd-03 172.16.0.52

5.2、 创建 ETCD 证书

# 创建目录文件夹
mkdir -p /opt/cert/etcd
# 配置etct证书
cd /opt/cert/etcd
cat > etcd-csr.json << EOF
{
        "CN": "etcd",
        "hosts": [
            "127.0.0.1", 
            "172.16.0.50", # 可以访问Etcd的ip(去除注释)
            "172.16.0.51",
            "172.16.0.52",
            "172.16.0.53",
            "172.16.0.54"
        ],
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "ST": "ShangHai",
                "L": "ShangHai"
            }
	]
}
EOF
            


            

5.3、 生成证书

[root@kubernetes-master-01 etcd]# cfssl gencert -ca=../ca/ca.pem -ca-key=../ca/ca-key.pem -config=../ca/ca-config.json -profile=kubernetes etcd-csr.json | cfssljson -bare etcd
# 结果信息
2021/01/30 05:47:34 [INFO] generate received request
2021/01/30 05:47:34 [INFO] received CSR
2021/01/30 05:47:34 [INFO] generating key: rsa-2048
2021/01/30 05:47:34 [INFO] encoded CSR
2021/01/30 05:47:34 [INFO] signed certificate with serial number 269529173740327644274425676513621163656889856201
2021/01/30 05:47:34 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@kubernetes-master-01 etcd]# ls
etcd.csr  etcd-csr.json  etcd-key.pem  etcd.pem
[root@kubernetes-master-01 etcd]#

image-20210129214801895

5.3.1、参数详解

参数项 解释
gencert 生成新的 key(密钥)和签名证书
-initca 初始化一个新 ca
-ca-key 指明 ca 的证书
-config 指明 ca 的私钥文件
-profile 指明请求证书的 json 文件
-ca 与 config 中的 profile 对应,是指根据 config 中的 profile 段来生成证书的相关信息

5.4、 分发证书

将生成的证书放到对应的服务器中

for ip in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03
do
ssh root@${ip} "mkdir -pv /etc/etcd/ssl"
scp ../ca/ca*.pem root@${ip}:/etc/etcd/ssl
scp ./etcd*.pem root@${ip}:/etc/etcd/ssl
done

# 查看各个服务上的证书是否已经在服务器中
for ip in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03; do
ssh root@${ip} "ls -l /etc/etcd/ssl";
done

image-20210129215518519

5.5、 部署 ETCD

# 下载 ETCD 安装包
cd /opt
wget https://mirrors.huaweicloud.com/etcd/v3.3.24/etcd-v3.3.24-linux-amd64.tar.gz
# 解压
tar xf etcd-v3.3.24-linux-amd64.tar.gz
# 分发至其他节点
cd /opt
for i in kubernetes-master-02 kubernetes-master-01 kubernetes-master-03
do
scp ./etcd-v3.3.24-linux-amd64/etcd* root@$i:/usr/local/bin/
done
# 查看 ETCD 安装是否成功
[root@kubernetes-master-01 opt]# etcdctl 
NAME:
   etcdctl - A simple command line client for etcd.

WARNING:
   Environment variable ETCDCTL_API is not set; defaults to etcdctl v2.
   Set environment variable ETCDCTL_API=3 to use v3 API or ETCDCTL_API=2 to use v2 API.

USAGE:
   etcdctl [global options] command [command options] [arguments...]
   
VERSION:
   3.3.24
   
COMMANDS:
     backup          backup an etcd directory
     cluster-health
.....

image-20210129220335404

5.6、 注册 ETCD 服务

将 etcd 注册 systemd 服务主要是为了方便管理 ETCD。

# 各个节点执行一遍创建文件夹
mkdir -pv /etc/kubernetes/conf/etcd
# 配置信息
ETCD_NAME=`hostname` INTERNAL_IP=`hostname -i` INITIAL_CLUSTER=kubernetes-master-01=https://172.16.0.50:2380,kubernetes-master02=https://172.16.0.51:2380,kubernetes-master-03=https://172.16.0.52:2380 cat << EOF | sudo tee /usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos
[Service]
ExecStart=/usr/local/bin/etcd \\
--name ${ETCD_NAME} \\
--cert-file=/etc/etcd/ssl/etcd.pem \\
--key-file=/etc/etcd/ssl/etcd-key.pem \\
--peer-cert-file=/etc/etcd/ssl/etcd.pem \\
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \\
--trusted-ca-file=/etc/etcd/ssl/ca.pem \\
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \\
--peer-client-cert-auth \\
--client-cert-auth \\
--initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\
--listen-peer-urls https://${INTERNAL_IP}:2380 \\
--listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\
--advertise-client-urls https://${INTERNAL_IP}:2379 \\
--initial-cluster-token etcd-cluster \\
--initial-cluster ${INITIAL_CLUSTER} \\
--initial-cluster-state new \\
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF

# 出现多个ip解析写死ip
ETCD_NAME=`hostname` INTERNAL_IP="172.16.0.50" INITIAL_CLUSTER=kubernetes-master-01=https://172.16.0.50:2380,kubernetes-master02=https://172.16.0.51:2380,kubernetes-master-03=https://172.16.0.52:2380 cat << EOF | sudo tee /usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos
[Service]
ExecStart=/usr/local/bin/etcd \\
--name ${ETCD_NAME} \\
--cert-file=/etc/etcd/ssl/etcd.pem \\
--key-file=/etc/etcd/ssl/etcd-key.pem \\
--peer-cert-file=/etc/etcd/ssl/etcd.pem \\
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \\
--trusted-ca-file=/etc/etcd/ssl/ca.pem \\
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \\
--peer-client-cert-auth \\
--client-cert-auth \\
--initial-advertise-peer-urls https://172.16.0.50:2380 \\
--listen-peer-urls https://172.16.0.50:2380 \\
--listen-client-urls https://172.16.0.50:2379,https://127.0.0.1:2379 \\
--advertise-client-urls https://172.16.0.50:2379 \\
--initial-cluster-token etcd-cluster \\
--initial-cluster ${INITIAL_CLUSTER} \\
--initial-cluster-state new \\
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF

image-20210129222932723

[Unit]
Description=etcd
Documentation=https://github.com/coreos
[Service]
ExecStart=/usr/local/bin/etcd \
--name kubernetes-master-01 \ # 当前节点的主机名
--cert-file=/etc/etcd/ssl/etcd.pem \ # 证书路径(改成对应路径证书)
--key-file=/etc/etcd/ssl/etcd-key.pem \
--peer-cert-file=/etc/etcd/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \
--trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-client-cert-auth \
--client-cert-auth \ # 开启客户端的认证 
--initial-advertise-peer-urls https://172.16.0.50 172.16.0.50 172.16.0.50:2380 \ # 集群通信的地址
--listen-peer-urls https://172.16.0.50 172.16.0.50 172.16.0.50:2380 \
--listen-client-urls https://172.16.0.50 172.16.0.50 172.16.0.50:2379,https://127.0.0.1:2379 \
--advertise-client-urls https://172.16.0.50 172.16.0.50 172.16.0.50:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster kubernetes-master-01=https://172.16.0.50:2380,kubernetes-master02=https://172.16.0.51:2380,kubernetes-master-03=https://172.16.0.52:2380 \
--initial-cluster-state new \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

5.6.1、配置项详解

配置选项 选项说明
name 节点名称
data-dir 指定节点的数据存储目录
listen-peer-urls 与集群其它成员之间的通信地址
listen-client-urls 监听本地端口,对外提供服务的地址
initial-advertise-peer-urls 通告给集群其它节点,本地的对等 URL 地址
advertise-client-urls 客户端 URL,用于通告集群的其余部分信息
initial-cluster 集群中的所有信息节点
initial-cluster-token 集群的 token,整个集群中保持一致
initial-cluster-state 初始化集群状态,默认为 new
--cert-file 客户端与服务器之间 TLS 证书文件的路径
--key-file 客户端与服务器之间 TLS 密钥文件的路径
--peer-cert-file 对等服务器 TLS 证书文件的路径
--peer-key-file 对等服务器 TLS 密钥文件的路径
--trusted-ca-file 签名 client 证书的 CA 证书,用于验证 client 证书
--peer-trusted-ca-file 签名对等服务器证书的 CA 证书。
--trusted-ca-file 签名 client 证书的 CA 证书,用于验证 client 证书
--peer-trusted-ca-file 签名对等服务器证书的 CA 证书。

5.6.2、启动 ETCD

# 在三台节点上执行
[root@kubernetes-master-01 etcd]# systemctl enable --now etcd
Created symlink from /etc/systemd/system/multi-user.target.wants/etcd.service to /usr/lib/systemd/system/etcd.service.

[root@kubernetes-master-01 etcd]# systemctl status etcd
● etcd.service - etcd
   Loaded: loaded (/usr/lib/systemd/system/etcd.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2021-01-30 06:31:57 CST; 29s ago
     Docs: https://github.com/coreos

image-20210129223301490

三个都已经执行ETCD都已经起来

image-20210129230951936

如果etcd启动不起来,如何解决

# 查看日志
[root@kubernetes-master-01 etcd]# tail -f /var/log/messages

image-20210129224228232

错误二

# etcd的配置
cat /usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos
[Service]
ExecStart=/usr/local/bin/etcd \
--name kubernetes-master-03 \ # 名字要和当前主机名一致
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--peer-cert-file=/etc/etcd/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \
--trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-client-cert-auth \
--client-cert-auth \
--initial-advertise-peer-urls https://172.16.0.52:2380 \ # 当前主机的ip
--listen-peer-urls https://172.16.0.52:2380 \ # 当前主机的ip
--listen-client-urls https://172.16.0.52:2379,https://127.0.0.1:2379 \ # 当前主机的ip
--advertise-client-urls https://172.16.0.52:2379 \ # 当前主机的ip
--initial-cluster-token etcd-cluster \
--initial-cluster kubernetes-master-01=https://172.16.0.50:2380,kubernetes-master02=https://172.16.0.51:2380,kubernetes-master-03=https://172.16.0.52:2380 \ # 对应主机的ip和名字都要一样
--initial-cluster-state new \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

image-20210129231245300

错误三,直观调试的方式

# 查看状态
systemctl status etcd
# 数据配置
[root@kubernetes-master-01 etcd]# cat /usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos
[Service]
ExecStart=/usr/local/bin/etcd \
--name kubernetes-master-01 \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--peer-cert-file=/etc/etcd/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \
--trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-client-cert-auth \
--client-cert-auth \
--initial-advertise-peer-urls https://172.16.0.50:2380 \
--listen-peer-urls https://172.16.0.50:2380 \
--listen-client-urls https://172.16.0.50:2379,https://127.0.0.1:2379 \
--advertise-client-urls https://172.16.0.50:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster kubernetes-master-01=https://172.16.0.50:2380,kubernetes-master02=https://172.16.0.51:2380,kubernetes-master-03=https://172.16.0.52:2380 \
--initial-cluster-state new \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

# 执行配置,根据执行的信息提示解决问题(ExecStart开始的下面复制过来执行,查看输出错误信息)
ExecStart=/usr/local/bin/etcd \
--name kubernetes-master-01 \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--peer-cert-file=/etc/etcd/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \
--trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-client-cert-auth \
--client-cert-auth \
--initial-advertise-peer-urls https://172.16.0.50:2380 \
--listen-peer-urls https://172.16.0.50:2380 \
--listen-client-urls https://172.16.0.50:2379,https://127.0.0.1:2379 \
--advertise-client-urls https://172.16.0.50:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster kubernetes-master-01=https://172.16.0.50:2380,kubernetes-master02=https://172.16.0.51:2380,kubernetes-master-03=https://172.16.0.52:2380 \
--initial-cluster-state new \
--data-dir=/var/lib/etcd

5.6.3、测试 ETCD 集群

方法一
# 方式一
ETCDCTL_API=3 etcdctl \
--cacert=/etc/etcd/ssl/etcd.pem \
--cert=/etc/etcd/ssl/etcd.pem \
--key=/etc/etcd/ssl/etcd-key.pem \
--endpoints="https://172.16.0.50:2379,https://172.16.0.51:2379,https://172.16.0.
52:2379" \
endpoint status --write-out='table'
    
# 方式二
ETCDCTL_API=3 etcdctl \
--cacert=/etc/etcd/ssl/etcd.pem \
--cert=/etc/etcd/ssl/etcd.pem \
--key=/etc/etcd/ssl/etcd-key.pem \
--endpoints="https://172.16.0.50:2379,https://172.16.0.51:2379,https://172.16.0.
52:2379" \
member list --write-out='table'

image-20210130145226446

6、 部署集群 master 节点

6.1、 master 节点规划

主机名(角色) IP 外网 IP
Kubernetes-master-01 172.16.0.50 192.168.12.50
Kubernetes-master-02 172.16.0.51 192.168.12.51
Kubernetes-master-03 172.16.0.52 192.168.12.52

6.2、 创建集群证书

Master 节点是集群当中最为重要的一部分,组件众多,部署也最为复杂。

[root@kubernetes-master-01 ~]# mkdir /opt/cert/k8s
[root@kubernetes-master-01 ~]# cd /opt/cert/k8s/
[root@kubernetes-master-01 k8s]# pwd
/opt/cert/k8s
[root@kubernetes-master-01 k8s]# cat > ca-config.json << EOF
{
        "signing": {
            "default": {
                "expiry": "87600h"
            },
            "profiles": {
                "kubernetes": {
                    "expiry": "87600h",
                    "usages": [
                        "signing",
                        "key encipherment",
                        "server auth",
                        "client auth"
                    ]
                }
            }
        }
}
EOF

6.3、 创建根证书签名

[root@kubernetes-master-01 k8s]# cat > ca-csr.json << EOF
cat > ca-csr.json << EOF
{
        "CN": "kubernetes",
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "L": "ShangHai",
                "ST": "ShangHai"
            }
        ]
}
EOF
[root@kubernetes-master-01 k8s]# ls
ca-config.json  ca-csr.json

6.4、 生成根证书

[root@kubernetes-master-01 k8s]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
2021/01/30 15:08:14 [INFO] generating a new CA key and certificate from CSR
2021/01/30 15:08:14 [INFO] generate received request
2021/01/30 15:08:14 [INFO] received CSR
2021/01/30 15:08:14 [INFO] generating key: rsa-2048
2021/01/30 15:08:15 [INFO] encoded CSR
2021/01/30 15:08:15 [INFO] signed certificate with serial number 371256228802509038763343393270938553024454994692
[root@kubernetes-master-01 k8s]# ll
total 20
-rw-r--r--. 1 root root  450 Jan 30 15:03 ca-config.json
-rw-r--r--. 1 root root  960 Jan 30 15:08 ca.csr
-rw-r--r--. 1 root root  262 Jan 30 15:06 ca-csr.json
-rw-------. 1 root root 1675 Jan 30 15:08 ca-key.pem
-rw-r--r--. 1 root root 1281 Jan 30 15:08 ca.pem

image-20210130150826337

6.5、 签发 kube-apiserver 证书

6.5.1、创建 kube-apiserver 证书签名配置

# 允许访问kube-apiserver服务的ip
cat > server-csr.json << EOF
{
    "CN": "kubernetes",
    "hosts": [
        "127.0.0.1",
        "172.16.0.50",
        "172.16.0.51",
        "172.16.0.52",
        "172.16.0.55", # vip虚拟节点
        "10.96.0.1",  # kuberctl集群的dns网关
        "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"
        }
    ]
}
EOF

host:localhost 地址 + master 部署节点的 ip 地址 + etcd 节点的部署地址 + 负载均衡指定的 VIP(172.16.0.55) + service ip 段的第一个合法地址(10.96.0.1) + k8s 默认指定的一些地址。

6.5.2、生成证书

[root@kubernetes-master-01 k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
2021/01/30 15:17:48 [INFO] generate received request
2021/01/30 15:17:48 [INFO] received CSR
2021/01/30 15:17:48 [INFO] generating key: rsa-2048
2021/01/30 15:17:48 [INFO] encoded CSR
2021/01/30 15:17:48 [INFO] signed certificate with serial number 203101726322014033232332363906799903931057921193
2021/01/30 15:17:48 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@kubernetes-master-01 k8s]# ll
total 36
-rw-r--r--. 1 root root  450 Jan 30 15:03 ca-config.json
-rw-r--r--. 1 root root  960 Jan 30 15:08 ca.csr
-rw-r--r--. 1 root root  262 Jan 30 15:06 ca-csr.json
-rw-------. 1 root root 1675 Jan 30 15:08 ca-key.pem
-rw-r--r--. 1 root root 1281 Jan 30 15:08 ca.pem
-rw-r--r--. 1 root root 1228 Jan 30 15:17 server.csr
-rw-r--r--. 1 root root  545 Jan 30 15:16 server-csr.json
-rw-------. 1 root root 1675 Jan 30 15:17 server-key.pem
-rw-r--r--. 1 root root 1558 Jan 30 15:17 server.pem


image-20210130151808787

6.6、 签发 kube-controller-manager 证书

6.6.1、创建 kube-controller-manager 证书签名配置
cat > kube-controller-manager-csr.json << EOF
{
    "CN": "system:kube-controller-manager",
    "hosts": [
        "127.0.0.1",
        "172.16.0.50",
        "172.16.0.51",
        "172.16.0.52",
        "172.16.0.55"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing",
            "O": "system:kube-controller-manager",
            "OU": "System"
        }
    ]
}
EOF

6.6.2、生成证书

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

[root@kubernetes-master-01 k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
2021/01/30 15:21:21 [INFO] generate received request
2021/01/30 15:21:21 [INFO] received CSR
2021/01/30 15:21:21 [INFO] generating key: rsa-2048
2021/01/30 15:21:22 [INFO] encoded CSR
2021/01/30 15:21:22 [INFO] signed certificate with serial number 182838418901722715316391111855537862612211179946
2021/01/30 15:21:22 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@kubernetes-master-01 k8s]# ll
total 52
-rw-r--r--. 1 root root  450 Jan 30 15:03 ca-config.json
-rw-r--r--. 1 root root  960 Jan 30 15:08 ca.csr
-rw-r--r--. 1 root root  262 Jan 30 15:06 ca-csr.json
-rw-------. 1 root root 1675 Jan 30 15:08 ca-key.pem
-rw-r--r--. 1 root root 1281 Jan 30 15:08 ca.pem
-rw-r--r--. 1 root root 1143 Jan 30 15:21 kube-controller-manager.csr
-rw-r--r--. 1 root root  445 Jan 30 15:21 kube-controller-manager-csr.json
-rw-------. 1 root root 1675 Jan 30 15:21 kube-controller-manager-key.pem
-rw-r--r--. 1 root root 1476 Jan 30 15:21 kube-controller-manager.pem
-rw-r--r--. 1 root root 1228 Jan 30 15:17 server.csr
-rw-r--r--. 1 root root  545 Jan 30 15:16 server-csr.json
-rw-------. 1 root root 1675 Jan 30 15:17 server-key.pem
-rw-r--r--. 1 root root 1558 Jan 30 15:17 server.pem

image-20210130152157681

6.7、 签发 kube-scheduler 证书

6.7.1、创建 kube-scheduler 签名配置

cat > kube-scheduler-csr.json << EOF
{
    "CN": "system:kube-scheduler",
    "hosts": [
        "127.0.0.1",
        "172.16.0.50",
        "172.16.0.51",
        "172.16.0.52",
        "172.16.0.55"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing", "ST": "BeiJing",
            "O": "system:kube-scheduler",
            "OU": "System"
        }
    ]
}
EOF

6.7.2、创建证书

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


[root@kubernetes-master-01 k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
2021/01/30 15:30:22 [INFO] generate received request
2021/01/30 15:30:22 [INFO] received CSR
2021/01/30 15:30:22 [INFO] generating key: rsa-2048
2021/01/30 15:30:22 [INFO] encoded CSR
2021/01/30 15:30:22 [INFO] signed certificate with serial number 494605084152414111794463767930247152343847290705
2021/01/30 15:30:22 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@kubernetes-master-01 k8s]# ls
ca-config.json  ca-key.pem                   kube-controller-manager-csr.json  kube-scheduler.csr       kube-scheduler.pem  server-key.pem
ca.csr          ca.pem                       kube-controller-manager-key.pem   kube-scheduler-csr.json  server.csr          server.pem
ca-csr.json     kube-controller-manager.csr  kube-controller-manager.pem       kube-scheduler-key.pem   server-csr.json

image-20210130153038080

6.8、 签发 kube-proxy 证书

6.8.1、创建 kube-proxy 证书签名配置
cat > kube-proxy-csr.json << EOF
{
    "CN": "system:kube-proxy",
    "hosts": [],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing", "O": "system:kube-proxy",
            "OU": "System"
        }
    ]
}
EOF

6.8.2、生成证书

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

[root@kubernetes-master-01 k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
2021/01/30 15:38:54 [INFO] generate received request
2021/01/30 15:38:54 [INFO] received CSR
2021/01/30 15:38:54 [INFO] generating key: rsa-2048
2021/01/30 15:38:54 [INFO] encoded CSR
2021/01/30 15:38:54 [INFO] signed certificate with serial number 298757643069799848877066821416641743610755384370
2021/01/30 15:38:54 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);

image-20210130153921201

6.9、 签发管理员用户证书

为了能让集群客户端工具安全的访问集群,所以要为集群客户端创建证书,使其具有所有的集群权限。

6.9.1、创建证书签名配置

cat > admin-csr.json << EOF
{
    "CN": "admin",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing",
            "O": "system:masters",
            "OU": "System"
        }
    ]
}
EOF

6.9.2、生成证书

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

[root@kubernetes-master-01 k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
2021/01/30 15:47:08 [INFO] generate received request
2021/01/30 15:47:08 [INFO] received CSR
2021/01/30 15:47:08 [INFO] generating key: rsa-2048
2021/01/30 15:47:08 [INFO] encoded CSR
2021/01/30 15:47:08 [INFO] signed certificate with serial number 247779236021000657265927853902036183570071781148
2021/01/30 15:47:08 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").

image-20210130154722132

6.10、颁发证书

Master 节点所需证书:ca、kube-apiservver、kube-controller-manager、kube-scheduler、用户证书、Etcd 证书。

6.10.1、 颁发 Master 节点证书

mkdir -pv /etc/kubernetes/ssl

# 将证书文件复制到/etc/kubernetes/ssl目录下面
cp -p ./*.* /etc/kubernetes/ssl/
cp -p ./{ca*pem,server*pem,kube-controller-manager*pem,kube-scheduler*.pem,kube-prox y*pem,admin*.pem} /etc/kubernetes/ssl

image-20210130155326259

# 将证书复制到各个节点中
for i in kubernetes-master-02 kubernetes-master-03; do
ssh root@$i "mkdir -pv /etc/kubernetes/ssl"
scp /etc/kubernetes/ssl/* root@$i:/etc/kubernetes/ssl
done

image-20210130155723033

6.11、部署 master 节点

6.11.1、 下载二进制组件

进入官网可以下载对应的版本的包

https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.18.md#server-binaries

# 下载 server 安装包
wget https://dl.k8s.io/v1.18.8/kubernetes-server-linux-amd64.tar.gz
    
# 如果无法下载,可用下方方法
[root@kubernetes-master-01 k8s]# docker pull
registry.cn-hangzhou.aliyuncs.com/k8sos/k8s:v1.18.8.1
v1.18.8.1: Pulling from k8sos/k8s
75f829a71a1c: Pull complete
183ee8383f81: Pull complete
a5955b997bb4: Pull complete
5401bb259bcd: Pull complete
0c05c4d60f48: Pull complete
6a216d9c9d7c: Pull complete
6711ab2c0ba7: Pull complete
3ff1975ab201: Pull complete
Digest: sha256:ee02569b218a4bab3f64a7be0b23a9feda8c6717e03f30da83f80387aa46e202
Status: Downloaded newer image for
registry.cn-hangzhou.aliyuncs.com/k8sos/k8s:v1.18.8.1
registry.cn-hangzhou.aliyuncs.com/k8sos/k8s:v1.18.8.1
# 紧接着在容器当中复制出来即可。

image-20210130161239632

6.11.2、 分发组件

for i in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03; 
do scp kube-apiserver kube-controller-manager kube-scheduler kubectl root@$i:/usr/local/bin/;
done

[root@kubernetes-master-01 bin]# for i in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03; 
> do scp kube-apiserver kube-controller-manager kube-scheduler kubectl root@$i:/usr/local/bin/;
> done
kube-apiserver                                                                      100%  115MB  88.7MB/s   00:01    
kube-controller-manager                                                             100%  115MB  92.4MB/s   00:01    
kube-scheduler                                                                      100%   41MB  76.8MB/s   00:00    
kubectl                                                                             100%   42MB  68.7MB/s   00:00    
kube-apiserver                                                                      100%  115MB  35.9MB/s   00:03    
kube-controller-manager                                                             100%  115MB  32.0MB/s   00:03    
kube-scheduler                                                                      100%   41MB  48.1MB/s   00:00    
kubectl                                                                             100%   42MB  22.3MB/s   00:01    
kube-apiserver                                                                      100%  115MB  38.7MB/s   00:02    
kube-controller-manager                                                             100%  115MB  36.3MB/s   00:03    
kube-scheduler                                                                      100%   41MB  30.4MB/s   00:01    
kubectl                             

image-20210130161655459

6.11.3、 创建集群配置文件

在 kubernetes 中,我们需要创建一个配置文件,用来配置集群、用户、命名空间及身份认证等信息。

6.11.3.1、 创建 kube-controller-manager.kubeconfig 文件

 cd /opt/cert/k8s/
# 最终操作的集群实在55这台机器中
export KUBE_APISERVER="https://172.16.0.55:8443"
# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-controller-manager.kubeconfig

# 设置客户端认证参数
kubectl config set-credentials "kube-controller-manager" \
--client-certificate=/etc/kubernetes/ssl/kube-controller-manager.pem \
--client-key=/etc/kubernetes/ssl/kube-controller-manager-key.pem \
--embed-certs=true \
--kubeconfig=kube-controller-manager.kubeconfig

# 设置上下文参数(在上下文参数中将集群参数和用户参数关联起来)
kubectl config set-context default \
--cluster=kubernetes \
--user="kube-controller-manager" \
--kubeconfig=kube-controller-manager.kubeconfig

# 配置默认上下文
kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig

image-20210130162233849

6.11.3.1.1、 参数详解

  1. --certificate-authority:验证 kube-apiserver 证书的根证书。
  2. --client-certificate、--client-key:刚生成的 kube-controller-manager 证书和私钥,连接 kube-apiserver 时使用。
  3. --embed-certs=true:将 ca.pem 和 kube-controller-manager 证书内容嵌入到生成的 kubectl.kubeconfig 文件中 (不加时,写入的是证书文件路径)。

6.11.3.2、 创建 kube-scheduler.kubeconfig 文件

export KUBE_APISERVER="https://172.16.0.55:8443"

# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-scheduler.kubeconfig

# 设置客户端认证参数
kubectl config set-credentials "kube-scheduler" \
--client-certificate=/etc/kubernetes/ssl/kube-scheduler.pem \
--client-key=/etc/kubernetes/ssl/kube-scheduler-key.pem \
--embed-certs=true \
--kubeconfig=kube-scheduler.kubeconfig

# 设置上下文参数(在上下文参数中将集群参数和用户参数关联起来)
kubectl config set-context default \
--cluster=kubernetes \
--user="kube-scheduler" \
--kubeconfig=kube-scheduler.kubeconfig
# 配置默认上下文
kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig

image-20210130162632111

6.11.3.3、 创建 kube-proxy.kubeconfig 文件

export KUBE_APISERVER="https://172.16.0.55:8443"

# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-proxy.kubeconfig

# 设置客户端认证参数
kubectl config set-credentials "kube-proxy" \
--client-certificate=/etc/kubernetes/ssl/kube-proxy.pem \
--client-key=/etc/kubernetes/ssl/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

image-20210130162800039

6.11.3.4、 创建 admin.kubeconfig 文件

export KUBE_APISERVER="https://172.16.0.55:8443"

# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=admin.kubeconfig

# 设置客户端认证参数
kubectl config set-credentials "admin" \
--client-certificate=/etc/kubernetes/ssl/admin.pem \
--client-key=/etc/kubernetes/ssl/admin-key.pem \
--embed-certs=true \
--kubeconfig=admin.kubeconfig

# 设置上下文参数(在上下文参数中将集群参数和用户参数关联起来)
kubectl config set-context default \
--cluster=kubernetes \
--user="admin" \
--kubeconfig=admin.kubeconfig

# 配置默认上下文
kubectl config use-context default --kubeconfig=admin.kubeconfig

image-20210130162913711

6.11.4、 分发集群配置文件

kube-controller-manager.kubeconfig、kube-scheduler.kubeconfig、kube-proxy.kubeconfig、admin.kubeconfig

6.11.5、 部署组件

for i in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03;
do
ssh root@$i "mkdir -p /etc/kubernetes/cfg";
scp kube-scheduler.kubeconfig kube-controller-manager.kubeconfig admin.kubeconfig kube-proxy.kubeconfig root@$i:/etc/kubernetes/cfg;
done

image-20210130163510404

6.11.5.1、 部署 api-server

创建 kube-apiserver 服务配置文件(三个节点都要执行,不能复制,注意 api server IP)。

KUBE_APISERVER_IP=`hostname -i`
# 指定当前主机的ip ${KUBE_APISERVER_IP}
cat > /etc/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--advertise-address=${KUBE_APISERVER_IP} \\
--default-not-ready-toleration-seconds=360 \\
--default-unreachable-toleration-seconds=360 \\
--max-mutating-requests-inflight=2000 \\
--max-requests-inflight=4000 \\
--default-watch-cache-size=200 \\
--delete-collection-workers=2 \\
--bind-address=0.0.0.0 \\
--secure-port=6443 \\
--allow-privileged=true \\
--service-cluster-ip-range=10.96.0.0/16 \\
--service-node-port-range=10-52767 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/etc/kubernetes/cfg/token.csv \\
--kubelet-client-certificate=/etc/kubernetes/ssl/server.pem \\
--kubelet-client-key=/etc/kubernetes/ssl/server-key.pem \\
--tls-cert-file=/etc/kubernetes/ssl/server.pem \\
--tls-private-key-file=/etc/kubernetes/ssl/server-key.pem \\
--client-ca-file=/etc/kubernetes/ssl/ca.pem \\
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/var/log/kubernetes/k8s-audit.log \\
--etcd-servers=https://172.16.0.50:2379,https://172.16.0.51:2379,https://172.16.0.52:2379 \\
--etcd-cafile=/etc/etcd/ssl/ca.pem \\
--etcd-certfile=/etc/etcd/ssl/etcd.pem \\
--etcd-keyfile=/etc/etcd/ssl/etcd-key.pem"
EOF
  

image-20210130172037877

6.11.5.1.1、 参数详解

配置选项 选项说明
--logtostderr=false 输出日志到文件中,不输出到标准错误控制台
--v=2 指定输出日志的级别
--advertise-address 向集群成员通知 apiserver 消息的 IP 地址
--etcd-servers 连接的 etcd 服务器列表
--etcd-cafile 用于 etcd 通信的 SSL CA 文件
--etcd-certfile 用于 etcd 通信的的 SSL 证书文件
--etcd-keyfile 用于 etcd 通信的 SSL 密钥文件
--service-cluster-ip-range Service 网络地址分配
--bind-address 监听 --seure-port 的 IP 地址,如果为空,则将使用所有接口 (0.0.0.0)
--secure-port=6443 用于监听具有认证授权功能的 HTTPS 协议的端口,默认值是 6443
--allow-privileged 是否启用授权功能
--service-node-port-range Service 使用的端口范围
--default-not-ready-toleration-seconds 表示 notReady 状态的容忍度秒数
--default-unreachable-toleration-seconds 表示 unreachable 状态的容忍度秒数:
--max-mutating-requests-inflight=2000 在给定时间内进行中可变请求的最大数量,0 值表示没有限制(默 认值 200)
--default-watch-cache-size=200 默认监视缓存大小,0 表示对于没有设置默认监视大小的资源,将 禁用监视缓存
--delete-collection-workers=2 用 于 DeleteCollection 调 用 的 工 作 者 数 量 , 这 被 用 于 加 速 namespace 的清理( 默认值 1)
--enable-admission-plugins 资源限制的相关配置
--authorization-mode 在安全端口上进行权限验证的插件的顺序列表,以逗号分隔的列 表。

6.11.5.1.2、 注册 kube-apiserver 服务

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-apiserver.conf
ExecStart=/usr/local/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=10
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
6.11.5.1.3、 分发 kube-apiserver 服务脚本
# 需要分发配置文件,需要手动在每个机器上执行一遍(kube-apiserver.conf )
for i in kubernetes-master-02 kubernetes-master-03;
do
scp /usr/lib/systemd/system/kube-apiserver.service root@$i:/usr/lib/systemd/system/kube-apiserver.service
done

image-20210130174020719

6.11.5.1.4、 启动

创建token.csv文件

cd /etc/kubernetes/cfg/
# 必须要用自己机器创建的 Token
TLS_BOOTSTRAPPING_TOKEN=`head -c 16 /dev/urandom | od -An -t x | tr -d ' '`
cat > token.csv << EOF
${TLS_BOOTSTRAPPING_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF

# 将token分发到各个master节点中
scp ./token.csv root@kubernetes-master-02:/etc/kubernetes/cfg/
scp ./token.csv root@kubernetes-master-03:/etc/kubernetes/cfg/

image-20210130181131333

image-20210130181307209

# 创建 kubernetes 日志目录(在各个master节点中启动)
mkdir -p /var/log/kubernetes/
systemctl daemon-reload  
systemctl enable --now kube-apiserver

image-20210130181410027

image-20210130181600840

apiserver启动失败解决

/usr/local/bin/kube-apiserver        "--logtostderr=false \
--v=2 \
--log-dir=/var/log/kubernetes \
--advertise-address=172.16.0.50 \
--default-not-ready-toleration-seconds=360 \
--default-unreachable-toleration-seconds=360 \
--max-mutating-requests-inflight=2000 \
--max-requests-inflight=4000 \
--default-watch-cache-size=200 \
--delete-collection-workers=2 \
--bind-address=0.0.0.0 \
--secure-port=6443 \
--allow-privileged=true \
--service-cluster-ip-range=10.96.0.0/16 \
--service-node-port-range=10-52767 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--enable-bootstrap-token-auth=true \
--token-auth-file=/etc/kubernetes/cfg/token.csv \
--kubelet-client-certificate=/etc/kubernetes/ssl/server.pem \
--kubelet-client-key=/etc/kubernetes/ssl/server-key.pem \
--tls-cert-file=/etc/kubernetes/ssl/server.pem \
--tls-private-key-file=/etc/kubernetes/ssl/server-key.pem \
--client-ca-file=/etc/kubernetes/ssl/ca.pem \
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/log/kubernetes/k8s-audit.log \
--etcd-servers=https://172.16.0.50:2379,https://172.16.0.51:2379,https://172.16.0.52:2379 \
--etcd-cafile=/etc/etcd/ssl/ca.pem \
--etcd-certfile=/etc/etcd/ssl/etcd.pem \
--etcd-keyfile=/etc/etcd/ssl/etcd-key.pem"

image-20210130175926521

6.11.5.2、 高可用部署 api-server

负载均衡器有很多种,只要能实现 api-server 高可用都行,这里我们采用官方推荐的 haproxy + keepalived。

出现了错误解决:https://www.cnblogs.com/along21/p/10044931.html,可能是因为格式的问题

image-20210202231328742

6.11.5.2.1、 安装高可用软件
# 在各个节点中安装
yum install -y keepalived haproxy

# 各个节点配置haproxy
cat > /etc/haproxy/haproxy.cfg <<EOF
global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    stats socket /var/run/haproxy-admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon
    nbproc 1
defaults
    log global
	mode http
	option httplog
	timeout connect 5000
	timeout client 50000
	timeout server 50000
	timeout http-request 15s
	timeout http-keep-alive 15s	
frontend monitor-in
	bind *:33305
	mode http
	option httplog
	monitor-uri /monitor

listen stats
	bind *:8006
	mode http
	stats enable
	stats hide-version
	stats uri /stats
	stats refresh 30s
	stats realm Haproxy\ Statistics
	stats auth admin:admin
 
frontend k8s-master
	bind 0.0.0.0:8443
	bind 127.0.0.1:8443
	mode tcp
	option tcplog
	tcp-request inspect-delay 5s
	default_backend k8s-master
 
backend k8s-master
	mode tcp
	option tcplog
	option tcp-check
	balance roundrobin
	default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
	server kubernetes-master-01 172.16.0.50:6443 check inter 2000 fall 2 rise 2 weight 100
	server kubernetes-master02 172.16.0.51:6443 check inter 2000 fall 2 rise 2 weight 100
	server kubernetes-master-03 172.16.0.52:6443 check inter 2000 fall 2 rise 2 weight 100
EOF

在各个节点执行启动命令

systemctl enable --now  haproxy.service 
systemctl status haproxy

image-20210202232315195

6.11.5.2.4、 haproxy 常见链接错误

如果出现启动失败如下,开启链接策略

setsebool -P haproxy_connect_any=1

image-20210202231901049

image-20210202232039707

6.11.5.2.5、 配置 keepalived 服务

master-01

# 在各个master-01节点执行
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak
cd /etc/keepalived

cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
	router_id LVS_DEVEL
}
vrrp_script chk_kubernetes {
	script "/etc/keepalived/check_kubernetes.sh"
	interval 2
	weight -5
	fall 3
	rise 2
}
vrrp_instance VI_1 {
	state MASTER # 节点
	interface ens37 # 修改对应的网卡
	mcast_src_ip 172.16.0.50
	virtual_router_id 51
	priority 100 # 权重
	advert_int 2
	authentication {
		auth_type PASS
		auth_pass K8SHA_KA_AUTH
	}
	virtual_ipaddress {
		172.16.0.55
	}
	# track_script {
	# chk_kubernetes
	# }
}
EOF

# 启动
systemctl enable --now keepalived.service
systemctl status keepalived
ip a

image-20210202234632495

image-20210202234735729

master-02

# 在各个master-01节点执行
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak
cd /etc/keepalived

cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
	router_id LVS_DEVEL
}
vrrp_script chk_kubernetes {
	script "/etc/keepalived/check_kubernetes.sh"
	interval 2
	weight -5
	fall 3
	rise 2
}
vrrp_instance VI_1 {
	state BACKUP # 作为备份
	interface ens37 # 指定网卡
	mcast_src_ip 172.16.0.51
	virtual_router_id 51
	priority 90 # 设置权重
	advert_int 2
	authentication {
		auth_type PASS
		auth_pass K8SHA_KA_AUTH
	}
	virtual_ipaddress {
		172.16.0.55
	}
	# track_script {
	# chk_kubernetes
	# }
}

EOF

# 启动
systemctl enable --now keepalived.service
systemctl status keepalived
ip a

![image-20210202235216197](https://img2020.cnblogs.com/blog/1739642/202111/1739642-20211123224227672-823933079.png 'https://img2020.cnblogs.com/blog/1739642/202111/1739642-20211123224227887-1357261391.png 'C:\Users\86183\Desktop\ks8\image-20210202235216197.png'')

master-03

mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak
cd /etc/keepalived

cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
	router_id LVS_DEVEL
}
vrrp_script chk_kubernetes {
	script "/etc/keepalived/check_kubernetes.sh"
	interval 2
	weight -5
	fall 3
	rise 2
}
vrrp_instance VI_1 {
	state BACKUP
	interface ens37
	mcast_src_ip 172.16.0.52
	virtual_router_id 51
	priority 80
	advert_int 2
	authentication {
		auth_type PASS
		auth_pass K8SHA_KA_AUTH
	}
	virtual_ipaddress {
		172.16.0.55
	}
	# track_script {
	# chk_kubernetes
	# }
}
EOF

# 启动
systemctl enable --now keepalived.service
systemctl status keepalived
ip a

![image-20210202235216197](https://img2020.cnblogs.com/blog/1739642/202111/1739642-20211123224227672-823933079.png 'https://img2020.cnblogs.com/blog/1739642/202111/1739642-20211123224227887-1357261391.png 'C:\Users\86183\Desktop\ks8\image-20210202235216197.png'')

云主机部署都会有55这个ip段,会有问题

6.11.5.3、 部署 kube-controller-manager 服务

Controller Manager 作为集群内部的管理控制中心,负责集群内的 Node、Pod 副本、服务端点(Endpoint)、 命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理,当某个 Node 意外 宕机时,Controller Manager 会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。如果多个 控制器管理器同时生效,则会有一致性问题,所以 kube-controller-manager 的高可用,只能是主备模式,而 kubernetes 集群是采用租赁锁实现 leader 选举,需要在启动参数中加入 --leader-elect=true。

6.11.5.3.1、 创建 kube-controller-manager 配置文件

cat > /etc/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=true \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--cluster-name=kubernetes \\
--bind-address=127.0.0.1 \\
--allocate-node-cidrs=true \\
--cluster-cidr=10.244.0.0/12 \\
--service-cluster-ip-range=10.96.0.0/16 \\
--cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \\
--root-ca-file=/etc/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \\
--kubeconfig=/etc/kubernetes/cfg/kube-controller-manager.kubeconfig \\
--tls-cert-file=/etc/kubernetes/ssl/kube-controller-manager.pem \\
--tls-private-key-file=/etc/kubernetes/ssl/kube-controller-manager-key.pem \\
--experimental-cluster-signing-duration=87600h0m0s \\
--controllers=*,bootstrapsigner,tokencleaner \\
--use-service-account-credentials=true \\
--node-monitor-grace-period=10s \\
--horizontal-pod-autoscaler-use-rest-clients=true"
EOF
6.11.5.3.2、 配置文件详解
配置选项 选项意义
--leader-elect 高可用时启用选举功能
--master 通过本地非安全本地端口 8080 连接 apiserver
--bind-address 监控地址
--allocate-node-cidrs 是否应在 node 节点上分配和设置 Pod 的 CIDR
--cluster-cidr Controller Manager 在启动时如果设置了--cluster-cidr 参 数,防止不同的节点的 CIDR 地址发生冲突
--service-cluster-ip-range 集群 Services 的 CIDR 范围
--cluster-signing-cert-file 指定用于集群签发的所有集群范围内证书文件(根证书 文件)
--cluster-signing-key-file 指定集群签发证书的 key
--root-ca-file 如果设置,该根证书权限将包含 service acount 的 toker secret,这必须是一个有效的 PEM 编码 CA 包
--service-account-private-key-file 包含用于签署 service account token 的 PEM 编码 RSA 或 者 ECDSA 私钥的文件名
--experimental-cluster-signing-duration 证书签发时间
6.11.5.3.3、 注册 kube-controller-manager 服务
cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/usr/local/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF

启动失败执行这个命令产看原因

/opt/kube-controller-manager         --logtostderr=true --v=2 --log-dir=/var/log/kubernetes --cluster-name=kubernetes --bind-address=127.0.0.1 --allocate-node-cidrs=true --cluster-cidr=10.244.0.0/12 --service-cluster-ip-range=10.96.0.0/16 --cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem --cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem --root-ca-file=/etc/kubernetes/ssl/ca.pem --service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem --kubeconfig=/etc/kubernetes/cfg/kube-controller-manager.kubeconfig --tls-cert-file=/etc/kubernetes/ssl/kube-controller-manager.pem --tls-private-key-file=/etc/kubernetes/ssl/kube-controller-manager-key.pem --experimental-cluster-signing-duration=87600h0m0s --controllers=*,bootstrapsigner,tokencleaner --use-service-account-credentials=true --node-monitor-grace-period=10s --horizontal-pod-autoscaler-use-rest-clients=true

启动出现连接失败,因为 keepalived.service 出了问题,重启一下服务

"https://172.16.0.55:8443"

6.11.5.3.4、 分发脚本
# 分发脚本到各个服务器上面
for i in kubernetes-master02 kubernetes-master-03;
do
scp /etc/kubernetes/cfg/kube-controller-manager.conf root@$i:/etc/kubernetes/cfg
scp /usr/lib/systemd/system/kube-controller-manager.service root@$i:/usr/lib/systemd/system/kube-controller-manager.service
done

image-20210203204144986

6.11.5.3.5、 启动
systemctl daemon-reload
systemctl enable --now kube-controller-manager.service
systemctl status kube-controller-manager

image-20210204225511621

6.11.5.4、 部署 kube-scheduler 服务

kube-scheduler 是 Kubernetes 集群的默认调度器,并且是集群 控制面 的一部分。对每一个新创建的 Pod 或 者是未被调度的 Pod,kube-scheduler 会过滤所有的 node,然后选择一个最优的 Node 去运行这个 Pod。

kube-scheduler 调度器是一个策略丰富、拓扑感知、工作负载特定的功能,调度器显著影响可用性、性能和容量。 调度器需要考虑个人和集体的资源要求、服务质量要求、硬件/软件/政策约束、亲和力和反亲和力规范、数据局 部性、负载间干扰、完成期限等。工作负载特定的要求必要时将通过 API 暴露。

6.11.5.4.1、 创建 kube-scheduler 配置文件

cat > /etc/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--kubeconfig=/etc/kubernetes/cfg/kube-scheduler.kubeconfig \\
--leader-elect=true \\
--master=http://127.0.0.1:8080 \\
--bind-address=127.0.0.1 "
EOF

6.11.5.4.2、 创建启动脚本

cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-scheduler.conf
ExecStart=/usr/local/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
6.11.5.4.3、 分发配置文件

for ip in kubernetes-master-02 kubernetes-master-03;
do
scp /usr/lib/systemd/system/kube-scheduler.service root@${ip}:/usr/lib/systemd/system
scp /etc/kubernetes/cfg/kube-scheduler.conf root@${ip}:/etc/kubernetes/cfg
done
6.11.5.4.4、 启动
# 分别在三台 master 节点上启动
systemctl daemon-reload
systemctl enable --now kube-scheduler
systemctl status kube-scheduler

image-20210203220018096

6.11.5.5、 查看集群状态

至此,master 所有节点均安装完毕。现在我们要检验集群安装是否成功。

[root@kubernetes-master-01 bin]# kubectl get cs
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-2               Healthy   {"health":"true"}   
etcd-0               Healthy   {"health":"true"}   
etcd-1               Healthy   {"health":"true"}   

image-20210204232451498

6.11.5.6、 配置 TLS bootstrapping

TLS bootstrapping 是用来简化管理员配置 kubelet 与 apiserver 双向加密通信的配置步骤的一种机制。当集 群开启了 TLS 认证后,每个节点的 kubelet 组件都要使用由 apiserver 使用的 CA 签发的有效证书才能与 apiserver 通讯,此时如果有很多个节点都需要单独签署证书那将变得非常繁琐且极易出错,导致集群不稳。

TLS bootstrapping 功能就是让 node 节点上的 kubelet 组件先使用一个预定的低权限用户连接到 apiserver, 然后向 apiserver 申请证书,由 apiserver 动态签署颁发到 Node 节点,实现证书签署自动化。

6.11.5.6.1、 生成 TLS bootstrapping 所需 token

6.11.5.6.2、 创建 TLS Bootstrapping 集群配置文件

在 kubernetes 中,我们需要创建一个配置文件,用来配置集群、用户、命名空间及身份认证等信息。

主要作用:自动为worker节点生成证书

export KUBE_APISERVER="https://172.16.0.55:8443"
# 设置集群参数
kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kubelet-bootstrap.kubeconfig
  

# 设置客户端认证参数,此处 token 必须用上叙 token.csv 中的 token cat /etc/kubernetes/cfg/token.csv
kubectl config set-credentials "kubelet-bootstrap" \
  --token=f6ea2af398bda5ce28eac691f0ced2bc \
  --kubeconfig=kubelet-bootstrap.kubeconfig
  
  
# 设置上下文参数(在上下文参数中将集群参数和用户参数关联起来)
kubectl config set-context default \
  --cluster=kubernetes \
  --user="kubelet-bootstrap" \
  --kubeconfig=kubelet-bootstrap.kubeconfig
  
# 配置默认上下文
kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig

image-20210207221336122

image-20210207222013550

image-20210207222054788

6.11.5.6.2.1、分发证书

for i in kubernetes-master02 kubernetes-master-03;
do
scp /etc/kubernetes/cfg/kubelet-bootstrap.kubeconfig  root@$i:/etc/kubernetes/cfg;
done

image-20210207222658490

6.11.5.6.3、 创建 TLS 匿名用户(授权TLS Bootrapping用户请求)
# 只需要在一个mster节点中执行(vim *.*.*55这个台机器中)
kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap

image-20210207224346460

image-20210207224418469

image-20210207224522744

6.11.5.7、 部署 kubelet 服务
6.11.5.7.1、 创建 kubelet 配置

kubeconfig:集群配置文件,kubelet不仅在集群中搭建还要在工作节点中搭建

config:集群的配置

在各个节点中创建

KUBE_HOSTNAME=`hostname`
cat > /etc/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--hostname-override=${KUBE_HOSTNAME} \\
--container-runtime=docker \\
--kubeconfig=/etc/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/etc/kubernetes/cfg/kubelet-bootstrap.kubeconfig \\
--config=/etc/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/etc/kubernetes/ssl \\
--image-pull-progress-deadline=15m \\
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/k8sos/pause:3.2"
EOF
6.11.5.7.1.1、 配置详解
配置选项 选项意义
--hostname-override 用 来 配 置 该 节 点 在 集 群 中 显 示 的 主 机 名 , kubelet 设 置 了 -–hostname-override 参数后,kube-proxy 也需要设置,否则会出现找 不到 Node 的情况
--container-runtime 指定容器运行时引擎
--kubeconfig kubelet 作 为 客 户 端 使 用 的 kubeconfig 认 证 文 件 , 此 文 件 是 由 kube-controller-mananger 自动生成的
--bootstrap-kubeconfig 指定令牌认证文件(自动生成证书的配置文件)
--config 指定 kubelet 配置文件
--cert-dir 设置 kube-controller-manager 生成证书和私钥的目录
--image-pull-progress-deadline 镜像拉取进度最大时间,如果在这段时间拉取镜像没有任何进展,将 取消拉取,默认:1m0s
--pod-infra-container-image 每个 pod 中的 network/ipc 名称空间容器将使用的镜像
6.11.5.7.2、 创建 kubelet-config 配置文件

address:地址是当前主机的ip,各个主机都要配置

clusterDNS:DNS的解析地址

clientCAFile:证书的路径

cat > /etc/kubernetes/cfg/kubelet-config.yml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 172.16.0.50
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.96.0.2
clusterDomain: cluster.local
failSwapOn: false
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 2m0s
    enabled: true
  x509:
    clientCAFile: /etc/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
6.11.5.7.2.1、 配置详解
配置选项 选项意义
address kubelet 服务监听的地址(修改对应的主机ip地址)
port kubelet 服务的端口,默认 10250
readOnlyPort 没有认证/授权的只读 kubelet 服务端口 ,设置为 0 表示禁用,默认 10255
clusterDNS DNS 服务器的 IP 地址列表
clusterDomain 集群域名, kubelet 将配置所有容器除了主机搜索域还将搜索当前域
6.11.5.7.3、 创建 kubelet 启动脚本
cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
After=docker.service
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kubelet.conf
ExecStart=/usr/local/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
RestartSec=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
6.11.5.7.4、 分发配置文件
for ip in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03 ;do
scp /etc/kubernetes/cfg/{kubelet-config.yml,kubelet.conf}
root@${ip}:/etc/kubernetes/cfg
scp /usr/lib/systemd/system/kubelet.service root@${ip}:/usr/lib/systemd/system
done
6.11.5.7.5、 配置文件处理
# 修改 kubernetes-master-02 配置
sed -i 's#master-01#master-02#g' /etc/kubernetes/cfg/kubelet.conf
sed -i 's#172.16.0.50#172.16.0.51#g' /etc/kubernetes/cfg/kubelet-config.yml
# 修改 kubernetes-master-03 配置
sed -i 's#master-01#master-03#g' /etc/kubernetes/cfg/kubelet.conf
sed -i 's#172.16.0.50#172.16.0.52#g' /etc/kubernetes/cfg/kubelet-config.yml
6.11.5.7.6、 开启 kubelet 服务
systemctl daemon-reload
systemctl enable --now kubelet
systemctl status kubelet.service
for i in kubernetes-master-01 kubernetes-master02 kubernetes-master-03;
do
scp kubelet  root@$i:/usr/local/bin/
done

image-20210207223302596

image-20210207223644875

image-20210207224500505

image-20210207225532253

kubectl get csr # 查看集群加入请求(需要进行批准,在批准之前需要配置kube-proxy),目前是没有办法加入节点
# 查看节点
kubectl get node

image-20210207225646294

image-20210207225906756

6.11.5.8、 配置 kube-proxy 服务

kube-proxy 是 Kubernetes 的核心组件,部署在每个 Node 节点上,它是实现 Kubernetes Service 的通信与负载 均衡机制的重要组件; kube-proxy 负责为 Pod 创建代理服务,从 apiserver 获取所有 server 信息,并根据 server 信 息创建代理服务,实现 server 到 Pod 的请求路由和转发,从而实现 K8s 层级的虚拟转发网络。

6.11.5.8.1、 创建 kube-proxy 配置文件
# 在各个master节点中执行
cat > /etc/kubernetes/cfg/kube-proxy.conf << EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--config=/etc/kubernetes/cfg/kube-proxy-config.yml"
EOF

image-20210207230227960

6.11.5.8.2、 创建 kube-proxy-config 配置文件
# 在各个masett节点中执行并修改  bindAddress,healthzBindAddress,metricsBindAddress,hostnameOverride,对用的主机ip和主机名 
cat > /etc/kubernetes/cfg/kube-proxy-config.yml << EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 172.16.0.50
healthzBindAddress: 172.16.0.50:10256
metricsBindAddress: 172.16.0.50:10249
clientConnection:
  burst: 200
  kubeconfig: /etc/kubernetes/cfg/kube-proxy.kubeconfig
  qps: 100
hostnameOverride: kubernetes-master-01
clusterCIDR: 10.96.0.0/16
enableProfiling: true
mode: "ipvs"
kubeProxyIPTablesConfiguration:
  masqueradeAll: false
kubeProxyIPVSConfiguration:
  scheduler: rr
  excludeCIDRs: []
EOF

image-20210207230740558

image-20210207231301264

6.11.5.8.2.1、 配置文件详解
选项配置 选项意义
clientConnection 与 kube-apiserver 交互时的参数设置
burst: 200 临时允许该事件记录值超过 qps 设定值
kubeconfig kube-proxy 客户端连接 kube-apiserver 的 kubeconfig 文件路径设置
qps: 100 与 kube-apiserver 交互时的 QPS,默认值 5
bindAddress kube-proxy 监听地址
healthzBindAddress 用于检查服务的 IP 地址和端口
metricsBindAddress metrics 服务的 ip 地址和端口。默认:127.0.0.1:10249
clusterCIDR kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,指定 --cluster-cidr 或 --masquerade-all 选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT
hostnameOverride 参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node, 从而不会创建任何 ipvs 规则;
masqueradeAll 如果使用纯 iptables 代理,SNAT 所有通过服务集群 ip 发送的通信
mode 使用 ipvs 模式
scheduler 当 proxy 为 ipvs 模式时,ipvs 调度类型
6.11.5.8.3、 创建 kube-proxy 启动脚本
# 在各个master节点中执行
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Proxy
After=network.target

[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-proxy.conf
ExecStart=/usr/local/bin/kube-proxy \$KUBE_PROXY_OPTS
Restart=on-failure
RestartSec=10
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

image-20210207230928107

6.11.5.8.4、 分发配置文件
for ip in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03 ;do
scp /etc/kubernetes/cfg/{kube-proxy-config.yml,kube-proxy.conf} root@${ip}:/etc/kubernetes/cfg/
scp /usr/lib/systemd/system/kube-proxy.service root@${ip}:/usr/lib/systemd/system/
done
6.11.5.8.4.1、 修改 kubernetes-master-02 配置文件
sed -i 's#172.16.0.50#172.16.0.51#g' /etc/kubernetes/cfg/kube-proxy-config.yml
sed -i 's#master-01#master-02#g' /etc/kubernetes/cfg/kube-proxy-config.yml
6.11.5.8.4.2、 修改 kubernetes-master-03 配置文件
sed -i 's#172.16.0.50#172.16.0.52#g' /etc/kubernetes/cfg/kube-proxy-config.yml
sed -i 's#master-01#master-03#g' /etc/kubernetes/cfg/kube-proxy-config.yml
6.11.5.8.4.3、 查看配置文件
for ip in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03 ;do
echo ''; echo $ip; echo '';
ssh root@$ip "cat /etc/kubernetes/cfg/kube-proxy-config.yml";
done

image-20210207231419545

6.11.5.8.5、 启动
cd /opt/kubernetes/server/bin
for i in kubernetes-master-01 kubernetes-master02 kubernetes-master-03;
do
scp kube-proxy  root@$i:/usr/local/bin/
done
systemctl daemon-reload
systemctl enable --now kube-proxy
systemctl status kube-proxy

image-20210207232153504

6.11.5.8.6、 查看 kubelet 加入集群请求
kubectl get csr

[root@kubernetes-master-01 bin]# kubectl get csr
NAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-WLNbxPvLPj2TbZssrPlj8av_HS88KwJ_dgs2vTvWBdk   38m   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
node-csr-j4c0N_lVK7wqDyD_tXvQ-YYflY-Zq5avnQ2FKHljjf8   28m   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
node-csr-nTGfj1NpwLXzX35dFhVNczd2iiKzX0Xb6mjcLJqeTP0   29m   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending

image-20210207232329814

6.11.5.8.7、 批准加入
kubectl certificate approve `kubectl get csr | grep "Pending" | awk '{print $1}'`

image-20210207232545245

6.11.5.8.8、 查看加入集群的新节点
[root@kubernetes-master-01 bin]# kubectl get node
NAME                   STATUS   ROLES    AGE   VERSION
kubernetes-master-01   Ready    <none>   63s   v1.18.15
kubernetes-master-03   Ready    <none>   61s   v1.18.15
kubernetes-master02    Ready    <none>   69s   v1.18.15

image-20210207232937464

6.11.5.8.9、 设置集群角色
kubectl label nodes kubernetes-master-01 node-role.kubernetes.io/master=kubernetes-master-01
kubectl label nodes kubernetes-master02 node-role.kubernetes.io/master=kubernetes-master02
kubectl label nodes kubernetes-master-03 node-role.kubernetes.io/master=kubernetes-master-03

image-20210207233856605

image-20210207233950916

6.11.5.8.10、 为 master 节点打污点

master 节点一般情况下不运行 pod,因此我们需要给 master 节点添加污点使其不被调度。

master节点只负责监控不负责业务逻辑,避免docker进行放到master节点中

kubectl taint nodes kubernetes-master-01 node-role.kubernetes.io/master=kubernetes-master-01:NoSchedule --overwrite
kubectl taint nodes kubernetes-master-02 node-role.kubernetes.io/master=kubernetes-master-02:NoSchedule --overwrite
kubectl taint nodes kubernetes-master-03 node-role.kubernetes.io/master=kubernetes-master-03:NoSchedule --overwrite

6.11.5.8.11、 部署集群网络插件

kubernetes 设计了网络模型,但却将它的实现交给了网络插件,CNI 网络插件最主要的功能就是实现 POD 资 源能够跨主机进行通讯。常见的 CNI 网络插件:

  1. Flannel
  2. Calico
  3. Canal
  4. Contiv
  5. OpenContrail
  6. NSX-T
  7. Kube-router
6.11.5.8.11.1、 安装网络插件
for i in kubernetes-master-01 kubernetes-master02 kubernetes-master-03; do 
scp flanneld mk-docker-opts.sh root@$i:/usr/local/bin;
done

image-20210207235025862

6.11.5.8.11.2、 将 flanneld 配置写入集群数据库
# 将 flanneld 配置写入集群数据库
etcdctl \
--ca-file=/etc/etcd/ssl/ca.pem \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--endpoints="https://172.16.0.50:2379,https://172.16.0.51:2379,https://172.16.0.52:2379" \
mk /coreos.com/network/config '{"Network":"10.244.0.0/12", "SubnetLen": 21, "Backend": {"Type": "vxlan", "DirectRouting": true}}'


# 使用 get 查看信息
etcdctl \
--ca-file=/etc/etcd/ssl/ca.pem \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--endpoints="https://172.16.0.50:2379,https://172.16.0.51:2379,https://172.16.0.52:2379" \
get /coreos.com/network/config

image-20210207235319481

image-20210207235510179

6.11.5.8.11.3、 注册 Flanneld 服务
cat > /usr/lib/systemd/system/flanneld.service << EOF
[Unit]
Description=Flanneld address
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service
[Service]
Type=notify
ExecStart=/usr/local/bin/flanneld \\
  -etcd-cafile=/etc/etcd/ssl/ca.pem \\
  -etcd-certfile=/etc/etcd/ssl/etcd.pem \\
  -etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \\
-etcd-endpoints=https://172.16.0.50:2379,https://172.16.0.51:2379,https://172.16.0.52:2379 \\
  -etcd-prefix=/coreos.com/network \\
  -ip-masq
ExecStartPost=/usr/local/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/subnet.env
Restart=always
RestartSec=5
StartLimitInterval=0
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
EOF
6.11.5.8.11.3.1、 配置详解
配置选项 选项说明
-etcd-cafile 用于 etcd 通信的 SSL CA 文件
-etcd-certfile 用于 etcd 通信的的 SSL 证书文件
-etcd-keyfile 用于 etcd 通信的 SSL 密钥文件
--etcd-endpoints 所有 etcd 的 endpoints
-etcd-prefix etcd 中存储的前缀
-ip-masq -ip-masq=true 如果设置为 true,这个参数的目的是让 flannel 进行 ip 伪装,而不让 docker 进行 ip 伪装。这么做的原因是如果 docker 进行 ip 伪装,流量再从 flannel 出去,其他 host 上看到的 source ip 就是 flannel 的网关 ip,而不是 docker 容器的 ip
6.11.5.8.11.4、 分发配置文件
for i in kubernetes-master-02 kubernetes-master-03;do
scp /usr/lib/systemd/system/flanneld.service root@$i:/usr/lib/systemd/system; 
done

image-20210207235718060

6.11.5.8.11.5、 修改 docker 启动模式

此举是将 docker 的网络交给 flanneld 来管理,形成集群统一管理的网络

 # 查看docker启动模式
cat /usr/lib/systemd/system/docker.service
# 修改docker启动文件
sed -i '/ExecStart/s/\(.*\)/#\1/' /usr/lib/systemd/system/docker.service # 注释
sed -i '/ExecReload/a ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS -H fd:// --containerd=/run/containerd/containerd.sock' /usr/lib/systemd/system/docker.service # 添加

image-20210207235904076

image-20210208000532057

6.11.5.8.11.6、 分发 docker 启动脚本
for ip in kubernetes-master02 kubernetes-master-03;do 
scp /usr/lib/systemd/system/docker.service root@${ip}:/usr/lib/systemd/system; 
done

image-20210208000631900

6.11.5.8.11.7、 启动 Flanneld 服务
systemctl daemon-reload
systemctl enable flanneld.service
systemctl status flanneld
systemctl restart docker

image-20210208001718800

image-20210208001852266

image-20210208002135601

image-20210208002102214

6.11.5.8.12、 部署 CoreDNS

CoreDNS 用于集群中 Pod 解析 Service 的名字,Kubernetes 基于 CoreDNS 用于服务发现功能。

6.11.5.8.12.1、 下载配置文件
git clone https://github.com/coredns/deployment.git
6.11.5.8.12.2、 绑定集群匿名用户权限
# 在master节点上面执行
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=kubernetes

image-20210208002420589

cd /opt/deployment/kubernetes
cat coredns.yaml.sed | grep image
[root@kubernetes-master-01 kubernetes]# cat coredns.yaml.sed | grep image
        image: coredns/coredns:1.8.0
        imagePullPolicy: IfNotPresent

image-20210208002717493

6.11.5.8.12.3、 修改 CoreDNS 并运行
# 替换 coreDNS 镜像为:registry.cn-hangzhou.aliyuncs.com/k8s121/coredns:1.8.0
vim coredns.yaml.sed
# 执行启动命令
./deploy.sh -i 10.96.0.2 -s | kubectl apply -f -

# 查看集群是否运行起来
[root@kubernetes-master-01 bin]# kubectl get pods -n kube-system


[root@kubernetes-master-01 bin]# kubectl get pods -n kube-system
NAME                       READY   STATUS    RESTARTS   AGE
coredns-6f5774d776-92h9j   1/1     Running   0          6m4s
[root@kubernetes-master-01 bin]# kubectl get pods -n kube-system -o wide

image-20210208004134774

image-20210208004722677

image-20210208004931720

image-20210208005310567

6.11.5.8.13、 绑定用户的超管权限

此举是将超管的用户权限绑定到集群。


6.11.5.8.14、 测试集群 DNS
kubectl run test -it --rm --image=busybox:1.28.3

image-20210208005811491

image-20210208005821732

image-20210208010624349

image-20210306220708360

6.12、部署集群 Node 节点

Node 节点主要负责提供应用运行环境,其最主要的组件就是 kube-proxy 和 kubelet。接下来我们就在集群当 中部署 Node 节点。

6.12.1、 分发工具
cd /opt/kubernetes/server/bin
for i in kubernetes-node-02 kubernetes-node-01; do
scp kubelet kube-proxy root@$i:/usr/local/bin/; done

image-20210208222438441

6.12.2、 颁发 Node 节点证书
for i in kubernetes-node-01 kubernetes-node-02; do
ssh root@$i "mkdir -pv /etc/kubernetes/ssl"
scp -pr ./{ca*.pem,admin*pem,kube-proxy*pem} root@$i:/etc/kubernetes/ssl
done

image-20210208222505545

6.12.3、 配置 TLS bootstrapping(在master已经执行过了,不需要再次执行)

TLS bootstrapping 是用来简化管理员配置 kubelet 与 apiserver 双向加密通信的配置步骤的一种机制。当集 群开启了 TLS 认证后,每个节点的 kubelet 组件都要使用由 apiserver 使用的 CA 签发的有效证书才能与 apiserver 通讯,此时如果有很多个节点都需要单独签署证书那将变得非常繁琐且极易出错,导致集群不稳。

TLS bootstrapping 功能就是让 node 节点上的 kubelet 组件先使用一个预定的低权限用户连接到 apiserver, 然后向 apiserver 申请证书,由 apiserver 动态签署颁发到 Node 节点,实现证书签署自动化。


6.12.4、 生成 TLS bootstrapping 所需 token(在master已经执行过了,不需要再次执行)

6.12.5、 创建 TLS Bootstrapping 集群配置文件(在master已经执行过了,不需要再次执行)

在 kubernetes 中,我们需要创建一个配置文件,用来配置集群、用户、命名空间及身份认证等信息。


6.12.6、 分发 TLS bootstrap 证书(和集群配置文件)
cd /etc/kubernetes/cfg/
for i in kubernetes-node-01 kubernetes-node-02;
do
ssh root@$i "mkdir -p /etc/kubernetes/cfg";
scp token.csv kube-scheduler.kubeconfig kube-controller-manager.kubeconfig
admin.kubeconfig kube-proxy.kubeconfig kubelet-bootstrap.kubeconfig root@$i:/etc/kubernetes/cfg;
done

image-20210208222800486

6.12.14、 同步 ETCD 配置至节点
cd /etc/etcd/ssl

for i in kubernetes-node-01 kubernetes-node-02;
do
ssh root@$i "mkdir -pv /etc/etcd/ssl";
scp *.pem root@$i:/etc/etcd/ssl;
done

image-20210208223435116

6.12.7、 配置 kubelet 服务
for ip in kubernetes-node-01 kubernetes-node-02;do
ssh root@${ip} "mkdir -pv /var/log/kubernetes"
ssh root@${ip} "mkdir -pv /etc/kubernetes/cfg/"
scp /etc/kubernetes/cfg/{kubelet-config.yml,kubelet.conf} root@${ip}:/etc/kubernetes/cfg
scp /usr/lib/systemd/system/kubelet.service root@${ip}:/usr/lib/systemd/system
done

image-20210208224053888

6.12.8、 处理配置文件
# 修改 kubernetes-node-01 配置
sed -i 's#master-01#node-01#g' /etc/kubernetes/cfg/kubelet.conf
sed -i 's#172.16.0.50#172.16.0.53#g' /etc/kubernetes/cfg/kubelet-config.yml

# 修改 kubernetes-node-02 配置
sed -i 's#master-01#node-02#g' /etc/kubernetes/cfg/kubelet.conf
sed -i 's#172.16.0.50#172.16.0.54#g' /etc/kubernetes/cfg/kubelet-config.yml

image-20210208224455962

6.12.9、 开启 kubelet
systemctl daemon-reload
systemctl enable --now kubelet
systemctl status kubelet.service

image-20210208224709555

6.12.10、 配置 kube-proxy 服务
for ip in kubernetes-node-01 kubernetes-node-02;do
scp /etc/kubernetes/cfg/{kube-proxy-config.yml,kube-proxy.conf} root@${ip}:/etc/kubernetes/cfg/
scp /usr/lib/systemd/system/kube-proxy.service root@${ip}:/usr/lib/systemd/system/
done

image-20210208224900080

6.12.11、 修改配置文件
# 修改 kubernetes-node-01 节点
sed -i 's#172.16.0.50#172.16.0.54#g' /etc/kubernetes/cfg/kube-proxy-config.yml
sed -i 's#master-01#node-01#g' /etc/kubernetes/cfg/kube-proxy-config.yml

# 修改 kubernetes-node-02 节点
sed -i 's#172.16.0.50#172.16.0.54#g' /etc/kubernetes/cfg/kube-proxy-config.yml
sed -i 's#master-01#node-02#g' /etc/kubernetes/cfg/kube-proxy-config.yml

6.12.12、 设置开机自启动
# 要配置域名解析/etc/hosts
systemctl daemon-reload
systemctl enable --now kube-proxy
systemctl status kube-proxy

kubectl get csr

image-20210208225108126

image-20210208225728719

image-20210208225822608

6.12.13、 分发网络插件
cd /opt/flanneld

for i in kubernetes-node-01 kubernetes-node-02; do 
scp flanneld mk-docker-opts.sh root@$i:/usr/local/bin; 
done

image-20210208230108608

6.12.15、 分发 flannel 服务脚本

image-20210208230351138

6.12.16、 分发 Docker 脚本
for ip in kubernetes-node-01 kubernetes-node-02;do
scp /usr/lib/systemd/system/docker.service root@${ip}:/usr/lib/systemd/system;
done

image-20210208230441218

6.12.17、 重启 docker,开启 flanneld 服务
systemctl daemon-reload
systemctl enable --now flanneld.service
systemctl status flanneld.service
systemctl restart docker

image-20210208231236023

image-20210208231323532

6.12.18、 查看 kubelet 加入集群请求
kubectl get csr

[root@kubernetes-master-01 ~]# kubectl get csr
NAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-i2N_TyL2MFAkNpohlKlSI06Hx7ZddL4i4dfQEgkhtGc   27m   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
node-csr-pDZ8ADqnOdoDiSNCZJTd94JxPv_O5fHtq9pOamyggtc   27m   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending

image-20210208231442485

6.12.19、 批准加入
kubectl certificate approve `kubectl get csr | grep "Pending" | awk '{print $1}'`

image-20210208231619131

6.12.20、 查看节点
kubectl get cs
kubectl get nodes -o wide
kubectl get nodes
6.12.21、 验证集群
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
[root@kubernetes-master-01 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        35d
nginx        NodePort    10.96.106.13   <none>        80:26755/TCP   25d

image-20210208232247820

image-20210306220935831

设置集群角色
kubectl label nodes kubernetes-node-01  node-role.kubernetes.io/node=kubernetes-node-01
kubectl label nodes kubernetes-node-02  node-role.kubernetes.io/node=kubernetes-node-02

image-20210208233759316

posted @ 2021-11-23 22:44  RandySun  阅读(156)  评论(0编辑  收藏  举报