首页 > 技术文章 > Kubernetes集群部署

pengpengboshi 2021-11-06 18:02 原文

一、Kubernetes集群部署方式

方式1. minikube

Minikube是一个工具,可以在本地快速运行一个单点的Kubernetes,尝试Kubernetes或日常开发的用户使用。不能用于生产环境。

官方地址:https://kubernetes.io/docs/setup/minikube/

方式2. kubeadm

Kubeadm也是一个工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。

官方地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/

方式3. 直接使用epel-release yum源,缺点就是版本较低 1.5

方式4. 二进制包

从官方下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。

其他的开源工具:

https://docs.kubeoperator.io/kubeoperator-v2.2/introduction

二、kubeadm部署k8s集群

官方文档:

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

kubeadm部署k8s高可用集群的官方文档:

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/
参考:https://www.cnblogs.com/ssgeek/p/11942062.html

1、系统配置

1.1、集群环境

机器数量

6台均为4核4g(因为redis集群最少6个节点,这样更符合实际环境)

每台机器必须设置域名解析

cat << EOF >> /etc/hosts
192.168.67.11 master1
192.168.67.12 master2
192.168.67.13 master3
192.168.67.21 node1
192.168.67.22 node2
192.168.67.23 node3
EOF

操作系统

Centos7.9

设置静态ip
https://www.cnblogs.com/pengpengboshi/p/13590430.html
每台机器设置主机名

hostname servername
nmcli general hostname servername
systemctl restart systemd-hostnamed
所有节点执行
ssh-keygen -t rsa
然后一路回车,
就会在各个节点生成公钥和私钥
ssh-copy-id -i master1
ssh-copy-id -i master2
ssh-copy-id -i master3
ssh-copy-id -i node1
ssh-copy-id -i node2
ssh-copy-id -i node3
然后输入一下登录密码,
被控制端就会生成一个authorized_keys,里面包含了你的公钥

测试一下,在master分别测试连通性,exit可以退出pty回到mater继续测试

ssh master1 $ ssh master2 $ ssh master3 $ ssh node1 $ ssh node2 $ ssh node3

1.2、禁用开机启动防火墙,selinux,Swap分区

systemctl disable firewalld
setenforce 0
sed -i 's/SELINUX=permissive/SELINUX=disabled/' /etc/sysconfig/selinux
SELINUX=disabled
swapoff -a && sysctl -w vm.swappiness=0
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab

1.5、检查MAC地址和product_uuid不能重复

ip link
cat /sys/class/dmi/id/product_uuid

2、安装软件

2.1 所有机器安装docker

update-alternatives --set iptables /usr/sbin/iptables-legacy
yum install -y yum-utils device-mapper-persistent-data lvm2 && yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && yum makecache && yum -y install docker-ce -y && systemctl enable docker.service && systemctl start docker

2.2 所有机器安装kubeadm和kubelet

配置aliyun的yum源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

安装最新版kubeadm

yum makecache -y
yum install -y kubelet kubeadm kubectl ipvsadm

说明:如果想安装指定版本的kubeadmin
yum install kubelet-1.16.0-0.x86_64 kubeadm-1.16.0-0.x86_64 kubectl-1.16.0-0.x86_64
 

配置内核参数

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

#手动加载所有的配置文件
sysctl --system
#加载模块                               
modprobe br_netfilter
#单独指定配置文件加载          
sysctl -p /etc/sysctl.d/k8s.conf                 
加载ipvs相关内核模块
如果重新开机,需要重新加载(可以写在 注意!!vi /etc/rc.local 中开机自动加载)source /etc/rc.local
modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh
modprobe nf_conntrack_ipv4

#查看是否加载成功
lsmod | grep ip_vs

3、获取镜像

特别说明:

  • 六个节点都要下载

  •    **注意下载时把版本号修改到官方最新版,即使下载了最新版也可能版本不对应,需要按报错提示下载**
    
  • 每次部署都会有版本更新,具体版本要求,运行初始化过程失败会有版本提示

  • kubeadm的版本和镜像的版本必须是对应的

    用命令查看版本当前kubeadm对应的k8s镜像版本

[root@master1 ~]# kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.22.3
k8s.gcr.io/kube-controller-manager:v1.22.3
k8s.gcr.io/kube-scheduler:v1.22.3
k8s.gcr.io/kube-proxy:v1.22.3
k8s.gcr.io/pause:3.5
k8s.gcr.io/etcd:3.5.0-0
k8s.gcr.io/coredns/coredns:v1.8.4

使用下面的方法在aliyun拉取相应的镜像并重新打标

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.22.3
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.22.3 k8s.gcr.io/kube-apiserver:v1.22.3
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.22.3
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.22.3 k8s.gcr.io/kube-controller-manager:v1.22.3
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.22.3
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.22.3 k8s.gcr.io/kube-scheduler:v1.22.3
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.22.3
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.22.3 k8s.gcr.io/kube-proxy:v1.22.3
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5 k8s.gcr.io/pause:3.5
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.0-0
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.0-0 k8s.gcr.io/etcd:3.5.0-0
docker pull coredns/coredns:1.8.4
docker tag coredns/coredns:1.8.4 k8s.gcr.io/coredns:1.8.4
docker tag registry.cn-shanghai.aliyuncs.com/flannel:v0.10.0-amd64
docker tag registry.cn-shanghai.aliyuncs.com/gcr-k8s/flannel:v0.10.0-amd64 registry.io/gcr-k8s/flannel:v0.10.0-amd64

下图是2021-11-06的版本1.22.3的下载列表

docker images | wc -l
24
[root@master1 flannel]# docker images

4、所有节点配置启动kubelet

4.1、配置kubelet使用国内pause镜像

配置kubelet的cgroups

cat > /etc/sysconfig/kubelet << EOF
KUBELET_EXTRA_ARGS="--cgroup-driver=$DOCKER_CGROUPS --pod-infra-container-image=k8s.gcr.io/pause:3.5"
EOF

4.2、启动

systemctl daemon-reload
systemctl enable kubelet && systemctl start kubelet

特别说明:在这里使用systemctl status kubelet,你会发现报错误信息

10月 11 00:26:43 node1 systemd[1]: kubelet.service: main process exited, code=exited, status=255/n/a

10月 11 00:26:43 node1 systemd[1]: Unit kubelet.service entered failed state.

10月 11 00:26:43 node1 systemd[1]: kubelet.service failed.

运行journalctl -xefu kubelet 命令查看systemd日志才发现,真正的错误是:

​ unable to load client CA file /etc/kubernetes/pki/ca.crt: open /etc/kubernetes/pki/ca.crt: no such file or directory

这个错误在运行kubeadm init 生成CA证书后会被自动解决,此处可先忽略。

简单地说就是在kubeadm init 之前kubelet会不断重启。

5、初始化集群

5.1、在master节点进行初始化操作

特别说明:

初始化完成必须要记录下初始化过程最后的命令,如下图所示

[root@master ~# kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.22.3 --apiserver-advertise-address 192.168.67.11 --pod-network-cidr=10.244.0.0/16 --token-ttl 0

#查看kubelet运行状态
systemctl status kubelet

上面记录了完成的初始化输出的内容,根据输出的内容基本上可以看出手动初始化安装一个Kubernetes集群所需要的关键步骤。

其中有以下关键内容:

[kubelet] 生成kubelet的配置文件”/var/lib/kubelet/config.yaml”

[certificates]生成相关的各种证书

[kubeconfig]生成相关的kubeconfig文件

[bootstraptoken]生成token记录下来,后边使用kubeadm join往集群中添加节点时会用到

5.2、在master节点配置使用kubectl

rm -rf $HOME/.kube
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

5.3、查看node节点

# kubectl get nodes
NAME   STATUS   ROLES   AGE   VERSION
master  NotReady  master  6m19s  v1.13.0

6、配置网络插件

6.1、master节点下载yaml配置文件

看我这篇文章配置:https://i.cnblogs.com/posts/edit;postId=15518513

6.2、修改配置文件kube-flannel.yml

说明:默认的镜像是quay.io/coreos/flannel:v0.10.0-amd64,如果你能pull下来就不用修改镜像地址,否则,修改yml中镜像地址为阿里镜像源,要修改所有的镜像版本,里面有好几条flannel镜像地址

image: registry.cn-shanghai.aliyuncs.com/gcr-k8s/flannel:v0.10.0-amd64

指定启动网卡

flanneld启动参数加上--iface=

  containers:
  - name: kube-flannel
    image: registry.cn-shanghai.aliyuncs.com/gcr-k8s/flannel:v0.10.0-amd64
    command:
    - /opt/bin/flanneld

    args:
    - --ip-masq
    - --kube-subnet-mgr
    - --iface=ens33
    - --iface=eth0   

⚠️⚠️⚠️--iface=ens33 的值,是你当前的网卡,或者可以指定多网卡

启动

# kubectl apply -f ~/flannel/kube-flannel.yml

查看

[root@master1 flannel]# kubectl get pods --namespace kube-system
NAME                              READY   STATUS    RESTARTS   AGE
coredns-7f6cbbb7b8-5cfbv          1/1     Running   0          3h52m
coredns-7f6cbbb7b8-ck54m          1/1     Running   0          3h52m
etcd-master1                      1/1     Running   0          3h53m
kube-apiserver-master1            1/1     Running   0          3h53m
kube-controller-manager-master1   1/1     Running   0          3h53m
kube-flannel-ds-75ksn             1/1     Running   0          46m
kube-flannel-ds-96725             1/1     Running   0          46m
kube-proxy-8sk9x                  1/1     Running   0          81m
kube-proxy-g679l                  1/1     Running   0          3h52m
kube-scheduler-master1            1/1     Running   0          3h53m
[root@master1 flannel]# kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   136m
[root@master1 flannel]# 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   136m

只有网络插件也安装配置完成之后,才能会显示为ready状态

7、配置所有node节点加入集群

在所有node节点操作,此命令为初始化master成功后返回的结果
加入集群 这里加入集群的命令每个人都不一样,可以登录master节点,使用kubeadm token create --print-join-command 来获取。获取后执行如下。
加入集群,如果这里不知道加入集群的命令,可以登录master节点,使用kubeadm token create --print-join-command 来获取

kubeadm join 192.168.67.11:6443 --token jtxwsr.n3y6wnmqr0crnffv --discovery-token-ca-cert-hash sha256:6d174a242e167adc5cd8e25800a12d4d2a421bdd5ed6c7bf86fc596f03d542bb

8、集群检测

查看pods

说明:节点加入到集群之后需要等待几分钟再查看

# kubectl get pods -n kube-system
NAME               						READY  STATUS       RESTARTS  AGE
coredns-6c66ffc55b-l76bq   		1/1   Running       0      16m
coredns-6c66ffc55b-zlsvh    	1/1   Running       0      16m
etcd-node1               			1/1   Running       0      16m
kube-apiserver-node1       		1/1   Running       0      16m
kube-controller-manager-node1 1/1   Running   		0      15m
kube-flannel-ds-sr6tq       	0/1   CrashLoopBackOff  6      7m12s
kube-flannel-ds-ttzhv       	1/1   Running       0      9m24s
kube-proxy-nfbg2          		1/1   Running       0      7m12s
kube-proxy-r4g7b          		1/1   Running       0      16m
kube-scheduler-node1       		1/1   Running       0      16m

遇到异常状态0/1的pod长时间启动不了可删除它等待集群创建新的pod资源

# kubectl delete pod kube-flannel-ds-sr6tq -n kube-system
pod "kube-flannel-ds-sr6tq" deleted

删除后再次查看,发现状态为正常

[root@master flannel]# kubectl get pods -n kube-system
NAME                             READY   STATUS    RESTARTS   AGE
coredns-6955765f44-g767b         1/1     Running   0          18m
coredns-6955765f44-l8zzs         1/1     Running   0          18m
etcd-master                      1/1     Running   0          18m
kube-apiserver-master            1/1     Running   0          18m
kube-controller-manager-master   1/1     Running   0          18m
kube-flannel-ds-amd64-bsdcr      1/1     Running   0          60s
kube-flannel-ds-amd64-g8d7x      1/1     Running   0          2m33s
kube-flannel-ds-amd64-qjpzg      1/1     Running   0          5m9s
kube-proxy-5pmgv                 1/1     Running   0          2m33s
kube-proxy-r962v                 1/1     Running   0          60s
kube-proxy-zklq2                 1/1     Running   0          18m
kube-scheduler-master            1/1     Running   0          18m

再次查看节点状态

[root@master1 flannel]# kubectl get nodes -n kube-system
NAME      STATUS   ROLES                  AGE     VERSION
master1   Ready    control-plane,master   3h54m   v1.22.3
node1     Ready    <none>                 82m     v1.22.3

到此集群配置完成

9、问题

1、问题01

描述:在搭建好的k8s集群内创建的容器,只能在其所在的节点上curl可访问,但是在其他任何主机上无法访问容器占用的端口

1.1、解决方案1:你的系统可能没开路由

# vim /etc/sysctl.conf
找到这一行,放开注释
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
重启主机(必须要重启才能生效)

1.2、解决方案2:

1.2.1、使用iptables打通网络
docker 从 1.13 版本开始,可能将 iptables FORWARD chain的默认策略设置为DROP,从而导致 ping 其它 Node 上的 Pod IP 失败,遇到这种情况时,需要手动设置策略为 ACCEPT:

# iptables -P FORWARD ACCEPT

并且把以下命令写入/etc/rc.local文件中,防止节点重启iptables FORWARD chain的默认策略又还原为DROP

# vim /etc/rc.local
sleep 60 && /sbin/iptables -P FORWARD ACCEPT
chmod +x /etc/rc.d/rc.local

2、问题02

kubectl命令补全设置

kubectl 自动补全
# source <(kubectl completion bash)
# echo "source <(kubectl completion bash)" >> ~/.bashrc
需要退出当前shell重新登录以使其生效

推荐阅读