ksonnet 使用教程

ksonnet - 使用教程

Ksonnet是編寫和配置KUBERNETES配置文件的流程化方法的支持工具。linux

所使用的關鍵的ksonnet concepts包括:git

  1. Prototypes 和 parameters 組合造成 components。
  2. 多個 components 組合爲 app。
  3. 一個app能夠部署到多個environments。
  4. 不一樣的environments的差別經過參數來指定。

概述

本教程不須要 ksonnet的預先知識,不須要對Kubernetes很是熟悉,但會很是有用。kubectl apply用於將應用提交到 Kubernetes clusters。github

  • 與Helm的區別:
    • Helm主要管理Pakages級別的應用組件,以Chart格式描述,在安裝時須要根據不一樣環境將其定製化、改變參數。
    • Ksonnet的配置參數按照環境env來組織,能夠直接部署到相應的集羣。

咱們構建了什麼?

在本教程中,咱們將進行一個在集羣中使用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

0. 預先準備

開始以前,確保:api

  • 本地安裝了ksonnet。若是沒有,按照這裏安裝 install instructions
  • 能夠訪問運行的Kubernetes cluster. 支持的 Kubernetes 版本是1.7 (stable) 和 1.8 (beta),若是尚未,參考官方的Kubernetes文檔 choose a setup solution
  • 須要使用 kubectl。若是沒有,安裝參考 installing via Homebrew (MacOS) 和 building the binary (Linux).
  • 環境變量 $KUBECONFIG 指向一個有效的 kubeconfig 文件。裏面指向一個想要使用的[+]。
  • 你的 cluster 的kube-dns運行正常,這裏構建的 application依賴於此 [+]。

1. 初始化app

本節,咱們使用ksonnet CLI 來設置一個application。瀏覽器

定義 「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爲應用定義了下面的組件:

  • A UI (AngularJS/PHP) - the webpage that your user interacts with
  • A basic datastore (Redis) - where user messages are stored

該過程經過 ksonnet CLI實現自動化。任何 boilerplate YAML將被自動建立,從而避免全部的拷貝、粘貼工做。

定義「component」

添加新的components, 使用下面的command pattern:

  • ks generate - 爲特定組件建立manifest。
  • ks apply - 應用全部可用的 manifests 到你的集羣。

命令 (UI component)

首先開始 Guestbook UI。該manifest 將聲明兩個 Kubernetes API resources:

該container image自己使用PHP 和 AngularJS編寫。

爲了設置Guestbook UI 組件:

(1)首先建立 manifest,描述了 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.) [+]

(2)查看 YAML 等價的內容:

ks show default

ksonnet 經過 Jsonnet自動建立 component/ manifests ,可是你能夠拉入 YAML 和 JSON 文件 到ksonnet app。純JSON能夠直接整合進Jsonnet代碼,Jsonnet也能夠轉回到JSON或 YAML。

(3)如今 deploy 該 UI 到集羣:

ks apply default

注意, default 引用ks-dev context (and implicit namespace) ,爲剛纔咱們使用ks init建立。

(4)看一下 Guestbook app運行情況:

這裏介紹兩種方法將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

(5)將剛纔的變化加入版本控制。

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的優點更爲明顯。

3. 理解prototypes如何build components

定義 「prototype」

在着手讓 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的過程當中,將會看到幾回這樣的操做。

命令 (Datastore component)

Now let’s use the redis-stateless prototype to generate the datastore component of our app, as depicted below:

你須要作一點額外的包管理工做,該 redis-stateless prototype 缺省還不可用。

  1. 查看可用的prototypes:
    ks prototype list
  2. 看看那些 packages 能夠下載:
    ks pkg list

     

  3. 下載指定版本的ksonnet Redis library (包含various Redis prototypes):
    ks pkg install incubator/redis@master
  4. 檢查更新後的 packages 和 prototypes列表 (會看到 redis 和 stateless-redis):
    ks pkg list
     ks prototype list
  5. 計算須要的 prototype的參數:
    ks prototype describe redis-stateless
  6. 此時,咱們已經準備爲 Redis component建立 manifest
    ks generate redis-stateless redis

     

  7. 查看 YAML 等價的文件 (一直在 default 「sandbox」):
     
    ks show default
  8. 如今部署 Redis 到集羣:
    ks apply default

     

  9. 檢查 Guestbook page,打開:
     
    open $GUESTBOOK_URL

    在文本框輸入,而後點擊 Submit button。

  10. 加入版本控制。
    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來實現更爲靈活的需求。

4. 爲app設置另外一個環境

此時,咱們已經有一個Guestbook app 能夠運行。能夠經過UI提交消息,而後保存到Redis datastore。

咱們還未涉及到複雜的特徵(好比 search 和 logging),可是咱們將首先展現如何使用ksonnet application一樣的component manifests部署到不一樣的集羣環境。實際上,你能夠想象在dev環境下開發 manifests 而後部署到另一個生產環境。

定義「environment」

同一個集羣的不一樣namespace的環境:

一般,能夠認爲一個環境包含四個部分,部分來自於你的當前kubeconfig context:

  1. A name — environment, 對於ksonnet app是惟一的。
  2. A server URI — Kubernetes API server的 address 和 port ,換句話說,標識了一個集羣。
  3. A namespace — server URI裏集羣的namespace,缺省爲 default。
  4. A Kubernetes API version —  Kubernetes API server 運行的版本。Used to generate the appropriate helper libraries from Kubernetes’s OpenAPI spec.

咱們將設置相似的結構,用於發佈管理的過程。

命令

  1. 建立新的namespace 和 context,都命名爲 ks-prod, 第二個環境爲:
    kubectl create namespace ks-prod
     kubectl config set-context ks-prod \
       --namespace ks-prod \
       --cluster $CURRENT_CLUSTER \
       --user $CURRENT_USER
  2. 添加 prod environment 爲名稱 prod, 重命名 default environment 爲 dev以示區分
    ks env list
     ks env add prod --context=ks-prod
     ks env set default --name dev
     ks env list
  3. 應用全部的 manifests (Guestbook UI 和 Redis) 到 prod environment:
    ks apply prod
  4. 如今,有一個並行的Guestbook應用運行在prod (同一個集羣, ks-prod namespace):
    PROD_GUESTBOOK_URL=$SERVICE_PREFIX/namespaces/ks-prod/services/guestbook-ui
    
     open $PROD_GUESTBOOK_URL
  5. 放入版本控制:
    git add .
     git commit -m "add prod env"

     

說明

Environments容許部署manifests的公共集合到不一樣的環境之中,若是不清楚如何使用,考慮下面的一些使用場景:

  • 發佈版本管理(dev vs test vs prod)
  • 多個部署點 (us-west-2 vs us-east-1)
  • 多個雲計算環境(AWS vs GCP vs Azure)

環境是分級的,處理多重環境,能夠嵌套 us-west-2/dev 和 us-east-1/prod。在下面將會進一步看到,能夠經過指定環境的參數覆蓋其base/parent environments。

5. 經過參數自定義environment

很好,將一樣的 manifests 部署到多個環境簡直是太棒了。可是,不少時候環境會有一些小小的差異。

能夠經過參數來定製環境,至此,咱們在 ks generate設置過參數, 將參數傳入命令行來定製化一個新的component。這裏,咱們將進一步展現,能夠在特定的environments中改變這些個參數。

定義 「parameters」

參數能夠設置在 entire app 或 per-environment。本教程中,全部的參數針對於component。未來的教程將着重於global parameters,可以在多個components間共享。

 ks param 命令更新本地Jsonnet files, 所以將總會有一個版本控制的表明,表明 ks apply 中的Kubernetes cluster。

命令

  1. 查看environments’ parameters的區別
    ks param diff dev prod
  2. 設置環境關聯的參數:
    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

     

  3. 經過param diff 查看參數差別:
    ks param diff dev prod

     

  4. 好了,如今部署到兩個environments (注意,是同一個cluster):
    ks apply dev && ks apply prod
  5. 查看兩個環境下 dev 和 prod的差別:
    ks diff remote:dev remote:prod

     

  6. 比較兩個 guestbook UIs (dev 看起來有些不同):
    # Check out dev guestbook
     open $GUESTBOOK_URL
    
     # Make sure that the changes didn't affect prod
     open $PROD_GUESTBOOK_URL
  7. 再次,將配置文件版本化:
    git add .
     git commit -m "update guestbook-ui parameters"

說明

經過參數化的能力,environments容許應用的拷貝在不一樣的集羣和命名空間部署的能力。使用parameters,你能夠微調參數部署到每個環境,不管是不一樣的載入requirements仍是精確的labels。

6. 組裝到一塊兒

你已經使用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)?) [+]

問題解決

ERROR user: Current not implemented on linux/amd64

If you encounter this error when running the ksonnet Linux binary, you can temporarily work around it by setting the USERenvironment 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.

Github rate limiting errors

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.

  1. Go to https://github.com/settings/tokens and generate a new token. You don’t have to give it any access at all as you are simply authenticating.
  2. Make sure you save that token someplace because you can’t see it again. If you lose it you’ll have to delete and create a new one.
  3. Set an environment variable in your shell: export GITHUB_TOKEN=<token>. You may want to do this as part of your shell startup scripts (i.e. .profile).
相關文章
相關標籤/搜索