1、规划清单
K8S 集群角色 | ip | 主机名 | 安装组件 | 系统 |
---|---|---|---|---|
控制节点 | 192.168.10.50 | master01 | apiserver、controller-manager、schedule、etcd、kube-proxy、容器运行时、keepalived、nginx | cetos7.9 |
控制节点 | 192.168.10.51 | master02 | apiserver、controller-manager、schedule、etcd、kube-proxy、容器运行时、keepalived、nginx | cetos7.9 |
控制节点 | 192.168.10.49 | master03 | apiserver、controller-manager、schedule、etcd、kube-proxy、容器运行时、keepalived、nginx | cetos7.9 |
工作节点 | 192.168.10.52 | node01 | Kube-proxy、calico、coredns、容 器运行时、kubelet | cetos7.9 |
vip | 192.168.10.199 |
二进制安装 k8s 尽可能贴近生产环境,所有 pod 只运行在工作节点上。
2、配置主机名
在192.168.10.50配置主机名:
hostnamectl set-hostname master01&& bash
在192.168.10.51配置主机名:
hostnamectl set-hostname master02&& bash
在192.168.10.49配置主机名:
hostnamectl set-hostname master03&& bash
在192.168.10.52配置主机名:
hostnamectl set-hostname node02&& bash
3、配置免密和hosts文件
配置hosts文件
[root@master01 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.10.50 master01
192.168.10.51 master02
192.168.10.52 node01
192.168.10.49 master03
#将hosts文件发送给各个节点
[root@master01 ~]# scp /etc/hosts master02:/etc/hosts
The authenticity of host 'master02 (192.168.10.51)' can't be established.
ECDSA key fingerprint is SHA256:FIodcU3fRGEPLQKn/t7qiU1t4AKgiXJxR2XA9n4TXZA.
ECDSA key fingerprint is MD5:02:db:73:57:a4:cf:de:2c:2c:78:0e:32:34:4d:5d:0a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'master02,192.168.10.51' (ECDSA) to the list of known hosts.
root@master02's password:
hosts 100% 248 233.2KB/s 00:00
[root@master01 ~]# scp /etc/hosts master03:/etc/hosts
The authenticity of host 'master03 (192.168.10.49)' can't be established.
ECDSA key fingerprint is SHA256:FIodcU3fRGEPLQKn/t7qiU1t4AKgiXJxR2XA9n4TXZA.
ECDSA key fingerprint is MD5:02:db:73:57:a4:cf:de:2c:2c:78:0e:32:34:4d:5d:0a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'master03,192.168.10.49' (ECDSA) to the list of known hosts.
root@master03's password:
hosts 100% 248 263.3KB/s 00:00
[root@master01 ~]# scp /etc/hosts node01:/etc/hosts
The authenticity of host 'node01 (192.168.10.52)' can't be established.
ECDSA key fingerprint is SHA256:FIodcU3fRGEPLQKn/t7qiU1t4AKgiXJxR2XA9n4TXZA.
ECDSA key fingerprint is MD5:02:db:73:57:a4:cf:de:2c:2c:78:0e:32:34:4d:5d:0a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'node01,192.168.10.52' (ECDSA) to the list of known hosts.
root@node01's password:
hosts
配置免密
#生成公钥
[root@master01 ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:aY6AH58XfwQcA4xYqcFLg3xdG8N8go37MGf11Tpl0Fw root@master01
The key's randomart image is:
+---[RSA 2048]----+
| . o +.@=.o .=E|
| o B * *=oo . *|
| o = ..+o. . + |
| .o + o. .. o |
| . o *S . . |
| . + =.o . |
| . + o . . |
| . . |
| |
+----[SHA256]-----+
[root@master01 ~]# cd .ssh/
[root@master01 .ssh]# ls
id_rsa id_rsa.pub known_hosts
[root@master01 .ssh]# cp id_rsa.pub authorized_keys
[root@master01 .ssh]# ls
authorized_keys id_rsa id_rsa.pub known_hosts
[root@master01 .ssh]# cd ~
#将公钥文件发送给各个节点
[root@master01 ~]# scp -r .ssh master02:/root/
root@master02's password:
known_hosts 100% 550 265.3KB/s 00:00
id_rsa 100% 1675 1.3MB/s 00:00
id_rsa.pub 100% 395 381.9KB/s 00:00
authorized_keys 100% 395 370.6KB/s 00:00
[root@master01 ~]# scp -r .ssh master03:/root/
root@master03's password:
known_hosts 100% 550 682.6KB/s 00:00
id_rsa 100% 1675 2.0MB/s 00:00
id_rsa.pub 100% 395 436.0KB/s 00:00
authorized_keys 100% 395 141.8KB/s 00:00
[root@master01 ~]# scp -r .ssh node01:/root/
root@node01's password:
known_hosts 100% 550 476.3KB/s 00:00
id_rsa 100% 1675 624.9KB/s 00:00
id_rsa.pub 100% 395 422.5KB/s 00:00
authorized_keys
4、关闭防火墙和selinux
#每个节点关闭防火墙
systemctl stop firewalld ; systemctl disable firewalld
#每个节点关闭防火墙
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
#修改 selinux 配置文件之后,重启机器,selinux 配置才能永久生效,重启之后,登录到机器,执行如下命令:
getenforce
#如果显示 Disabled 说明 selinux 已经关闭
5、关闭交换分区 swap,提升性能
#临时关闭,每个k8s节点都需要操作
[root@master01 ~]# swapoff -a
[root@master01 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─centos-root 253:0 0 17G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm #无挂载说明已经关闭
sdb 8:16 0 30G 0 disk
└─sdb1 8:17 0 30G 0 part /data
sr0 11:0 1 4.4G 0 rom
[root@master03 ~]# swapoff -a
[root@master02 ~]# swapoff -a
[root@node01 ~]# swapoff -a
#永久关闭,每个节点都需要操作
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
[root@node01 ~]# cat /etc/fstab | grep swap
#/dev/mapper/centos-swap swap swap defaults 0 0 #注释掉后,设备开机后就不会自动挂载
#问题 1:为什么要关闭 swap 交换分区?
Swap 是交换分区,如果机器内存不够,会使用 swap 分区,但是 swap 分区的性能较低,k8s 设计的时候为了能提升性能,默认是不允许使用交换分区的。Kubeadm 初始化的时候会检测 swap 是否关闭,如果没关闭,那就初始化失败。如果不想要关闭交换分区,安装 k8s 的时候可以指定--ignorepreflight-errors=Swap 来解决。
6、 修改机器内核参数
#每个k8s节点都需要执行
[root@node01 ~]# cat > /etc/sysctl.d/k8s.conf <<EOF
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> net.ipv4.ip_forward = 1
> EOF
[root@master03 ~]# modprobe br_netfilter
[root@master03 ~]# sysctl -p /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
#问题 1:sysctl 是做什么的?
在运行时配置内核参数
-p 从指定的文件加载系统参数,如不指定即从/etc/sysctl.conf 中加载
#问题 2:为什么要执行 modprobe br_netfilter?
修改/etc/sysctl.d/k8s.conf 文件,增加如下三行参数:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
sysctl -p /etc/sysctl.d/k8s.conf 出现报错:
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: No such file or directory
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: No such file or directory
#解决方法:
modprobe br_netfilter
#问题 3:为什么开启 net.bridge.bridge-nf-call-iptables 内核参数?
在 centos 下安装 docker,执行 docker info 出现如下警告:
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
解决办法:
vim /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
#问题 4:为什么要开启 net.ipv4.ip_forward = 1 参数?
net.ipv4.ip_forward 是数据包转发:
出于安全考虑,Linux 系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的 ip 地址将数据包发往本机另一块网卡,该网卡根据路由表继续发送数据包。这通常是路由器所要实现的功能。
要让 Linux 系统具有路由转发功能,需要配置一个 Linux 的内核参数 net.ipv4.ip_forward。这个参数指定了 Linux 系统当前对路由转发功能的支持情况;其值为 0 时表示禁止进行 IP 转发;如果是 1,则说明IP 转发功能已经打开。
7、 配置阿里云的 repo 源:安装 docker 和 containerd
#配置国内安装 docker 和 containerd 的阿里云的 repo 源
#每个节点都需要执行
yum install yum-utils -y
#安装docker得yum源,每个节点都需要执行
[root@master03 ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
已加载插件:fastestmirror, langpacks
adding repo from: http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
[root@master03 ~]# echo $?
0
#配置安装 k8s 组件需要的阿里云的 repo 源,每个节点都需要执行
[root@master03 ~]# cat > /etc/yum.repos.d/kubernetes.repo <<EOF
> [kubernetes]
> name=Kubernetes
> baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
> enabled=1
> gpgcheck=0
> EOF
#更新yum源
[root@master03 ~]# yum makecache
8、配置时间同步
chrony服务端配置
#每个节点安装chrony服务,每个节点都需要执行
[root@node01 ~]# yum -y install chrony
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
软件包 chrony-3.4-1.el7.x86_64 已安装并且是最新版本
无须任何处理
#master01配置chrony
[root@master01 ~]# cat /etc/chrony.conf | egrep -v "#|^$"
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp1.tencent.com iburst
server ntp2.tencent.com iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
allow 192.168.10.0/24
logdir /var/log/chrony
#master01重启 chrony服务
[root@master01 ~]# systemctl restart chronyd
[root@master01 ~]# systemctl enable chronyd
chrony客户端
#chony客户端配置,客户端同步master01得时间,除去master01其他都是客户端,所有客户端都得执行
[root@master03 ~]# cat /etc/chrony.conf | egrep -v "^$|#"
server 192.168.10.50 iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chrony
#客户端重启chrony服务
[root@master03 ~]# systemctl restart chronyd
[root@master03 ~]# systemctl enable chronyd
#客户端使用使用chronyc sources -v查看同步状态
[root@master02 ~]# chronyc sources -v
210 Number of sources = 1
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current synced, '+' = combined , '-' = not combined,
| / '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) -. | xxxx = adjusted offset,
|| Log2(Polling interval) --. | | yyyy = measured offset,
|| \ | | zzzz = estimated error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* master01 3 6 17 26 +990ns[+1989ns] +/- 16ms
*代表同步正常
9、安装 containerd 服务
#在 k8s 集群每个节点都操作如下命令:
yum install containerd.io-1.6.6 -y
#配置containerd
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
修改配置文件:
打开/etc/containerd/config.toml
把 SystemdCgroup = false 修改成 SystemdCgroup = true
把 sandbox_image = "k8s.gcr.io/pause:3.6"修改成
sandbox_image="registry.aliyuncs.com/google_containers/pause:3.7"
配置 containerd 开机启动,并启动 containerd
systemctl enable containerd --now
10、安装docker
#k8s 所有节点均按照以下配置:
yum install docker-ce -y
systemctl enable docker --now
#配置docker配置文件
cat /etc/docker/daemon.json
{
"data-root": "/data/docker/",
"registry-mirrors": [
"https://vh3bm52y.mirror.aliyuncs.com",
"https://registry.dockercn.com",
"https://docker.mirrors.ustc.edu.cn",
"https://dockerhub.azk8s.cn",
"http://hubmirror.c.163.com"
]
}
#重启docker
[root@master01 ~]# systemctl restart docker
[root@master01 ~]# systemctl enable docker
Created symlink from /etc/systemd/system/sockets.target.wants/docker.socket to /usr/lib/systemd/system/docker.socket.
11、安装签发证书工具 cfss
CFSSL(CloudFlare's SSL)是由 CloudFlare 开发的工具集,用于创建和管理 PKI(Public Key Infrastructure,公钥基础设施)。PKI 是一种广泛使用的安全框架,用于确保网络通信的机密性、完整
性和身份验证。
CFSSL 包含以下主要组件:
1、cfssl: 这是命令行工具,用于生成证书、密钥和其他安全资产。它支持多种证书配置选项,使用户能够轻松地生成自签名证书、服务器证书、客户端证书等。
2、cfssljson: 该工具用于将 JSON 格式的证书请求(CSR)转换为其他格式,如 PEM 格式。PEM 是一种常用的证书格式,适用于许多应用程序和服务器。
3、cfssl-bundle: 用于将证书绑定到其相应的中间证书和根证书,创建一个完整的证书链。
4、cfssl-certinfo: 用于解码和打印证书的信息,方便用户查看证书的详细信息。
5、cfssl-newkey: 用于生成新的私钥。
#安装cfssl工具
# master01节点下载证书生成工具
wget "https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_linux_amd64" -O /usr/local/bin/cfssl
wget "https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_linux_amd64" -O /usr/local/bin/cfssljson
chmod +x /usr/local/bin/cfssl*
12、生成etcd证书以及安装配置
12.1、生成ca证书
mkdir /etc/etcd/ssl -p
mkdir /root/ssl/etcd -p&& cd /root/ssl/etcd
#配置 ca 证书
[root@master01 zhengshu]# cat ca-csr.json
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "k8s",
"OU": "system"
}
],
"ca": {
"expiry": "87600h"
}
}
[root@master01 zhengshu]#cfssl gencert -initca ca-csr.json | cfssljson -bare ca
[root@master01 zhengshu]# ls ca*
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
#备注:
上述 ca-csr.json 配置文件是用于生成 Kubernetes 集群中的 CA 证书签名请求(CSR)的配置,解释如下:
1. CN (Common Name): 这是证书的通用名称,通常用于标识证书持有者的名称。在这个示例中,CN 被设置为"kubernetes",意味着生成的 CA 证书将用于 Kubernetes 集群。
2. key: 这个字段用于指定生成密钥的配置。在这里,使用 RSA 算法生成密钥,其大小为 2048位。
3. names: 这是一个包含有关证书主题(Subject)的信息的数组。主题信息描述了证书持有者的身份。在这个示例中,证书的主题包含以下字段:
• C (Country): 国家,设置为"CN"表示中国。
• ST (State): 省份或州,设置为"Hubei"表示湖北省。
• L (Locality): 城市或地区,设置为"Wuhan"表示武汉市。
• O (Organization): 组织名称,设置为"k8s"表示 Kubernetes。
• OU (Organizational Unit): 组织单元,设置为"system"表示系统级别。
4. ca: 这个字段用于设置 CA 证书的相关配置。
• expiry: 它指定了 CA 证书的有效期。在这个示例中,设置为"87600h",表示 CA 证书的有效期为 87600 小时(约合 10 年)。
#生成 ca 证书的配置文件
[root@master01 zhengshu]# cat ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",