你的Helm安全嗎?

一、背景


Kubernetes是目前最爲流行、成爲事實標準的容器集羣管理平臺,爲容器化應用提供了部署運行、資源調度、服務發現和動態伸縮等一系列完整功能。Kubernetes當中,用戶通過使用API對象,如PodServiceDeployment等,來描述應用的程序規則,而這些資源對象的定義一般需要寫入一系列的YAML文件中,然後通過 Kubernetes 命令行工具Kubectl進行部署由於通常應用程序都涉及到多個Kubernetes API對象,而要描述這些API對象就可能要同時維護多個YAML文件,從而在進行 Kubernetes 軟件部署時,通常會面臨下述幾個問題:

· 如何管理、編輯和更新這些這些分散的 Kubernetes 應用配置文件

· 如何把一套相關的配置文件作爲一個應用進行管理

· 如何分發和重用 Kubernetes 的應用配置

Helm https://helm.sh)的出現就是爲了很好地解決上面這些問題,是Kubernetes官方提供的包管理工具,主要是是通過管理被稱作Helm Chart的包來描述和管理雲服務的。使用 Helm後就不需要再編寫複雜的應用部署文件,可以以簡單的方式在 Kubernetes 上查找、安裝、升級、回滾、卸載應用程序。

在現在常用的Helm V2架構中,有一個稱爲“Tiller”的服務端組件。Tiller是一個集羣內服務器,可與Helm客戶端進行交互,並與Kubernetes API服務器連接。但由於Tiller具有root用戶訪問權限,使得有人可以未經授權訪問Kubernetes服務器你,從而構成了很大的風險。

JFrog的專家,也是Helm的聯合創始人,Rimas Mocevicius,提供了一種創新的、優雅的方法——Tillerless Helm,來解決這種情況,從而保護用戶的Kubernetes集羣。

二、Helm V2的應用架構

Helm v2開始,Helm的架構中有一個名爲The Tiller Server的服務器部分,該服務器部分是一個與helm客戶端交互並與Kubernetes API服務器連接的集羣內服務器。服務器負責以下各項工作:

· 監聽來自Helm客戶端的傳入請求

· 結合Chart和配置以創建發佈版本

· Chart安裝到Kubernetes中,然後跟蹤後續版本

· 通過與Kubernetes交互來升級和卸載Chart

簡而言之,客戶端負責管理ChartTiller負責管理髮布版本,其架構如下圖所示:

圖片1.png

默認情況下,執行如下命令將Tiller部署安裝到Kubernetes集羣:

helm init                    

同時還需要爲Tiller創建並部署RBAC授權,使其擁有執行任務的權限。Tiller常用的RBAC授權如下所示:

圖片2.png

    目前這樣的架構工作得很好,爲用戶提供了靈活和方便,但同時也存在一些安全問題。從上面的RBAC文件中可以看出,Tiller被授予了cluster-admin的角色,也就是說,Tiller在用戶的Kubernetes集羣中具有完全的管理權限,這就具備了有人未經授權而訪問和控制集羣的風險。

三、Helm V2 中的Tillerless方案

其實,在Helm V2中創建Tillerless的架構也並不困難,能夠爲Helm的應用提供更高的安全保障。JFrog的專家Rimas給出了優化的解決方案,而本節將通過細節的描述來解釋該方案如何運行。

首先,可以將Helm客戶端和Tiller都部署在工作站上,或者運行在CI/CD流水線中,而不需要將Tiller安裝到Kubernetes集羣之中。示例的安裝方式如下:

$ export TILLER_NAMESPACE=my-team-namespace

$ export HELM_HOST=localhost:44134

$ tiller --storage=secret

[main] 2018/07/23 15:52:29 Starting Tiller v2.10.0 (tls=false)

[main] 2018/07/23 15:52:29 GRPC listening on :44134

[main] 2018/07/23 15:52:29 Probes listening on :44135

[main] 2018/07/23 15:52:29 Storage driver is Secret

[main] 2018/07/23 15:52:29 Max history per release is 0

在這種安裝方式下,Helm的運行架構如下圖所示:

圖片3.png

在這種架構下,Tiller使用和Helm客戶端一樣的配置(kubeconfig)連接到Kubernetes集羣,並按照指定的命名空間(namespace)存儲和管理Helm的發行版本信息。用戶可以通過這種方式創建許多名稱空間,並在Tiller啓動時指定應該使用哪個命名空間。用戶定義的RBAC規則可以存儲在運行指定的名稱空間中的密鑰/配置映射中,而不再需要爲Tiller創建和指定ServiceAccount。而這個架構的另一個好處就是不再限定Kubernetes集羣中只能運行一個Tiller實例。

注意,在這種架構下,必須使用如下的命令來初始化Helm客戶端,否則Tiller仍然被安裝到Kubernetes集羣中:

    helm init --client-only

四、Helm V2中的Tillerless插件

那麼,有沒有更加方便的安裝方式呢?Rimas爲大家提供了一個簡單的Helm Tillerless插件,請參見https://github.com/rimusz/helm-tiller

插件的安裝非常方便,如下:

$ helm plugin install https://github.com/rimusz/helm-tiller

Installed plugin: tiller

該插件提供了四個簡單的命令:startstart-cistoprun

4.1 在本地使用Tillerless插件

對於在本地開發或訪問遠程Kubernetes集羣時,請使用helm tiller start命令:

$ helm tiller start

Client: &version.Version{SemVer:"v2.10.0", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}

[main] 2018/07/23 16:08:07 Starting Tiller v2.10.0 (tls=false)

[main] 2018/07/23 16:08:07 GRPC listening on :44134

[main] 2018/07/23 16:08:07 Probes listening on :44135

[main] 2018/07/23 16:08:07 Storage driver is Secret

[main] 2018/07/23 16:08:07 Max history per release is 0

Server: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}

Tiller namespace: kube-system

該命令將在本地啓動Tiller,並利用Tiller默認的設置,在kube-system名稱空間存儲和管理Helm版本。

也可以通過下述命令指定Tiller使用的命名空間:

$ helm tiller start my-team-namespace

Client: &version.Version{SemVer:"v2.10.0", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}

[main] 2018/07/23 16:08:38 Starting Tiller v2.10.0 (tls=false)

[main] 2018/07/23 16:08:38 GRPC listening on :44134

[main] 2018/07/23 16:08:38 Probes listening on :44135

[main] 2018/07/23 16:08:38 Storage driver is Secret

[main] 2018/07/23 16:08:38 Max history per release is 0

Server: &version.Version{SemVer:"v2.10.0", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}

Tiller namespace: my-team-namespace

該命令還會打開一個新bash shell,帶有預設的環境變量:

HELM_HOST=localhost:44134

這樣,Helm客戶端就知道如何連接Tiller了。

現在,就可以開始部署或更新Helm的發佈版本了。

當完成了所有工作之後,只需要運行下述命令,就可以關閉Tiller了。

$ exit

$ helm tiller stop

/Users/user/.helm/plugins/helm-tiller

Stopping Tiller..

接下來,用戶也可以重複上面的過程,通過指定新的命名空間來部署和更新其他團隊的發佈版本。

4.2 CI/CD流水線中使用Tillerless插件

那如何在CI/CD流水線當中使用該插件呢?有兩種方法:

第一與上面的過程非常相似,只是沒有啓動帶有預設變量的bash shell

$ helm tiller start-ci

$ export HELM_HOST=localhost:44134

然後,Helm客戶端將知道連接到Tiller的位置,而無需在CI流水線中進行任何更改。並且在流水線的結尾執行:

$ helm tiller stop

結束全部工作。

第二也很容易,就是運行helm tiller run,可以使Tiller在指定命令之前或之後啓動/停止:

$ helm tiller run helm list

$ helm tiller run my-team-namespace -- helm list

$ helm tiller run my-team-namespace -- bash -c 'echo running helm; helm list'

舉例來看:

$ helm tiller run test -- bash -c 'echo running helm; helm list'

Installed Helm version v2.10.0

Installing Tiller v2.10.0 ...

x tiller

args=bash -c echo running helm; helm list

Client: &version.Version{SemVer:"v2.10.0", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}

[main] 2018/07/25 17:33:54 Starting Tiller v2.10.0 (tls=false)

[main] 2018/07/25 17:33:54 GRPC listening on :44134

[main] 2018/07/25 17:33:54 Probes listening on :44135

[main] 2018/07/25 17:33:54 Storage driver is Secret

[main] 2018/07/25 17:33:54 Max history per release is 0

Server: &version.Version{SemVer:"v2.10.0", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}

Tiller namespace: test

running helm

[storage] 2018/07/25 17:33:55 listing all releases with filter

NAME    REVISION    UPDATED                     STATUS      CHART       NAMESPACE

keel    1           Sun Jul 22 15:42:43 2018    DEPLOYED    keel-0.5.0  default

Stopping Tiller...

附加功能:該插件還能夠檢查安裝的Helm客戶端和Tiller的版本,如果不匹配,則下載正確的Tiller版本文件。

五、總結

Helm作爲Kubenetes的官方包管理工具,爲用戶提供了方便、快捷的在Kubernetes集羣裏部署和管理自己應用程序的方式。然而,Helm V2架構中的Tiller組件,在提供了操作便利的同時,也帶來了安全上的隱患。

本文爲大家介紹了一種在Helm V2中實現TillerlessHelm部署和應用的解決方案,在保留了Helm V2靈活性和便利性的同時,也大大提升了應用和管理的安全性。

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章