概述
**本人部落格網站 **IT小神 www.itxiaoshen.com
Kubernetes官網位址 https://kubernetes.io Kubernetes GitHub源碼位址 https://github.com/kubernetes/kubernetes Kubernetes,也稱為K8s,生産級别的容器編排系統,是一個用于自動化部署、擴充和管理容器化應用程式的開源系統。
Kubernetes,是一個go語言開發(docker也是go語言開發,可見go語言的厲害和趨勢,其兼具 Python 等動态語言的開發速度和 C/C++ 等編譯型語言的性能與安全性”,部署簡單、并發性好、語言設計良好、執行性能高,後續我們專題學習它)用于跨多個主機管理容器化應用程式的開放源代碼系統。它為應用程式的部署、維護和擴充提供了基本機制。
Kubernetes的發展曆史,從公有雲Iaas、Paas、Saas的雲計算時代開始,到Docker Swarm用于容器化叢集和Apache Mesos為分布式資源管理架構,最終成為容器化編排主流引領者
特性
自動化上線和復原
Kubernetes 會分步驟地将針對應用或其配置的更改上線,同時監視應用程式運作狀況以確定你不會同時終止所有執行個體。如果出現問題,Kubernetes 會為你復原所作更改。你應該充分利用不斷成長的部署方案生态系統。
服務發現與負載均衡
無需修改你的應用程式即可使用陌生的服務發現機制。Kubernetes 為容器提供了自己的 IP 位址和一個 DNS 名稱,并且可以在它們之間實作負載均衡。
存儲編排
自動挂載所選存儲系統,包括本地存儲、諸如 GCP 或 AWS 之類公有雲提供商所提供的存儲或者諸如 NFS、iSCSI、Gluster、Ceph、Cinder 或 Flocker 這類網絡存儲系統。
密鑰和配置管理
部署和更新 Secrets 和應用程式的配置而不必重新建構容器鏡像,且 不必将軟體堆棧配置中的秘密資訊暴露出來。
自動裝箱
根據資源需求和其他限制自動放置容器,同時避免影響可用性。将關鍵性工作負載和盡力而為性質的服務工作負載進行混合放置,以提高資源使用率并節省更多資源。
批量執行
除了服務之外,Kubernetes 還可以管理你的批處理和 CI 工作負載,在期望時替換掉失效的容器。
IPv4/IPv6 雙協定棧
為 Pod 和 Service 配置設定 IPv4 和 IPv6 位址
水準擴縮
使用一個簡單的指令、一個 UI 或基于 CPU 使用情況自動對應用程式進行擴縮。
自我修複
重新啟動失敗的容器,在節點死亡時替換并重新排程容器,殺死不響應使用者定義的健康檢查的容器,并且在它們準備好服務之前不會将它們公布給用戶端。
為擴充性設計
無需更改上遊源碼即可擴充你的 Kubernetes 叢集
kubernetes使用
kubernetes中文文檔位址 https://kubernetes.io/zh/docs/home 目前最新版本為 v1.22 ,對于自己管理的叢集,官方支援的用于部署 Kubernetes 的工具是 kubeadm。
演進過程:傳統部署時代 - 虛拟化部署時代 - 容器部署時代
傳統部署時代:在實體伺服器上運作應用程式
虛拟化部署時代:虛拟化技術允許你在單個實體伺服器的 CPU 上運作多個虛拟機
容器部署時代:與 VM 類似,可以在應用程式之間共享作業系統,容器被認為是輕量級的,具有自己的檔案系統、CPU、記憶體、程序空間

控制平面元件(Control Plane Components)
kube-apiserver:提供了 Kubernetes API的統一入口,是 Kubernetes 控制面的前端,提供 HTTP API,以供使用者、叢集中的不同部分和叢集外部元件互相通信,可以查詢和操縱 Kubernetes API 中對象(例如:Pod、Namespace、ConfigMap 和 Event)的狀态,大部分操作都可以通過kubectl指令行接口或 類似kubeadm這類指令行工具來執行, 這些工具在背後也是調用 API,也可以使用 REST 調用來通路這些 API或者使用用戶端庫
etcd:兼具一緻性和高可用性的分布式鍵值資料庫,用于儲存 Kubernetes 所有叢集和狀态包括Pod、Deployment、Service等
kube-scheduler:負責監視新建立的、未指定運作節點和pod,計算和選擇 Pod 在哪些節點上運作,包括節點控制器、任務控制器、端點控制器等
kube-controller-manager:用于叢集監控、故障轉移等,執行叢集級别的功能,如複制元件、追蹤工作結點狀态、處理結點失敗等
可選元件
kube-dns:負責整個叢集内部dns解析服務,屬于非必要元件,可實作所有pod通過名稱通路
dashboard:儀表盤,是 Kubernetes 叢集的通用的、基于 Web 的使用者界面。 它使使用者可以管理叢集中運作的應用程式以及叢集本身并進行故障排除
cloud-controller-manager:嵌入特定雲的控制邏輯的控制平面元件
Node 元件(節點可以是一個虛拟機或者實體機器,節點元件在每個節點上運作,負責運作容器的軟體維護運作的 Pod )
kubelet:負責節點上運作Pod容器中,管理工作節點上的容器
kube-proxy:主節點代理,叢集中每個節點上運作的網絡代理,實作Kubernetes 的Service映射通路
容器運作時:提供 Kubernetes 運作環境實際運作容器的元件比如docker、containerd、CRI-O
網絡插件(兩個docker主控端之間通信需要具有實作CNI的插件)
部署基于 Pod 網絡插件的容器網絡接口(CNI),讓 Pod 可以互相通信,網絡插件包括Calico、Flannel、Cilium、Weave等,官方還提供其他網絡插件
Pod 是可以在 Kubernetes 中建立和管理的、最小的可部署的計算單元和排程機關,Pod可以包含是一個或者多個容器化應用、挂載和網絡。而一個節點Node隻要資源足夠是可以運作和管理很多很多的pod;Pod安裝在節點上,包含一組容器和卷。同一個Pod裡的容器共享同一個網絡命名空間,可以使用localhost互相通信
如果Pod是短暫的,那麼怎麼才能持久化容器資料使其能夠跨重新開機而存在? 是的,Kubernetes支援卷的概念,是以可以使用持久化的卷類型。
是否手動建立Pod,如果想要建立同一個容器的多份拷貝,需要一個個分别建立出來麼?可以手動建立單個Pod,但是也可以使用Replication Controller使用Pod模闆建立出多份拷貝。
Replication Controller確定任意時間都有指定數量的Pod“副本”在運作。如果為某個Pod建立了Replication Controller并且指定3個副本,它會建立3個Pod,并且持續監控它們。如果某個Pod不響應,那麼Replication Controller會替換它,保持總數為3。如果之前不響應的Pod恢複了,現在就有4個Pod了,那麼Replication Controller會将其中一個終止保持總數為3。如果在運作中将副本總數改為5,Replication Controller會立刻啟動2個新Pod,保證總數為5。還可以按照這樣的方式縮小Pod,這個特性在執行滾動更新時很有用。
當建立Replication Controller時,需要指定兩個東西:
Pod模闆:用來建立Pod副本的模闆
Label:Replication Controller需要監控的Pod的标簽
deployment是pod版本管理的工具,用來區分不同版本的pod,保證pod的數量和健康;從開發者角度看,deployment也即是部署意思,對于完整的應用部署流程,除了運作代碼(既pod)之外,需要考慮更新政策,副本數量,復原,重新開機等步驟
Service是一個邏輯的概念,是定義一系列Pod以及通路這些Pod的政策的一層抽象。Service通過Label找到Pod組;通常用于将一組相同pod應用有一個虛拟網絡IP進行管理,如果Pod是短暫的,那麼重新開機時IP位址可能會改變,那麼怎麼才能從前端容器正确可靠地指向背景容器呢?這時可以使用Service,Service還可以實作其一組pod内部的服務發現和負載均衡,通過每個Node上運作的代理(kube-proxy)完成。
部署Kubernetes叢集有多種方式,包括kind、minikube、kubeadm、二進制檔案、yum安裝、第三方工具、kops、kubespray、花錢購買
kind讓你能夠在本地計算機上運作 Kubernetes,一般用于學習使用
minikube與kind類似,運作一個單節點的 Kubernetes 叢集,也是用于學習使用
kubeadm該工具能夠執行必要的動作并用一種使用者友好的方式啟動一個可用的、安全的叢集。部署簡單,通過kubeadm init和kubeadm join兩個指令就可以建立叢集。也比較适合學習Kubernetes運維,現在也比較穩定可用于生産環境
二進制檔案:下載下傳二進制包,手動部署每個元件,比較繁瑣,但是能對Kubernetes各個元件有更清晰更深刻的認識
yum安裝:通過yum安裝每個元件,由于yum源有可能比較老,一般也較少使用
第三方工具,比如GitHub有些大神封裝的一些工具用于部署Kubernetes叢集
kops、kubespray
花錢購買:比如阿裡雲、騰訊雲共有雲k8s平台,一鍵搞定
伺服器最低配置要求: 2core 、2G、 50G,由于需要部署docker,是以如果是centos則要求7以上
所有伺服器的作業系統
主機名
IP
k8s-master2
192.168.50.36
k8s-node-1
192.168.50.34
k8s-node-2
192.168.50.35
網段劃分
名稱
IP網段
備注
service-cluster-ip
10.10.0.0/16
可用位址 65534
pods-ip
10.20.0.0/16
叢集dns
10.10.0.2
用于叢集service域名解析
k8s svc
10.10.0.1
叢集 kubernetes svc 解析ip
下面是所有的節點均需操作
檢視已安裝版本資訊
根據上面的提示資訊繼續操作
分别在兩台node節點192.168.50.34、192.168.50.35執行加k8s叢集的指令
接下來需要給k8s叢集添加CNI網絡插件,有很多方式,這裡先提供兩種
通過查找pod的詳細資訊發現問題
我們再來解決coredns的ImagePullBackOff的問題
常見幾個問題
GitHub上搜尋kubernetes二進制,選擇一個較新的進行部署
GitHub kubernetes叢集部署,下載下傳源碼檔案
伺服器規劃
k8s-master1
192.168.50.33
nginx-ingress-slb
服務版本
Docker CE version 20.10.8
Kubernetes Version 1.22.1
Etcd Version v3.5.0
叢集說明
所有主機使用 CentOS Linux release 7.9.2009 (Core) 版本,并且核心都升到5.x版本。
kube-proxy 使用 ipvs 模式(預留iptables模式)
Calico 使用 IPIP 模式
叢集域使用預設 svc.cluster.local
10.10.0.1 為叢集 kubernetes svc 解析ip
haproxy設定TCP監聽nginx-ingress的svc端口,實作ingress高可用
nginx-ingress後端擷取用戶端真實IP
初始化
關閉 firewalld
關閉 swap
關閉 Selinux
修改核心參數
預先設定 PATH
設定hostname
判斷核心并更新
安裝docker
證書生成
準備cfssl證書生成工具
自簽TLS證書,metrics-server 證書
部署Etcd叢集
從Github下載下傳Etcd二進制檔案和k8s相關元件,解壓k8s二進制包
拷貝master上的ssl證書到node
設定kubeconfig
依次啟動etcd
健康檢查
部署Master Node
部署kube-apiserver
部署kube-controller-manager
部署kube-scheduler
配置kubelet證書自動續期和建立Node授權使用者
準許kubelet證書申請并加入叢集
部署Worker Node
建立工作目錄并拷貝二進制檔案
部署kubelet
部署kube-proxy
先将k8s-normal-master.zip檔案上傳到master和node節點上并解壓,如果節點已安裝docker先執行解除安裝老版本
修改shell檔案夾下面的init.sh腳本檔案,按照下面修改兩處地方
至此,三台伺服器的docker安裝已安裝完畢
修改mktls.sh裡面hosts為我們部署節點host
修改etcd_install.sh腳本etcd版本為最新的v3.5.0
修改apiserver.sh中内容
去掉controller-manager.sh中内容--feature-gates=RotateKubeletClientCertificate=true \
準備admin證書配置 admin-csr.json,放在 admin目錄
使用根證書(ca.pem)簽發admin證書
暫時先到這裡,其他部署後續有時間我們再繼續,本篇我們主要還是學習指令和部署實戰
所有指令不清楚就是用--help這個萬能的神指令檢視,這裡采用deployment部署,當然也可以單獨建立pod,這種在實際場景會比較少用
上面有幾個Ip和端口需要了解下。k8s-node-1的ip是192.168.50.34,主控端上的端口為32173,是以我們可以通過http://192.168.50.34:32173 通路到這個pod暴露的服務
上面我們都是基于kubectl也即是指令方式直接建立deployment和pod、service,這種方式一般是簡單測試使用,接下來我們基于yaml檔案方式部署
編寫單獨建立pod的yaml檔案nginx-pod.yaml
編寫建立deploy的yaml檔案nginx-deploy.yaml,也可以直接通過下面指令生成一個deployment的yaml檔案
接下來我們看下service部分,也即是kubernetes的ingress來暴露應用,建立nginx-service.yaml檔案
有幾個重要端口我們一起來了解下
nodePort:這個是提供給叢集外部的叢集通路的,像這類配置為30080則可以提供給外部通路,比如這裡直接通路http://192.168.50.34:30080,service内部實作服務發現和負載均衡
targetPort:容器的端口,與制作容器鏡像時暴露端口一緻,和我們之前學習docker制作dockerfile檔案是一樣的,例如我們這裡的測試的nginx,docker.io官方鏡像暴露端口就是80
port:這個是kubernetes叢集内部各個服務之間互相通路的端口,比如我們mysql容器雖然暴露3306端口,沒有配置nodePort,外部無法直接通路容器,但叢集内部容器之間是可以通過通路mysql服務
我們可以進入任意一個容器進行測試,我們進入到kubernetes-bootcamp,然後通路nginx的pod服務
生成10.20網段的位址是容器内的位址,10.10網段是用于叢集内容通信的位址,也可以pod直接通路 ,比如我們這裡的http://10.10.11.146
可以通過nginx-service名稱通路到nginx的服務
通過節點通路https://192.168.50.34:30109/#/login 頁面
在我們上面下載下傳recommended.yaml檔案裡面就有subjects,表示建立了 kubernetes-dashbord 賬戶
将上面的token複制,點選登入即可
到此我們初步了解k8s及簡單指令,後續再學習k8s進階内容、例如configmap、secrets、有狀态應用、高可用k8s叢集、helm以及基于微服務叢集容器編排部署實戰等