對象管理
本節(jié)介紹對象的相關(guān)概念和管理機制。只有了解了這些機制,我們才能輕松的對k8s資源進行編排。
1 對象 Object
k8s對象
即是對應(yīng)用程序、工作負載、存儲、網(wǎng)絡(luò)等資源的抽象表示,如image、pod、node、volume、service
等。集群中每個對象都有一個名稱
來標(biāo)識其在同類資源中
的唯一性
,同時擁有一個UID
來標(biāo)識其在整個集群中
的唯一性
。
由于許多資源類型需要用作DNS子域名的名稱,所以,對象命名需遵守RFC 1035定義的DNS標(biāo)簽標(biāo)準(zhǔn)。
對象命名規(guī)范
- 最多 63 個字符。
- 只能包含
小寫
字母、數(shù)字
、‘-
’。有些資源名稱也可以使用'
.'
- 必須以
字母
開頭。- 必須以
字母
、數(shù)字
結(jié)尾。
2 命名空間 namespace
通過命名空間,將資源分組,分組間相互隔離。
同一命名空間
中的資源名稱
需要唯一
。k8s會為所有命名空間
設(shè)置一個不可變的標(biāo)簽kubernetes.io/metadata.name: "<namespace_name>"
,標(biāo)簽值是命名空間
的名稱,可使用標(biāo)簽運算符
快速定位到命名空間<namespace_name>
。
絕大多數(shù)的k8s對象都屬于某一命名空間,但是也有一些資源(如:命名空間本身,節(jié)點,持久化卷
)不屬于任何命名空間。
2.1 查看命名空間中的資源
# 查看 位于命名空間中的資源
kubectl api-resources --namespaced=true
# 查看 不在命名空間中的資源
kubectl api-resources --namespaced=false
2.2 創(chuàng)建命名空間
# Source: /myworkdir/myns.yaml
apiVersion: v1
kind: NameSpace
metadata:
name: myns
# 通過資源描述文件創(chuàng)建命名空間
kubectl create -f /myworkdir/myns.yaml
# 通過命令創(chuàng)建命名空間
kubectl create namespace myns
# 查看/刪除命名空間
kubectl get ns
kubectl delete namespace myns
2.3 設(shè)置當(dāng)前默認的命名空間
kubectl config set-context --current --namespace=<名字空間名稱>
# 驗證
kubectl config view --minify | grep namespace:
2.4 DNS解析
當(dāng)創(chuàng)建一個Service時,k8s會創(chuàng)建一條DNS記錄,格式為
<服務(wù)名稱>.<名字空間名稱>.svc.cluster.local
。
- 如果容器只使用
<服務(wù)名稱>
訪問Service,它會被解析到本地命名空間
中的Service。- 如果你想跨
命名空間
訪問Service,則需要使用完全限定域名
(FQDN)。命名空間
名稱必須滿足RFC 1123 DNS名稱規(guī)范。
3 標(biāo)簽 labels
標(biāo)簽
labels
,顧名思義就是給k8s對象做個標(biāo)記,它是附加到k8s對象(如pod
)上的鍵值對
,用來標(biāo)識對象屬性。標(biāo)簽可以在創(chuàng)建時附加到對象上,也可以在創(chuàng)建后隨時添加和修改。k8s中的對象標(biāo)簽
與名稱
和UID
不同,不具有唯一性,主要用來分組和篩選。
3.1 標(biāo)簽鍵:
由前綴
+名稱
兩段組成,用斜杠/
分割,前綴是可選的,名稱是必需的。如kubernetes.io/master
。
前綴段
的使用規(guī)范:
- 如果指定前綴,則必須是DNS子域,由’
.
'和一系列DNS標(biāo)簽組成,最多253個字符。前綴kubernetes.io/
和k8s.io/
是為k8s核心組件保留的。- 如果省略前綴,則認為標(biāo)簽鍵是用戶私有的。
名稱段
的命名規(guī)范:
- 最多 63 個字符。
- 只能包含字母、
數(shù)字
,破折號’-
‘、下劃線’_
‘、點’.
'。- 以字母數(shù)字字符([a-z0-9A-Z])開頭和結(jié)尾。
3.2 標(biāo)簽值:
- 可以為空。最多 63 個字符。
- 以字母數(shù)字字符([a-z0-9A-Z])開頭和結(jié)尾。
- 只能包含字母、
數(shù)字
,破折號’-
‘、下劃線’_
‘、點’.
'。
3.3 標(biāo)簽語法
# json格式
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
# yaml格式
metadata:
labels:
key1: value1
key2: value2
3.4 示例:
apiVersion: v1
kind: Pod # 資源類型
metadata:
name: label-demo # 定義資源名稱,在同類資源中唯一。
labels:
environment: production # 定義私有標(biāo)簽environment:production
app: nginx # 定義私有標(biāo)簽app:nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2 # 引用鏡像版本。
ports:
- containerPort: 80
4 標(biāo)簽選擇器 selector
一般我們會給
一批資源對象
打上相同的標(biāo)簽,然后通過標(biāo)簽選擇器
進行匹配,選擇滿足匹配條件
的一組資源對象。標(biāo)簽選擇器
的匹配方式可分為基于等值
和基于集合
兩種方式。這兩種方式既可以在REST客戶端 kubeclt
中使用,也可以在k8s對象
中引用。
4.1 在REST客戶端 kubeclt
中使用
# 基于等值:支持'='、'=='和'!='
kubectl get pods -l environment=production,tier=frontend # 查找標(biāo)簽為environment=production,tier=frontend的pod。
kubectl get pods -l environment!=production,tier==frontend
# 基于集合:支持'in' 'notin'
kubectl get pods -l 'environment in (production),tier in (frontend)'
kubectl get pods -l 'environment in (production, qa)' # 查看標(biāo)簽environment的值在(production, qa)中的pod。
kubectl get pods -l 'environment,environment notin (frontend)'
# 混合使用
kubectl get pods -l 'partition in (customerA, customerB),environment!=qa'
4.2 在k8s對象
中引用
# 基于等值
---
"selector": { # json格式
"component" : "redis",
"type": "Cluster"
}
selector: # yaml格式
component: redis
type: Cluster
nodeSelector: # 節(jié)點選擇器 spec.nodeSelector
accelerator: nvidia-tesla-p100 # 選擇帶有該標(biāo)簽的節(jié)點。
# 基于集合
---
selector:
# 集合形式,由{key,value}對組成的映射。類似于matchExpressions的In操作。
matchLabels:
component: redis
# 列表形式,支持運算符:In NotIn Exists DoesNotExist。
matchExpressions:
- { key: tier, operator: In, values: [cache] }
- { key: environment, operator: NotIn, values: [dev] }
4.3 根據(jù)標(biāo)簽查找
# 使用-L key查看所有具有key標(biāo)簽的pod。
$ kubectl get pods -Lapp -Ltier -Lrole
NAME READY STATUS RESTARTS AGE APP TIER ROLE
guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend <none>
guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master
guestbook-redis-replica-2q2yf 1/1 Running 0 1m guestbook backend replica
guestbook-redis-replica-qgazl 1/1 Running 0 1m guestbook backend replica
my-nginx-divi2 1/1 Running 0 29m nginx <none> <none>
# 指定標(biāo)簽鍵值
$ kubectl get pods -lapp=guestbook,role=replica
NAME READY STATUS RESTARTS AGE
guestbook-redis-replica-2q2yf 1/1 Running 0 3m
guestbook-redis-replica-qgazl 1/1 Running 0 3m
4.4 更新標(biāo)簽
# 根據(jù)"app=nginx"過濾所有的Pod,然后用打上"tier=fe"標(biāo)簽
$ kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
# 查看剛設(shè)置了標(biāo)簽的Pod
$ kubectl get pods -l app=nginx -L tier # -L 表示查看所有鍵為tier的pod。
NAME READY STATUS RESTARTS AGE TIER
my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe
my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe
5 注解 annotations標(biāo)簽
和注解
都是為k8s對象
附加元數(shù)據(jù)。但是,標(biāo)簽
可以用來選擇對象
和查找
滿足某些條件的對象集合。注解
附加的是非標(biāo)識
元數(shù)據(jù),不用于標(biāo)識
和選擇
對象。
5.1 注解語法
注解
和標(biāo)簽
一樣,也是鍵/值對
。
注解的鍵
也由前綴
+名稱
兩段組成,用斜杠/
分割,前綴是可選的,名稱是必需的。鍵的命名規(guī)范同標(biāo)簽的鍵。注解的值
大小沒有限制,結(jié)構(gòu)沒有規(guī)定,能夠包含標(biāo)簽不允許的字符,客戶端程序(例如工具和庫)能夠獲取這些元數(shù)據(jù)信息,然后進行加工和處理。
# json格式
"metadata": {
"annotations": {
"key1" : "value1",
"key2" : "value2"
}
# yaml格式
metadata:
annotations:
key1: value1
key2: value2
5.2 示例
apiVersion: v1
kind: Pod
metadata:
name: annotations-demo
annotations:
imageregistry: "https://hub.docker.com/" # 定義注解內(nèi)容
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
6 字段選擇器
字段選擇器常用在
REST客戶端
中,根據(jù)字段值篩選k8s對象
。支持的字段有metadata.name、metadata.namespace、status.phase
等,使用不被支持的字段時選擇器會報錯。
# 篩選出status.phase字段值為Running的所有Pod
$ kubectl get pods --field-selector status.phase=Running
# 使用不支持的字段,選擇器報錯
$ kubectl get ingress --field-selector foo.bar=baz
Error from server (BadRequest): Unable to find "ingresses" that match label selector "", field selector "foo.bar=baz": "foo.bar" is not a known field selector: only "metadata.name", "metadata.namespace"
# 支持'='、'=='和'!='
$ kubectl get services --all-namespaces --field-selector metadata.namespace!=default # 篩選非defualt命名空間的svc
# 鏈?zhǔn)竭x擇器,同標(biāo)簽選擇器一樣,可以使用逗號分隔的列表組成一個選擇鏈。
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always
# 查看多種資源類型
kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default
7 屬主與附屬機制
7.1 基本概念
一些
對象
是其他對象
的屬主
,稱為屬主對象
。具有屬主
的對象
是屬主對象
的附屬
,簡稱附屬對象
。例如,ReplicaSet
是一組Pod
的屬主
,Pod
是ReplicaSet
的附屬
。
7.2 屬主引用
附屬對象
有一個metadata.ownerReferences
字段,用來引用
其屬主對象
,這種引用方式就稱為屬主引用
。屬主引用
定義了對象間的附屬關(guān)系
,k8s對象
大多都是通過屬主引用
鏈接到彼此的。metadata.ownerReferences
字段中,包含在同一個命名空間
下的屬主對象名稱
和屬主對象UID
。通常,k8s會自動
給附屬對象
設(shè)置屬主引用
值,這些對象包含ReplicaSet、DaemonSet、Deployment、Job、CronJob、ReplicationController等
。當(dāng)然,也可以手動修改該字段的值。
7.3 垃圾回收
k8s會檢查并刪除不再擁有
屬主引用
的附屬對象
。例如,屬主對象ReplicaSet
被刪除之后留下來的附屬對象Pod
,將會被k8s自動清理。
7.4 級聯(lián)刪除
附屬對象
還有一個ownerReferences.blockOwnerDeletion
字段(布爾值
),用來控制附屬對象
是否阻止屬主對象
被回收刪除。k8s會自動將該字段設(shè)置為true,也可手動更改。當(dāng)刪除一個附屬對象
時,k8s將根據(jù)該字段的值判斷是否刪除該對象的屬主對象
,默認情況下,該字段為true,表示不刪除屬主對象
。比如,默認情況下,刪除附屬對象Pod
時,屬主對象ReplicaSet
不會被刪除。
7.5 與標(biāo)簽選擇器不同
屬主引用
定義了對象間的附屬關(guān)系
,而標(biāo)簽選擇器
只是定義了對象間的調(diào)用關(guān)系
,這種調(diào)用關(guān)系
是松耦合的
,屬主引用
則是對象間的強綁定關(guān)系
。例如,Service
會通過標(biāo)簽選擇器
選擇滿足條件的EndpointSlice對象
,同時,每個EndpointSlice對象
都有一個屬主引用
屬性,指定了其附屬于哪些Service。
Pod原理
- 工作負載Pod
概述:
Pod
是 k8s 系統(tǒng)中可以創(chuàng)建和管理的最小單元
,k8s 不會直接處理容器
,而是通過Pod
管理容器
,通過控制器
管理Pod
,這些控制器
有ReplicaSet、Job、CronJob、Deployment、StatefulSet、DaemonSet等
。
1.1 Pod
結(jié)構(gòu)
Pod
中都包含一個Infra容器
,至少一個應(yīng)用容器
,以及零或多個init容器
和sidecar容器
,除init容器
外,它們共享存儲
和網(wǎng)絡(luò)資源
。
1.2 Infra/Pause容器
基礎(chǔ)設(shè)施容器
Infra容器
創(chuàng)建完成后就會進入Pause狀態(tài)
,所以也叫做Pause容器
。它是Pod
的根容器,Pod中其他的容器都會被加入到Pause
容器中,成為它的子容器。容器技術(shù)參見我的另一篇文章:《Docker企業(yè)級應(yīng)用(架構(gòu)原理+工作流)》
容器之間是通過
命名空間
進行隔離的,為了讓Pod
中的容器共享資源,就需要打破命名空間
的隔離。所以,在Pod
初始化時會首先創(chuàng)建一個Infra容器
,然后再將創(chuàng)建的應(yīng)用容器
加入到Infra容器
中,這樣它們就共享同一套資源了。
容器運行時
可以通過創(chuàng)建父子容器的方式,控制容器組間共享級別。即先創(chuàng)建一個父容器Infra,然后在創(chuàng)建子容器myapp時,指定需要加入的父容器Infra,如docker run -d --name myapp --pip=container:InfraId --net=container:InfraId --ipc=container:InfraId myImage
。
1.2 應(yīng)用容器及回調(diào)
用戶的
應(yīng)用程序
就運行在這些應(yīng)用容器
中。此外,我們可以為應(yīng)用容器設(shè)置回調(diào)函數(shù),在容器啟動和終止時操作。通過spec.containers.lifecycle字段
定義回調(diào)函數(shù)PostStart和PreStop
?;卣{(diào)函數(shù)的作用:
- PostStart
在容器被創(chuàng)建之后立即被執(zhí)行。但是,不能保證回調(diào)會在容器入口點(ENTRYPOINT)之前執(zhí)行。 沒有參數(shù)傳遞給處理程序。- PreStop
在容器因API 請求
或者管理事件
(諸如存活態(tài)探針、啟動探針失敗、資源搶占、資源競爭
等) 而被終止之前,此回調(diào)會被調(diào)用。 如果容器已經(jīng)處于已終止或者已完成狀態(tài),則對 preStop回調(diào)的調(diào)用將失敗。停止容器的TERM 信號
被發(fā)出之前,回調(diào)必須執(zhí)行結(jié)束。Pod 的終止寬限周期在PreStop 回調(diào)
被執(zhí)行之前即開始計數(shù), 所以無論回調(diào)函數(shù)的執(zhí)行結(jié)果如何,容器最終都會在 Pod 的終止寬限期內(nèi)被終止。 沒有參數(shù)會被傳遞給處理程序。
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
dnsPolicy: Default
containers:
- name: myapp-container
image: busybox:1.28
lifecycle:
postStart:
exec:
# command: ["/bin/sh", "-c", "do_postStart.sh"]
command: ["/bin/sh", "-c", "echo Hello postStart> /usr/share/message"]
preStop:
exec:
# command: ["/bin/sh", "-c", "do_preStop.sh"]
command: ["/bin/sh","-c","while killall -0 myapp; do sleep 1; done"]
1.3 Init容器
Pod中可以有多個
init容器
,init容器
會在應(yīng)用容器
啟動之前,依次逐個運行,每個init容器
運行成功后才能執(zhí)行下一個init容器
。當(dāng)所有的init容器
都運行成功后,才會初始化應(yīng)用容器
。當(dāng)init容器運行完成后,它的生命周期也就結(jié)束了,然后被k8s回收。
- 與普通容器不同:
Init容器不支持lifecycle、livenessProbe、readinessProbe或者startupProbe
字段,Init容器必須在Pod準(zhǔn)備就緒之前完成啟動。Init 容器與應(yīng)用容器
共享資源(CPU、內(nèi)存、網(wǎng)絡(luò)
),但不直接與主應(yīng)用容器進行交互。不過這些容器可以使用共享卷進行數(shù)據(jù)交換。- 用途:
1.init容器擁有獨立的文件系統(tǒng)視圖,可以訪問應(yīng)用容器不能訪問的Secret。
2.init容器在應(yīng)用容器啟動之前運行完成,所以可以使用init容器完成一些先決條件,等到前置條件滿足才會運行應(yīng)用容器。
3.方便運行應(yīng)用程序中不能有的工具,如編譯工具、sed、awk等。
# Source: /myworkdir/mypod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app.kubernetes.io/name: MyApp
spec:
# 應(yīng)用容器定義
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
# init容器定義
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
# init容器定義
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
1.4 Sidecar容器
Sidecar容器
是與應(yīng)用容器
在同一個 Pod 中運行的輔助容器。這些容器通過提供額外的服務(wù)或功能(如日志記錄、監(jiān)控、安全性或數(shù)據(jù)同步)來增強或擴展應(yīng)用容器
的功能, 而無需直接修改主應(yīng)用代碼
。
- 與常規(guī)容器不同:
1.Sidecar容器
具有獨立的生命周期。它們可以獨立于應(yīng)用容器
啟動、停止和重啟。 這意味著你可以更新、擴展或維護Sidecar容器
,而不影響主應(yīng)用。
2.可以直接與主應(yīng)用容器進行交互,共享相同的網(wǎng)絡(luò)命名空間、文件系統(tǒng)和環(huán)境變量。- 與Init容器不同:
1.init容器運行完成后就是被k8s回收,而Sidecar容器有獨立的生命周期。
2.sidecar容器支持lifecycle、livenessProbe、readinessProbe或者startupProbe
字段。
apiVersion: apps/v1
kind: Pod
metadata:
name: myapp
labels:
app: myapp
spec:
# 應(yīng)用容器定義
containers:
- name: myapp
image: alpine:latest
command: ['sh', '-c', 'echo "logging" > /opt/logs.txt']
volumeMounts:
- name: data
mountPath: /opt
# 通過initContainers字段定義Sidecar容器
initContainers:
- name: logshipper
image: alpine:latest
restartPolicy: Always # Pod整個生命周期
command: ['sh', '-c', 'tail /opt/logs.txt'] # tail命令保持進程不退出。
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
1.5 Pod生命周期
Pod在其生命周期內(nèi)只能被調(diào)度一次,一旦Pod被調(diào)度到某個節(jié)點上,將一直運行到被終止。每個Pod都有一個唯一的UID值。Pod自身不具備自愈能力,如果Pod所在節(jié)點出現(xiàn)故障,Pod會被刪除。所以,k8s使用
控制器
來管理這些相對臨時性的Pod。
Pod在其生命周期中所處的狀態(tài):文章來源:http://www.zghlxwxcb.cn/news/detail-851132.html
Pod狀態(tài)值 | 描述 |
---|---|
Pending | Pod 已被 Kubernetes 系統(tǒng)接受,但有一個或者多個容器尚未創(chuàng)建亦未運行。此階段包括等待 Pod 被調(diào)度的時間和通過網(wǎng)絡(luò)下載鏡像的時間。 |
ContainerCreating | Pod 已經(jīng)綁定到了某個節(jié)點。正在創(chuàng)建容器。 |
Running | Pod 已經(jīng)綁定到了某個節(jié)點,Pod 中所有的容器都已被創(chuàng)建。至少有一個容器仍在運行,或者正處于啟動或重啟狀態(tài)。 |
Succeeded | Pod 中的所有容器都已成功終止,并且不會再重啟。 |
Failed | Pod 中的所有容器都已終止,并且至少有一個容器是因為失敗終止。也就是說,容器以非 0 狀態(tài)退出或者被系統(tǒng)終止。 |
Unknown | 因為某些原因無法取得 Pod 的狀態(tài)。這種情況通常是因為與 Pod 所在主機通信失敗。 |
1.6 外部訪問Pod容器的應(yīng)用程序文章來源地址http://www.zghlxwxcb.cn/news/detail-851132.html
curl -ivh -k https://${POD_IP}:${CONTAINER_PORT}/path -w %{http_code}
到了這里,關(guān)于k8s企業(yè)級應(yīng)用系列(二):對象管理及Pod原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!