1. k8s+containerd部署方式
通常使用 kubeadm 部署和二进制方式部署,他们之间的区别:
- kubeadm 方式部署,组件容器化部署,只有 kubelet 没有被容器化
- 二进制方式部署,传统的守护进程(systemd)管理服务 systemctl
目前生产环境部署kubernetes集群主要由两种方式:
- kubeadm:
kubeadm是一个K8S部署工具,提供kubeadm init和kubeadm join,用于快速部署kubernetes集群。
- 二进制部署:
从GitHub下载发行版的二进制包,手动部署每个组件,组成kubernetes集群。
除了上述介绍的两种方式部署外,还有其他部署方式的途径:
- yum:
已废弃,目前支持的最新版本为2017年发行的1.5.2版本。
- minikube:
适合开发环境,能够快速在Windows或者Linux构建K8S集群。
参考链接:
https://minikube.sigs.k8s.io/docs/
- rancher:
基于K8S改进发行了轻量级K8S,让K3S孕育而生。
参考链接:
https://www.rancher.com/
- KubeSphere:
青云科技基于开源KubeSphere快速部署K8S集群。
参考链接:
https://kubesphere.com.cn
- kuboard:
也是对k8s进行二次开发的产品,新增了很多独有的功能。
参考链接:
https://kuboard.cn/
- kubeasz:
使用ansible部署,扩容,缩容kubernetes集群,安装步骤官方文档已经非常详细了。
参考链接:
https://github.com/easzlab/kubeasz/
- 第三方云厂商:
比如aws,阿里云,腾讯云,京东云等云厂商均有K8S的相关SAAS产品。
- 更多的第三方部署工具:
参考链接:
https://landscape.cncf.io/
目前生产环境部署kubernetes集群主要由两种方式:
- kubeadm:
kubeadm是一个K8S部署工具,提供kubeadm init和kubeadm join,用于快速部署kubernetes集群。
- 二进制部署:
从GitHub下载发行版的二进制包,手动部署每个组件,组成kubernetes集群。
除了上述介绍的两种方式部署外,还有其他部署方式的途径:
- yum:
已废弃,目前支持的最新版本为2017年发行的1.5.2版本。
- minikube:
适合开发环境,能够快速在Windows或者Linux构建K8S集群。
参考链接:
https://minikube.sigs.k8s.io/docs/
- rancher:
基于K8S改进发行了轻量级K8S,让K3S孕育而生。
参考链接:
https://www.rancher.com/
- KubeSphere:
青云科技基于开源KubeSphere快速部署K8S集群。
参考链接:
https://kubesphere.com.cn
- kuboard:
也是对k8s进行二次开发的产品,新增了很多独有的功能。
参考链接:
https://kuboard.cn/
- kubeasz:
使用ansible部署,扩容,缩容kubernetes集群,安装步骤官方文档已经非常详细了。
参考链接:
https://github.com/easzlab/kubeasz/
- 第三方云厂商:
比如aws,阿里云,腾讯云,京东云等云厂商均有K8S的相关SAAS产品。
- 更多的第三方部署工具:
参考链接:
https://landscape.cncf.io/
2. k8s部署规划
2.1 集群模式
1. nginx
2. haproxy+keepalived
1.所有节点(k8s-master)安装keepalived和haproxy
yum -y install keepalived haproxy
yum -y install keepalived haproxy
2.所有节点(k8s-master)配置haproxy,配置文件各个节点相同
(1)备份配置文件
cp /etc/haproxy/haproxy.cfg{,`date +%F`}
(2)所有节点的配置文件内容相同
cat > /etc/haproxy/haproxy.cfg <<'EOF'
global
maxconn 2000
ulimit-n 16384
log 127.0.0.1 local0 err
stats timeout 30s
defaults
log global
mode http
option httplog
timeout connect 5000
timeout client 50000
timeout server 50000
timeout http-request 15s
timeout http-keep-alive 15s
frontend monitor-in
bind *:33305
mode http
option httplog
monitor-uri /monitor
frontend k8s-master
bind 0.0.0.0:16443
bind 127.0.0.1:16443
mode tcp
option tcplog
tcp-request inspect-delay 5s
default_backend k8s-master
backend k8s-master
mode tcp
option tcplog
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
server k8s-master01 10.0.0.201:6443 check
server k8s-master02 10.0.0.202:6443 check
server k8s-master03 10.0.0.203:6443 check
EOF
(1)备份配置文件
cp /etc/haproxy/haproxy.cfg{,`date +%F`}
(2)所有节点的配置文件内容相同
cat > /etc/haproxy/haproxy.cfg <<'EOF'
global
maxconn 2000
ulimit-n 16384
log 127.0.0.1 local0 err
stats timeout 30s
defaults
log global
mode http
option httplog
timeout connect 5000
timeout client 50000
timeout server 50000
timeout http-request 15s
timeout http-keep-alive 15s
frontend monitor-in
bind *:33305
mode http
option httplog
monitor-uri /monitor
frontend k8s-master
bind 0.0.0.0:16443
bind 127.0.0.1:16443
mode tcp
option tcplog
tcp-request inspect-delay 5s
default_backend k8s-master
backend k8s-master
mode tcp
option tcplog
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
server k8s-master01 10.0.0.201:6443 check
server k8s-master02 10.0.0.202:6443 check
server k8s-master03 10.0.0.203:6443 check
EOF
3.所有节点(k8s-master)配置keepalived,配置文件各节点不同
(1)备份配置文件
cp /etc/keepalived/keepalived.conf{,`date +%F`}
(2)"k8s-master01"节点创建配置文件
cat > /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
script_user root
enable_script_security
}
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 5
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface ens33
mcast_src_ip 10.0.0.201
virtual_router_id 51
priority 101
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
10.0.0.250
}
track_script {
chk_apiserver
}
}
EOF
(3)"k8s-master02"节点创建配置文件
cat > /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
script_user root
enable_script_security
}
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 5
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface ens33
mcast_src_ip 10.0.0.202
virtual_router_id 51
priority 101
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
10.0.0.250
}
track_script {
chk_apiserver
}
}
EOF
(4)"k8s-master03"节点创建配置文件
cat > /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
script_user root
enable_script_security
}
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 5
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface ens33
mcast_src_ip 10.0.0.203
virtual_router_id 51
priority 101
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
10.0.0.250
}
track_script {
chk_apiserver
}
}
EOF
(1)备份配置文件
cp /etc/keepalived/keepalived.conf{,`date +%F`}
(2)"k8s-master01"节点创建配置文件
cat > /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
script_user root
enable_script_security
}
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 5
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface ens33
mcast_src_ip 10.0.0.201
virtual_router_id 51
priority 101
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
10.0.0.250
}
track_script {
chk_apiserver
}
}
EOF
(3)"k8s-master02"节点创建配置文件
cat > /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
script_user root
enable_script_security
}
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 5
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface ens33
mcast_src_ip 10.0.0.202
virtual_router_id 51
priority 101
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
10.0.0.250
}
track_script {
chk_apiserver
}
}
EOF
(4)"k8s-master03"节点创建配置文件
cat > /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
script_user root
enable_script_security
}
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 5
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface ens33
mcast_src_ip 10.0.0.203
virtual_router_id 51
priority 101
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
10.0.0.250
}
track_script {
chk_apiserver
}
}
EOF
4.所有节点(k8s-master)配置KeepAlived健康检查文件
(1)创建检查脚本
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 keepalived"
/usr/bin/systemctl stop keepalived
exit 1
else
exit 0
fi
EOF
(2)添加执行权限
chmod +x /etc/keepalived/check_apiserver.sh
(1)创建检查脚本
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 keepalived"
/usr/bin/systemctl stop keepalived
exit 1
else
exit 0
fi
EOF
(2)添加执行权限
chmod +x /etc/keepalived/check_apiserver.sh
❌ 注意
1.我们通过KeepAlived虚拟出来一个VIP,VIP会配置到一个master节点上面,它会通过haproxy暴露的16443的端口反向代理到我们的三个master节点上面,所以我们可以通过VIP的地址加上16443访问到我们的API server;
2.健康检查会检查haproxy的状态,三次失败就会将KeepAlived停掉,停掉之后KeepAlived会跳到其他的节点;
- 启动服务
1.启动harproxy
systemctl daemon-reload
systemctl enable --now haproxy
2.启动keepalived
systemctl enable --now keepalived
2.查看VIP
ip a
1.启动harproxy
systemctl daemon-reload
systemctl enable --now haproxy
2.启动keepalived
systemctl enable --now keepalived
2.查看VIP
ip a
3.云厂商用nlb,elb
如果在云上安装K8S则无安装高可用组件了,毕竟公有云大部分都是不支持keepalived的,可以直接使用云产品,比如阿里的"SLB",腾讯的"ELB"等SAAS产品;
推荐使用ELB,SLB有回环的问题,也就是SLB代理的服务器不能反向访问SLB,但是腾讯云修复了这个问题;
2.2 资源
生产环境中,建议使用小版本大于5的Kubernetes版本,比如1.19.5以后的才可用于生产环境
vm 环境,规划如下:
k8s 集群角色 | ip 地址 | hostname 主机名称 | 资源规格 | 操作系统 | 安装组件 |
---|---|---|---|---|---|
master | kube-master-01 | 2x4g/60g | Rocklinux9.4 | containerd,nerdctl,etcd ,apiserver,controller-manager,scheduler,kubectl,kubelet,kube-proxy,calico | |
work-node | kube-node-01 | 2x4g/60g | Rocklinux9.4 | containerd,etcd ,nerdctl,kubelet,kube-proxy,calico | |
work-node | kube-node-02 | 2x4g/60g | Rocklinux9.4 | containerd,etcd ,nerdctl,kubelet,kube-proxy,calico |
etcd节省资源,在master,work进行安装,线上环境单独安装
2.3 Ip分配
主机名 | ip地址 |
---|---|
slb | 10.103.236.236 |
kubeadm-master | 10.103.236.150 |
kubeadm-node01 | 10.103.236.151 |
kubeadm-node02 | 10.103.236.152 |
pod网段 | 172.16.0.0/12 |
service网段 | 192.168.0.0/16 |
host网段 | 10.103.236.0/12 |
2.4 下载
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.29.md
#查看最新版本
curl -Ls https://dl.k8s.io/release/stable.txt
#查看最新版本
curl -Ls https://dl.k8s.io/release/stable.txt
软件名字 | 版本 |
---|---|
kubernetes-server | v1.29.7 |
containerd | v1.7.22 |
etcd | v3.5.12 |
cfssl | v1.6.5 |
cfssljson | v1.6.5 |
wget https://dl.k8s.io/v1.29.7/kubernetes-server-linux-amd64.tar.gz
wget https://github.com/containerd/containerd/releases/download/v1.7.22/cri-containerd-cni-1.7.22-linux-amd64.tar.gz
wget https://github.com/etcd-io/etcd/releases/download/v3.5.12/etcd-v3.5.12-linux-amd64.tar.gz
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl_1.6.5_linux_amd64 -O /usr/local/bin/cfssl
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssljson_1.6.5_linux_amd64 -O /usr/local/bin/cfssljson
wget https://dl.k8s.io/v1.29.7/kubernetes-server-linux-amd64.tar.gz
wget https://github.com/containerd/containerd/releases/download/v1.7.22/cri-containerd-cni-1.7.22-linux-amd64.tar.gz
wget https://github.com/etcd-io/etcd/releases/download/v3.5.12/etcd-v3.5.12-linux-amd64.tar.gz
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl_1.6.5_linux_amd64 -O /usr/local/bin/cfssl
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssljson_1.6.5_linux_amd64 -O /usr/local/bin/cfssljson
3. 部署
3.1 containerd部署-所有节点
#解压
tar zxvf cri-containerd-cni-1.7.22-linux-amd64.tar.gz -C /
#解压
tar zxvf cri-containerd-cni-1.7.22-linux-amd64.tar.gz -C /
- 生成containerd配置文件
mkdir /etc/containerd/
containerd config default | tee /etc/containerd/config.toml
vim config.toml
...
SystemdCgroup = false #修改为true
...
再修改/etc/containerd/config.toml中的
[plugins."io.containerd.grpc.v1.cri"]
...
# sandbox_image = "k8s.gcr.io/pause:3.6"
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9" #这里一定要注意,要根据下载到本地 pause镜像的版本来进行修改,否则初始化会过不去。
再修改,默认是io.containerd.runc.v2,否则crictl 无法连接containerd
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runtime.v1.linux
mkdir /etc/containerd/
containerd config default | tee /etc/containerd/config.toml
vim config.toml
...
SystemdCgroup = false #修改为true
...
再修改/etc/containerd/config.toml中的
[plugins."io.containerd.grpc.v1.cri"]
...
# sandbox_image = "k8s.gcr.io/pause:3.6"
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9" #这里一定要注意,要根据下载到本地 pause镜像的版本来进行修改,否则初始化会过不去。
再修改,默认是io.containerd.runc.v2,否则crictl 无法连接containerd
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runtime.v1.linux
或者用sed修改
sed -ri -e 's/(.*SystemdCgroup = ).*/\1true/' -e 's@(.*sandbox_image = ).*@\1\"registry.aliyuncs.com/google_containers/pause:3.9\"@' /etc/containerd/config.toml
# 命令直接修改, SystemdCgroup : false -> true
sed -i '/SystemdCgroup/s/false/true/' /etc/containerd/config.toml
#镜像加速,也可以不修改
sed -i "s#config_path\ \=\ \"\"#config_path\ \=\ \"/etc/containerd/certs.d\"#g" /etc/containerd/config.toml
sed -ri -e 's/(.*SystemdCgroup = ).*/\1true/' -e 's@(.*sandbox_image = ).*@\1\"registry.aliyuncs.com/google_containers/pause:3.9\"@' /etc/containerd/config.toml
# 命令直接修改, SystemdCgroup : false -> true
sed -i '/SystemdCgroup/s/false/true/' /etc/containerd/config.toml
#镜像加速,也可以不修改
sed -i "s#config_path\ \=\ \"\"#config_path\ \=\ \"/etc/containerd/certs.d\"#g" /etc/containerd/config.toml
- 启动containerd服务
# 重新加载Unit file
systemctl daemon-reload
#开机启动,并启动服务
systemctl enable --now containerd
# 重新加载Unit file
systemctl daemon-reload
#开机启动,并启动服务
systemctl enable --now containerd
- 节点配置crictl客户端连接的运行时位置
cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
❌ 注意
由于containerd,桥接默认启动分配的网络是10.4.0.0/24,按需进行修改
- 验证crictl连通性
crictl -r unix:///var/run/containerd/containerd.sock info
或者
[root@kube-master-01 ~]# crictl version
Version: 0.1.0
RuntimeName: containerd
RuntimeVersion: v1.7.22
RuntimeApiVersion: v1
crictl -r unix:///var/run/containerd/containerd.sock info
或者
[root@kube-master-01 ~]# crictl version
Version: 0.1.0
RuntimeName: containerd
RuntimeVersion: v1.7.22
RuntimeApiVersion: v1
如果没有这个工具,下载方式
VERSION="1.29.0"
3.2 部署buildkit-所有节点
- 解压
tar zxvf nerdctl-full-1.7.7-linux-amd64.tar.gz -C /usr/local/
tar zxvf nerdctl-full-1.7.7-linux-amd64.tar.gz -C /usr/local/
- 配置systemd文件
cp /usr/local/lib/systemd/system/buildkit.service /etc/systemd/system/buildkitd.service
cp /usr/local/lib/systemd/system/buildkit.service /etc/systemd/system/buildkitd.service
- 配置内核参数,否则nerdctl执行命令会提示警告
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
sysctl -p
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
sysctl -p
- 启动服务
# 重新加载Unit file
systemctl daemon-reload
#开机启动,并启动服务
systemctl enable --now buildkit
# 重新加载Unit file
systemctl daemon-reload
#开机启动,并启动服务
systemctl enable --now buildkit
3.3 部署nerdctl-所有节点
看3.2环节
- 验证
[root@kube-node-01 ~]# nerdctl info
Client:
Namespace: default
Debug Mode: false
Server:
Server Version: v1.7.22
Storage Driver: overlayfs
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Log: fluentd journald json-file syslog
Storage: native overlayfs
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 5.14.0-427.33.1.el9_4.x86_64
Operating System: Rocky Linux 9.4 (Blue Onyx)
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.543GiB
Name: kube-node-01
ID: c8f2114c-e5a8-4e14-a8f2-af9f6ca67ba5
[root@kube-node-01 ~]# nerdctl info
Client:
Namespace: default
Debug Mode: false
Server:
Server Version: v1.7.22
Storage Driver: overlayfs
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Log: fluentd journald json-file syslog
Storage: native overlayfs
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 5.14.0-427.33.1.el9_4.x86_64
Operating System: Rocky Linux 9.4 (Blue Onyx)
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.543GiB
Name: kube-node-01
ID: c8f2114c-e5a8-4e14-a8f2-af9f6ca67ba5
3.4 部署证书-在master操作
cp cfssl_1.6.5_linux_amd64 /usr/local/bin/cfssl
cp cfssljson_1.6.5_linux_amd64 /usr/local/bin/cfssljson
#添加权限
chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson
cp cfssl_1.6.5_linux_amd64 /usr/local/bin/cfssl
cp cfssljson_1.6.5_linux_amd64 /usr/local/bin/cfssljson
#添加权限
chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson
3.5 部署etcd
3.5.1 安装
tar -xf etcd-v3.5.12-linux-amd64.tar.gz --strip-components=1 -C /usr/local/bin etcd-v3.5.7-linux-amd64/etcd{,ctl}
#验证
[root@kube-master-01 init_pack]# etcdctl version
etcdctl version: 3.5.12
API version: 3.5
tar -xf etcd-v3.5.12-linux-amd64.tar.gz --strip-components=1 -C /usr/local/bin etcd-v3.5.7-linux-amd64/etcd{,ctl}
#验证
[root@kube-master-01 init_pack]# etcdctl version
etcdctl version: 3.5.12
API version: 3.5
- 部署其它节点
MasterNodes='kube-node-01 kube-node-02'
for NODE in $MasterNodes; do echo $NODE; scp /usr/local/bin/etcd* $NODE:/usr/local/bin/; done
MasterNodes='kube-node-01 kube-node-02'
for NODE in $MasterNodes; do echo $NODE; scp /usr/local/bin/etcd* $NODE:/usr/local/bin/; done
3.5.2 配置证书
- 创建证书目录和配置目录,
需要在部署etcd所在节点进行创建
mkdir -p /etc/etcd/ssl/
mkdir -p /etc/etcd/cfg
mkdir -p /var/lib/etcd
mkdir -p /var/log/etcd
mkdir -p /etc/etcd/ssl/
mkdir -p /etc/etcd/cfg
mkdir -p /var/lib/etcd
mkdir -p /var/log/etcd
- 配置CA证书,
只在master01上面执行
cd /etc/etcd/ssl/
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "876000h"
}
}
}
}
EOF
cat > etcd-ca-csr.json << EOF
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "etcd",
"OU": "Etcd Security"
}
],
"ca": {
"expiry": "876000h"
}
}
EOF
[root@kube-master-01 ssl]# cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare /etc/etcd/ssl/etcd-ca
2024/09/19 15:29:52 [INFO] generating a new CA key and certificate from CSR
2024/09/19 15:29:52 [INFO] generate received request
2024/09/19 15:29:52 [INFO] received CSR
2024/09/19 15:29:52 [INFO] generating key: rsa-2048
2024/09/19 15:29:52 [INFO] encoded CSR
2024/09/19 15:29:52 [INFO] signed certificate with serial number 120213013390660577809730590415784165837334607123
cd /etc/etcd/ssl/
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "876000h"
}
}
}
}
EOF
cat > etcd-ca-csr.json << EOF
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "etcd",
"OU": "Etcd Security"
}
],
"ca": {
"expiry": "876000h"
}
}
EOF
[root@kube-master-01 ssl]# cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare /etc/etcd/ssl/etcd-ca
2024/09/19 15:29:52 [INFO] generating a new CA key and certificate from CSR
2024/09/19 15:29:52 [INFO] generate received request
2024/09/19 15:29:52 [INFO] received CSR
2024/09/19 15:29:52 [INFO] generating key: rsa-2048
2024/09/19 15:29:52 [INFO] encoded CSR
2024/09/19 15:29:52 [INFO] signed certificate with serial number 120213013390660577809730590415784165837334607123
- 自签CA签发Etcd HTTPS证书
创建证书申请文件
文件hosts字段中IP为所有etcd节点的集群内部通信IP,不要漏了!为了方便后期扩容可以多写几个ip预留扩容
cat > etcd-csr.json << EOF
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"hosts": [
"127.0.0.1",
"kube-master-01",
"kube-node-02",
"kube-node-01",
"10.103.236.150",
"10.103.236.151",
"10.103.236.152"
],
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "etcd",
"OU": "Etcd Security"
}
]
}
EOF
#生成证书
cfssl gencert -ca=/etc/etcd/ssl/etcd-ca.pem -ca-key=/etc/etcd/ssl/etcd-ca-key.pem -config=ca-config.json -profile=kubernetes etcd-csr.json | cfssljson -bare /etc/etcd/ssl/etcd
#查看
ls -thl etcd*
-rw-r--r-- 1 root root 1017 9月 19 15:44 etcd.csr
-rw-r--r-- 1 root root 296 9月 19 15:35 etcd-csr.json
-rw------- 1 root root 1675 9月 19 15:44 etcd-key.pem
-rw-r--r-- 1 root root 1346 9月 19 15:44 etcd.pem
cat > etcd-csr.json << EOF
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"hosts": [
"127.0.0.1",
"kube-master-01",
"kube-node-02",
"kube-node-01",
"10.103.236.150",
"10.103.236.151",
"10.103.236.152"
],
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "etcd",
"OU": "Etcd Security"
}
]
}
EOF
#生成证书
cfssl gencert -ca=/etc/etcd/ssl/etcd-ca.pem -ca-key=/etc/etcd/ssl/etcd-ca-key.pem -config=ca-config.json -profile=kubernetes etcd-csr.json | cfssljson -bare /etc/etcd/ssl/etcd
#查看
ls -thl etcd*
-rw-r--r-- 1 root root 1017 9月 19 15:44 etcd.csr
-rw-r--r-- 1 root root 296 9月 19 15:35 etcd-csr.json
-rw------- 1 root root 1675 9月 19 15:44 etcd-key.pem
-rw-r--r-- 1 root root 1346 9月 19 15:44 etcd.pem
3.5.3 配置etcd文件
在master-01上执行,然后把生成的文件拷贝到其他etcd集群主机,修改name(主机名字)和ip
cat > /etc/etcd/cfg/etcd.yml << EOF
name: 'kube-master-01'
data-dir: /var/lib/etcd
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 8589934592 # 设置为 8GB 或根据需要调整
listen-peer-urls: 'https://10.103.236.150:2380'
listen-client-urls: 'https://10.103.236.150:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
initial-advertise-peer-urls: 'https://10.103.236.150:2380'
advertise-client-urls: 'https://10.103.236.150:2379'
initial-cluster: 'kube-master-01=https://10.103.236.150:2380,kube-node-01=https://10.103.236.151:2380,kube-node-02=https://10.103.236.152:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: false # 推荐关闭
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
cert-file: '/etc/etcd/ssl/etcd.pem'
key-file: '/etc/etcd/ssl/etcd-key.pem'
client-cert-auth: true
trusted-ca-file: '/etc/etcd/ssl/etcd-ca.pem'
auto-tls: true
peer-transport-security:
cert-file: '/etc/etcd/ssl/etcd.pem'
key-file: '/etc/etcd/ssl/etcd-key.pem'
peer-client-cert-auth: true
trusted-ca-file: '/etc/etcd/ssl/etcd-ca.pem'
auto-tls: true
log-outputs: ["/var/log/etcd/etcd.log"]
force-new-cluster: false
EOF
cat > /etc/etcd/cfg/etcd.yml << EOF
name: 'kube-master-01'
data-dir: /var/lib/etcd
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 8589934592 # 设置为 8GB 或根据需要调整
listen-peer-urls: 'https://10.103.236.150:2380'
listen-client-urls: 'https://10.103.236.150:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
initial-advertise-peer-urls: 'https://10.103.236.150:2380'
advertise-client-urls: 'https://10.103.236.150:2379'
initial-cluster: 'kube-master-01=https://10.103.236.150:2380,kube-node-01=https://10.103.236.151:2380,kube-node-02=https://10.103.236.152:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: false # 推荐关闭
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
cert-file: '/etc/etcd/ssl/etcd.pem'
key-file: '/etc/etcd/ssl/etcd-key.pem'
client-cert-auth: true
trusted-ca-file: '/etc/etcd/ssl/etcd-ca.pem'
auto-tls: true
peer-transport-security:
cert-file: '/etc/etcd/ssl/etcd.pem'
key-file: '/etc/etcd/ssl/etcd-key.pem'
peer-client-cert-auth: true
trusted-ca-file: '/etc/etcd/ssl/etcd-ca.pem'
auto-tls: true
log-outputs: ["/var/log/etcd/etcd.log"]
force-new-cluster: false
EOF
- 复制ssl证书和配置文件到其他etcd所在节点
[root@kube-master-01 ssl]# Master='kube-node-02 kube-node-01'
for NODE in $Master; do ssh $NODE "mkdir -p /etc/etcd/ssl"; for FILE in etcd-ca-key.pem etcd-ca.pem etcd-key.pem etcd.pem; do scp /etc/etcd/ssl/${FILE} $NODE:/etc/etcd/ssl/${FILE}; done; done
#复制配置文件
[root@kube-master-01 cfg]# cd /etc/etcd/cfg/
[root@kube-master-01 cfg]# scp etcd.yml kube-node-01:/etc/etcd/cfg/
[root@kube-master-01 cfg]# scp etcd.yml kube-node-02:/etc/etcd/cfg/
[root@kube-master-01 ssl]# Master='kube-node-02 kube-node-01'
for NODE in $Master; do ssh $NODE "mkdir -p /etc/etcd/ssl"; for FILE in etcd-ca-key.pem etcd-ca.pem etcd-key.pem etcd.pem; do scp /etc/etcd/ssl/${FILE} $NODE:/etc/etcd/ssl/${FILE}; done; done
#复制配置文件
[root@kube-master-01 cfg]# cd /etc/etcd/cfg/
[root@kube-master-01 cfg]# scp etcd.yml kube-node-01:/etc/etcd/cfg/
[root@kube-master-01 cfg]# scp etcd.yml kube-node-02:/etc/etcd/cfg/
- 修改name和ip
vim /etc/etcd/cfg/etcd.yml
vim /etc/etcd/cfg/etcd.yml
3.5.4 配置unit文件
cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Service
Documentation=https://coreos.com/etcd/docs/v3.5.12/
After=network.target
Wants=network-online.target
[Service]
Type=notify
Delegate=yes
ExecStart=/usr/local/bin/etcd --config-file=/etc/etcd/cfg/etcd.yml
Restart=always
RestartSec=10
TimeoutStartSec=300
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
Alias=etcd3.service
EOF
cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Service
Documentation=https://coreos.com/etcd/docs/v3.5.12/
After=network.target
Wants=network-online.target
[Service]
Type=notify
Delegate=yes
ExecStart=/usr/local/bin/etcd --config-file=/etc/etcd/cfg/etcd.yml
Restart=always
RestartSec=10
TimeoutStartSec=300
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
Alias=etcd3.service
EOF
- 启动服务
systemctl daemon-reload
systemctl enable --now etcd
systemctl daemon-reload
systemctl enable --now etcd
- 验证
export ETCDCTL_API=3
etcdctl --endpoints="10.103.236.150:2379,10.103.236.151:2379,10.103.236.152:2379" --cacert=/etc/etcd/ssl/etcd-ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem endpoint status --write-out=table
export ETCDCTL_API=3
etcdctl --endpoints="10.103.236.150:2379,10.103.236.151:2379,10.103.236.152:2379" --cacert=/etc/etcd/ssl/etcd-ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem endpoint status --write-out=table
3.6 部署kubernetes组件
二进制安装,master节点默认是没有污点, kubeadm安装则有污点
3.6.1 master节点-所有master节点
#解压
tar -xf kubernetes-server-linux-amd64.tar.gz --strip-components=3 -C /usr/local/bin kubernetes/server/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy}
#验证
[root@kube-master-01 init_pack]# kubectl version
Client Version: v1.29.7
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
The connection to the server localhost:8080 was refused - did you specify the right host or port?
#解压
tar -xf kubernetes-server-linux-amd64.tar.gz --strip-components=3 -C /usr/local/bin kubernetes/server/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy}
#验证
[root@kube-master-01 init_pack]# kubectl version
Client Version: v1.29.7
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
The connection to the server localhost:8080 was refused - did you specify the right host or port?
如果有其它master节点
MasterNodes='kube-master-02 kube-master-03'
for NODE in $MasterNodes; do echo $NODE; scp /usr/local/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy} $NODE:/usr/local/bin/; done
MasterNodes='kube-master-02 kube-master-03'
for NODE in $MasterNodes; do echo $NODE; scp /usr/local/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy} $NODE:/usr/local/bin/; done
1.0 生成k8s所需证书
#所有节点操作
mkdir -p /etc/kubernetes/pki
#所有节点操作
mkdir -p /etc/kubernetes/pki
1.生成ca
- 创建ca-csr文件
自签证书颁发机构(CA),只在master其中一个节点执行
#master01 节点生成 k8s 证书, 写入生成证书所需的配置文件
cd /etc/kubernetes/pki
cat > ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "Kubernetes",
"OU": "Kubernetes-manual"
}
],
"ca": {
"expiry": "876000h"
}
}
EOF
#Kubernetes 使用证书中的 'subject' 的通用名称(Common Name)字段(例如,"/CN=kubernetes")来 确定用户名, Kubernetes使用证书中的 'subject' 的单位名称 (Organization Name) 字段(例如,"/O=system:masters")来确定用户组
#master01 节点生成 k8s 证书, 写入生成证书所需的配置文件
cd /etc/kubernetes/pki
cat > ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "Kubernetes",
"OU": "Kubernetes-manual"
}
],
"ca": {
"expiry": "876000h"
}
}
EOF
#Kubernetes 使用证书中的 'subject' 的通用名称(Common Name)字段(例如,"/CN=kubernetes")来 确定用户名, Kubernetes使用证书中的 'subject' 的单位名称 (Organization Name) 字段(例如,"/O=system:masters")来确定用户组
- 生成证书
[root@kube-master-01 pki]# cfssl gencert -initca ca-csr.json | cfssljson -bare /etc/kubernetes/pki/ca
[root@kube-master-01 pki]# cfssl gencert -initca ca-csr.json | cfssljson -bare /etc/kubernetes/pki/ca
2.签发apiserver
- 创建apiserver-csr
hosts字段中IP为所有集群成员的ip集群内部ip,一个都不能少!为了方便后期扩容可以多写几个预留的IP或者domain
cat > apiserver-csr.json << EOF
{
"CN": "kube-apiserver",
"hosts": [
"127.0.0.1",
"10.0.0.1",
"10.255.0.1",
"192.168.0.1",
"10.103.236.150",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local",
"10.103.236.151",
"10.103.236.152"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "Kubernetes",
"OU": "Kubernetes-manual"
}
]
}
EOF
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "876000h"
}
}
}
}
EOF
# signing:表示该证书可用于签名其它证书;生成的 .pem 证书文件中 CA=TRUE
# expiry:默认的证书到期时间为50年,876000h为100年
# profiles:包含了server auth和client auth,所以可以签发三种不同类型证书;expiry 证书有效期,默认50年,可以定义多个profile
# kubernetes:kubernetes这个名字可以自定义,后续指定profiles时要一致,这就是一个单个的profile
# server auth:表示client可以用该 CA 对server提供的证书进行验证
# client auth:表示server可以用该CA对client提供的证书进行验证
cat > apiserver-csr.json << EOF
{
"CN": "kube-apiserver",
"hosts": [
"127.0.0.1",
"10.0.0.1",
"10.255.0.1",
"192.168.0.1",
"10.103.236.150",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local",
"10.103.236.151",
"10.103.236.152"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "Kubernetes",
"OU": "Kubernetes-manual"
}
]
}
EOF
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "876000h"
}
}
}
}
EOF
# signing:表示该证书可用于签名其它证书;生成的 .pem 证书文件中 CA=TRUE
# expiry:默认的证书到期时间为50年,876000h为100年
# profiles:包含了server auth和client auth,所以可以签发三种不同类型证书;expiry 证书有效期,默认50年,可以定义多个profile
# kubernetes:kubernetes这个名字可以自定义,后续指定profiles时要一致,这就是一个单个的profile
# server auth:表示client可以用该 CA 对server提供的证书进行验证
# client auth:表示server可以用该CA对client提供的证书进行验证
❌ 注意
"192.168.0.1"为咱们的svc网段的第一个地址,您需要根据自己的场景稍作修改。
"10.103.236.158"是负载均衡器的VIP地址。如果没有请用eth0地址
"kubernetes,...,kubernetes.default.svc.cluster.loca"对应的是apiServer解析的A记录。
"10.103.236.151,...,10.103.236.152"对应的是K8S集群的地址。这里也可以多预留几个,后期扩容
- 生成证书
[root@kube-master-01 pki]# cfssl gencert -ca=/etc/kubernetes/pki/ca.pem -ca-key=/etc/kubernetes/pki/ca-key.pem -config=ca-config.json -profile=kubernetes apiserver-csr.json | cfssljson -bare /etc/kubernetes/pki/apiserver
[root@kube-master-01 pki]# cfssl gencert -ca=/etc/kubernetes/pki/ca.pem -ca-key=/etc/kubernetes/pki/ca-key.pem -config=ca-config.json -profile=kubernetes apiserver-csr.json | cfssljson -bare /etc/kubernetes/pki/apiserver
3.生成 apiserver 聚合证书
cat > front-proxy-ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"ca": {
"expiry": "876000h"
}
}
EOF
#生成
cfssl gencert -initca front-proxy-ca-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-ca
cat > front-proxy-client-csr.json << EOF
{
"CN": "front-proxy-client",
"key": {
"algo": "rsa",
"size": 2048
}
}
EOF
cfssl gencert \
-ca=/etc/kubernetes/pki/front-proxy-ca.pem \
-ca-key=/etc/kubernetes/pki/front-proxy-ca-key.pem \
-config=ca-config.json \
-profile=kubernetes front-proxy-client-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-client
cat > front-proxy-ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"ca": {
"expiry": "876000h"
}
}
EOF
#生成
cfssl gencert -initca front-proxy-ca-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-ca
cat > front-proxy-client-csr.json << EOF
{
"CN": "front-proxy-client",
"key": {
"algo": "rsa",
"size": 2048
}
}
EOF
cfssl gencert \
-ca=/etc/kubernetes/pki/front-proxy-ca.pem \
-ca-key=/etc/kubernetes/pki/front-proxy-ca-key.pem \
-config=ca-config.json \
-profile=kubernetes front-proxy-client-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-client
4.签发controller-manage
❌ 注意
注意:节点hosts ip根据所需设置即可。hosts 列表包含所有 kube-controller-manager 节点 IP; CN 为 system:kube- controller-manager
O 为 system:kube-controller-manager, kubernetes 内置的 ClusterRoleBindings system:kube-controller-manager 赋予 kube-controller-manager 工作所需的权限
cat > manager-csr.json << EOF
{
"CN": "system:kube-controller-manager",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:kube-controller-manager",
"OU": "Kubernetes-manual"
}
]
}
EOF
#生成
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.pem \
-ca-key=/etc/kubernetes/pki/ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
manager-csr.json | cfssljson -bare /etc/kubernetes/pki/controller-manager
cat > manager-csr.json << EOF
{
"CN": "system:kube-controller-manager",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:kube-controller-manager",
"OU": "Kubernetes-manual"
}
]
}
EOF
#生成
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.pem \
-ca-key=/etc/kubernetes/pki/ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
manager-csr.json | cfssljson -bare /etc/kubernetes/pki/controller-manager
- 配置上下文
#设置一个集群
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true \
--server=https://10.103.236.150:6443 \
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
#设置一个用户项
kubectl config set-context system:kube-controller-manager@kubernetes \
--cluster=kubernetes \
--user=system:kube-controller-manager \
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
#设置一个上下文环境
kubectl config set-credentials system:kube-controller-manager \
--client-certificate=/etc/kubernetes/pki/controller-manager.pem \
--client-key=/etc/kubernetes/pki/controller-manager-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
#使用默认的上下文
kubectl config use-context system:kube-controller-manager@kubernetes \
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
#设置一个集群
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true \
--server=https://10.103.236.150:6443 \
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
#设置一个用户项
kubectl config set-context system:kube-controller-manager@kubernetes \
--cluster=kubernetes \
--user=system:kube-controller-manager \
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
#设置一个上下文环境
kubectl config set-credentials system:kube-controller-manager \
--client-certificate=/etc/kubernetes/pki/controller-manager.pem \
--client-key=/etc/kubernetes/pki/controller-manager-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
#使用默认的上下文
kubectl config use-context system:kube-controller-manager@kubernetes \
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
5.签发kube-scheduler
❌ 注意
注意:节点hostsip根据所需设置即可。hosts 列表包含所有 kube-scheduler 节点 IP;
CN 为 system:kube-scheduler、
O 为 system:kube-scheduler,kubernetes 内置的 ClusterRoleBindings system:kube-scheduler 将赋予 kube-scheduler 工作所需的权限
cat > scheduler-csr.json << EOF
{
"CN": "system:kube-scheduler",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:kube-scheduler",
"OU": "Kubernetes-manual"
}
]
}
EOF
#生成
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.pem \
-ca-key=/etc/kubernetes/pki/ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
scheduler-csr.json | cfssljson -bare /etc/kubernetes/pki/scheduler
cat > scheduler-csr.json << EOF
{
"CN": "system:kube-scheduler",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:kube-scheduler",
"OU": "Kubernetes-manual"
}
]
}
EOF
#生成
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.pem \
-ca-key=/etc/kubernetes/pki/ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
scheduler-csr.json | cfssljson -bare /etc/kubernetes/pki/scheduler
- 配置上下文
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true \
--server=https://10.103.236.150:6443 \
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig
kubectl config set-credentials system:kube-scheduler \
--client-certificate=/etc/kubernetes/pki/scheduler.pem \
--client-key=/etc/kubernetes/pki/scheduler-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig
kubectl config set-context system:kube-scheduler@kubernetes \
--cluster=kubernetes \
--user=system:kube-scheduler \
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig
kubectl config use-context system:kube-scheduler@kubernetes \
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true \
--server=https://10.103.236.150:6443 \
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig
kubectl config set-credentials system:kube-scheduler \
--client-certificate=/etc/kubernetes/pki/scheduler.pem \
--client-key=/etc/kubernetes/pki/scheduler-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig
kubectl config set-context system:kube-scheduler@kubernetes \
--cluster=kubernetes \
--user=system:kube-scheduler \
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig
kubectl config use-context system:kube-scheduler@kubernetes \
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig
6.签发admin
# 生成 admin 的证书配置
cat > admin-csr.json << EOF
{
"CN": "admin",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:masters",
"OU": "Kubernetes-manual"
}
]
}
EOF
#生成
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.pem \
-ca-key=/etc/kubernetes/pki/ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
admin-csr.json | cfssljson -bare /etc/kubernetes/pki/admin
# 生成 admin 的证书配置
cat > admin-csr.json << EOF
{
"CN": "admin",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:masters",
"OU": "Kubernetes-manual"
}
]
}
EOF
#生成
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.pem \
-ca-key=/etc/kubernetes/pki/ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
admin-csr.json | cfssljson -bare /etc/kubernetes/pki/admin
❌ 注意
O: system:masters:kube-apiserver 收到使用该证书的客户端请求后,为请求添加组(Group)认证标识 system:masters;
预定义的 ClusterRoleBinding cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予操作集群所需的最高权限;
"hosts": [""],该证书只会被 kubectl 当做 client 证书使用,所以 hosts 字段为空
- 配置上下文
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true \
--server=https://10.103.236.150:6443 \
--kubeconfig=/etc/kubernetes/admin.kubeconfig
kubectl config set-credentials kubernetes-admin \
--client-certificate=/etc/kubernetes/pki/admin.pem \
--client-key=/etc/kubernetes/pki/admin-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/admin.kubeconfig
kubectl config set-context kubernetes-admin@kubernetes \
--cluster=kubernetes \
--user=kubernetes-admin \
--kubeconfig=/etc/kubernetes/admin.kubeconfig
kubectl config use-context kubernetes-admin@kubernetes --kubeconfig=/etc/kubernetes/admin.kubeconfig
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true \
--server=https://10.103.236.150:6443 \
--kubeconfig=/etc/kubernetes/admin.kubeconfig
kubectl config set-credentials kubernetes-admin \
--client-certificate=/etc/kubernetes/pki/admin.pem \
--client-key=/etc/kubernetes/pki/admin-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/admin.kubeconfig
kubectl config set-context kubernetes-admin@kubernetes \
--cluster=kubernetes \
--user=kubernetes-admin \
--kubeconfig=/etc/kubernetes/admin.kubeconfig
kubectl config use-context kubernetes-admin@kubernetes --kubeconfig=/etc/kubernetes/admin.kubeconfig
❌ 注意
--certificate-authority:验证 kube-apiserver 证书的根证书;
--client-certificate、--client-key:刚生成的 admin 证书和私钥,与 kube-apiserver https 通信时使用;
--embed-certs=true:将 ca.pem 和 admin.pem 证书内容嵌入到生成的 kubectl.kubeconfig 文件中(否则,写入的是证书文件路径,后续拷贝 kubeconfig 到其它机器时,还需要单独拷贝证书文件,不方便。);
--server:指定 kube-apiserver 的地址;
7.签发kube-proxy
# 创建 kube-proxy 证书
cat > kube-proxy-csr.json << EOF
{
"CN": "system:kube-proxy",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:kube-proxy",
"OU": "Kubernetes-manual"
}
]
}
EOF
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.pem \
-ca-key=/etc/kubernetes/pki/ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kube-proxy-csr.json | cfssljson -bare /etc/kubernetes/pki/kube-proxy
# 创建 kube-proxy 证书
cat > kube-proxy-csr.json << EOF
{
"CN": "system:kube-proxy",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:kube-proxy",
"OU": "Kubernetes-manual"
}
]
}
EOF
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.pem \
-ca-key=/etc/kubernetes/pki/ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kube-proxy-csr.json | cfssljson -bare /etc/kubernetes/pki/kube-proxy
- 配置上下文
10.103.236.150 根据环境进行修改,如果有高可用,则这里修改成高可用ip地址
#设置一个集群
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true \
--server=https://10.103.236.150:6443 \
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
#设置一个用户项
kubectl config set-credentials kube-proxy \
--client-certificate=/etc/kubernetes/pki/kube-proxy.pem \
--client-key=/etc/kubernetes/pki/kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
#设置一个上下文环境
kubectl config set-context kube-proxy@kubernetes \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
#使用默认的上下文
kubectl config use-context kube-proxy@kubernetes --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
#设置一个集群
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true \
--server=https://10.103.236.150:6443 \
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
#设置一个用户项
kubectl config set-credentials kube-proxy \
--client-certificate=/etc/kubernetes/pki/kube-proxy.pem \
--client-key=/etc/kubernetes/pki/kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
#设置一个上下文环境
kubectl config set-context kube-proxy@kubernetes \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
#使用默认的上下文
kubectl config use-context kube-proxy@kubernetes --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
查看证书有效时间
find /etc/kubernetes/pki -type f -name "*.pem" ! -name "*key*" -exec sh -c 'echo "File: {}"; openssl x509 -noout -dates -in "{}"' \;
find /etc/kubernetes/pki -type f -name "*.pem" ! -name "*key*" -exec sh -c 'echo "File: {}"; openssl x509 -noout -dates -in "{}"' \;
8.创建ServiceAccount
#ServiceAccount是k8s一种认证方式,创建ServiceAccount的时候会创建一个与之绑定的secret,这个secret会生成一个token
openssl genrsa -out /etc/kubernetes/pki/sa.key 2048
#基于sa.key创建sa.pub
openssl rsa -in /etc/kubernetes/pki/sa.key -pubout -out /etc/kubernetes/pki/sa.pub
#ServiceAccount是k8s一种认证方式,创建ServiceAccount的时候会创建一个与之绑定的secret,这个secret会生成一个token
openssl genrsa -out /etc/kubernetes/pki/sa.key 2048
#基于sa.key创建sa.pub
openssl rsa -in /etc/kubernetes/pki/sa.key -pubout -out /etc/kubernetes/pki/sa.pub
分发到其它master节点上面
# 将证书发送到其他 master 节点 # 其他节点创建目录 mkdir /etc/kubernetes/pki/ -p for NODE in k8s-master02 k8s-master03; do for FILE in $(ls /etc/kubernetes/pki | grep -v etcd); do scp /etc/kubernetes/pki/${FILE} $NODE:/etc/kubernetes/pki/${FILE}; done; for FILE in admin.kubeconfig controller-manager.kubeconfig scheduler.kubeconfig; do scp /etc/kubernetes/${FILE} $NODE:/etc/kubernetes/${FILE}; done; done
# 将证书发送到其他 master 节点 # 其他节点创建目录 mkdir /etc/kubernetes/pki/ -p for NODE in k8s-master02 k8s-master03; do for FILE in $(ls /etc/kubernetes/pki | grep -v etcd); do scp /etc/kubernetes/pki/${FILE} $NODE:/etc/kubernetes/pki/${FILE}; done; for FILE in admin.kubeconfig controller-manager.kubeconfig scheduler.kubeconfig; do scp /etc/kubernetes/${FILE} $NODE:/etc/kubernetes/${FILE}; done; done
1.1 kube-Apiserver
所有Master节点创建kube-apiserver service
❌ 注意
本文档使用的k8s service网段为192.168.0.0/16,该网段不能和宿主机的网段、Pod网段的重复,请按需修改
- 所有节点执行
mkdir -p /etc/kubernetes/manifests/ /var/lib/kubelet /var/log/kubernetes /etc/kubernetes/cfg
mkdir -p /etc/kubernetes/manifests/ /var/lib/kubelet /var/log/kubernetes /etc/kubernetes/cfg
- 创建token.csv文件
cd /etc/kubernetes/cfg/
cat > token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
cd /etc/kubernetes/cfg/
cat > token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
1.创建api-server的配置文件
cat > /etc/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logging-format=json \\
--v=2 \\
--etcd-servers=https://10.103.236.150:2379,https://10.103.236.151:2379,https://10.103.236.152:2379 \\
--bind-address=0.0.0.0 \\
--secure-port=6443 \\
--advertise-address=10.103.236.150 \\
--allow-privileged=true \\
--service-cluster-ip-range=192.168.0.0/16 \\
--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--service-node-port-range=30000-61000 \\
--kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem \\
--kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem \\
--tls-cert-file=/etc/kubernetes/pki/apiserver.pem \\
--tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem \\
--client-ca-file=/etc/kubernetes/pki/ca.pem \\
--service-account-key-file=/etc/kubernetes/pki/sa.pub \\
--service-account-signing-key-file=/etc/kubernetes/pki/sa.key \\
--service-account-issuer=https://kubernetes.default.svc.cluster.local \\
--etcd-cafile=/etc/etcd/ssl/etcd-ca.pem \\
--etcd-certfile=/etc/etcd/ssl/etcd.pem \\
--etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \\
--requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem \\
--proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem \\
--proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem \\
--requestheader-allowed-names=aggregator \\
--requestheader-extra-headers-prefix=X-Remote-Extra- \\
--requestheader-group-headers=X-Remote-Group \\
--requestheader-username-headers=X-Remote-User \\
--enable-aggregator-routing=true \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/var/log/kubernetes/k8s-audit.log"
EOF
cat > /etc/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logging-format=json \\
--v=2 \\
--etcd-servers=https://10.103.236.150:2379,https://10.103.236.151:2379,https://10.103.236.152:2379 \\
--bind-address=0.0.0.0 \\
--secure-port=6443 \\
--advertise-address=10.103.236.150 \\
--allow-privileged=true \\
--service-cluster-ip-range=192.168.0.0/16 \\
--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--service-node-port-range=30000-61000 \\
--kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem \\
--kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem \\
--tls-cert-file=/etc/kubernetes/pki/apiserver.pem \\
--tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem \\
--client-ca-file=/etc/kubernetes/pki/ca.pem \\
--service-account-key-file=/etc/kubernetes/pki/sa.pub \\
--service-account-signing-key-file=/etc/kubernetes/pki/sa.key \\
--service-account-issuer=https://kubernetes.default.svc.cluster.local \\
--etcd-cafile=/etc/etcd/ssl/etcd-ca.pem \\
--etcd-certfile=/etc/etcd/ssl/etcd.pem \\
--etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \\
--requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem \\
--proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem \\
--proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem \\
--requestheader-allowed-names=aggregator \\
--requestheader-extra-headers-prefix=X-Remote-Extra- \\
--requestheader-group-headers=X-Remote-Group \\
--requestheader-username-headers=X-Remote-User \\
--enable-aggregator-routing=true \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/var/log/kubernetes/k8s-audit.log"
EOF
2.配置unit文件
cat >/usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-apiserver.conf
ExecStart=/usr/local/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=10s
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
cat >/usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-apiserver.conf
ExecStart=/usr/local/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=10s
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
3.启动
systemctl daemon-reload && systemctl enable --now kube-apiserver && systemctl status kube-apiserver
systemctl daemon-reload && systemctl enable --now kube-apiserver && systemctl status kube-apiserver
#查看
[root@kube-master-01 ~]# curl -k https://10.103.236.150:6443/
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {},
"code": 403
}
#查看
[root@kube-master-01 ~]# curl -k https://10.103.236.150:6443/
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {},
"code": 403
}
1.2 kube-controller-manager
官档: https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/
1.创建kube-controller-manager配置文件
cat >/etc/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS=" \
--bind-address=0.0.0.0 \
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig \
--service-cluster-ip-range=192.168.0.0/16 \
--cluster-cidr=172.16.0.0/12 \
--cluster-name=kubernetes \
--allocate-node-cidrs=true \
--leader-elect=true \
--feature-gates=RotateKubeletServerCertificate=true \
--controllers=*,bootstrapsigner,tokencleaner \
--horizontal-pod-autoscaler-sync-period=10s \
--use-service-account-credentials=true \
--logging-format=json \
--cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem \
--cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem \
--root-ca-file=/etc/kubernetes/pki/ca.pem \
--service-account-private-key-file=/etc/kubernetes/pki/sa.key \
--cluster-signing-duration=438000h0m0s \
--node-monitor-grace-period=40s \
--node-monitor-period=5s \
--allocate-node-cidrs=true \
--node-cidr-mask-size=24 \
--requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem \
--v=2"
EOF
cat >/etc/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS=" \
--bind-address=0.0.0.0 \
--kubeconfig=/etc/kubernetes/controller-manager.kubeconfig \
--service-cluster-ip-range=192.168.0.0/16 \
--cluster-cidr=172.16.0.0/12 \
--cluster-name=kubernetes \
--allocate-node-cidrs=true \
--leader-elect=true \
--feature-gates=RotateKubeletServerCertificate=true \
--controllers=*,bootstrapsigner,tokencleaner \
--horizontal-pod-autoscaler-sync-period=10s \
--use-service-account-credentials=true \
--logging-format=json \
--cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem \
--cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem \
--root-ca-file=/etc/kubernetes/pki/ca.pem \
--service-account-private-key-file=/etc/kubernetes/pki/sa.key \
--cluster-signing-duration=438000h0m0s \
--node-monitor-grace-period=40s \
--node-monitor-period=5s \
--allocate-node-cidrs=true \
--node-cidr-mask-size=24 \
--requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem \
--v=2"
EOF
service-cluster-ip-range ----> service 网段
cluster-cidr -->Pod网段
2.创建unit文件
cat >/usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/usr/local/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
cat >/usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/usr/local/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
3.启动
systemctl daemon-reload ;systemctl --now enable kube-controller-manager;systemctl status kube-controller-manager.service
systemctl daemon-reload ;systemctl --now enable kube-controller-manager;systemctl status kube-controller-manager.service
1.3 kube-scheduler
1.创建 kube-scheduler 配置文件
cat >/etc/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logging-format=json \\
--v=2 \\
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig \\
--authentication-kubeconfig=/etc/kubernetes/scheduler.kubeconfig \\
--authorization-kubeconfig=/etc/kubernetes/scheduler.kubeconfig \\
--leader-elect \\
--bind-address=0.0.0.0"
EOF
cat >/etc/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logging-format=json \\
--v=2 \\
--kubeconfig=/etc/kubernetes/scheduler.kubeconfig \\
--authentication-kubeconfig=/etc/kubernetes/scheduler.kubeconfig \\
--authorization-kubeconfig=/etc/kubernetes/scheduler.kubeconfig \\
--leader-elect \\
--bind-address=0.0.0.0"
EOF
2.创建unit文件
cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-scheduler.conf
ExecStart=/usr/local/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-scheduler.conf
ExecStart=/usr/local/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
3.启动
systemctl daemon-reload ;systemctl --now enable kube-scheduler;systemctl status kube-scheduler
systemctl daemon-reload ;systemctl --now enable kube-scheduler;systemctl status kube-scheduler
- 查看状态
如果这里执行kubectl命令日提示8080,则是没有配置kubeconfig文件
# 查看集群状态
[root@kube-master-01 kubernetes]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
etcd-0 Healthy ok
scheduler Healthy ok
[root@kube-master-01 kubernetes]# kubectl cluster-info
Kubernetes control plane is running at https://10.103.236.150:6443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
# 查看集群状态
[root@kube-master-01 kubernetes]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
etcd-0 Healthy ok
scheduler Healthy ok
[root@kube-master-01 kubernetes]# kubectl cluster-info
Kubernetes control plane is running at https://10.103.236.150:6443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
1.4 kube-proxy
1.创建 kube-proxy 配置文件
cat > /etc/kubernetes/kube-proxy.yaml << EOF
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
clientConnection:
acceptContentTypes: ""
burst: 10
contentType: application/vnd.kubernetes.protobuf
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
qps: 5
clusterCIDR: 172.16.0.0/12
configSyncPeriod: 15m0s
conntrack:
max: null
maxPerCore: 32768
min: 131072
tcpCloseWaitTimeout: 1h0m0s
tcpEstablishedTimeout: 24h0m0s
enableProfiling: false
healthzBindAddress: 0.0.0.0:10256
hostnameOverride: ""
iptables:
masqueradeAll: false
masqueradeBit: 14
minSyncPeriod: 0s
syncPeriod: 30s
ipvs:
masqueradeAll: true
minSyncPeriod: 5s
scheduler: "rr"
syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 0.0.0.0:10249
mode: "ipvs"
nodePortAddresses: null
oomScoreAdj: -999
portRange: ""
udpIdleTimeout: 250ms
EOF
cat > /etc/kubernetes/kube-proxy.yaml << EOF
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
clientConnection:
acceptContentTypes: ""
burst: 10
contentType: application/vnd.kubernetes.protobuf
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
qps: 5
clusterCIDR: 172.16.0.0/12
configSyncPeriod: 15m0s
conntrack:
max: null
maxPerCore: 32768
min: 131072
tcpCloseWaitTimeout: 1h0m0s
tcpEstablishedTimeout: 24h0m0s
enableProfiling: false
healthzBindAddress: 0.0.0.0:10256
hostnameOverride: ""
iptables:
masqueradeAll: false
masqueradeBit: 14
minSyncPeriod: 0s
syncPeriod: 30s
ipvs:
masqueradeAll: true
minSyncPeriod: 5s
scheduler: "rr"
syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 0.0.0.0:10249
mode: "ipvs"
nodePortAddresses: null
oomScoreAdj: -999
portRange: ""
udpIdleTimeout: 250ms
EOF
2.配置 unit文件
# 所有 k8s 节点添加 kube-proxy 的 service 文件
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
ExecStart=/usr/local/bin/kube-proxy \\
--config=/etc/kubernetes/kube-proxy.yaml \\
--cluster-cidr=172.16.0.0/12 \\
--v=2
Restart=always
RestartSec=10s
TimeoutStartSec=300
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
# 所有 k8s 节点添加 kube-proxy 的 service 文件
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
ExecStart=/usr/local/bin/kube-proxy \\
--config=/etc/kubernetes/kube-proxy.yaml \\
--cluster-cidr=172.16.0.0/12 \\
--v=2
Restart=always
RestartSec=10s
TimeoutStartSec=300
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
3.启动
systemctl daemon-reload
systemctl enable --now kube-proxy.service
systemctl status kube-proxy.service
systemctl daemon-reload
systemctl enable --now kube-proxy.service
systemctl status kube-proxy.service
1.5 kubelet
1.创建配置文件
cat > /etc/kubernetes/kubelet-conf.yml <<EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
cgroupDriver: systemd
cgroupsPerQOS: true
clusterDNS:
- 192.168.0.10
clusterDomain: cluster.local
containerLogMaxFiles: 5
containerLogMaxSize: 10Mi
contentType: application/vnd.kubernetes.protobuf
cpuCFSQuota: true
cpuManagerPolicy: none
cpuManagerReconcilePeriod: 10s
enableControllerAttachDetach: true
enableDebuggingHandlers: true
enforceNodeAllocatable:
- pods
eventBurst: 10
eventRecordQPS: 5
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
evictionPressureTransitionPeriod: 5m0s
failSwapOn: true
fileCheckFrequency: 20s
hairpinMode: promiscuous-bridge
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 20s
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
imageMinimumGCAge: 2m0s
iptablesDropBit: 15
iptablesMasqueradeBit: 14
kubeAPIBurst: 10
kubeAPIQPS: 5
makeIPTablesUtilChains: true
maxOpenFiles: 1000000
maxPods: 110
nodeStatusUpdateFrequency: 10s
oomScoreAdj: -999
podPidsLimit: -1
registryBurst: 10
registryPullQPS: 5
resolvConf: /etc/resolv.conf
rotateCertificates: true
runtimeRequestTimeout: 2m0s
serializeImagePulls: true
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 4h0m0s
syncFrequency: 1m0s
volumeStatsAggPeriod: 1m0s
EOF
cat > /etc/kubernetes/kubelet-conf.yml <<EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
cgroupDriver: systemd
cgroupsPerQOS: true
clusterDNS:
- 192.168.0.10
clusterDomain: cluster.local
containerLogMaxFiles: 5
containerLogMaxSize: 10Mi
contentType: application/vnd.kubernetes.protobuf
cpuCFSQuota: true
cpuManagerPolicy: none
cpuManagerReconcilePeriod: 10s
enableControllerAttachDetach: true
enableDebuggingHandlers: true
enforceNodeAllocatable:
- pods
eventBurst: 10
eventRecordQPS: 5
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
evictionPressureTransitionPeriod: 5m0s
failSwapOn: true
fileCheckFrequency: 20s
hairpinMode: promiscuous-bridge
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 20s
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
imageMinimumGCAge: 2m0s
iptablesDropBit: 15
iptablesMasqueradeBit: 14
kubeAPIBurst: 10
kubeAPIQPS: 5
makeIPTablesUtilChains: true
maxOpenFiles: 1000000
maxPods: 110
nodeStatusUpdateFrequency: 10s
oomScoreAdj: -999
podPidsLimit: -1
registryBurst: 10
registryPullQPS: 5
resolvConf: /etc/resolv.conf
rotateCertificates: true
runtimeRequestTimeout: 2m0s
serializeImagePulls: true
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 4h0m0s
syncFrequency: 1m0s
volumeStatsAggPeriod: 1m0s
EOF
2.配置unit文件
cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=network-online.target firewalld.service cri-docker.service docker.socket containerd.service
Wants=network-online.target
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \\
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig \\
--cert-dir=/etc/kubernete/pki \\
--client-ca-file=/etc/kubernetes/pki/ca.pem \\
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
--config=/etc/kubernetes/kubelet-conf.yml \\
--container-runtime-endpoint=unix:///run/containerd/containerd.sock \\
--node-labels=node.kubernetes.io/node= \\
--v=2
Restart=always
RestartSec=10s
TimeoutStartSec=300
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=network-online.target firewalld.service cri-docker.service docker.socket containerd.service
Wants=network-online.target
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \\
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig \\
--cert-dir=/etc/kubernete/pki \\
--client-ca-file=/etc/kubernetes/pki/ca.pem \\
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
--config=/etc/kubernetes/kubelet-conf.yml \\
--container-runtime-endpoint=unix:///run/containerd/containerd.sock \\
--node-labels=node.kubernetes.io/node= \\
--v=2
Restart=always
RestartSec=10s
TimeoutStartSec=300
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
3.启动
systemctl daemon-reload
systemctl enable --now kubelet.service
systemctl status kubelet.service
systemctl daemon-reload
systemctl enable --now kubelet.service
systemctl status kubelet.service
1.6 TLS Bootstrapping
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/
1.介绍
在一个 Kubernetes 集群中,Worker 节点上的组件(kubelet 和 kube-proxy)需要与 Kubernetes 控制平面组件通信,尤其是 kube-apiserver。 为了通信的安全性, 需要使用到节点上的客户端 TLS 证书。
但是客户端很多,又很难有通用的 TSL 证书直接使用,如果每一次加节点都需要重新生成证书,那维护将变得非常麻烦。
为了简化这一过程,从 1.4 版本开始,Kubernetes 引入了一个证书请求和签名 API
采用 TLS bootstrapping 生成证书的大致简化流程如下:
- 管理员通过 apiserver 生成一个 bootstrap token 并将它写入到 kubeconfig 文件中。
- Kubelet 通过 --bootstrap-kubeconfig 启动参数指定 kubeconfig 文件,然后调用 apiserver 的 API 接口,生成自己所需的服务器和客户端证书。
- 证书生成后,Kubelet 采用生成的证书和 apiserver 进行通信,并删除本地的 kubeconfig 文件,避免 bootstrap token 泄漏。
想要启动该功能,只需要在 apiserver 中启动参数中添加 --enable-bootstrap-token-auth
,并创建一个 Kubelet 访问的 bootstrap token secret 即可。
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/bootstrap-tokens/
2.部署
# 在 master01 上配置
- "--server"只想的是负载均衡器的IP地址,由负载均衡器对master节点进行反向代理
- "--token"也可以自定义,但也要同时修改"bootstrap"的Secret的"token-id"和"token-secret"对应值
#设置集群
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true --server=https://10.103.236.150:6443 \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
#创建用户
kubectl config set-credentials tls-bootstrap-token-user \
--token=c8ad9c.2e4d610cf3e7426e \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
#将集群和用户进行绑定
kubectl config set-context tls-bootstrap-token-user@kubernetes \
--cluster=kubernetes \
--user=tls-bootstrap-token-user \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
#配置默认的上下文
kubectl config use-context tls-bootstrap-token-user@kubernetes \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
mkdir -p /root/.kube ; cp /etc/kubernetes/admin.kubeconfig /root/.kube/config
# 在 master01 上配置
- "--server"只想的是负载均衡器的IP地址,由负载均衡器对master节点进行反向代理
- "--token"也可以自定义,但也要同时修改"bootstrap"的Secret的"token-id"和"token-secret"对应值
#设置集群
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true --server=https://10.103.236.150:6443 \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
#创建用户
kubectl config set-credentials tls-bootstrap-token-user \
--token=c8ad9c.2e4d610cf3e7426e \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
#将集群和用户进行绑定
kubectl config set-context tls-bootstrap-token-user@kubernetes \
--cluster=kubernetes \
--user=tls-bootstrap-token-user \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
#配置默认的上下文
kubectl config use-context tls-bootstrap-token-user@kubernetes \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
mkdir -p /root/.kube ; cp /etc/kubernetes/admin.kubeconfig /root/.kube/config
cat > bootstrap.secret.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
name: bootstrap-token-c8ad9c
namespace: kube-system
type: bootstrap.kubernetes.io/token
stringData:
description: "The default bootstrap token generated by 'kubelet '."
token-id: c8ad9c
token-secret: 2e4d610cf3e7426e
usage-bootstrap-authentication: "true"
usage-bootstrap-signing: "true"
auth-extra-groups: system:bootstrappers:default-node-token,system:bootstrappers:worker,system:bootstrappers:ingress
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubelet-bootstrap
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:node-bootstrapper
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:bootstrappers:default-node-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-autoapprove-bootstrap
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:bootstrappers:default-node-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-autoapprove-certificate-rotation
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:nodes
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-apiserver-to-kubelet
rules:
- apiGroups:
- ""
resources:
- nodes/proxy
- nodes/stats
- nodes/log
- nodes/spec
- nodes/metrics
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:kube-apiserver
namespace: ""
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-apiserver-to-kubelet
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: kube-apiserver
EOF
cat > bootstrap.secret.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
name: bootstrap-token-c8ad9c
namespace: kube-system
type: bootstrap.kubernetes.io/token
stringData:
description: "The default bootstrap token generated by 'kubelet '."
token-id: c8ad9c
token-secret: 2e4d610cf3e7426e
usage-bootstrap-authentication: "true"
usage-bootstrap-signing: "true"
auth-extra-groups: system:bootstrappers:default-node-token,system:bootstrappers:worker,system:bootstrappers:ingress
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubelet-bootstrap
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:node-bootstrapper
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:bootstrappers:default-node-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-autoapprove-bootstrap
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:bootstrappers:default-node-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-autoapprove-certificate-rotation
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:nodes
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-apiserver-to-kubelet
rules:
- apiGroups:
- ""
resources:
- nodes/proxy
- nodes/stats
- nodes/log
- nodes/spec
- nodes/metrics
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:kube-apiserver
namespace: ""
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-apiserver-to-kubelet
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: kube-apiserver
EOF
- 创建
kubectl create -f bootstrap.secret.yaml
kubectl create -f bootstrap.secret.yaml
3.6.2 node节点
1.部署
WorkNodes='kube-node-01 kube-node-02'
for NODE in $WorkNodes; do echo $NODE; scp /usr/local/bin/kube{let,-proxy} $NODE:/usr/local/bin/; done
WorkNodes='kube-node-01 kube-node-02'
for NODE in $WorkNodes; do echo $NODE; scp /usr/local/bin/kube{let,-proxy} $NODE:/usr/local/bin/; done
1.复制证书
# 在 master01 上将证书复制到 node 节点
cd /etc/kubernetes/
for NODE in kube-node-01 kube-node-02; do ssh $NODE mkdir -p /etc/kubernetes/{pki,manifests}; for FILE in pki/ca.pem pki/ca-key.pem pki/front-proxy-ca.pem bootstrap-kubelet.kubeconfig kube-proxy.kubeconfig; do scp /etc/kubernetes/$FILE $NODE:/etc/kubernetes/${FILE}; done; done
# 在 master01 上将证书复制到 node 节点
cd /etc/kubernetes/
for NODE in kube-node-01 kube-node-02; do ssh $NODE mkdir -p /etc/kubernetes/{pki,manifests}; for FILE in pki/ca.pem pki/ca-key.pem pki/front-proxy-ca.pem bootstrap-kubelet.kubeconfig kube-proxy.kubeconfig; do scp /etc/kubernetes/$FILE $NODE:/etc/kubernetes/${FILE}; done; done
2.kubelet
1.创建配置文件
cat > /etc/kubernetes/kubelet-conf.yml <<EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
cgroupDriver: systemd
cgroupsPerQOS: true
clusterDNS:
- 192.168.0.10
clusterDomain: cluster.local
containerLogMaxFiles: 5
containerLogMaxSize: 10Mi
contentType: application/vnd.kubernetes.protobuf
cpuCFSQuota: true
cpuManagerPolicy: none
cpuManagerReconcilePeriod: 10s
enableControllerAttachDetach: true
enableDebuggingHandlers: true
enforceNodeAllocatable:
- pods
eventBurst: 10
eventRecordQPS: 5
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
evictionPressureTransitionPeriod: 5m0s
failSwapOn: true
fileCheckFrequency: 20s
hairpinMode: promiscuous-bridge
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 20s
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
imageMinimumGCAge: 2m0s
iptablesDropBit: 15
iptablesMasqueradeBit: 14
kubeAPIBurst: 10
kubeAPIQPS: 5
makeIPTablesUtilChains: true
maxOpenFiles: 1000000
maxPods: 110
nodeStatusUpdateFrequency: 10s
oomScoreAdj: -999
podPidsLimit: -1
registryBurst: 10
registryPullQPS: 5
resolvConf: /etc/resolv.conf
rotateCertificates: true
runtimeRequestTimeout: 2m0s
serializeImagePulls: true
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 4h0m0s
syncFrequency: 1m0s
volumeStatsAggPeriod: 1m0s
EOF
cat > /etc/kubernetes/kubelet-conf.yml <<EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
cgroupDriver: systemd
cgroupsPerQOS: true
clusterDNS:
- 192.168.0.10
clusterDomain: cluster.local
containerLogMaxFiles: 5
containerLogMaxSize: 10Mi
contentType: application/vnd.kubernetes.protobuf
cpuCFSQuota: true
cpuManagerPolicy: none
cpuManagerReconcilePeriod: 10s
enableControllerAttachDetach: true
enableDebuggingHandlers: true
enforceNodeAllocatable:
- pods
eventBurst: 10
eventRecordQPS: 5
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
evictionPressureTransitionPeriod: 5m0s
failSwapOn: true
fileCheckFrequency: 20s
hairpinMode: promiscuous-bridge
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 20s
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
imageMinimumGCAge: 2m0s
iptablesDropBit: 15
iptablesMasqueradeBit: 14
kubeAPIBurst: 10
kubeAPIQPS: 5
makeIPTablesUtilChains: true
maxOpenFiles: 1000000
maxPods: 110
nodeStatusUpdateFrequency: 10s
oomScoreAdj: -999
podPidsLimit: -1
registryBurst: 10
registryPullQPS: 5
resolvConf: /etc/resolv.conf
rotateCertificates: true
runtimeRequestTimeout: 2m0s
serializeImagePulls: true
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 4h0m0s
syncFrequency: 1m0s
volumeStatsAggPeriod: 1m0s
EOF
2.配置unit文件
cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=network-online.target firewalld.service cri-docker.service docker.socket containerd.service
Wants=network-online.target
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \\
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig \\
--cert-dir=/etc/kubernete/pki \\
--client-ca-file=/etc/kubernetes/pki/ca.pem \\
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
--config=/etc/kubernetes/kubelet-conf.yml \\
--container-runtime-endpoint=unix:///run/containerd/containerd.sock \\
--node-labels=node.kubernetes.io/node= \\
--v=2
Restart=always
RestartSec=10s
TimeoutStartSec=300
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=network-online.target firewalld.service cri-docker.service docker.socket containerd.service
Wants=network-online.target
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \\
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig \\
--cert-dir=/etc/kubernete/pki \\
--client-ca-file=/etc/kubernetes/pki/ca.pem \\
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
--config=/etc/kubernetes/kubelet-conf.yml \\
--container-runtime-endpoint=unix:///run/containerd/containerd.sock \\
--node-labels=node.kubernetes.io/node= \\
--v=2
Restart=always
RestartSec=10s
TimeoutStartSec=300
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
3.启动
systemctl daemon-reload
systemctl enable --now kubelet.service
systemctl status kubelet.service
systemctl daemon-reload
systemctl enable --now kubelet.service
systemctl status kubelet.service
3.kube-proxy
1.创建 kube-proxy 配置文件
# 所有 k8s节点添加 kube-proxy 的配置
cat > /etc/kubernetes/kube-proxy.yaml << EOF
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
cgroupDriver: systemd
clusterDNS:
- 192.168.0.10
clientConnection:
acceptContentTypes: ""
burst: 10
contentType: application/vnd.kubernetes.protobuf
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
qps: 5
clusterCIDR: 172.16.0.0/12
configSyncPeriod: 15m0s
conntrack:
max: null
maxPerCore: 32768
min: 131072
tcpCloseWaitTimeout: 1h0m0s
tcpEstablishedTimeout: 24h0m0s
enableProfiling: false
healthzBindAddress: 0.0.0.0:10256
hostnameOverride: ""
iptables:
masqueradeAll: false
masqueradeBit: 14
minSyncPeriod: 0s
syncPeriod: 30s
ipvs:
masqueradeAll: true
minSyncPeriod: 5s
scheduler: "rr"
syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 0.0.0.0:10249
mode: "ipvs"
nodePortAddresses: null
oomScoreAdj: -999
portRange: ""
udpIdleTimeout: 250ms
clusterDomain: cluster.local
failSwapOn: false
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110
EOF
# 所有 k8s节点添加 kube-proxy 的配置
cat > /etc/kubernetes/kube-proxy.yaml << EOF
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
cgroupDriver: systemd
clusterDNS:
- 192.168.0.10
clientConnection:
acceptContentTypes: ""
burst: 10
contentType: application/vnd.kubernetes.protobuf
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
qps: 5
clusterCIDR: 172.16.0.0/12
configSyncPeriod: 15m0s
conntrack:
max: null
maxPerCore: 32768
min: 131072
tcpCloseWaitTimeout: 1h0m0s
tcpEstablishedTimeout: 24h0m0s
enableProfiling: false
healthzBindAddress: 0.0.0.0:10256
hostnameOverride: ""
iptables:
masqueradeAll: false
masqueradeBit: 14
minSyncPeriod: 0s
syncPeriod: 30s
ipvs:
masqueradeAll: true
minSyncPeriod: 5s
scheduler: "rr"
syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 0.0.0.0:10249
mode: "ipvs"
nodePortAddresses: null
oomScoreAdj: -999
portRange: ""
udpIdleTimeout: 250ms
clusterDomain: cluster.local
failSwapOn: false
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110
EOF
2.配置 unit文件
# 所有 k8s 节点添加 kube-proxy 的 service 文件
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
ExecStart=/usr/local/bin/kube-proxy \\
--config=/etc/kubernetes/kube-proxy.yaml \\
--cluster-cidr=172.16.0.0/12 \\
--v=2
Restart=always
RestartSec=10s
TimeoutStartSec=300
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
# 所有 k8s 节点添加 kube-proxy 的 service 文件
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
ExecStart=/usr/local/bin/kube-proxy \\
--config=/etc/kubernetes/kube-proxy.yaml \\
--cluster-cidr=172.16.0.0/12 \\
--v=2
Restart=always
RestartSec=10s
TimeoutStartSec=300
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
3.启动
systemctl daemon-reload
systemctl enable --now kube-proxy.service
systemctl status kube-proxy.service
systemctl daemon-reload
systemctl enable --now kube-proxy.service
systemctl status kube-proxy.service
3.6.3检查集群健康性
kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy ok
kubectl get --raw='/readyz?verbose'
...
readyz check passed
kubectl get --raw='/livez?verbose'
...
livez check passed
kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy ok
kubectl get --raw='/readyz?verbose'
...
readyz check passed
kubectl get --raw='/livez?verbose'
...
livez check passed
3.6.4 部署网络插件-master节点
- 版本兼容性
calico版本 | kubernetes版本 |
---|---|
v3.18 | v1.20、1.19、1.18 |
v3.19 | v1.21、v1.20、1.19 |
v3.20 | v1.21、v1.20、1.19 |
v3.21 | v1.22、v1.21、v1.20 |
v3.22 | v1.23、v1.22、v1.21 |
v3.23 | v1.23、v1.22、v1.21 |
v3.24 | v1.25、v1.24、v1.23、v1.22 |
v3.26 | v1.28、v1.27、v1.26、v1.25、v1.24 |
v3.27 | v1.29、v1.28、v1.27 |
v3.28 | v1.30、v1.29、v1.28、v1.27 |
1.calico
wget https://github.com/projectcalico/calico/blob/master/manifests/calico-typha.yaml
或者
wget https://projectcalico.docs.tigera.io/archive/v3.25/manifests/calico.yaml
wget https://github.com/projectcalico/calico/blob/master/manifests/calico-typha.yaml
或者
wget https://projectcalico.docs.tigera.io/archive/v3.25/manifests/calico.yaml
#修改POD网段
- name: CALICO_IPV4POOL_CIDR
value: "172.16.0.0/12"
# 修改为 BGP 模式
# Enable IPIP
- name: CALICO_IPV4POOL_IPIP
value: "Always" #改成Off
#修改POD网段
- name: CALICO_IPV4POOL_CIDR
value: "172.16.0.0/12"
# 修改为 BGP 模式
# Enable IPIP
- name: CALICO_IPV4POOL_IPIP
value: "Always" #改成Off
#或者通过sed修改
sed -i 's/# - name: CALICO_IPV4POOL_CIDR/- name: CALICO_IPV4POOL_CIDR/g' calico.yaml
sed -i 's/# value: "192.168.0.0\/16"/ value: "172.16.0.0\/12"/g' calico.yaml
sed -i 's/"type": "calico-ipam"/"type": "calico-ipam",\n "assign_ipv4": "true"/g' calico.yaml
sed -i "s#docker.io/calico/#m.daocloud.io/docker.io/calico/#g" calico.yaml
#或者通过sed修改
sed -i 's/# - name: CALICO_IPV4POOL_CIDR/- name: CALICO_IPV4POOL_CIDR/g' calico.yaml
sed -i 's/# value: "192.168.0.0\/16"/ value: "172.16.0.0\/12"/g' calico.yaml
sed -i 's/"type": "calico-ipam"/"type": "calico-ipam",\n "assign_ipv4": "true"/g' calico.yaml
sed -i "s#docker.io/calico/#m.daocloud.io/docker.io/calico/#g" calico.yaml
- 执行
kubectl apply -f calico.yaml
kubectl apply -f calico.yaml
- 查看效果
[root@kube-master-01 init_pack]# kubectl get pod -A -owide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-node-02 <none> <none>
kube-system calico-kube-controllers-bd77b565b-tv5jt 1/1 Running 0 34m 10.88.0.2 kube-node-01 <none> <none>
kube-system calico-node-2nc7p 1/1 Running 0 34m 10.103.236.152 kube-node-02 <none> <none>
kube-system calico-node-8qw5w 1/1 Running 0 34m 10.103.236.151 kube-node-01 <none> <none>
kube-system calico-node-sn9xm 1/1 Running 0 34m 10.103.236.150 kube-master-01 <none> <none>
[root@kube-master-01 init_pack]# kubectl get pod -A -owide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-node-02 <none> <none>
kube-system calico-kube-controllers-bd77b565b-tv5jt 1/1 Running 0 34m 10.88.0.2 kube-node-01 <none> <none>
kube-system calico-node-2nc7p 1/1 Running 0 34m 10.103.236.152 kube-node-02 <none> <none>
kube-system calico-node-8qw5w 1/1 Running 0 34m 10.103.236.151 kube-node-01 <none> <none>
kube-system calico-node-sn9xm 1/1 Running 0 34m 10.103.236.150 kube-master-01 <none> <none>
calicoctl客户端工具
下载地址:https://github.com/projectcalico/calico
#创建配置文件
mkdir /etc/calico -p
cat >/etc/calico/calicoctl.cfg <<EOF
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
datastoreType: "kubernetes"
kubeconfig: "/root/.kube/config"
EOF
#验证
[root@kube-master-01 init_pack]# calicoctl node status
Calico process is running.
IPv4 BGP status
+----------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+----------------+-------------------+-------+----------+-------------+
| 10.103.236.151 | node-to-node mesh | up | 02:11:45 | Established |
| 10.103.236.152 | node-to-node mesh | up | 02:11:48 | Established |
+----------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
#创建配置文件
mkdir /etc/calico -p
cat >/etc/calico/calicoctl.cfg <<EOF
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
datastoreType: "kubernetes"
kubeconfig: "/root/.kube/config"
EOF
#验证
[root@kube-master-01 init_pack]# calicoctl node status
Calico process is running.
IPv4 BGP status
+----------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+----------------+-------------------+-------+----------+-------------+
| 10.103.236.151 | node-to-node mesh | up | 02:11:45 | Established |
| 10.103.236.152 | node-to-node mesh | up | 02:11:48 | Established |
+----------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
2.coredns
官方文档,https://coredns.io/plugins/ready/
CoreDNS用于集群内部Service名称解析
wget https://raw.githubusercontent.com/coredns/deployment/master/kubernetes/coredns.yaml.sed
#修改corefile.yaml
Corefile: |
.:53 {
log
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa { #修改为
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf #修改为本机的resolv.conf
cache 30
loop
reload
loadbalance
}#去掉这个地方的后缀
#修改文件,参考/etc/kubernetes/kubelet-config.yml 配置文件中的clusterIP
spec:
selector:
k8s-app: kube-dns
clusterIP: 10.96.0.10 #根据自己需求进行修改
wget https://raw.githubusercontent.com/coredns/deployment/master/kubernetes/coredns.yaml.sed
#修改corefile.yaml
Corefile: |
.:53 {
log
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa { #修改为
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf #修改为本机的resolv.conf
cache 30
loop
reload
loadbalance
}#去掉这个地方的后缀
#修改文件,参考/etc/kubernetes/kubelet-config.yml 配置文件中的clusterIP
spec:
selector:
k8s-app: kube-dns
clusterIP: 10.96.0.10 #根据自己需求进行修改
3.6.5部署 Metrics Server
各版本对应关系
Metrics Server | kubernetes |
---|---|
v0.7.2 | v1.29.8 |
v0.7.1 | v1.29.2 |
v0.6.3 | v1.23.17 |
v0.6.0 | v1.22.2 |
#下载最新
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
#下载最新
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
- 修改配置
# 修改配置
vim components.yaml
---
# 1
- args:
- --cert-dir=/tmp
- --secure-port=10250
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem
- --requestheader-username-headers=X-Remote-User
- --requestheader-group-headers=X-Remote-Group
- --requestheader-extra-headers-prefix=X-Remote-Extra-
# 2
volumeMounts:
- mountPath: /tmp
name: tmp-dir
- name: ca-ssl
mountPath: /etc/kubernetes/pki
# 3
volumes:
- emptyDir: {}
name: tmp-dir
- name: ca-ssl
hostPath:
path: /etc/kubernetes/pki
---
# 修改配置
vim components.yaml
---
# 1
- args:
- --cert-dir=/tmp
- --secure-port=10250
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem
- --requestheader-username-headers=X-Remote-User
- --requestheader-group-headers=X-Remote-Group
- --requestheader-extra-headers-prefix=X-Remote-Extra-
# 2
volumeMounts:
- mountPath: /tmp
name: tmp-dir
- name: ca-ssl
mountPath: /etc/kubernetes/pki
# 3
volumes:
- emptyDir: {}
name: tmp-dir
- name: ca-ssl
hostPath:
path: /etc/kubernetes/pki
---
- 执行
kubectl apply -f components.yaml
kubectl apply -f components.yaml
- 查看效果
[root@kube-master-01 init_pack]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
kube-master-01 263m 13% 1487Mi 39%
kube-node-01 212m 10% 593Mi 15%
kube-node-02 162m 8% 566Mi 14%
[root@kube-master-01 init_pack]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
kube-master-01 263m 13% 1487Mi 39%
kube-node-01 212m 10% 593Mi 15%
kube-node-02 162m 8% 566Mi 14%
3.6.6 验证集群
集群结果:
- Pod必须能解析Service
- Pod必须能解析跨namespace的Service
- 每个节点都必须要能访问Kubernetes的kubernetes svc 443和kube-dns的service 53
- Pod和Pod之前要能通
a) 同namespace能通信
b) 跨namespace能通信
c) 跨机器能通信
1.创建
kubectl create deployment nginx --image=nginx --replicas=3
#创建负载均衡
kubectl expose deployment nginx --port=8080 --target-port=80
#查看pod,默认命名空间是defalut
[root@kube-master-01 CoreDNS]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-7854ff8877-8z9jj 1/1 Running 0 118s
nginx-7854ff8877-985nf 1/1 Running 0 118s
nginx-7854ff8877-9sszv 1/1 Running 0 118s
#查看service
[root@kube-master-01 CoreDNS]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 192.168.0.1 <none> 443/TCP 151m
nginx ClusterIP 192.168.212.179 <none> 8080/TCP 119s
#验证svc
[root@kube-master-01 CoreDNS]# curl -I 192.168.212.179:8080
HTTP/1.1 200 OK
Server: nginx/1.27.1
Date: Sun, 22 Sep 2024 05:25:47 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 12 Aug 2024 14:21:01 GMT
Connection: keep-alive
ETag: "66ba1a4d-267"
Accept-Ranges: bytes
kubectl create deployment nginx --image=nginx --replicas=3
#创建负载均衡
kubectl expose deployment nginx --port=8080 --target-port=80
#查看pod,默认命名空间是defalut
[root@kube-master-01 CoreDNS]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-7854ff8877-8z9jj 1/1 Running 0 118s
nginx-7854ff8877-985nf 1/1 Running 0 118s
nginx-7854ff8877-9sszv 1/1 Running 0 118s
#查看service
[root@kube-master-01 CoreDNS]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 192.168.0.1 <none> 443/TCP 151m
nginx ClusterIP 192.168.212.179 <none> 8080/TCP 119s
#验证svc
[root@kube-master-01 CoreDNS]# curl -I 192.168.212.179:8080
HTTP/1.1 200 OK
Server: nginx/1.27.1
Date: Sun, 22 Sep 2024 05:25:47 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 12 Aug 2024 14:21:01 GMT
Connection: keep-alive
ETag: "66ba1a4d-267"
Accept-Ranges: bytes
#或者
cat <<EOF | kubectl create -f -
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25.1
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
type: NodePort
EOF
# 查看
kubectl get pod
kubectl get svc
#或者
cat <<EOF | kubectl create -f -
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25.1
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
type: NodePort
EOF
# 查看
kubectl get pod
kubectl get svc
2.检查ip连通性
[root@kube-master-01 CoreDNS]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7854ff8877-8z9jj 1/1 Running 0 4m35s 172.18.10.65 kube-node-01 <none> <none>
nginx-7854ff8877-985nf 1/1 Running 0 4m35s 172.25.241.2 kube-node-02 <none> <none>
nginx-7854ff8877-9sszv 1/1 Running 0 4m35s 172.18.201.68 kube-master-01 <none> <none>
#在每个节点上ping其他pod节点上的ip
kubectl exec -ti busybox -- sh
/#ping pod_ip
[root@kube-master-01 CoreDNS]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7854ff8877-8z9jj 1/1 Running 0 4m35s 172.18.10.65 kube-node-01 <none> <none>
nginx-7854ff8877-985nf 1/1 Running 0 4m35s 172.25.241.2 kube-node-02 <none> <none>
nginx-7854ff8877-9sszv 1/1 Running 0 4m35s 172.18.201.68 kube-master-01 <none> <none>
#在每个节点上ping其他pod节点上的ip
kubectl exec -ti busybox -- sh
/#ping pod_ip
3.检查service可达性
#在每个节点上访问服务
curl service-ip:port
#在每个节点上访问服务
curl service-ip:port
4.检查dns
cat<<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- name: busybox
image: busybox:1.28.3
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
restartPolicy: Always
EOF
cat<<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- name: busybox
image: busybox:1.28.3
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
restartPolicy: Always
EOF
#进入pod容器中去
[root@kube-master-01 CoreDNS]# kubectl exec -it nginx-7854ff8877-9sszv /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-7854ff8877-9sszv:/#
#查看dns解析
root@nginx-7854ff8877-9sszv:/# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 192.168.0.10
options ndots:5
[root@kube-master-01 CoreDNS]# kubectl get service -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 192.168.0.10 <none> 53/UDP,53/TCP,9153/TCP 24m
root@nginx-7854ff8877-9sszv:/# curl -I nginx.default.svc.cluster.local:8080
#进入pod容器中去
[root@kube-master-01 CoreDNS]# kubectl exec -it nginx-7854ff8877-9sszv /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-7854ff8877-9sszv:/#
#查看dns解析
root@nginx-7854ff8877-9sszv:/# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 192.168.0.10
options ndots:5
[root@kube-master-01 CoreDNS]# kubectl get service -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 192.168.0.10 <none> 53/UDP,53/TCP,9153/TCP 24m
root@nginx-7854ff8877-9sszv:/# curl -I nginx.default.svc.cluster.local:8080
- 用pod解析默认命名空间中的kubernetes
kubectl get svc
#NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 192.168.0.1 <none> 443/TCP 32d
[root@kube-master-01 ~]# kubectl exec busybox -n default -- nslookup kubernetes
Server: 192.168.0.10
Address 1: 192.168.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 192.168.0.1 kubernetes.default.svc.cluster.local
kubectl get svc
#NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 192.168.0.1 <none> 443/TCP 32d
[root@kube-master-01 ~]# kubectl exec busybox -n default -- nslookup kubernetes
Server: 192.168.0.10
Address 1: 192.168.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 192.168.0.1 kubernetes.default.svc.cluster.local
测试跨命名空间是否可以解析
[root@kube-master-01 ~]# kubectl exec busybox -n default -- nslookup kube-dns.kube-system
Server: 192.168.0.10
Address 1: 192.168.0.10 kube-dns.kube-system.svc.cluster.local
Name: kube-dns.kube-system
Address 1: 192.168.0.10 kube-dns.kube-system.svc.cluster.local
[root@kube-master-01 ~]# kubectl exec busybox -n default -- nslookup kube-dns.kube-system
Server: 192.168.0.10
Address 1: 192.168.0.10 kube-dns.kube-system.svc.cluster.local
Name: kube-dns.kube-system
Address 1: 192.168.0.10 kube-dns.kube-system.svc.cluster.local
3.7 安装命令补全
yum install bash-completion -y
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
yum install bash-completion -y
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
alias ectl='etcdhelper --endpoints="10.103.236.150:2379,10.103.236.151:2379,10.103.236.152:2379" --cacert=/etc/etcd/ssl/etcd-ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem'
# 查看当前的 schedule 主节点
ectl get /registry/leases/kube-system/kube-scheduler
# 查看当前的 controllermanager 主节点
ectl get /registry/leases/kube-system/kube-controller-manager
cat >> /etc/profile << EOF
# ETCD 变量
export ETCDCTL_API=3
alias etcdctl='etcdctl --endpoints="10.103.236.150:2379,10.103.236.151:2379,10.103.236.152:2379" --cacert=/etc/etcd/ssl/etcd-ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem'
EOF
alias ectl='etcdhelper --endpoints="10.103.236.150:2379,10.103.236.151:2379,10.103.236.152:2379" --cacert=/etc/etcd/ssl/etcd-ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem'
# 查看当前的 schedule 主节点
ectl get /registry/leases/kube-system/kube-scheduler
# 查看当前的 controllermanager 主节点
ectl get /registry/leases/kube-system/kube-controller-manager
cat >> /etc/profile << EOF
# ETCD 变量
export ETCDCTL_API=3
alias etcdctl='etcdctl --endpoints="10.103.236.150:2379,10.103.236.151:2379,10.103.236.152:2379" --cacert=/etc/etcd/ssl/etcd-ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem'
EOF
读取 etcd 的方式:https://github.com/openshift/origin/tree/master/tools/etcdhelper
3.8 修改k8s数据目录
3.9 FAQ
[ERROR] Get "https://192.168.0.1:443/api?timeout=32s": tls: failed to verify certificate: x509: certificate is valid for 127.0.0.1,10.103.236.150,10.103.236.151,10.103.236.152, not 192.168.0.1
报错原因: 使用"192.168.0.1"作为svc地址,和证书预定义的svc的IP地址不匹配导致的错误。