1. 程式人生 > 實用技巧 >Kubernetes實戰指南(三十三):都0202了,你還在手寫k8s的yaml檔案?

Kubernetes實戰指南(三十三):都0202了,你還在手寫k8s的yaml檔案?

目錄

1. k8s的yaml檔案到底有多複雜

Kubernetes建立、更新、刪除資源等操作時均可以使用json或yaml檔案進行操作,更新和刪除可以依賴之前的檔案進行更改,但是建立具有多變形,往往編輯起來比較複雜,容器出錯,而且k8s的配置項實在太多,稍微不注意就會犯錯。要寫好一個yaml檔案,你需要了解yaml的語法,需要掌握k8s的各種配置,對於一個k8s的初學者而言,這將是一件很難的事情。

 

比如我們看一個同時建立一個Deployment、Service、Ingress的yaml檔案內容:

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: test-yaml
  name: test-yaml
  namespace: freeswitch
spec:
  ports:
  - name: container-1-web-1
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: test-yaml
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  creationTimestamp: null
  name: test-yaml
spec:
  rules:
  - host: test.com
    http:
      paths:
      - backend:
          serviceName: test-yaml
          servicePort: 8080
        path: /
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test-yaml
  name: test-yaml
  namespace: freeswitch
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-yaml
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      annotations:
        info: test for yaml
      labels:
        app: test-yaml
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - test-yaml
              topologyKey: kubernetes.io/hostname
            weight: 100
      containers:
      - env:
        - name: TZ
          value: Asia/Shanghai
        - name: LANG
          value: C.UTF-8
        image: nginx
        imagePullPolicy: Always
        lifecycle: {}
        livenessProbe:
          failureThreshold: 2
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: 8080
          timeoutSeconds: 2
        name: test-yaml
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        readinessProbe:
          failureThreshold: 2
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: 8080
          timeoutSeconds: 2
        resources:
          limits:
            cpu: 195m
            memory: 375Mi
          requests:
            cpu: 10m
            memory: 10Mi
        securityContext:
          allowPrivilegeEscalation: false
          capabilities: {}
          privileged: false
          procMount: Default
          readOnlyRootFilesystem: false
          runAsNonRoot: false
        volumeMounts:
        - mountPath: /usr/share/zoneinfo/Asia/Shanghai
          name: tz-config
        - mountPath: /etc/localtime
          name: tz-config
        - mountPath: /etc/timezone
          name: timezone
      dnsPolicy: ClusterFirst
      hostAliases:
      - hostnames:
        - www.baidu.com
        ip: 114.114.114.114
      imagePullSecrets:
      - name: myregistrykey
      - name: myregistrykey2
      restartPolicy: Always
      securityContext: {}
      volumes:
      - hostPath:
          path: /usr/share/zoneinfo/Asia/Shanghai
          type: ""
        name: tz-config
      - hostPath:
          path: /etc/timezone
          type: ""
        name: timezone

這是一個包含了Service、Ingress、Deployment比較常用並且沒有用到高階功能的yaml配置,就已經有上百行,如果是在添加了一些高階配置或者是Deployment中的容器不止一個,這個yaml會更大,就會造成一種視覺上疲勞,更改起來也比較麻煩而且非常容易出錯。

 

2. 基於圖形化的方式自動生成yaml

 

2.1 k8s圖形化管理工具Ratel安裝

 

本次採用Ratel自動生成yaml檔案,Ratel安裝文件:https://github.com/dotbalo/ratel-doc/blob/master/cluster/Install.md

 

2.2 使用Ratel建立生成yaml檔案

 

2.2.1 基本配置

 

安裝完成後,可以生成、建立管理常用的k8s核心資源,比如建立一個Deployment:
點選Deployment -- 建立如圖所示:

 

之後可以填寫一些基本的配置資訊,比如Deployment名稱、副本數、標籤資訊等,當然也可以點選必須/儘量部署至不同宿主機進行Pod親和力的配置

 

同時也可新增一些複雜的配置,比如核心配置、容忍配置、節點親和力快捷配置:

 

2.2.2 親和力配置

 

基本配置編譯完成以後,點選NEXT,下一個配置親和力配置,如果上一頁使用了親和力快捷鍵,這邊會自動生成親和力配置,你可以再次編輯或者新增、刪除:

 

2.2.3 儲存配置

 

親和力配置完成以後,可以點選NEXT進行儲存配置,目前支援volume和projectedVolume配置,volume支援configMap、Secret、HostPath、PVC、NFS、Empty等常用型別的配置:

 

2.2.4 容器配置

 

接下來是容器配置,支援常用的容器配置,當然也可以新增多個容器:

 
稍微複製一點的配置:

 

2.2.4 初始化容器配置

 

初始化容器和容器配置類似

 

2.2.5 Service和Ingress配置

 

建立Deployment時可以一鍵新增Service和Ingress,新增Service時會自動讀取容器的埠配置,新增Ingress時會自動讀取Service配置


 

2.2.6 建立資源或生成yaml檔案

 

上述配置完成以後,可以選擇建立資源或生成yaml檔案,假如點選生成yaml檔案,會自動生成Service、Ingress、Deployment的yaml檔案,可以直接拿著使用:

 

生成的內容如下:

---
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: test-yaml
  name: test-yaml
  namespace: default
spec:
  ports:
  - name: container-1-web-1
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: test-yaml
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  creationTimestamp: null
  name: test-yaml
spec:
  rules:
  - host: test.com
    http:
      paths:
      - backend:
          serviceName: test-yaml
          servicePort: 8080
        path: /
status:
  loadBalancer: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: test-yaml
  name: test-yaml
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-yaml
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: test-yaml
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - preference:
              matchExpressions:
              - key: loki
                operator: In
                values:
                - "true"
            weight: 100
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: master
                operator: NotIn
                values:
                - "true"
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - test-yaml
            topologyKey: kubernetes.io/hostname
      containers:
      - args:
        - '*.jar --server.port=80'
        command:
        - java -jar
        env:
        - name: TZ
          value: Asia/Shanghai
        - name: LANG
          value: C.UTF-8
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        envFrom:
        - configMapRef:
            name: testcm
        image: nginx
        imagePullPolicy: IfNotPresent
        lifecycle:
          postStart:
            exec:
              command:
              - echo "start"
          preStop:
            exec:
              command:
              - sleep 30
        livenessProbe:
          failureThreshold: 2
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: 8080
          timeoutSeconds: 2
        name: test-yaml
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        readinessProbe:
          failureThreshold: 2
          httpGet:
            httpHeaders:
            - name: a
              value: b
            path: /
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 2
        resources:
          limits:
            cpu: 493m
            memory: 622Mi
          requests:
            cpu: 10m
            memory: 10Mi
        securityContext:
          allowPrivilegeEscalation: false
          capabilities: {}
          privileged: false
          procMount: Default
          readOnlyRootFilesystem: false
          runAsNonRoot: false
        volumeMounts:
        - mountPath: /usr/share/zoneinfo/Asia/Shanghai
          name: tz-config
        - mountPath: /etc/localtime
          name: tz-config
        - mountPath: /etc/timezone
          name: timezone
        - mountPath: /mnt
          name: nfs-test
      dnsPolicy: ClusterFirst
      initContainers:
      - args:
        - init
        command:
        - echo
        env:
        - name: TZ
          value: Asia/Shanghai
        - name: LANG
          value: C.UTF-8
        image: nignx-init
        imagePullPolicy: Always
        name: init
        resources:
          limits:
            cpu: 351m
            memory: 258Mi
          requests:
            cpu: 10m
            memory: 10Mi
        securityContext:
          allowPrivilegeEscalation: false
          capabilities: {}
          privileged: false
          procMount: Default
          readOnlyRootFilesystem: false
          runAsNonRoot: false
        volumeMounts:
        - mountPath: /usr/share/zoneinfo/Asia/Shanghai
          name: tz-config
        - mountPath: /etc/localtime
          name: tz-config
        - mountPath: /etc/timezone
          name: timezone
      nodeSelector:
        ratel: "true"
      restartPolicy: Always
      securityContext:
        sysctls:
        - name: net.core.somaxconn
          value: "16384"
        - name: net.ipv4.tcp_max_syn_backlog
          value: "16384"
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
        operator: Exists
      volumes:
      - name: projected-test
        projected:
          defaultMode: 420
          sources:
          - downwardAPI:
              items:
              - fieldRef:
                  fieldPath: metadata.name
                path: /opt/x
      - hostPath:
          path: /usr/share/zoneinfo/Asia/Shanghai
          type: ""
        name: tz-config
      - hostPath:
          path: /etc/timezone
          type: ""
        name: timezone
      - name: nfs-test
        nfs:
          path: /data/nfs
          server: 1.1.1.1
status: {}

這個yaml比之前的稍複雜,並且添加了一些高階配置,手動編寫的還是比較麻煩的,所以用Ratel自動生成還是比較方便的,並且不會出錯。

 

3. 其他資原始檔自動生成

 

目前支援了很多資原始檔的自動生成,比如:Deployment、StatefulSet、DaemonSet、Service、Ingress、CronJob、Secret、ConfigMap、PV、PVC等,可以大大減少我們的工作量和k8s的複雜度。

 
 
如果想要系統的學習k8s,可以專注下k8s的課程:

51CTO
 
騰訊課堂