Ksonnet是編寫和配置KUBERNETES配置文件的流程化方法的支持工具。linux
所使用的關鍵的ksonnet concepts包括:git
本教程不須要 ksonnet的預先知識,不須要對Kubernetes很是熟悉,但會很是有用。kubectl apply
用於將應用提交到 Kubernetes clusters。github
在本教程中,咱們將進行一個在集羣中使用ksonnet配置和運行一個基本的web app的步驟。該應用基於 classic Kubernetes guestbook example,經過簡單的消息提交查詢。當部署後,guestbook看起來以下:web
經過這一過程,你將看到 ksonnet workflows的通用過程,學習到最佳實踐,理解 ksonnet 概念,從而經過編寫 Kubernetes manifests實現流水線的處理。redis
若是有任何下面的問題,能夠到這裏瞭解更多(參考https://ksonnet.io/docs/tutorial)。shell
若是還有其它的問題,但願幫助咱們改進,經過 raising a documentation issue.macos
好,如今準備開始!json
開始以前,確保:api
kubectl。
若是沒有,安裝參考 installing via Homebrew (MacOS) 和 building the binary (Linux).$KUBECONFIG
指向一個有效的 kubeconfig 文件。裏面指向一個想要使用的[+]。kube-dns運行正常,
這裏構建的 application依賴於此 [+]。本節,咱們使用ksonnet CLI 來設置一個application。瀏覽器
首先, ksonnet application是什麼? 能夠設想爲Kubernetes manifests保存爲一個良好結構化的目錄,以一種簡單的方式耦合到一塊兒。
在這裏的示例,咱們的app manifests定義了以下的架構:
咱們的UI、datastore、search service、logging stack都經過獨立的manifest來定義。注意這裏的教程只是覆蓋了UI和datastore。未來的教程將加入search service 和 logging stack。
首先,來運行一些命令:
建立一個「sandbox」 namespace到Kubernetes集羣之中,後續教程將會使用。
看起來有不少命令,只須要拷貝、粘貼便可。
kubectl create namespace ks-dev CURRENT_CONTEXT=$(kubectl config current-context) CURRENT_CLUSTER=$(kubectl config get-contexts $CURRENT_CONTEXT | tail -1 | awk '{print $3}') CURRENT_USER=$(kubectl config get-contexts $CURRENT_CONTEXT | tail -1 | awk '{print $4}') kubectl config set-context ks-dev \ --namespace ks-dev \ --cluster $CURRENT_CLUSTER \ --user $CURRENT_USER
初始化app, 使用 ks-dev
context,在第一步中已經建立出來。
若是使用 Kubernetes 1.8, 須要添加 --api-spec=version:v1.8.0
到下面的命令後面。
ks init guestbook --context ks-dev
查看結果:
cd guestbook
產生的目錄結構以下:
. ├── app.yaml ├── components // *What* is deployed to your cluster │ └── params.libsonnet ├── environments // *Where* your app is deployed │ ├── base.libsonnet │ └── default │ ├── main.jsonnet │ ├── params.libsonnet │ └── spec.json ├── lib // *Helper code* specific to your app └── vendor // *External libraries* that your app leverages
將該ksonnet app目錄放入git的版本控制。
git init git add . git commit -m "initialize guestbook app"
ksonnet app的目錄結構很是重要,不只是一個模塊化的標準,也是 ksonnet magic的關鍵。換句話說,該結構容許ksonnet CLI 假定App的內容而且自動化特定的工做流程。
如今咱們的應用有了一個工做目錄,能夠添加用於部署的manifests。這些manifests爲應用定義了下面的組件:
該過程經過 ksonnet CLI實現自動化。任何 boilerplate YAML將被自動建立,從而避免全部的拷貝、粘貼工做。
添加新的components, 使用下面的command pattern:
ks generate
- 爲特定組件建立manifest。ks apply
- 應用全部可用的 manifests 到你的集羣。首先開始 Guestbook UI。該manifest 將聲明兩個 Kubernetes API resources:
該container image自己使用PHP 和 AngularJS編寫。
爲了設置Guestbook UI 組件:
ks generate deployed-service guestbook-ui \ --image gcr.io/heptio-images/ks-guestbook-demo:0.1 \ --type ClusterIP
(I have a lot of questions about what just happened.) [+]
ks show default
ksonnet 經過 Jsonnet自動建立 component/
manifests ,可是你能夠拉入 YAML 和 JSON 文件 到ksonnet app。純JSON能夠直接整合進Jsonnet代碼,Jsonnet也能夠轉回到JSON或 YAML。
ks apply default
注意, default
引用ks-dev
context (and implicit namespace) ,爲剛纔咱們使用ks init建立。
這裏介紹兩種方法將Service提供給外部訪問,經過proxy和port-forward。其它如ingress和istio等之後再介紹。
首先運行 kubectl proxy。若是須要其它機器訪問,運行:
kubectl proxy --address='0.0.0.0' --accept-hosts='^*$'
A、下面的腳本代碼暴露出 Guestbook service, 使其能從瀏覽器訪問。
如今還不能提交信息,由於尚未部署Redis component,點擊buttons將會失敗。
# Set up an API proxy so that you can access the guestbook-ui service locally kubectl proxy > /dev/null & KC_PROXY_PID=$! SERVICE_PREFIX=http://localhost:8001/api/v1/proxy GUESTBOOK_URL=$SERVICE_PREFIX/namespaces/ks-dev/services/guestbook-ui # Check out the guestbook app in your browser open $GUESTBOOK_URL
上面方法會出錯(可能上面的語法版本較老)。我用1.10.2,改成以下可用(先運行kubectl proxy):
http://localhost:8001/api/v1/namespaces/ks-dev/services/guestbook-ui:80/proxy/
B、對於已經運行過 kubectl proxy, 也能夠用下面的方法:
http://localhost:8001/api/v1/namespaces/ks-dev/services/http:guestbook-ui:/proxy/#!/pod/ks-dev/guestbook-ui-584f58dcc4-xhrsm?namespace=ks-dev
其中 guestbook-ui-584f58dcc4-xhrsm爲相應的pod運行實例名稱,能夠經過dashboard查到,或者運行下面的命令得到:
kubectl get pods --namespace ks-dev -l "app=guestbook-ui" -o jsonpath="{.items[0].metadata.name}"
C、也可使用端口映射的方法,以下:
export POD_NAME=$(kubectl get pods --namespace ks-dev -l "app=guestbook-ui" -o jsonpath="{.items[0].metadata.name}") kubectl --namespace ks-dev port-forward $POD_NAME 8003:80
git add . git commit -m "autogenerate ui component"
咱們怎樣知道那些組件可用,是怎樣建立的?
組件基於通用的 manifest patterns,稱爲prototypes,只須要不多的工做就能夠原型化一個組件。只需查看 deployed-service
prototype, 來自於 ksonnet out-of-the-box。
瀏覽剛纔所作的,咱們只須要 steps (1) ks generate
和 (3) ks apply
就可使 Guestbook UI 運行在集羣上。不錯! 但咱們能作的更好。你也許熟悉 kubectl,如命令
run
和 expose
。當咱們部署一個 prototype ,尤爲對於Service 和 Deployment combo (Redis!), ksonnet commands的優點更爲明顯。
在着手讓 Redis 工做以前,首先花點時間理解 prototypes。除了 Kubernetes API objects 如 deployed-service的組合以外
, prototypes 能夠定義一般的 off-the-shelf components,如databases。
咱們下一步將使用 redis-stateless
prototype ,設置一個基本的 Redis 實例 (stateless是由於沒有使用 persistent volumes來作持久化存儲支撐。)。更復雜的prototypes須要下載,不包含在 out-of-the-box; 本節,咱們將展現如何來作。
一個prototype是未完成的skeleton manifest, 採用 Jsonnet編寫。在 ks generate的時候,你能夠指定一個
命令行參數到prototype的 「fill-in-the-blanks」 ,而後輸出component:
在後續的設置Guestbook app的過程當中,將會看到幾回這樣的操做。
Now let’s use the redis-stateless
prototype to generate the datastore component of our app, as depicted below:
你須要作一點額外的包管理工做,該 redis-stateless
prototype 缺省還不可用。
ks prototype list
ks pkg list
ks pkg install incubator/redis@master
redis
和 stateless-redis
): ks pkg list ks prototype list
ks prototype describe redis-stateless
ks generate redis-stateless redis
default
「sandbox」):ks show default
ks apply default
open $GUESTBOOK_URL
在文本框輸入,而後點擊 Submit button。
git add . git commit -m "autogenerate redis component"
至此,Guestbook 已經工做!
使用 ks generate
and ks apply
, 可使用 prototypes 和 parameters 快速讓應用的 components of 在 Kubernetes cluster中工做。可使用命令 ks show
和 ks describe
提供開發 manifests的過程的幫助。
揭示:即便有參數定製,所自動建立的manifests將不會徹底匹配你的需求。不過,the ksonnet tour 演示中,你可使用 Jsonnet language來實現更爲靈活的需求。
此時,咱們已經有一個Guestbook app 能夠運行。能夠經過UI提交消息,而後保存到Redis datastore。
咱們還未涉及到複雜的特徵(好比 search 和 logging),可是咱們將首先展現如何使用ksonnet application一樣的component manifests部署到不一樣的集羣環境。實際上,你能夠想象在dev環境下開發 manifests 而後部署到另一個生產環境。
同一個集羣的不一樣namespace的環境:
一般,能夠認爲一個環境包含四個部分,部分來自於你的當前kubeconfig context:
default。
咱們將設置相似的結構,用於發佈管理的過程。
ks-prod
, 第二個環境爲: kubectl create namespace ks-prod kubectl config set-context ks-prod \ --namespace ks-prod \ --cluster $CURRENT_CLUSTER \ --user $CURRENT_USER
prod
, 重命名 default
environment 爲 dev以示區分
: ks env list ks env add prod --context=ks-prod ks env set default --name dev ks env list
prod
environment: ks apply prod
prod
(同一個集羣, ks-prod
namespace): PROD_GUESTBOOK_URL=$SERVICE_PREFIX/namespaces/ks-prod/services/guestbook-ui open $PROD_GUESTBOOK_URL
git add . git commit -m "add prod env"
Environments容許部署manifests的公共集合到不一樣的環境之中,若是不清楚如何使用,考慮下面的一些使用場景:
環境是分級的,處理多重環境,能夠嵌套 us-west-2/dev
和 us-east-1/prod。在下面將會進一步看到,
能夠經過指定環境的參數覆蓋其base/parent environments。
很好,將一樣的 manifests 部署到多個環境簡直是太棒了。可是,不少時候環境會有一些小小的差異。
能夠經過參數來定製環境,至此,咱們在 ks generate設置過參數
, 將參數傳入命令行來定製化一個新的component。這裏,咱們將進一步展現,能夠在特定的environments中改變這些個參數。
參數能夠設置在 entire app 或 per-environment。本教程中,全部的參數針對於component。未來的教程將着重於global parameters,可以在多個components間共享。
ks param
命令更新本地Jsonnet files, 所以將總會有一個版本控制的表明,表明 ks apply
中的Kubernetes cluster。
ks param diff dev prod
ks param set guestbook-ui image gcr.io/heptio-images/ks-guestbook-demo:0.2 --env dev ks param set guestbook-ui replicas 3 --env prod
param diff
查看參數差別: ks param diff dev prod
ks apply dev && ks apply prod
dev
和 prod的差別:
ks diff remote:dev remote:prod
dev
看起來有些不同): # Check out dev guestbook open $GUESTBOOK_URL # Make sure that the changes didn't affect prod open $PROD_GUESTBOOK_URL
git add . git commit -m "update guestbook-ui parameters"
經過參數化的能力,environments容許應用的拷貝在不一樣的集羣和命名空間部署的能力。使用parameters,你能夠微調參數部署到每個環境,不管是不一樣的載入requirements仍是精確的labels。
你已經使用ksonnet開發部署了Guestbook的主要組件。如今,你有了一個能夠持續使用的manifests集合,能夠在後面添加更多的功能。
If you’d like to remove the Guestbook app and other residual traces from your cluster, run the following commands in the root of your Guestbook app directory:
# Remove your app from your cluster (everything defined in components/) ks delete dev && ks delete prod # If you used 'kubectl proxy' to connect to your Guestbook service, make sure # to end that process sudo kill -9 $KC_PROXY_PID # Remove the "sandbox" kubectl delete namespace ks-dev ks-prod kubectl config delete-context ks-dev && kubectl config delete-context ks-prod
We’ve also only just skimmed the surface of the ksonnet framework. Much of what you’ve seen has been focused on the CLI. To learn more, check out the following resources:
(What about the rest of the Guestbook (e.g. search)?) [+]
If you encounter this error when running the ksonnet Linux binary, you can temporarily work around it by setting the USER
environment variable (e.g. export USER=your-username
).
This error results from cross-compilation (Linux on Mac). To avoid this, future binaries will be built on the appropriate target machines.
If you get an error saying something to the effect of 403 API rate limit of 60 still exceeded
you can work around that by getting a Github personal access token and setting it up so that ks
can use it. Github has higher rate limits for authenticated users than unauthenticated users.
export GITHUB_TOKEN=<token>
. You may want to do this as part of your shell startup scripts (i.e. .profile
).