k8s二进制集群中添加/新增node节点
原有环境说明
主机名 | 系统版本 | ip地址 | docker version | kubelet version | kubeadm version | kubectl version | flannel version | 备注 |
---|---|---|---|---|---|---|---|---|
master | centos-release-7-7.1908.0.el7.centos.x86_64 | 192.168.137.221 | Docker 18.09.6 | V1.14.2 | V1.14.2 | V1.14.2 | V0.11.0 | master节点 |
node01 | centos-release-7-7.1908.0.el7.centos.x86_64 | 192.168.137.222 | Docker 18.09.6 | V1.14.2 | V1.14.2 | V1.14.2 | V0.11.0 | node节点 |
node02 | centos-release-7-7.1908.0.el7.centos.x86_64 | 192.168.137.223 | Docker 18.09.6 | V1.14.2 | V1.14.2 | V1.14.2 | V0.11.0 | node节点 |
新增node03环境说明
主机名 | 系统版本 | ip地址 | docker version | kubelet version | kubeadm version | kubectl version | flannel version | 备注 |
---|---|---|---|---|---|---|---|---|
node03 | centos-release-7-7.1908.0.el7.centos.x86_64 | 192.168.137.221 | Docker 18.09.6 | V1.14.2 | V1.14.2 | V1.14.2 | V0.11.0 | node节点 |
之前搭建的k8s集群环境是参考https://k8s-install.opsnull.com这篇文档进行搭建的,这次的节点新增也是基于这个环境之上。
参考文档:https://k8s-install.opsnull.com
一、系统基础优化
1.工具安装
[root@centos7 ~]# yum install -y epel-release
[root@centos7 ~]# yum install -y vim conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
2.修改主机名
[root@centos7 ~]# hostnamectl set-hostname node03
[root@centos7 ~]# cat /etc/hostname
node03
重启服务器
3.修改ip地址(静态)
[root@node03 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static ##改成static 静态
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=2d7cb38b-cd33-4a42-b309-13f4fbe13650
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.137.224 ##ip地址
NETMASK=255.255.255.0
GATEWAY=192.168.137.2
DNS1=192.168.137.2
ZONE=public
重启服务器
4.关闭防火墙
[root@node03 ~]# systemctl stop firewalld ##停止firewalld服务
[root@node03 ~]# systemctl disable firewalld ##设置开机禁用防火墙
[root@node03 ~]# iptables -F && iptables -F -t nat ##清除所有规则
[root@node03 ~]# iptables -X && iptables -X -t nat ##清除用户自定义规则
[root@node03 ~]# iptables -P FORWARD ACCEPT ##刷新Forward跟accept规则
5.swap 分区
如果开启了 swap 分区,kubelet 会启动失败(可以通过将参数 --fail-swap-on 设置为 false 来忽略 swap on),故需要在每台机器上关闭 swap 分区。同时注释 /etc/fstab 中相应的条目,防止开机自动挂载 swap 分区:
[root@node03 ~]# swapoff -a ##禁用 /proc/swaps 中的所有交换区
[root@node03 ~]# sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab ##注释掉/etc/fstab中所有 swap 的行
6.关闭 SELinux
关闭 SELinux,否则后续 K8S 挂载目录时可能报错 Permission denied:
[root@node03 ~]# setenforce 0 ##临时关闭
[root@node03 ~]# sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config ##修改SELINUX=disabled 永久关闭
7.加载内核模块
[root@node03 ~]# modprobe ip_vs_rr
[root@node03 ~]# modprobe br_netfilter
8.优化内核参数
1.创建参数文件
[root@node03 ~]# mkdir -p /opt/k8s/work/ ##建一个文件夹用来存放k8s相关的文件
[root@node03 ~]# cat > /opt/k8s/work/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0 ##必须关闭 tcp_tw_recycle,否则和 NAT 冲突,会导致服务不通;
vm.swappiness=0 ##禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
vm.overcommit_memory=1 ##不检查物理内存是否够用
vm.panic_on_oom=0 ##开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1 ##关闭 IPV6,防止触发 docker BUG;
net.netfilter.nf_conntrack_max=2310720
EOF
2.移动参数文件
[root@node03 ~]# cp /opt/k8s/work/kubernetes.conf /etc/sysctl.d/kubernetes.conf
3.读取配置文件,使参数生效
[root@node03 ~]# sysctl -p /etc/sysctl.d/kubernetes.conf
9.设置系统时区
[root@node03 ~]# timedatectl set-timezone Asia/Shanghai ##调整系统 TimeZone
[root@node03 ~]# timedatectl set-local-rtc 0 ##将当前的 UTC 时间写入硬件时钟
[root@node03 ~]# systemctl restart rsyslog && systemctl restart crond ##重启依赖于系统时间的服务
10.关闭无关的服务
[root@node03 ~]# systemctl stop postfix && systemctl disable postfix
11.设置 rsyslogd 和 systemd journald
systemd 的 journald 是 Centos 7 默认的日志记录工具,它记录了所有系统、内核、Service Unit 的日志。
相比 systemd,journald 记录的日志有如下优势:
- 可以记录到内存或文件系统;(默认记录到内存,对应的位置为 /run/log/jounal);
- 可以限制占用的磁盘空间、保证磁盘剩余空间;
- 可以限制日志文件大小、保存的时间;
journald 默认将日志转发给 rsyslog,这会导致日志写了多份,/var/log/messages 中包含了太多无关日志,不方便后续查看,同时也影响系统性能。
[root@node03 ~]# mkdir /var/log/journal ##持久化保存日志的目录
[root@node03 ~]# mkdir /etc/systemd/journald.conf.d
[root@node03 ~]# cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史日志
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存时间 2 周
MaxRetentionSec=2week
# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
[root@node03 ~]# systemctl restart systemd-journald ##重启服务
12.创建相关目录
[root@node03 ~]# mkdir -p /opt/k8s/{bin,work} /etc/{kubernetes,etcd}/cert
13.升级内核
CentOS 7.x 系统自带的 3.10.x 内核存在一些 Bugs,导致运行的 Docker、Kubernetes 不稳定,例如:
- 高版本的 docker(1.13 以后) 启用了 3.10 kernel 实验支持的 kernel memory account 功能(无法关闭),当节点压力大如频繁启动和停止容器时会导致 cgroup memory leak;
- 网络设备引用计数泄漏,会导致类似于报错:“kernel:unregister_netdevice: waiting for eth0 to become free. Usage count = 1”;
升级内核到 4.4.X 以上解决以上问题:
[root@node03 ~]# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm ##安装完成后检查 /boot/grub2/grub.cfg 中对应内核 menuentry 中是否包含 initrd16 配置,如果没有,再安装一次!
[root@node03 ~]# yum --enablerepo=elrepo-kernel install -y kernel-lt
[root@node03 ~]# grub2-set-default 0 ##设置开机从新内核启动
重启服务器并查看内核版本
[root@node03 ~]# uname -a ##第三列显示的是内核版本。如果是4.4.X就说明升级成功
Linux node03 4.4.196-1.el7.elrepo.x86_64 #1 SMP Mon Oct 7 16:17:40 EDT 2019 x86_64 x86_64 x86_64 GNU/Linux
14.关闭 NUMA
[root@node03 ~]# vim /etc/default/grub ##在 GRUB_CMDLINE_LINUX 一行添加 `numa=off` 参数,如下所示:
重新生成 grub2 配置文件:
[root@node03 ~]# cp /boot/grub2/grub.cfg{,.bak}
[root@node03 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
输出:
15.修改hosts文件
需要在所有k8s节点中修改
[root@node03 ~]# vim /etc/hosts
16.无密码 ssh 登录其它节点
这个一般只需要在集群的 master节点上执行就可以了,并且由于之前master上已经生成了证书,所以可以直接执行下面的命令,过程中需要输入node03节点的root账号密码
[root@master ~]# ssh-copy-id root@node03
17.创建docker账号
[root@node03 ~]# useradd -m docker
18.更新 PATH 变量
[root@node03 ~]# echo 'PATH=/opt/k8s/bin:$PATH' >>/root/.bashrc
[root@node03 ~]# source /root/.bashrc
二、master节点分发相关文件
以下操作如果没有特殊说明,则都在master节点上进行
1. 分发ca证书文件
[root@master ~]# scp /etc/kubernetes/cert/ca*.pem /etc/kubernetes/cert/ca-config.json root@node03:/etc/kubernetes/cert
2. 分发kubectl二进制文件
[root@master ~]# scp /opt/k8s/bin/kubectl root@node03:/opt/k8s/bin/
[root@master ~]# ssh root@node03 "chmod +x /opt/k8s/bin/*"
3. 分发 kubeconfig 文件
[root@master ~]# ssh root@node03 "mkdir -p ~/.kube"
[root@master ~]# scp ~/.kube/config root@node03:~/.kube/config
4. 分发 flanneld 二进制文件
[root@master ~]# scp /opt/k8s/bin/{flanneld,mk-docker-opts.sh} root@node03:/opt/k8s/bin/
[root@master ~]# ssh root@node03 "chmod +x /opt/k8s/bin/*"
5.分发flanneld证书跟私钥
[root@master ~]# ssh root@node03 "mkdir -p /etc/flanneld/cert"
[root@master ~]# scp /etc/flanneld/cert/flanneld*.pem root@node03:/etc/flanneld/cert
6. 分发 flanneld systemd unit 文件
直接从master节点进行分发即可,不用修改任何东西
[root@master ~]# scp /etc/systemd/system/flanneld.service root@node03:/etc/systemd/system/
7. 启动 flanneld 服务
[root@master ~]# ssh root@node03 "systemctl daemon-reload && systemctl enable flanneld && systemctl restart flanneld"
如果启动成功,则到node03节点上检查启动结果。
[root@node03 ~]# ssh root@node03 "systemctl status flanneld"
一开始我的flanneld服务是显示 active的,但是仔细看会发现报错了。而且ping其他集群节点的ip也ping不通
在node03节点进行ping集群ip 无法ping通
然后我将node03机器重启,重启后再查看状态就ok了。也可以ping通其他机子。
8.检查分配给各 flanneld 的 Pod 网段信息
[root@master ~]# etcdctl \
--endpoints=https://192.168.137.221:2379,https://192.168.137.222:2379,https://192.168.137.223:2379 \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
ls /kubernetes/network/subnets
如果可以看到刚刚从node03节点上看到的 172.30.48.0网段的信息。并且各个节点之间能够互相ping通就是成功的。
三、node03节点安装docker
以下操作如果没有特殊说明,则都在master节点上进行
1.分发master节点的docker相关文件
[root@master ~]# scp /opt/k8s/work/docker/* root@node03:/opt/k8s/bin/
[root@master ~]# scp /etc/systemd/system/docker.service root@node03:/etc/systemd/system/
[root@master ~]# ssh root@node03 "mkdir -p /etc/docker/ /data/k8s/docker/{data,exec}"
[root@master ~]# scp /etc/docker/daemon.json root@node03:/etc/docker/daemon.json
2.启动 docker 服务
[root@master ~]# ssh root@node03 "systemctl daemon-reload && systemctl enable docker && systemctl restart docker"
3.检查服务运行状态
直接到node03节点上进行检查
[root@node03 ~]# systemctl status docker
Active: active (running) 并且日志中没有错误则启动成功
可以在node03节点上查看docker信息
[root@node03 ~]# docker info
四、kube-apiserver 高可用之 nginx 代理
以下操作如果没有特殊说明,则都在master节点上进行
1.拷贝二进制程序:
[root@master ~]# ssh root@node03 "mkdir -p /opt/k8s/kube-nginx/{conf,logs,sbin}"
[root@master ~]# scp /opt/k8s/work/nginx-1.15.3/nginx-prefix/sbin/nginx root@node03:/opt/k8s/kube-nginx/sbin/kube-nginx
[root@master ~]# ssh root@node03 "chmod a+x /opt/k8s/kube-nginx/sbin/*"
2.拷贝 nginx配置文件:
[root@master ~]# scp /opt/k8s/kube-nginx/conf/kube-nginx.conf root@node03:/opt/k8s/kube-nginx/conf/kube-nginx.conf
3.拷贝nginx systemd unit 文件:
[root@master ~]# scp /etc/systemd/system/kube-nginx.service root@node03:/etc/systemd/system/
4.启动 kube-nginx 服务:
[root@master ~]# ssh root@node03 "systemctl daemon-reload && systemctl enable kube-nginx && systemctl restart kube-nginx"
5.检查 kube-nginx 服务运行状态
[root@master ~]# ssh root@node03 "systemctl status kube-nginx"
五、node03节点部署 kubelet 组件
以下操作如果没有特殊说明,则都在master节点上进行
1.拷贝二进制文件到node03节点
[root@master ~]# scp /opt/k8s/bin/{kube-proxy,kubectl,kubelet} root@node03:/opt/k8s/bin/
2.创建 kubelet bootstrap kubeconfig 文件
# 创建 token
[root@master ~]# export BOOTSTRAP_TOKEN=$(kubeadm token create \
--description kubelet-bootstrap-token \
--groups system:bootstrappers:node03 \
--kubeconfig ~/.kube/config)
# 设置集群参数
[root@master ~]# kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/cert/ca.pem \
--embed-certs=true \
--server=https://127.0.0.1:8443 \
--kubeconfig=kubelet-bootstrap-node03.kubeconfig
# 设置客户端认证参数,注意--token的值是第一步中定义的BOOTSTRAP_TOKEN的值。
[root@master ~]# kubectl config set-credentials kubelet-bootstrap \
--token=${BOOTSTRAP_TOKEN} \
--kubeconfig=kubelet-bootstrap-node03.kubeconfig
# 设置上下文参数
[root@master ~]# kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=kubelet-bootstrap-node03.kubeconfig
# 设置默认上下文
[root@master ~]# kubectl config use-context default --kubeconfig=kubelet-bootstrap-node03.kubeconfig
在当前目录下会生成一个kubelet-bootstrap-node03.kubeconfig文件,如下。等下需要分发到node03节点
3.查看 kubeadm 为node03节点创建的 token
[root@master ~]# kubeadm token list --kubeconfig ~/.kube/config
- token 有效期为 1 天,超期后将不能再被用来 boostrap kubelet,且会被 kube-controller-manager 的 tokencleaner 清理;
- kube-apiserver 接收 kubelet 的 bootstrap token 后,将请求的 user 设置为 system:bootstrap:,group 设置为 system:bootstrappers,后续将为这个 group 设置 ClusterRoleBinding;
4.确认token
vim kubelet-bootstrap-node03.kubeconfig
查看文件中token的值是否跟刚刚kubeadm token list --kubeconfig ~/.kube/config
查询出来的token一致(我这里不一致的原因是因为两张截图不是同一天截的,第一天的token过期了)
5.查看 token 关联的 Secret
[root@master ~]# kubectl get secrets -n kube-system|grep bootstrap-token
6.分发 bootstrap-kubeconfig 文件到node03节点
在kubelet-bootstrap-node03.kubeconfig文件所在目录下执行。
[root@master ~]# scp kubelet-bootstrap-node03.kubeconfig root@node03:/etc/kubernetes/kubelet-bootstrap.kubeconfig
7.分发 kubelet 参数配置文件
复制一份kubelet-config.yaml到/opt/k8s/work/下,命名为kubelet-config-node03.yaml,待会儿需要修改几个字段
[root@master ~]# cp /etc/kubernetes/kubelet-config.yaml /opt/k8s/work/kubelet-config-node03.yaml
vim /opt/k8s/work/kubelet-config.yaml.cp文件进行修改,一共需要改两个地方。改成对应的node03的ip地址即可。
[root@master ~]# vim /opt/k8s/work/kubelet-config-node03.yaml
需要修改的地方如下:
复制/opt/k8s/work/kubelet-config-node03.yaml 到node03节点并重命名为kubelet-config.yaml
[root@master ~]# scp /opt/k8s/work/kubelet-config-node03.yaml root@node03:/etc/kubernetes/kubelet-config.yaml
8.分发 kubelet systemd unit 文件
复制一份kubelet.service到/opt/k8s/work/下,命名为kubelet-node03.service,待会儿需要修改几个字段
[root@master ~]# cp /etc/systemd/system/kubelet.service /opt/k8s/work/kubelet-node03.service
vim /opt/k8s/work/kubelet-node03.service
进行修改,只需要改一个地方,改成node03节点的hostname即可
复制/opt/k8s/work/kubelet-node03.service 到node03节点并重命名为kubelet.service
[root@master ~]# scp /opt/k8s/work/kubelet-node03.service root@node03:/etc/systemd/system/kubelet.service
9.启动 kubelet 服务
该步骤到node03节点下执行
[root@node03 ~]# mkdir -p /data/k8s/k8s/kubelet/kubelet-plugins/volume/exec/
[root@node03 ~]# /usr/sbin/swapoff -a
[root@node03 ~]# systemctl daemon-reload && systemctl enable kubelet && systemctl restart kubelet
启动服务之前需要创建工作目录,并且一定要关闭swap(虽然前面已经设置过)。
10.查看 kubelet 状态
该步骤到node03节点下执行
[root@node03 ~]# systemctl status kubelet
发现是启动成功了的,并且已经开始在下载各种镜像了。这里应该就说明node03节点加入集群成功了。
11.查看节点状态
master节点输入kubectl get node
查看,确认node03节点已经加入成功,并且状态是Ready的。
12.手动 approve server cert csr
基于安全性考虑,CSR approving controllers 不会自动 approve kubelet server 证书签名请求,需要手动 approve:
如果不approve会出现如下错误:
10月 18 14:51:43 node04 kubelet[24450]: E1018 14:51:43.571211 24450 certificate_manager.go:396] Certificate request was not signed: timed out waiting for the condition
先查看csr
[root@master ~]# kubectl get csr
手动approve所有Pending的 csr
[root@master ~]# kubectl certificate approve csr-hhwp2 csr-x58zw
六、node03节点部署 kube-proxy 组件
以下操作如果没有特殊说明,则都在master节点上进行
kube-proxy 二进制文件已经在上一环节全部分发完成了,所以这里不再拷贝。
1.分发 kubeconfig 文件
[root@master ~]# scp /etc/kubernetes/kube-proxy.kubeconfig root@node03:/etc/kubernetes/
2.创建和分发 kube-proxy 配置文件:
拷贝kube-proxy-config.yaml并修改相关参数,一共要修改四个地方,见下图。
[root@master ~]# cp /etc/kubernetes/kube-proxy-config.yaml /opt/k8s/work/kube-proxy-config-node03.yaml.template
[root@master ~]# vim /opt/k8s/work/kube-proxy-config-node03.yaml.template
分发kube-proxy配置文件:
[root@master ~]# scp /opt/k8s/work/kube-proxy-config-node03.yaml.template root@node03:/etc/kubernetes/kube-proxy-config.yaml
3.分发 kube-proxy systemd unit 文件
[root@master ~]# scp /etc/systemd/system/kube-proxy.service root@node03:/etc/systemd/system/
4.启动 kube-proxy 服务
[root@master ~]# ssh root@node03 "mkdir -p /data/k8s/k8s/kube-proxy"
[root@master ~]# ssh root@node03 "modprobe ip_vs_rr"
[root@master ~]# ssh root@node03 "systemctl daemon-reload && systemctl enable kube-proxy && systemctl restart kube-proxy"
5.检查启动结果
[root@master ~]# ssh root@node03 "systemctl status kube-proxy"
查看日志中是否有错误信息,没有的话说明启动成功。
至此,k8s二进制集群中添加node节点就完成了。鼓掌,鸣炮!