04 . kubernetes資源清單YAML入門

men發表於2020-07-01

YAML

通過k8s操作yaml配置檔案在node上建立資源,yaml配置檔案就像船垛,用來操控docker這艘大船

yam是專門用來寫配置檔案的語言,非常簡潔和強大。而實際上使用yaml配置檔案建立這些操作物件的方式會比直接使用命令列更可取,因為這些檔案可以進行版本控制,而且檔案的變化和內容也可以進行稽核,當使用及其複雜的配置來提供一個穩健、可靠和易維護的系統時,這些點就顯得非常重要。
在宣告定義配置檔案的時候,所有的配置檔案都儲存在YAML或者JSON格式的檔案中並且遵循k8s的資源配置方式。kubectl可以建立、更新、刪除和獲得API操作物件,當前apiVersion、kind和name會組成一個API Path以供kubectl來呼叫。

使用YAML用於K8s的定義帶來的好處:

# 便捷性:不必新增大量的引數到命令列中執行命令  
# 可維護性:YAML檔案可以通過源頭控制,跟蹤每次操作  
# 靈活性:YAML可以建立比命令列更加複雜的結構
YAML語法規則
# 1. 大小寫敏感.
# 2. 使用縮排表示層級關係.
# 3. 縮排時不允許使用Tab鍵,只允許使用空格set ai.
# 4. 縮排的空格數不重要,只要相同層級的元素左側對齊即可.  
# 5. 表示註釋,從這個字元一直到行尾,都會被解析器忽略.
# 在Kubernetes中,只需要知道兩種結構型別:
# 例一.Maps: 對映即字典Kye: Value
---
apiVersion: v1
kind: Pod
# ---為可選的分隔符,當需要在一個檔案中定義多個結構的時候就需要使用

# 例二.lists列表即陣列
# python中的列表: args=[beijing,shaohai,shenzhen,guangzhou]
args:
 - beijing
 - shanghai
 - shenzhen
 - guangzhou
# 可以指定任何數量的項在列表中,每個項的定義以(-)開頭,並且與父元素之間存在縮排

一個簡單的Hello World容器Pod可以通過YAML這樣定義

cat hello.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
spec:
  containers:
  - name: hello
    image: daocloud.io/library/centos:7
    command: ["/bin/echo","hello","world"]
      
# apiVersion: v1		
# API群組名稱和版本,由組名+版本號組成: group/version,如果group省略表示核心組的定義: 可用$kubectl api-versions獲取;
# 所有的對映資料都可以使用花括號,所有列表資料都得使用中括號.
# apiVersion:piserver版本,建立任何資源都是需要定義的,大部分用v1,但v1不支援deployment,用v1的擴充套件版extensions/v1beta1
# metadata.name:  Pod名,該名稱必須是唯一的.
# spec:  當前Pod內容的宣告.
# restartPollcy:  Never標識啟動後執行一次就終止這個Pod
# containers: name為容器的名字
# container[1]: image為該啟動容器的映象
# containers[2]:  command相當於Dockerfile中定義的Entrypoint,通過下列的方式來宣告cmd的引數.
# command: ["/bin/echo"]
# args: ["hello","world"]
使用yaml釋出一個容器化應用

專案描述

1、需要映象,此映象可以來自於官方,開發,或者是自己製作的映象。

2、在k8s叢集中按照 Kubernetes 專案的規範和要求,將映象組織以它能夠"認識"的方式部署此應用。考慮是否做副本,不做副本就以pod方式部署應用;做副本就需要以deployment方式部署應用,而且還需要部署一個service

什麼叫Kubernetes專案能"認識"的方式?

就是使用YAML或者是JSON格式編寫Kubernetes的配置檔案,這是k8s的必備技能
Kubernetes跟Docker等很多專案最大的不同在於它雖然支援使用kubectl run這樣的命令列方式執行容器,但它並不推薦使用此方式,而是希望用YAML檔案的方式來執行容器,即把容器的定義、引數、配置,統統記錄在一個 YAML 檔案中,然後用kubectl create -f 配置檔案的方式把它執行起來。這樣部署應用還有一個最大的優點在於:檔案中記錄了Kubernetes到底"run"了什麼。

部署過程
編寫建立Pod的YAML檔案

YAML 檔案,對應到 k8s 中,就是一個API Object(API 物件)。當你為這個物件的各個欄位填好值並提交給 k8s 之後,k8s 就會負責建立出這些物件所定義的容器或者其他型別的 API 資源.

cat pod-demo.yaml 
---
apiVersion: v1			
kind: Pod
metadata:
 name: nginx 
 labels:
  app: web
spec:
 containers:
  - name: front-end
    image: nginx
    ports:
     - containerPort: 80
  - name: flaskapp-demo
    image: jcdemo/flaskapp
    ports:
        - containerPort: 5000


kubectl apply -f pod-demo.yaml --validate
# kind:這裡我們建立的是一個Pod,當然根據你的實際情況,這裡的資源型別可以是Deployment,Job,ngress,Service等.
# metadata: 包含了我們定義的Pod的一些meta資訊,比如名稱namespace、標籤等等資訊.
# spec:包括一些containers,storage,volumes,或者其他Kubernetes需要知道的引數,以及諸如是否在容器失敗時重新啟動容器的屬性,
# 你可以在特定KubernetesAP找到完整的Kubernetes Pod的屬性讓我們看一個典型容器的定義.
spec:
  containers:
    - name: front-end
      image: nginx
      ports:
        - containerPort: 80
# 我們將上面內容儲存成為Pod.yaml檔案,來建立Pod

查詢Pod的狀態和生命週期事件

kubectl describe pod nginx
Name:         nginx
Namespace:    default
Priority:     0
Node:         node2/172.19.0.54
Start Time:   Thu, 19 Dec 2019 16:51:44 +0800
Labels:       app=web
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"web"},"name":"nginx","namespace":"default"},"spec":{"contain...
Status:       Running
IP:           10.244.1.4
IPs:
  IP:  10.244.1.4
Containers:
  front-end:
    Container ID:   docker://5b4895a1e08387557a02760b8c49513bc2728476d627677662605b1f09b4103c
    Image:          nginx
    Image ID:       docker-pullable://nginx@sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Thu, 19 Dec 2019 16:53:03 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-j9thc (ro)
  flaskapp-demo:
    Container ID:   docker://7d2e0353226f5a36df8384244a8dbcd766bd356ca037a33eb481d4990986fcfc
    Image:          jcdemo/flaskapp
    Image ID:       docker-pullable://jcdemo/flaskapp@sha256:8dd21e8822e08414c0fe2531c22b575a33da3964e51d39cfa27e7b68520056af
    Port:           5000/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Thu, 19 Dec 2019 16:52:18 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-j9thc (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-j9thc:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-j9thc #(目標狀態),以目標狀態為準,k8s就用來確保當前狀態無限向目標狀態轉移
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s	# 容忍那些汙點.
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason     Age                From               Message

----     ------     ----               ----               -------

  Normal   Scheduled  <unknown>          default-scheduler  Successfully assigned default/nginx to node2
  Warning  Failed     11m                kubelet, node2     Failed to pull image "nginx": rpc error: code = Unknown desc = Get https://registry-1.docker.io/v2/library/nginx/manifests/sha256:189cce606b29fb2a33ebc2fcecfa8e33b0b99740da4737133cdbcee92f3aba0a: net/http: TLS handshake timeout
  Normal   Pulling    11m                kubelet, node2     Pulling image "jcdemo/flaskapp"
  Normal   Pulled     10m                kubelet, node2     Successfully pulled image "jcdemo/flaskapp"
  Normal   Created    10m                kubelet, node2     Created container flaskapp-demo
  Normal   Started    10m                kubelet, node2     Started container flaskapp-demo
  Warning  Failed     10m (x2 over 11m)  kubelet, node2     Error: ErrImagePull
  Warning  Failed     10m                kubelet, node2     Failed to pull image "nginx": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
  Normal   BackOff    10m (x2 over 10m)  kubelet, node2     Back-off pulling image "nginx"
  Warning  Failed     10m (x2 over 10m)  kubelet, node2     Error: ImagePullBackOff
  Normal   Pulling    10m (x3 over 11m)  kubelet, node2     Pulling image "nginx"
  Normal   Pulled     10m                kubelet, node2     Successfully pulled image "nginx"
  Normal   Created    10m                kubelet, node2     Created container front-end
  Normal   Started    10m                kubelet, node2     Started container front-end
describe解釋
# 名欄位含義 (以Go Template方式過濾指定的資訊—— 查詢Pod的執行狀態(類似docker的inspect))
kubectl get pods nginx --output=go-template --template={{.status.phase}}
Running

# 各欄位含義  
Name: Pod的名稱  
Namespace: Pod的Namespace。  
Image(s): Pod使用的映象  
Node: Pod所在的Node。  
Start Time: Pod的起始時間  
Labels: Pod的Label。  
Status: Pod的狀態Running、Complete、Pending,就是pod的生命週期。  
Reason: Pod處於當前狀態的原因。  
Message: Pod處於當前狀態的資訊。  
IP: Pod的PodIP  
Replication Controllers: Pod對應的Replication Controller。  
  
Containers:Pod中容器的資訊  
  
Container ID: 容器的ID  
Image: 容器的映象  
Image ID:映象的ID  
State: 容器的狀態  
Ready: 容器的準備狀況(true表示準備就緒)。  
Restart Count: 容器的重啟次數統計  
Environment Variables: 容器的環境變數  
Conditions: Pod的條件,包含Pod準備狀況(true表示準備就緒)  
Volumes: Pod的資料卷  
Events: 與Pod相關的事件列
建立一個簡單的Pod
cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx

# 如果需要更改這個Pod,修改這個配置檔案要修改的資訊,然後刪除重建
kubectl replace -f pod-demo.yaml --force
kubectl apply -f pod-demo.yaml --force

進入Pod對應的容器內部

kubectl exec -it nginx /bin/bash
# 也可以去node端使用docker命令進入命令,並且exit對容器不會產生影響.
使用yaml建立一個名稱空間
cat namespace.yml 
---
apiVersion: v1
kind: Namespace
metadata:
  name: ns-monitor
  labels:
    name: na-monitor
# 後設資料習慣帶name,查詢時可以使用名字,但是labels可以不帶,資源之間呼叫時使用標籤.

# 建立該資源
kubectl apply -f namespace.yml

# 檢視該資源
kubectl get namespaces
NAME              STATUS   AGE
default           Active   47h
kube-node-lease   Active   47h
kube-public       Active   47h
kube-system       Active   47h
ns-monitor        Active   21s

kubectl describe namespace ns-monitor
Name:         ns-monitor
Labels:       name=na-monitor
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"labels":{"name":"na-monitor"},"name":"ns-monitor"}}
Status:       Active
No resource quota.
No LimitRange resource.

# 刪除該資源
kubectl delete -f namespace.yml

YAML建立deployment和service

建立deployment和pod

cat nginx-deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: daocloud.io/library/nginx
        ports:
        - containerPort: 80 

建立service

cat nginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx

YAML資源限制

cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: daocloud.io/library/nginx
    resources:
      requests:
        memory: "64Mi"		# 初始記憶體
        cpu: "250m"
      limits:
        memory: "128Mi"	# 最大記憶體
        cpu: "500m"
# 其實此處的資源限制是跟docker差不多的,可以在docker用docker inspect檢視.

相關文章