本文已参与「新人创作礼」活动,一起开启掘金创作之路。
kubernetes部署
版本太新的会报错,docker和kubelet kubeadm kubectl的版本要对应,不然下错了无法启动。
1、docker的部署和环境配置——每台服务器都要操作
[root@master ~]# systemctl stop firewalld.service
[root@master ~]# systemctl disalbe firewalld.service
[root@master ~]# setenforce 1 #临时关闭selinux
[root@master ~]# getenforce 0 #查看selinux
[root@master ~]# vim /etc/selinux/config #修改为disable
[root@master ~]# vim /etc/fstab #注释swap分区
[root@master ~]# wapoff -a #临时关闭swap分区
#在/etc/hosts下相互解析
[root@master ~]# cat >> /etc/hosts <<-EOF
172.17.232.41 master
172.17.232.33 node1
172.17.232.32 node2
EOF
[root@master ~]# yum -y install yum-utils.noarch device-mapper-persistent-data lvm2 && yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo && yum makecache && yum -y install docker-ce-20.10.5 && systemctl restart docker.service && systemctl enable docker.service #配置docker环境、yum源,启动和开机自启
2、kubeadm、kubelet和kubectl部署——每台服务器都要操作
[root@master ~]# cat > /etc/yum.repos.d/kubernetes.repo <<-EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
#[root@master ~]# yum install -y kubelet kubeadm kubectl ipvsadm 最新版本可能出错
[root@master ~]# yum -y install kubelet-1.20.15 kubeadm-1.20.15 kubectl-1.20.15
[root@master ~]# yum install -y kubelet-1.20.9 kubeadm-1.20.9 kubectl-1.20.9 --disableexcludes=kubernetes
[root@master ~]# systemctl enable kubelet && systemctl start kubelet
#安装指定版本,自己指定版本号
配置内核参数——每台服务器都要操作
[root@master ~]# cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness=0
EOF
[root@master ~]# sysctl --system
[root@master ~]# modprobe br_netfilter
[root@master ~]# sysctl -p /etc/sysctl.d/k8s.conf
#加载ipvs相关内核模块
#如果重启启动,需要重新加载(可以写在/etc/rc.local中开机自动加载)
###linux8.x以上版本 modprobe nf_conntrack_ipv4 这个参数去掉 _ipv4
[root@master ~]# cat >>/etc/profile.d/k8s.sh <<-EOF
modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh
modprobe nf_conntrack_ipv4
EOF
[root@master ~]# modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh
modprobe nf_conntrack_ipv4
#查看是否加载成功
[root@master ~]# lsmod |grep ip_vs
3、获取镜像——每台服务器都要操作
[root@master ~]# kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.20.15
k8s.gcr.io/kube-controller-manager:v1.20.15
k8s.gcr.io/kube-scheduler:v1.20.15
k8s.gcr.io/kube-proxy:v1.20.15
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns/coredns:1.7.0
#如果不能科学上网,需要用阿里云或者其他源,下载后,然后打一个tag。
#把k8s.gcr.io/更换成registry.cn-hangzhou.aliyuncs.com/google_containers,阿里云的源,后面版本号不变
[root@master ~]# vim kubernetes.pull
#!/bin/bash
img_list='
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.20.15
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.20.15
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.20.15
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.20.15
registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.13-0
registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.7.0
'
for img in $img_list
do
docker pull $img
done
[root@master ~]# /bin/bash kubernetes.pull
[root@master ~]# docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.20.15 k8s.gcr.io/kube-apiserver:v1.20.15
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.20.15 k8s.gcr.io/kube-controller-manager:v1.20.15
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.20.15 k8s.gcr.io/kube-scheduler:v1.20.15
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.20.15 k8s.gcr.io/kube-proxy:v1.20.15
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 k8s.gcr.io/pause:3.2
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.13-0 k8s.gcr.io/etcd:3.4.13-0
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.7.0 k8s.gcr.io/coredns:1.7.0
4、配置kubelet和启动——每台服务器都要操作
[root@master ~]# docker info |grep 'Cgroup Driver'|awk '{print $3}'
[root@master ~]# DOCKER_CGROUPS=$(docker info |grep 'Cgroup Driver'|awk '{print $3}')
[root@master ~]# echo $DOCKER_CGROUPS
cgroupfs
[root@master ~]# docker image list |grep pause
k8s.gcr.io/pause 3.2 6270bb605e12 6 months ago 683kB
#pause版本号要和下面的对应好
[root@master ~]# cat >/etc/sysconfig/kubelet <<EOF
KUBELET_EXTRA_ARGS="--cgroup-driver=$DOCKER_CGROUPS --pod-infra-container-image=k8s.gcr.io/pause:3.2"
EOF
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl start kubelet.service && systemctl enable kubelet.service
[root@master ~]# systemctl status kubelet.service
#会发现报错
[root@master ~]# journalctl -xefu kubelet
Mar 08 14:48:33 master systemd[1]: Unit kubelet.service entered failed state.
Mar 08 14:48:33 master systemd[1]: kubelet.service failed.
Mar 08 14:51:37 master systemd[1]: kubelet.service: main process exited, code=exited, status=1/FAILURE
Mar 08 14:51:37 master systemd[1]: Unit kubelet.service entered failed state.
Mar 08 14:51:37 master systemd[1]: kubelet.service failed.
#kubelet启动失败是因为kubeadm init没有初始化集群,这个错误在解决kubeadm init生成证书后会被自动解决,此处可以先忽略,简单地说就是在kubeadm init之前kubelet会不断重启。
5、初始化集群——master节点初始化
[root@master ~]# kubectl version #查看版本
[root@master ~]# docker image list
#--kubernetes-version=v1.20.15 #制定版本号
#--pod-network-cidr=10.244.0.0/16 #定义POD的网段
#--apiserver-advertise-address #地址就是master本机IP地址,如果有内网地址用内网地址。
#--ignore-preflight-errors=Swap #初始化时添加参数,关闭Swap分区
[root@master ~]# kubeadm init --kubernetes-version=v1.20.15 --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=172.17.232.41 --ignore-preflight-errors=Swap
[root@master ~]# kubeadm reset #如果初始化失败需要删除环境后,更改错误,重新执行
[root@master ~]# rm -rf $HOME/.kube/config
#成功之后复制最后一行,这是加入集群的命令
kubeadm join 192.168.11.10:6443 --token t86uby.enzgkhvwsnx9c1l5 \
--discovery-token-ca-cert-hash sha256:01a7c6925642fa4228c7dd298a8b6bd903327a5996e675b89a7fa16b6c407eff
#成功之后执行以下步骤
[root@master ~]# mkdir -p $HOME/.kube
[root@master ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@master ~]# chown $(id -u):$(id -g) $HOME/.kube/config
[root@master ~]# kubectl get nodes #查看node节点
6、网络插件——master节点
在master节点操作
下载配置
# cd ~ && mkdir flannel && cd flannel
# curl -O https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
修改配置文件kube-flannel.yml:
此处的ip配置要与上面kubeadm的pod-network一致,本来就一致,不用改
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
# 这里注意kube-flannel.yml这个文件里的flannel的镜像是0.11.0,quay.io/coreos/flannel:v0.11.0-amd64
# 默认的镜像是quay.io/coreos/flannel:v0.11.0-amd64,需要提前pull下来。
# 如果Node有多个网卡的话,参考flannel issues 39701,
# https://github.com/kubernetes/kubernetes/issues/39701
# 目前需要在kube-flannel.yml中使用--iface参数指定集群主机内网网卡的名称,
# 否则可能会出现dns无法解析。容器无法通信的情况,需要将kube-flannel.yml下载到本地,
# flanneld启动参数加上--iface=<iface-name>
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.11.0-amd64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
- --iface=ens33
- --iface=eth0
⚠️⚠️⚠️--iface=ens33 的值,是你当前的网卡,或者可以指定多网卡
# 1.12版本的kubeadm额外给node1节点设置了一个污点(Taint):node.kubernetes.io/not-ready:NoSchedule,
# 很容易理解,即如果节点还没有ready之前,是不接受调度的。可是如果Kubernetes的网络插件还没有部署的话,节点是不会进入ready状态的。
# 因此修改以下kube-flannel.yaml的内容,加入对node.kubernetes.io/not-ready:NoSchedule这个污点的容忍:
- key: beta.kubernetes.io/arch
operator: In
values:
- arm64
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
- key: node.kubernetes.io/not-ready #添加如下三行---在261行左右
operator: Exists
effect: NoSchedule
serviceAccountName: flannel
[root@master ~]# kubectl apply -f kube-flannel.yml
[root@master ~]# cd ~ && mkdir flannel && cd flannel
[root@master flannel]# curl https://docs.projectcalico.org/manifests/calico.yaml -O
#修改POD网络,如果是默认的192.168.0.0/16,可以忽略
[root@master flannel]# vim calico.yaml
...
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"
...
#flannel 默认 pod 网络地址 10.244.0.0/16 calico 默认 pod 网络地址 192.168.0.0/16
[root@master flannel]# kubectl apply -f kube-flannel.yml
[root@master ~]# kubectl get pods --namespace kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-68845d5dc9-2xldw 1/1 Running 0 17h
calico-node-8wzj4 1/1 Running 0 16h
coredns-64897985d-86pp9 1/1 Running 0 18h
coredns-64897985d-wq8cs 1/1 Running 0 18h
etcd-master 1/1 Running 0 18h
kube-apiserver-master 1/1 Running 0 18h
kube-controller-manager-master 1/1 Running 0 18h
kube-flannel-ds-9987t 1/1 Running 0 17h
kube-proxy-jq4zj 1/1 Running 0 18h
kube-scheduler-master 1/1 Running 0 18h
[root@master ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18h
[root@master ~]# kubectl get svc --namespace kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 18h
7、重新生成token,node节点加入集群
kubeadm join 192.168.80.10:6443 --token t86uby.enzgkhvwsnx9c1l5 \
--discovery-token-ca-cert-hash sha256:01a7c6925642fa4228c7dd298a8b6bd903327a5996e675b89a7fa16b6c407eff
#默认token的有效期为24小时,当过期之后,该token就不可用了。
[root@master ~]# kubeadm token list #查看master的token
[root@master ~]# kubeadm token create --print-join-command #第一个不行用第二个查看master的token
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPSt86uby.enzgkhvwsnx9c1l5 5h 2022-03-09T07:13:18Z authentication,signing The default bootstrap token generated by 'kube
adm init'. system:bootstrappers:kubeadm:default-node-token
[root@master ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt |openssl rsa -pubin -outform der 2>/dev/null |openssl dgst -sha256 -hex| sed 's/^.* //' #查看master的sha256
解决方法:
1. 重新生成新的token:
[root@node1 flannel]# kubeadm token create
kiyfhw.xiacqbch8o8fa8qj
[root@node1 flannel]# kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
gvvqwk.hn56nlsgsv11mik6 <invalid> 2018-10-25T14:16:06+08:00 authentication,signing <none> system:bootstrappers:kubeadm:default-node-token
kiyfhw.xiacqbch8o8fa8qj 23h 2018-10-27T06:39:24+08:00 authentication,signing <none> system:bootstrappers:kubeadm:default-node-token
2. 获取ca证书sha256编码hash值:
[root@node1 flannel]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
5417eb1b68bd4e7a4c82aded83abc55ec91bd601e45734d6aba85de8b1ebb057
3. 节点加入集群:
kubeadm join 18.16.202.35:6443 --token kiyfhw.xiacqbch8o8fa8qj --discovery-token-ca-cert-hash sha256:5417eb1b68bd4e7a4c82aded83abc55ec91bd601e45734d6aba85de8b1ebb057
几秒钟后,您应该注意到kubectl get nodes在主服务器上运行时输出中的此节点。
上面的方法比较繁琐,一步到位:
kubeadm token create --print-join-command
第二种方法:
token=$(kubeadm token generate)
kubeadm token create $token --print-join-command --ttl=0
8、查看集群各组件状态
[root@master ~]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERR
ORscheduler Unhealthy Get "http://127.0.0.1:10251/healthz": dial tcp 127.0.0.1:10251: connect: connection refused
controller-manager Unhealthy Get "http://127.0.0.1:10252/healthz": dial tcp 127.0.0.1:10252: connect: connection refused
etcd-0 Healthy {"health":"true"}
#修改kube-scheduler.yaml文件和kube-controller-manager.yaml文件,把里面的port=0注释掉
[root@master ~]# vim /etc/kubernetes/manifests/kube-scheduler.yaml
[root@master ~]# vim /etc/kubernetes/manifests/kube-controller-manager.yaml
#每台master重启kubelet
[root@master ~]# systemctl restart kubelet.service
9、删除node
[root@master ~]# kubectl delete nodes node1 #master上面删除node1
[root@node1 ~]# kubeadm reset #node1上面重置环境
[root@node1 ~]# kubeadm join + #重新加入集群
10、重置kubeadm环境
整个集群所有节点(包括master)重置/移除节点
1.驱离k8s-node-1节点上的pod(master上)
[root@master ~]# kubectl drain kub-k8s-node1 --delete-local-data --force --ignore-daemonsets
2.删除节点(master上)
[root@master ~]# kubectl delete node kub-k8s-node1
3.重置节点(node上-也就是在被删除的节点上)
[root@node1 ~]# kubeadm reset
注1:需要把master也驱离、删除、重置,这里给我坑死了,第一次没有驱离和删除master,最后的结果是查看结果一切正常,但coredns死活不能用,搞了整整1天,切勿尝试
注2:master上在reset之后需要删除如下文件
# rm -rf /var/lib/cni/ $HOME/.kube/config
###注意:如果整个k8s集群都做完了,需要重置按照上面步骤操作。如果是在初始化出错只需要操作第三步