三、Kubernetes 組件與Namespace

1、 YAML基礎

參考鏈接: k8s-YAML配置文件

  • 前提知識點

    在正式學習K8S的各組件之前,我們先了解一下 YAML 文件的語法規則,熟悉語法之后才能更好的理解配置文件是如何描述的。

    YAML是專門用來寫配置文件的語言,非常簡潔和強大,使用比json更方便。它實質上是一種通用的數據串行化格式。

    • YAML語法規則

      • 大小寫敏感
      • 使用縮進表示層級關系
      • 縮進時不允許使用Tal鍵,只允許使用空格
      • 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
      • ”#” 表示注釋,從這個字符一直到行尾,都會被解析器忽略
      • 使用key: value,其中 ":" 和 value 之間要有一個英文空格
    • 在Kubernetes中,只需要知道兩種結構類型即可

      • Lists

        List即列表,其實就是數組,例如:

        args
         - beijing
         - shanghai
         - shenzhen
         - guangzhou
        

        可以指定任何數量的項在列表中,每個項的定義以破折號(-)開頭,并且與父元素之間存在縮進。在JSON格式中,表示如下:

        {
          "args": ["beijing", "shanghai", "shenzhen", "guangzhou"]
        }
        

        當然Lists的子項也可以是Maps,Maps的子項也可以是List,例如:

        apiVersion: v1
        kind: Pod
        metadata:
          name: kube100-site
          labels:
            app: web
        spec:
          containers:
            - name: front-end
              image: nginx
              ports:
                - containerPort: 80
            - name: flaskapp-demo
              image: jcdemo/flaskapp
              ports: 8080
        

        如上述文件所示,定義一個containers的List對象,每個子項都由name、image、ports組成,每個ports都有一個KEY為containerPort的Map組成,轉成JSON格式文件:

        {
          "apiVersion": "v1",
          "kind": "Pod",
          "metadata": {
              "name": "kube100-site",
              "labels": {
                  "app": "web"
              },
          },
          "spec": {
              "containers": [{
                  "name": "front-end",
                  "image": "nginx",
                  "ports": [{
                      "containerPort": "80"
                  }]
              }, {
                  "name": "flaskapp-demo",
                  "image": "jcdemo/flaskapp",
                  "ports": [{
                      "containerPort": "5000"
                  }]
              }]
          }
        }
        
      • Maps

        Map顧名思義指的是字典,即一個Key:Value 的鍵值對信息。例如:

        ---
        apiVersion: v1
        kind: Pod
        

        注:--- 為可選的分隔符 ,當需要在一個文件中定義多個結構的時候需要使用。

        上述內容表示有兩個鍵apiVersion和kind,分別對應的值為v1和Pod。Maps的value既能夠對應字符串也能夠對應一個Maps。例如:

        ---
        apiVersion: v1
        kind: Pod
        metadata:
          name: kube100-site
          labels:
            app: web
        

        注:上述的YAML文件中,metadata這個KEY對應的值為一個Maps,而嵌套的labels這個KEY的值又是一個Map。實際使用中可視情況進行多層嵌套。

        YAML處理器根據行縮進來知道內容之間的關聯。上述例子中,使用兩個空格作為縮進,但空格的數據量并不重要,只是至少要求一個空格并且所有縮進保持一致的空格數 。

        例如,name和labels是相同縮進級別,因此YAML處理器知道他們屬于同一map;它知道app是lables的值因為app的縮進更大。

        注意:在YAML文件中絕對不要使用tab鍵

2、Kubernetes 組件

2.1 Pod

在上一章節其實已經演示了 Pod 的創建,但是那是使用 ReplicaSet 來創建和管理Pod,而且沒有進行講解。

本章從最小操作單元 Pod 來開始演示,并說明 YAML 文件要如何配置。

  • 理解 Pod

    • Pod 是 Kubernetes 應用程序的基本執行單元,即它是 Kubernetes 對象模型中創建或部署的最小和最簡單的單元。Pod 表示在集群上運行的進程。
    • Pod 封裝了應用程序容器(或者在某些情況下封裝多個容器)、存儲資源、唯一網絡 IP 以及控制容器應該如何運行的選項。
    • Pod 表示部署單元:Kubernetes 中應用程序的單個實例,它可能由單個 容器 或少量緊密耦合并共享資源的容器組成。
    • Pod 中的容器被自動的安排到集群中的同一物理或虛擬機上,并可以一起進行調度。 容器可以共享資源和依賴、彼此通信、協調何時以及何種方式終止它們。
    • 上面的內容用一句話來說就是:Pod 就是一個或多個相同Container的集合,相互之間可以互通與共享資源。
  • 使用 Pod

    • 定義 pod_nginx.yaml

      apiVersion: v1          # 必寫,指定api版本,此值必須在 kubectl api-versions 中存在
      kind: Pod               # 必寫,指定創建資源的類型為 Pod  
      metadata:               # 必寫,資源的元數據
        name: nginx-pod       # 必寫,表示pod名稱,在同一個namespace中必須唯一,namespace后面再說
        namespace: default    # 表示pod所屬的命名空間
        labels:               # 設定資源的標簽
          app: nginx          # key: app, value: nginx
      spec:                   # 必寫,pod中容器的詳細定義
        containers:           # 必寫,pod中容器列表
        - name: nginx         # 必寫,容器的名字
         image: nginx         # 必寫,使用的鏡像
         ports:               # 定義端口
         - containerPort: 80  # 容器對外開放的端口
      

      spec 上面的配置都是對 Pod 資源的配置信息,從 spec 往下開始才是去定義容器的。

    • 創建 Pod

      # 根據 pod_nginx.yaml 創建資源
      [root@master-kubeadm-k8s pod]# kubectl apply -f pod_nginx.yaml
      pod/nginx-pod created
      
    • 查看 Pod 信息

      # 查看 pod,這里正在創建中,等一會就會創建完成
      [root@master-kubeadm-k8s pod]# kubectl get pods
      NAME        READY   STATUS              RESTARTS   AGE
      nginx-pod   0/1     ContainerCreating   0          15s
      
      # 再次查看,容器已經運行起來了
      [root@master-kubeadm-k8s pod]# kubectl get pods
      NAME        READY   STATUS              RESTARTS   AGE
      nginx-pod   1/1     Running             0          20s
      
      # 查看 pod 詳情
      [root@master-kubeadm-k8s pod]# kubectl get pods -o wide
      NAME        READY   STATUS    RESTARTS   AGE   IP             NODE                   NOMINATED NODE   READINESS GATES
      nginx-pod   1/1     Running   0          22m   192.168.14.4   worker01-kubeadm-k8s   <none>           <none>
      
      # 查看 Pod 的詳情描述
      [root@master-kubeadm-k8s pod]# kubectl describe pod nginx-pod
      Name:               nginx-pod
      Namespace:          default
      Priority:           0
      PriorityClassName:  <none>
      Node:               worker01-kubeadm-k8s/10.0.2.15
      Start Time:         Fri, 27 Mar 2020 14:31:43 +0000
      Labels:             app=nginx
      Annotations:        cni.projectcalico.org/podIP: 192.168.14.5/32
                          kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},
      
      # ....省略....
      
      Events:
        Type    Reason     Age   From                           Message
        ----    ------     ----  ----                           -------
        Normal  Scheduled  28s   default-scheduler              Successfully assigned default/nginx-pod to worker01-kubeadm-k8s
        Normal  Pulling    26s   kubelet, worker01-kubeadm-k8s  Pulling image "nginx"
      
    • 測試

      # 訪問容器 ip, 成功訪問到了Nginx
      [root@master-kubeadm-k8s pod]# curl 192.168.14.4
      <!DOCTYPE html>
      <html>
      <head>
      <title>Welcome to nginx!</title>
      <style>
          body {
              width: 35em;
              margin: 0 auto;
              font-family: Tahoma, Verdana, Arial, sans-serif;
          }
      </style>
      </head>
      <body>
      <h1>Welcome to nginx!</h1>
      <p>If you see this page, the nginx web server is successfully installed and
      working. Further configuration is required.</p>
      
      <p>For online documentation and support please refer to
      <a >nginx.org</a>.<br/>
      Commercial support is available at
      <a >nginx.com</a>.</p>
      
      <p><em>Thank you for using nginx.</em></p>
      </body>
      </html>
      
    • 刪除 Pod

      [root@master-kubeadm-k8s pod]# kubectl delete -f pod_nginx.yaml
      pod "nginx-pod" deleted
      

      對于 Pod 的使用大概就是這些常用操作了,還有就是 Pod 的特性還需要在補充一下。

  • Storage and Networking

    • Networking

      每個Pod會被分配一個唯一的IP地址。Pod 中的每個容器共享網絡命名空間,包括IP地址和網絡端口。也就是說可以通過一個 IP 訪問到 Pod 中的不同容器。

    • Storage

      Pod可以指定一組共享存儲卷。Pod中的所有容器都可以訪問共享卷,從而允許這些容器共享數據。卷還允許 Pod 中的持久數據保留下來,以防其中的容器需要重新啟動。

2.2 Controller

2.2.1 ReplicationController
  • 理解 ReplicationController

    • ReplicationController 確保在任何時候都有特定數量的 pod 副本處于運行狀態。 換句話說,ReplicationController 確保一個 pod 或一組同類的 pod 總是可用的。再簡單點說即聲明某種Pod的副本數量在任意時刻都符合設定的預期值。
    • 所以RC的定義包含以下幾個部分:
      • 期待的 Pod 副本數(replicas)
      • 用于篩選目標Pod的 Label Selector
      • 當 Pod 的副本數量小于預期數量時,用于創建新 Pod 的 Pod 模板(template)

    ReplicationController 通常縮寫為 rc,并作為 kubectl 命令的快捷方式通過RC可以自動實現集群中 Pod 的高可用,減少了傳統IT環境中手工運維的工作。

  • 使用 ReplicationController

    • 創建 nginx_replication.yaml

      配置文件的說明現在只說明之前沒用過的,已經說明過的就不再重復了。

      apiVersion: v1
      kind: ReplicationController # 指定資源類型為 ReplicationController
      metadata:
        name: nginx
      spec:
        replicas: 3               # 指定 Pod 的副本數為 3
        selector:                 # 標簽選擇器,通過 selector 選取具有相同 label 的容器,這里表示包含 app: nginx的 label 的 Pod 都會被該 RC 管理
          app: nginx
        template:                 # 表示用于定義Pod的模板,比如Pod名稱、擁有的label以及Pod中運行的應用等,通過改變RC里Pod模板中的鏡像版本,可以實現Pod的升級功能
          metadata:               # 下面的配置就與配置 Pod 時一致了
            name: nginx
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx
              ports:
              - containerPort: 80
      
    • 創建 ReplicationController

      # 所有資源類型創建的方式都是一致的
      [root@master-kubeadm-k8s replicationController]# kubectl apply -f nginx_replication.yaml
      replicationcontroller/nginx created
      
    • 查詢 RC 信息

      # 查看 pod
      [root@master-kubeadm-k8s replicationController]# kubectl get pods
      NAME          READY   STATUS              RESTARTS   AGE
      nginx-22ctb   0/1     ContainerCreating   0          72s
      nginx-7jvb5   1/1     Running             0          72s
      nginx-qbtz4   0/1     ContainerCreating   0          72s
      
      # 查看 Pod 的詳情
      [root@master-kubeadm-k8s replicationController]# kubectl get pods -o wide
      NAME          READY   STATUS    RESTARTS   AGE     IP               NODE                   NOMINATED NODE   READINESS GATES
      nginx-22ctb   1/1     Running   0          4m37s   192.168.221.68   worker02-kubeadm-k8s   <none>           <none>
      nginx-7jvb5   1/1     Running   0          4m37s   192.168.221.67   worker02-kubeadm-k8s   <none>           <none>
      nginx-qbtz4   1/1     Running   0          4m37s   192.168.14.6     worker01-kubeadm-k8s   <none>           <none>
      
      # 通過查看 rc 也可以查看
      [root@master-kubeadm-k8s replicationController]# kubectl get rc
      NAME    DESIRED   CURRENT   READY   AGE
      nginx   3         3         2       85s
      
      # 也可以查看 rc 詳情
      [root@master-kubeadm-k8s replicationController]# kubectl get rc -o wide
      NAME    DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES   SELECTOR
      nginx   3         3         3       2m23s   nginx        nginx    app=nginx
      
      # 同樣的 describe 也是可以查看的
      [root@master-kubeadm-k8s replicationController]# kubectl describe rc nginx
      Name:         nginx
      Namespace:    default
      Selector:     app=nginx
      Labels:       app=nginx
      Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"v1","kind":"ReplicationController","metadata":{"annotations":{},"name":"nginx","namespace":"default"},"spec":{"replicas":3,...
      Replicas:     3 current / 3 desired
      Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
      Pod Template:
        Labels:  app=nginx
        Containers:
         nginx:
          Image:        nginx
          Port:         80/TCP
          Host Port:    0/TCP
          Environment:  <none>
          Mounts:       <none>
        Volumes:        <none>
      Events:
        Type    Reason            Age    From                    Message
        ----    ------            ----   ----                    -------
        Normal  SuccessfulCreate  3m41s  replication-controller  Created pod: nginx-7jvb5
        Normal  SuccessfulCreate  3m41s  replication-controller  Created pod: nginx-qbtz4
        Normal  SuccessfulCreate  3m41s  replication-controller  Created pod: nginx-22ctb
      
    • 測試高可用

      • 嘗試刪除其中一個 Pod

        [root@master-kubeadm-k8s replicationController]# kubectl delete pods nginx-22ctb
        pod "nginx-22ctb" deleted
        
        # 查看 Pod,發現還是有 3 個 Pod
        # 其實 "nginx-22ctb" 這個 Pod 已經刪除了,但是 RC 自身有高可用的特性,又自動幫我們創建了一個新的 Pod
        [root@master-kubeadm-k8s replicationController]# kubectl get pods -o wide
        NAME          READY   STATUS    RESTARTS   AGE     IP               NODE                   NOMINATED NODE   READINESS GATES
        nginx-5nw6m   1/1     Running   0          58s     192.168.14.7     worker01-kubeadm-k8s   <none>           <none>
        nginx-7jvb5   1/1     Running   0          7m45s   192.168.221.67   worker02-kubeadm-k8s   <none>           <none>
        nginx-qbtz4   1/1     Running   0          7m45s   192.168.14.6     worker01-kubeadm-k8s   <none>           <none>
        
      • 對 pod 進行擴縮容

        # 將 nginx 這個 rc 擴容為 5
        [root@master-kubeadm-k8s replicationController]# kubectl scale rc nginx --replicas=5
        replicationcontroller/nginx scaled
        
        # 查看 Pod,發現已經新增了 2 個正在創建中的 Pod 了
        [root@master-kubeadm-k8s replicationController]# kubectl get pods
        NAME          READY   STATUS              RESTARTS   AGE
        nginx-5nw6m   1/1     Running             0          3m14s
        nginx-7jvb5   1/1     Running             0          10m
        nginx-bfhp4   0/1     ContainerCreating   0          6s
        nginx-qbtz4   1/1     Running             0          10m
        nginx-wrhbf   0/1     ContainerCreating   0          6s
        
    • 測試

      # 任意一個 ip 都是可以正常訪問的
      [root@master-kubeadm-k8s replicationController]# curl 192.168.221.67
      <!DOCTYPE html>
      <html>
      <head>
      <title>Welcome to nginx!</title>
      <style>
          body {
              width: 35em;
              margin: 0 auto;
              font-family: Tahoma, Verdana, Arial, sans-serif;
          }
      </style>
      </head>
      <body>
      <h1>Welcome to nginx!</h1>
      <p>If you see this page, the nginx web server is successfully installed and
      working. Further configuration is required.</p>
      
      <p>For online documentation and support please refer to
      <a >nginx.org</a>.<br/>
      Commercial support is available at
      <a >nginx.com</a>.</p>
      
      <p><em>Thank you for using nginx.</em></p>
      </body>
      </html>
      
    • 刪除 RC

      [root@master-kubeadm-k8s replicationController]# kubectl delete -f nginx_replication.yaml
      replicationcontroller "nginx" deleted
      

    RC 現在已經不推薦使用了,但是還是要提一下的,官方為 RC 提供了 升級版本,就是 ReplicaSet

2.2.2 ReplicaSet
  • 理解 ReplicaSet

    • ReplicaSet 是下一代的 Replication Controller。 ReplicaSet 和 Replication Controller 的唯一區別是選擇器的支持。ReplicaSet 支持新的基于集合的選擇器(selector)需求,而 Replication Controller 僅支持基于相等選擇器的需求。
    • 簡單來說就是 RC 只能根據單個 label 進行選擇 Pod,而 RS 則可以選則多個 label。
    • 大多數支持 Replication Controllers 的 kubectl命令也支持 ReplicaSets。但 rolling-update 命令是個例外。如果想要滾動更新功能請考慮使用 Deployment。
    • 雖然 ReplicaSets 可以獨立使用,但今天它主要被 Deployments 用作協調 Pod 創建、刪除和更新的機制。 當使用 Deployment 時,不必擔心還要管理它們創建的 ReplicaSet。Deployment 會擁有并管理它們的 ReplicaSet。
  • 使用 ReplicaSet

    • 創建 nginx_rs.yaml 文件

      apiVersion: apps/v1     # 版本
      kind: ReplicaSet        # 定義資源的類型為 RS
      metadata:
        name: nginx-rs
        labels:               # 這里可以配置多個標簽
          app: guestbook
          podLabel: nginx-label
      spec:
        replicas: 3
        selector:
          matchLabels:        # 可以匹配多個標簽
            podLabel: nginx-label # 注意這里的標簽必須與template中定義的標簽一致,否則匹配不到
        template:
          metadata:
            labels:
              podLabel: nginx-label
          spec:
            containers:
            - name: nginx-pod
              image: nginx
      
    • 創建 ReplicaSet

      [root@master-kubeadm-k8s replicaSet]# kubectl apply -f nginx_rs.yaml
      replicaset.apps/nginx-rs created
      
    • 查看 ReplicaSet

      # 查看 Pod 都是通用的命令,不管使用哪種資源類型,都可以使用 get pods這些命令
      [root@master-kubeadm-k8s replicaSet]# kubectl get pods
      NAME             READY   STATUS              RESTARTS   AGE
      nginx-rs-b6fjz   1/1     Running             0          65s
      nginx-rs-dg4vj   1/1     Running             0          65s
      nginx-rs-fwkhd   0/1     ContainerCreating   0          66s
      
      # 與 RC 一樣, 無非就是 rc 換成了 rs
      [root@master-kubeadm-k8s replicaSet]# kubectl get rs
      NAME       DESIRED   CURRENT   READY   AGE
      nginx-rs   3         3         3       113s
      
      [root@master-kubeadm-k8s replicaSet]# kubectl get rs -o wide
      NAME       DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES   SELECTOR
      nginx-rs   3         3         3       2m27s   nginx-pod    nginx    podLabel=nginx-label
      ...
      
    • 刪除 ReplicaSet

      [root@master-kubeadm-k8s replicaSet]# kubectl delete -f nginx_rs.yaml
      replicaset.apps "nginx-rs" deleted
      

    ReplicaSet 與 ReplicationController 操作都是一致的,只有編寫 yaml 文件時 rs 可以選擇多個 label,那么其他功能就不再演示了。

    注意:一般情況下,我們很少單獨使用Replica Set,它主要是被 Deployment 這個更高的資源對象所使用,從而形成一整套Pod創建、刪除、更新的編排機制。當我們使用 Deployment 時,無須關心它是如何創建和維護ReplicaSet的,這一切都是自動發生的。同時,無需擔心跟其他機制的不兼容問題(比如ReplicaSet不支持 rolling-update 但 Deployment 支持)。

2.2.3 Deployment
  • 理解 Deployment

    • 一個 Deployment 控制器為 PodsReplicaSets 提供描述性的更新方式。
    • Deployment 控制器以受控速率更改實際狀態,以達到期望狀態。可以定義 Deployments 以創建新的 ReplicaSets ,或刪除現有 Deployments ,并通過新的 Deployments 使用其所有資源。
    • Deployment 是 K8S 中推薦使用的管理、編排容器的方式,它相比 RC 與 RS 最大的升級就是我們可以隨時知道當前 Pod 部署的進度,可以檢查 Deployment 的狀態來看部署是否完成。
  • 使用 Deployment

    • 創建 nginx_deployment.yaml

      基礎配置方面都與 RS 配置一模一樣, 除了修改資源類型為 Deployment

      apiVersion: apps/v1
      kind: Deployment            # 定義資源類型為 Deployment
      metadata:
        name: nginx-deployment
        labels:
          app: nginx
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx:1.7.9
              ports:
              - containerPort: 80
      
    • 創建 Deployment

      [root@master-kubeadm-k8s deployment]# kubectl apply -f nginx_deployment.yaml
      deployment.apps/nginx-deployment created
      
    • 查看 Deployment

      [root@master-kubeadm-k8s deployment]# kubectl get pods -o wide
      NAME                               READY   STATUS              RESTARTS   AGE   IP       NODE                   NOMINATED NODE   READINESS GATES
      nginx-deployment-6dd86d77d-fddx5   0/1     ContainerCreating   0          32s   <none>   worker01-kubeadm-k8s   <none>           <none>
      nginx-deployment-6dd86d77d-hcbsv   0/1     ContainerCreating   0          32s   <none>   worker02-kubeadm-k8s   <none>           <none>
      nginx-deployment-6dd86d77d-hrx2f   0/1     ContainerCreating   0          32s   <none>   worker02-kubeadm-k8s   <none>           <none>
      
      # 也可以查看 rs
      [root@master-kubeadm-k8s deployment]# kubectl get rs
      NAME                         DESIRED   CURRENT   READY   AGE
      nginx-deployment-6dd86d77d   3         3         2       79s
      
      # 查看 deployment 部署情況
      [root@master-kubeadm-k8s deployment]# kubectl get deployment
      NAME               READY   UP-TO-DATE   AVAILABLE   AGE
      nginx-deployment   0/3     3            0           53s
      
      # 查看 deployment 詳情
      [root@master-kubeadm-k8s deployment]# kubectl get deployment -o wide
      NAME               READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES        SELECTOR
      nginx-deployment   3/3     3            3           103s   nginx        nginx:1.7.9   app=nginx
      
    • 高級特性 rolling-update

      使用 Deployment 的好處之一就是我們可以通過 滾動更新 的方式去在線升級應用的版本

      # 查看當前nginx的版本, nginx我們是指定了使用 1.7.9 版本的
      [root@master-kubeadm-k8s deployment]# kubectl get deployment -o wide
      NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES        SELECTOR
      nginx-deployment   3/3     3            3           5m28s   nginx        nginx:1.7.9   app=nginx
      
      # 更新 nginx 的 image 版本
      [root@master-kubeadm-k8s deployment]# kubectl set image deployment nginx-deployment nginx=nginx:1.9.1
      deployment.extensions/nginx-deployment image updated
      
      # -w 監控當前 pod 變化情況
      # 可以發現它是為我們創建新的Pod,然后再慢慢停止之前舊版本的 Pod
      [root@master-kubeadm-k8s deployment]# kubectl get pods -w
      NAME                                READY   STATUS              RESTARTS   AGE
      nginx-deployment-6dd86d77d-fddx5    1/1     Running             0          9m58s
      nginx-deployment-6dd86d77d-hcbsv    1/1     Running             0          9m58s
      nginx-deployment-6dd86d77d-hrx2f    1/1     Running             0          9m58s
      nginx-deployment-784b7cc96d-fqzzp   0/1     ContainerCreating   0          30s
      
      nginx-deployment-784b7cc96d-fqzzp   1/1     Running             0          84s
      nginx-deployment-6dd86d77d-hcbsv    1/1     Terminating         0          10m
      nginx-deployment-784b7cc96d-xrdz6   0/1     Pending             0          0s
      nginx-deployment-784b7cc96d-xrdz6   0/1     Pending             0          0s
      nginx-deployment-784b7cc96d-xrdz6   0/1     ContainerCreating   0          0s
      nginx-deployment-784b7cc96d-xrdz6   0/1     ContainerCreating   0          1s
      nginx-deployment-6dd86d77d-hcbsv    0/1     Terminating         0          10m
      nginx-deployment-6dd86d77d-hcbsv    0/1     Terminating         0          11m
      nginx-deployment-6dd86d77d-hcbsv    0/1     Terminating         0          11m
      
      # ...省略...
      
      # 最終還是會保持 3 個 replicas 運行
      nginx-deployment-784b7cc96d-d6rdn   1/1     Running   0          87s
      nginx-deployment-784b7cc96d-fqzzp   1/1     Running   0          4m10s
      nginx-deployment-784b7cc96d-xrdz6   1/1     Running   0          2m46s
      
      # 再次查看詳情,發現nginx的版本已經更新為 1.9.1 了
      [root@master-kubeadm-k8s deployment]# kubectl get deployment -o wide
      NAME               READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES        SELECTOR
      nginx-deployment   3/3     3            3           14m   nginx        nginx:1.9.1   app=nginx
      
      • Deployment 可確保在更新時僅關閉一定數量的 Pods。默認情況下,它確保至少 75%所需 Pods 運行(25%最大不可用)。
      • Deployment 還確保僅創建一定數量的 Pods 高于期望的 Pods 數。默認情況下,它可確保最多增加 25% 期望 Pods 數(25%最大增量)。
      • 如果仔細查看上述 Deployment ,將看到它首先創建了一個新的 Pod,然后刪除了一些舊的 Pods,并創建了新的 Pods。它不會殺死老 Pods,直到有足夠的數量新的 Pods 已經出現,并沒有創造新的 Pods,直到足夠數量的舊 Pods 被殺死。它確保至少 2 個 Pods 可用,并且總共最多 4 個 Pods 可用。

    控制器的幾個組件就簡單介紹到這里,其他命令與常用操作將會在后續章節慢慢的展開。

2.2.4 Labels and Selectors

在前面的 YAML 文件中,看到很多 label,顧名思義,就是給一些資源打上標簽的。

  • 理解 Labels

    • 標簽 是附加到 Kubernetes 對象(比如 Pods)上的鍵值對。
    • 標簽旨在用于指定對用戶有意義且相關的對象的標識屬性,但不直接對核心系統有語義含義。
    • 標簽可以用于組織和選擇對象的子集。
    • 標簽可以在創建時附加到對象,隨后可以隨時添加和修改。
    • 每個對象都可以定義一組鍵/值標簽。每個鍵對于給定對象必須是唯一的。
  • 案例說明

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-pod
      labels:
        app: nginx
    

    表示名稱為 nginx-pod 的 pod,有一個label,key為app,value為 nginx。

    我們可以將具有同一個 label 的 pod,交給 selector 管理

  • selector

    selector 是選取具有同一個 label 的pod進行管理,相同 label 的Pod就是抽象層面的 Service

    • 案例說明

      apiVersion: apps/v1
      kind: Deployment
      metadata: 
        name: nginx-deployment
        labels:
          app: nginx
      spec:
        replicas: 3
        selector:             # 匹配具有同一個label屬性的pod標簽
          matchLabels:
            app: nginx         
        template:             # 定義pod的模板
          metadata:
            labels:
              app: nginx      # 定義當前pod的label屬性,app為key,value為nginx
          spec:
            containers:
            - name: nginx
              image: nginx:1.7.9
              ports:
              - containerPort: 80
      

      如果 selector 匹配不到 label,運行將會報錯

      將 上面 yaml文件中的 selector 匹配的標簽改個名字:app: nginx1

      # 報錯了,找不到匹配的標簽
      [root@master-kubeadm-k8s deployment]# kubectl apply -f nginx_deployment.yaml
      The Deployment "nginx-deployment" is invalid: spec.template.metadata.labels: Invalid value: map[string]string{"app":"nginx"}: `selector` does not match template `labels`
      
    • 查看pod的 label 標簽

      [root@master-kubeadm-k8s deployment]# kubectl get pods --show-labels
      NAME                                READY   STATUS    RESTARTS   AGE   LABELS
      nginx-deployment-784b7cc96d-d6rdn   1/1     Running   0          14m   app=nginx,pod-template-hash=784b7cc96d
      nginx-deployment-784b7cc96d-fqzzp   1/1     Running   0          17m   app=nginx,pod-template-hash=784b7cc96d
      nginx-deployment-784b7cc96d-xrdz6   1/1     Running   0          16m   app=nginx,pod-template-hash=784b7cc96d
      

3、Namespace

  • 理解 Namespace

    • Kubernetes 支持多個虛擬集群,它們底層依賴于同一個物理集群。 這些虛擬集群被稱為命名空間。
    • 命名空間適用于存在很多跨多個團隊或項目的用戶的場景。對于只有幾到幾十個用戶的集群,根本不需要創建或考慮命名空間。
    • 命名空間為名稱提供了一個范圍。資源的名稱需要在命名空間內是唯一的,但不能跨命名空間。命名空間不能相互嵌套,每個 Kubernetes 資源只能在一個命名空間中。
    • 命名空間是在多個用戶之間劃分集群資源的一種方法。
    • 簡單來說,Namespace 就是用來做資源隔離的。
  • 使用 Namespace

    • 查看

      # 在不指定命名空間的時候,K8S是默認從 default 命名空間查詢 Pod
      # 當前還沒有在 default 命名空間創建資源, 所以是空的
      [root@master-kubeadm-k8s deployment]# kubectl get pods
      No resources found.
          
      # 通過 -n kube-system 查看 K8S 系統命名空間
      # 這里是運行 K8S 所需的一些資源
      [root@master-kubeadm-k8s deployment]# kubectl get pods -n kube-system
      NAME                                         READY   STATUS    RESTARTS   AGE
      calico-kube-controllers-99f457df4-q7jlb      1/1     Running   2          3d15h
      calico-node-hbwbd                            1/1     Running   2          3d15h
      calico-node-pftqd                            1/1     Running   2          3d15h
      calico-node-tdspb                            1/1     Running   2          3d15h
      coredns-fb8b8dccf-gwqj9                      1/1     Running   2          3d16h
      coredns-fb8b8dccf-lj92j                      1/1     Running   2          3d16h
      etcd-master-kubeadm-k8s                      1/1     Running   2          3d16h
      kube-apiserver-master-kubeadm-k8s            1/1     Running   2          3d16h
      kube-controller-manager-master-kubeadm-k8s   1/1     Running   2          3d16h
      kube-proxy-9sxk6                             1/1     Running   2          3d15h
      kube-proxy-hh6hx                             1/1     Running   2          3d15h
      kube-proxy-hhnmc                             1/1     Running   2          3d16h
      kube-scheduler-master-kubeadm-k8s            1/1     Running   2          3d16h
      
      # 列出集群中現存的命名空間
      [root@master-kubeadm-k8s deployment]# kubectl get namespaces
      NAME              STATUS   AGE
      default           Active   3d16h
      kube-node-lease   Active   3d16h
      kube-public       Active   3d16h
      kube-system       Active   3d16h
      
      # default   沒有指明使用其它命名空間的對象所使用的默認命名空間
      # kube-node-lease  這個官方沒有文檔說明,只知道是與心跳相關的
      # kube-system   Kubernetes系統創建對象所使用的命名空間
      # kube-public 
          # 這個命名空間是自動創建的,所有用戶(包括未經過身份驗證的用戶)都可以讀取它。
          # 這個命名空間主要用于集群使用,以防某些資源在整個集群中應該是可見和可讀的。
      

      其實說白了,命名空間就是為了隔離不同的資源,比如:Pod、Service、Deployment等。可以在輸入命令的時候指定命名空間 -n,如果不指定,則使用默認的命名空間:default。

    • 創建 Namespace

      • 一、YAML方式

        apiVersion: v1
        kind: Namespace   # 指定資源類型為 Namespace
        metadata:
          name: my-namespace-1
        
        # YAML方式創建命名空間
        [root@master-kubeadm-k8s namespace]# kubectl apply -f namespace.yaml
        namespace/my-namespace-1 created
        
        # 查看命名空間,可以看到新創建的 Namespace
        [root@master-kubeadm-k8s namespace]# kubectl get namespaces
        NAME              STATUS   AGE
        default           Active   3d16h
        kube-node-lease   Active   3d16h
        kube-public       Active   3d16h
        kube-system       Active   3d16h
        my-namespace-1    Active   12s
        
+ 二、命令方式

  ```ruby
  # 命令方式創建命名空間
  [root@master-kubeadm-k8s namespace]# kubectl create namespace my-namespace-2
  namespace/my-namespace-2 created
  
  # 同樣也可以查看到新創建的命名空間
  [root@master-kubeadm-k8s namespace]# kubectl get namespaces
  NAME              STATUS   AGE
  default           Active   3d16h
  kube-node-lease   Active   3d16h
  kube-public       Active   3d16h
  kube-system       Active   3d16h
  my-namespace-1    Active   66s
  my-namespace-2    Active   3s
  ```

> **注意:**Namespace名稱必須由小寫字母數字字符或“-”組成,并且必須以字母數字字符(例如“ my-name”或“ 123-abc”)開頭和結尾,用于驗證的正則表達式為“ [a- z0-9]([-a-z0-9] * [a-z0-9])') 
  • 使用 Namespace

    • 創建資源指定命名空間

      apiVersion: v1
      kind: Pod
      metadata:
        name: nginx-pod
        namespace: my-namespace-1   # 指定命名空間
      spec:
        containers:
        - name: nginx-container
          image: nginx
          ports:
          - containerPort: 80
      
      # 創建 Pod
      [root@master-kubeadm-k8s namespace]# kubectl apply -f nginx-ns.yaml
      pod/nginx-pod created
      
    • 查看 Pod

      # 沒有? 別忘了 Namespace 是資源隔離的,我們是指定了資源創建在哪個命名空間的
      # 這里默認是查詢 default 命名空間,所以肯定是查不到的
      [root@master-kubeadm-k8s namespace]# kubectl get pods
      No resources found.
      
      # 通過 -n 指定我們創建的 Namespace 就可以查看到剛才創建的 Pod 了
      [root@master-kubeadm-k8s namespace]# kubectl get pods -n my-namespace-1
      NAME        READY   STATUS    RESTARTS   AGE
      nginx-pod   1/1     Running   0          111s
      
      # 通過 --all-namespaces 參數可以查詢所有命名空間下的 Pod
      [root@master-kubeadm-k8s namespace]# kubectl get pods --all-namespaces
      NAMESPACE        NAME                                         READY   STATUS    RESTARTS   AGE
      kube-system      calico-kube-controllers-99f457df4-q7jlb      1/1     Running   2          3d15h
      kube-system      calico-node-hbwbd                            1/1     Running   2          3d15h
      kube-system      calico-node-pftqd                            1/1     Running   2          3d15h
      kube-system      calico-node-tdspb                            1/1     Running   2          3d15h
      kube-system      coredns-fb8b8dccf-gwqj9                      1/1     Running   2          3d16h
      kube-system      coredns-fb8b8dccf-lj92j                      1/1     Running   2          3d16h
      kube-system      etcd-master-kubeadm-k8s                      1/1     Running   2          3d16h
      kube-system      kube-apiserver-master-kubeadm-k8s            1/1     Running   2          3d16h
      kube-system      kube-controller-manager-master-kubeadm-k8s   1/1     Running   2          3d16h
      kube-system      kube-proxy-9sxk6                             1/1     Running   2          3d15h
      kube-system      kube-proxy-hh6hx                             1/1     Running   2          3d15h
      kube-system      kube-proxy-hhnmc                             1/1     Running   2          3d16h
      kube-system      kube-scheduler-master-kubeadm-k8s            1/1     Running   2          3d16h
      my-namespace-1   nginx-pod                                    1/1     Running   0          3m10s
      
  • 刪除 Namespace

    [root@master-kubeadm-k8s namespace]# kubectl delete namespaces  my-namespace-1
    namespace "my-namespace-1" deleted
    

    注意:刪除命名空間會刪除命名空間下的 所有內容

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容