Kubernetes v1.25.0集群搭建實(shí)戰(zhàn)案例(新版本含Docker容器運(yùn)行時(shí))
一、前言
k8s的部署方式有多種kubeadm、kind、minikube、Kubespray、kops等本文介紹官方推薦的kubeadm的方式搭建集群。
二、安裝步驟
虛擬機(jī)兩臺(tái)(ip按自己的網(wǎng)絡(luò)環(huán)境相應(yīng)配置)(master/node)。
ip | hostname |
192.168.1.100 | master |
192.168.1.101 | node1 |
關(guān)閉防火墻(master/node)。
systemctl stop firewalld
systemctl disable firewalld
關(guān)閉selinux(master/node)。
setenforce 0 # 臨時(shí)關(guān)閉
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config # 永久關(guān)閉
關(guān)閉swap(master/node)。
swapoff -a # 臨時(shí)關(guān)閉;關(guān)閉swap主要是為了性能考慮
free # 可以通過(guò)這個(gè)命令查看swap是否關(guān)閉了
sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久關(guān)閉
打開(kāi)fstab后注釋掉這一行:
UUID=c83b0fb3-eb59-4b1e-bca0-a1731159c553 swap swap defaults 0 0
設(shè)置fstab要永久生效要reboot系統(tǒng),為了不立即reboot所以之前先使用swapoff -a臨時(shí)關(guān)閉一下。后續(xù)要reboot系統(tǒng)后就永久生效了。
free -m
添加主機(jī)名與IP對(duì)應(yīng)的關(guān)系(master/node)。
$ vim /etc/hosts
#添加如下內(nèi)容:
192.168.1.100 master
192.168.1.101 node1
#保存退出
修改主機(jī)名(master/node)。
#k8s-master
[root@localhost ~] hostname
localhost.localdomain
[root@localhost ~] hostname master ##臨時(shí)生效
[root@localhost ~] hostnamectl set-hostname master ##重啟后永久生效
#k8s-node1
[root@localhost ~] hostname
localhost.localdomain
[root@localhost ~] hostname node1 ##臨時(shí)生效
[root@localhost ~] hostnamectl set-hostname node1 ##重啟后永久生效
橋接設(shè)置(master/node)。
$ cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sysctl --system
- 以上幾步最好照著都執(zhí)行一下,以免后面報(bào)一大堆錯(cuò)
安裝docker(master/node)。
如果已經(jīng)安裝了dokcer就不需要重復(fù)安裝了,可以忽略此步驟
$ yum -y install docker-ce
# 設(shè)置開(kāi)機(jī)啟動(dòng)
$ systemctl enable docker
# 啟動(dòng)docker
$ systemctl start docker
為kubernetes添加國(guó)內(nèi)阿里云YUM軟件源(master/node)。
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[k8s]
name=k8s
enabled=1
gpgcheck=0
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
EOF
安裝kubeadm,kubelet和kubectl(master/node)。
#版本可以選擇自己要安裝的版本號(hào)
$ yum install -y kubelet-1.25.0 kubectl-1.25.0 kubeadm-1.25.0
# 此時(shí),還不能啟動(dòng)kubelet,因?yàn)榇藭r(shí)配置還不能,現(xiàn)在僅僅可以設(shè)置開(kāi)機(jī)自啟動(dòng)
$ systemctl enable kubelet
安裝容器運(yùn)行時(shí)(master/node)。
如果k8s版本低于1.24版,可以忽略此步驟。
由于1.24版本不能直接兼容docker引擎。
Docker Engine 沒(méi)有實(shí)現(xiàn) CRI, 而這是容器運(yùn)行時(shí)在 Kubernetes 中工作所需要的。 為此,必須安裝一個(gè)額外的服務(wù)cri-dockerd。 cri-dockerd 是一個(gè)基于傳統(tǒng)的內(nèi)置 Docker 引擎支持的項(xiàng)目, 它在 1.24 版本從 kubelet 中移除。
目前最新k8s版本為1.28.x。
你需要在集群內(nèi)每個(gè)節(jié)點(diǎn)上安裝一個(gè)容器運(yùn)行時(shí)以使Pod可以運(yùn)行在上面。高版本Kubernetes要求你使用符合容器運(yùn)行時(shí)接口(CRI)的運(yùn)行時(shí)。
以下是幾款 Kubernetes 中幾個(gè)常見(jiàn)的容器運(yùn)行時(shí)的用法:
- containerd
- CRI-O
- Docker Engine
- Mirantis Container Runtime
以下是使用 cri-dockerd 適配器來(lái)將 Docker Engine 與 Kubernetes 集成。
安裝cri-dockerd。
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.6/cri-dockerd-0.2.6.amd64.tgz
tar -xf cri-dockerd-0.2.6.amd64.tgz
cp cri-dockerd/cri-dockerd /usr/bin/
chmod +x /usr/bin/cri-dockerd
配置啟動(dòng)服務(wù)。
cat <<"EOF" > /usr/lib/systemd/system/cri-docker.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket
[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.8
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
EOF
主要是以下命令:ExecStart=/usr/bin/cri-dockerd --network-plugin=cni。
--pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.8。
p.s.pause的版本可以通過(guò)kubeadm config images list。
生成 socket 文件。
cat <<"EOF" > /usr/lib/systemd/system/cri-docker.socket
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-docker.service
[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
EOF
啟動(dòng) cri-docker 服務(wù)并配置開(kāi)機(jī)啟動(dòng)。
systemctl daemon-reload
systemctl enable cri-docker
systemctl start cri-docker
systemctl is-active cri-docker
部署Kubernetes (master) ,node節(jié)點(diǎn)不需要執(zhí)行kubeadm init。
創(chuàng)建kubeadm.yaml文件,內(nèi)容如下:
kubeadm init \
--apiserver-advertise-address=192.168.1.100 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.25.0 \
--service-cidr=10.10.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=all \
--cri-socket unix:///var/run/cri-dockerd.sock
--apiserver-advertise-address=master節(jié)點(diǎn)IP。
--pod-network-cidr=10.244.0.0/16 要與后面kube-flannel.yml里的ip一致也就是使用10.244.0.0/16不要改它。
成功后末尾輸出信息如下:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.9.2.94:6443 --token xhurmz.i2tnhhuw7c0ecuw6 \
--discovery-token-ca-cert-hash sha256:b3683deac5daa34a5778ede0ac0210bfbefce78a380c738aac7c2304c1cb1e4f
這里是通過(guò)kubeadm init安裝,所以執(zhí)行后會(huì)下載相應(yīng)的docker鏡像,一般會(huì)發(fā)現(xiàn)在控制臺(tái)卡著不動(dòng)很久,這時(shí)就是在下載鏡像,你可以docker images查看是不是有新的鏡像增加。
使用kubectl工具,kubeadm安裝好后,控制臺(tái)也會(huì)有提示執(zhí)行以下命令,照著執(zhí)行(也就是第11步最后控制臺(tái)輸出的)(master/node)。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
然后:
vim /etc/profile
#加入以下變量
export KUBECONFIG=/etc/kubernetes/admin.conf
source /etc/profile
測(cè)試一下kubectl命令。
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady master 23m v1.25.0
一般來(lái)說(shuō)狀態(tài)先會(huì)是NotReady ,可能程序還在啟動(dòng)中,過(guò)一會(huì)再看看就會(huì)變成Ready。
安裝Pod網(wǎng)絡(luò)插件flannel(master/node)。
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
報(bào)錯(cuò):The connection to the server
http://raw.githubusercontent.com was refused - did you specify the right host or port?
原因:國(guó)外資源訪問(wèn)不了。
解決辦法:host配置可以訪問(wèn)的ip。
vim /etc/hosts
#在/etc/hosts增加以下這條
199.232.28.133 raw.githubusercontent.com
重新執(zhí)行上面命令,便可成功安裝!
node節(jié)點(diǎn)加入master(node) 第12步控制臺(tái)輸出內(nèi)容。
kubeadm join 10.9.2.94:6443 --token ebe5w8.hfd3b59u9ww1r966 \
--discovery-token-ca-cert-hash sha256:b3683deac5daa34a5778ede0ac0210bfbefce78a380c738aac7c2304c1cb1e4f \
--ignore-preflight-errors=all \
--cri-socket unix:///var/run/cri-dockerd.sock
--ignore-preflight-errors=all \
--cri-socket unix:///var/run/cri-dockerd.sock
這兩行一定要加上不然就會(huì)報(bào)各種錯(cuò):
[preflight] Running pre-flight checks
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR CRI]: container runtime is not running: output: time="2023-08-31T16:42:23+08:00" level=fatal msg="validate service connection: CRI v1 runtime API is not implemented for endpoint \"unix:///var/run/cri-dockerd.sock\": rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService"
, error: exit status 1
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
Found multiple CRI endpoints on the host. Please define which one do you wish to use by setting the 'criSocket' field in the kubeadm configuration file: unix:///var/run/containerd/containerd.sock, unix:///var/run/cri-dockerd.sock
To see the stack trace of this error execute with --v=5 or higher
在master可node查看。
kubectl get nodes
到這里整個(gè)k8s集群環(huán)境就基本搭建完成了!
注意
- 安裝時(shí)注意自己安裝的程序版本。
- k8s組件也是以docker容器的形式存在,所以會(huì)下載很多dokcer image。
- 一般安裝不會(huì)在勝利,會(huì)出現(xiàn)不少問(wèn)題,用tailf /var/log/messages跟蹤下日志。
- 最好把幾臺(tái)機(jī)器系統(tǒng)時(shí)間同步下,節(jié)點(diǎn)通訊中的token與時(shí)間也有關(guān)。
三、相關(guān)筆記
- K8S在kubeadm init后,沒(méi)有記錄kubeadm join如何查詢?
#再生成一個(gè)token即可
kubeadm token create --print-join-command
#下在的命令可以查看歷史的token
kubeadm token list
- node節(jié)點(diǎn)kubeadm join失敗后,要重新join怎么辦?
#先執(zhí)行
kubeadm -y reset
#再執(zhí)行
kubeadm join xx.....
- 重啟kubelet
systemctl daemon-reload
systemctl restart kubelet
- 查詢
#查詢節(jié)點(diǎn)
kubectl get nodes
#查詢pods 一般要帶上"-n"即命名空間。不帶等同 -n dafault
kubectl get pods -n kube-system
四、相關(guān)問(wèn)題
k8s"棄用"docker?
記得當(dāng)時(shí)“k8s棄用docker”解讀滿天飛,很多文章說(shuō)docker已死。后來(lái)也出來(lái)一波說(shuō)并不是完全棄用docker只是移除了docker作為容器運(yùn)行時(shí)的支持。
- k8s去掉的其實(shí)是dockershim,這是一個(gè)在kubelet和docker之間的適配器,用來(lái)將docker的接口轉(zhuǎn)換為k8s所需的CRI(容器運(yùn)行時(shí)接口)。這樣做是為了簡(jiǎn)化k8s的架構(gòu),提高性能和安全性,以及支持更多的容器運(yùn)行時(shí)。
- k8s并沒(méi)有完全棄用docker,而是棄用了docker作為容器運(yùn)行時(shí)的支持。這意味著k8s將不再使用docker來(lái)創(chuàng)建和運(yùn)行容器,而是使用其他符合CRI標(biāo)準(zhǔn)的運(yùn)行時(shí),如containerd或CRI-O123。這樣做的原因是docker不符合CRI標(biāo)準(zhǔn),而且需要一個(gè)叫做dockershim的中間層來(lái)適配k8s的API。
- k8s去掉docker并不意味著docker就沒(méi)有用了,或者你不能或者不應(yīng)該用docker作為開(kāi)發(fā)工具。docker仍然是構(gòu)建容器鏡像的非常有用的工具,而且它生成的鏡像是符合OCI(開(kāi)放容器倡議)標(biāo)準(zhǔn)的。這意味著任何用docker構(gòu)建的鏡像都可以在k8s中與其他容器運(yùn)行時(shí)正常工作。所以你不需要擔(dān)心你的docker鏡像會(huì)失效或者不兼容。