Help us understand the problem. What is going on with this article?

zlabjp/kubernetes-resource を使う

More than 1 year has passed since last update.

概要

今日は、zlabjp/kubernetes-resource を実際に使うというのをやります。kubernetes-resource は、k8s にアプリケーションをデプロイするための concourse リソースです。ゼットラボで必要に迫られて作って、それから便利に使っています。@superbrothers による初日の記事の通りです。ツールというのは、あれこれ触ってみると理解が進みます。手元に k8s クラスタと concourse があって、GitHub と Docker Hub を利用できる環境であれば、同じことができるはずです。よかったら一緒にやりましょう。

やること

あらかじめ k8s に nginx-1.13.6 をデプロイしておいて、concourse から nginx-1.13.7 にアップデートします。あらかじめの方は、手元の PC から個人の権限でデプロイします。アップデートの方は、GitHub リポジトリの Tag の作成をトリガーにして、concourse から ServiceAccount の権限でデプロイします。k8s と kubectl のバージョンは、ともに v1.7.11 を使います。大きくは、準備して実行するだけです。

準備

GitHub → k8s → concourse の順に準備します。

GitHub

今回は、bhiro/myproject というリポジトリを新しく Private で作りました。README.md もリポジトリと一緒に作りました。これを手元の PC に git clone します。

$ git clone git@github.com:bhiro/myproject.git
$ cd myproject

このリポジトリを concourse から Read するための Deploy key を作成します。Deploy Key の実体は、SSH キーペアです。このキーペアは、concourse が使います。パスフレーズは設定してはいけません。no passphrase でないと concourse のジョブが失敗します。作成した鍵は、secrets ディレクトリに保存します。

$ mkdir secrets
$ ssh-keygen -t rsa -b 4096 -C "" -f secrets/id_rsa

公開鍵は、GitHub リポジトリの Deploy Keys に Read only の設定で登録します。秘密鍵は、あとで concourse パイプラインに登録します。

secrets
├── id_rsa
└── id_rsa.pub

secrets ディレクトリは、誤って Git にコミットしないように、.gitignore に書いておきます。

/secrets

k8s

定義ファイルを作ってから、k8s リソースを作ります。

定義ファイル

k8s の定義ファイルを作ります。作り終えると、手元の PC のディレクトリは、以下のようになります。

myproject
├── .git
├── .gitignore
├── README.md
├── deploy
│   └── nginx-deploy.yaml
├── k8s
│   ├── 0_ns.yaml
│   ├── role.yaml
│   ├── rolebinding.yaml
│   └── sa.yaml
└── secrets
    ├── id_rsa
    └── id_rsa.pub

k8s ディレクトリには、クラスタ向けの定義ファイルを置きます。deploy ディレクトリには nginx 向けの定義ファイルを置きます。以下は、定義ファイルの一覧です。

定義ファイル リソース種別 リソース名
k8s/ns.yaml Namespace dev
k8s/sa.yaml Service Account deploy
k8s/role.yaml Role deploy
k8s/rolebinding.yaml RoleBinding deploy
deploy/nginx-deploy.yaml Deployment nginx

ファイルの内容は以下の通りです。

dev ネームスペースです。

k8s/ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: dev

deploy という ServiceAccount と Role を作って、それらをバインドします。これらのリソースは、dev ネームスペースに置きます。

k8s/sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: deploy
  namespace: dev
k8s/role.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: deploy
  namespace: dev
rules:
- apiGroups: [""]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["extensions"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["autoscaling"]
  resources: ["*"]
  verbs: ["*"]
k8s/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: deploy
  namespace: dev
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: deploy
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: system:serviceaccount:dev:deploy
  namespace: dev

nginx-1.13.6 をデプロイするための、Deployment です。

deploy/nginx-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.13.6
        name: nginx

リソース

kubectl コマンドを使って、手元の PC から k8s リソースを作ります。先にクラスタ向けのリソースを作ります。

$ kubectl apply -f k8s/

それから、nginx 向けのリソースを作ります。

$ kubectl apply -f deploy/ --namespace=dev

すでに定義ファイルがあるので簡単ですね。
pod が Running で nginx-1.13.6 のイメージなら OK です。

$ kubectl get pod --namespace=dev
NAME                     READY     STATUS    RESTARTS   AGE
nginx-1161159442-nlvzx   1/1       Running   0          5m

$ kubectl describe pod nginx-1161159442-nlvzx --namespace=dev |grep 'Image:'
Image:          nginx:1.13.6

concourse

定義ファイル

concourse の定義ファイルを作ります。作り終えると、手元の PC のディレクトリは、以下のようになります。

myproject
├── .git
├── .gitignore
├── README.md
├── concourse
│   └── pipeline.yaml
├── deploy
│   └── nginx-deploy.yaml
├── k8s
│   ├── 0_ns.yaml
│   ├── role.yaml
│   ├── rolebinding.yaml
│   └── sa.yaml
└── secrets
    ├── concourse-secrets.yaml
    ├── id_rsa
    └── id_rsa.pub

concourse ディレクトリにパイプライン向けの定義ファイルを置きます。秘密情報は、Git にコミットされないように secrets ディレクトリに置きます。以下は、定義ファイルの一覧です。

定義ファイル
concourse/pipeline.yaml
secrets/concourse-secrets.yaml

pipeline.yaml の内容は以下の通りです。

最初に kubernetes-resource の定義があります。tag は、デプロイ先の k8s のマイナーバージョンに合わせてセットします。今回のデプロイ先は k8s-v1.7.11 なので、tag: "1.7" としています。{{key}}{{config}} は秘密情報です。パイプライン作成時に、concourse-secrets.yaml から展開します。

concourse/pipeline.yaml
resource_types:
- name: kubernetes
  type: docker-image
  source:
    repository: zlabjp/kubernetes-resource
    tag: "1.7"

resources:
- name: myproject
  type: git
  source:
    uri: git@github.com:bhiro/myproject.git
    branch: master
    tag_filter: v*
    private_key: {{key}}

- name: myk8s
  type: kubernetes
  source:
    kubeconfig: {{config}}

jobs:
- name: deploy
  serial: true
  plan:
  - get: myproject
    trigger: true
  - put: myk8s
    params:
      kubectl: apply -f myproject/deploy --namespace=dev
      wait_until_ready_selector: app=nginx

次に、concourse-secrets.yaml を作ります。

concourse-secrets.yaml には、GitHub リポジトリを Read するための Deploy Key と、k8s クラスタを操作するための kubeconfig を記入します。Deploy key には、GitHub の準備で作成した SSH キーペアの秘密鍵を使います。

$ cat secrets/id_rsa > secrets/concourse-secrets.yaml
$ chmod 600 secrets/concourse-secrets.yaml

kubeconfig は、zlabjp/kubernetes-scripts に含まれる create-kubeconfig というツールを使ってジェネレートします。create-kubeconfig の引数は ServiceAccount 名です。k8s の準備で dev ネームスペースに作成した deploy サービスアカウント を渡します。

$ curl -LO https://raw.githubusercontent.com/zlabjp/kubernetes-scripts/master/create-kubeconfig
$ chmod +x ./create-kubeconfig
$ mv ./create-kubeconfig /tmp/
$ /tmp/create-kubeconfig deploy --namespace=dev >> secrets/concourse-secrets.yaml

key と config をキーとして yaml に整形します。ここは、エディタの矩形編集を使って頑張ります。

secrets/concourse-secrets.yaml
key: |
  -----BEGIN RSA PRIVATE KEY-----
  ....
  ....
  -----END RSA PRIVATE KEY-----

config: |
  apiVersion: v1
  ....
  ....
  token: ....

これで、全ての定義ファイルが揃いました。最後に GitHub に Push しておきます。

$ git add -A
$ git commit -m "create definition files"
$ git push origin master

パイプライン

fly コマンドを使って、手元の PC から concourse のパイプラインを作ります。${URL}${TEAM} は、環境に合わせてセット下さい。ターゲット名とパイプライン名は任意です。今回はそれぞれ dev, myproject としています。

$ fly --target dev login --concourse-url ${URL} --team-name ${TEAM}
$ fly --target dev set-pipeline --pipeline myproject --config concourse/pipeline.yaml --load-vars-from secrets/concourse-secrets.yaml
$ fly --target dev unpause-pipeline --pipeline myproject

すでに定義ファイルがあるので簡単ですね。
UI や コマンドラインからパイプラインが確認できれば OK です。

$ fly --target dev pipelines

実行

実行は、準備よりだいぶ簡単です。GitHub リポジトリ の Tag の作成をトリガーにして、k8s 上の nginx-1.13.6 を concourse から nginx-1.13.7 にアップデートします。

nginx-deploy.yaml を以下のように変更します。

git diff deploy/nginx-deploy.yaml
diff --git a/deploy/nginx-deploy.yaml b/deploy/nginx-deploy.yaml
index ec17270..4a8c9a9 100644
--- a/deploy/nginx-deploy.yaml
+++ b/deploy/nginx-deploy.yaml
@@ -14,5 +14,5 @@ spec:
         app: nginx
     spec:
       containers:
-      - image: nginx:1.13.6
+      - image: nginx:1.13.7
         name: nginx

コミットして push します。

$ git add deploy/nginx-deploy.yaml
$ git commit -m "update nginx"
$ git push origin master

最後に Tag を切ります。

$ git tag v0.0.1
$ git push origin v0.0.1

これを、トリガーに concourse の job が動きます。

$ fly --target dev builds|grep myproject
2674  myproject/deploy 1   succeeded  2017-12-06@20:04:26+0900  2017-12-06@20:04:48+0900  22s

22秒で終わりました。成功したようです。UI も job の成功を表す緑色になっています。

image.png

k8s を確認します。

$ kubectl get pod --namespace=dev
NAME                     READY     STATUS    RESTARTS   AGE
nginx-3944497639-tzk71   1/1       Running   0          3m

$ kubectl describe pod nginx-3944497639-tzk71 --namespace=dev |grep 'Image:'
    Image:          nginx:1.13.7

確かに、nginx-1.13.7 にアップデートされています。

まとめ

今日は、zlabjp/kubernetes-resource を使って、concourse から k8s へのデプロイをやりました。CI や CD の準備というのは大変なものですが、組み終わって、動き出すと、なんとも気持ちのいいものです。ぜひ、お試しください。

おわりに

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

zlab
技術で新しい世界へシフトする。
https://zlab.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした