Kubernetes 之二基于二进制方式搭建集群

前言

软件环境

软件 版本 安装方式
CentOS 7.9 3.10.0-1160.15.2.el7.x86_64 虚拟机
Docker docker-19.03.9 二进制安装包
Kubernetes 1.19 二进制安装包
Etcd 3.4.9 二进制安装包

集群搭建要求

搭建 Kubernetes 集群需要满足以下几个条件:

  • 一台或多台机器,建议操作系统 CentOS 7_x86_64
  • Master 节点的硬件配置:2GB 或更多 RAM,2 个 CPU 或更多 CPU,硬盘 20GB 或更多
  • Node 节点的硬件配置:4GB 或更多 RAM,4 个 CPU 或更多 CPU,硬盘 40GB 或更多
  • 系统内可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点
  • 集群中所有机器之间的网络可以互通
  • 禁用 swap 分区

集群服务器规划

kubernetes-kubeadm-1

Host Name 角色 IP CPU Memory Disk 组件
k8s-master master 192.168.1.109 >= 2C >=2G >=20G kube-apiserver,kube-controller-manager,kube-scheduler,etcd
k8s-node1 node 192.168.1.200 >= 4C >=4G >=40G kubelet,kube-proxy,docker,etcd
k8s-node2 node 192.168.1.111 >= 4C >=4G >=40G kubelet,kube-proxy,docker,etcd
k8s-node3 node 192.168.1.112 >= 4C >=4G >=40G kubelet,kube-proxy,docker,etcd

Kubernetes 单 Master 集群搭建

系统初始化

值得一提的是,以下系统初始化操作必须在所有节点上执行一次,包括 Master 节点与 Node 节点。


关闭防火墙

1
2
3
4
5
# 临时关闭
# systemctl stop firewalld

# 永久关闭
# systemctl disable firewalld

关闭 selinux

1
2
3
4
5
# 临时关闭
# setenforce 0

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

关闭 swap

1
2
3
4
5
# 临时关闭
$ swapoff -a

# 永久关闭
# sed -i 's/.*swap.*/#&/' /etc/fstab

系统时间同步

1
2
3
4
5
# 安装时间同步工具
# yum install ntpdate -y

# 设置时间同步服务器
# ntpdate time.windows.com

将桥接的 IPv4 流量传递到 iptables 的链

1
2
3
4
5
6
7
# 添加路由规则
# vim /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1

# 配置生效
# sysctl --system

设置主机名

1
# hostnamectl set-hostname <hostname>

添加 hosts(Master 和各 Node 节点都需要配置)

1
2
3
4
5
6
# 添加hosts
# vim /etc/hosts
192.168.1.109 k8s-master
192.168.1.200 k8s-node1
192.168.1.111 k8s-node2
192.168.1.112 k8s-node3

搭建 Etcd 集群

Etcd 是一个分布式键值存储系统,Kubernetes 使用 Etcd 进行数据存储,所以先准备一个 Etcd 系统。为解决 Etcd 单点故障,建议采用集群方式部署,这里使用 3 台机器组建 Etcd 集群,可容忍 1 台机器故障。当然,也可以使用 5 台组建集群,可容忍 2 台机器故障。为了节省机器,这里与 Kubernetes 节点机器复用,也可以独立于 Kubernetes 集群之外部署,只要 api-server 能连接上就行。

CFSSL 生成证书

CFSSL 是 CloudFlare 开源的一款 PKI/TLS 工具,包含一个命令行工具和一个用于签名、验证并且捆绑 TLS 证书的 HTTP API 服务,详细使用教程在这里


安装 CFSSL

1
2
3
4
5
6
7
8
9
10
# 二进制方式安装
# curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl
# curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson
# curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo

# 文件授权
# chmod +x /usr/local/bin/cfssl*

# 配置环境变量
# export PATH=/usr/local/bin:$PATH

创建 CA 证书的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# cat << EOF | tee ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"www": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF

创建 CA 证书签名的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# cat << EOF | tee ca-csr.json
{
"CN": "etcd ca",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
],
"ca": {
"expiry": "87600h"
}
}
EOF

创建 Etcd 证书的配置文件,hosts 字段中的 IP 为所有 Etcd 节点的集群内部通信 IP,为了方便后期扩容,可以多写几个预留的 IP。由于这里的 Etcd 集群节点和 Kubernetes 的集群节点共同安装在不同虚拟机内,所以 IP 列表就是 Kubernetes 集群各节点的 IP 集合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# cat << EOF | tee server-csr.json
{
"CN": "etcd",
"hosts": [
"192.168.1.109",
"192.168.1.200",
"192.168.1.111",
"192.168.1.112"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF

使用自签 CA 签发 Etcd 证书

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看目录文件
# ls
ca-config.json ca-csr.json server-csr.json

# 生成CA证书
# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

# 生成Etcd证书,"-profile" 参数的值必须与 `ca-config.json` 配置文件中的值一致
# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server

# 查看生成结果
# ls
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem server.csr server-csr.json server-key.pem server.pem

部署 Etcd 集群

以下操作都是在 Kubernetes 的 Master 节点上执行,完成后会将 Master 节点上生成的所有 Etcd 文件全部拷贝到其他 Node 节点。千万不要在每个 Node 节点都单独执行生成 Etcd 证书的操作,否则 Etcd 集群里的节点可能会因证书不一致而导致集群启动失败。


Master 节点安装 Etcd 服务

1
2
3
4
5
6
7
8
9
10
11
# 下载安装文件
# wget https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz

# 创建安装目录
# mkdir -p /opt/etcd/{bin,cfg,ssl}

# 解压安装文件
# tar zxvf etcd-v3.4.9-linux-amd64.tar.gz

# 拷贝安装文件
# mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/

Master 节点拷贝上面生成的 Etcd 证书

1
2
# 拷贝证书
# cp ca.pem ca-key.pem server.pem server-key.pem /opt/etcd/ssl

Master 节点创建 Etcd 的配置文件,这里必须根据实际情况更改 Etcd 各节点的 IP、端口、名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 创建Etcd的配置文件
# cat > /opt/etcd/cfg/etcd.conf << EOF
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.1.109:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.1.109:2379"

#[Cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.1.109:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.1.109:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.1.109:2380,etcd-2=https://192.168.1.200:2380,etcd-3=https://192.168.1.111:2380,etcd-4=https://192.168.1.112:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
1
2
3
4
5
6
7
8
9
ETCD_NAME:节点名称,集群中唯一
ETCDDATADIR:数据目录路径
ETCD_LISTEN_PEER_URLS:集群通信监听地址
ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址
ETCD_INITIAL_ADVERTISE_PEER_URLS:集群通告地址
ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址
ETCD_INITIAL_CLUSTER:集群节点地址
ETCD_INITIAL_CLUSTER_TOKEN:集群 Token
ETCD_INITIAL_CLUSTER_STATE:加入集群的当前状态,new 是新集群,existing 表示加入已有集群

Master 节点使用 Systemd 管理 Etcd 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 创建Etcd服务管理的配置文件
# cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
EnvironmentFile=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--peer-cert-file=/opt/etcd/ssl/server.pem \
--peer-key-file=/opt/etcd/ssl/server-key.pem \
--trusted-ca-file=/opt/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
--logger=zap
Restart=always
RestartSec=10s
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

# 更新配置
# systemctl daemon-reload

# 开机自启动
# systemctl enable etcd

拷贝 Kubernetes 的 Master 节点里的所有 Etcd 文件到其他 Node 节点,并在各个 Node 节点里分别配置 Etcd 和设置 Etcd 服务开机自启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 拷贝Etcd的文件到各个Node节点
# scp -r /opt/etcd/ root@k8s-node1:/opt/
# scp -r /opt/etcd/ root@k8s-node2:/opt/
# scp -r /opt/etcd/ root@k8s-node3:/opt/

# 拷贝Etcd服务管理的配置文件到各个Node节点
# scp /usr/lib/systemd/system/etcd.service root@k8s-node1:/usr/lib/systemd/system/
# scp /usr/lib/systemd/system/etcd.service root@k8s-node2:/usr/lib/systemd/system/
# scp /usr/lib/systemd/system/etcd.service root@k8s-node3:/usr/lib/systemd/system/

# 在各个Node节点里分别编辑Etcd的配置文件,包括更改当前节点的名称和IP
# vim /opt/etcd/cfg/etcd.conf

# 在各个Node节点里分别设置Etcd服务开机自启动
# systemctl daemon-reload
# systemctl enable etcd

启动 Etcd 集群

在 Etcd 的多个节点里分别执行以下命令来启动 Etcd 集群,值得一提的是,必须在多个 Etcd 节点里同时执行 systemctl start etcd 命令来启动集群,否则单个 Etcd 节点是无法正常启动的

1
2
3
4
5
6
7
8
9
# 启动Etcd
# systemctl start etcd

# 查看运行状态
# systemctl satus etcd

# 查看启动日志
# journalctl -u etcd
# tail -f 200 /var/log/message

若 Etcd 集群启动失败,可以在各个 Etcd 节点里分别执行以下操作来解决

1
2
3
4
5
6
7
8
# 关闭Etcd
# systemctl stop etcd

# 删除数据目录
# rm -rf /var/lib/etcd/default.etcd

# 重启Etcd
# systemctl start etcd

参考博客