是時候使用Helm了:Helm, Kubernetes的包管理工具

目前咱們的一個產品共有4套環境:dev環境、test環境、staging環境、production環境。 其中dev, test, staging環境在一個Kubernetes集羣上以不一樣namespace部署,production環境部署在另外一個Kubernetes集羣上。這個產品總共有14個微服務組成,對應gitlab中14個代碼庫,Kubernetes的deployment yaml文件也保存在代碼庫,爲每一個服務的每套環境以環境名建立了一個目錄,裏面是yaml文件,yaml文件的內容使用sed實現了簡單的模板功能。14個服務*4套環境總共56個yaml文件,比較原始。nginx

最近須要新起另外的一套測試環境這裏稱它爲test2吧,須要在第一個Kubernetes集羣上建立新的namespace,要維護的yaml文件立刻也要增長到70個,有點噩夢的感受了。 所以咱們須要一個模板工具來管理這些yaml文件。早就知道helm這個東西,但爲了保持簡單,一直遵循着最少引入新東西的原則,那麼如今是時候使用Helm了吧?git

1.Helm的基本概念

Helm是Kubernetes的一個包管理工具,用來簡化Kubernetes應用的部署和管理。能夠把Helm比做CentOS的yum工具。 Helm有以下幾個基本概念:github

  • Chart: 是Helm管理的安裝包,裏面包含須要部署的安裝包資源。能夠把Chart比做CentOS yum使用的rpm文件。每一個Chart包含下面兩部分:
  • 包的基本描述文件Chart.yaml
  • 放在templates目錄中的一個或多個Kubernetes manifest文件模板
  • Release:是chart的部署實例,一個chart在一個Kubernetes集羣上能夠有多個release,即這個chart能夠被安裝屢次
  • Repository:chart的倉庫,用於發佈和存儲chart

使用Helm能夠完成如下事情:golang

  • 管理Kubernetes manifest files
  • 管理Helm安裝包charts
  • 基於chart的Kubernetes應用分發

2.Helm的組成

Helm由兩部分組成,客戶端helm和服務端tiller。docker

  • tiller運行在Kubernetes集羣上,管理chart安裝的release
  • helm是一個命令行工具,可在本地運行,通常運行在CI/CD Server上。

如下是摘自Helm – Application deployment management for Kubernetes的一張Helm的架構圖,一圖勝千言了。json

3.Helm的安裝

咱們將在Kubernetes 1.8上安裝Helm。api

3.1 客戶端helm和服務端tiller

首先從這裏下載Helm的二進制文件. 這裏下載的是helm 2.7.2,解壓縮後將可執行文件helm拷貝到/usr/local/bin下。這樣客戶端helm就在這臺機器上安裝完成了。網絡

此時運行helm version能夠打印出客戶端helm的版本,同時會提示沒法鏈接到服務端Tiller。架構

helm version
Client: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
Error: cannot connect to Tiller

爲了安裝服務端tiller,還須要在這臺機器上配置好kubectl工具和kubeconfig文件,確保kubectl工具能夠在這臺機器上訪問apiserver且正常使用。app

kubectl get cs
NAME                 STATUS    MESSAGE              ERROR
scheduler            Healthy   ok
controller-manager   Healthy   ok
etcd-4               Healthy   {"health": "true"}
etcd-0               Healthy   {"health": "true"}
etcd-2               Healthy   {"health": "true"}
etcd-3               Healthy   {"health": "true"}
etcd-1               Healthy   {"health": "true"}

使用helm在k8s上部署tiller:

helm init --service-account tiller --skip-refresh
Creating /root/.helm
Creating /root/.helm/repository
Creating /root/.helm/repository/cache
Creating /root/.helm/repository/local
Creating /root/.helm/plugins
Creating /root/.helm/starters
Creating /root/.helm/cache/archive
Creating /root/.helm/repository/repositories.yaml
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
Adding local repo with URL: http://127.0.0.1:8879/charts
$HELM_HOME has been configured at /root/.helm.

注意因爲某些緣由須要網絡能夠訪問gcr.io和kubernetes-charts.storage.googleapis.com,若是沒法訪問能夠經過helm init –service-account tiller –tiller-image <your-docker-registry>/tiller:2.7.2 –skip-refresh使用私有鏡像倉庫中的tiller鏡像

tiller默認被部署在k8s集羣中的kube-system這個namespace下。

kubectl get pod -n kube-system -l app=helm
NAME                             READY     STATUS    RESTARTS   AGE
tiller-deploy-587df449fb-c6tzp   1/1       Running   0          9m

再次helm version能夠打印客戶端和服務端的版本:

helm version
Client: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}

3.2 Kubernetes RBAC配置

由於咱們將tiller部署在Kubernetes 1.8上,Kubernetes APIServer開啓了RBAC訪問控制,因此咱們須要建立tiller使用的service account: tiller並分配合適的角色給它。 詳細內容能夠查看helm文檔中的Role-based Access Control。 這裏簡單起見直接分配cluster-admin這個集羣內置的ClusterRole給它。

建立rbac-config.yaml文件:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system
kubectl create -f rbac-config.yaml
serviceaccount "tiller" created
clusterrolebinding "tiller" created

4.Helm的基本使用

已經安裝helm的客戶端helm和服務端tiller,下面要熟悉如何使用helm管理Kubernetes集羣的安裝包。

更新chart repo:

helm repo update

實際上若是helm所在的機器訪問不了google的話,會報錯,由於訪問不了 「stable」 chart repository (https://kubernetes-charts.storage.googleapis.com)

4.1 建立一個chart

下面咱們開始嘗試建立一個chart,這個chart用來部署一個簡單的服務。

helm create hello-svc
Creating hello-svc

tree hello-svc/
hello-svc/
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   └── service.yaml
└── values.yaml

2 directories, 7 files

先熟悉一下hello-svc這個chart中目錄和文件內容:

  • charts目錄中是本chart依賴的chart,當前是空的
  • Chart.yaml這個yaml文件用於描述Chart的基本信息,如名稱版本等
    cat Chart.yaml
      apiVersion: v1
      description: A Helm chart for Kubernetes
      name: hello-svc
      version: 0.1.0
  • templates是Kubernetes manifest文件模板目錄,模板使用chart配置的值生成Kubernetes manifest文件。模板文件使用的Go語言模板語法
  • templates/NOTES.txt 純文本文件,可在其中填寫chart的使用說明
  • value.yaml 是chart配置的默認值

經過查看deployment.yaml和value.yaml,大概知道這個chart默認安裝就是在Kubernetes部署一個nginx服務。

更多Chart的內容能夠查看Chart官方文檔

4.2 對chart的模板和配置進行測試

使用helm在Kubernetes上安裝chart時,其實是將chart的模板生成Kubernetes使用的manifest yaml文件。 在編寫chart的過程當中能夠chart目錄下使用helm install –dry-run –debug ./來驗證模板和配置。

helm install --dry-run --debug ./
[debug] Created tunnel using local port: '22635'

[debug] SERVER: "127.0.0.1:22635"

[debug] Original chart version: ""
[debug] CHART PATH: /root/helm/hello-svc

NAME:   foolish-zebra
REVISION: 1
......輸出基於配置值和模板生成的yaml文件

4.3 在Kubernetes上安裝chart

在hello-svc這個chart目錄下執行:

helm install ./

NAME:   wishful-squid
LAST DEPLOYED: Thu Dec 21 22:04:19 2017
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME                     TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)  AGE
wishful-squid-hello-svc  ClusterIP  10.111.223.243  <none>       80/TCP   0s

==> v1beta1/Deployment
NAME                     DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
wishful-squid-hello-svc  1        0        0           0          0s

==> v1/Pod(related)
NAME                                      READY  STATUS   RESTARTS  AGE
wishful-squid-hello-svc-6bbb59dfb6-smvz5  0/1    Pending  0         0s


NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app=hello-svc,release=wishful-squid" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80

查看release:

helm list
NAME            REVISION        UPDATED                         STATUS          CHART           NAMESPACE
wishful-squid   1               Thu Dec 21 22:04:19 2017        DEPLOYED        hello-svc-0.1.0 default

刪除release:

helm delete wishful-squid
release "wishful-squid" deleted

4.4 chart的分發

打包:

helm package ./

tree
.
├── charts
├── Chart.yaml
├── hello-svc-0.1.0.tgz
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   └── service.yaml
└── values.yaml

參考

相關文章
相關標籤/搜索