集群证书
集群证书
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
验证是否安装成功
[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)
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
证书详解
-
default 是默认策略,指定证书默认有效期是 1 年
-
profiles 是定义使用场景,这里只是 kubernetes,其实可以定义多个场景,分别指定不同的过期时间,使用场 景等参数,后续签名证书时使用某个 profile;
-
signing: 表示该证书可用于签名其它证书,生成的 ca.pem 证书 (生成根证书)
-
server auth: 表示 client 可以用该 CA 对 server 提供的证书进行校验;
-
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
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]#
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
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
.....
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
[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
三个都已经执行ETCD都已经起来
如果etcd启动不起来,如何解决
# 查看日志
[root@kubernetes-master-01 etcd]# tail -f /var/log/messages
错误二
# 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
错误三,直观调试的方式
# 查看状态
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'
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
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
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
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
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);
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").
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
# 将证书复制到各个节点中
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
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
# 紧接着在容器当中复制出来即可。
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
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
6.11.3.1.1、 参数详解
- --certificate-authority:验证 kube-apiserver 证书的根证书。
- --client-certificate、--client-key:刚生成的 kube-controller-manager 证书和私钥,连接 kube-apiserver 时使用。
- --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
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
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
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
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
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
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/
# 创建 kubernetes 日志目录(在各个master节点中启动)
mkdir -p /var/log/kubernetes/
systemctl daemon-reload
systemctl enable --now kube-apiserver
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"
6.11.5.2、 高可用部署 api-server
负载均衡器有很多种,只要能实现 api-server 高可用都行,这里我们采用官方推荐的 haproxy + keepalived。
出现了错误解决:https://www.cnblogs.com/along21/p/10044931.html,可能是因为格式的问题
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
6.11.5.2.4、 haproxy 常见链接错误
如果出现启动失败如下,开启链接策略
setsebool -P haproxy_connect_any=1
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
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 出了问题,重启一下服务
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
6.11.5.3.5、 启动
systemctl daemon-reload
systemctl enable --now kube-controller-manager.service
systemctl status kube-controller-manager
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
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"}
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
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
6.11.5.6.3、 创建 TLS 匿名用户(授权TLS Bootrapping用户请求)
# 只需要在一个mster节点中执行(vim *.*.*55这个台机器中)
kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap
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
kubectl get csr # 查看集群加入请求(需要进行批准,在批准之前需要配置kube-proxy),目前是没有办法加入节点
# 查看节点
kubectl get node
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
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
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
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
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
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
6.11.5.8.7、 批准加入
kubectl certificate approve `kubectl get csr | grep "Pending" | awk '{print $1}'`
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
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
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 网络插件:
- Flannel
- Calico
- Canal
- Contiv
- OpenContrail
- NSX-T
- 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
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
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
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 # 添加
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
6.11.5.8.11.7、 启动 Flanneld 服务
systemctl daemon-reload
systemctl enable flanneld.service
systemctl status flanneld
systemctl restart docker
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
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
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
6.11.5.8.13、 绑定用户的超管权限
此举是将超管的用户权限绑定到集群。
6.11.5.8.14、 测试集群 DNS
kubectl run test -it --rm --image=busybox:1.28.3
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
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
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
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
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
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
6.12.9、 开启 kubelet
systemctl daemon-reload
systemctl enable --now kubelet
systemctl status kubelet.service
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
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
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
6.12.15、 分发 flannel 服务脚本
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
6.12.17、 重启 docker,开启 flanneld 服务
systemctl daemon-reload
systemctl enable --now flanneld.service
systemctl status flanneld.service
systemctl restart docker
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
6.12.19、 批准加入
kubectl certificate approve `kubectl get csr | grep "Pending" | awk '{print $1}'`
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
设置集群角色
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