iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 4
1
DevOps

從題目中學習k8s系列 第 4

【從題目中學習k8s】-【Day4】K8s中的resource object(一) - Pod、Deployment


title: 【從題目中學習k8s】-【Day4】K8s中的resource object(一) - Pod、Deployment
description: 以無比的恆毅力堅持30天鍊成鐵人--連續30天,一天發表一篇IT技術文章

【從題目中學習k8s】-【Day4】K8s中的resource object(一) - Pod、Deployment

tags: DevOps CICD K8s Docker

前言

今天我們開始進入 K8s 元件的介紹,筆者想說還是先介紹一些基本的東東,但是會盡量focus在一些比較不容易注意到的事,那就開始吧~


Pod

K8s 中有一點是非常重要的,那就是我們無法直接對Container操作,我們只能操作PodPod是在 K8s 中能創建和操作的最小單位。

一個image被run成ConatinerPod運行這個ContainerNode


Pod的YAML範例如下:

$ vim pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx

創建這個Pod可以透過kubectl命令:

$ kubectl apply -f pod.yaml
## or
$ kubectl create -f pod.yaml

kubectl create v.s. kubectl apply
kubectl create :

  1. kubectl create是所謂的"命令式管理"(Imperative Management)。通過這種方法,可以告訴Kubernetes API你要創建,替換或刪除的內容。
  2. kubectl create命令,是先刪除所有現有的東西,重新根據YAML文件生成新的。所以要求YAML文件中的配置必須是完整的
  3. kubectl create命令,用同一個YAML文件重複創建會失敗。

kubectl apply :

  1. kubectl apply是"聲明式管理"(Declarative Management)方法的一部分,在該方法中,即使對目標用了其他更改,也可以"保持"你對目標(即按比例縮放)應用的更改。
  2. kubectl apply命令,根據配置文件裡面列出来的内容,生及現有的。所以YAML文件的内容可以只寫需要升级的欄位

簡單理解就是,kubectl apply可以重複創建;kubectl create只能創建一次

Pod相關指令如下(這些先列舉一些,更詳細的會在之後幾天的【K8s常用指令&Cheat Sheet】主題作介紹)

## 創建po
$ kubectl apply -f pod.yaml
$ kubectl create -f pod.yaml
$ kubectl run po <pod-name> --image=<image-name> --restart=Never --dry-run=client

## 查看現有pod
$ kubectl get po

## 查看該pod詳細資訊
$ kubectl describe po <pod-name>

## 刪除pod
$ kubectl delete po

## 查看pod log
$ kubectl logs <pod-name>

Pod QoS

因為Pod QoS跟資源配置有關,一般教學文章可能會省略這邊,但考試還滿常出現的,所以特別拉出一個QoS的主題來介紹~
Kubernetes 創建一個 Pod 時,它會给 Pod 分配一個 QoS 等級,分為:

  • Guaranteed
  • Burstable
  • BestEffort

Guaranteed

要给 Pod 分配 QoS 等級為 Guaranteed:

  • Pod 裡的每個Container都必須有memory limit和request,而且必須是一樣的。
  • Pod 裡的每個Container都必須有CPU limit和request,而且必須是一樣的。

創建一個Pod

$ kubectl run nginx --image=nginx --limits cpu=1,memory=200Mi --restart=Never --dry-run=client -o yaml > pod.yaml
$ kubectl apply -f pod.yaml

查看Pod訊息

$ kubectl describe po nginx 
...
    Limits:
      cpu:     1
      memory:  200Mi
    Requests:
      cpu:        1
      memory:     200Mi
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-68jm7 (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-68jm7:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-68jm7
    Optional:    false
QoS Class:       Guaranteed
...

最後一行顯示QoSGuaranteed等級,且limit=request

如果一個容器配置了cpu/memory limit,但是没有配置cpu/memory request,那 Kubernetes 會自動给容器分配一個符合cpu/memory limit的request。也就是說,其實K8sPod提供的預設QoS等級是Guaranteed


Burstable

要给 Pod 分配 QoS 等級為 Burstable:

  • Pod 不滿足 QoS 等级 Guaranteed 的要求。
  • Pod 裡至少有一個容器有memory或CPU request。

例子 1 :

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-2
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-2-ctr
    image: nginx
    resources:
      limits:
        memory: "200Mi"
      requests:
        memory: "100Mi"

例子 2

一個含有两個容器的 Pod 的配置文件,其中一個容器指定了memory request為 200MB ,另外一個沒有任何request或limit。

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-4
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-4-ctr-1
    image: nginx
    resources:
      requests:
        memory: "200Mi"

  - name: qos-demo-4-ctr-2
    image: redis

注意到這個 Pod 滿足了 QoS 等級為 Burstable 的要求。即,不滿足 Guaranteed 的要求,而且其中一個容器有memory request。


BestEffort

要给 Pod 分配 QoS 等級為 BestEffort:

  • Pod 裡的容器必須沒有任何memory或者 CPU 的limit或request。

例如 :

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-3
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-3-ctr
    image: nginx

Pod Scaling

當越來越多使用者存取Pod時,會讓Pod負擔增高,這時K8s會啟動Scaling的機制,幫忙分擔大量的服務需求。有兩種可能的Scaling方式:

  1. 在同個Pod內增加一個一樣Container
  2. 增加一個一樣的Pod,包含裡面的Container

大家覺得哪種方法比較好呢?

K8s採用的方法是 第2種: 增加一個一樣的Pod,包含裡面的Container啦~

看到這你可能會想,是不是一個Pod內只能有一個Container?其實不然,一個Pod可以由一個或多個Conatiner組成,但是在同個Pod內的Container,通常彼此之間有緊密的關係,會互相搭配使用
舉例來說,一個Web Application會需要一個主要的Web Server,其他輔助的像是Database、使用者輸入、檔案處理和身分驗證等等的,我們會將這些都拆分成一個個Container,包在同一個Pod內。我們稱這些輔助型ContainerHelper Containers,這個Pod則稱為Multi-Container Pod

Deployment

前面提到Pod Scaling的策略,那麼這個策略是怎麼做到的呢?今天當我們要把一個 Pod 做橫向擴展,也就是複製多個相同的 PodCluster 中同時提供服務,並監控若有 Pod 當機就需重新啟動。如果我們要一個 Pod 一個 Pod 透過指令建立並監控是很花時間的。因此,Deployment 這個特殊元件就是用來幫我們達成上述的要求。

Deployment最主要的功能之一就是自動佈署一個容器應用的多份備份,以及持續監控備份的數量,在集群內始終維持使用者指定的備份數量

當我們說一個Application時,其實指的就是一個Deployment

Deployment範例YAML檔 :

$ vim deploy.yaml

apiVersion: apps/v1
kind: 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.14.2
        ports:
        - containerPort: 80

我們看一下spce裡的information

  • replicas
    指定要建立多少個相同的 Pod,在這邊給的數字是所謂的 Desire State,當 Cluster 運行時如果 Pod 數量低於此數字,Kubernetes 就會自動幫我們增加 Pod,反之就會幫我們關掉 Pod,若有 Pod 故障,也會自動刪除此 Pod,並新增一個新的。(是不是很神奇阿~)
  • template
    指定這個 Deployment 所建立的 Pod 的設定,重建後的 Pod 也依此設定重建。可直接將 Pod YAML內metadataspec的欄位資料貼上就行了
  • selector
    指定這個 Deployment 的規則要適用到哪些 Pod,可依據 Podlabel來選取

Deployment創建後,會同步創建ReplcaSetPod,他們的關係是這樣

Deployment 的另外一個好處就是系統無縫更新,當 Pod 需要更新時,Kubernetes 不會直接砍掉我們所有的 Pod,而是會先建立新的 Pod,該 Pod 開始正常運行後,才會刪除舊的 Pod,如此就可達到無停機的系統升級(Zero Downtime Rollout)。

可參考這篇教學。


結論

今天我們開始介紹 K8s 中的 resource-object ,介紹了最小運行單元 Pod,以及 PodQoS ,筆者覺得這部分還滿重要的,考試也經常看到此類題型,因此特別拉出來介紹;也介紹了經常用到的 Deployment,跳過了Replication ControllerReplicaSet,主要是因為篇幅不夠,而這兩者又通常和 Deployment 一同使用,所以筆者就只介紹 Deployment。好啦,今天就到這囉~ 謝謝大家~


參考資料

Kubernetes 基礎教學(二)實作範例
Zero-downtime Deployment in Kubernetes with Jenkins
What are Pods in Kubernetes?

Thank you!

You can find me on

  • george4908090@gmail.com

上一篇
【從題目中學習k8s】-【Day3】建立K8s Cluster環境-以kubeadm為例
下一篇
【從題目中學習k8s】-【Day5】K8s中的resource object(二) - Service
系列文
從題目中學習k8s31

尚未有邦友留言

立即登入留言