官网地址:https://kubernetes.io/zh-cn/docs/home/supported-doc-versions
资源列表
主机IP | 主机名称 | 主机角色 | 软件 |
---|---|---|---|
192.168.111.30 | master1 | 主节点1 | kube-apiserver、kubectl、kube-controller-manager、kube-scheduler、etcd、containerd |
192.168.111.31 | master2 | 主节点2 | kube-apiserver、kubectl、kube-controller-manager、kube-scheduler、etcd、containerd |
192.168.111.32 | master3 | 主节点3 | kube-apiserver、kubectl、kube-controller-manager、kube-scheduler、etcd、containerd |
192.168.111.33 | loadBalancer1 | Master集群负载均衡器1 | haproxy、keepalived |
192.168.111.34 | loadBalancer2 | Master集群负载均衡器2 | haproxy、keepalived |
192.168.111.100 | 该主机不存在 | virtual_ip | 备注:通过keepalived动态漂移该IP到loadBalancer1、loadBalancer2 |
192.168.111.40 | node1 | 工作节点1 | kubelet、kube-proxy、containerd |
192.168.111.41 | node2 | 工作节点2 | kubelet、kube-proxy、containerd |
192.168.111.42 | node3 | 工作节点3 | kubelet、kube-proxy、containerd |
192.168.111.43 | node4 | 工作节点4 | kubelet、kube-proxy、containerd |
192.168.111.44 | node5 | 工作节点5 | kubelet、kube-proxy、containerd |
1、Master主机:2核CPU、4G内存、20G硬盘
2、Node主机:4+核CPU、8G+内存、40G+硬盘
3、集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)
4、节点之中不可以有重复的主机名、MAC 地址或 product_uuid
5、开启机器上的某些端口
6、为了保证 kubelet 正常工作,必须禁用交换分区
网络配置
名称 | 网段 |
---|---|
Node网段 | 192.168.111.0/24 |
Service网段 | 10.96.0.0/16 |
Pod网段 | 10.244.0.0/16 |
软件版本
软件 | 版本 |
---|---|
Debian | 11.x |
Kubeneters | 1.6x |
etcd | 3.5.x |
calico | 3.25.x |
coredns | 1.10.x |
containerd | 1.7.x |
runc | 1.1.x |
初始化环境
设置各节点的主机名
hostnamectl set-hostname master1 && hostname # 在主节点1设置
hostnamectl set-hostname master2 && hostname # 在主节点2设置
hostnamectl set-hostname master3 && hostname # 在主节点3设置
#
hostnamectl set-hostname loadBalancer1 && hostname # 在LoadBalancer节点1设置
hostnamectl set-hostname loadBalancer2 && hostname # 在LoadBalancer节点2设置
#
hostnamectl set-hostname node1 && hostname # 在从节点1设置
hostnamectl set-hostname node2 && hostname # 在从节点2设置
hostnamectl set-hostname node3 && hostname # 在从节点3设置
hostnamectl set-hostname node4 && hostname # 在从节点4设置
hostnamectl set-hostname node5 && hostname # 在从节点5设置
设置各节点Host文件(所有Master和Node节点)
vi /etc/hosts # 编辑文件,注意不能有空格
192.168.111.30 master1
192.168.111.31 master2
192.168.111.32 master3
192.168.111.33 loadBalancer1
192.168.111.34 loadBalancer2
192.168.111.40 node1
192.168.111.41 node2
192.168.111.42 node3
192.168.111.43 node4
192.168.111.44 node5
关闭各节点的防火墙(所有Master和Node节点)
systemctl disable nftables.service && systemctl stop nftables.service && systemctl status nftables.service
永久禁用各节点的交换分区(所有Master和Node节点)
swapoff -a && sed -i 's/.*swap.*/#&/' /etc/fstab # 注释掉swap那一行
同步各节点的时区(所有Master和Node节点)
#timedatectl status # 查看当前系统时区
#timedatectl list-timezones # 查看所有时区
timedatectl set-timezone Asia/Shanghai # 设置系统时区为中国/上海
升级系统
apt update # 只检查是否有可用更新
apt upgrade # 更新已安装的软件包
通过 cfssl 生成CA自签证书(在Master1节点生成并同步到各节点)
注意:自签证书在内部服务之间的HTTPS通讯没有问题,如果通过域名对外提供访问则建议使用权威机构颁发的证书(收费)
- 下载 cfssl 到 /usr/local/bin 目录(需要梯子,建议本地下载后同步到服务器)
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/bin/cfssl-json
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/bin/cfssl-certinfo
# 提示:如果下载慢,可以本地下载后上传到服务器 /home/lixing/k8s/cfssl 目录下,再执行以下操作
# cp -f /home/lixing/k8s/cfssl/cfssl_linux-amd64 /usr/bin/cfssl
# cp -f /home/lixing/k8s/cfssl/cfssljson_linux-amd64 /usr/bin/cfssljson
# cp -f /home/lixing/k8s/cfssl/cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
chmod +x /usr/bin/cfssl* && cfssl
- 生成 ca 证书请求文件
mkdir -p /etc/certs/ca && vi /etc/certs/ca/ca-csr.json # 编辑文件,添加如下内容
# CN:证书公用名称
## kube-apiserver从证书中提取该字段作为请求的用户名 (User Name)
## 浏览器使用该字段验证网站是否合法
## 对于SSL证书,一般为网站域名
## 对于代码签名证书则为申请单位名称
## 对于客户端证书则为证书申请者的姓名
# C:国家字母缩写,如中国:CN
# ST:所在省份
# L:所在城市
# O:Organization(单位名称)
## kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);
## 对于SSL证书,一般为网站域名;
## 对于代码签名证书则为申请单位名称
## 对于客户端单位证书则为证书申请者所在单位名称
# OU:部门名称
{
"CN": "ca",
"hosts": [],
"key": {"algo": "rsa","size": 2048},
"names": [{"C": "CN","ST": "江苏省","L": "南京市","O": "公司名称","OU": "部门名称"}],
"ca": {"expiry": "175200h"}
}
- 生成 ca 证书
cfssl gencert -initca /etc/certs/ca/ca-csr.json | cfssljson -bare /etc/certs/ca/ca
ca-csr.json: CSR的JSON设定文件
ca.csr: 证书签名请求文件
ca-key.pem:CA私钥
ca.pem: CA证书
- 生成根证书的 config 配置文件(为后期生成域名证书做准备)
cd /etc/certs/ca && cfssl print-defaults config > ca-config.json
# 默认配置文件格式
{
"signing": {
"default": {"expiry": "168h"},
"profiles": {
"www": {"expiry": "8760h","usages": ["signing","key encipherment","server auth"]},
"client": {"expiry": "8760h","usages": ["signing","key encipherment","client auth"]}
}
}
}
vi /etc/certs/ca/ca-config.json # 自定义ca-config.json
# server auth 表示 client 可以对使用该 ca 对 server 提供的证书进行验证
# client auth 表示 server 可以使用该 ca 对 client 提供的证书进行验证
{
"signing": {
"default": {"expiry": "168h"},
"profiles": {
"kubernetes": {"expiry": "175200h","usages": ["signing","key encipherment","server auth","client auth"]}
}
}
}
部署 HaProxy + KeepAlived 高可用集群(loadBalancer1、loadBalancer2)
- 1、Web集群调度器分为软件和硬件,软件开源的LVS、Haproxy、Nginx,硬件使用比较多的是F5
- 2、LVS、Haproxy、Nginx 最常用的调度算法有三种:
Round Robin:即轮询调度。根据轮询分配访问请求来实现负载均衡的效果。此算法还有一种加权轮询,即根据每个节点分配的权重轮询分配访问请求
Least Connections:即最小连接数法。每次将新的请求指派给连接数最小的客户端
Source Hashing :基于来源访问调度算法。该算法用于服务端需要保存Session会话记录的场景。可以基于来源IP、Cookie等做集群调度。该算法的好处是实现会话保持,但某些IP访问量非常大时,可能会导致负载不均衡,不分节点访问量变大,影响业务使用
安装 HaProxy
HaProxy官方地址
HAProxy是一个C语言编写的开源软件,提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。适用于负载特大的web站点,完全可以支持数以万计的并发连接
apt install haproxy # 安装haproxy,默认创建/etc/haproxy目录 # 创建相关目录 # apt remove haproxy
find / -name 'haproxy' # 查询相关目录和文件
#/var/lib/haproxy
#/etc/haproxy
#/etc/default/haproxy
#/etc/logrotate.d/haproxy
#/etc/init.d/haproxy
#/usr/share/doc/haproxy
#/usr/sbin/haproxy
#/run/haproxy
自定义 HaProxy 配置文件
cp -rf /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg_back # 备份默认的配置文件
cat > /etc/haproxy/haproxy.cfg << "EOF"
# 全局配置参数,属于进程级的配置
global
# 使用本地127.0.0.1上的rsyslog服务器中的local0设备记录,日志等级为info
log 127.0.0.1 local0 info
# haproxy工作目录
chroot /var/lib/haproxy
# haproxy启动后进程的pid文件路径
pidfile /var/run/haproxy.pid
# 每个haproxy进程可接受的最大并发连接数
maxconn 4000
# haproxy启动时可创建的进程数,默认1个,值应小于服务器的CPU核数
nbproc 1
# 以后台形式运行harpoxy
daemon
# 默认参数配置。所有的frontend、backend和listen都从该区段继承默认配置
defaults
# 设置Haproxy默认运行方式。如果没有指定默认为tcp模式
mode http
# 定义日志为global配置中所定义的日志格式
log global
# 最大连接数
maxconn 3000
# 配置连接后端服务器失败重试次数,超过3次后会将失败的后端服务器标记为不可用
retries 3
# 日志类别采用http日志格式
option httplog
# 当服务器负载很高的时候,自动结束掉当前队列处理比较久的连接
option abortonclose
# 不记录健康检查日志信息
option dontlognull
# 客户端和服务请求完毕后主动关闭http连接
option httpclose
# 当后端server宕机后,强制把请求定向到其他健康的服务器上
option redispatch
# 如果后端服务器需要获得客户端的真实ip,可以从http header 中获取客户端的IP
option forwardfor
# roundrobin:动态轮询,支持权重的运行时调整,支持慢启动,每个后端中最多支持4095个server
# static-rr:静态轮询,不支持权重的运行时调整,不支持慢启动,适用于短连接场景
# leastconn:最少连接算法,该算法本质上同static-rr没有太多的不同,适用于长连接的场景,如MySQL、LDAP等
# first:根据服务器在列表中的位置,自上而下进行调度;前面服务器的连接数达到上限,新请求才会分配给下一台服务
# source:源地址hash算法,类似LVS中的sh算法;hash类的算法动态与否取决于hash-type的值
balance roundrobin
# 配置成功连接到一台服务器的最长等待时间,默认单位是毫秒,可自定义单位
timeout connect 5000
# 配置连接客户端发送数据时的最长等待时间,默认单位是毫秒,可自定义单位
timeout client 1m
# 配置服务器端回应客户端数据发送时最长等待时间,默认单位是毫秒,可自定义单位
timeout server 1m
# 配置对后端服务器的检测超时时间,默认单位是毫秒,可自定义单位
timeout check 10s
# 默认http请求超时时间
timeout http-request 10s
# session 会话保持超时时间,范围内会转发到相同的后端服务器
timeout http-keep-alive 10s
# 定义虚拟节点(admin_stats) ,通过以下地址访问haproxy后台
# http://192.168.111.34:8085/admin
# http://192.168.111.34:8085/admin
frontend admin_stats
# 监听地址和端口
bind *:8085
maxconn 10
stats enable
stats refresh 30s
# 统计页面路径
stats uri /admin
# 设置统计页面认证的用户和密码
stats auth admin:admin
stats hide-version
stats admin if TRUE
# 接收请求的前端虚拟节点
frontend k8s-master
bind 0.0.0.0:6443
bind 127.0.0.1:6443
mode tcp
option tcplog
tcp-request inspect-delay 5s
# 定义默认服务器组,指向已创建的backend实例名称
default_backend k8s-master
# 后端服务集群的配置,代理将连接到服务器转发收到的请求
backend k8s-master
mode tcp
option tcplog
option tcp-check
# 指定应用的负载均衡算法:
## roundrobin:简单轮询调度
## static-rr:基于权重的调度算法
## leastconn:最小连接数量算法
## source:根据请求源ip地址
## url:根据请求的URL
## url_param:根据请求的url参数进行调度
## hdr(name):根据HTTP请求头来锁定每一次HTTP请求
## rdp-cookie:根据cookie名来锁定并hash每一次TCP请求
balance roundrobin
# 定义后端服务器的地址和参数:
## check:启用服务器健康检查,如果没有启用,则不进行健康检查,并且始终认为服务器可用
## inter <delay>:执行健康检查间隔周期。单位为延迟ms,默认为2000ms。
## fall <count>:在count次健康检查失败后,服务器将被认为不可用,默认值为3。
## rise <count>:在count次连续成功检查后,服务器被认为可正常运行,默认值为2。
## maxconn <maxconn>:指定将发送到此服务器的最大并发连接数 如果传入的并发连接数超过这个值,它们将被排队并等待一个连接被释放。
## weight <weight>:用于调整服务器相对其他服务器的权重。权重越高,负载越高。缺省值为1,最大值为256。
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
# 反向代理服务器的地址列表
server k8s-master1 192.168.111.30:6443 check
server k8s-master2 192.168.111.31:6443 check
server k8s-master3 192.168.111.32:6443 check
EOF
设置开机自启并查看运行状态
systemctl daemon-reload && systemctl enable --now haproxy && systemctl status haproxy
ps -ef|grep haproxy
安装 KeepAlived
apt install keepalived # 安装(默认会自动创建/etc/keepalived目录)
find / -name 'keepalived' # 查询相关目录和文件
#/etc/keepalived
#/etc/default/keepalived
#/etc/init.d/keepalived
#/usr/share/doc/keepalived
#/usr/sbin/keepalived
创建主节点配置文件(loadBalancer1)
cat > /etc/keepalived/keepalived.conf << "EOF"
! Configuration File for keepalived
# 全局默认配置
global_defs {
script_user root
router_id LVS_DEVEL
enable_script_security
}
# 自定义检测脚本:keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整 vrrp_instance 的优先级
## 如果脚本check_apiserver.sh执行结果为0,并且 weight 配置的值大于0,则优先级相应的增加
## 如果脚本check_apiserver.sh执行结果非0,并且 weight配置的值小于0,则优先级相应的减少
## 其他情况,维持原本配置的优先级,即配置文件中 priority 对应的值
vrrp_script check_apiserver {
# 本地脚本地址
script "/etc/keepalived/check_apiserver.sh"
# 每2秒检查一次
interval 2
# 脚本执行成功,权重减少5
weight -5
# 连续失败3次
fall 3
# 最少成功2次
rise 1
}
# VRRP实例,VI_1 为虚拟路由的标示符
vrrp_instance VI_1 {
# 主节点为 MASTER,对应的备份节点为 BACKUP
state MASTER
# 绑定虚拟 IP 的网络接口,与本机 IP 地址所在的网络接口相同,通过 ipaddr 查看本地网络接口
interface ens32
# 主机的IP地址
mcast_src_ip 192.168.111.33
# 虚拟路由id
virtual_router_id 51
# 抢占虚拟IP的优先级,值范围 0-254,MASTER 要比 BACKUP 高
priority 100
# 组播信息发送间隔,所有节点设置必须一样,默认 1s
advert_int 1
# 设置验证信息,所有节点必须一致
authentication {
auth_type PASS
auth_pass K8S_PASS
}
# 虚拟 IP 池, 所有节点设置必须一样,默认填写虚拟IP地址
virtual_ipaddress {
192.168.111.100
}
# 定义检测脚本
track_script {
# vrrp_script实例名称
check_apiserver
}
}
EOF
创建从节点配置文件(loadBalancer2)
cat > /etc/keepalived/keepalived.conf << "EOF"
! Configuration File for keepalived
# 全局默认配置
global_defs {
script_user root
router_id LVS_DEVEL
enable_script_security
}
# 自定义检测脚本:keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整 vrrp_instance 的优先级
## 如果脚本check_apiserver.sh执行结果为0,并且 weight 配置的值大于0,则优先级相应的增加
## 如果脚本check_apiserver.sh执行结果非0,并且 weight配置的值小于0,则优先级相应的减少
## 其他情况,维持原本配置的优先级,即配置文件中 priority 对应的值
vrrp_script check_apiserver {
# 本地脚本地址
script "/etc/keepalived/check_apiserver.sh"
# 每2秒检查一次
interval 2
# 脚本执行成功,权重减少5
weight -5
# 连续失败3次
fall 3
# 最少成功2次
rise 1
}
# VRRP实例的,VI_1 为虚拟路由的标示符
vrrp_instance VI_1 {
# 主节点为 MASTER,对应的备份节点为 BACKUP
state BACKUP
# 绑定虚拟 IP 的网络接口,与本机 IP 地址所在的网络接口相同,通过 ipaddr 查看本地网络接口
interface ens32
# 主机的IP地址
mcast_src_ip 192.168.111.34
# 虚拟路由id
virtual_router_id 51
# 抢占虚拟IP的优先级,值范围 0-254,MASTER 要比 BACKUP 高
priority 99
# 组播信息发送间隔,所有节点设置必须一样,默认 1s
advert_int 1
# 设置验证信息,所有节点必须一致
authentication {
auth_type PASS
auth_pass K8S_PASS
}
# 虚拟 IP 池, 所有节点设置必须一样,默认填写虚拟IP地址
virtual_ipaddress {
192.168.111.100
}
# 定义检测脚本
track_script {
# vrrp_script实例名称
check_apiserver
}
}
EOF
创建健康检查脚本(All)
cat > /etc/keepalived/check_apiserver.sh << "EOF"
#!/bin/bash
err=0
for k in $(seq 1 3)
do
check_code=$(pgrep haproxy)
if [[ $check_code == "" ]]; then
err=$(expr $err + 1)
sleep 1
continue
else
err=0
break
fi
done
if [[ $err != "0" ]]; then
echo "systemctl stop kAepalived"
/usr/bin/systemctl stop keepalived
exit 1
else
exit 0
fi
EOF
chmod +x /etc/keepalived/check_apiserver.sh # 脚本文件授权
设置开机自启并查询运行状态
systemctl enable --now keepalived && systemctl status keepalived
- 验证虚拟IP
- 模拟切换节点
systemctl stop haproxy && systemctl status haproxy # 关闭主节点上的 haproxy,观察虚拟节点是否切换到从节点
安装容器运行时(所有Node节点)
- 常见的容器运行时有:Containerd、CRI-O、Docker Engine、Mirantis Container Runtime。Kubernetes 1.24 之前的版本直接集成了 Docker Engine 的一个组件(dockershim),但自1.24版起Dockershim 已从 Kubernetes 项目中移除,如果需要使用基于Docker Engine的容器运行时则需要自行安装三方插件
- Kubernetes 1.26 要求使用符合容器运行时接口(CRI)的运行时,需要在集群内每个节点上安装一个容器运行时,以使 Pod 可以运行在上面
配置 containerd 内核模块
- 转发 IPv4 并让 iptables 看到桥接流量
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
lsmod | grep overlay # 确认 overlay 模块被加载
lsmod | grep br_netfilter # 确认 br_netfilter 模块被加载
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system # 应用 sysctl 参数而不重新启动
# 确认 net.bridge.bridge-nf-call-iptables、net.bridge.bridge-nf-call-ip6tables 和 net.ipv4.ip_forward 系统变量在你的 sysctl 配置中被设置为 1
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
Containerd安装教程
安装 ipvsadm(所有Master和Node节点)
ipvs (IP Virtual Server) 作为 Linux 内核的一部分,实现了传输层负载均衡,也就是我们常说的 4 层 LAN交换。ipvs 可以将基于 TCP 和 UDP 的服务请求转发到真实服务器上,并使真实服务器的服务在单个 IP 地址上显示为虚拟服务
kube-proxy 支持 iptables 和 ipvs 两种代理模式, kubernetes v1.8 中引入了 ipvs 模式,v1.11 中正式使用。ipvs 和 iptables 都是基于netfilter 的,但是 ipvs 采用的是 hash 表,因此当 service 数量达到一定规模时,hash 查表的速度优势就会显现出来,从而提高 service 的服务性能
- Debian 系统安装
apt install -y ipvsadm ipset
- 查看ipvs开启状态
ipvsadm -Ln
- 通过配置文件来实现永久加载
cat > /etc/modules-load.d/ipvs.conf << EOF
ip_vs
ip_vs_lc
ip_vs_wlc
ip_vs_rr
ip_vs_wrr
ip_vs_lblc
ip_vs_lblcr
ip_vs_dh
ip_vs_sh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF
- 确保所有节点的 ipvs 的模块已经运行
lsmod | grep ip_vs
部署 etcd 集群(Master1、Master2、Master3)
1、创建 etcd 证书
- 生成 etcd 证书请求文件
mkdir -p /etc/certs/etcd && vi /etc/certs/etcd/etcd-csr.json # 编辑文件,添加如下内容
{
"CN": "etcd",
"hosts": ["127.0.0.1", "192.168.111.30", "192.168.111.31", "192.168.111.32"],
"key": {"algo": "rsa","size": 2048},
"names": [{"C": "CN","ST": "江苏省","L": "南京市","O": "k8s","OU": "system"}]
}
- 生成 etcd 证书
cfssl gencert \
-ca=/etc/certs/ca/ca.pem \
-ca-key=/etc/certs/ca/ca-key.pem \
-config=/etc/certs/ca/ca-config.json \
-profile=kubernetes /etc/certs/etcd/etcd-csr.json | cfssljson -bare /etc/certs/etcd/etcd
etcd.csr:证书签名请求文件
etcd-csr.json:CSR的JSON设定文件
etcd-key.pem:CA私钥
etcd.pem:CA证书
- 同步 etcd 证书到 Master1 和 Master2
默认Master1节点安装成功后,然后下载到本地,再从本地同步到Master2和Master3,如果下载提示没有权限,可以执行:chmod -R 777 /home/lixing 给文件夹赋值权限
2、下载 etcd 并安装
cd /home/lixing/k8s/etcd && tar -zxvf etcd-v3.5.7-linux-amd64.tar.gz # 解压
cp -f /home/lixing/k8s/etcd/etcd-v3.5.7-linux-amd64/etcd* /usr/local/bin/ # 创建软链接
3、创建 etcd 配置文件
注意:修改/etc/etcd/etcd.conf文件时,要先删除/var/lib/etcd目录下已经存在的数据,再重新启用服务
- 创建目录(ALL)
mkdir -p /etc/etcd/ && mkdir -p /var/lib/etcd/ # 分别创建etcd的配置文件和数据文件目录
# etcd.conf 模板字段说明:
ETCD_NAME:节点名称,集群中唯一
ETCD_DATA_DIR:数据目录,需要自行创建
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表示加入已有集群(扩容时用)
- 创建配置文件(Master1)
cat > /etc/etcd/etcd.conf <<"EOF"
#[Member]
ETCD_NAME="etcd_192.168.111.30"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.111.30:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.111.30:2379,http://127.0.0.1:2379"
#[clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.111.30:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.111.30:2379"
ETCD_INITIAL_CLUSTER="etcd_192.168.111.30=https://192.168.111.30:2380,etcd_192.168.111.31=https://192.168.111.31:2380,etcd_192.168.111.32=https://192.168.111.32:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
- 创建配置文件(Master2)
cat > /etc/etcd/etcd.conf <<"EOF"
#[Member]
ETCD_NAME="etcd_192.168.111.31"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.111.31:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.111.31:2379,http://127.0.0.1:2379"
#[clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.111.31:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.111.31:2379"
ETCD_INITIAL_CLUSTER="etcd_192.168.111.30=https://192.168.111.30:2380,etcd_192.168.111.31=https://192.168.111.31:2380,etcd_192.168.111.32=https://192.168.111.32:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
- 创建配置文件(Master3)
cat > /etc/etcd/etcd.conf <<"EOF"
#[Member]
ETCD_NAME="etcd_192.168.111.32"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.111.32:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.111.32:2379,http://127.0.0.1:2379"
#[clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.111.32:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.111.32:2379"
ETCD_INITIAL_CLUSTER="etcd_192.168.111.30=https://192.168.111.30:2380,etcd_192.168.111.31=https://192.168.111.31:2380,etcd_192.168.111.32=https://192.168.111.32:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
4、创建 etcd 服务配置文件
注意:修改/etc/etcd/etcd.conf文件时,要先删除/var/lib/etcd目录下已经存在的数据,再重新启用服务
- 创建配置文件(Master1、Master2、Master3)
cat > /etc/systemd/system/etcd.service << "EOF"
[Unit]
Description=EtcdServer
After=networking.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/certs/etcd/etcd.pem \
--key-file=/etc/certs/etcd/etcd-key.pem \
--trusted-ca-file=/etc/certs/ca/ca.pem \
--client-cert-auth \
--peer-cert-file=/etc/certs/etcd/etcd.pem \
--peer-key-file=/etc/certs/etcd/etcd-key.pem \
--peer-trusted-ca-file=/etc/certs/ca/ca.pem \
--peer-client-cert-auth
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
5、启动 etcd
systemctl daemon-reload # 刷新配置文件并重启(需要先删除/var/lib/etcd目录下已经存在的数据)
systemctl enable --now etcd.service # 开机自启(Mater1、Master2、Master3按顺序同时启动)
systemctl status etcd # systemctl restart etcd
journalctl -xe # 查看启动详情
journalctl -f # 显示实时日志
journalctl -xe -u etcd # 查看日志细节
netstat -tunlp|grep etcd # 查看本机监听端口
netstat -nal #查看接口
6、验证 etcd
- 查看健康状态
ETCDCTL_API=3 /usr/local/bin/etcdctl \
--write-out=table \
--cacert=/etc/certs/ca/ca.pem \
--cert=/etc/certs/etcd/etcd.pem \
--key=/etc/certs/etcd/etcd-key.pem \
--endpoints=https://192.168.111.30:2379,https://192.168.111.31:2379,https://192.168.111.32:2379 endpoint health
- 查看集群列表
ETCDCTL_API=3 /usr/local/bin/etcdctl \
--write-out=table \
--cacert=/etc/certs/ca/ca.pem \
--cert=/etc/certs/etcd/etcd.pem \
--key=/etc/certs/etcd/etcd-key.pem \
--endpoints=https://192.168.111.30:2379,https://192.168.111.31:2379,https://192.168.111.32:2379 member list
- 查看集群状态
ETCDCTL_API=3 /usr/local/bin/etcdctl \
--write-out=table \
--cacert=/etc/certs/ca/ca.pem \
--cert=/etc/certs/etcd/etcd.pem \
--key=/etc/certs/etcd/etcd-key.pem \
--endpoints=https://192.168.111.30:2379,https://192.168.111.31:2379,https://192.168.111.32:2379 endpoint status
- 验证数据库性能
ETCDCTL_API=3 /usr/local/bin/etcdctl \
--write-out=table \
--cacert=/etc/certs/ca/ca.pem \
--cert=/etc/certs/etcd/etcd.pem \
--key=/etc/certs/etcd/etcd-key.pem \
--endpoints=https://192.168.111.30:2379,https://192.168.111.31:2379,https://192.168.111.32:2379 check perf
K8S集群部署
- Master集群组件
部署 kube-apiserver 集群
部署 kubectl 集群
部署 kube-controller-manager 集群
部署 kube-scheduler 集群
- Node 组件
部署 kubelet
部署 kube-proxy
部署 Contrinerd
下载K8S的二进制文件
解压安装包(Mastrer和Node)
cd /home/lixing/k8s && tar -zxvf kubernetes-server-linux-amd64.tar.gz
分发可执行文件(Mastrer和Node)
# 所有Master节点执行
cd /home/lixing/k8s/kubernetes/server/bin && cp kube-apiserver kubectl kube-controller-manager kube-scheduler /usr/local/bin
# 所有Node节点执行
cd /home/lixing/k8s/kubernetes/server/bin && cp kubelet kube-proxy /usr/local/bin
初始化目录(Mastrer和Node)
# 所有Master节点执行
mkdir -p /etc/kubernetes \
mkdir -p /var/log/kubernetes \
mkdir -p /etc/certs/kube-apiserver \
mkdir -p /etc/certs/kubectl \
mkdir -p /etc/certs/kube-controller-manager \
mkdir -p /etc/certs/kube-scheduler \
mkdir -p /etc/certs/kubelet \
mkdir -p /etc/certs/kube-proxy
# 所有Node节点执行
mkdir -p /etc/kubernetes \
mkdir -p /var/log/kubernetes \
mkdir -p /etc/certs/kubelet \
mkdir -p /etc/certs/kube-proxy
安装 kube-apiserver(Master1、Master2、Master3)
1、创建 kube-apiserver 证书
备注1:
Master节点上的 kube-apiserver 启用了TLS认证后,Node节点上的 kubelet 和 kube-proxy 与 kube-apiserver 进行通信时必须使用由 kube-apiserver 签发的CA证书才可以。当Node节点很多时则需要颁发大量的客户端证书,为了简化客户端证书颁发的流程,Kubernetes引入了 TLS Bootstraping 机制来自动颁发客户端证书,kubelet 会以低权限用户自动向 kube-apiserver 动态申请证书
#
备注2:
RBAC中规定了一个用户或者用户组(subject)具有请求哪些 api 的权限,在配合 TLS 加密的时候,实际上 kube-apiserver 读取客户端证书的 CN 字段作为用户名,读取 O 字段作为用户组
- 生成 kube-apiserver 证书请求文件
# 注意:hosts中填写的是则授权使用该证书的 IP(虚拟IP、service 网段开始IP),为了方便后期扩容可以多写几个预留的IP
cat > /etc/certs/kube-apiserver/kube-apiserver-csr.json << EOF
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"192.168.111.30","192.168.111.31","192.168.111.32",
"192.168.111.33","192.168.111.34","192.168.111.100",
"192.168.111.40","192.168.111.41","192.168.111.42","192.168.111.43","192.168.111.44","192.168.111.45","192.168.111.46","192.168.111.47",
"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": "江苏省",
"L": "南京市",
"O": "k8s",
"OU": "system"
}]
}
EOF
- 生成 kube-apiserver 证书
# 注意:-profile=kubernetes关联的是ca-config.json配置文件中profiles中的配置项
cfssl gencert \
-ca=/etc/certs/ca/ca.pem \
-ca-key=/etc/certs/ca/ca-key.pem \
-config=/etc/certs/ca/ca-config.json \
-profile=kubernetes /etc/certs/kube-apiserver/kube-apiserver-csr.json | cfssljson -bare /etc/certs/kube-apiserver/kube-apiserver
kube-apiserver-csr.json: CSR的JSON设定文件
kube-apiserver.csr: 证书签名请求文件
kube-apiserver-key.pem:CA私钥
kube-apiserver.pem: CA证书
- 创建 TLS 机制所需的TOKEN文件
cat > /etc/certs/kube-apiserver/token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
cat /etc/certs/kube-apiserver/token.csv # 查看文件,格式:token,用户名,UID,用户组
- 同步 kube-apiserver 证书以及TOKEN文件到 Master1 和 Master2
默认Master1节点安装成功后,然后下载到本地,再从本地同步到Master2和Master3,如果下载提示没有权限,可以执行:chmod -R 777 /home/lixing 给文件夹赋值权限
3、创建 kube-apiserver 配置文件
- 创建配置文件(Master1)
cat > /etc/kubernetes/kube-apiserver.conf << "EOF"
KUBE_APISERVER_OPTS="
--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--anonymous-auth=false \
--bind-address=192.168.111.30 \
--secure-port=6443 \
--advertise-address=192.168.111.30 \
--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/certs/kube-apiserver/token.csv \
--service-node-port-range=30000-32767 \
--tls-cert-file=/etc/certs/kube-apiserver/kube-apiserver.pem \
--tls-private-key-file=/etc/certs/kube-apiserver/kube-apiserver-key.pem \
--client-ca-file=/etc/certs/ca/ca.pem \
--kubelet-client-certificate=/etc/certs/kube-apiserver/kube-apiserver.pem \
--kubelet-client-key=/etc/certs/kube-apiserver/kube-apiserver-key.pem \
--service-account-key-file=/etc/certs/ca/ca-key.pem \
--service-account-signing-key-file=/etc/certs/ca/ca-key.pem \
--service-account-issuer=api \
--etcd-cafile=/etc/certs/ca/ca.pem \
--etcd-certfile=/etc/certs/etcd/etcd.pem \
--etcd-keyfile=/etc/certs/etcd/etcd-key.pem \
--etcd-servers=https://192.168.111.30:2379,https://192.168.111.31:2379,https://192.168.111.32:2379 \
--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 \
--v=4"
EOF
- 创建配置文件(Master2)
cat > /etc/kubernetes/kube-apiserver.conf << "EOF"
KUBE_APISERVER_OPTS="
--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--anonymous-auth=false \
--bind-address=192.168.111.31 \
--secure-port=6443 \
--advertise-address=192.168.111.31 \
--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/certs/kube-apiserver/token.csv \
--service-node-port-range=30000-32767 \
--tls-cert-file=/etc/certs/kube-apiserver/kube-apiserver.pem \
--tls-private-key-file=/etc/certs/kube-apiserver/kube-apiserver-key.pem \
--client-ca-file=/etc/certs/ca/ca.pem \
--kubelet-client-certificate=/etc/certs/kube-apiserver/kube-apiserver.pem \
--kubelet-client-key=/etc/certs/kube-apiserver/kube-apiserver-key.pem \
--service-account-key-file=/etc/certs/ca/ca-key.pem \
--service-account-signing-key-file=/etc/certs/ca/ca-key.pem \
--service-account-issuer=api \
--etcd-cafile=/etc/certs/ca/ca.pem \
--etcd-certfile=/etc/certs/etcd/etcd.pem \
--etcd-keyfile=/etc/certs/etcd/etcd-key.pem \
--etcd-servers=https://192.168.111.30:2379,https://192.168.111.31:2379,https://192.168.111.32:2379 \
--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 \
--v=4"
EOF
- 创建配置文件(Master3)
cat > /etc/kubernetes/kube-apiserver.conf << "EOF"
KUBE_APISERVER_OPTS="
--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--anonymous-auth=false \
--bind-address=192.168.111.32 \
--secure-port=6443 \
--advertise-address=192.168.111.32 \
--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/certs/kube-apiserver/token.csv \
--service-node-port-range=30000-32767 \
--tls-cert-file=/etc/certs/kube-apiserver/kube-apiserver.pem \
--tls-private-key-file=/etc/certs/kube-apiserver/kube-apiserver-key.pem \
--client-ca-file=/etc/certs/ca/ca.pem \
--kubelet-client-certificate=/etc/certs/kube-apiserver/kube-apiserver.pem \
--kubelet-client-key=/etc/certs/kube-apiserver/kube-apiserver-key.pem \
--service-account-key-file=/etc/certs/ca/ca-key.pem \
--service-account-signing-key-file=/etc/certs/ca/ca-key.pem \
--service-account-issuer=api \
--etcd-cafile=/etc/certs/ca/ca.pem \
--etcd-certfile=/etc/certs/etcd/etcd.pem \
--etcd-keyfile=/etc/certs/etcd/etcd-key.pem \
--etcd-servers=https://192.168.111.30:2379,https://192.168.111.31:2379,https://192.168.111.32:2379 \
--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 \
--v=4"
EOF
4、创建 kube-apiserver 服务配置文件
- 创建配置文件(Master1、Master2、Master3)
cat > /etc/systemd/system/kube-apiserver.service << "EOF"
[Unit]
Description=Kubernetes ApiServer
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
5、启动 kube-apiserver
systemctl daemon-reload # 刷新配置文件
systemctl enable --now kube-apiserver.service # 开机自启
systemctl status kube-apiserver # systemctl restart kube-apiserver
journalctl -xe # 查看启动详情
journalctl -f # 显示实时日志
journalctl -xe -u kube-apiserver # 查看日志细节
netstat -tunlp|grep kube-apiserver # 查看本机监听端口
netstat -nal #查看接口
6、验证 kube-apiserver
https://192.168.111.30:6443
https://192.168.111.31:6443
https://192.168.111.32:6443
#
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}
安装 kubectl 客户端工具(Master1、Master2、Master3)
1、创建 kubectl 证书
- 生成 admin 证书请求文件【由于kubectl相当于系统管理员,所以这里以 admin 命名】
cat > /etc/certs/kubectl/admin-csr.json << EOF
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "CN",
"ST": "江苏省",
"L": "南京市",
"O":"system:masters",
"OU":"system"
}]
}
EOF
- 生成 kubectl 证书
# 注意:-profile=kubernetes关联的是ca-config.json配置文件中profiles中的配置项
cfssl gencert \
-ca=/etc/certs/ca/ca.pem \
-ca-key=/etc/certs/ca/ca-key.pem \
-config=/etc/certs/ca/ca-config.json \
-profile=kubernetes /etc/certs/kubectl/admin-csr.json | cfssljson -bare /etc/certs/kubectl/admin
admin-csr.json: CSR的JSON设定文件
admin.csr: 证书签名请求文件
admin-key.pem:CA私钥
admin.pem: CA证书
- 同步 kubectl 证书到 Master1 和 Master2
提示:Master1节点安装证书成功后,然后下载到本地,再从本地同步到Master2和Master3,如果下载提示没有权限,可以执行:chmod -R 777 /home/lixing 给文件夹赋值权限
2、创建 kubectl 的 kubeconfig 配置文件
- 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/certs/ca/ca.pem \
--embed-certs=true \
--server=https://192.168.111.100:6443 \
--kubeconfig=/etc/kubernetes/kube.config
- 设置客户端认证参数
kubectl config set-credentials admin \
--client-certificate=/etc/certs/kubectl/admin.pem \
--client-key=/etc/certs/kubectl/admin-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/kube.config
- 设置上下文参数
kubectl config set-context kubernetes --cluster=kubernetes --user=admin --kubeconfig=/etc/kubernetes/kube.config
- 设置默认上下文
kubectl config use-context kubernetes --kubeconfig=/etc/kubernetes/kube.config
- 准备 kubectl 配置文件并进行角色绑定
# mkdir -p $HOME/.kube # root用户执行会创建/root/.kube、普通用户执行会创建/home/用户名/.kube
# cd /etc/kubernetes && cp ./admin.kubeconfig $HOME/.kube/config # 复制admin.kubeconfig到相关目录下的config
# chown $(id -u):$(id -g) $HOME/.kube/config # 修改文件的权限,export KUBECONFIG = $HOME/.kube/config
# kubeconfig是为访问K8S集群所作的配置。kubectl默认会从 $HOME/.kube 目录下查找文件名为 config 的文件
mkdir ~/.kube && cp -rf /etc/kubernetes/kube.config ~/.kube/config
# 授权 kubernetes证书(kube-apiserver证书) 访问 kubelet api 权限
kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes --kubeconfig=/root/.kube/config
3、查看集群状态
kubectl cluster-info # 查看集群信息
kubectl get componentstatuses # 查看集群组件状态
kubectl get all --all-namespaces # 查看命名空间中资源对象
安装 kube-controller-manager(Master1、Master2、Master3)
1、创建 kube-controller-manager 证书
- 生成 kube-controller-manager 证书请求文件
cat > /etc/certs/kube-controller-manager/kube-controller-manager-csr.json << EOF
{
"CN": "system:kube-controller-manager",
"hosts": [
"127.0.0.1",
"192.168.111.30","192.168.111.31","192.168.111.32"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "CN",
"ST": "江苏省",
"L": "南京市",
"O":"system:kube-controller-manager",
"OU":"system"
}]
}
EOF
- 生成 kube-controller-manager 证书
# -profile=kubernetes关联的是ca-config.json配置文件中profiles中的配置项
cfssl gencert \
-ca=/etc/certs/ca/ca.pem \
-ca-key=/etc/certs/ca/ca-key.pem \
-config=/etc/certs/ca/ca-config.json \
-profile=kubernetes /etc/certs/kube-controller-manager/kube-controller-manager-csr.json | cfssljson \
-bare /etc/certs/kube-controller-manager/kube-controller-manager
kube-controller-manager-csr.json: CSR的JSON设定文件
kube-controller-manager.csr: 证书签名请求文件
kube-controller-manager-key.pem:CA私钥
kube-controller-manager.pem: CA证书
- 同步 kube-controller-manager 证书到 Master1 和 Master2
提示:Master1节点安装证书成功后,然后下载到本地,再从本地同步到Master2和Master3,如果下载提示没有权限,可以执行:chmod -R 777 /home/lixing 给文件夹赋值权限
2、创建 kube-controller-manager的 kubeconfig 配置文件
- 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/certs/ca/ca.pem \
--embed-certs=true \
--server=https://192.168.111.100:6443 \
--kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig
- 设置客户端认证参数
kubectl config set-credentials system:kube-controller-manager \
--client-certificate=/etc/certs/kube-controller-manager/kube-controller-manager.pem \
--client-key=/etc/certs/kube-controller-manager/kube-controller-manager-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig
- 设置上下文参数
kubectl config set-context system:kube-controller-manager --cluster=kubernetes --user=system:kube-controller-manager --kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig
- 设置默认上下文
kubectl config use-context system:kube-controller-manager --kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig
3、创建 kube-controller-manager 配置文件
cat > /etc/kubernetes/kube-controller-manager.conf << "EOF"
KUBE_CONTROLLER_MANAGER_OPTS="
--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/certs/ca/ca.pem \
--cluster-signing-key-file=/etc/certs/ca/ca-key.pem \
--allocate-node-cidrs=true \
--cluster-cidr=10.244.0.0/16 \
--root-ca-file=/etc/certs/ca/ca.pem \
--service-account-private-key-file=/etc/certs/ca/ca-key.pem \
--leader-elect=true \
--feature-gates=RotateKubeletServerCertificate=true \
--controllers=*,bootstrapsigner,tokencleaner \
--horizontal-pod-autoscaler-sync-period=10s \
--tls-cert-file=/etc/certs/kube-controller-manager/kube-controller-manager.pem \
--tls-private-key-file=/etc/certs/kube-controller-manager/kube-controller-manager-key.pem \
--use-service-account-credentials=true \
--v=2"
EOF
4、创建 kube-controller-manager 服务配置文件
cat > /etc/systemd/system/kube-controller-manager.service << "EOF"
[Unit]
Description=Kubernetes ControllerManager
[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、启动 kube-controller-manager
systemctl daemon-reload # 刷新配置文件
systemctl enable --now kube-controller-manager # 开机自启
systemctl status kube-controller-manager # systemctl restart kube-controller-manager
6、查看集群组件状态
kubectl get componentstatuses # 查看集群组件状态
安装 kube-scheduler(Master1、Master2、Master3)
1、创建 kube-scheduler 证书
- 生成 kube-scheduler 证书请求文件
cat > /etc/certs/kube-scheduler/kube-scheduler-csr.json << EOF
{
"CN": "system:kube-scheduler",
"hosts": [
"127.0.0.1",
"192.168.111.30","192.168.111.31","192.168.111.32"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "CN",
"ST": "江苏省",
"L": "南京市",
"O":"system:kube-scheduler",
"OU":"system"
}]
}
EOF
- 生成 kube-scheduler 证书
# -profile=kubernetes关联的是ca-config.json配置文件中profiles中的配置项
cfssl gencert \
-ca=/etc/certs/ca/ca.pem \
-ca-key=/etc/certs/ca/ca-key.pem \
-config=/etc/certs/ca/ca-config.json \
-profile=kubernetes /etc/certs/kube-scheduler/kube-scheduler-csr.json | cfssljson \
-bare /etc/certs/kube-scheduler/kube-scheduler
kube-scheduler-csr.json: CSR的JSON设定文件
kube-scheduler.csr: 证书签名请求文件
kube-scheduler-key.pem:CA私钥
kube-scheduler.pem: CA证书
- 同步 kubectl 证书到 Master1 和 Master2
提示:Master1节点安装证书成功后,然后下载到本地,再从本地同步到Master2和Master3,如果下载提示没有权限,可以执行:chmod -R 777 /home/lixing 给文件夹赋值权限
2、创建 kube-scheduler 的 kubeconfig 配置文件
- 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/certs/ca/ca.pem \
--embed-certs=true \
--server=https://192.168.111.100:6443 \
--kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig
- 设置客户端认证参数
kubectl config set-credentials system:kube-scheduler \
--client-certificate=/etc/certs/kube-scheduler/kube-scheduler.pem \
--client-key=/etc/certs/kube-scheduler/kube-scheduler-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig
- 设置上下文参数
kubectl config set-context system:kube-scheduler --cluster=kubernetes --user=system:kube-scheduler --kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig
- 置默认上下文
kubectl config use-context system:kube-scheduler --kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig
3、创建 kube-scheduler 配置文件
cat > /etc/kubernetes/kube-scheduler.conf << "EOF"
KUBE_SCHEDULER_OPTS="
--bind-address=127.0.0.1 \
--kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
--leader-elect=true \
--v=2"
EOF
4、创建 kube-scheduler 服务配置文件
cat > /etc/systemd/system/kube-scheduler.service << "EOF"
[Unit]
Description=Kubernetes Scheduler
[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、启动 kube-scheduler
systemctl daemon-reload # 刷新配置文件
systemctl enable --now kube-scheduler # 开机自启
systemctl status kube-scheduler # systemctl restart kube-scheduler
6、查看集群组件状态
kubectl get componentstatuses # 查看集群组件状态
部署 Node 节点
安装 kubelet
- kubelet 定期调用 ApiServer 报告自身状态, ApiServer 接收信息后将节点状态信息更新到 etcd 中
- kubelet 调用 ApiServer 监听 Pod信息,从而对当前 Node 上的 POD 进行管理(创建、删除、更新)
1、创建 kubelet-bootstrap.kubeconfig 配置文件(Master1节点操作)
- 获取Master节点中的 token.csv 中的 token
# cat /opt/certs/kube-apiserver/token.csv # 56b4e09d22b5f4c31520d6459bcbe81c
BOOTSTRAP_TOKEN=$(awk -F "," '{print $1}' /etc/certs/kube-apiserver/token.csv) && echo $BOOTSTRAP_TOKEN
- 设置访问集群的证书
kubectl config set-cluster kubernetes --certificate-authority=/etc/certs/ca/ca.pem --embed-certs=true --server=https://192.168.111.100:6443 --kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig
- 设置客户端认证参数
kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig
- 设置上下文参数
kubectl config set-context default --cluster=kubernetes --user=kubelet-bootstrap --kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig
- 设置默认上下文
kubectl config use-context default --kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig
- 创建 kubelet-bootstrap 的角色绑定
# kubectl delete clusterrolebinding kubelet-bootstrap
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
# kubectl describe clusterrolebinding kubelet-bootstrap # 验证 kubelet-bootstrap 角色绑定信息
-
同步 kubelet-bootstrap.kubeconfig 文件到 Node 节点
提示:Master1节点创建成功后,然后下载到本地,再从本地同步到Node节点,如果下载提示没有权限,可以执行:chmod -R 777 /home/lixing 给文件夹赋值权限 -
同步 ca 文件到 Node 节点
提示:Master1节点创建成功后,然后下载到本地,再从本地同步到Node节点,如果下载提示没有权限,可以执行:chmod -R 777 /home/lixing 给文件夹赋值权限
2、创建 kubelet.json 配置文件
- 同步 Master 节点的ca证书到 Node 节点
mkdir -p /etc/certs/ca
- Node节点(注意:每个Node节点配置不一样)
cat > /etc/kubernetes/kubelet.json << "EOF"
{
"apiVersion":"kubelet.config.k8s.io/v1beta1",
"kind":"KubeletConfiguration",
"authentication": {
"x509": {
"clientCAFile": "/etc/certs/ca/ca.pem"
},
"webhook": {
"enabled": true,
"cacheTTL": "2m0s"
},
"anonymous": {
"enabled": false
}
},
"authorization": {
"mode": "Webhook",
"webhook": {
"cacheAuthorizedTTL": "5m0s",
"cacheUnauthorizedTTL": "30s"
}
},
"address": "192.168.111.40",
"port": 10250,
"readonlyPort": 10255,
"cgroupDriver": "systemd",
"hairpinMode": "promiscuous-bridge",
"featureGates": {
"RotateKubeletServerCertificate": true
},
"clusterDomain":"cluster.local.",
"clusterDNS": ["10.96.0.2"],
"enableServer": true
}
EOF
3、创建 kubelet 服务启动文件
kubelet --help # 查询启动参数配置项
mkdir -p /var/lib/kubelet
cat > /etc/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
After=containerd.service
Requires=containerd.service
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/usr/local/bin/kubelet \
--cert-dir=/etc/certs/ca \
--bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig \
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
--config=/etc/kubernetes/kubelet.json \
--container-runtime-endpoint=unix:///run/containerd/containerd.sock \
--root-dir=/etc/cni/net.d \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
4、设置开机自启
systemctl daemon-reload && systemctl enable --now kubelet && systemctl status kubelet
journalctl -xe # 查看启动详情
journalctl -f # 显示实时日志
journalctl -xe -u kubelet # 查看日志细节
netstat -tunlp|grep kubelet # 查看本机监听端口
netstat -nal #查看接口
- master 节点审批 node 节点的请求
注意:node 节点上的 kubelet 启动成功后,会向 master 节点申请 csr 证书,所以需要在 master 节点上同意申请,这样 Node 节点才能连接到 Master 节点上
kubectl get csr # 查看csr状态,默认会生成一个申请记录,默认状态为待审核
kubectl certificate approve node-csr-xxx # 审批请求
- 查看 Node 节点的相关文件
安装kube-proxy
- 为 Pod 创建网络代理和负载均衡,从 apiserver 获取所有 service 信息,并根据 service 信息创建代理服务,实现 service 到 Pod 的请求路由和转发
1、创建 kube-proxy 证书(Master1节点操作)
- 生成 kube-proxy 证书请求文件
cat > /etc/certs/kube-proxy/kube-proxy-csr.json << EOF
{
"CN": "system:kube-proxy",
"key": { "algo": "rsa", "size": 2048},
"names": [{"C": "CN","ST": "江苏省","L": "南京市","O": "公司名称","k8s": "system"}]
}
EOF
- 生成 kube-proxy 证书
cfssl gencert \
-ca=/etc/certs/ca/ca.pem \
-ca-key=/etc/certs/ca/ca-key.pem \
-config=/etc/certs/ca/ca-config.json \
-profile=kubernetes /etc/certs/kube-proxy/kube-proxy-csr.json | cfssljson -bare /etc/certs/kube-proxy/kube-proxy
kube-proxy-csr.json: CSR的JSON设定文件
kube-proxy.csr: 证书签名请求文件
kube-proxy-key.pem:CA私钥
kube-proxy.pem: CA证书
- 同步 kube-proxy 证书到 Node 节点
提示:Master1节点创建成功后,然后下载到本地,再从本地同步到Node节点,如果下载提示没有权限,可以执行:chmod -R 777 /home/lixing 给文件夹赋值权限
2、创建 kube-proxy 的 kubeconfig 配置文件(Master1节点执行)
kubectl config set-cluster kubernetes --certificate-authority=/etc/certs/ca/ca.pem --embed-certs=true \
--server=https://192.168.111.100:6443 --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy \
--client-certificate=/etc/certs/kube-proxy/kube-proxy.pem \
--client-key=/etc/certs/kube-proxy/kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
kubectl config set-context default --cluster=kubernetes --user=kube-proxy --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
kubectl config use-context default --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
- 同步 kube-proxy 的 kubeconfig 配置文件到 Node 节点
提示:Master1节点创建成功后,然后下载到本地,再从本地同步到Node节点,如果下载提示没有权限,可以执行:chmod -R 777 /home/lixing 给文件夹赋值权限
3、创建 kube-proxy 服务配置文件
- Node节点(注意:每个Node节点配置都不一样)
cat > /etc/kubernetes/kube-proxy.yaml << "EOF"
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 192.168.111.40
clientConnection:
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
clusterCIDR: 192.168.111.0/24
healthzBindAddress: 192.168.111.40:10256
kind: KubeProxyConfiguration
metricsBindAddress: 192.168.111.40:10249
mode: "ipvs"
EOF
4、创建 kube-proxy 服务启动文件
kube-proxy --help
mkdir -p /var/lib/kube-proxy
cat > /etc/systemd/system/kube-proxy.service << "EOF"
[Unit]
Description=Kubernetes KubeProxyService
After=network.target
[Service]
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/usr/local/bin/kube-proxy \
--config=/etc/kubernetes/kube-proxy.yaml \
--v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
5、设置开机自启
systemctl daemon-reload && systemctl enable --now kube-proxy && systemctl status kube-proxy
journalctl -xe # 查看启动详情
journalctl -f # 显示实时日志
journalctl -xe -u kube-proxy # 查看日志细节
netstat -tunlp|grep kube-proxy # 查看本机监听端口
netstat -nal #查看接口
6、查看k8s集群节点
kubectl get nodes -o wide
没有安装CNI网络插件,安装即可
部署 网络插件(Calico)(Master1节点安装)
-
为了实现Pod网络而需要的插件,由于Kubernetes通过开放的CNI(Container Network Interface,容器网络接口)接口来允许插件的接入,又称之为CNI网络插件【解决容器跨主机通信问题,使跨主机间运行的Pod位于同一个网络平面】
-
Calico是一款广泛采用、久经考验的开源网络和网络安全解决方案,适用于Kubernetes、虚拟机和裸机工作负载。与Flannel对比,Calico除了支持基本网络功能的实现之外,它还支持全套Kubernetes网络策略功能,以及在其之上扩展网络策略
-
首次安装只需要在Master节点即可,后期为Master节点添加Node成功后,会自动在相应的Node节点上安装Calico
1、配置NetworkManager
如果主机系统使用NetworkManager来管理网络的话,则需要配置NetworkManager,以允许Calico管理接口。NetworkManger操作默认网络命名空间接口的路由表,这可能会干扰Calico代理正确路由的能力
systemctl status NetworkManager #查看NetworkManager 状态
#systemctl stop NetworkManager # 关闭 NetworkManager
#systemctl disable NetworkManager # enabl表示开机自启 disable表示开启不启动
# 如果存在 NetworkManager 则需要再所有节点上进行配置
vi /etc/NetworkManager/conf.d/calico.conf # 编辑配置文件,添加以下内容:
[keyfile]
unmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:vxlan-v6.calico;interface-name:wireguard.cali;interface-name:wg-v6.cali
2、查询最新版本与K8S版本的对照表
https://docs.tigera.io/calico/latest/getting-started/kubernetes/requirements
3、安装
https://docs.tigera.io/calico/latest/getting-started/kubernetes/self-managed-onprem/onpremises
- 下载文件地址
curl https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/calico-typha.yaml -o /etc/kubernetes/calico.yaml
- 自定义 calico.yaml 文件
# 默认的calico.yaml清单文件无需手动配置Pod子网范围(如果需要可通过 CALICO_IPV4POOL_CIDR 指定)
# 开启 - name: CALICO_IPV4POOL_CIDR 配置,配置其 value为:10.244.0.0/16【pod网段】
- 安装
kubectl delete -f /etc/kubernetes/calico.yaml # 卸载calico
kubectl apply -f /etc/kubernetes/calico.yaml # 安装calico
4、查看 kube-system 空间下的资源
kubectl get deployment,pods,service -n kube-system -o wide
# kubectl describe -n kube-system pod [podName]
kubectl describe -n kube-system pod calico-xx
# kubectl logs -n kube-system [podName]
kubectl logs -n kube-system calico-xx
# kubectl delete -n kube-system pod [podName] --force --grace-period=0 # 强制删除pod
kubectl delete -n kube-system pod calico-xx --force --grace-period=0
5、查看k8s集群节点
kubectl get nodes -o wide
部署 负载插件(CoreDNS)(Master1节点安装)
- 与 Kubernetes 一样,CoreDNS 项目由 CNCF 托管,是一个灵活可扩展的 DNS 服务器,可以作为 Kubernetes 集群 DNS
- CoreDNS 是 Golang 编写的一个插件式 DNS 服务器,Kubernetes 1.13 后所内置的默认 DNS 服务器
- CoreDNS 在K8S中主要用作服务发现,为Node中的Pod提供域名解析,实现通过域名访问Service
K8S官方文档
手动部署或替换 kube-dns,请参阅 CoreDNS GitHub 项目
1、手动下载并命名为 coredns.yaml
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/coredns
2、修改 coredns.yaml 文件
修改 k8s 集群后缀名称
__DNS__DOMAIN__ 替换为 cluster.local
修改 pod 启动内存限制大小
__DNS__MEMORY__LIMIT__ 替换为 300Mi
修改 coredns 的 svcIP 地址
一般为 Service网段 的第二位,当前Service网段配置为10.96.0.0/16
__DNS__SERVER__ 替换为 10.96.0.2
修改镜像地址
# registry.k8s.io国内无法访问的,去掉 registry.k8s.io/ 后,默认会从docker仓库拉取
image: registry.k8s.io/coredns/coredns:v1.10.1 替换为 image: coredns/coredns:1.10.1
3、安装
kubectl delete -f /etc/kubernetes/coredns.yaml
kubectl apply -f /etc/kubernetes/coredns.yaml
4、查看 kube-system 空间下的资源
kubectl get deployment,pods,service -n kube-system -o wide
# kubectl describe -n kube-system pod [podName]
kubectl describe -n kube-system pod coredns-xx
# kubectl logs -n kube-system [podName]
kubectl logs -n kube-system coredns-xx
# kubectl delete -n kube-system pod [podName] --force --grace-period=0 # 强制删除pod
kubectl delete -n kube-system pod coredns-xx --force --grace-period=0