kubernetes 集群搭建 -- 二进制方式

主机信息

作为练习,只准备一台master,一台node,操作系统为centos7.9,多台node的添加只是重复工作。

参照上一篇,和kubeadm方式安装时的初始化一样,进行关闭防火墙、关闭 selinux、关闭swap、修改主机名、在 master 添加 hosts、将桥接的IPv4流量传递到 iptables 的链以及时间同步等初始化工作。

部署Etcd 集群

Etcd 是一个分布式键值存储系统,Kubernetes 使用 Etcd 进行数据存储,所以先准备一个 Etcd 数据库,为解决 Etcd 单点故障,应采用集群方式部署,这里只使用 2 台组建集群。

3台组件的集群,可容忍 1 台机器故障;5 台组建的集群,可容忍 2 台机器故障。

注:为了节省机器,这里与 K8s 节点机器复用;当然也可以独立于 k8s 集群之外部署,只要apiserver 能连接到就行。

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

就可以使用这三个命令了:

[root@binary-master bin]# pwd
/usr/local/bin
[root@binary-master bin]# ll
total 18808
-rwxr-xr-x 1 root root 10376657 Mar 30  2016 cfssl
-rwxr-xr-x 1 root root  6595195 Mar 30  2016 cfssl-certinfo
-rwxr-xr-x 1 root root  2277873 Mar 30  2016 cfssljson

2.生成 Etcd 证书

(1)自签证书颁发机构(CA)

创建工作目录:

mkdir -p ~/TLS/{etcd,k8s}
cd TLS/etcd

自签CA,两个json文件:

cat > ca-config.json<< EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"www": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
cat > ca-csr.json<< EOF
{
"CN": "etcd CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
EOF

生成证书(初始化):cfssl gencert -initca ca-csr.json | cfssljson -bare ca –

[root@binary-master etcd]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
2021/03/22 17:36:34 [INFO] generating a new CA key and certificate from CSR
2021/03/22 17:36:34 [INFO] generate received request
2021/03/22 17:36:34 [INFO] received CSR
2021/03/22 17:36:34 [INFO] generating key: rsa-2048
2021/03/22 17:36:35 [INFO] encoded CSR
2021/03/22 17:36:35 [INFO] signed certificate with serial number 558179141153695072425640815117027228526462947382
[root@binary-master etcd]# ls *pem
ca-key.pem  ca.pem

(2)使用自签 CA 签发 Etcd HTTPS 证书

创建证书申请文件:

cat > server-csr.json<< EOF
{
"CN": "etcd",
"hosts": [
"172.31.93.210",
"172.31.93.211"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF

注:上述文件 hosts 字段中 IP 为所有 etcd 节点的集群内部通信 IP,一个都不能少!为了方便后期扩容可以多写几个预留的 IP。

生成证书:cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server

[root@binary-master etcd]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
2021/03/22 17:50:56 [INFO] generate received request
2021/03/22 17:50:56 [INFO] received CSR
2021/03/22 17:50:56 [INFO] generating key: rsa-2048
2021/03/22 17:50:56 [INFO] encoded CSR
2021/03/22 17:50:56 [INFO] signed certificate with serial number 487201065380785180427832079165743752767773807902
2021/03/22 17:50:56 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@binary-master etcd]# ls *.pem
ca-key.pem  ca.pem  server-key.pem  server.pem

其中server-key.pem和server.pem就是最后需要的etcd证书。

3.部署etcd集群

Etcd下载地址:https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz

以下在master上操作,为简化操作,待会将master 生成的所有文件拷贝到node节点。

(1)创建工作目录并解压二进制包,

mkdir -p /opt/etcd/{bin,cfg,ssl}
tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/

(2)创建 etcd 配置文件

cat > /opt/etcd/cfg/etcd.conf << EOF
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://172.31.93.210:2380"
ETCD_LISTEN_CLIENT_URLS="https://172.31.93.210:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.31.93.210:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://172.31.93.210:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://172.31.93.210:2380,etcd-2=https://172.31.93.211: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_PEER_URLS:集群通告地址
ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址
ETCD_INITIAL_CLUSTER:集群节点地址
ETCD_INITIAL_CLUSTER_TOKEN:集群 Token
ETCD_INITIAL_CLUSTER_STATE:加入集群的当前状态,new 是新集群,existing表示加入已有集群

(3)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/ca.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
--logger=zap
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

(4)拷贝已经生成好的证书

把刚才生成的证书拷贝到etcd.service文件中设置的路径:

cp ~/TLS/etcd/ca*pem ~/TLS/etcd/server*pem /opt/etcd/ssl/

即四个.pem文件:

[root@binary-master ssl]# pwd
/opt/etcd/ssl
[root@binary-master ssl]# ll
total 16
-rw------- 1 root root 1679 Mar 22 22:03 ca-key.pem
-rw-r--r-- 1 root root 1265 Mar 22 22:03 ca.pem
-rw------- 1 root root 1679 Mar 22 22:03 server-key.pem
-rw-r--r-- 1 root root 1330 Mar 22 22:03 server.pem

 到此,Master上的etcd部署已完成。

(5)将上面节点master所有生成的文件拷贝到节点node

scp -r /opt/etcd/ root@172.31.93.211:/opt/
scp /usr/lib/systemd/system/etcd.service root@172.31.93.211:/usr/lib/systemd/system/

(6)在node节点上修改 etcd.conf 配置文件中的节点名称和当前服务器 IP

(7)在master和node节点上都启动并设置开机启动

systemctl daemon-reload
systemctl start etcd
systemctl enable etcd

(8)使用etcdctl查看集群状态

/opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://172.31.93.210:2379,https://172.31.93.211:2379" endpoint health

[root@binary-master ssl]# /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://172.31.93.210:2379,https://172.31.93.211:2379" endpoint health
https://172.31.93.210:2379 is healthy: successfully committed proposal: took = 11.468435ms
https://172.31.93.211:2379 is healthy: successfully committed proposal: took = 12.058593ms

如果输出上面信息,就说明etcd集群部署成功。如果有问题第一步先看日志:/var/log/message 或 journalctl -u etcd

所有节点二进制安装docker

之前使用kubeadm安装k8s集群时,是用yum安装的docker,这次用二进制安装k8s集群,所以也用二进制安装docker。当然用yum也可以,只是不同的安装方式而已。如果在不联网的情况下,只能上传二进制包来安装。

下载地址:https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz

1.解压二进制包

tar zxvf docker-19.03.9.tgz
mv docker/* /usr/bin

2.systemd 管理 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.创建配置文件,配置阿里云镜像加速器

mkdir /etc/docker
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF

4.启动并设置开机启动

systemctl daemon-reload
systemctl start docker
systemctl enable docker

5.把docker-19.03.9.tgz包scp到其他节点上,按照上述步骤都安装一遍

部署master节点

Master节点包括三个组件:apiserver、controller-manager、scheduler

部署步骤都一致:

  • 创建配置文件
  • 由systemd管理组件服务
  • 启动并设置开机启动

其中apiserver还需要生成并配置上证书(和etcd一样),并启用 TLS Bootstrapping 机制。

1.生成 kube-apiserver 证书

这个过程和上面生成etcd证书的过程一样。在TLS目录下,之前创建了etcd和k8s两个文件夹,apiserver证书生成的操作就在k8s文件夹中执行:

[root@binary-master TLS]# pwd
/root/TLS
[root@binary-master TLS]# ls
etcd  k8s
[root@binary-master TLS]# cd k8s/

(1)自签证书颁发机构(CA)

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

(2)生成证书(初始化)

cfssl gencert -initca ca-csr.json | cfssljson -bare ca –

[root@binary-master k8s]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
2021/03/23 16:48:08 [INFO] generating a new CA key and certificate from CSR
2021/03/23 16:48:08 [INFO] generate received request
2021/03/23 16:48:08 [INFO] received CSR
2021/03/23 16:48:08 [INFO] generating key: rsa-2048
2021/03/23 16:48:08 [INFO] encoded CSR
2021/03/23 16:48:08 [INFO] signed certificate with serial number 674155349167693061708935668878485858330936601612
[root@binary-master k8s]# ls *pem
ca-key.pem  ca.pem

(3)使用自签 CA 签发 kube-apiserver HTTPS 证书

创建证书申请文件:

cat > server-csr.json<< EOF
{
"CN": "kubernetes",
"hosts": [
"10.0.0.1",
"127.0.0.1",
"172.31.93.210",
"172.31.93.211",
"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

注意,其中一定要hosts中添加集群的所有可信任IP。

(4)生成证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server

[root@binary-master k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
2021/03/23 16:54:41 [INFO] generate received request
2021/03/23 16:54:41 [INFO] received CSR
2021/03/23 16:54:41 [INFO] generating key: rsa-2048
2021/03/23 16:54:41 [INFO] encoded CSR
2021/03/23 16:54:41 [INFO] signed certificate with serial number 321029219572130619553803174282705384482149958458
2021/03/23 16:54:41 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements"). 
[root@binary-master k8s]# ls server*pem
server-key.pem  server.pem

其中server-key.pem和server.pem就是最后需要的apiserver自签证书。

2.从GitHub下载 kubernetes-server-linux-amd64.tar.gz 

下载地址:https://github.com/kubernetes/kubernetes/tree/master/CHANGELOG

选择想要下载的版本,进入后里面会有很多包,注意要下载服务端的版本包(Server Binaries),其中已经包含了Master和Node二进制文件。

3.解压二进制包,并创建相应工作目录,复制需要的命令工具

tar zxvf kubernetes-server-linux-amd64.tar.gz

目录结构:

[root@binary-master kubernetes]# ll
total 32792
drwxr-xr-x 2 root root        6 Aug 26  2020 addons
-rw-r--r-- 1 root root 33576969 Aug 26  2020 kubernetes-src.tar.gz
drwxr-xr-x 3 root root       49 Aug 26  2020 LICENSES
drwxr-xr-x 3 root root       17 Aug 26  2020 server

然后执行:

#创建工作目录
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
#复制相关命令
cd kubernetes/server/bin
cp kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin
cp kubectl /usr/bin/

4.部署 kube-apiserver

(1)创建配置文件kube-apiserver.conf

cat > /opt/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--etcd-servers=https://172.31.93.210:2379,https://172.31.93.211:2379 \\
--bind-address=172.31.93.210 \\
--secure-port=6443 \\
--advertise-address=172.31.93.210 \\
--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 \\
--etcd-cafile=/opt/etcd/ssl/ca.pem \\
--etcd-certfile=/opt/etcd/ssl/server.pem \\
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \\
--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:监听地址 –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 证书 –etcd-xxxfile:连接 Etcd 集群证书 –audit-log-xxx:审计日志

一般只需修改其中的几个ip地址即可。

(2)启用 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 还是由我们统一颁发一个证书。

即上述配置文件中的:

--enable-bootstrap-token-auth=true \\                  表示开启
--token-auth-file=/opt/kubernetes/cfg/token.csv \\    指定bootstrap token文件

所以创建上述配置文件中 token 文件:

cat > /opt/kubernetes/cfg/token.csv << EOF
c47ffb939f5ca36231d9e3121a252940,kubelet-bootstrap,10001,"system:node-
bootstrapper"
EOF

文件格式为:token,用户名,UID,用户组

(3)拷贝刚才生成的apiserver证书到配置文件中指定的路径:

cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/

[root@binary-master ssl]# pwd
/opt/kubernetes/ssl
[root@binary-master ssl]# ll
total 16
-rw------- 1 root root 1675 Mar 24 16:02 ca-key.pem
-rw-r--r-- 1 root root 1359 Mar 24 16:02 ca.pem
-rw------- 1 root root 1675 Mar 24 16:02 server-key.pem
-rw-r--r-- 1 root root 1659 Mar 24 16:02 server.pem

(4)systemd 管理 apiserver

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

(5)启动并设置开机启动

systemctl daemon-reload
systemctl start kube-apiserver
systemctl enable kube-apiserver

(6)授权 kubelet-bootstrap 用户允许请求证书

kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap


[root@binary-master ssl]# kubectl create clusterrolebinding kubelet-bootstrap \
> --clusterrole=system:node-bootstrapper \
> --user=kubelet-bootstrap
clusterrolebinding.rbac.authorization.k8s.io/kubelet-bootstrap created

5.  部署 kube-controller-manager

(1)创建配置文件

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 \\
--master=127.0.0.1:8080 \\
--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 \\
--experimental-cluster-signing-duration=87600h0m0s"
EOF

说明:
–master:通过本地非安全本地端口 8080 连接 apiserver。
–leader-elect:当该组件启动多个时,自动选举(HA)
–cluster-signing-cert-file/–cluster-signing-key-file:自动为 kubelet 颁发证书的CA,与 apiserver 保持一致

这里的配置基本不用改,都是内部通信。

(2)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

(3)启动并设置开机启动

systemctl daemon-reload
systemctl start kube-controller-manager
systemctl enable kube-controller-manager

6.部署 kube-scheduler

(1)创建配置文件

cat > /opt/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--leader-elect \
--master=127.0.0.1:8080 \
--bind-address=127.0.0.1"
EOF

说明:
–master:通过本地非安全本地端口 8080 连接 apiserver。
–leader-elect:当该组件启动多个时,自动选举(HA)

(2)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

(3)启动并设置开机启动

systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler

7.查看集群状态

此时3个组件都已经启动成功,通过 kubectl 工具查看当前集群组件状态:

[root@binary-master cfg]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-1               Healthy   {"health":"true"}   
etcd-0               Healthy   {"health":"true"}   

如上输出说明 Master 节点各组件运行正常,master节点部署完成。

部署Worker Node节点

1.创建工作目录并拷贝二进制文件

创建工作目录:

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}

从 master 节点scp拷贝下载安装包里的二进制命令文件:

[root@binary-master bin]# pwd
/root/kubernetes/server/bin
[root@binary-master bin]# ls
apiextensions-apiserver  kube-apiserver             kube-controller-manager             kubectl     kube-proxy.docker_tag  kube-scheduler.docker_tag
kubeadm                  kube-apiserver.docker_tag  kube-controller-manager.docker_tag  kubelet     kube-proxy.tar         kube-scheduler.tar
kube-aggregator          kube-apiserver.tar         kube-controller-manager.tar         kube-proxy  kube-scheduler         mounter
[root@binary-master bin]# scp  kubelet kube-proxy root@172.31.93.211:/opt/kubernetes/bin

worker node上就有kubelet和kube-proxy命令了:

[root@binary-node bin]# pwd
/opt/kubernetes/bin
[root@binary-node bin]# ll
total 145296
-rwxr-xr-x 1 root root 109974472 Mar 30 14:41 kubelet
-rwxr-xr-x 1 root root  38805504 Mar 30 14:41 kube-proxy
[root@binary-node bin]# 

2.部署 kubelet

(1)创建配置文件

cat > /opt/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=binary-node \\
--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=lizhenliang/pause-amd64:3.0"
EOF

说明:
–hostname-override:显示名称,集群中唯一
–network-plugin:启用 CNI
–kubeconfig:空路径,会自动生成,后面用于连接 apiserver
–bootstrap-kubeconfig:首次启动向 apiserver 申请证书
–config:配置参数文件
–cert-dir:kubelet 证书生成目录
–pod-infra-container-image:管理 Pod 网络容器的镜像

一般只要改一下--hostname-override即可。

(2)配置参数文件

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: cgroupfs
clusterDNS:
- 10.0.0.2
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

(3)在master上生成bootstrap.kubeconfig文件,然后复制到node节点

需要用到kubectl命令,所以在master上操作:

# apiserver IP:PORT
KUBE_APISERVER="https://172.31.93.210:6443"
# 与 token.csv 里保持一致
TOKEN="c47ffb939f5ca36231d9e3121a252940"
# 生成 kubelet bootstrap kubeconfig 配置文件
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
kubectl config set-credentials "kubelet-bootstrap" \
--token=${TOKEN} \
--kubeconfig=bootstrap.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user="kubelet-bootstrap" \
--kubeconfig=bootstrap.kubeconfig
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

一步步执行,执行后会生成一个bootstrap.kubeconfig文件:

[root@binary-master ~]# KUBE_APISERVER="https://172.31.93.210:6443"
[root@binary-master ~]# TOKEN="c47ffb939f5ca36231d9e3121a252940"
[root@binary-master ~]# kubectl config set-cluster kubernetes \
> --certificate-authority=/opt/kubernetes/ssl/ca.pem \
> --embed-certs=true \
> --server=${KUBE_APISERVER} \
> --kubeconfig=bootstrap.kubeconfig
Cluster "kubernetes" set.
[root@binary-master ~]# kubectl config set-credentials "kubelet-bootstrap" \
> --token=${TOKEN} \
> --kubeconfig=bootstrap.kubeconfig
User "kubelet-bootstrap" set.
[root@binary-master ~]# kubectl config set-context default \
> --cluster=kubernetes \
> --user="kubelet-bootstrap" \
> --kubeconfig=bootstrap.kubeconfig
Context "default" created.
[root@binary-master ~]# kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
Switched to context "default".
[root@binary-master ~]# cat bootstrap.kubeconfig 
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR2akNDQXFhZ0F3SUJBZ0lVZGhZcjMwN2hSRVJQc3lJbGZYMXBPTlFiN0F3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1pURUxNQWtHQTFVRUJoTUNRMDR4RURBT0JnTlZCQWdUQjBKbGFXcHBibWN4RURBT0JnTlZCQWNUQjBKbAphV3BwYm1jeEREQUtCZ05WQkFvVEEyczRjekVQTUEwR0ExVUVDeE1HVTNsemRHVnRNUk13RVFZRFZRUURFd3ByCmRXSmxjbTVsZEdWek1CNFhEVEl4TURNeU16QTRORE13TUZvWERUSTJNRE15TWpBNE5ETXdNRm93WlRFTE1Ba0cKQTFVRUJoTUNRMDR4RURBT0JnTlZCQWdUQjBKbGFXcHBibWN4RURBT0JnTlZCQWNUQjBKbGFXcHBibWN4RERBSwpCZ05WQkFvVEEyczRjekVQTUEwR0ExVUVDeE1HVTNsemRHVnRNUk13RVFZRFZRUURFd3ByZFdKbGNtNWxkR1Z6Ck1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBd2RvYzcyOWNkd2dEODBGUzdZb1EKRjlScEdHb1BqMEJaTzdpL3dNaGRkRi9XVXZSem81ZHF0N1pzM25VS2VPU3dGUzg5SlNMOWZndVhuQVZ5RXZNcQpwQzBxMk8zZlAvbG5ua203bmlzeDJXYStHYVZuYUphRkRQMmkrbG1CWnhVeXVibTlHMFdydXJ3aEcydGxuVHMxClpwaG9JVWJoMngxRHJub2VldFI3Rk11UXpDZzJrUmhQOTFFY0xITVR6YUhwVnNjYnk1ZTh3NXZCbjU4YWRselEKZThKVkFSemFHUVZMREZ0OUpZQlNoaUYwSmF6RHJCMmlBdzE5VklFY3MrSUdjdjlFWHVMTjdkKytGbWwyZWJoego1WmNoWEIxZHhvUUhadFZvcDRTVzUwQ005YzRuQkdCbFVJVTN4VTBvVTlnVkNSQnI2MDlGTkZzUmJ1RjZMc2VZCmVRSURBUUFCbzJZd1pEQU9CZ05WSFE4QkFmOEVCQU1DQVFZd0VnWURWUjBUQVFIL0JBZ3dCZ0VCL3dJQkFqQWQKQmdOVkhRNEVGZ1FVK3BKL0dPczRrL3hub2N2L3FGajZyaW5Uc244d0h3WURWUjBqQkJnd0ZvQVUrcEovR09zNAprL3hub2N2L3FGajZyaW5Uc244d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFCTW5LV1lUeXQxQmJ1Q0h0SDRFCjNhVDB4S0RNNUZKcVR6bU1vV1ZWWExtZjlTV0V5UU13QlErK0dvOUo3NlBqOVYwV0tSSk0rNFdOam9WWEViZnMKaUdDSlhubE5kZk5aSFplSzN6U1dhNFl2M1kzTmlaUVpxaGtHUHFTdXJuempjd0FKVlU4dzlZUWxXaTBFaFdjVApXanBBSitWRVlWWjh6aWF2RWZ3OXhjaTZ0UGhSYlpxazU2MlBBUkNvWUx5RC9DQmpnSFljejQ3YVcvSWNINHNECmFJODBuUWpzbldOSEFvR0JBQmJ2TnJRNzRSanF0M3pQcnlRYWhxVGp6OUczVmRSS2REYnJKVjN2VG8zN3dZQ3AKRkpVTTgvdlc0dGhxUTBwd3dTRXdHWUNOYXVaRnczWWg5SzA5SDg3T2NTUWxlTEdvYWc4YzdqelAyUk0xcFZyNQo0c2M9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://172.31.93.210:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubelet-bootstrap
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: kubelet-bootstrap
  user:
    token: c47ffb939f5ca36231d9e3121a252940

把这个文件拷贝到node节点的配置文件路径:

scp bootstrap.kubeconfig root@172.31.93.211:/opt/kubernetes/cfg

(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)启动并设置开机启动

systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet

3.在master的apiserver上批准 kubelet 证书申请并加入集群

由于之前在apiserver上设置了启用 TLS Bootstrapping 机制,kubelet 启动时会向 kube-apiserver 发送 TLS bootstrapping 请求。

在master上使用命令kubectl get csr可以看到还未认证的节点:

[root@binary-master k8s]# kubectl get csr
NAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-UdCmaoVbWhqqdxWo7gkP3pH5vzoqliQPtvvCzJ54DBM   7s    kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending

然后在master上批准证书:kubectl certificate approve  'nodename'

[root@binary-master k8s]# kubectl certificate approve node-csr-UdCmaoVbWhqqdxWo7gkP3pH5vzoqliQPtvvCzJ54DBM
certificatesigningrequest.certificates.k8s.io/node-csr-UdCmaoVbWhqqdxWo7gkP3pH5vzoqliQPtvvCzJ54DBM approved

此时再使用命令kubectl get csr可以看到状态已经变为approved:

[root@binary-master k8s]# kubectl get csr
NAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-UdCmaoVbWhqqdxWo7gkP3pH5vzoqliQPtvvCzJ54DBM   10m   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued

查看节点:

[root@binary-master k8s]# kubectl get node
NAME          STATUS     ROLES    AGE   VERSION
binary-node   NotReady   <none>   13m   v1.19.0

由于网络插件还没有部署,节点会没有准备就绪,所以是 NotReady。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ps:这里遇到一个问题,kubectl get csr 显示No Resources Found,即apiserver没有收到kubelet的认证请求

[root@binary-master k8s]# kubectl get csr
No resources found

出现这个问题,一般检查:kubelet 使用的 bootstrap.kubeconfig 文件中User 是否是 kubelet-boostrap,token是否是kube-apiserver 使用的 token.csv 文件中的token

检查后发现都是正确的,再查看kubelet的日志,发现有错误:无法创建证书签名请。

F0330 17:59:28.096982    2887 server.go:265] failed to run Kubelet: cannot create certificate signing request: Post "https://172.31.93.210:6443/apis/certificates.k8s.io/v1/certificatesigningrequests": x509: certificate is valid for 10.0.0.1, 127.0.0.1, 192.168.31.71, 192.168.31.72, 192.168.31.73, 192.168.31.74, 192.168.31.81, 192.168.31.82, 192.168.31.88, not 172.31.93.210
goroutine 1 [running]:

原来是在自签CA签发apiserver证书时,创建的证书申请文件server-csr.json中未添加集群的所有可信任IP。

修改这个文件,重新生成证书,并把新证书放到apiserver的证书目录,最后重启apiserver,问题解决。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 4.部署 kube-proxy

(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)配置参数文件kube-proxy-config.yml

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: binary-node
clusterCIDR: 10.0.0.0/24
EOF

一般只要改一下--hostname-override即可。

(3)生成 kube-proxy.kubeconfig 文件

先在master节点生成 kube-proxy 证书,因为生成 .kubeconfig 文件需要用到证书:

# 切换工作目录
[root@binary-master k8s]# cd ~/TLS/k8s

# 创建证书请求文件
[root@binary-master 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

# 生成证书
[root@binary-master k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
2021/03/31 15:04:11 [INFO] generate received request
2021/03/31 15:04:11 [INFO] received CSR
2021/03/31 15:04:11 [INFO] generating key: rsa-2048
2021/03/31 15:04:11 [INFO] encoded CSR
2021/03/31 15:04:11 [INFO] signed certificate with serial number 223055766142513681177047308544368105041301659941
2021/03/31 15:04:11 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").

#查看证书
[root@binary-master k8s]# ls kube-proxy*pem
kube-proxy-key.pem  kube-proxy.pem

在master上生成kube-proxy.kubeconfig文件,然后复制到node节点

需要用到kubectl命令,所以也在master上操作:

# apiserver IP:PORT
KUBE_APISERVER="https://172.31.93.210:6443"
#生成kube-proxy.kubeconfig文件
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy \
--client-certificate=/root/TLS/k8s/kube-proxy.pem \
--client-key=/root/TLS/k8s/kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=kube-proxy.kubeconfig
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

一步步执行,执行后会生成一个 kube-proxy.kubeconfig文件:

[root@binary-master ~]# KUBE_APISERVER="https://172.31.93.210:6443"
[root@binary-master ~]# kubectl config set-cluster kubernetes \
> --certificate-authority=/opt/kubernetes/ssl/ca.pem \
> --embed-certs=true \
> --server=${KUBE_APISERVER} \
> --kubeconfig=kube-proxy.kubeconfig
Cluster "kubernetes" set.
[root@binary-master ~]# kubectl config set-credentials kube-proxy --client-certificate=/root/TLS/k8s/kube-proxy.pem --client-key=/root/TLS/k8s/kube-proxy-key.pem --embed-certs=true --kubeconfig=kube-proxy.kubeconfig
User "kube-proxy" set.
[root@binary-master ~]# kubectl config set-context default \
> --cluster=kubernetes \
> --user=kube-proxy \
> --kubeconfig=kube-proxy.kubeconfig
Context "default" created.
[root@binary-master ~]# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
Switched to context "default".

把这个文件拷贝到node节点的配置文件路径:

scp kube-proxy.kubeconfig root@172.31.93.211:/opt/kubernetes/cfg

(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)启动并设置开机启动

systemctl daemon-reload
systemctl start kube-proxy
systemctl enable kube-proxy

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ps:这里遇到一个问题,kube-proxy无法启动,查看错误日志:unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined

[root@binary-node logs]# cat kube-proxy.binary-node.root.log.FATAL.20210402-181634.77665
Log file created at: 2021/04/02 18:16:34
Running on machine: binary-node
Binary: Built with gc go1.15 for linux/amd64
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
F0402 18:16:34.526797   77665 server.go:495] unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined

是因为kube-proxy-config.yml这个配置文件中,kubeconfig:/opt/kubernetes/cfg/kube-proxy.kubeconfig,这一行最前面应该有一个空格:

修改后重启即可。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

5.部署 CNI 网络

(1)在node节点准备好 CNI 二进制文件

下载地址:https://github.com/containernetworking/plugins/releases/download/v0.8.6/cni-plugins-linux-amd64-v0.8.6.tgz

解压二进制包并移动到默认工作目录:

mkdir /opt/cni/bin
tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin

 二进制文件都在 /opt/cni/bin/:

[root@binary-node ~]# ll
total 95336
-rw-------. 1 root root     1260 Mar 19 01:44 anaconda-ks.cfg
-rw-r--r--  1 root root 36878412 Mar 31 18:20 cni-plugins-linux-amd64-v0.8.6.tgz
drwxrwxr-x  2 1000 1000        6 Mar 23 14:35 docker
-rw-r--r--  1 root root 60730088 Mar 23 14:35 docker-19.03.9.tgz
-rw-r--r--  1 root root     4821 Mar 31 17:43 kube-flannel.yml
[root@binary-node ~]# tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin
./
./flannel
./ptp
./host-local
./firewall
./portmap
./tuning
./vlan
./host-device
./bandwidth
./sbr
./static
./dhcp
./ipvlan
./macvlan
./loopback
./bridge
[root@binary-node ~]# ls /opt/cni/bin/
bandwidth  bridge  dhcp  firewall  flannel  host-device  host-local  ipvlan  loopback  macvlan  portmap  ptp  sbr  static  tuning  vlan

(2)在master节点使用 kubectl apply 部署CNI网络,这一步和上一篇kubeadm方式中的操作一样

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml

如下:

[root@binary-master ~]# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
--2021-04-01 10:40:48--  https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.108.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 4821 (4.7K) [text/plain]
Saving to: ‘kube-flannel.yml’

100%[===================================================================================================================================================>] 4,821       --.-K/s   in 0s      

2021-04-01 10:40:48 (24.9 MB/s) - ‘kube-flannel.yml’ saved [4821/4821]

[root@binary-master ~]# kubectl apply -f kube-flannel.yml
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created

部署好网络插件,Node 就准备就绪:

[root@binary-master ~]# kubectl get pods -n kube-system
NAME                    READY   STATUS    RESTARTS   AGE
kube-flannel-ds-8zjwr   1/1     Running   6          9m33s
[root@binary-master ~]# kubectl get node
NAME          STATUS   ROLES    AGE   VERSION
binary-node   Ready    <none>   40h   v1.19.0

6.若要新增work node

假设需要新增work节点:172.31.93.212

(1)拷贝已部署好的 Node 相关文件到新节点

从已部署好的work节点(172.31.93.211)上将涉及的文件拷贝到新work节点(172.31.93.212):

#kubernetes工作目录
scp -r /opt/kubernetes root@172.31.93.212:/opt/
#服务注册
scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service root@172.31.93.212:/usr/lib/systemd/system
#cni网络插件
scp -r /opt/cni/ root@172.31.93.212:/opt/
#证书
scp /opt/kubernetes/ssl/ca.pem root@172.31.93.212:/opt/kubernetes/ssl

(2)拷贝完成后,删除 kubelet 证书和 kubeconfig 文件

rm /opt/kubernetes/cfg/kubelet.kubeconfig

rm -f /opt/kubernetes/ssl/kubelet*

这几个文件是证书申请审批后自动生成的,每个 Node 不同,必须删除重新生成。

(3)修改主机名

#这两个文件中的主机名要修改掉
vi
/opt/kubernetes/cfg/kubelet.conf --hostname-override= vi /opt/kubernetes/cfg/kube-proxy-config.yml hostnameOverride:

(4) 启动并设置开机启动

systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet
systemctl start kube-proxy
systemctl enable kube-proxy

(5) 在 Master 上批准新 Node kubelet 证书申请

kubectl get csr

kubectl certificate approve xxxxxxx

(6)查看 Node 状态验证

Kubectl get node

 

测试 kubernetes 集群

在 Kubernetes 集群中创建一个 pod(以nginx为例),验证是否正常运行:kubectl create deployment nginx --image=nginx

[root@binary-master ~]# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
[root@binary-master ~]# kubectl get pod
NAME                     READY   STATUS              RESTARTS   AGE
nginx-6799fc88d8-2tf8z   0/1     ContainerCreating   0          15s

暴露内部端口80:

kubectl expose deployment nginx --port=80 --type=NodePort

查看pod与svc:kubectl get pod,svc

[root@binary-master flannel]# kubectl get pod,svc
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-6799fc88d8-6g9q2   1/1     Running   0          12m

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.0.0.1     <none>        443/TCP        10d
service/nginx        NodePort    10.0.0.149   <none>        80:31503/TCP   38m

对外暴露的端口为31503,可以通过浏览器访问集群中任一work node的IP加31503端口来测试:

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ps:这里遇到一个问题,创建了nginx的pod后,该pod一直处于ContainerCreating状态:

[root@binary-master flannel]# kubectl get pod
NAME                     READY   STATUS              RESTARTS   AGE
nginx-6799fc88d8-6g9q2   0/1     ContainerCreating   0          5s

通过 kubectl describe pod nginx 查看pod详细信息:

[root@binary-master ~]# kubectl describe pod nginx
Name:           nginx-6799fc88d8-mlc22
Namespace:      default
Priority:       0
Node:           binary-node/172.31.93.211
Start Time:     Sat, 03 Apr 2021 20:59:57 +0800
Labels:         app=nginx
                pod-template-hash=6799fc88d8
Annotations:    <none>
Status:         Pending
IP:             
IPs:            <none>
Controlled By:  ReplicaSet/nginx-6799fc88d8
Containers:
  nginx:
    Container ID:   
    Image:          nginx
    Image ID:       
    Port:           <none>
    Host Port:      <none>
    State:          Waiting
      Reason:       ContainerCreating
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-74sf7 (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 
Volumes:
  default-token-74sf7:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-74sf7
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason                  Age                 From                  Message
  ----     ------                  ----                ----                  -------
  Normal   Scheduled               95s                                       Successfully assigned default/nginx-6799fc88d8-mlc22 to binary-node
  Warning  FailedCreatePodSandBox  95s                 kubelet, binary-node  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "5240a4b7f8d25d59542c8ffb75937999c7d09c58056e7e7d7b9131d99635333b" network for pod "nginx-6799fc88d8-mlc22": networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory
  Warning  FailedCreatePodSandBox  94s                 kubelet, binary-node  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "09f9728baca36797f2efcc111fd8bd63749e8e40dd0a84780a6ddae447c10ffd" network for pod "nginx-6799fc88d8-mlc22": networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory
  Warning  FailedCreatePodSandBox  93s                 kubelet, binary-node  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "3453f4e978941bd442bcbaece321c79b48dff8633c87f33f7ef86c2d5de3ada4" network for pod "nginx-6799fc88d8-mlc22": networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory
  Warning  FailedCreatePodSandBox  92s                 kubelet, binary-node  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "25b8a4368c66c23b4ed5ab55b8f40b7020ff2fe5d1be25b0c605cd187be88ec4" network for pod "nginx-6799fc88d8-mlc22": networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory
  Warning  FailedCreatePodSandBox  91s                 kubelet, binary-node  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "eb2dcd49db7e1366df8cb2842b37b5dc86b7b07b9a87cb8572aa5907262631d3" network for pod "nginx-6799fc88d8-mlc22": networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory
  Warning  FailedCreatePodSandBox  90s                 kubelet, binary-node  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "8e65cc2af4f387b0dcd307d22513e074900f2879c323608a3986c960bcf3f4dd" network for pod "nginx-6799fc88d8-mlc22": networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory
  Warning  FailedCreatePodSandBox  89s                 kubelet, binary-node  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "67af2477a1e0aeac6f5254922ac83518a9cb54af6e667a9dc7e8643095fc2430" network for pod "nginx-6799fc88d8-mlc22": networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory
  Warning  FailedCreatePodSandBox  87s                 kubelet, binary-node  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "09d99848e555b858c0f76f2b55d3c55e73552f464e916ccc56547aa0d24995f1" network for pod "nginx-6799fc88d8-mlc22": networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory
  Warning  FailedCreatePodSandBox  86s                 kubelet, binary-node  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "5d1c24620fe5620f7f4abc098b011a3df99d0c9391e5724d6f8dcdc75568d7d2" network for pod "nginx-6799fc88d8-mlc22": networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory
  Normal   SandboxChanged          83s (x12 over 94s)  kubelet, binary-node  Pod sandbox changed, it will be killed and re-created.
  Warning  FailedCreatePodSandBox  82s (x4 over 85s)   kubelet, binary-node  (combined from similar events): Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "662c7162eb2922ba76cd4fd3eafd917e3d7e986331896fcee3abae2130e12613" network for pod "nginx-6799fc88d8-mlc22": networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory

提示:binary-node上的kubelet报错:networkPlugin cni failed to set up pod "nginx-6799fc88d8-mlc22_default" network: open /run/flannel/subnet.env: no such file or directory

应该是cni网络插件的问题,推测是之前binary-node节点上kube-proxy没有启动成功而导致。

查了很多网上资料,也没有解决问题,最后重启了下binary-node节点的docker,就可以了。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

posted @ 2021-04-03 22:02  酒红色  阅读(993)  评论(0编辑  收藏  举报