Edited at
Z LabDay 1

zlabjp/kubernetes-resource: Kubernetes を操作する Concourse リソース

More than 1 year has passed since last update.


概要

ゼットラボではいくつかの CI/CD ツールを利用していますが、その中の一つが Concourse です。Concourse はパイプラインベースの CI/CD ツールで Pivotal により開発されています。Concourse から Kubernetes にアプリケーションをデプロイするための Concourse リソースに我々の要件を満たすものが存在しなかったため、新たに開発し OSS (MIT License) として公開しています。


Kubernetes にどのようにアプリケーションをデプロイするか

Kubernetes にアプリケーションをデプロイするには Kubernetes を操作するための CLI である kubectl を利用します。


  • kubectl run: 特定のコンテナイメージをクラスタで実行する

  • kubectl create: リソースを作成する(既に作成済の場合は実行に失敗する)

  • kubectl delete: リソースを削除する

  • kubectl apply: リソースに設定を適応する

  • kubectl get: 一つまたは複数のリソースの情報を表示する

この他にも多くのサブコマンドが用意されており、これらを組み合わせてアプリケーションをデプロイします。Kubernetes はアプリケーションの構成を Pod, Service, Volume など複数の「リソース」を組み合わせて表現します。そのため、デプロイというのはリソースを操作することと同義です。

これらのサブコマンドを駆使してリソースを管理する手法を3つ紹介します。


Imperative command

Imperative command はおもに kubectl run などの一度限りのコマンドを利用してアプリケーションをデプロイする方法です。以下の例は、nginx:latest イメージをレプリカ数5で myapp という名前で作成します。この手法はアプリケーションの設定を詳細に設定できないため、開発用途など一時的に実行したい場合に利用します。

# Start a replicated contianer of nginx

$ kubectl run myapp --image=nginx:latest --replicas=5


Imperative object configuration

Imperative object configuration はリソースの設定をマニフェストファイルとして YAML または JSON としてファイルに記載し、kubectl createkubectl delete などを利用してリソースを作成、削除します。この方法は Imperative command と比較してアプリケーションの設定をファイルとして記載するため、バージョン管理することができます。ただしこれらのコマンドはリソースが既に作成されていたり、削除されていて存在しない場合に実行に失敗します。

# Create a resource by a manifest file

$ kubectl create -f nginx-deployment.yaml


Declarative object configuration

Declarative object configuration をマニフェストファイルを kubectl apply のみを利用してリソースを作成、削除します。kubectl applykubectl create と比較して既にリソースが存在していればそれを更新し、存在していなければ作成します。また更新方法も他のコマンドによるリソースの操作に干渉しないものとなっており、CD としてアプリケーションを継続的にデプロイするにはもっとも適しています。

# Create/Update a resource by a manifest file

$ kubectl apply -f nginx-deployment.yaml

kubectl apply の挙動についてより詳しく知りたいなら kubectl apply の仕組み / How kubectl apply works を参照してください。


Concourse で Kubernetes にアプリケーションを継続的にデプロイする

Concourse から Kubernetes を操作するには zlabjp/kubernetes-resource を利用できます。これは Concourse リソースとして動作し、クラスタに対して kubectl を使った任意のコマンドを実行できます。またアプリケーションをデプロイする上で便利な機能を備えています。


Versions

このリソースは下記のような複数のバージョンを提供しています。バージョンは kubectl のバージョンと紐付いているため、Kubernetes クラスタのバージョンと同一のバージョンを利用することを推奨します。


ソース設定

kubeconfig ファイルを直接渡す方法とクラスタコンフィグを個々に設定する方法の二つを提供します。


kubeconfig



  • kubeconfig: 任意. kubeconfig ファイル
    yaml
    kubeconfig: |
    apiVersion: v1
    clusters:
    - cluster:
    ...


kubeconfig ファイルの生成には zlabjp/kubernetes-scripts に含まれる create-kubeconfig スクリプトを利用すると便利です。

# Create a kubeconfig to access the apiserver with the specified serviceaccount and outputs it to stdout.

$ ./create-kubeconfig <serviceaccount-name> <kubectl-options>


クラスタ設定



  • server: 任意. API サーバとアドレスとポート。token が必須です。 (e.g. https://192.168.99.100:8443


  • token: 任意. API サーバの認証に利用するトークン。server が必須です。 (e.g. eyj....


  • namespace: 任意. ネームスペース。デフォルトは default です。


  • certificate_authority: 任意. 認証局の証明書です。


  • insecure_skip_tls_verify: 任意. もし true なら、API サーバの証明書の有効性を確認しません。HTTPS が安全ではなくなります。デフォルトは false です。


動作

out のみの実装です。


check: 何もしない


in: 何もしない


out: Kubernetes クラスタを操作する

kubectl applykubectl delete, kubectl label などのような Kubernetes クラスタの操作を行う。


パラメータ



  • kubectl: 必須. kubectl に続く任意のコマンドを指定します。(e.g. apply -f ...


  • wait_until_ready: 任意. 全ての Pods が Ready になるまで待機する秒数です。0 なら待機しません。デフォルトは 30 です。


  • wait_until_ready_interval: 任意. 全ての Pods が Ready かどうか確認する間隔(秒)です。デフォルトは 3 です。


  • wait_until_ready_selector: 任意. Ready かどうか確認する Pods を絞り込むラベルセレクタです。デフォルトはネームスペース内の全ての Pods です。

Kubernetes は非同期の分散システムのため、リソースの操作はスペックさえ満たしていればコマンドとしては成功しますが、実際には例えばコンテナイメージのバージョンが存在しないものが指定されている場合などデプロイに失敗している場合があります。そのような場合にジョブを失敗させるために wait_until_ready を用意しています。これはそのネームスペースの Pod が Running になるまで待機します。もし指定された時間内に Pod が全て Running にならなければジョブが失敗します。対象の Pod を絞り込むには wait_until_ready_selector を利用してください。またこの機能によってデプロイ後に e2e テストを実施する場合にコンテナが起動する前にテストを実行してしまうことを防ぐことができます。


パイプライン例

repo リポジトリに含まれるマニフェストファイルの更新をトリガに prod クラスタに対して kubectl apply を実行しています。

image.png

resource_types:

- name: kubernetes
type: docker-image
source:
repository: zlabjp/kubernetes-resource
tag: "1.8"
resources:
- name: prod
type: kubernetes
source:
kubeconfig: ((prod-kubeconfig))
- name: repo
type: git
source:
...
jobs:
- name: prod-deploy
plan:
- get: repo
trigger: true
- put: prod
params:
kubectl: apply -f repo/deploy -f repo/deploy/prod
wait_until_ready_selector: app=myapp

kubectl パラメータはコマンド置換に対応しているため、下記のような使い方もできます。

jobs:

- name: force-update-deployment
serial: true
plan:
- put: mycluster
params:
kubectl: |
patch deploy nginx -p '{"spec":{"template":{"metadata":{"labels":{"updated_at":"'$(date +%s)'"}}}}}'
wait_until_ready_selector: run=nginx


まとめ

zlabjp/kubernetes-resource は Kubernetes クラスタを操作する Concourse リソースです。kubectl のさまざまなサブコマンドを駆使してクラスタを操作することができます。下記リポジトリにこのリソースを利用したデモのパイプラインを用意しています。こちらも参考にしてください。


おわりに

このエントリは、弊社 Z Lab のメンバーによる Z Lab Advent Calendar 2017 の一日目として業務時間中に書きました。二日目は @Ladicle による Istio 入門です。


参考