kubernetes架構原理與集群環境部署
- 概述
- 為什么需要 Kubernetes
- Kubernetes 帶來的挑戰
- kubernetes架構解析
- master 節點的組件
- (1)API server
- (2)scheduler
- (3)Controller Manager
- (4)etcd
- Node 節點包含的組件
- (1)容器運行時
- (2)kubelet
- (3)kube-proxy代理
- kubernetes 網絡插件
- (1)Flannel 網絡
- (2)calico 網絡
- kubeadm快速安裝kubernetes集群
- 部署docker環境
- 基礎環境配置
- 時間同步(若同步可省略)
- (1)將虛擬機工具的離線包(linux.iso)添加至虛擬機的虛擬光驅
- (2)掛載此光盤
- (3)將光盤里的文件拷貝出來
- (4)解壓
- (5)進入解壓目錄
- (6)安裝虛擬機工具
- 下載repo文件
- kubelet設置開機啟動
- 生成初始化配置文件
- 修改初始化配置文件
- 拉取所需鏡像
- 初始化 k8s-master
- 復制配置文件到用戶的 home 目錄
- node 節點加入集群
- 在k8s-master節點設置環境變量并查看節點信息
- 部署Calico網絡插件
- Metrics-server部署
- 安裝helm客戶端
- (1)下載安裝包
- (2)解壓
- (3)安裝
- (4)查看版本
- 測試
概述
Kubernetes 是谷歌以 Borg 為前身,基于谷歌 15 年的生產環境經驗開源的一個項目。Kubernetes是一個開源的,用于管理云平臺中多個主機上的容器化的應用,Kubernetes 致力于提供跨主機集群的自動部署、擴展、高可用以及運行應用程序容器的平臺,其遵循主從式架構設計、組件可以分為工作節點(Node)組件,和控制平面組件。Kubernetes Master 是集群的主要控制單元,用于管理工作負載并指導整個系統的通信。Kubernetes 控制平面由各自的進程組成,沒個組件都可以在單個節點上運行,也可以在支持高可用集群的多個節點上運行。
為什么需要 Kubernetes
很多人會有疑問,有了 Docker 為什么還用 Kubernetes?
在業務開始進行容器化時,前期需要容器化的項目可能并不多,涉及的容器也并不多,此時基于Docker 容器直接部署至宿主機也能實現基本的需求。但是隨著項目越來越多,管理的容器也會越來越多,此時使用“裸容器”部署的方式管理起來就顯得很吃力,并且隨著業務量的增加,會明顯體會到“裸容器的不足。比如:
宿主機宕機造成該宿主機上的容器不可用,且無法自動恢復。
容器明明在運行,接口就是不通(健康檢查做得不到位)
應用程序部署、回滾、擴縮容困難。
成百上千的容器和涉及的端口難以維護。
上面的問題知識做一個簡單的羅列,真正使用時還有很多其他的問題。大家也可能使用過Docker-compose、Docker-swarm 等編排工具,但是這些工具的功能和 Kubernetes 比起來還是相差很多的。所以注定 Kubernetes 編排工具將成為主流的容器編排工具。
Kubernetes 帶來的挑戰
Kubernetes 從誕生至今,一路突飛猛進,在容器編排的領域過關斬將,最終拿下了容器編排的冠軍寶座,成為最無可替代、不可撼動的佼佼者,但是針對 Kubernetes 的學習和使用始終是一個很大的難題。
首先,Kubernetes 本身的學習就很困難,因為Kubernetes 概念太多,涉及的知識面也非常廣泛,可能學習了一個月也無法入門,甚至連集群也搭建不出來,使人望而卻步。并且 Kubernetes 的技術能力要求也比較高,因為運維不僅僅均線于傳統運維,有時候可能要修改業務代碼、制定業務上線體系、給研發人員在開發應用中提供更好的建議等。需要掌握的知識也有很多,可能需要掌握公司內所有使用帶的代碼,比如代碼如何進行編譯、如何正確發布、如何修改代碼配置文件等,這對于運維人員也是一種挑戰。Kubernetes 的誕生把運維從傳統的運維轉變到了 Devops 方向,需要面臨的問題更多,需要面臨的新技術也很多,但是當真正掌握Kubernetes 的核心和涉及理念,就會收益終身。
kubernetes架構解析
由圖可知,Kubernetes 架構可以簡單分為主(master)節點,從(worker/node)節點和數據庫 ETCD。其中主節點為集群的控制單元,一般不會運行業務應用程序,主要包含的組件 Kube-APIServer、Kube-ControllerManager、Kube-Scheduler。從節點為工作節點,也就是部署應用程序容器的節點,主要包含的組件有 Kubelet、Kube-Proxy,當然如果 master 節點也要部署容器,也會包含這兩個組件
同時,可以看出一個集群中可以有多個 node 節點,用于保證集群容器的分布式部署,以保證業務的高可用性,也可以有很多的 master 節點,之后通過一個負載均衡保證集群控制節點的高可用。負載均衡可以使用軟件負載均衡 Nginx、LVS、Haproxy+Keepalived 或者硬件負載均衡 F5 等,通過負載均衡對Kube-APIServer 提供的 VIP 即可實現 master 節點的高可用,其他組件通過該 VIP 連接至Kube-APIServer。ETCD 集群可以和 master 節點部署在同一個宿主機,也可以單獨部署,生產環境建議部署大于3的奇數臺 ETCD 節點用于實現 ETCD 集群的高可用。etcd 的 Leader 選舉和數據寫入都需要半數以上的成員投票通過確認,因此,集群最好由奇數個成員組成,以確保集群內部一定能夠產生多數投票通過的場景。這也就是為什么etcd 集群至少需要3個以上的成員
master 節點的組件
master 節點是 Kubernetes 集群的控制節點,在生產環境中不建議部署集群核心組件外的任何容器(在 kubeadm 安裝方式下,系統組件以容器方式運行在 master 節點的宿主機上;二進制安裝方式下,系統組件以守護進程的方式運行,master節點可以不運行任何容器),公司業務程序的容器是不建議部署在 master 節點上,以免升級或者維護時對業務在成影響。
(1)API server
API server 提供了集群網關,是整個集群的控制中樞,提供集群中各個模塊之間的數據交換,并將集群信息存儲到 ETCD 集群中。同時,它也是集群管理、資源配額、提供完備的集群安全機制的入口,為集群各類資源對象提供增刪改査。API server 在客戶端對集群進行訪問,客戶端需要通過認證,并使用
API server 作為訪問節點和 pod(以及服務)的堡壘和代理/通道。
API 服務器公開 Kubernetes API。
REST/kubectl 的入口點–它是 Kubernetes 控制平面的前端。
它跟蹤所有集群組件的狀態并管理它們之間的交互。
它旨在水平擴展。
它使用 YAML/JSON manifest 文件。
它驗證和處理通過 API 發出的請求。
(2)scheduler
Scheduler 主要功能是資源調度,將 pod 調度到對應的主機上。依據請求資源的可用性、服務請求的質量等約束條件,K8s也支持用戶自己提供的調度器
它將 pod 調度到工作節點。
它監視 api-server 以查找沒有分配節點的新創建的 Pod,并選擇一個健康的節點讓它們運行。
如果沒有合適的節點,則Pod 將處于掛起狀態,直到出現這樣一個健康的節點。
它監視 API Server 的新工作任務。
(3)Controller Manager
Controller Manager 負責維護集群的狀態,比如故障檢測、內存垃圾回收、滾動更新等,也執行API 業務邏輯;K8s 默認提供 replication controller、replicaset controller、daemonsetcontroller 等控制器
它監視它管理的對象的期望狀態并通過 API 服務器監視它們的當前狀態。
采取糾正措施以確保當前狀態與所需狀態相同。
它是控制器的控制器。
它運行控制器進程。從邏輯上講,每個控制器都是一個單獨的進程,但為了降低復雜性,它們都被編譯成一個二進制文件并在單個進程中運行。
(4)etcd
etcd 用于可靠的存儲集群的配置數據,是一種持久性、輕量型、分布式的鍵值數據存儲組件。可以理解為一種分布式的非關系型數據庫。etcd 是集群的狀態, K8s 默認使用分布式的 etcd 集群整體存儲用來實現發現服務和共享配置集群的所有狀態都存儲在 etcd 實例中,并具有監控的能力,因此當 etcd中的信息發生變化時,能夠快速地通知集群中相關的組件。
它是一個一致的、分布式的、高度可用的鍵值存儲。
它是有狀態的持久存儲,用于存儲所有 Kubernetes 集群數據(集群狀態和配置)
它是集群的真相來源。
它可以是控制平面的一部分,也可以在外部進行配置。
etcd 集群最少3個節點,容錯點才會有1個。3 個節點和4個節點的容錯能力是一樣的,所以有時候保持奇數節點更好,從這里可以判斷出我們在部署k8s 的時候,至少有3個節點,才保證 etcd有1個節點容錯性。
另外,etcd 的 Leader 選舉和數據寫入都需要半數以上的成員投票通過確認,因此,集群最好由奇數個成員組成,以確保集群內部一定能夠產生多數投票通過的場景。所以etcd 集群至少需要 3個以上的奇數個成員。
如果使用偶數個節點,可能出現以下問題:
偶數個節點集群不可用風險更高,表現在選主(Leader 選舉)過程中,有較大概率的等額選票從而觸發下一輪選舉。
偶數個節點集群在某些網絡分割的場景下無法正常工作。當網絡分割發生后,將集群節點對半分割開,形成腦裂。
Node 節點包含的組件
Node 節點也被成為 worker 節點,是主要負責部署容器的主機,集群中的每個節點都必須具備容器的Runtime(運行時),比如docker
kubelet 作為守護進程運行在 Node 節點上,負責監聽該節點上所有的 pod,同時負責上報該節點上所有 pod 的運行狀態,確保節點上的所有容器都能正常運行。當 Node 節點宕機或故障時,該節點上運行的 pod 會被自動轉移到其他節點上。
(1)容器運行時
docker 引擎是本地的容器運行時環境,負責鏡像管理以及 pod 和容器的真正運行。K8s 本身并不提供容器運行時環境,但提供了接口,可以插入所選擇的容器運行時環境,目前支持 Docker 和 rkt。容器運行時是負責運行容器(在 Pod 中)的軟件,為了運行容器,每個工作節點都有一個容器運行時引擎,它從容器鏡像注冊表(container image registry)中提取鏡像并啟動和停止容器。
Kubernetes 支持多種容器運行時:
Docker
containerd
CRI-0
Kubernetes CRI(Container Runtime Interface,容器運行時接口)的任何實現
(2)kubelet
kubelet 是 node 節點上最主要的工作代理,用于匯報節點狀態并負責維護 pod 的生命周期,也負責volume(CVI)和網絡(CNI)的管理。kubelet 是 pod 和節點 API 的主要實現者,負責驅動容器執行層。作為基本的執行單元,pod 可以擁有多個容器和存儲卷,能夠方便地在每個容器中打包一個單一的應用,從而解耦了應用構建時和部署時所關心的事項,方便在物理機或虛擬機之間進行遷移。
它是在集群中的每個節點上運行的代理。
它充當 API 服務器和節點之間的管道。
它確保容器在 Pod 中運行并且它們是健康的。
它實例化并執行 Pod。
它監視 API Server 的工作任務!
它從主節點那里得到指令并報告給主節點
(3)kube-proxy代理
kube-proxy 代理對抽象的應用地址的訪問,服務提供了一種訪問一群 pod 的途徑, kube-proxy 負責為服務提供集群內部的服務發現和應用的負載均衡(通常利用 iptables 規則),實現服務到 pod 的路由和轉發。此方式通過創建一個虛擬的 IP 來實現,客戶端能夠訪問此 IP,并能夠將服務透明地代理至 pod.
它是網絡組件,在網絡中起著至關重要的作用。
它管理 IP 轉換和路由。
它是運行在集群中每個節點上的網絡代理。
它維護節點上的網絡規則。這些網絡規則允許從集群內部或外部與Pod進行網絡通信。
它確保每個 Pod 獲得唯一的 IP 地址。
這使得 pod 中的所有容器共享一個 IP 成為可能。
它促進了 Kubernetes 網絡服務和服務中所有 pod 的負載平衡。
它處理單個主機子網并確保服務可供外部各方使用。
kubernetes 網絡插件
CNI(容器網絡接口)是一個云原生計算基金會項目,它包含了一些規范和庫,用于編寫在 Linux容器中配置網絡接口的一系列插件。CNI 只關注容器的網絡連接,并在容器被刪除時移除所分配的資源。
Kubernetes 使用 CNI 作為網絡提供商和 Kubernetes Pod 網絡之間的接口。
(1)Flannel 網絡
由 Coreosk 開發的一個項目,很多部署工具或者 k8s 的發行版都是默認安裝,flannel 是可以用集群現有的 etcd,利用 api 方式存儲自身狀態信息,不需要專門的數據存儲,是配置第三層的 ipv4 0verlay網絡,在此網絡內,每個節點一個子網,用于分配 ip 地址,配置 pod 時候,節點上的網橋接口會為每個新容器分配一個地址,同一主機中的 pod 可以使用網橋通信,不同主機的 pod 流量封裝在 udp 數據包中,路由到目的地。
Flannel 通過每個節點上啟動一個 flnnel 的進程,負責給每一個節點上的子網劃分、將子網網段等信息保存至 etcd,具體的報文轉發是后端實現,在啟動時可以通過配置文件指定不同的后端進行通信,目前有 UDP、VXLAN、host-gateway 三種,VXLAN 是官方推薦,因為性能良好,不需人工干預。UDP、VXLAN是基于三層網絡即可實現,host-gateway 模式需要集群所有機器都在同一個廣播域、就是需要在二層網絡在同一個交換機下才能實現,host-gateway 用于對網絡性能要求較高的常見,需要基礎網絡架構支持,UDP 用于測試或者不支持 VXLAN 的 linux 內核。反正一般小規模集群是完全夠用的,直到很多功能無法提供時在考慮其他插件。
(2)calico 網絡
雖然 fa1nnel 很好,但是 calico 因為其性能、靈活性都好而備受歡迎,calico 的功能更加全面不但具有提供主機和 pod 間網絡通信的功能,還有網絡安全和管理的功能,而且在 CNI 框架之內封裝了calico 的功能,calico 還能與服務網絡技術 Istio 集成,不但能夠更加清楚的看到網絡架構也能進行靈活的網絡策略的配置,calico 不使用 overlay 網絡,配置在第三層網絡,使用 BGP 路由協議在主機之間路由數據包,意味著不需要包裝額外的封裝層。主要點在網絡策略配置這一點,可以提高安全性和網絡環境的控制。
如果集群規模較大,選擇 calico 沒錯,當然 calico 提供長期支持,對于一次配置長期使用的目的來說,是個很好的選擇。
kubeadm快速安裝kubernetes集群
確保可連接互聯網,推薦虛擬機使用 NAT 模式。k8s-master 主機最小建議配置為 2 核 4G,k8s-node 節點最小建議配置 為 2 核 2G。
Kubernetes v1.23 支持高達 5008 節點。更準備地說,在使用 Kubernetes 時,應當遵循以下所有準則:
每個節點不要超過 110個 Pod,
集群不要超過 5000 節點,
集群不要超過 150000 個 Pod,
不要超過 300000個Container。
部署docker環境
(這一步可以看我之前的文章配置,此處不進行詳解)
基礎環境配置
systemctl stop firewalld
setenforce 0
systemctl disabled firewalld
sed -i '^SELINUX=/s/enforcing/disabled/' /etc/selinux/config
時間同步(若同步可省略)
確保三臺時間同步(可與宿主機不同步,但三臺主機必須一致)
(1)將虛擬機工具的離線包(linux.iso)添加至虛擬機的虛擬光驅
(2)掛載此光盤
mount /dev/cdrom /mnt
(3)將光盤里的文件拷貝出來
cp VMwareTools-10.3.26-22085142.tar.gz /root
(4)解壓
cd
tar zxvf VMwareTools-10.3.26-22085142.tar.gz
(5)進入解壓目錄
cd vmware-tools-distrib/
(6)安裝虛擬機工具
./vmware-install.pl
然后一直按回車
下載repo文件
此處用的舊版本
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=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
想找新版可以去阿里的倉庫找https://developer.aliyun.com/mirror/
dnf clean all
dnf makecache
dnf -y install kubelet-1.23.0 kubeadm-1.23.0 kubectl-1.23.0
如果在命令執行過程中出現索引 gpg 檢査失敗的情況,請使用 yum insta11 -y --nogpgcheckkubelet-1.23.0 kubeadm-1.23,0 kubect1-1.23.0 來安裝,或者將gpgcheck=1和repo gpgcheck=1設置為 0
kubelet設置開機啟動
三臺節點都需要做
systemctl enable kubelet
生成初始化配置文件
master節點做
kubeadm config print init-defaults > init-config.yaml
Kubeadm 提供了很多配置項,Kubeadm 配置在 Kubernetes 集群中是存儲在 ConfigMap 中的,也可將這些配置寫入配置文件,方便管理復雜的配置項。Kubeadm 配置內容是通過 kubeadm config 命令寫入配置文件的。
其中,kubeadm config 除了用于輸出配置項到文件中,還提供了其他一些常用功能,如下所示。
kubeadm config view:查看當前集群中的配置值
kubeadm config print join-defaults:輸出 kubeadm join 默認參數文件的內容。
kubeadm config images list:列出所需的鏡像列表。
kubeadm config images pull:拉取鏡像到本地。
kubeadm config upload from-flags: 由配置參數生成 ConfigMap
修改初始化配置文件
master節點
vim init-config.yaml
修改以下內容
advertiseAddress: 192.168.10.101(master節點IP)
name: k8s-master
imageRepository: registry.aliyuncs.com/google_containers
podSubnet: 10.244.0.0/16
注意:1.24.8 的版本中 apiVersion:kubeadm.k8s.io/v1beta2 被棄用,
servicesubnet:指定使用 ipvs 網絡進行通信,ipvs 稱之為 IP 虛擬服務器(IP Virtual Server,簡寫為IPVS)。是運行在 LVS下的提供負載平衡功能的一種技術。含義 IPVS基本上是一種高效的Layer-4交換機
podsubnet 10.244.0.0/16 參數需要和后文中 kube-flannel.yml 中的保持一致,否則,可能會使得 Node 間 cluster IP 不通
默認情況下,每個節點會從 Podsubnet 中注冊一個掩碼長度為 24 的子網,然后該節點的所有 podip 地址都會從該子網中分配。
拉取所需鏡像
master節點
操作節點:k8s-master
如果地址無法解析,可以使用阿里的公共 DNS:223.5.5.5或223.6.6.6
kubeadm config images list --config init-config.yaml
kubeadm config images pull--config=init-config.yaml
此步驟是拉取 k8s 所需的鏡像,如果已經有離線鏡像,可以直接導入,這一步就不需要了
初始化 k8s-master
操作節點:k8s-master
注意:master節點最少需要2個CPU
kubeadm init --config=init-config.yaml
執行完該命令后一定記下最后生成的 token:
kubeadm join 192.168.10.101:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash
sha256:8b17b7d607ab7f79c2249c58d74525368bbb15ad884c365aaa1a968b9833d107
Kubeadm 通過初始化安裝是不包括網絡插件的,也就是說初始化之后是不具備相關網絡功能的,比如k8s-master 節點上査看節點信息都是“Not Ready”狀態、Pod 的 CoreDNS 無法提供服務等。
復制配置文件到用戶的 home 目錄
操作節點:k8s-master
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g)$HOME/.kube/config
node 節點加入集群
操作節點:k8s-node01、k8s-node02
將 master 中生成的 token,直接復制過來即可
在k8s-master節點設置環境變量并查看節點信息
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
kubectl get nodes
kubectl get pod -A
因為此時還沒安裝網絡插件,coredns 無法獲得解析的 IP,就會使得 coredns 處于 pending 狀態。
各個節點的狀態也處于 NotReady 的狀態,這些異常情況待安裝過網絡插件后都會自行解決。
部署Calico網絡插件
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
也可以提前下載好 calica 的資源清單直接部署
[root@k8s-master ~]# kubectl create -f calico.yaml
kubectl get nodes
kubectl get pod --all-namespaces
Metrics-server部署
Metrics Server 是一種可擴展、高效的容器資源指標來源,適用于Kubernetes 內置的自動縮放管道。Metrics Server 從 Kubelets 收集資源指標,并通過 Metrics API 將它們暴露在 Kubernetesapiserver 中,供Horizontal Pod Autoscaler 和 Vertical Pod Autoscaler 使用。指標 API 也可以通過 訪問 kubectl top,從而更容易調試自動縮放管道。
Metrics server 對集群和網絡配置有特定的要求。這些要求并不是所有集群分布的默認要求。在使用 Metrics Server 之前,請確保您的集群分布支持這些要求:
kube-apiserver 必須啟用聚合層。
節點必須啟用 Webhook 身份驗證和授權。
Kubelet 證書需要由集群證書頒發機構簽名(或通過傳遞–kubelet-insecure-tls 給Metrics Server 來禁用證書驗證)注意這里是重點,如果本地沒有簽名需要傳遞 args:"–kubelet-insecure-tls"給Metrics Server
容器運行時必須實現容器指標RPC(或具有cAdvisor 支持)
網絡應支持以下通信:
(1)控制平面到指標服務器。控制平面節點需要到達 Metrics Server 的 pod IP 和端口10250(或節點 IP 和自定義端口,如果 hostNetwork 已啟用)
(2)所有節點上的 Kubelet 的指標服務器。指標服務器需要到達節點地址和 Kubelet 端口。地址和端口在 Kubelet 中配置并作為 Node 對象的一部分發布。字段中的地址.status.daemonEndpoints.kubeletEndpoint.port(默認 10250)。Metrics Server 將根據 kubelet-preferred-address-types 命令行標志(InternalIP,ExternalIP,Hostname 清單中的默認值) 提供的列表選擇第一個節點地址
源碼位置:
matrics-server的github地址:https://github.com/kubernetes-sigs/metrcs-server
kubectl create -f components.yaml
kubectl top node
kubectl top pod -A
安裝helm客戶端
(1)下載安裝包
wget https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz
(2)解壓
tar zxvf helm-v3.9.4-linux-amd64.tar.gz
(3)安裝
mv linux-amd64/helm /usr/local/bin/
(4)查看版本
helm version
在使用 kubectl命令的時候,如果覺得單詞不好打,可以設置一個別名:
vim ~/.bashrc
添加
alias ku='kubectl'
測試
vim nginx-service.yaml
kubectl create -f nginx-service.yaml
kubectl get pod
kubectl get service
用宿主機瀏覽器訪問
http://192.168.10.101:32362