ksonnet 使用教程

ksonnet - 使用教程

Ksonnet是编写和配置KUBERNETES配置文件的流程化方法的支持工具。

所使用的关键的ksonnet concepts包括:

  1. Prototypes 和 parameters 组合形成 components。
  2. 多个 components 组合为 app。
  3. 一个app可以部署到多个environments。
  4. 不同的environments的差异通过参数来指定。

概述

本教程不需要 ksonnet的预先知识,不需要对Kubernetes非常熟悉,但会非常有用。kubectl apply用于将应用提交到 Kubernetes clusters。

  • 与Helm的区别:
    • Helm主要管理Pakages级别的应用组件,以Chart格式描述,在安装时需要根据不同环境将其定制化、改变参数。
    • Ksonnet的配置参数按照环境env来组织,可以直接部署到相应的集群。

我们构建了什么?

在本教程中,我们将进行一个在集群中使用ksonnet配置和运行一个基本的web app的步骤。该应用基于 classic Kubernetes guestbook example,通过简单的消息提交查询。当部署后,guestbook看起来如下:

通过这一过程,你将看到 ksonnet workflows的通用过程,学习到最佳实践,理解 ksonnet 概念,从而通过编写 Kubernetes manifests实现流水线的处理。

额外的内容

如果有任何下面的问题,可以到这里了解更多(参考https://ksonnet.io/docs/tutorial)。

如果还有其它的问题,希望帮助我们改进,通过 raising a documentation issue.

好,现在准备开始!

0. 预先准备

开始之前,确保:

  • 本地安装了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的内容并且自动化特定的工作流程。

2、创建和部署应用组件

现在我们的应用有了一个工作目录,可以添加用于部署的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).

转载于:https://my.oschina.net/u/2306127/blog/1808581

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值