1. 程式人生 > 其它 >Kubernetes的yaml檔案使用語法及簡單操作

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檔案語法

  • 大小寫敏感
  • 使用縮排表示層級關係
  • 縮排時不允許使用Tab鍵,只允許使用空格。
  • 縮排的空格數目不重要,只要相同層級的元素左側對齊即可
  • 表示註釋,從這個字元一直到行尾,都會被解析器忽略。

直接編寫使用一個檔案做示例

[[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