使用 Helm 管理 Kubernetes 資源 - ianchen0119/Introduce-to-5GC GitHub Wiki

如果讀者有使用 Kubernetes 部署服務的經驗,那麼或多或少都會遇到一個問題:當 Service 增長到一定數量,管理與部署 Kubernetes 的資源會變得很麻煩。 舉例來說:

  • 如果要部署多個 Pod 會需要維護 Deployment 設定檔
  • 如果有流量導向的需求,需要維護 Service 設定檔
  • 如果有服務對外的需求,可能還需要維護 ingress 的設定檔

因此,當服務的數量到達一定門檻,每一次的整合與部署都是一種痛! 為了解決這個問題,開源社群發起了 Helm 專案幫助使用者更加便利的管理 Kubernetes 資源。

Helm 介紹

image

前面有提到,Helm 是用於管理 Kubernetes 應用程式的解決方案,從應用程式的定義、安裝到部署,甚至是升級,開發者都可以使用 Helm 做到。

作者的話:Helm 與 Kubernetes、Prometheus 等專案都是從 CNCF 畢業的喔!

Helm 設計概念

對於 Helm 來說,每一個應用程式都是一個 Chart,每一個 Chart 都至少包含了:

  • Kubernetes 設定檔(模板)
  • Chart 的資訊(版本、解說與參數設定)

Helm 透過將 Kubernetes 設定檔模板化的方式,在部署服務時根據使用者希望套用的參數(Values)去產生並安裝 Kubernetes 資源(產出的資源可以稱為 Release)。 簡單來說,如果開發者想要部署多個變形的應用程式,那麼就只需要準備一份 Kubernetes 模板加上多個不同的參數設定(values.yaml)即可!

Helm 基本操作

0. 安裝與建立 helm 專案

請輸入以下命令完成 Helm 的安裝:

$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh

安裝完畢後,使用以下命令就能夠在本機初始化一個最基礎的 Helm 專案:

$ helm create <YOUR_PROJECT_NAME>

完成專案的初始化動作後,我們可以觀察一下該專案包含了哪些檔案:

$ cd <YOUR_PROJECT>
$ tree
.
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

1. values.yaml

values.yaml 包含了 Chart 需要的資訊,像是:replica 數量、Pod 使用的 Image、Service 與 Ingress 等等。

# Default values for helm-pratice.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: nginx
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: ""

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

serviceAccount:
  # Specifies whether a service account should be created
  create: true
  # Annotations to add to the service account
  annotations: {}
  # The name of the service account to use.
  # If not set and create is true, a name is generated using the fullname template
  name: ""

podAnnotations: {}

podSecurityContext: {}
  # fsGroup: 2000

securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  className: ""
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #   cpu: 100m
  #   memory: 128Mi
  # requests:
  #   cpu: 100m
  #   memory: 128Mi

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80

nodeSelector: {}

tolerations: []

affinity: {}

2. /templates

/templates 資料夾包含了多個檔案的模板,像是:

  • deployment:Kubernetes 中用於部署一至多個 Pod 的方式。
  • hpa:對於 Deployment 的動態擴展策略,像是至少或至多能有多少個 replica、CPU 與 Memory 的資源。
  • service:由於 Pod 的資源會被 Kubernetes 動態的管理,它們的實際位址會是浮動的。為了讓服務的請求能被這些 Pod 處理,我們會需要 service 的幫忙。
  • ingress:使 service 能夠對外服務。

1. 部署 Helm 專案

使用 helm install 命令,Helm 會幫我們部署專案描述的資源並且在 Kubernetes 上執行:

$ cd <YOUR_PROJECT>
$ helm install <RELEASE_NAME> .

部署完畢後,使用 helm list 可以查詢當前已部署的專案。

2. 其他基礎操作

解除安裝已部署的資源:

$ helm uninstall <RELEASE_NAME>

檢查 Chart 的語法是否正確:

$ cd <YOUR_PROJECT>
$ helm lint .

更新已部署的 Helm 專案:

$ cd <YOUR_PROJECT>
$ helm upgrade <RELEASE_NAME> .

3. 管理 Helm 專案

Docker 能夠讓我們發布自己的 Image 到 Repository,同理,Helm 也提供了 repository 讓我們可以自由的拉取、發佈 Helm 專案供其他人使用。 使用 helm package 可以將 Helm Chart 打包:

$ cd <YOUR_PROJECT>
$ helm package <PACKAGE_NAME>

將 Helm Chart 打包後,使用 helm repo index 產生 index.yaml:

$ cd <YOUR_PROJECT>
$ helm repo index --url <GITHUB_REPO> .

輸入以上指令後,會產出一個 index.yaml 檔案,這時就可以將整個專案資料夾 push 至 GitHub 上了!

$ cd <YOUR_PROJECT>
$ git init
$ git remote add origin <GITHUB_REPO>
$ git commit -a -m "init commit"
$ git push origin master

完成這一步驟後,其他人可以透過以下方式存取到你的 Helm Chart:

$ helm repo add <REPO_NAME> <GITHUB_REPO>

如果需要查詢本機有哪些 Repository,或是查詢某個 Repo 包含了哪些 Chart,可以這麼做:

# 查詢本機的 repository
$ helm repo list
# 查詢某個 Repo 包含了哪些 Chart
$ helm search <REPO_NAME>
# 拉取最新的 repo
$ helm repo update

部署 free5GC

筆者用了數篇文章介紹 Kubernetes 與 Docker Container 技術,其實就是為了將 free5GC 部署至 Kubernetes 上鋪程。 本篇文章使用 towards5gs-helm 專案部署 free5GC,該專案已經為我們準備好所有 NF 的 Chart,甚至 整合了 Prometheus 與 Grafana。

準備

要部署 free5GC 到 Kubernetes 上,你需要:

  • 安裝 Kubernetes(本文使用最簡單的 minikube 進行安裝)
  • 設定 CNI
  • 安裝 kubectl
  • 安裝 helm

安裝與部署 towards5gs-helm

本節參考並修改自 Deploying 5G core network with Free5GC, Kubernetes and Helm

在取得 Helm repo 之前,我們先為待會的實驗環境建立一個 Kubernetes namespace:

$ kubectl create namespace free5gc

接著,使用 helm repo add 取得 towards5gs-helm:

$ helm repo add towards5gs 'https://raw.githubusercontent.com/Orange-OpenSource/towards5gs-helm/main/repo/'
$ helm repo update

取得 towards5gs-helm 後,我們將它部署至 Kubernetes 的 free5gc namespace 上:

$ helm install -n free5gc install free5gc-deploy towards5gs/free5gc

等到上面提到的命令由 Helm 處理完畢,我們就可以看到 Network Functions 以 Pod 的形式運作在 Kubernetes 上:

$ kubectl get pods -n free5gc

新增訂閱用戶

$ kubectl get svc -n free5gc

Webconsole 同樣以 Pod 的形式運作在 Kubernetes 上,為了能夠註冊訂閱用戶,我們需要讓本機能夠存取到 Webconsole:

$ kubectl port-forward --namespace free5gc svc/webui-service 5000:5000

完成這一步驟後,我們只要打開瀏覽器並輸入 localhost:5000 就能夠訪問 webconsole 了!

References

⚠️ **GitHub.com Fallback** ⚠️