書名: 深入理解邊緣計算:云、邊、端工作原理與源碼分析作者名: 崔廣章本章字數: 3964字更新時間: 2021-06-24 11:28:39
2.2 部署云部分——Kubernetes
Kubernetes是一個全新的基于容器技術的分布式架構的云部署方案,是Google開源的容器集群管理系統,為部署容器化的應用提供資源調度、服務發現和動態伸縮等一系列完整功能,提高了大規模容器集群管理的便捷性。本書將Kubernetes作為邊緣計算系統的云部分解決方案。
本節會對Kubernetes的部署方式進行梳理,主要對Kubernetes相關的容器運行時部署、Kubernetes的學習環境部署、Kubernetes的生產環境部署三方面進行梳理。
2.2.1 Kubernetes相關的容器運行時部署
Kubernetes通過容器運行時以Pod形式運行容器,官方默認支持Docker容器運行時。除此之外,Kubernetes支持的容器運行時還包括Containerd、Cri-o、Frakti等,具體如表2-1所示。
表2-1 Kubernetes支持的容器運行時

從Kubernetes支持的容器運行時列表,我們可知:
1)Docker和Containerd在實現原理上是相同的,只是Containerd裁剪了Docker原有的一些富功能。
2)Cri-o為了追求輕量級和簡潔,對CRI和OCI重新進行了實現。
3)Frakti的目的是實現容器運行時的強隔離,基于Hypervisors實現容器運行時,使每個容器具有獨立的操作系統。
目前,業界普遍使用的容器運行時是Docker。下面詳細說明部署Docker的相關步驟和注意事項。
本書使用的操作系統都是CentOS 7+,所以部署Docker的步驟也是針對CentOS 7+操作環境。
1)安裝需要的依賴包,命令如下:
# yum install yum-utils device-Mapper-persistent-data lvm2
2)增加安裝Docker所需的Repository,命令如下:
# yum-config-manager --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
3)安裝指定版本的Docker,命令如下:
# yum update && yum install containerd.io-1.2.10 docker-ce-19.03.4 docker-ce-cli-19.03.4
4)設置Docker的配置文件。
①創建配置文件目錄:
#mkdir /etc/docker
②設置Docker配置文件:
# cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ] } EOF
5)啟動Docker,命令如下:
# mkdir -p /etc/systemd/system/docker.service.d # systemctl daemon-reload # systemctl restart docker
至此,Docker容器運行時就安裝成功了。接下來,分析Docker配置相關的注意事項。
Docker的相關配置在/etc/docker/daemon.json文件中,包括設置私有倉庫、DNS解析服務器、Docker運行時使用的路徑、鏡像加速地址、日志輸出、Cgroup Driver、Docker主機的標簽等。本節重點介紹Cgroup Driver的設置。
Linux操作系統的發行版本中將Systemd作為其初始化系統,并初始化進程生成一個root控制組件。Systemd與Cgroup集成緊密,為每個進程分配Cgroup。Docker容器運行時默認的Cgroup管理器是Cgroupfs,也就是說Kubelet使用Cgroupfs來管理Cgroup。這樣就造成在同一臺主機上同時使用Systemd和Cgroupfs兩種Cgroup管理器來對Cgroup進行管理。
Cgroup用來約束分配給進程的資源。單個Cgroup管理器能夠簡化分配資源的視圖,并且默認情況下管理可用資源和使用中的資源時使用一致的視圖。當有兩個Cgroup管理器時,最終產生兩種視圖。我們已經看到某些案例中的節點配置讓Kubelet和Docker使用Cgroupfs管理器,而節點上運行的其余進程則使用Systemd,這類節點在資源壓力下會變得不穩定。
更改設置,令Docker和Kubelet使用Systemd作為Cgroup驅動,以便系統更穩定。請注意在/etc/docker/daemon.json文件中設置native.cgroupdriver=systemd選項,具體如下:
# vi /etc/docker/daemon.json { ... "exec-opts": ["native.cgroupdriver=systemd"], ... }
2.2.2 Kubernetes的學習環境部署
本節對部署Kubernetes學習環境的相關工具進行梳理,如表2-2所示。
表2-2 搭建Kubernetes學習環境的工具

從搭建Kubernetes學習環境的工具列表可知,Minikube、Kind都可以搭建Kubernetes的學習環境,但兩者所需要的依賴和原理各不相同。Minikube和Kind都是用于搭建Kubernetes學習環境的工具,二者的安裝步驟和使用方法相對比較簡單。接下來,筆者對二者的安裝步驟和使用方法進行詳細說明。
1. Minikube的安裝與使用
Minikube是一種可以在本地輕松運行Kubernetes的工具。其首先通過在物理服務器或計算機上創建虛擬機,然后在虛擬機(VM)內運行一個單節點Kubernetes集群。該Kubernetes集群可以用于開發和測試Kubernetes的最新版本。
下面對Minikube的安裝和使用進行說明。本書使用的操作系統都是CentOS 7+,所以本節安裝Minikube的步驟也是針對CentOS 7+操作環境。
(1)安裝Minikube
1)檢查對虛擬化的支持,命令如下:
# grep -E --color 'vmx|svm' /proc/cpuinf
2)安裝Kubectl。
推薦在Kubernetes的GitHub上的發布主頁下載pre-built的二進制壓縮包并進行安裝。
進入Kubernetes的GitHub倉庫上的發布主頁,找到需要下載的Kubernetes版本,比如本節要下載的版本是v1.16.6,如圖2-2所示。

圖2-2 Kubernetes v1.16.6發布版本
點擊CHANGELOG-1.16.md進入二進制文件下載列表,復制服務二進制壓縮包下載地址,使用wget命令下載服務二進制壓縮包,命令如下:
# wget https://dl.k8s.io/v1.16.6/Kubernetes-server-linux-amd64.tar.gz
下載Kubernetes具體如圖2-3所示。

圖2-3 下載Kubernetes
如圖2-4所示,解壓kubernetes-server-linux-amd64.tar.gz,命令如下:
# tar -zxvf kubernetes-server-linux-amd64.tar.gz

圖2-4 解壓Kubernetes
由圖2-4可知,Kubectl在kubernetes/server/bin下,只需將其放入/usr/bin下即可:
#cp kubernetes/server/bin/kubectl /usr/bin
3)安裝KVM。
在確認所在的操作系統支持虛擬機的前提下,通過如下步驟安裝KVM及相關依賴。
更新安裝KVM所需的源,命令如下:
#yum -y update && # yum install epel-release
安裝KVM及其所需的依賴包,命令如下:
# yum install qemu-kvm libvirt libvirt-python libguestfs-tools virt-install
設置libvirtd開機自動啟動,命令如下:
# systemctl enable libvirtd && systemctl start libvirtd
4)安裝Minikube,命令如下:
# curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-1.6.2.rpm \ && rpm -ivh minikube-1.6.2.rpm
(2)使用Minikube
1)啟動一個本地單節點集群,命令如下:
# minikube start --vm-driver=<driver_name>
2)檢查集群狀態,命令如下:
# minikube status
3)使用集群部署應用,命令如下:
# kubectl create deployment hello-minikube --image={image-name}
至此,我們已經成功安裝了Minikube,并通過Minikube創建了一個本地單節點的Kubernetes集群。
2. Kind的安裝與使用
Kind是一種使用Docker容器節點(該容器可用于運行嵌套容器,在該容器里可以使用Systemd運行、管理Kubernetes的組件)運行本地Kubernetes集群的工具。Kind主要是為了測試Kubernetes本身而設計的,可用于本地開發或持續集成。
下面對Kind的安裝和使用進行說明。
(1)安裝Kind
由于安裝Kind需要Go語言環境,使用Kind運行本地Kubernetes集群需要Docker容器運行時,因此在安裝Kind之前需要安裝Go和Docker。
1)安裝Go,命令如下:
# yum -y install Go
參考“部署Docker”小節來部署Docker容器運行時。
2)安裝Kind,命令如下:
#GO111MODULE="on" go get sigs.k8s.io/kind@v0.7.0
上述步驟會將Kind安裝到GOPATH/bin目錄下。為了使用方便,建議將其在/etc/profile中進行追加設置,命令如下:
# vi /etc/profile export PATH=$GOPATH/bin:$PATH
使在/etc/profile中設置的環境變量立即生效,命令如下:
#source /etc/profile
(2)使用Kind
1)使用Kind創建Kubernetes集群(如圖2-5所示),命令如下:
# kind create cluster

圖2-5 使用Kind創建集群
2)檢查、使用Kind部署的集群(如圖2-6所示),命令如下:
#kubectl get pods --all-namespaces

圖2-6 檢查使用Kind部署的集群狀態
至此,我們已經成功安裝了Kind,并通過Kind創建了一個本地單節點的Kubernetes集群。
2.2.3 Kubernetes的生產環境部署
本節對部署Kubernetes生產環境的相關工具進行梳理,具體如表2-3所示。
表2-3 搭建Kubernetes生產環境的工具

從表2-3可知,Kops、KRIB有明顯局限性,因為Kops主要在AWS上進行自動化部署Kubernetes集群;KRIB主要在裸機上進行自動化部署Kubernetes集群。Kubeadm和Kubespray可以在多種平臺上搭建Kubernetes的生產環境。Kubespray從v2.3開始支持Kubeadm,也就意味著Kubespray最終還是通過Kubeadm自動化部署Kubernetes集群。
本節首先對使用Kubeadm的注意事項進行說明,然后具體介紹如何安裝和使用Kubeam。Kubeadm支持的平臺和資源要求如表2-4所示。
表2-4 Kubeadm支持的平臺和資源要求

(1)使用Kubeadm的注意事項
1)確保集群中所有主機網絡可達。
在集群中不同主機間通過ping命令進行檢測,命令如下:
# ping {被檢測主機ip}
2)確保集群中所有主機的Hostname、MAC Address和product_uuid唯一。
查看主機Hostname命令:#hostname
查看MAC Address命令:#ip link
或者#ifconfig -a
查看product_uuid命令:#/sys/class/dmi/id/product_uuid
3)IPTables后端不用nftable,命令如下:
# update-alternatives --set iptables /usr/sbin/iptables-legacy
4)Kubernetes集群中主機需要打開的端口如表2-5所示。
表2-5 Kubernetes集群中主機需要打開的端口

由表2-5可知,上述需要打開的端口都是Kubernetes默認打開的端口。我們也可以根據需要對一些端口進行單獨指定,比如Kubernetes-api-server默認打開的端口是6443,也可以指定打開其他與現有端口不沖突的端口。
5)在Kubernetes集群的所有節點上關閉Swap分區,命令如下:
#swapoff -a
(2)安裝Kubeadm
安裝Kubeadm有兩種方式,即通過操作系統的包管理工具進行安裝,從Kubernetes的GitHub倉庫的發布主頁下載Pre-build的二進制壓縮包進行安裝。下面對這兩種安裝方式進行詳細說明。
1)通過操作系統的包管理工具安裝Kubeadm。
①在需要安裝Kubeadm的節點上設置安裝Kubeadm需要的倉庫,命令如下:
#cat <<EOF > /etc/yum.repos.d/kubernetes.repo [Kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/Kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF
②將SELINUX設置為permissive,命令如下:
#setenforce 0 #sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
③安裝Kubeadm、Kubelet、Kubectl,命令如下:
#yum install -y Kubelet kubeadm kubectl --disableexcludes=Kubernetes
④將Kubelet設置為開機自啟動,命令如下:
#systemctl enable --now Kubelet
2)通過在Kubernetes GitHub倉庫的發布主頁下載pre-build的二進制壓縮包來安裝Kubeadm。
(3)使用Kubeadm
使用Kubeadm可以部署Kubernetes單節點集群、Kubernetes單控制節點集群和Kubernetes高可用集群。下面將詳細說明部署這3種集群的具體步驟。
1)部署Kubernetes單節點集群。
使用Kubeadm部署Kubernetes單節點集群,其實是在一個節點使用Kubeadm部署Kubernetes的控制平面,然后對該節點進行設置,使其能夠運行應用負載。
①查看使用Kubeadm部署Kubernetes單節點集群時所需的鏡像,命令如下:
#kubeadm config images list
所需鏡像如圖2-7所示。

圖2-7 使用Kubeadm部署Kubernetes單節點集群所需鏡像
這些鏡像都是以k8s.gcr.io*開頭的。一般情況下,Kubeadm無法正常下載這些鏡像,需要提前準備好。獲取這些鏡像的方法不止一種,筆者建議通過DockerHub獲得。
②使用Kubeadm創建Kubernetes單節點集群,在創建的過程中會用到圖2-10列出的所有鏡像,命令如下:
#kubeadm init {args}
在args中一般只需指定--control-plane-endpoint、--pod-network-cidr、--cri-socket、--apiserver-advertise-address參數。這些參數的具體作用如下。
- --control-plane-endpoint:指定搭建高可用Kubernetes集群時,多個控制平面共用的域名或負載均衡IP。
- --pod-network-cidr:指定Kubernetes集群中Pod所用的IP池。
- --cri-socket:指定Kubernetes集群使用的容器運行時。
- --apiserver-advertise-address:指定kube-api-server綁定的IP地址——既可以是IPv4,也可以是IPv6。
我們可以根據具體情況指定以上參數。
③根據non-root用戶和root用戶,設置Kubectl使用的配置文件。
- 若是non-root用戶,設置命令如下:
$mkdir -p $HOME/.kube $sudo cp -i /etc/Kubernetes/admin.conf $HOME/.kube/config $sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 若是root用戶,設置命令如下:
export KUBECONFIG=/etc/Kubernetes/admin.conf
為了方便,我們也可以將KUBECONFIG設置成自動生效的系統環境變量,命令如下:
# vim /etc/profile export KUBECONFIG=/etc/Kubernetes/admin.conf
④安裝Pod所需的網絡插件,命令如下:
# kubectl apply -f https://docs.projectCalico.org/v3.8/manifests/Calico.yaml
本節使用的網絡插件是Calico,我們也可以根據具體需求選擇其他的網絡插件,比如Flannel、Weave Net、Kube-router等。
至此,一個完整的Kubernetes控制節點就搭建完成了,但這還不能算一個完整單節點集群,因為該控制節點默認不接受負載調度。要使其能夠接受負載調度,需要進行如下設置:
# kubectl taint nodes --all node-role.Kubernetes.io/master-
2)部署Kubernetes單控制節點集群。
Kubernetes單控制節點集群是指該Kubernetes集群只有一個控制節點,但可以有不止一個計算節點。部署該集群只需在部署Kubernetes單節點集群中安裝Pod所需的網絡插件之后,將計算節點加入該控制節點,具體命令如下:
ubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
使用kubeadm join命令將多個計算節點加入已經部署成功的控制節點,與控制節點組成一個單控制節點的Kubernetes集群。
3)部署Kubernetes高可用集群。
Kubeadm除了可以部署Kubernetes單節點集群和Kubernetes單控制節點集群外,還可以部署Kubernetes高可用集群。Kubeadm部署Kubernetes高可用集群的架構包含兩種,即Etcd集群與Kubernetes控制節點集群一起部署的Kubernetes高可用集群,以及Etcd集群與Kubernetes控制節點集群分開部署的Kubernetes高可用集群,具體架構如圖2-8和圖2-9所示。

圖2-8 Etcd集群與Kubernetes控制節點集群一起部署

圖2-9 Etcd集群與Kubernetes控制節點集群分開部署
由圖2-8和圖2-9可知,Kubernetes集群高可用即Kubernetes集群中Master節點和Etcd集群高可用。部署Kubernetes高可用集群是面向生產環境的,需要的資源比較多,部署步驟也相對比較復雜,限于篇幅本書就不展開說明了,感興趣的讀者可以參考Kubernetes官網進行實踐。