kubernetesを学ぶ~その4:マニフェスト・コントローラ~


目次

  1. 前回のあらすじ
  2. マニフェストについて
  3. コントローラについて
  4. 用語について
  5. あとがき

前回のあらすじ

 前回のkubernetesを学ぶ~その3~は、kubectlについて記載してみた。ほんの一部分だけであったが基本を抑えることが大事だと思う。特に私のようなK8s未経験者にとっては基本を忠実にすることが大事かと。あれ?部活みたい。

マニフェストについて

 K8sのオブジェクトを生成するためにオブジェクトに対応したAPIやメタ情報をYAML形式やJSON形式で書かれた宣言書のことをいいます。色んな情報ググったり体験談を拝見すると運用ではマニフェストでポッドの起動とかしないみたい。理由としては、運用でよく使うのが「コントローラ」であり、コントローラのマニフェストにポッドの雛形を記述した部分があるからだそうです。なるほど。コントローラについては、別でやろう。

形式の選択

 YAML形式か、JSON形式かどちらにしようか検討する時、読みやすさやぱっと見のわかりやすさ(可読性)からYAML形式がよいと思います。

書き方

 手始めに書き方を学ぶため、ポッドを起動するマニフェストを作ってみる。ホントはコントローラから作るのがいいんですが、基本を知るということでお許しを。別途やります。
test.ymlは、OpenLiteSpeedのポッドを作るマニフェストです。

test.yml
apiVersion: v1
kind: Pod
metadata: 
 name: litespeed
spec: 
 containers: 
  - name: litespeed
    image: indeedplusplus/openlitespeed:latest
1行目
apiVersion: v1
→キー(左側)と値(右側)で構成

・apiVersionは、オブジェクトが管理されているバージョンを指定します。
※キーや値については、K8s APIリファレンスを確認ください。

あと、よくやってしまうのですが、:(コロン)の右側に半角スペースが必要です
これがないと、正しく認識しません。
※何度も「あれー? error parsingでたー。あぁ、半角スペースすぅ~(´;ω;`)」となっちゃった。何か気づく方法ないかな。

さらに、キーの大文字小文字も一致させないとエラーになっちゃった。

2~4行目
kind: Pod
metadata:
 name: litespeed

・kindは、クライアントからリクエストを送るときのRESTリソースを表す文字を指定します。ポッド作るようにしたので、Podです。
・metadataは、オブジェクトのメタデータを指定します。必須項目のnameはポッドのオブジェクト名になります。なので、名前空間内で一意にする必要があります。
・metadata:を改行して半角スペースでインデントすると、ネストできます。
ハッシュなので、metadataというキーに対して、{name: litespeed}とハッシュが値になります。

5~8行目
spec: 
 containers: 
  - name: litespeed
    image: indeedplusplus/openlitespeed:latest

・specは、kindで指定した値の仕様を記述します。
・containersは、ポッドで動かくコンテナの起動条件などを記述します。
・nameの左にハイフンがありますが、これは配列を表します。

例の場合、要素数は1つだけ。
ちなみに、imageの左にハイフンをつけると要素数が2つになります。いや、この場合つけないけど。

なお、1つのポッドに2つコンテナが存在するサイドカーの構成では、containersの配列に複数コンテナを記述します。

複数コンテナの例
spec: 
 containers: 
  - name: litespeed #メインコンテナ
    image: indeedplusplus/openlitespeed:latest
  - name: cloner    #サイドカーコンテナ
    image: maho/c-cloner:0.1

その他にもボリュームをコンテナのファイルシステムにマウントする設定や、環境変数をコンテナに設定するキー項目があります。更に学んでいくと使うので、ここでは省略。

コントローラについて

 コントローラはポッドの実行を制御するオブジェクト。
いくつも種類があって、デプロイメントコントローラやジョブコントローラなどがあります。

デプロイメントコントローラ

 Webサーバやアプリケーションサーバのようなサービス提供を継続するサーバに適しています。理由としては、ポッドの稼働数や不要なポッドの後始末をするので負荷が増えたり減ったりアクセス変化が激しい機能に向いているのかと。

まずは、デプロイメントコントローラを作ってみます。

D:\Repository\kubernetes\vagrant-kubernetes>kubectl create deployment --image=hello-world hello-world
deployment.apps/hello-world created

確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get all
NAME                               READY   STATUS      RESTARTS   AGE
pod/hello-world-7fd49b7477-rgl9v   0/1     Completed   2          40s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.32.0.1    <none>        443/TCP   2d23h

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/hello-world   0/1     1            0           40s

NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/hello-world-7fd49b7477   1         1         0       40s

4つオブジェクトができました。
pod/hello-world-7fd49b7477-rgl9vは、ポッド
service/kubernetesは、サービス
deployment.apps/hello-worldは、デプロイメントコントローラ
replicaset.apps/hello-world-7fd49b7477は、レプリカセット
です。

サービスは、別途学ぶとしてレプリカセット?

レプリカセット

 ポッドの稼働数を目的の数になるように制御するオブジェクトです。
デフォルトでポッドの稼働数は1つだけって設定されています。なので、増やしてみましょう。

確認します。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get pods
NAME                           READY   STATUS             RESTARTS   AGE
hello-world-7fd49b7477-5pm66   0/1     CrashLoopBackOff   4          2m55s

3つに増やします。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl scale --replicas=3 deployment/hello-world
deployment.extensions/hello-world scaled

確認します。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get pods
NAME                           READY   STATUS             RESTARTS   AGE
hello-world-7fd49b7477-5pm66   0/1     CrashLoopBackOff   5          3m51s
hello-world-7fd49b7477-dkxzv   0/1     CrashLoopBackOff   1          11s
hello-world-7fd49b7477-tzqjh   0/1     CrashLoopBackOff   1          11s

増えたー!!!この制御をしているのが、レプリカセットだということです。
※ちなみにSTATUSがCompletedになっていないのは訳があるのでスルーしててください。describeで確認したらLast State:のexitコードは0デス。

もとに戻します。

1つになーれ。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl scale --replicas=1 deployment/hello-world
deployment.extensions/hello-world scaled

2つ抹殺されていっています。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get pods
NAME                           READY   STATUS             RESTARTS   AGE
hello-world-7fd49b7477-5pm66   0/1     CrashLoopBackOff   7          16m
hello-world-7fd49b7477-dkxzv   0/1     Terminating        7          12m
hello-world-7fd49b7477-tzqjh   0/1     Terminating        7          12m

1つ生き残りました。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get pods
NAME                           READY   STATUS             RESTARTS   AGE
hello-world-7fd49b7477-5pm66   0/1     CrashLoopBackOff   8          20m

ジョブコントローラ

 デプロイメントコントローラで利用したイメージは、メッセージを出力したら終了する処理だったので、コンテナもメッセージ出力、そして終了!というバッチ処理だったので、コンテナ終了する→レプリカセットが目標数の1にしなきゃ!生成!!ってやっていたので、CrashLoopBackOffが表示されてました。describeで確認した内容を見たらそんな感じです。
 バッチ処理にはジョブコントローラです。

まずは、ジョブコントローラを作ってみます。

ジョブコントローラ作成
D:\Repository\kubernetes\vagrant-kubernetes>kubectl create job hello-world --image=hello-world
job.batch/hello-world created

確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get all
NAME                    READY   STATUS      RESTARTS   AGE
pod/hello-world-b6wg6   0/1     Completed   0          105s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.32.0.1    <none>        443/TCP   3d

NAME                    COMPLETIONS   DURATION   AGE
job.batch/hello-world   1/1           5s         105s

pod/hello-world-b6wg6は、ポッド
job.batch/hello-worldは、ジョブコントローラですね。
ジョブコントローラのCOMPLETIONSが1/1になっているので、ジョブが完了していますね。

ジョブ消します。

ジョブさようなら
D:\Repository\kubernetes\vagrant-kubernetes>kubectl delete job hello-world
job.batch "hello-world" deleted

確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.32.0.1    <none>        443/TCP   3d

用語について

REST
 REST(REpresentational State Transfer)はWebサービスの設計モデルです。このモデルで作ったサービスのURIにHTTPメソッドでアクセスすることでデータの送受信を行います。
サイドカーコンテナ
 主となるコンテナと共にそれを補助する役割を果たすコンテナです。

あとがき

 アーキテクチャを把握しながらやっていたので、結構時間がかかったなー。Hello-worldのイメージ使ってたらSTATUSがCompletedにならなかったので原因調査をずーっとしてたw。色々調べたりしてコントローラの使い分けかーって身を持って体験したので良かったと思う。※そもそもHello-worldが何してるか先に調べろよってw
 次は、ヘルスチェックについて学ぼうと思う。

参考文献

プログラマーのための YAML 入門 (初級編)
15Stepで習得Dockerから入るKubernetes
API OVERVIEW