k8s二进制方式部署
生产环境部署 K8s 集群的两种方式 :
- Kubeadm方式: Kubeadm 是一个 K8s 部署工具,提供 kubeadm init 和 kubeadm join,用于快速部署 Kubernetes 集群。
- 二进制方式: 从 github 下载发行版的二进制包,手动部署每个组件,组成 Kubernetes 集群。
总结: Kubeadm 降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可控,推荐使用二进制包部署 Kubernetes 集群,虽然部署麻烦,期间可以学习很多工作原理,也利于后期维护。
环境准备:
节点数 | 系统 | docker版本 | kubernetes版本 |
master(3台) | centos7 | docker-ce 19.03.9 | 1.20.8 |
worker(2台) | centos7 | docker-ce 19.03.9 | 1.20.8 |
#注意:master节点至少要2个cpu,否则报错 error execution phase preflight: [preflight] Some fatal errors occurred: [ERROR NumCPU]: the number of available CPUs 1 is less than the required 2
操作系统初始化设置:
1、修改/etc/hosts,设置主机名,添加内容如下:
192.168.15.215 k8s-master01
192.168.15.216 k8s-master02
192.168.15.217 k8s-master03
192.168.15.218 k8s-worker1
192.168.15.219 k8s-worker2
2、 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
systemctl stop NetworkManager #关闭后calico才可以管理网卡,否则有影响
systemctl disable NetworkManager
3、关闭 selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
setenforce 0 # 临时
4、关闭 swap
#swap开启会影响k8s编排和调度应用程序运行的效果,会降低性能
swapoff -a # 临时
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab # 永久
5、将桥接的 IPv4 流量传递到 iptables 的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system # 生效
6、安装常用工具:
yum -y install wget jq psmisc vim net-tools telnet yum-utils device-mapper-persistent-data lvm2 git network-scripts tar curl
7、时间同步
#各个节点需要通过时间服务器保持时间同步
yum install ntpdate -y
ntpdate time.windows.com 或者 ntpdate -u cn.pool.ntp.org(中国ntp服务器)
8、修改内核参数文件/etc/security/limits.conf,添加内容如下:
cat >> /etc/security/limits.conf <<EOF
* soft nofile 65535
* hard nofile 65535
* soft noproc 65535
* hard noproc 65535
* soft memlock unlimited
* hard memlock unlimited
EOF
9、升级一下系统,执行命令如下:
yum update -y --exclude=kernel* && reboot #排除内核,下面会单独升级内核
10、升级内核,至少要达到4.18+ 才可以
yum -y localinstall kernel-ml* (包含kernel-ml-5.17.5-1.el7.elrepo.x86_64.rpm和kernel-ml-devel-5.17.5-1.el7.elrepo.x86_64.rpm两个包)
更改内核启动顺序:
grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg
grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"
grubby --default-kernel #检查默认内核
reboot #最后重启即可
11、安装ipvsadm
yum -y install ipvsadm ipset sysstat conntrack libseccomp
内核配置ipvs模块
cat > /etc/modules-load.d/ipvs.conf << EOF
ip_vs
ip_vs_lc
ip_vs_wlc
ip_vs_rr
ip_vs_wrr
ip_vs_lblc
ip_vs_lblcr
ip_vs_dh
ip_vs_sh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF
#执行命令启动服务,注意,上一步升级内核如果不重启此处会不成功
systemctl enable --now systemd-modules-load.service
#重启系统后查看是否加载
lsmod | grep -e ip_vs -e nf_conntrack
注意:如果内核版本小于4.19,那么配置中的nf_conntrack应该为nf_conntrack_ipv4
12、开启一些k8s集群中必须的内核参数
cat >> /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward =1
fs.may_detach_mounts = 1
vm.overcommit_memory = 1
vm.panic_on.oom = 0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open = 52706963
net.netfilter.nf_conntrack_max = 2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_contrack_max = 65536
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF
#配置完成后,重启服务器,查看内核加载情况
lsmod | grep --color=auto -e ip_vs -e nf_conntrack
一、部署etcd集群:
Etcd 是一个分布式键值存储系统,Kubernetes 使用 Etcd 进行数据存储,所以先 准备一个 Etcd 数据库,为解决 Etcd 单点故障,应采用集群方式部署,这里使用 3 台组建集群,可容忍 1 台机器故障,当然,你也可以使用 5 台组建集群,可容忍 2 台机器故障。 本例子中使用三台master节点机器组成集群
etcd1 | 192.168.15.215 |
etcd2 | 192.168.15.216 |
etcd3 | 182.168.15.217 |
1、 准备 cfssl 证书生成工具 :
cfssl 是一个开源的证书管理工具,使用 json 文件生成证书,相比 openssl 更方便使用。
找任意一台服务器操作,这里用 Master 节点,执行命令如下:
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
2、 生成 Etcd 证书 :
2.1 自签证书颁发机构(CA):
#在当前用户的根目录下创建文件加TLS,里面创建目录etcd和k8s
mkdir -p ~/TLS/{etcd,k8s}
自签 CA:
#进入创建的etcd目录中
cd ~/TLS/etcd
#"expiry": "87600h", 表示证书过期时间
cat > etcd-ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"www": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
#再次执行命令创建etcd-ca-csr.json证书请求文件
cat > etcd-ca-csr.json << EOF
{
"CN": "etcd CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
EOF
可通过 cat etcd-ca-config.json | jq . 来检查json文件是否正确(需要提前yum -y install jq )


接下来执行如下命令生成证书, 会生成 ca.pem 和 ca-key.pem 文件,如下:
cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare etcd-ca -


2.2 使用自签 CA 签发 Etcd HTTPS 证书 :
创建证书申请文件:
#"192.169.15.*" 表示预留IP 可以写多个
cat > server-csr.json <<EOF
{
"CN": "etcd",
"hosts": [
"192.168.15.215",
"192.168.15.216",
"192.168.15.217"
"192.168.15.*"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
注:上述文件 hosts 字段中 IP 为所有 etcd 节点的集群内部通信 IP,一个都不能 少!为了方便后期扩容可以多写几个预留的 IP。
生成证书, 会生成 server.pem 和 server-key.pem 文件,执行命令如下:
cfssl gencert -ca=etcd-ca.pem -ca-key=etcd-ca-key.pem -config=etcd-ca-config.json -profile=www server-csr.json | cfssljson -bare server

3、下载etcd,地址:https://github.com/etcd-io/etcd/releases/tag/v3.5.0
接下来正式部署etcd,首先现在节点1上操作, 为简化操作,待会将节点 1 生成的所有文件拷贝到节点 2 和 节点 3 上
创建工作目录并解压二进制包:
mkdir /opt/etcd/{bin,cfg,ssl} -p
tar zxvf etcd-v3.5.0-linux-amd64.tar.gz
mv etcd-v3.5.0-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/
创建 etcd 配置文件 :
cat > /opt/etcd/cfg/etcd.conf <<EOF
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/opt/etcd/data"
ETCD_LISTEN_PEER_URLS="https://192.168.15.215:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.15.215:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.15.215:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.15.215:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.15.215:2380,etcd-2=https://192.168.15.216:2380,etcd-3=https://192.168.15.217:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
说明:
- ETCD_NAME:节点名称,集群中唯一
- ETCD_DATA_DIR:数据目录
- ETCD_LISTEN_PEER_URLS:集群通信监听地址
- ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址
- ETCD_INITIAL_ADVERTISE_PEERURLS:集群通告地址
- ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址
- ETCD_INITIAL_CLUSTER:集群节点地址
- ETCD_INITIALCLUSTER_TOKEN:集群 Token
- ETCD_INITIALCLUSTER_STATE:加入集群的当前状态,new 是新集群,existing 表示加入已有集群
通过systemd 管理 etcd :
cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--peer-cert-file=/opt/etcd/ssl/server.pem \
--peer-key-file=/opt/etcd/ssl/server-key.pem \
--trusted-ca-file=/opt/etcd/ssl/etcd-ca.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/etcd-ca.pem \
--logger=zap
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
拷贝刚才生成的证书 : 把刚才生成的证书拷贝到配置文件中的路径
#将第一步生成的证书文件,拷贝到ssl文件夹下
cp ~/TLS/etcd/*ca*pem ~/TLS/etcd/server*pem /opt/etcd/ssl/
将上面节点 1 所有生成的文件拷贝到master节点 2 和master节点 3 :
for i in k8s-master02 k8s-master03 ;do scp -r /opt/etcd ${i}:/opt ;done
for i in k8s-master02 k8s-master03 ;do scp -r /lib/systemd/system/etcd.service ${i}:/lib/systemd/system ;done
然后在节点 2 和节点 3 分别修改 etcd.conf 配置文件中的节点名称和当前服务器 IP: 例如
ETCD_NAME="etcd-2" #修改集群唯一标识
ETCD_DATA_DIR="/opt/etcd/data"
ETCD_LISTEN_PEER_URLS="https://192.168.15.216:2380" #改为本机IP
ETCD_LISTEN_CLIENT_URLS="https://192.168.15.216:2379" #改为本机IP
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.15.216:2380" #改为本机IP
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.15.216:2379" #改为本机IP
设置etcd开启自启动,如下命令:
systemctl daemon-reload
systemctl enable etcd --now #设置开机自启,并启动
注意:如果etcd集群通讯出现问题,显示已经有用户在使用,此时可以将集群中每个节点的/opt/etcd/data下的member删除,然后重启所有节点即可
查看集群状态,执行命令如下:
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/etcd-ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.15.215:2379,https://192.168.15.216:2379,https://192.168.15.217:2379" endpoint health --write-out=table
如果输出上面信息,就说明集群部署成功:

如果有问题第一步先看日志:/var/log/message 或 journalctl -u etcd
注意:etcd集群可单独部署在任意机器上,只要能和apiserver通讯即可,etcd备份可参考:k8s之etcd的备份与回恢复 – IT运维 (ywdevops.cn)
二、部署docker:
以下在所有节点操作,这里采用二进制安装,用 yum 安装也一样
1、解压二进制包,并将可执行文件加入到环境变量中,执行命令如下:
tar -zxvf docker-19.03.9.tgz #解压二进制包
mv docker/* /usr/bin #移动到环境变量/usr/bin/目录下
2、由于新版的kubernetes使用systemd来进行资源限制,因此修改docker的CgoupDriver为systemd,执行命令如下:
mkdir /etc/docker
cat > /etc/docker/daemon.json << EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 5,
"log-driver": "json-file",
"storage-driver": "overlay2",
"data-root": "/data/docker",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"log-opts":{
"max-size": "300m",
"max-file": "2"
},
"live-restore": true
}
EOF
#live-restore:true 重启docker 不影响运行中的容器
#设置完成后,重启docker
3、通过systemctl 管理docker,执行命令如下:
cat > /usr/lib/systemd/system/docker.service << EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
EOF
3、 启动并设置开机启动 :
systemctl daemon-reload
systemctl start docker
systemctl enable docker
注意:如果docker启动的时候卡死,停止也不行,总之无法启动,可能是selinux没有关闭,k8s1.24之后不在支持dockershim插件,此时可以通过替代品Cri-dockerd实现继续使用docker
三、部署nginx+Keepalived 高可用负载均衡器
注:本例子部署所有组件连接api-server时候直接指定了vip地址,还可以先指定一台机器的api-server地址后,最后统一将配置文件中的机器IP地址和端口替换为vip的地址和端口
1、部署keepalived,可直接通过yum安装或者编译安装,参考链接:部署keepalived
编辑/etc/keealived/keepalived.conf,添加内容如下:
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER #注意其余改为BACKUP
interface ens192
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.15.253/24 #VIP
}
}
2、编译安装nginx,可参考kubeadm部署章节,链接地址:kubeadm部署k8s
3、执行命令启动keepalived和nginx,如下:
systemctl enable keepalived --now #添加开机启动并启动
systemctl enable nginx --now
四、部署Master Node:
1、 自签证书颁发机构(CA) :
#进入目录
cd ~/TLS/k8s
#创建ca文件,注意json的数据格式要对齐
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
cat > ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
生成证书, 会生成 ca.pem 和 ca-key.pem 文件 ,执行命令如下:
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -


2、 使用自签 CA 签发 kube-apiserver HTTPS 证书 :
创建证书申请文件:
cat > server-csr.json <<EOF
{
"CN": "kubernetes",
"hosts": [
"10.0.0.1",
"127.0.0.1",
"192.168.15.215",
"192.168.15.216",
"192.168.15.217",
"192.168.15.222",
"192.168.15.223",
"192.168.15.253",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
- 10.0.0.1:serverIP 的首个IP地址
- 192.168.15.253:VIP
- 其余IP为apiserverIP,可预留多个
注:上述文件 hosts 字段中 IP 为所有 Master/LB/VIP IP,一个都不能少!为了方 便后期扩容可以多写几个预留的 IP。
生成证书,会生成server.pem和server-key.pem文件,如下命令,
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server

3、从github上下载kubeneter-server的二进制文件,下载地址:
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md
解压二进制包并拷贝可执行文件,如下:
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} #创建文件夹
tar zxvf kubernetes-server-linux-amd64.tar.gz #解压缩
cd kubernetes/server/bin #拷贝包
cp kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin
cp kubectl /usr/bin/
#将kubectl文件复制到其余两个master节点
for i in k8s-master02 k8s-master03; do scp kubectl ${i}:/usr/bin/ ; done
4、 部署 kube-apiserver :
创建配置文件:
cat > /opt/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--etcd-servers=https://192.168.15.215:2379,https://192.168.15.216:2379,https://192.168.15.217:2379 \\
--bind-address=192.168.15.215 \\
--secure-port=6443 \\
--advertise-address=192.168.15.215 \\
--allow-privileged=true \\
--service-cluster-ip-range=10.0.0.0/24 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/opt/kubernetes/cfg/token.csv \\
--service-node-port-range=30000-32767 \\
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \\
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \\
--tls-cert-file=/opt/kubernetes/ssl/server.pem \\
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \\
--client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--service-account-issuer=https://kubernetes.default.svc.cluster.local \\
--service-account-signing-key-file=/opt/kubernetes/ssl/server-key.pem \\
--etcd-cafile=/opt/etcd/ssl/etcd-ca.pem \\
--etcd-certfile=/opt/etcd/ssl/server.pem \\
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \\
--requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--proxy-client-cert-file=/opt/kubernetes/ssl/server.pem \\
--proxy-client-key-file=/opt/kubernetes/ssl/server-key.pem \\
--requestheader-allowed-names=kubernetes \\
--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=/opt/kubernetes/logs/k8s-audit.log"
EOF
注:上面两个\ \ 第一个是转义符,第二个是换行符,使用转义符是为了使用 EOF 保留换行符。
- –logtostderr:启用日志
- –v : 日志等级
- –log-dir:日志目录
- –etcd-servers:etcd 集群地址
- –bind-address:监听地址 ,也可以写0.0.0.0
- –secure-port:https 安全端口
- –advertise-address:集群通告地址
- –allow-privileged:启用授权
- –service-cluster-ip-range:Service 虚拟 IP 地址段
- –enable-admission-plugins:准入控制模块
- –authorization-mode:认证授权,启用 RBAC 授权和节点自管理
- –enable-bootstrap-token-auth:启用 TLS bootstrap 机制
- –token-auth-file:bootstrap token 文件
- –service-node-port-range:Service nodeport 类型默认分配端口范围
- –kubelet-client-xxx:apiserver 访问 kubelet 客户端证书
- –tls-xxx-file:apiserver https 证书
- 1.20 版本必须加的参数:–service-account-issuer,–service-accountsigning-key-file
- –etcd-xxxfile:连接 Etcd 集群证书
- –audit-log-xxx:审计日志
- 启动聚合层相关配置:–requestheader-client-ca-file,–proxy-clientcert-file,–proxy-client-key-file,–requestheader-allowed-names,- -requestheader-extra-headers-prefix,–requestheader-group-headers, –requestheader-username-headers,–enable-aggregator-routing(此参数设置为true,metric-server才可采集到数据)
拷贝刚才生成的证书 :
把刚才生成的证书拷贝到配置文件中的路径, 执行命令如下:
cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/
启用 TLS Bootstrapping 机制 :
TLS Bootstraping:Master apiserver 启用 TLS 认证后,Node 节点 kubelet 和 kube-proxy 要与 kube-apiserver 进行通信,必须使用 CA 签发的有效证书才可以, 当 Node 节点很多时,这种客户端证书颁发需要大量工作,同样也会增加集群扩展 复杂度。为了简化流程,Kubernetes 引入了 TLS bootstraping 机制来自动颁发客 户端证书,kubelet 会以一个低权限用户自动向 apiserver 申请证书,kubelet 的 证书由 apiserver 动态签署。所以强烈建议在 Node 上使用这种方式,目前主要用 于 kubelet,kube-proxy 还是由我们统一颁发一个证书。
TLS bootstraping 工作流程:

创建上述配置文件中 token 文件:
cat > /opt/kubernetes/cfg/token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
#格式:token,用户名,UID,用户组
#token 也可自行生成替换:head -c 16 /dev/urandom | od -An -t x | tr -d ' '
#kubelet-bootstrap用户将作为kubelet首次启动的预设用户,默认情况下没有任何权限,需要给它授权使用此token请求apiserver,包括创建CSR请求
systemd 管理 apiserver :
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=etcd.service
Wants=etcd.service
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
将master节点1的文件拷贝到对应的master节点2和master节点3上面,执行命令如下:
for i in k8s-master02 k8s-master03;do scp -r /opt/kubernetes ${i}:/opt ;done
for i in k8s-master02 k8s-master03;do scp /lib/systemd/system/kube-apiserver.service ${i}:/lib/systemd/system ;done
注:拷贝过去之后记得要修改节点2和节点的kube-apiserver.conf文件中IP地址为本机的IP地址,否则apiserver启动会失败
启动并设置开机启动
systemctl daemon-reload
systemctl enable kube-apiserver --now

1、启动日志输出:kube-apiserver[7509]: E0715 10:38:57.686241 7509 instance.go:392] Could not construct pre-rendered responses for ServiceAccountIss..., got: api
Hint: Some lines were ellipsized, use -l to show in full.
解决:查看kube-apiserver.conf中的server-account-issuer配置,修改为https://kubernetes.default.svc.cluster.local
2、Unable to remove old endpoints from kubernetes service: StorageError: key not found, Code: 1, Key: /registry/masterleases/10.88.15.215, ResourceVersion: 0, AdditionalErrorMsg:
解决:此错误无影响
3、etcd提示:leader failed to send out heartbeat on time; took too long, leader is overloaded likely from slow disk,
解决:此内容并非错误,只是提示数据写入etcd时间长,不影响apiserver使用,将etcd磁盘换成ssd即可
注:3个master节点都部署了apiserver+controller-manager+scheduler,kube-controller-manager、kube-scheduler是连接本机的kube-apiserver,可以把它们看做一个整体,只要有一个节点的apiserver实例正常,就可以保证集群apiserver可用,最外层通过haproxy/nginx做负载
5、 部署 kube-controller-manager(master1节点执行) :
创建配置文件 : (三台master机器都要执行,可copy过去)
cat > /opt/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect=true \\
--kubeconfig=/opt/kubernetes/cfg/kube-controller-manager.kubeconfig \\
--bind-address=127.0.0.1 \\
--allocate-node-cidrs=true \\
--cluster-cidr=10.244.0.0/16 \\
--service-cluster-ip-range=10.0.0.0/24 \\
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--root-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--cluster-signing-duration=87600h0m0s"
EOF
- –kubeconfig:连接 apiserver 配置文件
- –leader-elect:当该组件启动多个时,自动选举(HA)
- –cluster-signing-cert-file/–cluster-signing-key-file:自动为 kubelet 颁发证书的 CA,与 apiserver 保持一致
- –cluster-cidr: pod网段地址
#将配置文件copy到其余机器上
for i in k8s-master02 k8s-master03 ;do scp /opt/kubernetes/cfg/kube-controller-manager.conf ${i}:/opt/kubernetes/cfg ;done
生成 kube-controller-manager 证书: (可将证书拷贝到其余节点)
# 切换工作目录
cd ~/TLS/k8s
# 创建证书请求文件
cat > kube-controller-manager-csr.json << EOF
{
"CN": "system:kube-controller-manager",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "System"
}
]
}
EOF
生成证书,会生成两个pem文件 :
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

#将生成的证书文件复制到本机的/opt/kubernetes/ssl
cp kube-controller-manager.pem kube-controller-manager-key.pem /opt/kubernetes/ssl/
#将证书文件复制到其余master节点
for i in k8s-master02 k8s-master03;do scp /opt/kubernetes/ssl/{kube-controller-manager.pem, kube-controller-manager-key.pem} ${i}:/opt/kubernetes/ssl/ ;done
生成 kubeconfig 文件,用于连接apiserver:
KUBE_CONFIG="/opt/kubernetes/cfg/kube-controller-manager.kubeconfig"
KUBE_APISERVER="https://192.168.15.253:16443"
#注意要在证书所在路径执行,否则提示找不到证书文件
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials kube-controller-manager \
--client-certificate=./kube-controller-manager.pem \
--client-key=./kube-controller-manager-key.pem \
--embed-certs=true \
--kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
--cluster=kubernetes \
--user=kube-controller-manager \
--kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
systemd 管理 controller-manager :
cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
将服务启动配置文件和kubeconfig文件copy到其他master节点机器上,执行命令如下:
for i in k8s-master02 k8s-master03;do scp /lib/systemd/system/kube-controller-manager.service ${i}:/lib/systemd/system;done
for i in k8s-master02 k8s-master03;do scp /opt/kubernetes/cfg/kube-controller-manager.kubeconfig ${i}:/opt/kubernetes/cfg/;done
启动并设置开机启动:
systemctl daemon-reload
systemctl enable kube-controller-manager --now
启动后查看日志是否有报错,无报错即表示没问题
#如下错误可忽略
Failed to start service controller: WARNING: no cloud provider provided, services of type LoadBalancer will fail
6、 部署 kube-scheduler :(三台master都要部署)
创建配置文件 :
cat > /opt/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect \\
--kubeconfig=/opt/kubernetes/cfg/kube-scheduler.kubeconfig \\
--bind-address=127.0.0.1"
EOF
- –kubeconfig:连接 apiserver 配置文件
- –leader-elect:当该组件启动多个时,自动选举(HA)
#将配置文件发送到其余master节点
for i in k8s-master02 k8s-master03 ;do scp /opt/kubernetes/cfg/kube-scheduler.conf ${i}:/opt/kubernetes/cfg/ ; done
生成 kube-scheduler 证书请求文件CSR:
# 切换工作目录
cd ~/TLS/k8s
#创建证书请求文件
cat > kube-scheduler-csr.json << EOF
{
"CN": "system:kube-scheduler",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing",
"O": "system:masters",
"OU": "System"
}
]
}
EOF
生成证书,名称为kube-scheduler-key.pem和kube-scheduler.pem,命令如下:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler

#先将证书文件copy到本机的/opt/kubernetes/ssl
cp kube-scheduler-key.pem kube-scheduler.pem /opt/kubernetes/ssl
#再将证书copy导其余的master节点上
for i in k8s-master02 k8s-master03;do scp /opt/kubernetes/ssl/{kube-scheduler-key.pem,kube-scheduler.pem} ${i}:/opt/kubernetes/ssl/ ;done
生成 kubeconfig 文件,用于连接apiserver:
KUBE_CONFIG="/opt/kubernetes/cfg/kube-scheduler.kubeconfig"
KUBE_APISERVER="https://192.168.15.253:16443"
#下面步骤需要进入/opt/kubernetes/ssl目录执行
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials kube-scheduler \
--client-certificate=./kube-scheduler.pem \
--client-key=./kube-scheduler-key.pem \
--embed-certs=true \
--kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
--cluster=kubernetes \
--user=kube-scheduler \
--kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
systemd 管理 scheduler :
cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-scheduler.conf
ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
#服务配置文件和kubeconfig文件copy到其余两个master节点上
for i in k8s-master02 k8s-master03;do scp /lib/systemd/system/kube-scheduler.service ${i}:/lib/systemd/system ;done
for i in k8s-master02 k8s-master03;do scp /opt/kubernetes/cfg/kube-scheduler.kubeconfig ${i}:/opt/kubernetes/cfg/ ;done
启动并设置开机启动 :
systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler
7、 查看集群状态 :
注意:此步骤可以单独部署集群之外的机器上
生成 kubectl 连接集群的证书:
# 切换工作目录
cd ~/TLS/k8s
cat > admin-csr.json << EOF
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing",
"O": "system:masters",
"OU": "System"
}
]
}
EOF
生成证书:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

复制证书文件到/opt/kubernetes/ssl中
cp admin-key.pem admin.pem /opt/kubernetes/ssl/
生成 kubeconfig 文件:
#创建文件夹.kube
mkdir /root/.kube
KUBE_CONFIG="/root/.kube/config"
KUBE_APISERVER="https://192.168.15.253:16443" #注意:此地址为VIP地址,防止单点apiserver挂掉
cd /opt/kubernetes/ssl
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials cluster-admin \
--client-certificate=./admin.pem \
--client-key=./admin-key.pem \
--embed-certs=true \
--kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
--cluster=kubernetes \
--user=cluster-admin \
--kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
通过 kubectl 工具查看当前集群组件状态,输出如下表示各组件正常,如图:

注意:此步骤可以不部署在任何一个节点上,可以单独部署一个机器用来管理集群,在生成 kubeconfig 文件时kube-apiserver 地址要写vip地址(防止其中某个节点Down)
配置kubectl命令补全:
yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
kubectl completion bash > ~/.kube/completion.bash.inc
source '/root/.kube/completion.bash.inc'
source $HOME/.bash_profile
8、授权kubelet-bootstrap用户允许请求证书:
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
#在默认情况下,kubelet 通过 bootstrap.kubeconfig 中的预设用户 Token 声明了自己的身份,然后创建 CSR 请求,但是默认情况下此用户没任何权限的,包括创建 CSR 请求;所以需要如下命令创建一个 ClusterRoleBinding,将预设用户 kubelet-bootstrap 与内置的 ClusterRole system:node-bootstrapper 绑定到一起,使其能够发起 CSR 请求
五、 部署Node:
在master1节点执行,因为master节点也部署kubelet和proxy
#解压kubernetes-server-linux-amd64.tar.gz
tar -zxvf kubernetes-server-linux-amd64.tar.gz
cd kubernetes/server/bin
#copy到本地的/opt/kubernetes/bin路径下
cp kubelet kube-proxy /opt/kubernetes/bin
在node节点创建路径和文件夹
for i in k8s-node01 k8s-node02;do ssh ${i} mkdir -p /opt/kubernetes/{cfg,logs,bin,ssl} ;done
#将kubelet、kube-proxy拷贝到其余的master节点和node节点
for i in k8s-master02 k8s-master03 k8s-node01 k8s-node02;do scp /opt/kubernetes/bin/{kubelet, kube-proxy} ${i}:/opt/kubernetes/bin/ ;done
#将ca.pem、ca-key.pem文件拷贝到其余的node节点上
for i in k8s-node01 k8s-node02;do scp /opt/kubernetes/ssl/{ca.pem,ca-key.pem} ${i}:/opt/kubernetes/ssl/ ;done
注意:kubelet启动的时候需要ca.pem和ca-key.pem,没有这两个文件启动会报错
部署 kubelet (只在master1执行):
1、 创建配置文件 :
#导入pause镜像,执行命令docker load -i pause-amd64:3.3或者从阿里云下载:
docker pull registry.aliyuncs.com/google_containers/pause-amd64:3.3
#创建文件
cat > /opt/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=k8s-master1 \\
--network-plugin=cni \\
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \\
--config=/opt/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/opt/kubernetes/ssl \\
--pod-infra-container-image=registry.aliyuncs.com/google_containers/pause-amd64:3.3"
EOF
- 注意更改hostname-override名字
cat > /opt/kubernetes/cfg/kubelet-config.yml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: systemd #注意,驱动要和/etc/docker/daemon.json中一致
clusterDNS:
- 10.0.0.10
clusterDomain: cluster.local
failSwapOn: false
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /opt/kubernetes/ssl/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
- clusterDNS:集群DNS地址,一般为server ip的第十个IP地址
3、 生成 kubelet 初次加入集群引导 kubeconfig 文件 :
KUBE_CONFIG="/opt/kubernetes/cfg/bootstrap.kubeconfig"
KUBE_APISERVER="https://192.168.15.253:16443" #注意:连接的是VIP
TOKEN=$(awk -F "," '{print $1}' /opt/kubernetes/cfg/token.csv) # 与 token.csv 里保持一致
# 生成 kubelet bootstrap kubeconfig 配置文件,注意,需要先将master节点的/opt/kubernetes/ssl下的证书文件拷贝到worker节点中
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials "kubelet-bootstrap" \
--token=${TOKEN} \
--kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
--cluster=kubernetes \
--user="kubelet-bootstrap" \
--kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
4、 systemd 管理 kubelet :
cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
After=docker.service
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kubelet.conf
ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
5、将master1节点的kubelet相关组件发送到其他master和worker节点,举例如下:
for i in k8s-master02 k8s-master03 k8s-node01 k8s-node02;do scp /opt/kubernetes/cfg/{kubelet.conf,kubelet-config.yml,bootstrap.kubeconfig} ${i}:/opt/kubernetes/cfg/ ;done
for i in k8s-master02 k8s-master03 k8s-node01 k8s-node02;do scp /lib/systemd/system/kubelet.service ${i}:/lib/systemd/system ;done
注意: 目标机器上记得修改kubelet.conf中的hostname-override的
6、 启动并设置开机启动(所有节点) :
systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet
批准节点加入集群
1、手动方式批准:
在 kubelet 首次启动后,如果用户 Token 没问题,并且 RBAC 也做了相应的设置,那么此时在集群内应该能看到 kubelet 发起的 CSR 请求,如图:

在master节点执行,也可在单独的用于连接集群的机器上执行如下命令
# 批准加入集群
kubectl certificate approve node-csr-8CrwSP6Rpx7sxwa3T_DNl5AEyLEWuowxbruOasn6nYA
查看节点信息,如图:

注:由于网络插件还没有部署,节点会没有准备就绪 NotReady
注意:如果删除了节点,需要删除之前的csr请求,找到节点的/opt/kubernetes/ssl与/opt/kubernetes/cfg目录,删除如下几个文件和kubelet.kubeconfig文件:

删除后,重启kubelet,即可在master节点重新看到Pending请求
可通过如下命令查看csr属于哪个节点,并执行删除操作:
kubectl describe csr node-csr-7reKUW9KL3Ec70E6xvE834I_-BgyyH7Glx7wTTUC04s
kubectl delete csr node-csr-7reKUW9KL3Ec70E6xvE834I_-BgyyH7Glx7wTTUC04s
2、自动方式批准:
参考:kubelet初始化过程
部署 kube-proxy (只在master1执行):
1、 创建配置文件 :
cat > /opt/kubernetes/cfg/kube-proxy.conf << EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--config=/opt/kubernetes/cfg/kube-proxy-config.yml"
EOF
2、 配置参数文件 :
cat > /opt/kubernetes/cfg/kube-proxy-config.yml << EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
metricsBindAddress: 0.0.0.0:10249
clientConnection:
kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: k8s-master1
clusterCIDR: 10.244.0.0/16
mode: "ipvs"
EOF
3、 生成 kube-proxy.kubeconfig 文件 :
# 切换工作目录
cd ~/TLS/k8s
#创建证书请求文件
cat > kube-proxy-csr.json << EOF
{
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
生成证书:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy

生成 kubeconfig 文件:
KUBE_CONFIG="/opt/kubernetes/cfg/kube-proxy.kubeconfig"
KUBE_APISERVER="https://192.168.15.253:16443" #注意:此位置为VIP
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials kube-proxy \
--client-certificate=./kube-proxy.pem \
--client-key=./kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
4、 systemd 管理 kube-proxy
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Proxy
After=network.target
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-proxy.conf
ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
5、将master1节点上的kube-proxy相关文件发送到master和worker节点中,举例如下:
for i in k8s-master02 k8s-master03 k8s-node01 k8s-node02;do scp kube-proxy.conf kube-proxy-config.yml kube-proxy.kubeconfig ${i}:/opt/kubernetes/cfg/ ;done
for i in k8s-master02 k8s-master03 k8s-node01 k8s-node02;do scp /lib/systemd/system/kube-proxy.service ${i}:/lib/systemd/system ;done
注意:要修改kube-proxy-config.yml中的hostnameOverride的值
6、 启动并设置开机启动(全部节点) :
systemctl daemon-reload
systemctl start kube-proxy
systemctl enable kube-proxy
注:如果pod无法ping通svc的IP地址,可能是kube-proxy模式问题,修改为ipvs即可,查看当前模式命令:curl 127.0.0.1:10249/proxyMode
六、部署网络组件 :
Calico 是一个纯三层的数据中心网络方案,是目前 Kubernetes 主流的网络方案。
Calico以DaemonSet方式运行在集群的每个节点上,当扩容node节点后,新节点会自动运行calico的Pod
下载地址:https://projectcalico.docs.tigera.io/getting-started/kubernetes/self-managed-onprem/onpremises
下载命令:curl https://projectcalico.docs.tigera.io/manifests/calico.yaml -O
1、首先下载calico.yaml文件,编辑文件,修改镜像地址为内部的harbor地址(两个cni地址、一个flexvol地址、一个node地址、一个controllers地址),如图:

2、创建密钥认证文件(集群master1节点创建即可,其余连接到集群的都可以使用)
#首先编辑docker文件,添加仓库地址,执行命令如下:
vim /etc/docker/daemon.json
#添加内容如下:
"insecure-registries":["192.168.26.131"]
#重启docker
systemctl restart docker
#登录harbor
docker login 192.168.26.131
#进入root/.docker目录下,执行命令生成密钥
cat config.json | base64 #可以得到一串字符串
#编辑文件secret.yaml添加内容如下,其中.dockerconfigjson位置填写上一步生成的加密字符串,namespace指定命名空间,name用于指定名字,可自定义,其余都按照下图写即可

apiVersion: v1
kind: Secret
metadata:
name: secret-key
namespace: kube-system
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxMC44OC4yNi4xMzEiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTkuMDMuOSAobGludXgpIgoJfQp9
type: kubernetes.io/dockerconfigjson
#配置完成后,执行命令创建密钥认证
kubectl create -f secret.yaml
#执行命令查看,要执行命名空间,如下:
kubectl get secret -n kube-system
3、在calico.yaml中配置密钥认证文件,一共两个位置需要配
第一个位置是DaemonSet控制器位置,也就是cni容器上方,如图:

第二个是Deployment控制器位置,也就是controllers容器上方,如图:

注:在执行下面的apply命令之前确保所有节点都可以登录到仓库中,docker login 仓库地址
4、配置完成后执行命令创建calico网络组件,如下:
kubectl apply -f calico.yaml
5、通过如下命令查看calico是否创建成功,记得执行命名空间,如图:

从上图可以看出,状态都是running,表示成功,此时再次执行kubectl get node 可以看到已经显示Ready,如图:

注意:如果不改变其他配置,calico默认采用IPIP网络模式
calico配置文件,适用于1.20.8版本的kubernetes,参考:calico清单文件
授权 apiserver 访问 kubelet :
在master节点执行命令如下:
cat > apiserver-tokkubelet-rbac.yaml <<EOF
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
- pods/log
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: kubernetes
EOF

执行如下命令创建授权:
kubectl apply -f apiserver-to-kubelet-rbac.yaml

注意:如果不授权,那么通过kubectl logs查看日志会提示错误如下:
Error from server (Forbidden): Forbidden (user=kubernetes, verb=get, resource=nodes, subresource=proxy) ( pods/log calico-node-kg9pc)
部署 CoreDNS
CoreDNS 用于集群内部 Service 名称解析
执行如下命令运行coredns,如下:
kubectl apply -f coredns.yaml
查看是否创建成功,如图:

coredns内容参考:coredns清单文件
说明:
- 注意clusterIP的地址,要与kubelet配置文件中的clusterdns地址一致
集群可用性验证
- pod必须可以解析service
- pod必须可以解析跨namspace的service
- 每个节点都必须能访问kubernetes的service(443端口)和kube-dns的service(53端口)
- Pod和pod之间要能通(同namespace、跨namespace、跨机器能通)
1、创建busybox的pod,在内部验证解析service和跨namespace的service,如图:

注:busybox版本可用1.28.3,最新版本可能出现解析有问题
2、验证所有节点访问kubernetes的service(443端口)和kube-dns的service(53端口),如图:

3、pod与pod之间通信验证,登录进入pod内部,ping其余Pod的IP即可
metricsever部署
参考链接:metric-server部署
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步