一旋炒、背景
徒手搭建過k8s的同學都曉得其中的煎熬步悠,復雜的認證,配置環(huán)節(jié)相當折磨人瘫镇,出錯率相當高鼎兽,而minikube就是為解決這個問題而衍生出來的工具,它基于go語言開發(fā)铣除, 是一個易于在本地運行 Kubernetes 的工具谚咬,可在你的筆記本電腦上的虛擬機內輕松創(chuàng)建單機版 Kubernetes 集群。便于嘗試 Kubernetes或使用 Kubernetes日常開發(fā)尚粘≡褙裕可以在單機環(huán)境下快速搭建可用的k8s集群,非常適合測試和本地開發(fā)郎嫁。如果沒有服務器或在本地筆記本安裝秉继,則可以在線使用https://labs.play-with-k8s.com來體驗K8s。
1.1 Kubernetes集群的架構
通常情況下泽铛,一套完整的Kubernetes集群至少需要包括master節(jié)點和node節(jié)點尚辑,下圖是常規(guī)k8s的集群架構,master節(jié)點一般是獨立的盔腔,用于協(xié)調調試其它節(jié)點之用杠茬,而容器實際運行都是在node節(jié)點上,kubectl位于 master節(jié)點铲觉。
1.2 Minikube 的架構
下圖是 Minikube 的架構澈蝙,可以看出,master 節(jié)點與其它節(jié)點合為一體撵幽,而整體則通過宿主機上的 kubectl 進行管理灯荧,這樣可以更加節(jié)省資源。
二盐杂、Minikube
2.1 Minikube介紹
Minikube 是一個二進制工具逗载,項目源碼或文檔等內容可以在 https://github.com/kubernetes/minikube 中找到,已經編譯好的二進制可執(zhí)行文件链烈,可以在倉庫的 Release 中下載厉斟,Minikube 支持 Windows 、Linux强衡、MacOS擦秽。
直接下載 minikube 最新版本的二進制文件。可以通過官方 Github 倉庫下載感挥,也可以使用國內代理下載缩搅。
下載地址(Linux版本):
https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.20.0/minikube-linux-amd64
https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
注:如果要下載 Win 版本,把 minkube-linux-amd64
改成 minkube-windows-amd64.exe
即可触幼;如果是 MacOS 則是 minikube-darwin-amd64
硼瓣。另外要注意下載的版本號 。
阿里云源下載的二進制工具置谦,本身可以使用國內鏡像堂鲤,不需要代理,可以到倉庫了解 https://github.com/AliyunContainerService/minikube媒峡。
2.1.1 Minikube 的基本運作原理
簡單來說就是瘟栖,用戶使用Minikube CLI管理虛擬機上的Kubernetes環(huán)境,比如:啟動丝蹭,停止慢宗,刪除,獲取狀態(tài)等奔穿。一旦Minikube虛擬機啟動镜沽,用戶就可以使用熟悉的Kubectl CLI在Kubernetes集群上執(zhí)行操作。
Minikube運作的基本原理如下所示:
- A: Minikube 在PC本地生成 kubeconfig 配置文件
- B: Minikube 在虛擬環(huán)境中創(chuàng)建 Minikube 虛擬機
- C: Minikube 在虛擬機中構建 Kubernetes
- D: Kubectl 通過 kubeconfig 對虛機中的 Kubernetes 進行管理
2.2 Ubuntu安裝Minikube
參考Minikube官網進行以下操作
2.2.1 硬件&容器要求
- CUP & 內存:最少是2核2GB贱田,
- 硬盤:需要20G缅茉,
- 網絡:能連因特網(需要下載安裝包),
- 容器:需要先安裝Docker或其他容器男摧。(本文用Docker容器)
本文使用的機器環(huán)境是:阿里云ECS蔬墩,Ubuntu 18.04 64位,4核(vCPU) 8 GiB
容器說明:
從K8S 1.24開始耗拓,dockershim已經從kubelet中移除拇颅,但因為歷史問題Docker卻不支持K8S主推的CRI(容器運行時接口)標準,所以Docker不能再作為K8S的容器運行時了乔询,即從K8S 1.24開始不再使用Docker了樟插。
但是如果想繼續(xù)使用Docker的話,可以在kubelet和Docker之間加上一個中間層cri-docker竿刁。cri-docker是一個支持CRI標準的shim(墊片)黄锤。一頭通過CRI跟kubelet交互,另一頭跟docker api交互食拜,從而間接的實現了K8S以Docker作為容器運行時鸵熟。但是這種架構缺點也很明顯,調用鏈更長负甸,效率更低流强。推薦使用containerd作為K8S的容器運行時痹届。
常用驅動:
Minikube在不同操作系統(tǒng)上支持不同的驅動
macOS:xhyve driver , VirtualBox 或 VMware Fusion,Docker 缺省驅動
Linux:VirtualBox 或 KVM2打月,Docker 缺省驅動
Windows:VirtualBox 或 Hyper-V
注意:
1短纵、由于minikube復用了docker-machine,在其軟件包中已經支持了相應的VirtualBox, VMware Fusion驅動僵控。
2、VT-x/AMD-v 虛擬化必須在 BIOS 中開啟鱼冀。
3报破、在Windows環(huán)境下,如果開啟了Hyper-V千绪,不支持VirtualBox方式
2.2.2 安裝Docker
1充易、安裝命令如下:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
也可以使用國內 daocloud 一鍵安裝命令:
curl -sSL https://get.daocloud.io/docker | sh
2、檢查docker版本號
docker --version
3荸型、用docker運行hello-world
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:13e367d31ae85359f42d637adf6da428f76d75dc9afeb3c21faea0d976f5c651
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
root@iZ0jle7r7zuxdbg7z1oqi0Z:~#
4盹靴、配置docker加速
由于國內訪問直接訪問Docker hub網速比較慢,拉取鏡像的時間就會比較長瑞妇。一般我們會使用鏡像加速或者直接從國內的一些平臺鏡像倉庫上拉取稿静。
我比較常用的是網易的鏡像中心和daocloud鏡像市場。
daocloud鏡像市場:https://hub.daocloud.io/
創(chuàng)建/etc/docker/daemon.json
文件并配置如下內容:
vi /etc/docker/daemon.json
{
"registry-mirrors" : [
"http://hub-mirror.c.163.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
重啟docker
systemctl enable docker && systemctl restart docker
2.2.3 下載安裝Minikube
在Minikube官網上辕狰,根據選擇的系統(tǒng)及版本改备,官網會生成下載安裝命令
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
通過minikube version
命令可以查看 minikube 的版本。
2.2.4 Minikube部署
直接執(zhí)行 minikube start
命令即可進行部署蔓倍,但是國內會被墻悬钳,可能拉取不了鏡像,需要設置代理偶翅。
# 國外服務器
minikube start
# 使用阿里云版本時默勾,指定國內源
minikube start --image-mirror-country=cn
# 使用阿里云版本時,指定鏡像源
minikube start --image-mirror=registry.cn-hangzhou.aliyuncs.com/google_containers
2.2.4.1 問題一
如果啟動不起來提示沒有 docker 用戶聚谁,這是因為默認不應該使用 root 用戶執(zhí)行命令和啟動程序母剥,可以創(chuàng)建一個 docker 用戶,也可以使用 --driver=none 指定不用 docker 用戶垦巴。如果要用 docker 用戶:
grouped docker
useradd -m docker
passed docker
# 修改密碼后媳搪,加入用戶組
gpasswd -a docker docker
打開 /etc/sudoers 文件,在 root ALL=(ALL:ALL) ALL 下 增加新的一行:
vi /etc/sudoers
docker ALL=(ALL)ALL
然后切換為 docker 用戶:su docker
如果不用 docker 用戶骤宣,只需要在初始化集群時加上 --driver=none
minikube start --image-mirror-country=cn --driver=none
2.2.4.2 問題二
如果報 X Exiting due to GUEST_MISSING_CONNTRACK: Sorry, Kubernetes 1.20.2 requires conntrack to be installed in root's path
秦爆,則需要安裝 construct。
apt install conntrack
再次執(zhí)行
minikube start --image-mirror-country=cn --driver=none
2.2.4.3 問題三
錯誤信息Failed to enable unit: Unit file cri-docker.socket does not exist
憔披。
需要安裝cri-dockerd
等限。
1爸吮、下載cri-dockerd
二進制文件
項目地址:https://github.com/Mirantis/cri-dockerd
2、拷貝cri-dockerd文件到遠程服務器并安裝
scp /Users/AC/cri-dockerd-0.2.3.amd64.tgz root@47.107.79.46:cri-dockerd-0.2.3.amd64.tgz
tar -xvf cri-dockerd-0.2.3.amd64.tgz
cp cri-dockerd/cri-dockerd /usr/bin/
chmod +x /usr/bin/cri-dockerd
# 確認已安裝版本
cri-dockerd --version
3望门、配置啟動文件
創(chuàng)建cri-docker.service配置文件
vi /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.7
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
創(chuàng)建cri-docker.socket配置文件
vi /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
也可以直接下載https://github.com/Mirantis/cri-dockerd/tree/master/packaging/systemd
注意形娇,需要修改cri-docker.service
中ExecStart啟動參數,這里/usr/bin/cri-dockerd
一定要加上參數–pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.7
用來指定所用的pause鏡像是哪個筹误,否則默認拉取k8s.gcr.io/pause:3.6
桐早,會導致安裝失敗。
4厨剪、啟動cri-docker
systemctl daemon-reload
systemctl start docker.service
systemctl enable cri-docker
systemctl status docker.service
5哄酝、再次執(zhí)行啟動minikube
minikube start --image-mirror-country=cn --driver=none
2.2.4.4 問題四
錯誤信息:Exiting due to RUNTIME_ENABLE: Temporary Error: sudo crictl version: exit status 1
需要安裝crictl,我們可以參考官方安裝步驟:crictl官網安裝步驟
VERSION="v1.24.1"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz
再次執(zhí)行啟動minikube
minikube start --image-mirror-country=cn --driver=none
啟動成功
root@iZwz91ofbggjr3fobspnv0Z:~# minikube start --image-mirror-country=cn --driver=none
?? minikube v1.26.0 on Ubuntu 18.04 (amd64)
? Using the none driver based on existing profile
?? Starting control plane node minikube in cluster qinikube
?? Restarting existing none bare metal machine for "minikube" ...
?? OS release is Ubuntu 18.04.6 LTS
?? Preparing Kubernetes v1.24.1 on Docker 20.10.17 ...
? kubelet.resolv-conf=/run/systemd/resolve/resolv.conf
> kubectl.sha256: 64 B / 64 B [--------------------------] 100.00% ? p/s 0s
> kubeadm.sha256: 64 B / 64 B [--------------------------] 100.00% ? p/s 0s
> kubelet.sha256: 64 B / 64 B [--------------------------] 100.00% ? p/s 0s
> kubectl: 43.59 MiB / 43.59 MiB [--------------] 100.00% 6.32 MiB p/s 7.1s
> kubeadm: 42.31 MiB / 42.31 MiB [---------------] 100.00% 3.98 MiB p/s 11s
> kubelet: 110.96 MiB / 110.96 MiB [-------------] 100.00% 7.29 MiB p/s 15s
? Generating certificates and keys ...
? Booting up control plane ...
? Configuring RBAC rules ...
?? Configuring local host environment ...
? The 'none' driver is designed for experts who need to integrate with an existing VM
?? Most users should use the newer 'docker' driver instead, which does not require root!
?? For more information, see: https://minikube.sigs.k8s.io/docs/reference/drivers/none/
? kubectl and minikube configuration will be stored in /root
? To use kubectl or minikube commands as your own user, you may need to relocate them. For example, to overwrite your own settings, run:
? sudo mv /root/.kube /root/.minikube $HOME
? sudo chown -R $USER $HOME/.kube $HOME/.minikube
?? This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true
?? Verifying Kubernetes components...
? Using image registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v5
?? Enabled addons: default-storageclass, storage-provisioner
?? kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
?? Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
root@iZwz91ofbggjr3fobspnv0Z:~#
查看minikube的運行狀態(tài)
minikube status
運行結果
root@iZwz91ofbggjr3fobspnv0Z:~# minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
root@iZwz91ofbggjr3fobspnv0Z:~#
查看container
docker container ls
可以看到minikube在docker中啟動了很多k8s相關的container
2.2.5 查看集群狀態(tài)
本身minikube帶有一些簡單的kubectl
命令祷膳,可以查看集群狀態(tài)信息陶衅。
獲取集群所有節(jié)點(機器)
minikube kubectl get nodes
獲取集群所有命名空間
minikube kubectl get namespaces
查看集群所有 Pod
minikube kubectl -- get pods -A
2.3 安裝kubectl、kubelet
kubectl它是kubernetes的命令行工具直晨,可以使用kubectl部署應用程序搀军,檢查和管理集群資源以及查看日志,通過kubectl對K8S進行操作。由于minikube不會自動下載kubectl勇皇、kubelet 等工具罩句,我們需要手動安安裝。
# 下載最新穩(wěn)定版本的kubuctl二進制文件
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.17.0/bin/linux/amd64/kubectl
# 為kubectl賦予可執(zhí)行權限
chmod +x ./kubectl
# 安裝到/usr/local/bin/目錄儒士,將可執(zhí)行文件放到系統(tǒng)的PATH目錄
sudo mv ./kubectl /usr/local/bin/kubectl
# 成功
kubectl version --client
# 檢查版本:
kubectl version -o json
顯示kubelet狀態(tài)信息
systemctl status kubelet -l
2.3.1 問題一
問題描述:
查詢集群中節(jié)點信息
kubectl get nodes
status顯示NotReady
root@iZwz91ofbggjr3fobspnv0Z:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
izwz91ofbggjr3fobspnv0z NotReady control-plane 3h53m v1.24.1
root@iZwz91ofbggjr3fobspnv0Z:~#
解決步驟:
1的止、實時滾動顯示某個Unit的最新日志
journalctl -u kubelet -f
root@iZwz91ofbggjr3fobspnv0Z:~# journalctl -u kubelet -f
-- Logs begin at Sun 2022-07-10 08:50:15 CST. --
Jul 10 14:25:49 iZwz91ofbggjr3fobspnv0Z kubelet[8389]: E0710 14:25:49.570536 8389 kubelet.go:2344] "Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized"
Jul 10 14:25:54 iZwz91ofbggjr3fobspnv0Z kubelet[8389]: E0710 14:25:54.580855 8389 kubelet.go:2344] "Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized"
關鍵錯誤信息:"Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized"
2、安裝flannel網絡插件(簡單易用)
# 下載flannel插件的yml
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 修改kube-flannel.yml中的鏡像倉庫地址為國內源
sed -i 's/quay.io/quay-mirror.qiniu.com/g' kube-flannel.yml
# 安裝網絡插件
kubectl apply -f kube-flannel.yml
3着撩、重啟kubelet服務
systemctl restart kubelet
4诅福、再次查詢節(jié)點狀態(tài)
kubectl get nodes
已經變成Ready
root@iZwz91ofbggjr3fobspnv0Z:/opt/cni/bin# kubectl get nodes
NAME STATUS ROLES AGE VERSION
izwz91ofbggjr3fobspnv0z Ready control-plane 4h49m v1.24.1
root@iZwz91ofbggjr3fobspnv0Z:/opt/cni/bin#
2.4 創(chuàng)建Deployment
Deployment可以部署應用并管理實例數量,它提供了一種故障的自我修復機制拖叙,當應用掛了后氓润,Deployment可以自動啟動一個新的實例,維護固定數量的Pod薯鳍。
kubectl create deployment
命令創(chuàng)建管理Pod的Deployment咖气。
格式:
kubectl create deployment {deployment名稱} {參數}
部署nginx
kubectl create deployment hello-nginx --image=nginx:latest
查看 Deployment
kubectl get deployments
查看 Pod
kubectl get pods
查看集群事件
kubectl get events
查看 kubectl 配置
kubectl config view
2.5 創(chuàng)建Service
Service為Pod提供了一種外網訪問能力,默認情況下挖滤,Pod 只能在 Kubernetes 集群的同一節(jié)點訪問崩溪,如果要外部網絡訪問,則需要為 Pod 暴露一個Kubnetes Service斩松,Service 為 Pod 提供了外網訪問能力×嫖ǎ現在我們就把剛才創(chuàng)建的nginx pod暴露出去。
nginx鏡像會暴露一個80 端口惧盹,通過 80 端口我們可以訪問到nginx 服務乳幸。但是在Kubernetes 中瞪讼,則可能有些麻煩。每個Pod 在集群中都有一個唯一 IP粹断,我們可以查看詳細的 Pod 信息:
kubectl get pods -o wide
為了能夠在外網訪問符欠,我們創(chuàng)建 Service
kubectl expose deployment hello-nginx --port=6001 --target-port=80 --type=LoadBalancer
然后查看剛剛創(chuàng)建的 service
kubectl get service hello-nginx
# 或
minikube service hello-nginx
2.6 清理集群資源
由于 Minikube 創(chuàng)建的資源只是單機的,同時會產生很多 Docker 容器瓶埋,我們練習完畢后希柿,就要清除環(huán)境,以免影響后續(xù)實踐環(huán)境养筒。首先清除 service狡汉、deployment (可以跳過這個步驟)。
kubectl delete service hello-nginx
kubectl delete deployment hello-nginx
然后停止 Minikube 虛擬機(VM)
minikube stop
接著刪除 Minikube 虛擬機(VM)
minikube delete
2.6 啟動minikube dashboard
1闽颇、Enable dashboard
minikube addons enable dashboard
2、查看所有的addons
minikube addons list
3寄锐、啟動dashboard
minikube dashboard
參考資料:
使用 Minikube 部署
kubeadm 部署Kubernetes1.24_cri-docker版本