Ubuntu基于kubeadm快速部署K8S实战

                                              作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

目录

一.K8S集群部署之各节点环境准备

1.虚拟机操作系统环境准备

参考链接:
	https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

2.关闭swap分区

	1. 临时关闭
swapoff -a && sysctl -w vm.swappiness=0
	
	2 基于配置文件关闭
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab

3.确保硬件设备会拥有唯一的地址

[root@master241 ~]# ifconfig  ens33  | grep ether | awk '{print $2}'
00:0c:29:8b:5d:15
[root@master241 ~]# cat /sys/class/dmi/id/product_uuid 
cfd44d56-7951-e670-48e0-bead0c8b5d15
[root@master241 ~]# 



[root@worker242 ~]# ifconfig  ens33  | grep ether | awk '{print $2}'
00:0c:29:61:a1:78
[root@worker242 ~]# cat /sys/class/dmi/id/product_uuid 
d8404d56-9099-eb9b-f0de-d3772361a178
[root@worker242 ~]# 


[root@worker243 ~]# ifconfig  ens33  | grep ether | awk '{print $2}'
00:0c:29:08:3c:1e
[root@worker243 ~]# cat /sys/class/dmi/id/product_uuid 
30f14d56-fdea-adfa-2f4c-b274e5083c1e
[root@worker243 ~]# 



温馨提示:
	一般来讲,硬件设备会拥有唯一的地址,但是有些虚拟机的地址可能会重复。 因此要确保各个节点MAC地址或product_uuid唯一。
    Kubernetes使用这些值来唯一确定集群中的节点。 如果这些值在每个节点上不唯一,可能会导致安装失败。

4.检查网络节点是否互通

简而言之,就是检查你的k8s集群各节点是否互通,可以使用ping命令来测试。

cat >> /etc/hosts <<EOF
10.0.0.241 master241
10.0.0.242 worker242
10.0.0.243 worker243
10.0.0.250 harbor.yinzhengjie.com
EOF

5.允许iptable检查桥接流量

	1.创建配置文件
cat <<EOF | tee /etc/modules-load.d/k8s.conf
br_netfilter
bridge
EOF

cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system


	2.临时生效,需要加载模块,所有节点均要操作
[root@master241 ~]# modprobe br_netfilter bridge
[root@master241 ~]# 
[root@master241 ~]# lsmod | grep bridge
bridge                176128  1 br_netfilter
stp                    16384  1 bridge
llc                    16384  2 bridge,stp
[root@master241 ~]# 
[root@master241 ~]# sysctl -f /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
[root@master241 ~]# 

6.检查端口是否被占用

参考链接: 
	https://kubernetes.io/zh-cn/docs/reference/networking/ports-and-protocols/

7.禁用防火墙

systemctl disable --now ufw

温馨提示:
	ubuntu的ufw类似于Centos的firewalld

8.禁用apparmor

systemctl disable --now apparmor


温馨提示:
	ubuntu的apparmor类似于Centos的selinux

9.安装containerd服务

本教材并不打算采用docker作为容器运行时,而是使用containerd作为底层的容器运行时。

需要自行安装containerd,线下的VIP同学可以直接使用我写好的一键部署脚本即可。

线上的同学可以参考我之前整理的blog,里面也有具体的二进制部署教程,您也可以自行编写一键部署脚本。

参考链接:
	https://www.cnblogs.com/yinzhengjie/p/18030527

温馨提示:
	如果不修改cgroup的管理驱动为systemd,则默认值为cgroupfs,在初始化master节点时会失败哟!

二.K8S集群部署之所有节点安装kubeadm,kubelet,kubectl

1.软件包说明

你需要在每台机器上安装以下的软件包:
	kubeadm:
		用来初始化集群的指令。
	kubelet:
		在集群中的每个节点上用来启动Pod和容器等。
	kubectl:
		用来与集群通信的命令行工具。

kubeadm不能帮你安装或者管理kubelet或kubectl,所以你需要确保它们与通过kubeadm安装的控制平面(master)的版本相匹配。 如果不这样做,则存在发生版本偏差的风险,可能会导致一些预料之外的错误和问题。 

然而,控制平面与kubelet间的相差一个次要版本不一致是支持的,但kubelet的版本不可以超过"API SERVER"的版本。 例如,1.7.0版本的kubelet可以完全兼容1.8.0版本的"API SERVER",反之则不可以。

2.配置软件源

新版kubernetes源使用方法和之前有一定区别,请求按照如下配置方法配置使用。

其中新版kubernetes源按照安装版本区分不同仓库,该文档示例为配置1.24版本,如需其他版本请在对应位置字符串替换即可。

比如需要安装1.29版本,则需要将如下配置中的v1.24替换成v1.29。目前该源支持v1.24 - v1.29版本,后续版本会持续更新。


实操案例
	1.更新"apt"包索引并安装使用Kubernetes apt仓库所需要的包
apt-get update && apt-get install -y apt-transport-https ca-certificates curl gpg

	2.下载用于 Kubernetes 软件包仓库的公共签名密钥。所有仓库都使用相同的签名密钥,因此你可以忽略URL中的版本
mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.24/deb/Release.key |
    gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
    
    3.添加Kubernetes apt仓库
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.24/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list 

3.查看kubeadm的版本

	1.更新apt包索引
[root@master241 ~]# apt-get update

	2.查看支持的kubeadm版本号
[root@master241 ~]# apt-cache madison kubeadm | awk '{ print $3 }'
1.24.17-1.1
1.24.16-1.1
1.24.15-1.1
1.24.14-1.1
1.24.13-1.1
1.24.12-1.1
1.24.11-1.1
1.24.10-1.1
1.24.9-1.1
1.24.8-1.1
1.24.7-1.1
1.24.6-1.1
1.24.5-1.1
1.24.4-1.1
1.24.3-1.1
1.24.2-1.1
1.24.1-1.1
1.24.0-2.1
[root@master241 ~]# 


温馨提示:
	将来你要安装的K8S时请所有组件版本均保持一致!

4 安装kubeadm,kubelet,kubectl软件包

	1.安装 kubelet、kubeadm 和 kubectl
apt-get -y install  kubelet=1.24.17-1.1 kubeadm=1.24.17-1.1 kubectl=1.24.17-1.1

	2.查看安装的版本
[root@master241 ~]# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.17", GitCommit:"22a9682c8fe855c321be75c5faacde343f909b04", GitTreeState:"clean", BuildDate:"2023-08-23T23:43:11Z", GoVersion:"go1.20.7", Compiler:"gc", Platform:"linux/amd64"}
[root@master241 ~]# 
[root@master241 ~]# kubelet --version
Kubernetes v1.24.17
[root@master241 ~]# 

	3.锁定其版本
apt-mark hold kubelet kubeadm kubectl


温馨提示:
	kubelet现在每隔几秒就会重启,因为它陷入了一个等待kubeadm指令的死循环。
	
参考链接:
	https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-kubeadm-kubelet-and-kubectl

三.K8S集群部署之初始化master节点

1.使用kubeadm初始化master节点

	1.初始化master节点
[root@master241 ~]# kubeadm init --kubernetes-version=v1.24.17 --image-repository registry.aliyuncs.com/google_containers  --pod-network-cidr=10.100.0.0/16 --service-cidr=10.200.0.0/16  --service-dns-domain=yinzhengjie.com


相关参数说明:
	--kubernetes-version:
		指定K8S master组件的版本号。
		
	--image-repository:
		指定下载k8s master组件的镜像仓库地址。
		
	--pod-network-cidr:
		指定Pod的网段地址。
		
	--service-cidr:
		指定SVC的网段

	--service-dns-domain:
		指定service的域名。若不指定,默认为"cluster.local"。
		

使用kubeadm初始化集群时,可能会出现如下的输出信息:
[init] 
	使用初始化的K8S版本。
	
[preflight] 
	主要是做安装K8S集群的前置工作,比如下载镜像,这个时间取决于你的网速。

[certs] 
	生成证书文件,默认存储在"/etc/kubernetes/pki"目录哟。

[kubeconfig]
	生成K8S集群的默认配置文件,默认存储在"/etc/kubernetes"目录哟。

[kubelet-start] 
	启动kubelet,
    环境变量默认写入:"/var/lib/kubelet/kubeadm-flags.env"
    配置文件默认写入:"/var/lib/kubelet/config.yaml"

[control-plane]
	使用静态的目录,默认的资源清单存放在:"/etc/kubernetes/manifests"。
	此过程会创建静态Pod,包括"kube-apiserver","kube-controller-manager"和"kube-scheduler"

[etcd] 
	创建etcd的静态Pod,默认的资源清单存放在:""/etc/kubernetes/manifests"
	
[wait-control-plane] 
	等待kubelet从资源清单目录"/etc/kubernetes/manifests"启动静态Pod。

[apiclient]
	等待所有的master组件正常运行。
	
[upload-config] 
	创建名为"kubeadm-config"的ConfigMap在"kube-system"名称空间中。
	
[kubelet] 
	创建名为"kubelet-config-1.22"的ConfigMap在"kube-system"名称空间中,其中包含集群中kubelet的配置

[upload-certs] 
	跳过此节点,详情请参考”--upload-certs"
	
[mark-control-plane]
	标记控制面板,包括打标签和污点,目的是为了标记master节点。
	
[bootstrap-token] 
	创建token口令,例如:"kbkgsa.fc97518diw8bdqid"。
	如下图所示,这个口令将来在加入集群节点时很有用,而且对于RBAC控制也很有用处哟。

[kubelet-finalize] 
	更新kubelet的证书文件信息

[addons] 
	添加附加组件,例如:"CoreDNS"和"kube-proxy”

2.拷贝kubeconfig文件到家目录

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


温馨提示:
	1.也可以添加环境变量"export KUBECONFIG=/etc/kubernetes/admin.conf";
	2.后续课程我们也会讲到自定义用户及授权相关的内容哟;

3.查看集群节点

[root@master241 ~]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS    MESSAGE                         ERROR
scheduler            Healthy   ok                              
controller-manager   Healthy   ok                              
etcd-0               Healthy   {"health":"true","reason":""}   
[root@master241 ~]# 
[root@master241 ~]# 
[root@master241 ~]# kubectl get nodes
NAME        STATUS     ROLES           AGE   VERSION
master241   NotReady   control-plane   10m   v1.24.17
[root@master241 ~]# 

四.K8S集群部署之配置worker节点加入集群

1.worker节点加入集群

[root@worker242 ~]# kubeadm join 10.0.0.241:6443 --token eapq0k.erthrm6oksihzd9h --discovery-token-ca-cert-hash sha256:5357c608da3b5ea26e4162725eff17989ac6590dca8356eb6107ad3bd430a319 


[root@worker243 ~]# kubeadm join 10.0.0.241:6443 --token eapq0k.erthrm6oksihzd9h --discovery-token-ca-cert-hash sha256:5357c608da3b5ea26e4162725eff17989ac6590dca8356eb6107ad3bd430a319 



温馨提示:
	注意,你的环境和我的不一样,需要拷贝你上一步产生的输出信息。

2.查看集群现有的worker节点

[root@master241 ~]# kubectl get nodes
NAME        STATUS     ROLES           AGE   VERSION
master241   NotReady   control-plane   13m   v1.24.17
worker242   NotReady   <none>          42s   v1.24.17
worker243   NotReady   <none>          8s    v1.24.17
[root@master241 ~]# 

五.k8s部署CNI组件之flannel案例

1.下载flannel的资源清单

[root@master241 ~]# wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

2.修改flannel的资源清单配置文件

[root@master241 ~]# vim kube-flannel.yml 
[root@master241 ~]# 
[root@master241 ~]# grep 16 kube-flannel.yml 
      "Network": "10.100.0.0/16",
[root@master241 ~]# 


温馨提示:
	修改和咱们Pod网络相同的网段即可。	

3.部署flannel组件

[root@master241 ~]# kubectl apply -f kube-flannel.yml 
namespace/kube-flannel created
serviceaccount/flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
[root@master241 ~]# 

4.查看是否部署成功

[root@master241 ~]# kubectl get pods -o wide -n kube-flannel
NAME                    READY   STATUS    RESTARTS   AGE    IP           NODE        NOMINATED NODE   READINESS GATES
kube-flannel-ds-5gsst   1/1     Running   0          115s   10.0.0.243   worker243   <none>           <none>
kube-flannel-ds-mwpj6   1/1     Running   0          115s   10.0.0.241   master241   <none>           <none>
kube-flannel-ds-zfftm   1/1     Running   0          115s   10.0.0.242   worker242   <none>           <none>
[root@master241 ~]# 

5.查看集群的信息

[root@master241 ~]# kubectl get nodes
NAME        STATUS   ROLES           AGE   VERSION
master241   Ready    control-plane   68m   v1.24.17
worker242   Ready    <none>          55m   v1.24.17
worker243   Ready    <none>          55m   v1.24.17
[root@master241 ~]# 

6.校验网络插件是否部署成功

[root@master241 ~]# cat deploy-apps.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: oldboyedu-app01
spec:
  replicas: 1
  selector:
    matchLabels:
      apps: v1 
  template:
    metadata:
      labels:
        apps: v1
    spec:
      nodeName: worker242
      containers:
      - name: c1
        image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1 

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: oldboyedu-app02
spec:
  replicas: 1
  selector:
    matchLabels:
      apps: v2 
  template:
    metadata:
      labels:
        apps: v2
    spec:
      nodeName: worker243
      containers:
      - name: c2
        image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
[root@master241 ~]# 
[root@master241 ~]# kubectl apply -f deploy-apps.yaml 
deployment.apps/oldboyedu-app01 created
deployment.apps/oldboyedu-app02 created
[root@master241 ~]# 

7.访问测试Pod

[root@master241 ~]# kubectl get pods -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP           NODE        NOMINATED NODE   READINESS GATES
oldboyedu-app01-67fcb64b-pj75r     1/1     Running   0          40s   10.100.1.2   worker242   <none>           <none>
oldboyedu-app02-546c76bbd4-ws2wt   1/1     Running   0          40s   10.100.2.2   worker243   <none>           <none>
[root@master241 ~]# 
[root@master241 ~]# curl 10.100.1.2
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v1</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: green">凡人修仙传 v1 </h1>
    <div>
      <img src="1.jpg">
    <div>
  </body>

</html>
[root@master241 ~]# 
[root@master241 ~]# curl 10.100.2.2
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v2</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: red">凡人修仙传 v2 </h1>
    <div>
      <img src="2.jpg">
    <div>
  </body>

</html>
[root@master241 ~]# 

8.删除资源

[root@master241 ~]# kubectl get pods -o wide
NAME                               READY   STATUS    RESTARTS   AGE     IP           NODE        NOMINATED NODE   READINESS GATES
oldboyedu-app01-67fcb64b-pj75r     1/1     Running   0          5m17s   10.100.1.2   worker242   <none>           <none>
oldboyedu-app02-546c76bbd4-ws2wt   1/1     Running   0          5m17s   10.100.2.2   worker243   <none>           <none>
[root@master241 ~]# 
[root@master241 ~]# kubectl delete -f deploy-apps.yaml 
deployment.apps "oldboyedu-app01" deleted
deployment.apps "oldboyedu-app02" deleted
[root@master241 ~]# 
[root@master241 ~]# kubectl get pods -o wide
No resources found in default namespace.
[root@master241 ~]# 

六.K8S新手注意事项

1.配置自动补全功能

apt -y install bash-completion
kubectl completion bash > ~/.kube/completion.bash.inc
echo "source '$HOME/.kube/completion.bash.inc'" >> $HOME/.bash_profile
source $HOME/.bash_profile

2.集群搭建完毕后拍快照

一定要拍快照,一定要拍快照,一定要拍快照,重要的事情说三遍。

拍快照的目的是为了避免同学们上课不小心把K8S环境搞崩了,便与你恢复到K8S集群搭建完毕的状态。

七.可能会遇到的报错

1. /proc/sys/net/bridge/bridge-nf-call-iptables does not exist

问题原因:
	没有加载"br_netfilter"和"bridge"模块。

解决方案:
[root@master241 ~]# modprobe br_netfilter bridge
[root@master241 ~]# 
[root@master241 ~]# lsmod | grep bridge
bridge                176128  1 br_netfilter
stp                    16384  1 bridge
llc                    16384  2 bridge,stp
[root@master241 ~]# 
[root@master241 ~]# sysctl -f /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
[root@master241 ~]# 

2.The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)

问题原因:
	很明显,这个报错是由于被禁用了"cgroups"导致的报错哟。
	
解决方案:(请确保"SystemdCgroup"是被启用的)
[root@master241 ~]# grep SystemdCgroup /etc/containerd/config.toml 
            SystemdCgroup = true
[root@master241 ~]# 


温馨提示:
	参考我的blog或者我给大家的脚本来安装containerd就已经避免了这个问题了哟~

3.Failed to create pod sandbox: rpc error: code = Unknown desc = failed to create containerd task: failed to start shim: exec: "containerd-shim": executable file not found in $PATH: unknown

问题原因:
	如上图所示,kubelet调用containerd创建容器时会用到"containerd-shim"工具,因此我们需要确保你的主机上是有这个命令的。
	如下图所示,如果有containerd-shim相关的工具,但名称不一致,只需要创建一个软连接即可。
	
	
解决方案:
[root@worker242 ~]# which containerd-shim
[root@worker242 ~]# 
[root@worker242 ~]# ln -svf /usr/bin/containerd-shim-runc-v2 /usr/bin/containerd-shim
'/usr/bin/containerd-shim' -> '/usr/bin/containerd-shim-runc-v2'
[root@worker242 ~]# 
[root@worker242 ~]# which containerd-shim
/usr/bin/containerd-shim
[root@worker242 ~]# 
[root@worker242 ~]# ll /usr/bin/containerd-shim
lrwxrwxrwx 1 root root 32 Mar  9 17:37 /usr/bin/containerd-shim -> /usr/bin/containerd-shim-runc-v2*
[root@worker242 ~]# 

4.Failed to create pod sandbox: rpc error: code = Unknown desc = failed to create containerd task: ttrpc: closed: unknown

问题原因:
	sandbox为基础架构的容器镜像,或者是缺少ttrpc的相关配置。
	
解决方案:
	重新生成containerd相关的配置并重启服务测试。

5.Error: failed to run Kubelet: running with swap on is not supported, please disable swap! or...

问题原因:
	没禁用swap分区,导致kubelet无法正常启动。
	这个问题不太好发觉,尤其是在刚刚搭建集群的时候,重启K8S后发现你的swap分区没有禁用导致kubelet无法正常启动。
	
解决方案:
	禁用swap分区,或者是启动kubelet时忽略swap的警告信息,这要求你的K8S版本必须大于1.22才支持,目前也属于测试版。
	生产环境中还是建议大家禁用swap分区,因为会影响其使用的性能。
	
[root@master241 ~]# swapoff -a
[root@master241 ~]#
[root@master241 ~]# free -h
              total        used        free      shared  buff/cache   available
Mem:          3.8Gi       339Mi       2.7Gi       1.0Mi       798Mi       3.2Gi
Swap:            0B          0B          0B
[root@master241 ~]# 
[root@master241 ~]# sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
[root@master241 ~]# 

posted @ 2024-03-09 01:30  尹正杰  阅读(742)  评论(0编辑  收藏  举报