Kubernetes的yaml檔案使用語法及簡單操作
技術標籤:KubernetesK8S的yaml檔案語法yaml檔案使用語法及簡單操作
apiVersion版本
當編寫一個yml檔案時,第一行必須先寫入apiVersion的版本
不同的apiVersion可以實現不同的功能,或者配合不同的元件去使用
官方文件也沒有給出一個充分的解釋
使用kubectl api-version檢視當前系統下的k8s支援的apiVersion有那些
[[email protected] ~]# kubectl api-versions
admissionregistration.k8s.io/v1
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1 # Deployment/DaemonSet/ReplicaSet
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1
autoscaling/v2beta1
autoscaling/v2beta2
batch/v1 # Job
batch/v1beta1
batch/v2alpha2
certificates.k8s.io/v1beta1
coordination.k8s.io/v1
coordination.k8s.io/v1beta1
discovery.k8s.io/v1beta1
events.k8s.io/v1beta1
extensions/v1beta1
networking.k8s.io/v1
networking.k8s.io/v1beta1
node.k8s.io/v1beta1
policy/v1beta1
rbac.authorization.k8s.io/v1
rbac.authorization.k8s.io/v1beta1
scheduling.k8s.io/v1
scheduling.k8s.io/v1beta1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1 # service/PersistentVolume/Pod/Secret/ConfigMap
apiVersion版本分類
alpha
apiVersion版本名稱中包含alpha的,這是k8s準備出的一些新功能會包含在這個版本中,很有可能會出現未知無法解決的錯誤,僅用於測試的版本。測試沒有問題,很有可能會納入之後的新版本中。
不建議使用
beta
名稱中包含beta的是基於alpha測試成功,被預設啟用,會保留在後續版本中
stable
這是一個穩定版本,命名方式為v1/v2諸如類似,可以放心使用
Kubernetes的官方文件中並沒有對apiVersion的詳細解釋,而且因為K8S本身版本也在快速迭代,有些資源在低版本還在beta階段,到了高版本就變成了stable。
如: Deployment
1.6版本之前:extensions/v1beta1
1.6-1.9之間:apps/v1beta1同時保留舊版本
1.9-1.16之間:apps/v1同時保留舊版本
1.17以上:apps/v1,不保留extensions/v1beta1和apps/v1beta1
個別版本介紹
v1
Kubernetes API的穩定版本,包含了多核心物件Pod、service
apps/v1beta2
在kubernetes1.8版本中,新增加了apps/v1beta2的概念,apps/v1beta1同理
DaemonSet,Deployment,ReplicaSet 和 StatefulSet的當時版本遷入apps/v1beta2,相容原有的extensions/v1beta1
apps/v1
在kubernetes1.9版本中,引入apps/v1,deployment等資源從extensions/v1beta1, apps/v1beta1 和 apps/v1beta2遷入apps/v1,原來的v1beta1等被廢棄。
apps/v1代表:包含一些通用的應用層的api組合,如:Deployments, RollingUpdates, 和ReplicaSets
batch/v1
代表job相關的api組合
在kubernetes1.8版本中,新增了batch/v1beta1,後CronJob 已經遷移到了 batch/v1beta1,然後再遷入batch/v1
autoscaling/v1
代表自動擴縮容的api組合,kubernetes1.8版本中引入。
這個組合中後續的alpha 和 beta版本將支援基於memory使用量、其他監控指標進行擴縮容
extensions/v1beta1
deployment等資源在1.6版本時放在這個版本中,後遷入到apps/v1beta2,再到apps/v1中統一管理
certificates.k8s.io/v1beta1
安全認證相關的api組合
authentication.k8s.io/v1
資源鑑權相關的api組合
k8s的yaml檔案語法
直接編寫使用一個檔案做示例
[[email protected] ~]# vim nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
yaml檔案的固定結構
每個檔案必須的結構如下:
apiVersion: apps/v1 # api版本
kind: xxxx # 要建立的資源型別,如Deployment/Pod/ReplicaSet/StatefulSet/DaemonSet/Job/Cronjob/Service/Ingress...
metadata: # 元資料物件,該資源的基本屬性和資訊
name: xxx # 定義該資源的名稱
namespace: xxx # 名稱空間,預設放到default空間
lables: # 標籤,在下一行定義鍵值對,可以是多對鍵值對
xxx: xxxx
xxx: xxxx
annotations # 資源註解
xxx: xxxx
spec: # 定義期望狀態,詳細的建立資訊
containers: # 容器列表
- name: xxx # 容器名
image: xxxx # 容器映象
status: # 當前狀態,由k8s叢集維護,不可以自定義
拆分例項檔案結構
Controller定義部分
必須定義名字
------------------------------------------
apiVersion: apps/v1 # api版本(必須的)
kind: Deployment # 表示要建立的Controller資源型別
metadata: # 元資料物件,該資源的基本屬性和資訊(必須的)
name: nginx-deployment # 定義該資源的名稱(必須的),同一名稱空間內,必須唯一
namespace: xxxx # 名稱空間,預設放到default空間(可選)
labels: # 標籤,用來定位一個或多個資源,鍵值對方式進行定義,下方使用的selector會與這裡的鍵值對對應,作為selector的挑選條件
app: nginx # 設定key為app,value為nginx
------------------------------------------
資源的特點
也就是kind所建立的資源的資訊
------------------------------------------
spec: # 描述該資源的建立資訊,對應kind資源型別的資訊
revisionHistoryLimit: 10 # 回滾時會用到,用來保留最近10的版本
replicas: 2 # 建立2個應用例項
selector:
# 標籤選擇器,與上面的標籤共用,這個部分是17版本開始加的,必須與上面的labels對應
matchLabels: # 選擇包含標籤app:nginx的資源
# 正確的Deployment,讓matchLabels 和template.metadata.lables完全匹配才能不報錯
# 直接不寫spec.mathlabels建立直接報錯缺少缺少必要欄位selector
# 當把matchLables匹配的和下面pod模板不相對應,也會直接報錯:選擇的標籤和模板標籤不匹配
# matchLabel是pod的標籤選擇器。 由此選擇其pod的現有ReplicaSet(副本集)將受此部署影響的副本。
app: nginx
------------------------------------------
matchLabels總結
1、在Deployment中必須寫matchLabels
2、在定義模板的時候必須定義labels,因為Deployment.spec.selector是必須欄位,而又必須和template.labels對應
3、templdate裡面定義的內容會應用到下面所有的副本集裡面,在template.spec.containers裡面不能定義labels標籤
Pod的模板
必須定義labels
------------------------------------------
template: # 選擇或建立的Pod模板
metadata: # Pod的元資料,Pod的資訊
labels: # Pod標籤
app: nginx
------------------------------------------
Container的模板
------------------------------------------
spec: # 期望Pod實現的功能(在Pod中部署什麼)
strategy: # 在滾動更新Pod時的啟動Pod數量比值
rollingUpdate:
maxSurge: 35%
maxUnavailable: 35%
nodeSelector: # 指定pod執行在哪個叢集節點
restartPolicy: # 容器重啟策略(Never/Always/OnFailure)
hostNetwork: true # 表示直接使用節點中的主機網路,相當於docker的host網路
containers: # 在Pod中生成容器,容器列表,可寫入多個映象的例項
- name: xxxx # 定義容器名
image: xxxx # 容器使用的映象
- name: xxxx
image: xxxx
imagePullPolicy:
# 映象下載策略(IfNotPresent/Never/Always)
# 分別代表,沒有映象時下載,從不下載,總是下載
command: # 執行程式==dockerfile中的ENTRYPOINT,或者docker run時最後跟的/bin/bash等命令,會替代dockerfile中cmd和ENTRYPOINT執行的命令
- echo
- 'hello world'
args: # 向docker映象中傳遞命令,通常用來給command傳參,也可以單獨使用,與dockerfile中的CMD作用一樣,如果yml中只寫了args,將會給dockerfile中的ENTRYPOINT傳參,dockerfile中的CMD會失效。
- xxx
- xxx
ports: # 用來暴露埠,並不是埠對映,僅僅為了可以看到容器中使用了哪兩個埠
- name: xxx
containerPort: 80 # 容器中提供服務的埠
protocol: TCP/UDP # 預設是tcp
- name: xxx
containerPort: 443
volumeMounts: # 用來指定容器內的路徑
- name: nginxconf
mountPath: /usr/local/nginx/conf
- name: nginxhtml
mountPath: /usr/local/nginx/html
readOnly: True # 設定容器內只讀,預設是讀寫
volumes: # 指定對應name的物理機路徑,縮排與上方的containers對齊
- name: nginxconf
hostPath:
path: /nginx/conf
- name: nginxhtml
hostPath:
path: /nginx/html
- name: xxx
emptyDir: {}
- name: xxx
persistentVolumeClaim: # 使用PVC儲存資源
claimName: xxxxx-xxx
LivenessProbe: # 存活檢測,判斷檔案是否存在,檢測失敗重啟容器
exec:
command:
- cat
- /tmp/healthy
readinessProbe: # 讀取檢測,判斷檔案是否存在,檢測失敗,標記為不可用,將不會被Service所負載
exec:
command:
- cat
- /tmp/healthy
------------------------------------------
其他的一些引數功能,在後面的使用過程中會提到,也回去解釋
大致結構是這樣的
Labels的重要性
在新版的k8s中labels是非常重要的
注意:
必須在 Deployment 中指定適當的選擇器和 Pod 模板標籤(在本例中為app: nginx)。不要與其他控制器(包括其他Deployments 和狀態設定)重疊標籤或選擇器。Kubernetes不會阻止重疊,如果多個控制器具有重疊的選擇器,這些控制器可能會衝突並執行意外。
matchLabels/matchExpression作用
matchLabels用於定義一組Label,與直接寫在Selector中作用相同,直接給定鍵值;
matchExpression用於定義一組基於集合的篩選條件,基於表示式來定義使用標籤選擇器,{key: “KEY”, operator:
“OPERATOR”, values:[VAL1,VAL2,…]}。可用的條件運算子包括:
In、NotIn:values欄位的值必須為非空列表。
Exists、DoesNotExist:values欄位的值必須為空列表。如果同時設定了matchLabels和matchExpression,則兩組條件為“AND”關係,即所有條件需要滿足才能完成Selector的篩選。
matchLabels使用場景
1.kube-controller程序通過資源物件ReplicaSet上定義的Label Selector來篩選要監控的Pod副本的數量,從而實現Pod副本的數量始終符合預期設定的全自動控制流程
2.kube-proxy程序通過Service的Label Selector來選擇對應的Pod,自動建立器每個Service到對應Pod的請求轉發路由表,從而實現Service的智慧負載均衡機制
3.通過對某些Node定義特定的Label,並且在Pod定義檔案中使用NodeSelector這種標籤排程策略,Kube-scheduler程序可以實現Pod定向排程的特性
Pod 選擇器
.spec.selector 欄位是一個標籤選擇器。 ReplicationController 管理標籤與選擇器匹配的所有 Pod。它不區分它建立或刪除的 Pod 和其他人或程序建立或刪除的 Pod。 這允許在不影響正在執行的 Pod 的情況下替換ReplicationController。
如果指定了 .spec.template.metadata.labels,它必須和 .spec.selector 相同,否則它將被 API拒絕。 如果沒有指定 .spec.selector,它將預設為 .spec.template.metadata.labels。
另外,通常不應直接使用另一個 ReplicationController 或另一個控制器(例如 Job)來建立其標籤與該選擇器匹配的任何Pod。如果這樣做,ReplicationController 會認為它建立了這些 Pod,就會產生衝突, Kubernetes並沒有阻止你這樣做。
使用檔案部署Deployment
[[email protected] ~]# kubectl apply -f nginx.yml
deployment.apps/nginx-deployment created
如果出現以下報錯,則是有重複名字的Deployment存在
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
The Deployment "nginx-deployment" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"nginx"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
檢視建立的Deployment
[[email protected] ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 2 2 46s
檢視Deployment建立的ReplicaSet
[[email protected] ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5bf87f5f59 2 2 2 24s
檢視已執行的pod
[[email protected] ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-deployment-5bf87f5f59-8rrjv 1/1 Running 0 11m 10.244.1.4 node2
nginx-deployment-5bf87f5f59-cxjdm 1/1 Running 0 11m 10.244.2.4 node3
檢視pod的labels標籤
[[email protected] ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-5bf87f5f59-8rrjv 1/1 Running 0 11m app=nginx,pod-template-hash=5bf87f5f59
nginx-deployment-5bf87f5f59-cxjdm 1/1 Running 0 11m app=nginx,pod-template-hash=5bf87f5f59
刪除使用檔案建立的deployment的方法
[[email protected] ~]# kubectl delete -f nginx.yml
多Deployment環境中快速確定Pod的歸屬
如果在生產環境中有大量的Deployment的話,無法快速確定哪些Pod是屬於哪個Deployment,這個是就體現了label標籤的重要性
基於以上的nginx-deployment,在執行一個httpd-deployment的Deployment
[[email protected] ~]# vim httpd.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment
spec:
replicas: 3
selector:
matchLabels:
run: httpd
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: httpd:latest
ports:
- containerPort: 80
執行httpd-deployment
[[email protected] ~]# kubectl apply -f httpd.yml
deployment.apps/httpd-deployment created
這時候再來檢視Pod,直接看到了兩個Deployment中的所有pod
[[email protected] ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
httpd-deployment-5dd67c6b75-mdnsz 1/1 Running 0 77s
httpd-deployment-5dd67c6b75-v2pmt 1/1 Running 0 77s
httpd-deployment-5dd67c6b75-zfrgb 1/1 Running 0 77s
nginx-deployment-5bf87f5f59-8rrjv 1/1 Running 0 39m
nginx-deployment-5bf87f5f59-cxjdm 1/1 Running 0 39m
想要檢視某個Deployment中的pod,可以根據各自的標籤來檢視,如下:
[[email protected] ~]# kubectl get pods -l run=httpd
NAME READY STATUS RESTARTS AGE
httpd-deployment-5dd67c6b75-mdnsz 1/1 Running 0 2m29s
httpd-deployment-5dd67c6b75-v2pmt 1/1 Running 0 2m29s
httpd-deployment-5dd67c6b75-zfrgb 1/1 Running 0 2m29s
[[email protected] ~]# kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-5bf87f5f59-8rrjv 1/1 Running 0 41m
nginx-deployment-5bf87f5f59-cxjdm 1/1 Running 0 41m