Kubernetes集群部署
一、Kubernetes集群部署方式
方式1. minikube
Minikube是一个工具,可以在本地快速运行一个单点的Kubernetes,尝试Kubernetes或日常开发的用户使用。不能用于生产环境。
方式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集群。
其他的开源工具:
二、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重新登录以使其生效