【Linux运维大神系列】Kubernetes详解4(二进制部署k8s1.23高可用集群)
目录
2.使用现有的CA证书及其私钥 ,对etcd-csr.json 证书签名请求文件进行签署
6.为etcd创建服务管理文件(systemd管理etcd)
kubernetes集群规划
| 主机IP | 主机名 | 主机配置 | 角色 |
|---|---|---|---|
| 10.0.0.110 | master01 | 2C/4G | 管理节点 |
| 10.0.0.111 | master02 | 2C/4G | 管理节点 |
| 10.0.0.112 | master03 | 2C/4G | 管理节点 |
| 10.0.0.113 | node01 | 1C/2G | 工作节点 |
| 10.0.0.114 | node2 | 1C/2G | 工作节点 |
| 10.0.0.115 | k8s-ha1 | 1C/2G | LB |
| 10.0.0.116 | k8s-ha2 | 1C/2G | LB |
kubernetes集群网络
| 网络名称 | 网段 | 备注 |
|---|---|---|
| Service网络 | 10.96.0.0/16 | |
| Pod网络 | 172.16.85.0/16 |
集群前期环境准备
1.修改主机名
hostnamectl set-hostname master01
hostnamectl set-hostname master02
hostnamectl set-hostname master03
hostnamectl set-hostname worker01hostnamectl set-hostname worker02
hostnamectl set-hostname k8s-ha1
hostnamectl set-hostname k8s-ha2
2.配置本地解析
echo "10.0.0.110 master01" >> /etc/hosts
echo "10.0.0.111 master02" >> /etc/hosts
echo "10.0.0.112 master03" >> /etc/hosts
echo "10.0.0.113 worker01" >> /etc/hosts
echo "10.0.0.114 worker02" >> /etc/hosts
echo "10.0.0.115 k8s-ha1" >> /etc/hosts
echo "10.0.0.116 k8s-ha2" >> /etc/hosts
3.开启bridge网桥过滤功能
bridge(桥接) 是 Linux 系统中的一种虚拟网络设备,它充当一个虚拟的交换机,为集群内的容器提供网络通信功能,容器就可以通过这个 bridge 与其他容器或外部网络通信了。
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
加载br_netfilter模块
modprobe br_netfilter && lsmod | grep br_netfilter
加载配置文件,使上述配置生效
sysctl -p /etc/sysctl.d/k8s.conf
4.配置ipvs功能
下载软件
yum -y install ipset ipvsadm
#将模块写入文件中
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
EOF
#执行文件
chmod 755 /etc/sysconfig/modules/ipvs.modules
bash /etc/sysconfig/modules/ipvs.modules
lsmod | grep -e ip_vs -e nf_conntrack
5.关闭swap分区
#临时关闭
swapoff -a
#永久关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab
grep "swap" /etc/fstab
kubernetes负载均衡部署
在ha1和ha2中执行
#下载软件
yum -y install haproxy keepalived
1.修改haproxy配置文件
#修改haproxy配置文件(ha1和ha2保持一致)
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global #全局配置
maxconn 2000 #单个进程最大并发连接数
ulimit-n 16384 #每个进程可以打开的文件数量
log 127.0.0.1 local0 err #日志输出配置,所有日志都记录在本机系统日志,通过 local0 输出
stats timeout 30s #连接socket超时时间
defaults
log global #定义日志为global(全局)
mode http #使用的连接协议
option httplog #日志记录选项,httplog表示记录与HTTP会话相关的日志
timeout connect 5000 #定义haproxy将客户端请求转发至后端服务器所等待的超时时长
timeout client 50000 #客户端非活动状态的超时时长
timeout server 50000 #客户端与服务器端建立连接后,等待服务器端的超时时长
timeout http-request 15s #客户端建立连接但不请求数据时,关闭客户端连接超时时间
timeout http-keep-alive 15s # session 会话保持超时时间
frontend monitor-in #监控haproxy服务本身
bind *:33305 #监听的端口
mode http #使用的连接协议
option httplog #日志记录选项,httplog表示记录与HTTP会话相关的日志
monitor-uri /monitor #监控URL路径
frontend k8s-master #接收请求的前端名称,名称自定义,类似于Nginx的一个虚拟主机server。
bind 0.0.0.0:6443 #监听客户端请求的 IP地址和端口(以包含虚拟IP)
bind 127.0.0.1:6443
mode tcp #使用的连接协议
option tcplog #日志记录选项,tcplog表示记录与tcp会话相关的日志
tcp-request inspect-delay 5s #等待数据传输的最大超时时间
default_backend k8s-master #将监听到的客户端请求转发到指定的后端
backend k8s-master #后端服务器组,要与前端中设置的后端名称一致
mode tcp #使用的连接协议
option tcplog #日志记录选项,tcplog表示记录与tcp会话相关的日志
option tcp-check #tcp健康检查
balance roundrobin #负载均衡方式为轮询
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
server master01 10.0.0.110:6443 check # 根据自己环境修改后端实例IP
server master02 10.0.0.111:6443 check # 根据自己环境修改后端实例IP
server master03 10.0.0.112:6443 check # 根据自己环境修改后端实例IP
#启动haproxy
systemctl start haproxy
systemctl enable haproxy
systemctl status haproxy
2.修改ha1节点keepalived配置文件
[root@k8s-ha1 ~]#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
# 全局配置
global_defs {
router_id k8s-ha1 #标识身份
script_user root #指定脚本执行用户
enable_script_security
}
#定义一个自定义脚本,名称为chk_apiserver
vrrp_script chk_apiserver {
#脚本所在的路径及名称
script "/etc/keepalived/check_apiserver.sh"
#检查的时间间隔
interval 5
#检查失败时,当前节点的优先级减少 5
weight -5
#健康检查连续失败两次,则标记为不监控
fall 2
#健康检查成功一次,标记为健康
rise 1
}
#配置了一个名为VI_1的VRRP实例组
vrrp_instance VI_1 {
#该节点在VRRP组中的身份,Master节点负责处理请求并拥有虚拟IP地址
state MASTER
#实例绑定的网络接口,实例通过这个网络接口与其他VRRP节点通信,以及虚拟IP地址的绑定
interface eth0
#虚拟的路由ID,范围1到255之间的整数,用于在一个网络中区分不同的VRRP实例组,但是在同一个VRRP组中的节点,该ID要保持一致
virtual_router_id 51
#实例的优先级,范围1到254之间的整数,用于决定在同一个VRRP组中哪个节点将成为Master节点,数字越大优先级越>高
priority 101
#Master节点广播VRRP报文的时间间隔,用于通知其他Backup节点Master节点的存在和状态,在同一个VRRP组中,所有>节点的advert_int参数值必须相同
advert_int 2
#实例之间通信的身份验证机制
authentication {
#PASS为密码验证
auth_type PASS
#此密码必须为1到8个字符,在同一个VRRP组中,所有节点必须使用相同的密码,以确保正确的身份验证和通信
auth_pass abc123
}
#定义虚拟ip地址
virtual_ipaddress {
10.0.0.3/24
}
#引用自定义脚本,名称与上方vrrp_script中定义的名称保持一致
track_script {
chk_apiserver
}
}
3.修改ha2的keepalived配置文件
[root@k8s-ha2 /opt]#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
# 全局配置
global_defs {
router_id k8s-ha2 #标识身份
script_user root #指定脚本执行用户
enable_script_security
}
#定义一个自定义脚本,名称为chk_apiserver
vrrp_script chk_apiserver {
#脚本所在的路径及名称
script "/etc/keepalived/check_apiserver.sh"
#检查的时间间隔
interval 5
#检查失败时,当前节点的优先级减少 5
weight -5
#健康检查连续失败两次,则标记为不监控
fall 2
#健康检查成功一次,标记为健康
rise 1
}
#配置了一个名为VI_1的VRRP实例组
vrrp_instance VI_1 {
#该节点在VRRP组中的身份,Master节点负责处理请求并拥有虚拟IP地址
state BACKUP #需要修改节点身份
#实例绑定的网络接口,实例通过这个网络接口与其他VRRP节点通信,以及虚拟IP地址的绑定
interface eth0
#虚拟的路由ID,范围1到255之间的整数,用于在一个网络中区分不同的VRRP实例组,但是在同一个VRRP组中的节点,该ID要保持一致
virtual_router_id 51
#实例的优先级,范围1到254之间的整数,用于决定在同一个VRRP组中哪个节点将成为Master节点,数字越大优先级越>高
priority 99 #需要修改优先级
#Master节点广播VRRP报文的时间间隔,用于通知其他Backup节点Master节点的存在和状态,在同一个VRRP组中,所有节点的advert_int参数值必须相同
advert_int 2
#实例之间通信的身份验证机制
authentication {
#PASS为密码验证
auth_type PASS
#此密码必须为1到8个字符,在同一个VRRP组中,所有节点必须使用相同的密码,以确保正确的身份验证和通信
auth_pass abc123
}
#定义虚拟ip地址
virtual_ipaddress {
10.0.0.3/24
}
#引用自定义脚本,名称与上方vrrp_script中定义的名称保持一致
track_script {
chk_apiserver
}
}
4.编写脚本
[root@k8s-ha1 /opt]#cat /etc/keepalived/check_apiserver.sh
#!/bin/bash
err=0
for k in $(seq 3)
do
check_code=$(pgrep haproxy) #过滤haproxy进程
if [[ $check_code == "" ]]; then
let err++
sleep 1
continue
else
err=0
break
fi
done
if [[ $err -ne 0 ]]; then
echo "systemctl stop keepalived"
/usr/bin/systemctl stop keepalived
exit 1
else
exit 0
fi
#脚本添加执行权限
chmod +x /etc/keepalived/check_apiserver.sh
#两个节点启动keepalived
systemctl start keepalived
systemctl enable keepalived
systemctl status keepalived
准备集群所需证书
在k8s中,各个组件(如kubelet、kube-scheduler、kube-controller-manager等)以及用户需要进行相互通信,证书用来验证双方的身份,以确保通信的安全性。而且 k8s API 是通过HTTPS提供服务,这也需要一个 TLS( Transport Layer Security 传输层安全协议)证书保障在客户端(如kubectl)和API服务器之间建立一个安全连接。
k8s集群内部通讯并不需要购买商业证书,基本上都是使用自签证书来实现集群内部的通信
在master01上操作即可
创建目录用于准备集群相关证书
mkdir /root/work
cd /root/work
获取CFSSL工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
工具说明:
cfssl //管理证书的命令行工具
cfssljson //当你使用cfssl工具生成新的证书和私钥时,证书的格式是JSON对象,该工具来解析这个JSON对象,将证书和私钥提取出来,分别保存为.pem文件。
cfssl-certinfo //这个工具可以读取PEM格式的证书,解析证书中的信息,然后将这些信息以JSON格式显示出来。
添加执行权限并将程序移动到/usr/local/bin
chmod +x cfssl*
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
1.生成证书签名请求
证书签名请求(Certificate Signing Request,CSR)是一种用于申请新数字证书的标准请求,当你想要从一个公共的或私有的CA (Certificate Authority,证书颁发机构) 获取一个新的证书时,证书签名请求文件中包含了要在证书中定义的一些信息,如请求者的名字、组织和地理位置等。
cat > ca-csr.json <<"EOF"
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "kubemsb",
"OU": "CN"
}
],
"ca": {
"expiry": "87600h"
}
}
EOF
参数说明:
CN //证书的主题名称,例如,网站证书的CN通常是其域名(自签的证书,该名称自定义)
key //请求者的公钥,algo生成公钥的加密算法,size公钥的长度
names //这是一个列表,包含了C(国家)、ST(省份)、L(城市)、O(公司)、OU(部门)
ca //该证书将被标记为CA证书(可以用来签名其他证书),expiry定义新的CA证书的有效期(单位是小时)
2.生成自签CA根证书
基于ca-csr.json 证书签名请求文件生成一个新的自签名的根证书(也称为CA证书,Certificate Authority证书)和与之配套的私钥。
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
命令说明:
cfssl gencert //用于生成新的证书和私钥
-initca //该选项用来指定使用新的证书和私钥来签名一个证书签名请求(CSR),而不是使用现有的CA证书
cfssljson -bare ca //将证书和私钥提取出来,分别保存为.pem文件
生成自签CA根证书后,会生成如下证书与之配套的文件:
-
ca.pem这是生成的自签名证书文件,包含证书中定义的一些信息 -
ca.csr这是ca证书配套的签名请求文件, 其中包含证书一些信息 -
ca-key.pem这是ca证书配套的私钥文件, 验证这个证书的真实性
3.配置CA根证书策略
在使用 CFSSL 工具生成自签名证书时,ca-config.json 文件是一个配置文件,用于定义证书颁发机构(CA)的策略和默认设置。
cat > ca-config.json <<"EOF"
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
参数说明:
signing //定义CA的签名配置,default表示默认配置,expiry定义了证书有效期
profiles //定义证书策略,策略名为(kubernetes),在该策略中通过(usages)定义了新生成的证书可以用于哪些用途,如(signing)新生成的证书可以用于数字签名、(key encipherment)密钥加密、(server auth)服务器身份认证、(client auth)和客户端身份认证
部署ETCD集群
k8s使用etcd作为其后端存储,以存储集群中的所有数据,例如:节点信息、Pod信息、配置资源、密钥资源、服务状态等, 满足Kubernetes对于数据存储的需求。
etcd使用Raft一致性算法保证所有的etcd实例存储的数据一致性,任何一个节点的故障都不会导致数据丢失。
1.生成etcd证书签名请求文件
cat > etcd-csr.json <<"EOF"
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"10.0.0.110",
"10.0.0.111",
"10.0.0.112"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "kubemsb",
"OU": "CN"
}]
}
EOF
参数说明:
CN //证书的主题名称
hosts //定义可以使用此证书的主机IP地址
2.使用现有的CA证书及其私钥 ,对etcd-csr.json 证书签名请求文件进行签署
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
-config=ca-config.json -profile=kubernetes etcd-csr.json | cfssljson -bare etcd
命令说明:
-ca=ca.pem //参数指定了用于签名新证书的 CA 证书文件
-ca-key=ca-key.pem //参数指定了用于签名新证书的 CA 的私钥文件
-config=ca-config.json //参数指定了证书的配置文件,它定义了 CA 的策略和默认设置
-profile=kubernetes //定义证书策略,策略名为(kubernetes)
etcd-csr.json //证书签名请求文件
cfssljson -bare ca //将证书和私钥提取出来,分别保存为.pem文件
会生成如下证书与之配套的文件:
-
etcd.csr证书配套的签名请求文件, 包含证书中定义的一些信息 -
etcd-key.pem证书配套的私钥文件, 验证证书的真实性 -
etcd.pem证书文件
3.安装并配置etcd集群
下载etcd二进制包,Github下载地址:https://github.com/etcd-io/etcd/releases
wget https://github.com/etcd-io/etcd/releases/download/v3.5.2/etcd-v3.5.2-linux-amd64.tar.gz
#解压etcd软件包,并拷贝etcd相关工具到/usr/local/bin
tar -xvf etcd-v3.5.2-linux-amd64.tar.gz
cp -p etcd-v3.5.2-linux-amd64/etcd* /usr/local/bin/
#分发etcd工具到其他etcd节点
for etcd in master02 master03
do
scp etcd-v3.5.2-linux-amd64/etcd* $etcd:/usr/local/bin/
done
4.创建etcd目录,用于存储etcd配置文件
mkdir /etc/etcd
[root@master01 /etc/etcd]#cat /etc/etcd/etcd.conf
#[Member]
ETCD_NAME="etcd1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://10.0.0.110:2380"
ETCD_LISTEN_CLIENT_URLS="https://10.0.0.110:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.0.0.110:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://10.0.0.110:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://10.0.0.110:2380,etcd2=https://10.0.0.111:2380,etcd3=https://10.0.0.112:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new
变量说明:
ETCD_NAME //当前etcd实例的名称,集群中唯一
ETCD_DATA_DIR //etcd存储数据的目录,所有数据都将存到这个目录
ETCD_LISTEN_PEER_URLS //etcd实例用于监听其他etcd实例连接的URL
ETCD_LISTEN_CLIENT_URLS //etcd实例用于监听客户端连接的URL
ETCD_INITIAL_ADVERTISE_PEER_URLS //etcd实例用于向集群中的其他实例宣告自己的URL
ETCD_ADVERTISE_CLIENT_URLS //etcd实例用于向客户端宣告自己的URL
ETCD_INITIAL_CLUSTER //初始化集群时所有etcd实例的列表
ETCD_INITIAL_CLUSTER_TOKEN //集群Token,用于标识集群的唯一标记
ETCD_INITIAL_CLUSTER_STATE //etcd集群的初始状态,new是新集群,existing表示加入已有集群
5.创建etcd相关目录
#创建etcd证书目录
mkdir /etc/etcd/ssl
#拷贝相关证书到etcd证书目录
cd /root/work
cp ca*.pem /etc/etcd/ssl
cp etcd*.pem /etc/etcd/ssl
#创建etcd数据目录
mkdir -p /var/lib/etcd/default.etcd
6.为etcd创建服务管理文件(systemd管理etcd)
cat > /etc/systemd/system/etcd.service <<"EOF"
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=-/etc/etcd/etcd.conf
WorkingDirectory=/var/lib/etcd/
ExecStart=/usr/local/bin/etcd \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-cert-file=/etc/etcd/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-client-cert-auth \
--client-cert-auth
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
[Service] 部分参数介绍:
Type //服务启动类型,"notify"表示服务启动完成后向Systemd发送一个通知
EnvironmentFile //指定etcd环境变量文件,服务会在启动时加载文件中的环境变量
WorkingDirectory //定义了服务的工作目录,此处是 /var/lib/etcd/
ExecStart //定义了启动服务时要执行的命令,通过etcd的选项指定了相关证书
Restart //定义了服务失败时应如何操作,"on-failure"意味着在服务失败时重启服务
RestartSec //定义了服务失败后等待多久才重启服务,此处是 5 秒
LimitNOFILE //设置服务进程能打开的最大文件数,此处是 65536
7.同步文件到集群其他节点
提前在其他节点创建好对应的目录
mkdir -p /etc/etcd
mkdir -p /etc/etcd/ssl
mkdir -p /var/lib/etcd/default.etcd
同步文件
for etcd in master02 master03
do
scp /etc/etcd/etcd.conf $etcd:/etc/etcd
scp /etc/etcd/ssl/* $etcd:/etc/etcd/ssl
scp /etc/systemd/system/etcd.service $etcd:/etc/systemd/system
done
8.修改其他节点的etcd配置文件
master02节点
[root@master02 ~]#cat /etc/etcd/etcd.conf
#[Member]
ETCD_NAME="etcd2"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://10.0.0.111:2380"
ETCD_LISTEN_CLIENT_URLS="https://10.0.0.111:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.0.0.111:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://10.0.0.111:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://10.0.0.110:2380,etcd2=https://10.0.0.111:2380,etcd3=https://10.0.0.112:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
master03节点
[root@master03 ~]#cat /etc/etcd/etcd.conf
#[Member]
ETCD_NAME="etcd3"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://10.0.0.112:2380"
ETCD_LISTEN_CLIENT_URLS="https://10.0.0.112:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.0.0.112:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://10.0.0.112:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://10.0.0.110:2380,etcd2=https://10.0.0.111:2380,etcd3=https://10.0.0.112:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
9.启动etcd集群并验证
systemctl daemon-reload
systemctl start etcd
systemctl enable etcd
systemctl status etcd
验证集群状态
ETCDCTL_API=3 /usr/local/bin/etcdctl --write-out=table --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=https://10.0.0.110:2379,https://10.0.0.111:2379,https://10.0.0.112:2379 endpoint health
显示如下输出
+-------------------------+--------+-------------+-------+
| ENDPOINT | HEALTH | TOOK | ERROR |
+-------------------------+--------+-------------+-------+
| https://10.0.0.110:2379 | true | 10.774974ms | |
| https://10.0.0.112:2379 | true | 29.468141ms | |
| https://10.0.0.111:2379 | true | 49.745165ms | |
+-------------------------+--------+-------------+-------+
Kubernetes集群部署
1.准备docker环境
集群所有节点(不包括lb节点)
#准备阿里云仓库
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#下载docker
yum -y install docker-ce-20.10.9-3.el7.x86_64
#启动docker服务
systemctl enable docker
systemctl start docker
#设置docker的Cgroup
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
#重启docker服务
systemctl daemon-reload
systemctl restart docker
2.kubernetes集群软件下载
下载地址:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.23.md
在k8s-master01节点下载即可
wget https://dl.k8s.io/v1.23.0/kubernetes-server-linux-amd64.tar.gz
解压软件包并拷贝集群组件到/usr/local/bin
tar -xvf kubernetes-server-linux-amd64.tar.gz
cd kubernetes/server/bin/
cp kube-apiserver kube-controller-manager kube-scheduler kube-proxy kubelet kubectl /usr/local/bin
拷贝到master02和master03
for master in master02 master03
do
scp kube-apiserver kube-controller-manager kube-scheduler kube-proxy kubelet kubectl $master:/usr/local/bin
done
拷贝工作组件到worker01和worker02
for worker in worker01 worker02
do
scp kubelet kube-proxy $worker:/usr/local/bin
done
在集群所有节点(不包括LB节点)上创建目录
#用于存储集群配置文件
mkdir -p /etc/kubernetes/
#用于存储集群证书文件
mkdir -p /etc/kubernetes/ssl
#用于存储集群日志文件
mkdir -p /var/log/kubernetes
3.部署kube-apiserver
1)生成apiserver相关证书
生成apiserver证书签名请求文件
[root@master01 ~/work]#cat kube-apiserver-csr.json
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"10.0.0.110",
"10.0.0.111",
"10.0.0.112",
"10.0.0.113",
"10.0.0.114",
"10.0.0.117", #预留的ip,可以没有
"10.0.0.118", #预留的ip,可以没有
"10.0.0.3",
"10.96.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "kubemsb",
"OU": "CN"
}
]
}
参数说明:
CN //证书的主题名称
hosts //定义可以使用此证书的主机IP(含VIP)地址,方便后期扩容可以多预留一些IP,10.96.0.1是 k8s服务发现机制使用的IP
"kubernetes"、"kubernetes.default"、"kubernetes.default.svc"、"kubernetes.default.svc.cluster" 、"kubernetes.default.svc.cluster.local" 是k8s集群中用于访问 API 服务器的服务名和全域名,对这些名字的请求也将被视为有效。
使用现有的ca证书,对kube-apiserver-csr.json证书签名文件进行签署
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-apiserver-csr.json | cfssljson -bare kube-apiserver
#会生成如下证书与之配套的文件:
kube-apiserver.csr //证书配套的签名请求文件, 包含证书中定义的一些信息
kube-apiserver-key.pem //证书配套的私钥文件, 验证证书的真实性
kube-apiserver.pem //证书文件
创建一个token文件
k8s引入了TLS bootstraping机制来自动颁发客户端证书,当Node节点很多时,来简化证书颁发流程(在kubelet章节在详细讲解)
cat > token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
2)创建apiserver服务配置文件
该配置文件基于apiserver内部的变量定义了相关配置
[root@master01 ~/work]#cat /etc/kubernetes/kube-apiserver.conf
KUBE_APISERVER_OPTS="--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--anonymous-auth=false \
--bind-address=10.0.0.110 \
--secure-port=6443 \
--advertise-address=10.0.0.110 \
--insecure-port=0 \
--authorization-mode=Node,RBAC \
--runtime-config=api/all=true \
--enable-bootstrap-token-auth \
--service-cluster-ip-range=10.96.0.0/16 \
--token-auth-file=/etc/kubernetes/token.csv \
--service-node-port-range=30000-32767 \
--tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem \
--tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem \
--client-ca-file=/etc/kubernetes/ssl/ca.pem \
--kubelet-client-certificate=/etc/kubernetes/ssl/kube-apiserver.pem \
--kubelet-client-key=/etc/kubernetes/ssl/kube-apiserver-key.pem \
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \
--service-account-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
--service-account-issuer=api \
--etcd-cafile=/etc/etcd/ssl/ca.pem \
--etcd-certfile=/etc/etcd/ssl/etcd.pem \
--etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \
--etcd-servers=https://10.0.0.110:2379,https://10.0.0.111:2379,https://10.0.0.112:2379 \
--enable-swagger-ui=true \
--allow-privileged=true \
--apiserver-count=3 \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/log/kube-apiserver-audit.log \
--event-ttl=1h \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=4"
插件说明:
--enable-admission-plugins= //启用一组准入控制插件,在API请求被永久写入存储之前进行检查
NamespaceLifecycle //该插件会拒绝那些正在终止的命名空间中的请求
NodeRestriction //该插件限制kubelet只能管理自己的节点的Pod
LimitRanger //该插件实现资源使用的默认限制和配额
ServiceAccount //该插件则确保在创建的每个Pod中都有一个ServiceAccount
DefaultStorageClass //该插件实现动态存储(StorageClass)的PVC绑定
ResourceQuota //该插件实现对命名空间的资源使用量设定配额
选项说明:
--anonymous-auth=false //禁止匿名用户访问API服务器
--bind-address //API服务器监听的IP地址
--secure-port //API服务器监听HTTPS连接的端口
--advertise-address //这是API服务器公告给集群中其它组件的IP地址
--insecure-port //此选项设置为0,表示API服务器不监听不安全的HTTP连接
--authorization-mode //这是API服务器使用的授权模式
--runtime-config //这个选项用于启用或禁用API版本或特定的API资源
--enable-bootstrap-token-auth //启用用于节点引导的令牌认证
--service-cluster-ip-range //为Service分配的IP地址范围
--token-auth-file //此文件用于通过令牌进行身份验证
--service-node-port-range //为NodePort Service分配的端口范围
--service-account-issuer //ServiceAccount令牌的颁发者
--enable-swagger-ui //启用可视化功能,可通过浏览器向你的API发送请求
--allow-privileged //是否允许创建具有特权的容器
--apiserver-count //用于端点选举的API服务器的数量
--audit-log-maxage、--audit-log-maxbackup、--audit-log-maxsize、--audit-log-path //这些选项配置了审计日志功能
--alsologtostderr=true //将日志输出到标准错误(stderr)避免日志丢失
--logtostderr=false //生成日志文件
--log-dir=/var/log/kubernetes //指定kube-apiserver将日志写入到的目录
--v=4 //日志等级,数值越大,输出的日志越详细
3)创建apiserver服务管理文件
cat > /etc/systemd/system/kube-apiserver.service << "EOF"
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=etcd.service
Wants=etcd.service
[Service]
EnvironmentFile=-/etc/kubernetes/kube-apiserver.conf
ExecStart=/usr/local/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
[Unit] 部分参数说明:
Description //简单的服务描述
Documentation //服务文档的链接
After //这个服务会在etcd.service启动后启动
Wants //如果etcd.service服务失败,这个服务仍会尝试启动
[Service] 部分参数说明:
EnvironmentFile //指向服务的配置文件
ExecStart //定义了启动服务时运行的命令,基于$KUBE_APISERVER_OPTS变量中选项运行
Restart //如果服务进程失败(退出状态非零)systemd将重新启动它
RestartSec //定义了在服务重启之间的延迟,如果服务需要重启,systemd将等待5秒
Type //定义了服务的类型,notify表示服务在准备好接受请求时给systemd发送通知
LimitNOFILE //定义了服务进程可以打开的最大文件数量
4)同步文件到集群master节点
同步本机
[root@master01 ~/work]#cp ca*.pem /etc/kubernetes/ssl/
[root@master01 ~/work]#cp kube-apiserver*.pem /etc/kubernetes/ssl/
[root@master01 ~/work]#cp token.csv /etc/kubernetes/
同步其他master节点
[root@master01 ~/work]#for master in master02 master03
> do
> scp /etc/kubernetes/kube-apiserver.conf $master:/etc/kubernetes
> scp /etc/kubernetes/ssl/ca*.pem $master:/etc/kubernetes/ssl
> scp /etc/kubernetes/ssl/kube-apiserver*.pem $master:/etc/kubernetes/ssl
> scp /etc/kubernetes/token.csv $master:/etc/kubernetes
> scp /etc/systemd/system/kube-apiserver.service $master:/etc/systemd/system
> done
kube-apiserver.conf 100% 1554 1.8MB/s 00:00
ca-key.pem 100% 1675 1.7MB/s 00:00
ca.pem 100% 1359 1.3MB/s 00:00
kube-apiserver-key.pem 100% 1679 1.7MB/s 00:00
kube-apiserver.pem 100% 1667 1.8MB/s 00:00
token.csv 100% 84 71.1KB/s 00:00
kube-apiserver.service 100% 359 476.4KB/s 00:00
kube-apiserver.conf 100% 1554 2.0MB/s 00:00
ca-key.pem 100% 1675 1.2MB/s 00:00
ca.pem 100% 1359 1.4MB/s 00:00
kube-apiserver-key.pem 100% 1679 1.8MB/s 00:00
kube-apiserver.pem 100% 1667 1.5MB/s 00:00
token.csv 100% 84 93.9KB/s 00:00
kube-apiserver.service 100% 359 377.3KB/s 00:00
master02修改配置文件中的--bind-address 与--advertise-address IP为本机
[root@master02 /usr/local/bin]#egrep "bind-addres|advertise-address" /etc/kubernetes/kube-apiserver.conf
--bind-address=10.0.0.111 \
--advertise-address=10.0.0.111 \
master03修改配置文件中的--bind-address 与--advertise-address IP为本机
[root@master03 ~]#egrep "bind-addres|advertise-address" /etc/kubernetes/kube-apiserver.conf
--bind-address=10.0.0.112 \
--advertise-address=10.0.0.112 \
5)启动apiserver服务
systemctl daemon-reload
systemctl start kube-apiserver
systemctl enable kube-apiserver
systemctl status kube-apiserver
测试
curl --insecure https://10.0.0.110:6443/
curl --insecure https://10.0.0.111:6443/
curl --insecure https://10.0.0.112:6443/
curl --insecure https://10.0.0.3:6443/
4.部署kubectl组件
1)生成kubectl相关证书
生成kubectl证书签名请求文件
cat > admin-csr.json << "EOF"
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:masters",
"OU": "system"
}
]
}
EOF
说明:这个admin证书,是将来生成管理员用的kube.config配置文件用的,“O”(公司)参数必须是system:masters,否则后面kubectl create clusterrolebinding报错
使用现有的CA证书及其私钥 ,对admin-csr.json 证书签名请求文件进行签署
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
会生成如下证书与之配套的文件:
admin.csr //证书配套的签名请求文件, 包含证书中定义的一些信息
admin-key.pem //证书配套的私钥文件, 验证证书的真实性
admin.pem //证书文件
复制证书文件到/etc/kubernetes/ssl
[root@master01 ~/work]#cp admin*.pem /etc/kubernetes/ssl/
2)配置kubectl安全上下文
kube.config 是 kubectl 的安全上下文,该文件用于存储集群,用户,命名空间和认证信息的文件,kubectl 命令行工具用它来管理集群
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://10.0.0.3:6443 --kubeconfig=kube.config
命令说明:
kubectl config set-cluster //设置集群,kubernetes是集群名称
--certificate-authority=ca.pem //验证API server的证书文件
--embed-certs=true //将证书数据嵌入到kube.config文件中,这样即使证书文件移动或删除,kube.config文件仍然有效
--server=https://10.0.0.3:6443 //这个参数指定了API server的地址(VIP地址)
在 kube.config 文件中设置集群管理员( admin)用户
kubectl config set-credentials admin --client-certificate=admin.pem --client-key=admin-key.pem --embed-certs=true --kubeconfig=kube.config
命令说明:
kubectl config set-credentials //设置集群用户,用户名admin
--client-certificate=admin.pem //验证admin的证书文件
--client-key=admin-key.pem //验证admin的私钥文件
--embed-certs=true //将证书数据嵌入到kube.config文件中,这样即使证书文件移动或删除,kube.config文件仍然有效
--kubeconfig=kube.config //指定了将被修改的kubeconfig文件名
在kube.config文件中设置集群的上下文(context)信息,它会将集群、用户、命名空间关联起来, 以便快速轻松地在不同的集群,用户和命名空间之间切换
kubectl config set-context kubernetes --cluster=kubernetes --user=admin --kubeconfig=kube.config
命令说明:
kubectl config set-context //设置集群上下文,kubernetes是context名称
--cluster=kubernetes //指定了context关联的集群名称
--user=admin //指定了context关联的用户的名称(admin管理员)
--kubeconfig=kube.config //指定了将被修改的kubeconfig文件名
通过kube.config定义的context切换到 kubernetes集群环境验证
kubectl config use-context kubernetes --kubeconfig=kube.config
拷贝kube.config配置文件到用户家目录(该文件在那个用户家目录,那个用户就可以基于该文件的admin权限管理集群)
mkdir /root/.kube
cp kube.config /root/.kube/config
创建集群角色绑定, 用于将集群管理员的角色 (权限) 绑定给admin用户,这样admin用户就具备集群管理员的权限
kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes --kubeconfig=/root/.kube/config
设置环境变量 KUBECONFIG,用于保存config配置文件,kubectl 工具需要这个文件来管理集群
export KUBECONFIG=$HOME/.kube/config
3)查看集群状态
[root@master01 ~/work]#kubectl cluster-info #查看正在运行的集群的基本信息
Kubernetes control plane is running at https://10.0.0.3:6443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
[root@master01 ~/work]#kubectl get componentstatuses #检查集群的各个管理节点组件的健康状况
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
scheduler Unhealthy Get "https://127.0.0.1:10259/healthz": dial tcp 127.0.0.1:10259: connect: connection refused
controller-manager Unhealthy Get "https://127.0.0.1:10257/healthz": dial tcp 127.0.0.1:10257: connect: connection refused
etcd-1 Healthy {"health":"true","reason":""}
etcd-2 Healthy {"health":"true","reason":""}
etcd-0 Healthy {"health":"true","reason":""}
[root@master01 ~/work]#kubectl get all --all-namespaces #查看集群中的所有资源的信息(如:namespace、pods、service、deployment等)
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 44m
4)同步文件到master节点
#提前在其他节点创建好对应的目录
mkdir /root/.kube
#master01节点执行
for master in master02 master03
do
scp /root/.kube/config $master:/root/.kube/config
done
5.部署kube-controller-manager
1)生成controller-manager相关证书
生成controller-manager证书签名请求文件
cat > kube-controller-manager-csr.json << "EOF"
{
"CN": "system:kube-controller-manager",
"key": {
"algo": "rsa",
"size": 2048
},
"hosts": [
"127.0.0.1",
"10.0.0.110",
"10.0.0.111",
"10.0.0.112"
],
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:kube-controller-manager",
"OU": "system"
}
]
}
EOF
关键参数说明:
hosts //包含所有controller-manager节点IP
O(公司) //system:kube-controller-manager是集群内置的ClusterRoleBindings,赋予 kube-controller-manager工作所需的权限
使用现有的CA证书及其私钥 ,对kube-controller-manager-csr.json 证书签名请求文件进行签署
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
会生成如下证书与之配套的文件:
kube-controller-manager.csr //证书配套的签名请求文件, 包含证书中定义的一些信息
kube-controller-manager-key.pem //证书配套的私钥文件, 验证证书的真实性
kube-controller-manager.pem //证书文件
2)配置controller-manager安全上下文
kube-controller-manager.kubeconfig 是controller-manager安全上下文,该文件中用于存储集群,用户,命名空间和认证信息,controller-manager用它来找到自己的集群
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://10.0.0.3:6443 --kubeconfig=kube-controller-manager.kubeconfig
在文件中设置 system:kube-controller-manager 用户
kubectl config set-credentials system:kube-controller-manager --client-certificate=kube-controller-manager.pem --client-key=kube-controller-manager-key.pem --embed-certs=true --kubeconfig=kube-controller-manager.kubeconfig
在文件中设置集群的上下文(context)信息,这样system:kube-controller-manager 用户就可以找到自己的集群
kubectl config set-context system:kube-controller-manager --cluster=kubernetes --user=system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig
通过文件定义的context切换到 kubernetes集群环境验证
kubectl config use-context system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig
3)创建controller-manager服务配置文件
cat > kube-controller-manager.conf << "EOF"
KUBE_CONTROLLER_MANAGER_OPTS="--port=0 \
--secure-port=10257 \
--bind-address=127.0.0.1 \
--kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \
--service-cluster-ip-range=10.96.0.0/16 \
--cluster-name=kubernetes \
--cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \
--cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
--allocate-node-cidrs=true \
--cluster-cidr=10.244.0.0/16 \
--experimental-cluster-signing-duration=87600h \
--root-ca-file=/etc/kubernetes/ssl/ca.pem \
--service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \
--leader-elect=true \
--feature-gates=RotateKubeletServerCertificate=true \
--controllers=*,bootstrapsigner,tokencleaner \
--horizontal-pod-autoscaler-sync-period=10s \
--tls-cert-file=/etc/kubernetes/ssl/kube-controller-manager.pem \
--tls-private-key-file=/etc/kubernetes/ssl/kube-controller-manager-key.pem \
--use-service-account-credentials=true \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2"
EOF
选项说明:
--port=0 //关闭不安全HTTP端口访问
--secure-port //kube-controller-manager的HTTPS端口
--bind-address //kube-controller-manager绑定的本机IP地址
--kubeconfig //kube-controller-manager上下文,用于跟API server通信
--service-cluster-ip-range //指定服务IP地址范围
--cluster-name //指定当前集群的名称
--allocate-node-cidrs //启动集群CIDR(即子网)用于Pod网络
--cluster-cidr //集群的CIDR(即子网)范围
--experimental-cluster-signing-duration=87600h //证书签名的持续时间
--leader-elect //启用leader(领导者)选举,实现集群高可用性
--feature-gates=RotateKubeletServerCertificate //启用自动管理和更新Kubelet的TLS证书
--controllers //表示启动所有默认的控制器(*),并额外启动bootstrapsigner 和tokencleaner控制器,主要用于身份验证
--horizontal-pod-autoscaler-sync-period //HPA控制器规则检测时间
--use-service-account-credentials //每个控制使用单独的服务帐户凭证进行身份验证
--alsologtostderr //日志写入到标准错误,避免日志丢失
4)创建controller-manager服务管理文件
cat > kube-controller-manager.service << "EOF"
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/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
5)同步文件到集群master节点
同步本机
cp kube-controller-manager*.pem /etc/kubernetes/ssl/
cp kube-controller-manager.kubeconfig /etc/kubernetes/
cp kube-controller-manager.conf /etc/kubernetes/
cp kube-controller-manager.service /usr/lib/systemd/system/
其他master节点
for master in master02 master03
do
scp kube-controller-manager*.pem $master:/etc/kubernetes/ssl/
scp kube-controller-manager.kubeconfig $master:/etc/kubernetes/
scp kube-controller-manager.conf $master:/etc/kubernetes/
scp kube-controller-manager.service $master:/usr/lib/systemd/system/
done
6)启动controller-manager服务
systemctl daemon-reload
systemctl start kube-controller-manager
systemctl enable kube-controller-manager
systemctl status kube-controller-manager
6.部署kube-scheduler
1)生成scheduler相关证书
生成scheduler证书签名请求文件
cat > kube-scheduler-csr.json << "EOF"
{
"CN": "system:kube-scheduler",
"hosts": [
"127.0.0.1",
"10.0.0.110",
"10.0.0.111",
"10.0.0.112"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:kube-scheduler",
"OU": "system"
}
]
}
EOF
关键参数说明:
hosts //包含所有scheduler节点IP
O(公司) //system:kube-scheduler是集群内置的ClusterRoleBindings,赋予kube-scheduler工作所需的权限
使用现有的CA证书及其私钥 ,对kube-scheduler 证书签名请求文件进行签署
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
会生成如下证书与之配套的文件:
kube-scheduler.csr //证书配套的签名请求文件, 包含证书中定义的一些信息
kube-scheduler-key.pem //证书配套的私钥文件, 验证证书的真实性
kube-scheduler.pem //证书文件
2)配置scheduler安全上下文
kube-scheduler.kubeconfig 是scheduler安全上下文,该文件中用于存储集群,用户,命名空间和认证信息,scheduler用它来找到自己的集群
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://10.0.0.3:6443 --kubeconfig=kube-scheduler.kubeconfig
在文件中设置 system:kube-scheduler 用户
kubectl config set-credentials system:kube-scheduler --client-certificate=kube-scheduler.pem --client-key=kube-scheduler-key.pem --embed-certs=true --kubeconfig=kube-scheduler.kubeconfig
在文件中设置集群的上下文(context)信息,这样system:kube-scheduler 用户就可以找到自己的集群
kubectl config set-context system:kube-scheduler --cluster=kubernetes --user=system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig
通过文件定义的context切换到 kubernetes集群环境验证
[root@master01 ~/work]#kubectl config use-context system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig
Switched to context "system:kube-scheduler".
3)创建scheduler服务配置文件
cat > kube-scheduler.conf << "EOF"
KUBE_SCHEDULER_OPTS="--address=127.0.0.1 \
--kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
--leader-elect=true \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2"
EOF
4)创建scheduler服务管理文件
cat > kube-scheduler.service << "EOF"
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/kube-scheduler.conf
ExecStart=/usr/local/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
5)同步文件到集群master节点
同步本机
cp kube-scheduler*.pem /etc/kubernetes/ssl/
cp kube-scheduler.kubeconfig /etc/kubernetes/
cp kube-scheduler.conf /etc/kubernetes/
cp kube-scheduler.service /usr/lib/systemd/system/
其他master节点
for master in master02 master03
do
scp kube-scheduler*.pem $master:/etc/kubernetes/ssl/
scp kube-scheduler.kubeconfig $master:/etc/kubernetes/
scp kube-scheduler.conf $master:/etc/kubernetes/
scp kube-scheduler.service $master:/usr/lib/systemd/system/
done
6)启动scheduler服务
systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler
systemctl status kube-scheduler
7.部署kubelet组件
1)定义bootstrap.kubeconfig
kubelet在集群中负责启动和管理容器,也需要使用证书进行验证,然而,为新加入集群的节点手动颁发这些证书非常不方便,k8s引入了TLS bootstraping机制来简化证书颁发流程。
kubelet 会使用一个预先提供的 "bootstrap" 证书来向 apiserver 发送一个证书签名请求 (CSR) ,从而自动生成 kubelet 的 TLS 证书。
BOOTSTRAP_TOKEN=$(awk -F "," '{print $1}' /etc/kubernetes/token.csv)
2)配置kubelet安全上下文
kubelet-bootstrap.kubeconfig 作为kubelet安全上下文,该文件中用于存储集群,用户,命名空间和认证信息,scheduler用它来找到自己的集群
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://10.0.0.3:6443 --kubeconfig=kubelet-bootstrap.kubeconfig
在文件中设置 system:kubelet-bootstrap 用户
kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --kubeconfig=kubelet-bootstrap.kubeconfig
在文件中设置集群的上下文(context)信息,这样system:kubelet-bootstrap 用户就可以找到自己的集群
kubectl config set-context default --cluster=kubernetes --user=kubelet-bootstrap --kubeconfig=kubelet-bootstrap.kubeconfig
通过文件定义的context切换到 kubernetes集群环境验证
kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig
创建集群角色绑定, 用于将集群管理员的cluster-admin角色 (权限) 绑定给kubelet-bootstrap用户,这样kubelet-bootstrap用户就具备集群管理员的权限
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=kubelet-bootstrap
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap --kubeconfig=kubelet-bootstrap.kubeconfig
3)创建kubelet服务配置文件
cat > kubelet.json << "EOF"
{
"kind": "KubeletConfiguration",
"apiVersion": "kubelet.config.k8s.io/v1beta1",
"authentication": {
"x509": {
"clientCAFile": "/etc/kubernetes/ssl/ca.pem"
},
"webhook": {
"enabled": true,
"cacheTTL": "2m0s"
},
"anonymous": {
"enabled": false
}
},
"authorization": {
"mode": "Webhook",
"webhook": {
"cacheAuthorizedTTL": "5m0s",
"cacheUnauthorizedTTL": "30s"
}
},
"address": "10.0.0.110",
"port": 10250,
"readOnlyPort": 10255,
"cgroupDriver": "systemd",
"hairpinMode": "promiscuous-bridge",
"serializeImagePulls": false,
"clusterDomain": "cluster.local.",
"clusterDNS": ["10.96.0.2"]
}
EOF
参数说明:
kind //说明这个文档定义的是Kubelet配置
apiVersion //配置文件遵循的API版本
authentication //配置Kubelet的身份验证设置,包括 x509、webhook和匿名三种方式
x509 //用于验证来自API服务器的请求的CA证书文件
webhook //启用基于webhook的身份验证和缓存TTL
anonymous //关闭匿名用户的访问
authorization //配置Kubelet的授权模式为Webhook,设置授权和未授权的缓存TTL
address //Kubelet服务监听的IP地址
port //Kubelet服务监听的端口号
readOnlyPort //Kubelet只读端口号
cgroupDriver //Kubelet使用的cgroup驱动,用于限制容器的资源使用量
hairpinMode //同构bridge实现Pod中的不同容器间通信
serializeImagePulls //此设置为false表示允许Kubelet并行拉取镜像
clusterDomain //设置Kubernetes集群的DNS域名
clusterDNS //设置集群DNS服务器的地址
4)创建kubelet服务管理文件
cat > kubelet.service << "EOF"
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/usr/local/bin/kubelet \
--bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig \
--cert-dir=/etc/kubernetes/ssl \
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
--config=/etc/kubernetes/kubelet.json \
--network-plugin=cni \
--rotate-certificates \
--pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2 \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
参数说明:
Description //服务的简要描述
Documentation //服务的文档链接
After //定义了该服务启动应该在哪些服务之后
Requires //定义了该服务启动需要哪些服务
[Service] //定义了服务的启动细节
WorkingDirectory //定义了Kubelet的工作目录
ExecStart //定义了启动服务的命令和参数
--network-plugin //指定kubelet使用的网络插件
--rotate-certificates //启用kubelet证书轮换,证书有效期限结束时自动请求新的证书
--pod-infra-container-image //指定pause容器的镜像
--alsologtostderr //日志输出到标准错误,避免日志丢失
--log-dir //日志文件的路径
Restart //定义了服务在失败时是否重启
RestartSec //定义了服务失败后重启前的等待时间
5)同步文件到集群所有节点
同步本机
cp kubelet-bootstrap.kubeconfig /etc/kubernetes/
cp kubelet.json /etc/kubernetes/
cp kubelet.service /usr/lib/systemd/system/
集群所有节点
for k8s in master02 master03 worker01 worker02
do
scp kubelet-bootstrap.kubeconfig kubelet.json $k8s:/etc/kubernetes/
scp ca.pem $k8s:/etc/kubernetes/ssl/
scp kubelet.service $k8s:/usr/lib/systemd/system/
done
注意:kubelet.json中address需要修改为当前主机IP地址。
#master02节点
[root@master02 /usr/local/bin]#grep address /etc/kubernetes/kubelet.json
"address": "10.0.0.111",
#master03节点
[root@master03 ~]#grep address /etc/kubernetes/kubelet.json
"address": "10.0.0.112",
#worker01节点
[root@worker01 ~]#grep address /etc/kubernetes/kubelet.json
"address": "10.0.0.113",
#worker02节点
[root@worker02 ~]#grep address /etc/kubernetes/kubelet.json
"address": "10.0.0.114",
所有节点创建kubelet工作目录
mkdir /var/lib/kubelet
检查所有节点是否都有日志目录,没有则创建
ls /var/log/kubernetes
6)启动kubelet服务
systemctl daemon-reload
systemctl start kubelet
systemctl status kubelet
systemctl enable kubelet
#查看各节点信息
[root@master01 ~/work]#kubectl get node
NAME STATUS ROLES AGE VERSION
master01 NotReady <none> 4m2s v1.23.0
master02 NotReady <none> 23s v1.23.0
master03 NotReady <none> 23s v1.23.0
worker01 NotReady <none> 23s v1.23.0
worker02 NotReady <none> 23s v1.23.0
8.部署kube-proxy
1)生成kube-proxy相关证书
生成kubeproxy证书签名请求文件
cat > kube-proxy-csr.json << "EOF"
{
"CN": "system:kube-proxy",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "kubemsb",
"OU": "CN"
}
]
}
EOF
使用现有的CA证书及其私钥 ,对kube-proxy 证书签名请求文件进行签署
x cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
会生成如下证书与之配套的文件:
kube-proxy.csr //证书配套的签名请求文件, 包含证书中定义的一些信息
kube-proxy-key.pem //证书配套的私钥文件, 验证证书的真实性
kube-proxy.pem //证书文件
2)配置kube-proxy安全上下文
kube-proxy.kubeconfig 是kube-proxy安全上下文,该文件中用于存储集群,用户,命名空间和认证信息,kube-proxy用它来找到自己的集群
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://10.0.0.3:6443 --kubeconfig=kube-proxy.kubeconfig
在文件中设置 kube-proxy 用户
kubectl config set-credentials kube-proxy --client-certificate=kube-proxy.pem --client-key=kube-proxy-key.pem --embed-certs=true --kubeconfig=kube-proxy.kubeconfig
在文件中设置集群的上下文(context)信息,这样kube-proxy 用户就可以找到自己的集群
kubectl config set-context default --cluster=kubernetes --user=kube-proxy --kubeconfig=kube-proxy.kubeconfig
通过文件定义的context切换到 kubernetes集群环境验证
[root@master01 ~/work]#kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
Switched to context "default".
3)创建kube-proxy服务配置文件
cat > kube-proxy.yaml << "EOF"
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 10.0.0.3
clientConnection:
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
clusterCIDR: 10.244.0.0/16
healthzBindAddress: 10.0.0.3:10256
kind: KubeProxyConfiguration
metricsBindAddress: 10.0.0.3:10249
mode: "ipvs"
EOF
参数说明:
apiVersion //表明此配置遵循的API版本
bindAddress //kube-proxy监听的IP地址,用于接收传入的请求
clusterCIDR //集群的IP地址范围,这样kube-proxy进行适当的路由
healthzBindAddress //kube-proxy健康检查端口,其他组件通过这个地址来检查它的状态
kind //表明这个文件的类型是KubeProxyConfiguration
metricsBindAddress //指定kube-proxy提供指标数据端口,在这个端口获取kube-proxy的性能指标
mode //指定kube-proxy使用的代理模式为ipvs模式是一种基于内核的负载均衡技术
4)创建kube-proxy服务管理文件
cat > kube-proxy.service << "EOF"
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/usr/local/bin/kube-proxy \
--config=/etc/kubernetes/kube-proxy.yaml \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
5)同步主机到集群所有节点
同步主机
cp kube-proxy*.pem /etc/kubernetes/ssl/
cp kube-proxy.kubeconfig kube-proxy.yaml /etc/kubernetes/
cp kube-proxy.service /usr/lib/systemd/system/
同步集群所有节点
for k8s in master02 master03 worker01 worker02
do
scp kube-proxy.kubeconfig kube-proxy.yaml $k8s:/etc/kubernetes/
scp kube-proxy.service $k8s:/usr/lib/systemd/system/
done
注意:kube-proxy.yaml 文件中 bindAddress、healthzBindAddress、metricsBindAddress 需要修改为当前主机IP地址。
#master01节点
[root@master02 /etc/kubernetes]#egrep "bindAddress|healthzBindAddress|metricsBindAddress" /etc/kubernetes/kube-proxy.yaml
bindAddress: 10.0.0.111
healthzBindAddress: 10.0.0.111:10256
metricsBindAddress: 10.0.0.111:10249
#master02节点
[root@master03 /etc/kubernetes]#egrep "bindAddress|healthzBindAddress|metricsBindAddress" /etc/kubernetes/kube-proxy.yaml
bindAddress: 10.0.0.112
healthzBindAddress: 10.0.0.112:10256
metricsBindAddress: 10.0.0.112:10249
#worker01节点
[root@worker01 /etc/kubernetes]#egrep "bindAddress|healthzBindAddress|metricsBindAddress" /etc/kubernetes/kube-proxy.yaml
bindAddress: 10.0.0.113
healthzBindAddress: 10.0.0.113:10256
metricsBindAddress: 10.0.0.113:10249
#worker02节点
[root@worker02 /etc/kubernetes]#egrep "bindAddress|healthzBindAddress|metricsBindAddress" /etc/kubernetes/kube-proxy.yaml
bindAddress: 10.0.0.114
healthzBindAddress: 10.0.0.114:10256
metricsBindAddress: 10.0.0.114:10249
6)启动kube-proxy服务
systemctl daemon-reload
systemctl start kube-proxy
systemctl status kube-proxy
systemctl enable kube-proxy
9.部署Calico网络
在k8s-master01节点安装Calico网络即可
#下载calico文件
wget https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/calico.yaml
#创建calico网络
kubectl apply -f calico.yaml
#查看calico的Pod状态是否为Running
[root@master01 ~/work]#kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-66966888c4-rwtsv 1/1 Running 0 16m
calico-node-2cgcq 1/1 Running 0 16m
calico-node-jg66r 1/1 Running 0 16m
calico-node-ltt5w 1/1 Running 0 16m
calico-node-lxmtl 1/1 Running 0 21s
calico-node-r9v6d 1/1 Running 0 16m
查看集群节点状态是否为Ready
[root@master01 ~/work]#kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 Ready <none> 37m v1.23.0
master02 Ready <none> 34m v1.23.0
master03 Ready <none> 34m v1.23.0
worker01 Ready <none> 34m v1.23.0
worker02 Ready <none> 34m v1.23.0
10.部署CoreDNS
在k8s中,很多功能都需要用到DNS服务,例如:服务发现、负载均衡、有状态应用的访问等
文件地址:https://github.com/coredns/deployment/blob/master/kubernetes/coredns.yaml.sed
创建CoreDNS
[root@master01 ~]#kubectl apply -f coredns.yaml
#查看是否running
[root@master01 ~]#kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-764bcc6b75-t5vlg 1/1 Running 0 32s
11.Master节点设置污点
#设置污点
kubectl taint node master01 master02 master03 master:NoSchedule
#查看污点
[root@master01 ~]#kubectl describe node master01 master02 master03 | grep -i taint
Taints: master:NoSchedule
Taints: master:NoSchedule
Taints: master:NoSchedule
#取消污点
[root@master01 ~/test]#kubectl taint node master02 master:NoSchedule-
node/master02 untainted
12.部署应用验证
#部署nginx程序
[root@master01 ~]#kubectl create deployment nginx --image=nginx:latest
#暴露nginx的端口
[root@master01 ~]#kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
#查看pod状态
[root@master01 ~]#kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-7c658794b9-p27zh 1/1 Running 0 13m
#查看service状态
[root@master01 ~]#kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7h10m
nginx NodePort 10.96.31.28 <none> 80:32244/TCP 37s
#浏览器访问测试
http://集群任意节点:32244/

Node节点加入现有集群
后续如需往k8s集群中添加工作节点,可以通过以下方式添加
1.主机准备
| 主机IP | 主机名 | 主机配置 | 角色 |
|---|---|---|---|
| 10.0.0.17 | worker03 | 2C/4G | 工作节点 |
2.环境部署
配置集群本地解析
cat >> /etc/hosts << EOF
10.0.0.110 master01
10.0.0.111 master02
10.0.0.112 master03
10.0.0.113 worker01
10.0.0.114 worker02
10.0.0.117 worker03
10.0.0.115 k8s-ha1
10.0.0.116 k8s-ha2
EOF
集群现有节点增加解析
echo "10.0.0.117 worker03" >> /etc/hosts
3.开启bridge网桥过滤
bridge(桥接) 是 Linux 系统中的一种虚拟网络设备,它充当一个虚拟的交换机,为集群内的容器提供网络通信功能,容器就可以通过这个 bridge 与其他容器或外部网络通信了。
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
#加载br_netfilter模块
[root@worker03 ~]#modprobe br_netfilter && lsmod | grep br_netfilter
br_netfilter 22256 0
bridge 151336 1 br_netfilter
#加载配置文件,使上述配置生效
sysctl -p /etc/sysctl.d/k8s.conf
4.配置ipvs
#下载软件
yum -y install ipset ipvsadm
#ipvs相关模块写入文件中
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
EOF
#执行文件
chmod 755 /etc/sysconfig/modules/ipvs.modules
bash /etc/sysconfig/modules/ipvs.modules
lsmod | grep -e ip_vs -e nf_conntrack
5.关闭swap分区
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
grep "swap" /etc/fstab
free -h
6.安装docker
#准备阿里云仓库
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#下载docker软件
yum -y install docker-ce-20.10.9-3.el7.x86_64
#设置docker的Cgroup用于对容器实现资源限制
mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
#启动docker服务
systemctl enable docker
systemctl start docker
7.部署kubelet
#在master01节点拷贝kubelet、kube-proxy程序
[root@master01 /usr/local/bin]#scp kubelet kube-proxy worker03:/usr/local/bin
#在worker03节点准备相关目录
准备配置文件目录
mkdir -p /etc/kubernetes
准备证书目录
mkdir -p /etc/kubernetes/ssl
准备kubelet工作目录
mkdir -p /var/lib/kubelet
准备日志目录
mkdir -p /var/log/kubernetes
#在master节点拷贝 kubelet-bootstrap.kubeconfig、kubelet.json、kubelet.kubeconfig、kubelet.service、ca.pem 文件到worker03节点
cd /root/work
scp kubelet-bootstrap.kubeconfig kubelet.json worker03:/etc/kubernetes/
scp /etc/kubernetes/kubelet.kubeconfig worker03:/etc/kubernetes/
scp kubelet.service worker03:/usr/lib/systemd/system
scp ca.pem worker03:/etc/kubernetes/ssl
#在worker03节点修改kubelet.json文件
[root@worker03 /opt]#grep address /etc/kubernetes/kubelet.json
"address": "10.0.0.117",
#启动kubelet
systemctl daemon-reload
systemctl start kubelet
systemctl status kubelet
systemctl enable kubelet
#在master01查看node
[root@master01 ~/work]#kubectl get node
NAME STATUS ROLES AGE VERSION
master01 Ready <none> 91m v1.23.0
master02 Ready <none> 88m v1.23.0
master03 Ready <none> 88m v1.23.0
worker01 Ready <none> 88m v1.23.0
worker02 Ready <none> 88m v1.23.0
worker03 NotReady <none> 1s v1.23.0
8.部署kube-proxy
#同步kube-proxy相关文件到worker03节点
for k8s in worker03
do
scp kube-proxy.kubeconfig kube-proxy.yaml $k8s:/etc/kubernetes/
scp ku#be-proxy.service $k8s:/usr/lib/systemd/system/
done
#修改kube-proxy.yaml配置文件
[root@worker03 /opt]#egrep "bindAddress|healthzBindAddress|metricsBindAddress" /etc/kubernetes/kube-proxy.yaml
bindAddress: 10.0.0.117
healthzBindAddress: 10.0.0.117:10256
metricsBindAddress: 10.0.0.117:10249
#创建kube-proxy工作目录
mkdir /var/lib/kube-proxy
#再次查看node
[root@master01 ~/work]#kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 Ready <none> 99m v1.23.0
master02 Ready <none> 95m v1.23.0
master03 Ready <none> 95m v1.23.0
worker01 Ready <none> 95m v1.23.0
worker02 Ready <none> 95m v1.23.0
worker03 Ready <none> 7m22s v1.23.0 #已经Ready
更多推荐
所有评论(0)