05-K8S Basic-Pod資源管理(Pod網路、Labels)
阿新 • • 發佈:2021-06-13
一、Pod資源管理
1.1、什麼是pod
- 在一個pod中通常只能執行主容器,其他容器是為了輔助主容器的任何而設定。通常輔助容器稱之為邊車(side car)。
- 多個容器在同一pod中使用IPC pod相互通訊
- 一個pod中執行的多個容器可以通過localhost彼此找到
- 每個容器都繼承了pod的名稱
- 每個pod在平面共享網路空間中都有一個ip地址
- 在一個pod中,容器共享卷
1.2、k8s網路
- Node Network : 真正與外界網路通訊的介面
- Service Network : 進會出現在iptable或ipv4規則中,都不會被配置到網路介面中,因此沒有辦法ping,僅用於規則當中用於路徑和接受排程請求轉發給service請求流量
- Pod Network : 內部網路,pod地址也是被動態分配的網路地址,各個pod之間無論執行在哪個node節點上,pod之間可以直接通訊的,但是pod是動態的,隨之有可能被pod控制器所重建,也有可能被使用者誤刪除而重建節點,地址會發生變化,所以pod和pod之前通過ip地址通訊不是理想的狀態,應該藉助於service地址進行通訊。
- 當資源執行在k8s上,並響應使用者固定地址的請求時,必須將地址對映到service上,哪怕只有一個pod,service主要表現為iptables和ipvs規則,所以客戶端訪問這組資源時要先到service,service排程或反帶給後端pod,但是每一次請求都要經service進行動態轉發,這是沒辦法避免的資源消耗,必須有一個機制幫助我們實現服務註冊和服務發現機制,service就是幫助我們將服務註冊到k8s之上的服務匯流排,dns服務,動態註冊和更新的dns服務即CoreDNS
# 問題思考:執行一個pods,地址在10.244.0.0/16網路中,如何讓叢集外部進行訪問? 1、Service : NodePort型別的Service, 通過叢集中各個主機節點都開啟同一個埠,把使用者的請求對映給Pods,使其任何節點的這個埠都可以訪問到此Pods,埠是隨機的一般在30000~32767範圍。(kube-proxy生成對應的iptable及Lvs規則實現的,這些都是四層的排程,四層是不能解除安裝https協議的。)。 由於被對映到宿主機的埠是隨機的,所以不得不再在外面使用一個負載均衡器。如haproxy、nginx,將使用者的請求反代至每一個物理節點上的Service對映的隨機埠上,再到後端pods。 思考一個問題:我們怎麼知道Service對映到節點的埠是什麼呢?隨機的範圍30000~32767 因此,就得思考在k8s叢集之外的負載均衡器上按需建立,以觸發器觸發的方式按需檢測自動建立排程規則呢? 此時就得上雲端計算環境了,LBaaS負載均衡級服務,軟體的方式。自動檢測生成負載均衡的排程功能、排程規則,當檢測Service消亡時也會聯動被刪除,以實現使用者訪問的一直都是標準的埠。 2、hostPort : Pods一定是執行在叢集中的某一個節點上的,所以,Pods執行在哪個節點上,就使用哪個節點的埠訪問,其它未執行Pods的節點不可以訪問,即單一埠對映。 3、hostNetwork : pod資源的地址就時node節點的地址即監聽宿主機的名稱空間,Pods直接使用節點的網路,僅通過此執行Pods的節點進行訪問其Pods監聽的埠,其它未執行Pods的節點不可以訪問。
Service → NodePort
二、標籤Label
2.1、標籤介紹
-
需求:Pods是動態的,必要時都會將Pod進行重建,所以我們引入了Service來固定接入使用者的請求,同時又使用Pod Controller以便在Pod出現故障時得以重建,所以需求就是Service、Pod Controller是如何識別、過濾哪些Pod是當前Service、Pod Controller所管理的Pod,所以就引入了 Label標籤、Label Selector標籤選擇器。
-
補充:同一資源型別下,不允許同一資源進行同名。如果想在k8s上跑一臺測試的LNMP及生產的LNMP就需要執行在不同的名稱空間下,Pod是名稱空間級別的資源,所以可以將同名稱的Pod建立在不同的NameSpace下。
-
標籤就是“鍵值”型別的物件,它們可用於資源建立時直接指定,也可以隨時按需新增活動物件,而後即可由標籤選擇器進行匹配度檢查從而完成資源挑選。
- 一個物件可擁有不止一個標籤,而同一個標籤也可被新增至多個資源上
- 實踐中,可以為資源附加多個不同維度的標籤以實現靈活的資源分組管理功能
- 例如版本標籤、環境標籤、分層標籤等,用於交叉標識同一資源所屬的不同版本,環境及架構層級等
- 標籤中的鍵值名稱通常由字首和鍵名組成,其中鍵字首可選,其格式如“KEY_PREFIX/KEY_NAME”
- 鍵名至多使用63個字元,可使用字母、數字、連線號(-),下劃線(_),點號(.)等字元,且只能以字母或數字開頭
- 鍵字首必須為DNS子域名格式,且不能超過253個字元。省略鍵字首時,鍵將被視為使用者的私有資源,不過k8s系統元件或第三方元件會自動為使用者資源新增的鍵必須使用鍵字首,而“kubernetes.io/”字首於kubernetes的核心元件使用
- 標籤中的鍵值必須不能多餘63個字元,它要麼為空,要麼是以字母或數字開頭及結尾,且中間僅使用了字母、數字、連線號(-)、下劃線(_)、或點好(.)、等字元的資料
2.2、標籤示圖
三、標籤選擇器(Label Selector)
3.1、標籤選擇器介紹
- 標籤選擇器用於表示式標籤的查詢條件或選擇標準,kubernetesAPI目前支援兩種選擇器
- 基於等值關係(equuality-based)
- 操作符有=、==、!=三種,其中前兩個意義相同,都表示"等值"關係,最後一個表示”不等“關係
- 基於集合關係(set-based)
- KEY in (value1,value2)
- KEY not in (VALUE1,VALUE2,...)
- KEY : 所有存在鍵名標籤的資源
- !KEY : 所有不存在此鍵名標籤的資源
- 基於等值關係(equuality-based)
- 使用標籤選擇器時還將遵循以下邏輯
- 同時指定的多個選擇器之間的邏輯關係為 ”與“ 操作
- 使用空值的標籤選擇器意味著每個資源物件都將被選中
- 空的標籤選擇器將無法選出任何資源
3.2、定義標籤選擇器的方式
- kubernetes的諸多資源物件必須以標籤選擇器的方式關聯到pod資源物件,例如Service、Deployment和ReplicaSet型別的資源等,它們在apec欄位中巢狀使用巢狀"selector"欄位,通過“matchlables” 來指定標籤選擇器,有的甚至還支援使用“matchExperssions” 構造父愛的標籤選擇機制。
matchLables
: 通過直接給定鍵值對指定標籤選擇器matchxperssions
: 基本表示式指定的標籤選擇器列表,每個選擇器形如 “key:KEY_NAME, operator:OPERATOR, values: [VALUE1, BALUE2,.....]” 選擇器列表間為“邏輯與”關係- 使用in 或 Not in 操作符時,其values非必須為飛控字串列表,而使用Exists 或 DoseNotExist時,其value必須為空
四、簡單的標籤及標籤選擇器使用
4.1、宣告式apply常見pod指定pod的標籤
1、檢視已執行的pod的標籤資訊
~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
app="對應的控制器名稱" pod-template-hash(pod模組的hash值)= pod模板的雜湊指紋資訊
myapp-5c6976696c-8kpqh 1/1 Running 0 45h app=myapp,pod-template-hash=5c6976696c
myapp-5c6976696c-sxt79 1/1 Running 0 45h app=myapp,pod-template-hash=5c6976696c
nginx-dep-b4c55647f-nf7pt 1/1 Running 0 47h app=nginx-dep,pod-template-hash=b4c55647f
nginx-deplo-57c48cb848-ppgnf 1/1 Running 0 2d app=nginx-deplo,pod-template-hash=57c48cb848
nginx-deplo1-69dbc7b5bc-dzr5s 1/1 Running 0 47h app=nginx-deplo1,pod-template-hash=69dbc7b5bc
nginx-deploy-66ff98548d-gjnn8 1/1 Running 0 2d3h pod-template-hash=66ff98548d,run=nginx-deploy
ngx-dep-d554574bd-mg7jg 1/1 Running 0 46h app=ngx-dep,pod-template-hash=d554574bd
# 檢視之前再prod名稱空間下建立的pod資源標籤
basic]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 1 26h <none>
2、定義一個YAML pod資源配置並將其定義標籤
~]# cat mainfests/basic/pod-demo-2.yaml
#pod所屬的群組
apiVersion: v1
#資源型別為pod
kind: Pod
#元資料
metadata:
#pod名稱
name: pod-demo
#pod所屬的名稱空間,如果不指定可在apply時使用-n選項
namespace: prod
#定義pod的標籤
labels:
app: pod-demo
rel: stable
#定義pod的屬性
spec:
#容器
containers:
#第一個容器的名稱
- name: myapp
#這個容器使用的映象檔案
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
#第二個容器的名稱
- name: bbox
image: busybox:latest
imagePullPolicy: IfNotPresent
#定義這個容器啟動執行的命令
command: ["/bin/sh","-c","sleep 86400"]
3、刪除指定名稱空間下的pod
~]# kubectl get pods -n prod
NAME READY STATUS RESTARTS AGE
pod-demo 2/2 Running 0 16h
~]# kubectl delete pods -n prod pod-demo
pod "pod-demo" deleted
4、使用宣告式apply指定資原始檔建立pod
basic]# kubectl apply -f pod-demo-2.yaml
pod/pod-demo created
5、檢視建立pod的標籤
basic]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 88s app=pod-demo,rel=stable
4.2、kubctl label專門管理標籤以及指定標籤顯示
1、檢視kubectl label 命令的幫助文件
~]# kubectl label -h
Usage: #向哪個資源上打什麼標籤
kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
Examples:
# Update pod 'foo' with the label 'unhealthy' and the value 'true'.
kubectl label pods foo unhealthy=true
# Update pod 'foo' with the label 'status' and the value 'unhealthy', overwriting any existing value.
kubectl label --overwrite pods foo status=unhealthy
# Update all pods in the namespace
kubectl label pods --all status=unhealthy
# Update a pod identified by the type and name in "pod.json"
kubectl label -f pod.json status=unhealthy
# Update pod 'foo' only if the resource is unchanged from version 1.
kubectl label pods foo status=unhealthy --resource-version=1
# Update pod 'foo' by removing a label named 'bar' if it exists.
# Does not require the --overwrite flag.
kubectl label pods foo bar-
2、將之前建立的pod資源上新增標籤
~]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 6m57s app=pod-demo,rel=stable
~]# kubectl label pods pod-demo -n prod tier=frontend
pod/pod-demo labeled
~]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 8m9s app=pod-demo,rel=stable,tier=frontend
3、在已經有的標籤key上直接打標籤會報錯
~]# kubectl label pods pod-demo -n prod app=frontend
error: 'app' already has a value (pod-demo), and --overwrite is false
4、覆蓋之前已有的標籤(必須使用--overwrite=true即允許覆蓋之前已經存在的標籤)
~]# kubectl label pods pod-demo -n prod --overwrite=true app=myapp
pod/pod-demo labeled
~]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 10m app=myapp,rel=stable,tier=frontend
5、刪除已有的表標籤
~]# kubectl label pods pod-demo -n prod rel- #使用標籤key + -號意思為刪除此標籤
pod/pod-demo labeled
~]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 11m app=myapp,tier=frontend
6、kubectl get 選項指定根據標籤顯示資源
-L : 只顯示這個資源上指定的標籤
-l : 選擇器可是使用等值或不等值選擇式的標籤 '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
#等值的標籤選擇器
~]# kubectl get pods --show-labels -l app=myapp
NAME READY STATUS RESTARTS AGE LABELS
myapp-5c6976696c-8kpqh 1/1 Running 0 46h app=myapp,pod-template-hash=5c6976696c
myapp-5c6976696c-sxt79 1/1 Running 0 46h app=myapp,pod-template-hash=5c6976696c
#不等值選擇器
~]# kubectl get pods --show-labels -l app!=myapp
NAME READY STATUS RESTARTS AGE LABELS
nginx-dep-b4c55647f-nf7pt 1/1 Running 0 2d1h app=nginx-dep,pod-template-hash=b4c55647f
nginx-deplo-57c48cb848-ppgnf 1/1 Running 0 2d1h app=nginx-deplo,pod-template-hash=57c48cb848
nginx-deplo1-69dbc7b5bc-dzr5s 1/1 Running 0 2d1h app=nginx-deplo1,pod-template-hash=69dbc7b5bc
nginx-deploy-66ff98548d-gjnn8 1/1 Running 0 2d4h pod-template-hash=66ff98548d,run=nginx-deploy
ngx-dep-d554574bd-mg7jg 1/1 Running 0 47h app=ngx-dep,pod-template-hash=d554574bd
#列表選擇器
~]# kubectl get pods --show-labels -l "app in (myapp,ngx-dep)"
NAME READY STATUS RESTARTS AGE LABELS
myapp-5c6976696c-8kpqh 1/1 Running 0 47h app=myapp,pod-template-hash=5c6976696c
myapp-5c6976696c-sxt79 1/1 Running 0 47h app=myapp,pod-template-hash=5c6976696c
ngx-dep-d554574bd-mg7jg 1/1 Running 0 47h app=ngx-dep,pod-template-hash=d554574bd
~]# kubectl get pods -l "app in (myapp,ngx-dep)" -L app
NAME READY STATUS RESTARTS AGE APP
myapp-5c6976696c-8kpqh 1/1 Running 0 47h myapp
myapp-5c6976696c-sxt79 1/1 Running 0 47h myapp
ngx-dep-d554574bd-mg7jg 1/1 Running 0 47h ngx-dep
~]# kubectl get pods -l "app notin (myapp,ngx-dep)" -L app
NAME READY STATUS RESTARTS AGE APP
nginx-dep-b4c55647f-nf7pt 1/1 Running 0 2d1h nginx-dep
nginx-deplo-57c48cb848-ppgnf 1/1 Running 0 2d1h nginx-deplo
~]# kubectl get pods -l "app" -L app
~]# kubectl get pods -l '!app' -L app
五、資源註解(annotation)
5.1、資源註解介紹
- 註解也是"鍵值"型別的資料,不過它不能用於標籤及挑選kubernetes物件,僅用於為資源提供”元資料資訊“
- 註解中的元資料不受字元數量的限制,它可大可小,可以為結構化或非結構化形式,也支援使用標籤中禁止使用的其他字元
- 在kubernetes的新版中(Alpha或Beta階段)為某資源引入新欄位時,常以註解方式以避免其增刪等變動給使用者帶去的困擾,一旦確定支援使用它們,這些新增欄位再引入到資源中淘汰相關的註解
5.2、kubectl annotate管理資源的註解
1、檢視命令的幫助
basic]# kubectl explain pods.metadata.annotations
~]# kubectl annotate -h
Usage:
kubectl annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
3、將之前建立的pod資源上新增資源註解
~]# kubectl get pods -n prod
~]# kubectl delete -f mainfests/basic/pod-demo-2.yaml
pod "pod-demo" deleted
4、重新構建資源並指定資源註解
basic]# cat pod-demo-2.yaml
#pod所屬的群組
apiVersion: v1
#資源型別為pod
kind: Pod
#元資料
metadata:
#pod名稱
name: pod-demo
#pod所屬的名稱空間,如果不指定可在apply時使用-n選項
namespace: prod
#定義pod的標籤
labels:
app: pod-demo
rel: stable
#定義資源註解
annotations:
zhe.dai/project: hellow world
#定義pod的屬性
spec:
#容器
containers:
#第一個容器的名稱
- name: myapp
#這個容器使用的映象檔案
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
#第二個容器的名稱
- name: bbox
image: busybox:latest
imagePullPolicy: IfNotPresent
#定義這個容器啟動執行的命令
command: ["/bin/sh","-c","sleep 86400"]
5、建立pod
basic]# kubectl apply -f pod-demo-2.yaml
pod/pod-demo created
6、檢視pod的資源註解資訊
basic]# kubectl describe pods pod-demo -n prod
Name: pod-demo
Namespace: prod
Priority: 0
Node: 192.168.1.185/192.168.1.185
Start Time: Wed, 19 Feb 2020 17:14:38 +0800
Labels: app=pod-demo
rel=stable
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"zhe.dai/project":"hellow world"},"labels":{"app":"pod-demo","rel":"stable"},"n...
zhe.dai/project: hellow world
Status: Running
IP: 192.168.1.221
# 理解 : 為什麼當使用宣告時apply方式建立資源後,對其yaml檔案繼續修改後,還會重新讀取新的配置,其實本質上是將配置資訊存放在引數註解中,當yaml更新時就會做一個對比,當發生改變時重新apply一次,類似於補丁機制。