一開始接觸Kubernetes(以下簡稱K8s)時心裡有很多聲音:「它到底是什麼、它可以運用在什麼地方、它可以改變些什麼」,這些聲音持續的環繞在我腦中好久一直揮之不去XD,直到我真正開始使用管理Docker容器和執行Azure DevOps CI/CD時遇到了一些問題:

  1. 當測試/部署機數量多時每臺機子都要執行Docker指令
  2. Docker run之後如果容器壞掉了,他並不會自己重啟
  3. Docker-Compose雖然可以管理容器的關聯性,但是啟動後其中一個容器需要更新、壞掉或當掉時在更新或重啟的過程非常的麻煩(而且要記一堆指令XD)
  4. 呼應第一點就算把更新事宜套在Azure DevOps CI/CD做自動化時還是避免不了要先幫每臺機子設定代理程式集區,另外在每臺測試/部署機上都執行Docker命令在測試/部署就會花上很多時間

於是再重新看了一次K8s的教學才恍然大悟,它竟然解決了我以上的所有問題:

  1. 在K8s上我只需要執行一次指令(這裡指令是指Kubectl不是Docker指令)
  2. 容器壞了K8s自動幫我重新啟動(保持理想狀態)
  3. 添加/刪除/更新時只需要修改一下yaml檔案下指令套用後K8s自動幫我添加/刪除/更新容器
  4. 到了Azure DevOps CI/CD我只需要針對Cluster的主要節點下指令即可更新所有的測試/部署機子

其實K8s就是用來管理和調度的工具,它解決了Docker在以下方面的問題:

  1. 自動化管理和調度:K8s可以自動管理和調度容器,包括容器的運行、擴展和縮小、健康檢查和故障恢復等。這大大簡化了容器的管理和調度工作。
  2. 網絡和存儲管理:K8s提供了對容器網絡和存儲的統一管理,使容器之間的通信和存儲變得更加簡單和可靠。
  3. 可擴展性:K8s可以擴展到數千個節點和容器,而不會影響系統的穩定性和可靠性。這使得它成為一個可靠的分散式系統管理平台。
這篇我就簡單介紹K8s主要的構成和資源,其餘細部的內容官網也都寫的很清楚,如果有興趣可以自行到官網看看哦!



Cluster叢集

整個K8s組成就叫做Cluster,是由一個或多個主機組成的集合,這些主機可以是實體機器、虛擬機或雲端,其餘還有etcd等等的元件

實體機上的K8s則會看到一個主要節點和數個工作節點

如果使用的是Docker Desktop Kubernetes則只會看到一個主要節點
💡 Docker Desktop的Kubernetes使用的是單節點K8s叢集,並且採用了minikube驅動程序,因此只有一個主要節點

主要節點

主要節點不會運行容器,它只負責管理容器和資源的調度控管,另外在維運時管理員也是在這下指令進行調度和控管的哦!以下是主要節點的Control Plane Component幾個重要組建:
  1. kube-apiserver:Node之間溝通的管道也會根據kubectl的命令執行動作
  2. kube-controller-manager:統籌管理、執行(監控Node、管理Pod的數量…等)的控制器
  3. kube-scheduler:Pod的分派和調度管理
  4. etcd:儲存管理定義檔的資料庫

工作節點

會依據Control Plane Component的調度來運行相對應的結果,以下是工作節點幾個重要組建:
  1. kubelet:與Control Plan Component的kube-scheduler互動,管理、配置、監視Node上的Pod並且定期通知kube-scheduler
  2. kube-proxy:網路通訊路由機制實作了部分K8s Service的功能



K8s主要資源

主要資源(Resource Object)是用來表示目前Cluster的各種物件,如 Pod、Service、Deployment 等特定狀態規則和行為,譬如說:

  1. 我需要執行什麼樣的容器
  2. 運作時的狀態對應的行為,如容器重啟政策、容器更新的升降版、滾動政策等
  3. 自定義網路規則,如負載均衡和路由規則等

另外K8s的資源有很多(大約有50種)而且還有分很多種類,所以接著我會介紹4個初學者一定要會且實戰上也很長用到資源,如果想瞭解其它資源則可以自行去官網看【點我前往】。


Workloads - Pod:

為Node上的最小單位,Pod裡面可以運行多個容器而多個容器的資源是共享的,如storage和network,因此Pod內部是可以使用local port來進行溝通,因此我通常會讓有相關聯的容器寫在一起譬如:前後Web Application + 後端API Server + DataBase Server,不過在實戰時基本上是不會單獨撰寫Pod的yaml檔案哦!
apiVersion: v1
kind: Pod
metadata:
  name: "myapp"
  namespace: default
  labels:
    app: "myapp"
spec:
  containers:
  - name: myapp
    image: "debian-slim:latest"
    resources:
      limits:
        cpu: 200m
        memory: 500Mi
      requests:
        cpu: 100m
        memory: 200Mi
    ports:
    - containerPort: 80
      name: http
  restartPolicy: Always

Workloads - ReplicaSet(Replication Controller 進化版):

用於管理 Pod 副本數量的控制器。ReplicaSet 可以確保指定數量的 Pod 副本在 Kubernetes 叢集中運行,並根據需要進行自動擴展或縮小。它是Replication Controller的進化版,兩者的差異就是ReplicaSet可以被不同的label selector支援,另外ReplicaSet跟Pod一樣都不會單獨撰寫,而且官方也是推薦搭配Deployment一起使用

Workloads - Deployment:

用於管理應用程式的部署和升級。Deployment 可以讓用戶以聲明式的方式定義應用程式的期望狀態,如 Pod 的副本數量、容器鏡像、更新策略等。Deployment 控制器會根據定義的期望狀態,創建和管理 ReplicaSet,並在需要時進行滾動升級或回滾,另外它其實就是Pod和ReplicaSet的合體哦!
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myjob
  namespace: default
  labels:
    app: myjob
spec:
  selector:
    matchLabels:
      app: myjob
  replicas: 1
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: myjob
    spec:
      containers:
      - name: myapp
        image: "debian-slim:latest"
        resources:
          limits:
            cpu: 200m
            memory: 500Mi
          requests:
            cpu: 100m
            memory: 200Mi
        ports:
        - containerPort: 80
          name: http
      restartPolicy: Always

Services - Service:

Service資源被用來設定Pod的對外共通接口、負責不同Pod之間的溝通另外還有負載平衡的功能,比較特別是他和上方的Pod、ReplicatSet、Deployment被歸類在不同的Resource Object類型,不同的Pod、ReplicatSet、Deployment本身是無法在內部的Cluster之間互相存取因此需要使用Service搭建它們溝通的橋樑,另外若是要透過外部網路存取也是透過Service的設定來與外部網路做溝通的
apiVersion: v1
kind: Service
metadata:
  name: myjob
  namespace: default
spec:
  selector:
    app: myjob
  type: ClusterIP
  ports:
  - name: myjob
    protocol: TCP
    port: 80
    targetPort: 5000
    nodePort: 30001

Configuration - ConfigMaps

用於存儲應用程式配置數據的資源對象。ConfigMap 可以將配置數據從應用程式代碼中分離出來,從而實現配置和代碼的分離。我們可以在不修改應用程式代碼的情況下修改配置數據,從而實現對應用程式的動態配置
apiVersion: v1
kind: ConfigMap
metadata:
  name: registry-config
  namespace: wad-k8s
data:
  config.yml: |-
    version: 0.1
    log:
      level: error
      formatter: json
    storage:
      delete:
        enabled: true    
      cache:
        layerinfo: inmemory
      filesystem:
        rootdirectory: /var/lib/registry
    http:
      addr: :5000
      headers:
        X-Content-Type-Options: [nosniff]
        Access-Control-Allow-Origin: ['你的registryUI的URL']
        Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']
        Access-Control-Allow-Headers: ['Authorization', 'Accept']
        Access-Control-Max-Age: [1728000]
        Access-Control-Allow-Credentials: [true]
        Access-Control-Expose-Headers: ['Docker-Content-Digest']



K8s定義檔格式

定義檔是以資源為單位編寫的yaml檔案,K8s會依照定義檔的內容去建立所有的容器和規則,寫好的定義檔上傳到K8s之後會依照其內容將理想狀態」寫入etcd資料庫,最後所有工作節點會依照這個理想去維持伺服器的狀態,定義檔案的大項目基本格式為以下:
apiVersion: apps/v1
kind: xxxx
metadata: xxxx
spec: xxxx
  • apiVersion:資源的版本號
  • kind:資源的種類
  • metadata:元資料
  • spec:資源內容
定義檔可以依照資源選擇分開撰寫或是合在一起寫,就看每個人的習慣而定
💡 合在一起寫的話會使用 --- ←來區隔資源
編寫定義檔時使用VSCode」它可以安裝保哥的擴充套件【點我前往】讓編寫的速度快很多哦!



操作K8s

上面介紹了Cluster的組成也知道管理員控制是由主要節點去執行,接下來就是介紹如何與K8s互動,總共有三種溝通方式

kubectl:

透過命令的方式來操作主要節點,它是一個二進位的工具,最常見、最常用、初學時常常看到他、管理員必學XD,使用minikube和Docker Desktop Kubernetes時會自動安裝好,打開命令列直接下kubectl的命令即可,如果是在Linux伺服器上則是需要額外安裝

APIs:

K8s提供RESTful APIs的方式針對資源做新增修改刪除等等,我們可以在自己的應用程式上編寫客製的控制方式來操作APIs,算是一個彈性很大的一個功能,相關技術和使用方式可以參考官方網站【點我前往

Dashboard:

Dashboard則是如果很懶的記命令又很不想要自己寫UI用APIs操作,那麼Dashboard就是你的福音了XD,K8s提供Dashboard網頁用戶介面讓你不用下指令!不用操作APIs直接在Dashboard網頁上就操作是不是很方便!不過我自己是沒有用過拉XD,如果有興趣的可以看官網的介紹【點我前往


以上就是K8s的基礎介紹,由於有太多細部的東西多到文章會打不完而我自己也會吸收不完XD畢竟整個K8s可說是水很深呢!
這篇介紹的基礎都只是整個K8s的冰山一腳XD