關于 Kubernetes中一些基本概念和術語筆記(一)
寫在前面
學習K8s,所以整理記憶
一個不欣賞自己的人,是難以快樂的。-------三毛
一、簡述
Kubernetes中的大部分概念如Node, Pod,Replication Controller, Service等都可以看作一種“資源對象”,幾乎所有的資源對象都可以通過Kubernetes提供的kubect工具(或者API編程調用)執(zhí)行增、刪、改、查等操作并將其保存在etcd中持久化存儲。從這個角度來看,Kubernetes其實是一個高度自動化的資源控制系統(tǒng),它通過`跟蹤對比etcd庫里保存的“資源期望狀態(tài)”與當前環(huán)境中的“實際資源狀態(tài)”的差異來實現自動控制和自動糾錯的高級功能。
K8s中相關資源:隨版本變化
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create] └─$kubectl api-resources
二、Kubernetes集群的兩種管理角色: Master和Node
1、Master角色
Kubernetes里的Master指的是 集群控制節(jié)點,
每個Kubernetes集群里需要有一個Master節(jié)點來負責整個集群的管理和控制,基本上Kubernetes的所有控制命令都發(fā)給它,它來負責具體的執(zhí)行過程,我們后面執(zhí)行的所有命令基本都是在Master節(jié)點上運行的。
Master節(jié)點通常會占據一個獨立的服務器(高可用部署建議用3臺服務器),其主要原因是它太重要了,是整個集群的“首腦”,如果宕機或者不可用,那么對集群內容器應用的管理都將失效。Master節(jié)點上運行著以下一組關鍵進程。
除了Master,
Kubernetes集群中的其他機器被稱為Node節(jié)點
2、Node角色
在較早的版本中也被稱為Miniono與Master一樣, Node節(jié)點可以是一臺物理主機,也可以是一臺虛擬機。
Node節(jié)點才是Kubermetes集群中的工作負載節(jié)點,每個Node都會被Master分配一些工作負載(Docker容器),當某個Node宕機時,其上的工作負載會被Master自動轉移到其他節(jié)點上去。
每個Node節(jié)點上都運行著以下一組關鍵進程。
Node節(jié)點可以在運行期間動態(tài)增加到Kubernetes集群中,前提是這個節(jié)點上已經正確安裝、配置和啟動了上述關鍵進程,
在默認情況下kubelet會向Master注冊自己,這也是Kubernetes推薦的Node管理方式
。
一旦Node被納入集群管理范圍, kubelet進程就會定時向Master節(jié)點匯報自身的情報,例如操作系統(tǒng)、Docker版本、機器的CPU和內存情況,以及當前有哪些Pod在運行等,這樣Master可以獲知每個Node的資源使用情況,并實現高效均衡的資源調度策略。而某個Node超過指定時間不上報信息時,會被Master判定為“失聯", Node的狀態(tài)被標記為不可用(Not Ready),隨后Master會觸發(fā)“工作負載大轉移”的自動流程。
┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl get nodes NAME STATUS ROLES AGE VERSION vms81.liruilongs.github.io Ready control-plane,master 47d v1.22.2 vms82.liruilongs.github.io Ready worker1 47d v1.22.2 vms83.liruilongs.github.io NotReady worker2 47d v1.22.2
┌──[root@vms81.liruilongs.github.io]-[~] └─$kubectl describe node vms82.liruilongs.github.io # Node基本信息:名稱、標簽、創(chuàng)建時間等。 Name: vms82.liruilongs.github.io Roles: worker1 Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux disktype=node1 kubernetes.io/arch=amd64 kubernetes.io/hostname=vms82.liruilongs.github.io kubernetes.io/os=linux node-role.kubernetes.io/worker1= Annotations: dest: 這是一個工作節(jié)點 kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock node.alpha.kubernetes.io/ttl: 0 projectcalico.org/IPv4Address: 192.168.26.82/24 projectcalico.org/IPv4IPIPTunnelAddr: 10.244.171.128 volumes.kubernetes.io/controller-managed-attach-detach: true CreationTimestamp: Thu, 07 Oct 2021 01:15:45 +0800 Taints:
總結一下,我們要操作k8s,在管理節(jié)點那我們怎么操作,我們通過kube-apiserver來接受用戶的請求,通過kubu-scheduler來負責資源的調度,是使用work1計算節(jié)點來處理還是使用work2計算節(jié)點來處理,然后在每個節(jié)點上要運行一個代理服務kubelet,用來控制每個節(jié)點的操作,但是每個節(jié)點的狀態(tài),是否健康我們不知道,這里我們需要kube-controller-manager
3、 Pod資源對象
Pod是Kubernetes的最重要也最基本的概念,
每個Pod都有一個特殊的被稱為“根容器”的Pause容器。Pause容器對應的鏡像屬于Kubernetes平臺的一部分,除了Pause容器,每個Pod還包含一個或多個緊密相關的用戶業(yè)務容器。
Kubernetes 為每個Pod都分配了唯一的IP地址,稱之為Pod IP,一個Pod里的多個容器共享Pod IP地址。 Kuberetes要求底層網絡支持集群內任意兩個Pod之間的TCP/P直接通信,這通常采用虛擬二層網絡技術來實現(鏈路層網橋),
在Kubernetes里,一個Pod里的容器與另外主機上的Pod容器能夠直接通信。
Pod其實有兩種類型:普通的Pod及靜態(tài)Pod (Static Pod),如果使用kubeadm的方式部署,靜態(tài)pod在node節(jié)點和master節(jié)點創(chuàng)建略有不同
正常情況下,pod是在master上統(tǒng)一管理的,所謂靜態(tài)pod就是,即不是由master上創(chuàng)建調度的,是屬于node自身特的pod,在node上只要啟動kubelet之后,就會自動的創(chuàng)建的pod。這里理解的話,結合java靜態(tài)熟悉,靜態(tài)方法理解,即的node節(jié)點初始化的時候需要創(chuàng)建的一些pod
比如 kubeadm的安裝k8s的話,所以的服務都是通過容器的方式運行的。相比較二進制的方式方便很多,這里的話,那么涉及到master節(jié)點的相關組件在沒有k8s環(huán)境時是如何運行,構建master節(jié)點的,這里就涉及到靜態(tài)pod的問題。
在默認情況下,當Pod里的某個容器停止時,Kubernetes會自動檢測到這個問題并且重新啟動這個Pod(重啟Pod里的所有容器),如果Pod所在的Node宕機,則會將這個Node上的所有Pod重新調度到其他節(jié)點上.
Kubernetes里的所有資源對象都可以采用yaml或者JSON格式的文件來定義或描述,下面是我們在之前Hello World例子里用到的myweb這個Pod的資源定義文件:
apiVersion: v1 kind: Pod # Pod 定義 metadata: name: myweb # Pod 名字 lables: name: myweb spec: # 包含的容器組 containers: - name: myweb image: kubeguide/tomcat-app:v1 ports: - containerPort: 8080 env: - name: MYSQL_SERVICE_HOST value: 'mysql' - name: MYSQL_SERVICE_PORT value: '3306'
Kubernetes的Event概念, Event是一個事件的記錄,記錄了事件的最早產生時間、最后重現時間、重復次數、發(fā)起者、類型,以及導致此事件的原因等眾多信息。Event通常會關聯到某個具體的資源對象上,是排查故障的重要參考信息,
Pod同樣有Event記錄,當我們發(fā)現某個Pod遲遲無法創(chuàng)建時,可以用kubectl describe pod xxxx來查看它的描述信息,用來定位問題的原因
在Kubernetes里,一個計算資源進行配額限定需要設定以下兩個參數。
通常我們會把Request設置為一個比較小的數值,符合容器平時的工作負載情況下的資源需求,而把Limit設置為峰值負載情況下資源占用的最大量。
比如下面這段定義,表明MysQL容器申請最少0.25個CPU及64MiB內存,在運行過程中MySQL容器所能使用的資源配額為0.5個CPU及128MiB內存:
.... resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" ...
Pod Pod 周邊對象的示意圖
4 、Lable 標簽
Label是Kubernetes系統(tǒng)中另外一個核心概念。一個Label是一個key-value的鍵值對。其中key與value由用戶自己指定。
Label可以附加到各種資源對象上,例如Node、Pod、Service、RC等,
一個資源對象可以定義任意數量的Label,同一個Label也可以被添加到任意數量的資源對象上去, Label通常在資源對象定義時確定,也可以在對象創(chuàng)建后動態(tài)添加,或者刪除。
可以通過給指定的資源對象捆綁一個或多個不同的Label來實現多維度的資源分組管理功能,以便于靈活、方便地進行資源分配、調度、配置、部署等管理工作。
例如:部署不同版本的應用到不同的環(huán)境中;或者監(jiān)控和分析應用(日志記錄、監(jiān)控、告警)等。一些常用的Label示例如下。
版本標簽: "release" : "stable", "release":"canary".... 環(huán)境標簽: "environment":"dev", "environment":"ga","environment":"production"· 架構標簽: "ier":"frontend," "tier":"backend", "tier":"midleware" 分區(qū)標簽: "artition":"customerA", "partition": "customerB". 質量管控標簽: "track": "daily","track":"weeky"
可以通過多個Label Selector表達式的組合實現復雜的條件選擇,多個表達式之間用“,”進行分隔即可,幾個條件之間是“AND"的關系,即同時滿足多個條件,比如下面的例子:
name=標簽名 env != 標簽名 name in (標簽1,標簽2) name not in(標簽1) name in (redis-master, redis-slave):匹配所有具有標簽`name=redis-master`或者`name=redis-slave`的資源對象。 name not in (phn-frontend):匹配所有不具有標簽name=php-frontend的資源對象。 name=redis-slave, env!=production name notin (php-frontend),env!=production
apiVersion: v1 kind: Pod metadata: name: myweb lables: app: myweb # 管理對象RC和Service 在 spec 中定義Selector 與 Pod 進行關聯。 apiVersion: v1 kind: ReplicationController metadata: name: myweb spec: replicas: 1 selector: app: myweb template: ...略... apiVersion" v1 kind: Service metadata: name: myweb spec: selector: app: myweb ports: port: 8080
新出現的管理對象如Deployment, ReplicaSet, DaemonSet和Job則可以在Selector中使用基于集合的篩選條件定義,例如:
selector: matchLabels: app: myweb matchExpressions: - {key: tire,operator: In,values: [frontend]} - {key: environment, operator: NotIn, values: [dev]}
matchLabels用于定義一組Label,與直接寫在Selector中作用相同; matchExpressions用于定義一組基于集合的篩選條件,可用的條件運算符包括: In, NotIn, Exists和DoesNotExist.
如果同時設置了matchLabels和matchExpressions,則兩組條件為"AND"關系,即所有條件需要同時滿足才能完成Selector的篩選。
Label Selector在Kubernetes中的重要使用場景有以下幾處:
kube-controller進程通過資源對象RC上定義的Label Selector來篩選要監(jiān)控的Pod副本的數量,從而實現Pod副本的數量始終符合預期設定的全自動控制流程
kube-proxy進程通過Service的Label Selector來選擇對應的Pod, 自動建立起每個Service到對應Pod的請求轉發(fā)路由表,從而實現Service的智能負載均衡機制
通過對某些Node定義特定的Label,并且在Pod定義文件中使用NodeSelector這種標簽調度策略, kube-scheduler進程可以實現Pod “定向調度”的特性。
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podnodea name: podnodea spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: podnodea resources: {} affinity: nodeAffinity: #主機親和性 requiredDuringSchedulingIgnoredDuringExecution: #硬策略 nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - vms85.liruilongs.github.io - vms84.liruilongs.github.io dnsPolicy: ClusterFirst restartPolicy: Always status: {}
5、 Replication Controller
RC是Kubernetes系統(tǒng)中的核心概念之一,簡單來說,它其實是定義了一個期望的場景,即聲明某種Pod的副本數量在任意時刻都符合某個預期值,所以RC的定義包括如下幾個部分。
下面是一個完整的RC定義的例子,即確保擁有tier-frontend標簽的這個Pod (運行Tomcat容器)在整個Kubernetes集群中始終
只有一個副本:
apiVersion: v1 kind: ReplicationController metadata: name: frontend spec: replicas: 1 selector: tier: frontend template: metadata: labels: app: app-demo tier: frontend spec: containers: - name: tomcat-demo image: tomcat imagePullPolicy: IfNotPresent env: - name: GET_HOSTS_FROM value: dns ports: - containerPort: 80
當我們定義了一個RC并提交到Kubernetes集群中以后, Master節(jié)點上的Controller Manager組件就得到通知,定期巡檢系統(tǒng)中當前存活的目標Pod,并確保目標Pod實例的數量剛好等于此RC的期望值,如果有過多的Pod副本在運行,系統(tǒng)就會停掉一些Pod,否則系統(tǒng)就會再自動創(chuàng)建一些Pod
通過RC, Kubernetes實現了用戶應用集群的高可用性,并且大大減少了系統(tǒng)管理員在傳統(tǒng)IT環(huán)境中需要完成的許多手工運維工作(如主機監(jiān)控腳本、應用監(jiān)控腳本、故障恢復腳本等
)
下面我們以3個Node節(jié)點的集群為例,說明Kubernetes如何通過RC來實現Pod副本數量自動控制的機制。假如我們的RC里定義redis-slave這個Pod需要保持3個副本,系統(tǒng)將可能在其中的兩個Node上創(chuàng)建Pod。
在運行時,我們可以通過
修改RC的副本數量,來實現Pod的動態(tài)縮放(Scaling)功能
,這可以通過執(zhí)行kubectl scale命令來一鍵完成:
kubectl scale rc redsi-slave --replicas=3
需要注意的是
,
刪除RC并不會影響通過該RC已創(chuàng)建好的Pod,為了刪除所有Pod,可以設置replicas的值為0,然后更新該RC。另外, kubectl提供了stop和delete命令來一次性刪除RC和RC控制的全部Pod。
應用升級時
,通常會通過Build一個新的Docker鏡像,并用新的鏡像版本來替代舊的版本的方式達到目的。在系統(tǒng)升級的過程中,我們希望是平滑的方式,比如當前系統(tǒng)中10個對應的舊版本的Pod,最佳的方式是舊版本的Pod每次停止一個,同時創(chuàng)建一個新版本的Pod,在整個升級過程中,此消彼長,而運行中的Pod數量始終是10個,通過RC的機制, Kubernetes很容易就實現了這種高級實用的特性,
被稱為“滾動升級” (Rolling Update)
6、 Deployment
Deployment是Kubernetes v1.2引入的新概念,引入的目的是為了更好地解決Pod的編排問題。
Deployment相對于RC的一個最大升級是我們可以隨時知道當前Pod “部署”的進度
。實際上由于一個Pod的創(chuàng)建、調度、綁定節(jié)點及在目標Node上啟動對應的容器這一完整過程需要一定的時間,所以我們期待系統(tǒng)啟動N個Pod副本的目標狀態(tài),實際上是一個連續(xù)變化的“部署過程"導致的最終狀態(tài)。
Deployment的典型使用場景有以下幾個。
Deployment的定義與Replica Set的定義很類似,除了API聲明與Kind類型等有所區(qū)別:
apiversion: extensions/vlbetal apiversion: v1 kind: Deployment kind: ReplicaSet metadata: metadata: name: nginx-deployment name: nginx-repset
創(chuàng)建一個 tomcat-deployment.yaml Deployment 描述文件:
apiVersion: extensions/v1betal kind: Deployment metadata: name: frontend spec: replicas: 1 selector: matchLabels: tier: frontend matchExpressions: - {key: tier, operator: In,value: [frontend]} template: metadata: labels: app: app-demo tier: frontend spec: containers: - name: tomcat-demo images: tomcat imagePullPolicy: IfNotPresent ports: - containerPort: 8080
運行如下命令創(chuàng)建 Deployment:
kubectl create -f tomcat-deploment.yaml
對上述輸出中涉及的數量解釋如下。
運行下述命令查看對應的Replica Set,我們看到它的命名與Deployment的名字有關系:
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$kubectl get rs -A NAMESPACE NAME DESIRED CURRENT READY AGE kube-system calico-kube-controllers-78d6f96c7b 1 1 1 47d kube-system coredns-545d6fc579 0 0 0 47d kube-system coredns-7f6cbbb7b8 2 2 2 36d kube-system kuboard-78dccb7d9f 1 1 1 11d kube-system metrics-server-bcfb98c76
Kubernetes
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。