您好,登錄后才能下訂單哦!
這篇文章給大家介紹怎么使用helm-controller簡化容器云平臺應用商店的開發,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
熟練的閱讀并且進行相應的開發,大概需要對以下知識的了解:
k8s rest api 模型需要了解。
http協議需要熟練掌握。
openapi規范了解。
linux熟練掌握。
helm的理論架構了解。
k8s crd 的理解,controller概念掌握,rbac權限模型的理解。
helm私庫index.yaml的理解與使用。
core dns的配置與使用。
整體結構圖
helm是k8s的包管理器,也是k8s平臺復雜應用部署事實上的標準。包含了應用打包,部署,升級,回滾,卸載等符合生命周期管理的功能。
helm從v2到v3的版本升級,移除了重要的一個組件tiller,整體架構更簡潔。
helm至今為止,官方仍然沒有ga版的api。chart的下載,部署,升級,卸載,全部依賴cli。在多集群環境下cli很難滿足平臺的業務要求。
通過查看github issue,社區大概有兩種解決思路:
封裝cli成api。這種方式仍然存在每個集群需要通過ssh或者ansible的方式部署helm二進制文件到master節點上,給底層部署工作添加負擔。
CRD。將helm的核心能力打包成docker鏡像,部署到k8s集群中,以controller的方式提供能力。利用crd的方式完成release的部署,卸載,升級,回滾等業務動作。
cli方式最大的問題就在于不符合云原生的思想,而且cli的方式和helm版本鎖定,如果要升級helm,需要重新適配解析console內容。 crd的問題在于,官方目前還沒有ga。但仍然期待controller的方式。
我們團隊最初使用第一種方式進行了嘗試,但效果不理想。恰巧當時發現靈雀云開源了helm v3 controller captain,所以基于社區captain的進行了第二次嘗試,并最終完成了功能開發。
當時,在github搜索helm controller
,發現了兩個倉庫,一個是rancher提供的controller,一個是靈雀云提供的。經過簡單的測試,captain一次性安裝并測試成功,并結合內部的討論,最終決定基于captain進行開發。
github: https://github.com/alauda/captain
The Helm 3 Design Proposal exists for a while and currently it is still under heavy development. Captain comes as the first implementation of Helm v3 Controller based on the Proposal. This project is based on the core helm v3 code, acting as a library. Since it's not officially released yet (alpha stage for now), some modifications were made to help implement this controller on a fork: alauda/helm (will be deprecated once Helm's library is released).
captain是靈雀云開源的helm v3 controller
。其內部依賴helm library。所以核心的邏輯與helm client是一致的。等到后期helm官方正式ga后,可以遷移回官方正式版本,這對于以面向接口編程的java來說,so easy。
基于Apache 2.0協議開源
captain內部將helm部署成deployment。
安裝步驟:
kubectl create ns captain-system kubectl create clusterrolebinding captain --serviceaccount=captain-system:default --clusterrole=cluster-admin kubectl apply -n captain-system -f https://raw.githubusercontent.com/alauda/captain/master/artifacts/all/deploy.yaml
卸載:
kubectl delete -n captain-system -f https://raw.githubusercontent.com/alauda/captain/master/artifacts/all/deploy.yaml kubectl delete ns captain-system
安裝nginx chart
kind: HelmRequest apiVersion: app.alauda.io/v1alpha1 metadata: name: nginx-ingress spec: chart: stable/nginx-ingress
查看部署結果
root@VM-16-12-ubuntu:~/demo# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-ingress-controller-57987f445c-9rhv5 1/1 Running 0 16s nginx-ingress-default-backend-7679dbd5c9-wkkss 1/1 Running 0 16s root@VM-16-12-ubuntu:~/demo# kubectl get hr NAME CHART VERSION NAMESPACE ALLCLUSTER PHASE AGE nginx-ingress stable/nginx-ingress default Synced 23s
captain默認自帶stable的helm官方倉庫,helm官方的倉庫地址本身沒有問題,但是chart鏡像中如果使用了被墻了的docker鏡像,無法下載。測試的時候是使用的aliyun提供的倉庫地址https://developer.aliyun.com/hub/。這樣captain controller才能順利的將chart鏡像下載成功。
當測試結束時,我們需要將k8s與內網的chart私庫進行打通,需要新建一個ChartRepo的yaml文件
apiVersion: app.alauda.io/v1alpha1 kind: ChartRepo metadata: name: cloud namespace: captain-system spec: url: https://harbor.offline/chartrepo/library
然后使用kubectl create -f fileName
添加到k8s中,需要注意的是,我們使用了harbor做docker鏡像和helm鏡像的管理,因為docker的問題,我們使用了自簽的證書,captain在根據地址同步的時候,會校驗證書,這個問題我們也和官方進行了溝通,得到了解決,目前captain已經ga,可以直接使用,不需要擔心證書的問題。
云平臺的管理中,我們通過servicecount進行k8s api的使用,當安裝了captain之后,不同于命令行使用user account,我們需要額外的一步追加權限的動作
kubectl create clusterrolebinding default --serviceaccount=default:default --clusterrole=cluster-admin
captain 官方目前只提供了go和python的sdk,基于此,我們肯定要封裝一個captain的java sdk。
在架構底層,我們使用k8s官方的sdk進行開發。
基于crd和k8s openapi的簡單了解,結合官方的說明,嘗試性的進行了sdk生成的動作,結果失敗了,詳細見issue我們也聯系了作者,得知captain并沒有基于schema做校驗,內部使用了webhook進行的校驗。基于這樣的背景,直接使用openapi規范生成sdk的路不通,后面我們直接使用了kubectl -v9
的方式進行報文的驗證,以及代碼的開發。
使用kubectl命令行進行任意操作時,追加-v9
參數,可以獲取詳細的http報文信息
root@master:/home/kylin# kubectl get pod -v9 I0414 22:42:53.981748 16582 loader.go:359] Config loaded from file: /root/.kube/config I0414 22:42:54.042173 16582 round_trippers.go:419] curl -k -v -XGET -H "Accept: application/json;as=Table;v=v1beta1;g=meta.k8s.io, application/json" -H "User-Agent: kubectl/v1.15.5 (linux/amd64) kubernetes/20c265f" 'https://192.168.4.139:6443/api/v1/namespaces/default/pods?limit=500' I0414 22:42:54.077898 16582 round_trippers.go:438] GET https://192.168.4.139:6443/api/v1/namespaces/default/pods?limit=500 200 OK in 35 milliseconds I0414 22:42:54.077959 16582 round_trippers.go:444] Response Headers: I0414 22:42:54.078006 16582 round_trippers.go:447] Content-Type: application/json I0414 22:42:54.078054 16582 round_trippers.go:447] Date: Tue, 14 Apr 2020 14:42:54 GMT I0414 22:42:54.078394 16582 request.go:947] Response Body: {"kind":"Table","apiVersion":"meta.k8s.io/v1beta1","metadata":{"selfLink":"/api/v1/namespaces/default/pods","resourceVersion":"14332801"},"columnDefinitions":完整報文太長,略去!}]}}}]} I0414 22:42:54.092067 16582 get.go:564] no kind "Table" is registered for version "meta.k8s.io/v1beta1" in scheme "k8s.io/kubernetes/pkg/api/legacyscheme/scheme.go:30" NAME READY STATUS RESTARTS AGE busybox 1/1 Running 970 39d nginx-1585049022-b4f4c56c9-dvspz 1/1 Running 24 12d nginx-deployment-5bd886c88c-28d6q 0/1 Pending 0 2d1h nginx-deployment-5bd886c88c-968pd 0/1 MatchNodeSelector 0 4d3h nginx-deployment-5bd886c88c-dnh8q 0/1 MatchNodeSelector 0 4d3h nginx-deployment-5bd886c88c-pk9xz 0/1 Pending 0 2d1h
再結合k8s官方的java sdk提供的CustomObjectsApi。比較輕松的就開發了一整套chart鏡像生命周期對應的接口。
var customObjectsApi = new CustomObjectsApi(apiClient); var json = new JsonObjectBuilder() .set("apiVersion", "app.alauda.io/v1alpha1") .set("kind", "HelmRequest") .set("metadata", new JsonObjectBuilder().set("name", name).build()) .set("spec", new JsonObjectBuilder() .set("chart", chart) .set("namespace", namespace) .set("releaseName", name) .set("values", Map2JsonUtil.map2Json(params)) .set("version", version) ).build(); customObjectsApi.createNamespacedCustomObject("app.alauda.io","v1alpha1", "default", "helmrequests", json, null);
var customObjectsApi = new CustomObjectsApi(apiClient); customObjectsApi.deleteNamespacedCustomObject("app.alauda.io", "v1alpha1", "default","helmrequests", "test-nginx",new V1DeleteOptions().gracePeriodSeconds(0L).propagationPolicy("Foreground"),null, null, null);
這里可以選擇打patch或者直接replace,和k8s的概念是一致的。
captain并沒有像deployment原生的提供了對回滾的支持,需要自己將每次安裝或者升級的參數進行外部保存,再重新replace指定版本的參數,進行模擬回滾。
整體上,我們使用了三周的時間完成了應用商店第一版的開發,以及頁面接口聯調。這比使用cli方式的預期快了很多,而且我們的ansbile部署腳本上只需要再額外添加兩行安裝captain的腳本。
使用私有helm repo,默認情況下,集群內的coredns將非集群內的地址轉發到本機的/etc/resolv.conf
,這個時候一定要確保k8s宿主機的/etc/resolv.conf
dns地址修改為內網的dns server地址。否則captain controller找不到私有的helm repo,錯誤是 timeout。
在開發過程中,如果遇到問題無法定位,可以直接查看captain-controller的log,來進行處理。
網絡問題最好部署一個busybox,內置了nslookup,wget等工具。方便網絡檢測。
apiVersion: v1 kind: Pod metadata: name: busybox namespace: default spec: containers: - name: busybox image: busybox:1.28.4 command: - sleep - "3600" imagePullPolicy: IfNotPresent restartPolicy: Always
使用kubectl create -f busybox.yaml
完成busybox部署,使用kubectl exec -it busybox sh
進入容器內部,使用nslookup
,wget
等進行網絡檢測。
關于怎么使用helm-controller簡化容器云平臺應用商店的開發就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。