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).
相关文章
相关标签/搜索