Open13

k8s小ネタ集(超絶メモ書き)

ymz_noteymz_note

kubectl get pod で表示される STATUS と意味

  • ContainerCreating
    イメージをダウンロード中、またはコンテナ起動進行中を表す。
    また、ConfigMap や Secret をマウントできず、コンテナ生成が保留された時にもこの値が表示される。
  • CrashLopBackOff
    ポッド内のコンテナが終了し、起動まで待機状態にある。
    2回以上コンテナが終了すると、CrashLoopBackOff 時間を取るようになる、
    これが表示されたら、コンテナ内のプロセスを見直する必要がある。
  • Pending
    ポッド生成の要求を受け取ったが、一つ以上のコンテナが作成されていない状態。
    リソース不足やポリシーの制約によってスケジュールできないケースも含まれる。
  • Running
    ノードに対応つけられ、すべてのコンテナが作成された。
    または、少なくとも一つのコンテナが実行中、開始中、または再起動中。
  • Terminating
    コンテナへ終了要求シグナルを送信後、コンテナが終了するまでの待機時間。
    猶予時間を過ぎてもコンテナが終了できない場合は、コンテナを強制終了する。
  • Succeeded
    ポッド内のすべてのコンテナが正常に終了した。
  • Completed
    ポッド内のコンテナが正常終了し、存在している状態。
    ポッドは削除されるまで存在し続け、ポッド名を指定してログやステータスを取得できる。
    ポッド内に複数のコンテナがある場合は、第一次コンテナが正常終了(exircode = 0)すると、ポッドは正常終了として扱われる。
  • Error
    コンテナが異常終了した。
    exitcode = 0以外の時に異常終了とみなされる。
    ポッド内に複数のコンテナがある場合は、第一コンテナが異常終了すると、ポッドは異常終了として扱われる。
  • Failed
    ポッド内の少なくとも一つのコンテナが異常終了した。
  • Unknown
    何らかの理由により、ポッドの状態を取得できない状態である。
    ノード障害内度で、マスターからノードの状態を取得できなくなった時にも、この表示内容となる。
ymz_noteymz_note

k8s の「サービス」の役割

  1. サービスは LB の夜話区割りを持ち、ポッドを代表数r IP アドレスを獲得しtえ、クライアントのリクエストを受ける。
  2. サービスはオブジェクト生成時に、サービス名と代表 IP アドレスを内部 DNS へ登録する。これによりクライアントは、サービス名からその代表 IP アドレスを名前解決することができる。
  3. サービスがリクエストを転送するべきポッドw選別するために、サービスのセレクターにセットされたラベルと一致するポッドを選び出し、その IP アドレスへリクエストを転送する。
  4. サービスのオブジェクト存在時に起動されるポッドのコンテナには、サービスへアクセスするための環境変数が自動的に設定されるようになる。
  5. サービスには4種類のサービスタイプがあり、クライアントの範囲を k8s クラスタの内部とどめるか、外部まで対象とするか、また反対に k8s クラスタ外部の IP アドレスへ転送するかを設定する。
ymz_noteymz_note

ラベルとは

ポッドやオブジェクトに付与されたキーバリューのペアのこと。

ymz_noteymz_note

k8s の「コントローラ」タイプ

  • Deployment
    対等な関係にある複数のポッドで水平クラスタを構成できる。
    ポッドの起動と停止を迅速に実行す両振る舞い、稼働中のポッドの順次置き換え、オートスケーラーとの連動、更に高可用性構成が可能という特徴があり、オールラウンドに適用できる
  • StatefulSet
    ポッドと永続ボリュームの組み合わせで制御を行い、永続ボリュームの保護を優先する。
    ポッドをシリアル番号で管理し、永続ボリュームとポッドの対応関係を維持し、起動と停止の順序を制御するなどの特徴があり、永続データの処理に適している
  • Job
    バッチ処理なコンテナが正常終了するまで再試行を繰り返すコントローラ。
    ポッドの実行回数、同時実行数、試行回数の上限を設定して実行/さくじょされるまでログを保持するといった特徴があり、科学計算などのバッチ処理に適している
  • CronJob
    時刻指定で定期的に前述の「Job」を生成する。
    UNIX の cron と同じ形式。定期的にじっこうしなければならないバッチ処理に適している
  • DaemonSet
    k8s クラスタの全ノードで、同じポッドを実行するためにある。
    例えば、ポッドネットワークを構成するデーモンセット管理下のポッドは、ノードを追加すると自動的に稼働を開始し、追加されたノードを利用できるようになる。システム運用の自動化に適している
  • ReplicaSet
    デプロイメントコントローラと連動して。ポッドのレプリカ数の管理を担当する。
    デプロイメント(Deployment)を通じて利用することが推奨されている
  • replicationController
    次世代のコントローラであるデプロイメントの利用が推奨されている
ymz_noteymz_note
ワークロードのタイプ コントローラのタイプ 対応するテーマ
フロントエンド処理 Deployment デプロイメント、オートスケール、イングレス、サービス
バックエンド処理 StatefulSet ステートフルセット、永続ボリューム、サービス
バッチ処理 Job, CronJob ジョブとクーロンジョブ
システム運用 DaemonSet ステートフルセット、クラスタの仮想化
ymz_noteymz_note

Docker コマンドチートシート

コンテナ環境の表示

#dockerクライアントとサーバのバージョン
docker version

#環境情報を表示
docker info

コンテナイメージのビルド

#カレントディレクトリのDockerfileからイメージをビルドする
docker image build -t <リポジトリ>:<タグ> .

#ローカルのイメージをリストする
docker image ls

#ローカルのイメージを削除する
docker image rm <イメージ>

#ローカルのイメージを一括削除する
docker image prune -a

イメージの移動と共有

#リモートリポジトリのイメージをローカルリポジトリへダウンロードする
docker pull <リモートリポジトリ>:[タグ]

#ローカルのイメージをリモートに対応つけることで、docker push でリモートリポジトリへ転送できるようにする
docker image tag <イメージ>:[タグ] <リモートリポジトリ>:[タグ]

#レジストリサービスへログインする
docker login <レジストリサーバ>

#ローカルのイメージをレジストリサービスのリポジトリへ転送する
docker image push <リモートリポジトリ>:[タグ]

#イメージをアーカイブ形式のファイルとして書き出す
docker save -o <ファイル名> <イメージ>

#アーカイブ形式のファイルをリポジトリへ登録する
docker limage load -i <ファイル名>

#コンテナ名またはコンテナIDでコンテナを指定して、tar形式のファイルへ書き出す
docker container export <コンテナ名 | コンテナID> -o ファイル名

#tar形式ファイルをリポジトリのイメージ展開する
docker image import <ファイル名> <リポジトリ>:[タグ]

コンテナの実行

#対話型でコンテナを起動してコマンドをじっこ数r。終了時にはコンテナを削除する。コマンドにshうあbashを指定するとサーバにログインした時のような対話型のシェルでOSコマンドを実行可能
docker container run --rm -it <イメージ> <コマンド(sh, bash)>

#バックグラウンドでコンテナを実行する。コンテナ内プロセスの標準出力や標準エラー出力は、ログに保存される。保存されたログの表示についてはdocker logsで参照
docker container run -d -p <コンテナ公開ポート番号>:<コンテナ内プロセスの公開ポート番号> <イメージ>

#コンテナに名前を与えてイメージを実行する
docker container run -d <コンテナ名> -p <コンテナ公開ポート番号>:<コンテナ内プロセスの公開ポート番号> <イメージ>

#コンテナのファイルシステム編ディレクトリをマウントして実行する
#-vで指定するのは、<ローカル絶対パス>:<コンテナ内のパス>
docker container run -v `pwd`/html:/usr/share/nginx/html -d -p <コンテナ公開ポート番号>:<コンテナ内プロセスの公開ポート番号> <イメージ>

#実行中コンテナに対して、対話型コマンドを実行する
docker container exec -it <コンテナ名 | コンテナID> bash

#実行中のコンテナをリストする
docker container ls

#停止コンテナも含めてリストする
docker container ls -a

#コンテナのメインプロセスへシグナルSIGTERMによる終了要求を送り、その後、タイムアウトすると強制終了する
docker container stop <コンテナ名>

#コンテナを強制終了する
docker container kill <コンテナ名 | コンテナID>

#コンテナを削除する
docker container rm <コンテナ名 | コンテナID>

#終了したコンテナを一括削除する
docker container prune -a

#コンテナをイメージとしてリポジトリへ書き込む
docker container commit <コンテナ名 | コンテナID> <リポジトリ>:[タグ]

デバッグ関連の機能

#コンテナのログを表示する
docker container logs <コンテナ名 | コンテナID>

#コンテナのログをリアルタイムに表示する
docker container logs -f <コンテナ名 | コンテナID>

#コンテナの停止理由を表示する
docker container ls -a

#実行中コンテナに対して対話型でコマンドを実行する
docker container exec -it <コンテナ名 | コンテナID> bash

#低レベルコンテナ情報を表示する
docker container inspect <コンテナ名 | コンテナID>

#コンテナの実行状態をリアルタイムに表示する
docker container stats

#コンテナの標準出力を画面へ表示する。そして、コントロール-Cでコンテナから切り離され止まらないようにする
docker container attach --sig-proxy=false <コンテナ名 | コンテナID>

#コンテナを一時停止する
docker container pause <コンテナ名 | コンテナID>

#コンテナの一時停止を解除する
docker container unpause -a <コンテナ名 | コンテナID>

#停止したコンテナを実行する。この際、標準出力や標準エラー出力をターミナルへ表示する
docker container start -a <コンテナ名 | コンテナID>

Kubernetes と重複する機能

ネットワーク関連

#コンテナのネットワークを作成する
docker network create <ネットワーク名>

#コンテナのネットワークをリストする
docker network ls

#コンテナのネットワークを削除する
docker network rm <ネットワーク名>

#未使用のコンテナのネットワークを削除する
docker network prune

永続ボリューム関連

#永続ボリュームを作成する
docker volume create <ボリューム名>

#永続ボリュームをリストする
docker volume ls

#永続ボリュームを削除する
docker volume rm <ボリューム名>

#未使用の永続ボリュームを削除する
docker volume prune

Docker Compose 関連

#カレントディレクトリのdocker-compose.ymlを使用して複数のコンテナを起動する
docker-compose up -d

#Docker Compose管理下で実行中のコンテナをリストする
docker-compose ps

#Docker Compose管理下のコンテナを停止する
docker-compose down

#Docker Compose管理下のコンテナを停止して、それらのイメージも削除する
docker-compose down --rmi all
ymz_noteymz_note

kubectl コマンドのチートシート

Kubectl コマンドの基本

kubectl コマンドのパラメータの書式は以下の通り

kubectl <①コマンド> <②リソースタイプ> [名前] [③オプション]

①~③について、それぞれ適切なパラメータを組み合わせて、kubectl コマンドを組み立てていくことになる。

①コマンド

  • get
    1行に1オブジェクトといった形式でリストされる。
    リソースタイプや名前との組み合わせによりリスト範囲を限定可能。
kubectl get -f <マニフェスト|ディレクトリ>

kubectl get <リソースタイプ>

kubectl get <リソースタイプ> <名前>

kubectl get <リソースタイプ> <名前> <オプション>
  • describe
    getよりも詳細な情報を表示する
    マニフェストファイル、ディレクトリ、リソースタイプ、名前との組み合わせによる表示対象選択はgetと同じ。
kubectl describe -f <マニフェスト|ディレクトリ>

kubectl describe <リソースタイプ>

kubectl describe <リソースタイプ> <名前>

kubectl describe <リソースタイプ> <名前> <オプション>
  • apply
    マニフェストに記述されたオブジェクトについて、存在しなければ生成、既存があれば変更を実施する。
kubectl apply -f <マニフェスト>
  • create
    マニフェストに記述されたオブジェクトを生成する。
    既存があれば、エラーを返す。
kubectl create -f <マニフェスト>
  • delete
    マニフェストに記述されたオブジェクトを削除する。
    リソースタイプと名前に一致するオブジェクトを削除する。
kubectl delete -f <マニュアル>
  • config
    接続先の k8s クラスタ、名前空間、ユーザーのリストを表示する。
    コンテキスト名を指定して、接続先 k8s クラスタ名前空間を決定する。
kubectl config get-contexts

kubectl config use-context <コンテキスト名>
  • exec
    コンテナに対話型でコマンドを実行する。
    ポッド内にコンテナが複数ある場合は、[-c] でコンテナを指定する。
    コンテナ名は kubectl describe <ポッド名>で取得可能
kubectl exec -it <ポッド名> [-c <コンテナ名>] bash
  • run
    ポッドを実行する。
    1.12以降のバージョンでポッド以外の実行は非推奨になった。
kubectl run <名前> --image=<イメージ名>
  • logs
    コンテナのログを表示する
kubectl logs <ポッド名> [-c コンテナ名]

②リソースタイプ(各オブジェクトの概要説明を記載する)

コンテナに直接関連するワークロード

  • pod (po)
    コンテナの最小起動単位であり、k8s クラスタ内のポッドネットワーク上にIPアドレスを持ち、単一または複数のコンテナを起動する。
  • poddisruptionbudget (pdb)
    ポッド停止許容数を設定することで最小稼働数を定め、サービス提供を維持する。

サービス関連

  • service (svc)
    ポッドのサービスの公開方法を決定する
  • endpoints (ep)
    サービスを提供するポッドのIPアドレスとポートを管理する
  • ingress (ing)
    サービス公開、TLS暗号化、セッション維持、URLマッピングの機能を提供する

コントローラ関連

  • deployment (deploy)
    サーバ型ポッドのレプリカ稼働数、自己回復、ロールアウト、ロールバックなどを制御するコントローラ。
  • replicaset (rs)
    ポッドのレプリカ数を制御するコントローラでdeploymentと連動して動作する。
  • statefulset (sts)
    永続データを保持するポッドのコントローラ。これは永続ボリュームとセットで構成でき、名前を連番管理する。
  • job
    バッチ処理型のポッドの正常終了を管理するコントローラ。
  • cronjob
    定期起動するジョブを管理するコントローラ。
  • daemonset (ds)
    ノードにポッドを配置するコントローラ。
  • replicationcontroller (rc)
    ぽっどのレプリカ数を制御するコントローラであり、replicasets の前世代バージョン。
  • horizontalpodautoscaler (hpa)
    ワークロード応じてポッド数を増減するコントローラ。

ボリューム関連

  • persistentvolume (pv)
    低レベルのストレージの管理を行う。
  • persistentvolumeclaim (pvc)
    ストレージクラスと容量を指定しtえ、論理ボリュームのプロビジョニングを要求する。
  • storageclass (sc)
    クラウドプロバイダーや外部ストレージが提供するストレージ種別を管理する。

k8s クラスタ関連

  • node (no)
    k8s クラスタのワークロードを実行するサーバであり、ノードまたはワーカーノードと呼ばれるオブジェクトを管理する。
  • apiservice
    マスタがサポートするAPIサービスを管理する。
  • componentstatuses (cs)
    scheduler, controller-manager, etcd-0 のヘルスチェック結果を報告する。
  • controllerversion
    コントローラのバージョンを報告する。
  • event
    k8sクラスタ内で発生したイベントを記録し、表示するためのコントローラ。

コンフィグマップとシークレット関連

  • configmap (cm)
    設定ファイルを保存する
  • secret
    パスワードなどの秘匿性の必要な情報を保存する

名前空間関連

  • namespace (ns)
    k8s クラスタを名前空間で論理分割して利用する

役割ベースアクセス制御(RBAC)関連

  • serviceaccount (sa)
    サービスアカウントは、ポッドで実行されるプロセス用のアカウントであり、アクセス権を識別するために利用される。
  • role
    一連のアクセス許可を表すルール記述、ロールの有効範囲は名前空間内に限られる。
  • rolebinding
    サービスアカウント、ユーザー、グループとロールをバインドする。
  • clusterrole
    k8sクラスタ全体に有効なロール。すなわち、アクセス権限のルールセット。
  • clusterrolebinding
    k8s全体に有効となるように、アクセス権限を対応付ける。

セキュリティ関連

  • certificatesigningrequest (csr)
    ルート認証局へ証明書署名要求を作成する。
  • networkpolicies (netpol)
    名前空間間のネットワークアクセス制御を行う。
  • podsecuitypolicies (psp)
    ぽっどのセキュリティに関わる項目のデフォルトを設定する。

資源管理関連

  • limitrange (limits)
    名前空間下、コンテナのCPUとメモリの要求値と上限のデフォルトを設定する。
  • resourcequota (quota)
    名前空間毎のCPUとメモリの要求量と上限値。

③オプション

表示に関連したオプションの例

  1. -n <名前空間>
    捜査対象を指定の名前空間にする。
  2. --all-namespace | -A
    すべての名前空間のオブジェクトを対象とする。
  3. -o=yaml
    YAMLでAPIオブジェクトを表示する。
  4. -o=wide
    ポッドではIPアドレスとノード名が追加情報として表示する。
  5. -o=json
    JSONでAPIオブジェクトを表示する。
  6. -o=custom-colums=<spec>
    項目を指定してリストする。
  7. -o=custom-colums-file=<file>
    テンプレートファイルでカスタム表示する。
  8. -o=jsonpath=<template>
    jsonpathに一致するリストを表示する。
  9. -o=jsonpath-file=<filename>
    jsonpath形式テンプレートファイルでカスタム表示する。
ymz_noteymz_note

Dockerfile チートシート

  • FROM <イメージ>:[タグ]
    コンテナのベースイメージを指定する。

  • RUN <コマンド>

  • RUN ["コマンド","パラメータ1","パラメータ2"]
    FROMのベースイメージ上でコマンドを実行する。

  • ADD <ソース> <コンテナ内の宛先>

  • ADD ["ソース",..."<コンテナ内の宛先>"]
    ソース(ファイル,ディレクトリ,tarファイル,URL)をコンテナ内の宛先へコピーする。

  • COPY <ソース> <コンテナ内の宛先>

  • COPY ["ソース",..."<コンテナ内の宛先>"]
    ソース(ファイル,ディレクトリ)をコンテナ内の宛先へコピーする。

  • ENTRYPOINT ["実行可能なもの","パラメータ1","パラメータ2"]

  • ENTRYPOINT <コマンド> <パラメータ1> <パラメータ2>
    コンテナが実行するファイルを設定する。

  • CMD ["実行バイナリ","パラメータ1","パラメータ2"]

  • CMD <コマンド>

  • CMD ["パラメータ1","パラメータ2"]
    コンテナの実行時に実行されるコマンドを指定する。

  • ENV <key> <value>

  • ENV <key>=<value> ...
    環境変数をセットする。

  • EXPOSE <port> [<port>...]
    公開ポートをセットする。

  • USER <ユーザー名> | <UID>
    RUN, CMD, ENTRYPOINTの実行ユーザを指定する。

  • VOLUME ["/path"]
    共有可能なボリュームをマウントする。

  • WORKDIR /path
    RUN, CMD, ENTRYPOINT, COPY, ADDの作業ディレクトリを指定する。

  • ARG <名前>[=<デフォルト値>]
    ビルド時の引数を定義する。
    --build-tag <変数名>=<値>

  • LABEL <key>=<value> <key>=<value>
    イメージのメタデータにラベルを追加する。

  • MAINTAINER <名前>
    イメージのメタデータに著作者を追加する。

ymz_noteymz_note

コントローラーによるポッドの実行

kubectl run のオプションを変更することでポッドをデプロイメントコントローラの制御下で実行することもできる。
「--restart=Always」で,デプロイメントコントローラで制御する
「--restart=Never」では,ポッドだけを動かす場合

ymz_noteymz_note

Namespace

論理的にクラスタを分割する。Namespace を分ける単位は,検証環境や本番環境,マルチテナントのために管理するチームであったり自由。
そのほか,特定の Namespace にアプリケーションをデプロイできるチームを制限したり,利用できる CPU やメモリなどのリソースを制限したりできる。
以下は Namespace のマニフェストyaml。
オブジェクト名は共通して metadata.name フィールドで設定する。

apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace

Kubernetes のオブジェクトはほとんどが Namespace レベルのオブジェクトになっている。例えば Pod。
Namespace レベルのオブジェクトは Namespace 内で一意の名前じゃないといけない。Namespace を分けることで同じ名前のオブジェクトを複数作成することが可能。
逆にクラスタレベルのオブジェクトは,クラスタレベルで一意な名前である必要がある,もちろん Namespace オブジェクト自体は Namespace に属せないのでクラスタレベルのオブジェクトであり,クラスタ内で一意の名前じゃないとだめ。
なお,クラスタレベルのオブジェクトを扱うにはクラスタ管理者の強い権限が必要になるので注意。

Pod

Pod は,Kubernetes におけるデプロイの最小単位で,ボリュームとネットワークを共有する一つ以上のコンテナンのグループ。
Pod 内のコンテナは必ず同じノード内に展開されて,ボリュームを共有することで同じふぁいうrを参照できるしネットワークを共有しているため,Pod 内のコンテナ同氏はローカルネットワーク通信(127.0.0.1)することができる。
以下は Pod のマニフェスト例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
 containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80

Label と Label セレクタ

これらは Kubernetes における唯一のグルーピング機能で,Kubernetes オブジェクトではないが非常に重要な役割を担っている。

Label

Pod のような Kubernetes オブジェクトのメタデータとして,情報を追加して設定することが可能。
metadata.label フィールドに設定する。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: my-namespace
  labels:
    environment: production
    release: canary
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - continerPort: 80

Label セレクタ

Label を利用して kubernetes オブジェクトをグルーピングする機能。
Label セレクタには,2つの使いかたがある。

  1. 「=」や「!=」を使用した単純な条件
  2. 「in」,「notin」,「exists」というようなさらに複雑な条件
    ※キー名が存在するかどうかを条件することもできる。
    例えば,「キー名に environment を持つかどうか」⇒「!environment」のような感じ

ReplicaSet

ReplicaSet は実行されている Pod のレプリカ数を保証する。
ReplicaSet に定義されているテンプレをもとに,Pod のレプリカを指定された数に一致するように作成する。

以下にマニフェストの例
my-rsという名前の ReplicaSet オブジェクトになる。

  1. spec.replicaset フィールドは,Podのレプリカ数を表す。
  2. spec.template フィールドは,Pod のレプリカ基になる Pod テンプレートを表す。
---
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-rs
spec:
  replicas: 3
  selector:
    matchlabels:
      app: my-rs
  template:
    metadata:
      labels:
        app: my-rs
    spec:
      containers:
      - name: nginx
        image: k8spracticalguide:1.15.5

Deployment

Deployment は,ReplicaSet と Pod のアップデート機能を提供する。
ReplicaSet は,Pod を指定されたレプリカ数分作成することをだけに責任のあるオブジェクトで,Pod の更新はできない。
Deployment は,ReplicaSet を管理して,実行されている Pod レプリカの数を一定に保ちながら徐々に新しいオブジェクト Pod オブジェクトを更新していく。
また,更新前の状態を保持しているのでロールバックも可能。

以下,Deployment オブジェクトのマニフェスト例

  1. spec.strategy フィールド:RollingUpdate のようにどのように Pod の更新を行うかおデプロイ戦略を指定する。
  2. spec.strategy.rollingupdate フィールド:デプロイ戦略(ローリングアップデート)ごとのより細かい設定を行う
  3. maxSurge:更新中に spec.replicas フィールドで指定した Pod レプリカ数を上回って新しい Pod を作成することを許容するかどうか。5のような絶対値の値や,50%のようなパーセントでの指定も可能。
  4. maxUnavailable:更新中に spec.replicas フィールドで指定した Pod レプリカ数を下回って古い Pod を削除することを許容するかどうか。5のような絶対値の値や,50%のようなパーセントでの指定も可能。
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deploy
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingupdate:
      maxSurge: 25%
      maxUnavailable: 25%
  selector:
    matchlabels:
      app: my-deploy
  template:
    metadata:
      labels:
        app: my-deploy
  spec:
    containers:
    - name: nginx
      image: k8spracticalguide:1.15.5

Service

Service は,サービスに対してアクセス可能なエンドポイントを提供する。
Pod 群に対するロードバランサーのような立ち位置。
ClusterIP 問いあわれる k8s クラスタ内でのみ有効な仮想IPを持ち,ClusterIP に対するアクセスは,Label セレクタでグルーピングされた Pod の集合に分散される。

以下,Service オブジェクトのマニフェスト例
サービスは Kubernetes 自身の DNS サーバによって,名前解決が可能。
同一の名前空間内であれば,「<Serviceオブジェクト名>:<ポート番号>」でアクセス可能。
ほかの名前空間内からであれば,「service.namespace:<ポート番号>」でアクセス可能。

---
apiVersion: v1
kind: Service
metadata:
  name: my-svc
  namespace: default
spec:
  type: ClusterIP
  selector:
    app:nginx
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80

ConfigMap

ConfigMap は,データベースの接続先ホストや設定ファイルなど,アプリケーションの設定情報を扱うオブジェクト。
開発環境や本番環境など,様々な環境に同一のコンテナ化されたアプリケーションをデプロイするためには,設定情報をアプリケーションから明確に分離して管理する必要があるので,ConfigMap に設定情報を入れておくことでコンテナはファイル,環境変数またはコマンドライン引数として設定情報を使うことが可能になり,アプリケーション(コンテナ)と設定情報を分離することができるのだ。
以下,ConfigMap のマニフェスト例

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-cm
data:
  DATABASE_HOST: dev.db.samp.com
  nginx.conf: |
    server{
      listen 80 default;
      server_name _;
      access_log /dev/stdout;

      location / {
        root /var/www/html;
        index index.html;
      }
    }

ConfigMap をボリュームとして Pod にマウントする

次に ConfigMap を Pod から利用する方法を見ていく。
ConfigMap は,Pod からファイル,環境変数,コマンドライン引数として使える。
以下のマニフェストでは,ConfigMap をボリュームとしてマウントする例

  1. Pod spec.voulmes フィールドでボリュームとして ConfigMap my-cm を設定している
  2. Pod spec.containers.volumeMounts フィールドで1で設定したボリュームを読み取り専用で /var/nginx にマウントしている
---
apiVersion: v1
kind: Pod
metadata:
  name: cm-volume
spec:
  containers:
    - name: nginx
      image: k8spracticalguide/nginx:1.15.5
      ports:
        - containerPort: 80
      volumeMounts:
        - name: my-cm
          readOnly: true
          mountPath: /var/nginx
  volumes:
    - name: my-cm
      configMap:
        name: my-cm
        items:
          - key: nginx.conf
            path: nginx.conf

ConfigMap を環境変数として扱う

  1. Pod spec.containers.env フィールドで,DATABASE_HOST環境変数に ConfigMap my-cm の DATABASE_HOST のキー値を設定するようにしている
---
apiVersion: v1
kind: Pod
metadata:
  name: cm-env
spec:
  containers:
    - name: nginx
      image: k8spracticalguide/nginx:1.15.5
      ports:
        - containerPort: 80
      env:
      - name: DATABASE_HOST
        valueFrom:
          configMapKeyRef:
            name: my-cm
            key: DATABASE_HOST

Secret

Secret は,パスワードやトークン,TLS証明書の秘密鍵などアプリケーションの秘密情報を扱うオブジェクト。
ConfigMap と使い方はほぼ一緒。
ConfigMap と異なる点としては,Base64でエンコードされているなど。
マニフェストファイルで Secret を作成することもできるが,コード上にクレデンシャル情報が出てしまうため,マニフェストファイルはふつう作らない。
事前にコマンドで Secret オブジェクトを作っておくか,Azure KeyVault のようなシークレット保存のサービスを使用して都度アプリケーションから参照させるかといったような運用になる。

Kubernetes のアーキテクチャ

ざっと簡単にまとめるこんな感じ

実際コマンドでどんなリソースがあるかを確認すると以下のような感じ

マスターコンポーネント

REST, CRUD, 認証認可の「kube-apiserver」

kube-apiserver は,API オブジェクトのオペレーションとして,REST,CRUDやデータの検証,そのほかに認証認可などに責任を持つコンポーネント。
開発者からの API オブジェクトに対する操作はもちろん,ほかのコンポーネントの操作もすべてのこのコンポーネントを通して行われる。
また,認証認可のフェーズの後に実行される Admission Control と言われるリクエストの制御機能を持ち合わせている。

唯一のデータストア「etcd」

etcd は,分散型のキーバリューストア。
Kubernetes が扱う情報はすべてここに集約される。

Pod のスケジューリング「kube-scheduler」

kube-scheduler は,Pod を適切なノードにスケジュールすることにセク人を持つコンポーネント。
できる限るノードの中で実行中の Pod の数に偏りがないようにスケジュールする。
また,Pod に指定されたリソース要求や GPU 利用の要求を考慮する。

クラスタを望ましい状態にする「kube-controller-manager」

kube-controller-manager は,API オブジェクトの変更をトリガーとして,現在の状態を望ましい状態に一致させることに責任を持つコンポーネント。
Deploymentオブジェクトなど,API オブジェクトのビジネスロジックが実装されている。
マネージャーという名前になっているのは,ここに実装されてるコントローラが便宜上の理由から一つのバイナリにまとめられているため。

ノードコンポーネント

ノードに常駐するエージェント「kubelet」

kubelet は,すべてのノードに常駐するエージェント。
自身がインストールされているノードに Pod がスケジュールされたらコンテナランタイムを操作してコンテナを作成し,Pod が削除されたらコンテナを削除する。
このほかにコンテナのヘルスチェックやコンテナ,ノードのステータスを kube-apiserver に通知したりする。

Service の抽象化を実現する「kube-proxy」

kube-proxy は,すべてノードにインストールされ,Service オブジェクトによるクラスタ内の負荷分散の実現に責任を持つコンポーネント。
内部的にはデフォルトで iptables が利用されて実現される。

コンテナの取得と実行「コンテナランタイム」

kubelet から操作され,コンテナイメージの取得と実行を行う。
Kubernetes では,CRI(container Runtime Inteface)と言われるコンテナランタイムを操作するためのインターフェースを策定し,kubelet はこのコンテナランタイムを操作する。
したがって,CRI を持つコンテナランタイムであれば Kubernetes で利用可能。
代表的なのは,Docker,containerd,cri-o,rktletなど。

ymz_noteymz_note

クラスタの動作に必要なコンポーネント

コンテナレジストリ

これはまぁ好きなの使ってや

ログ分析

クラスタで現在稼働中のアプリケーションのログを確認するのは簡単だが,依然動いていたバージョンのアプリケーションのログを参照するのは簡単じゃない。
Pod がひとつならまだしもいっぱいあるときには大変。
よって,ログを閲覧したり分析するための仕組みを入れるのがいい。
プロジェクトで使用しているログ分析のシステムを利用するのがいい,例えば Datadog/Splunk/など
そのほかにもログ収集用のソフトウェアとして,fluentd や Logstash などがある。
また,ログの集約用のソフトウェアとして,Elasticsearch や Apache Solr などの全文検索エンジンを利用可能。
ログの可視化には,Kibana などが利用できる。

メトリクス

クラスタで実行中の各アプリケーションの状況を把握するために,メトリクスを利用できる。
マネージドKubernetes サービスを使用している場合は,それぞれのマネージドなサービスを利用するのが楽。
Datadog はメトリクスの集約もサポートしている。
OSS だとなんといってもやはり Prometheus 様かな。
ほんで Grafana で可視化すると完璧。

認証

Kuberjetes を操作するための Kubernetes API サーバには,認証の機能が実装されている。
特定のユーザのみが操作可能に制限をかけられるようになっている。
マネージドKubernetesサービスを使用している場合は,それぞれの認証機能を使えばいい。
独自にやる場合は,OIDC を使用可能。

ymz_noteymz_note

minikube に mattermost をデプロイする

超簡易的にデプロイしてみる

$ kubectl create deployment mattermost-preview --image mattermost/mattermost-preview
deployment.apps/mattermost-preview created

$ kubectl get deployment
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
mattermost-preview   1/1     1            1           2m14s

$ kubectl get po
NAME                                  READY   STATUS    RESTARTS   AGE
mattermost-preview-5fdd7db8bb-vp9bt   1/1     Running   0          96s

$ kubectl expose --type NodePort --port 8065 deployment mattermost-preview
service/mattermost-preview exposed

$ minikube service mattermost-preview
|-----------|--------------------|-------------|------------------------|
| NAMESPACE |        NAME        | TARGET PORT |          URL           |
|-----------|--------------------|-------------|------------------------|
| default   | mattermost-preview |        8065 | http://10.0.2.15:30929 |
|-----------|--------------------|-------------|------------------------|
🎉  Opening service default/mattermost-preview in default browser...
👉  http://10.0.2.15:30929

こんな感じで実装完了!

さらに細かくKubernetesの動きを体感していく!!

event オブジェクトを見て,どんなイベントが Kubernetes クラスタ内部で発生しているのかを確認する。
今回は,mattermost のデプロイ前に,Event オブジェクトを監視する。

kubectl get event -w -o custom-columns=KIND:.involvedObject.kind,NAME:.metadata.name,SOURCE:.source.component,REASON:.reason,MESSAGE:.mesage

KIND         NAME                                                       SOURCE                  REASON                    MESSAGE
Pod          dive-mattermost-preview-766f6c75c-922pm.17cdd0ad1efd1d6f   <none>                  Scheduled                 <none>
Pod          dive-mattermost-preview-766f6c75c-922pm.17cdd0ad4f83b887   kubelet                 Pulled                    <none>
Pod          dive-mattermost-preview-766f6c75c-922pm.17cdd0ad53295054   kubelet                 Created                   <none>
Pod          dive-mattermost-preview-766f6c75c-922pm.17cdd0ad580cfc16   kubelet                 Failed                    <none>
Pod          dive-mattermost-preview-766f6c75c-922pm.17cdd0ad697d5f21   kubelet                 Failed                    <none>
Pod          dive-mattermost-preview-766f6c75c-922pm.17cdd0b0f60a9622   kubelet                 Failed                    <none>
Pod          dive-mattermost-preview-766f6c75c-922pm.17cdd0b430e52200   kubelet                 BackOff                   <none>
Pod          dive-mattermost-preview-766f6c75c-922pm.17cdd0b705d652ca   kubelet                 Failed                    <none>
ReplicaSet   dive-mattermost-preview-766f6c75c.17cdd0ad1e5ec377         replicaset-controller   SuccessfulCreate          <none>
Deployment   dive-mattermost-preview.17cdd0ad1d598e8e                   deployment-controller   ScalingReplicaSet         <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd040e72fb902       <none>                  Scheduled                 <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd0417068fba7       kubelet                 Pulling                   <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd047633dea25       kubelet                 Pulled                    <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd0476640b7f2       kubelet                 Created                   <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd0476d66926c       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd04779463a55       kubelet                 Pulled                    <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd047818b8c81       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd04abedbac46       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd04dbeb8aad4       kubelet                 BackOff                   <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd0514516e5e6       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-55wk7.17cdd05b82d60fbf       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-h9wdh.17cdd0afb07900a6       <none>                  Scheduled                 <none>
Pod          mattermost-preview-545948544b-h9wdh.17cdd0afdd2e84df       kubelet                 Pulled                    <none>
Pod          mattermost-preview-545948544b-h9wdh.17cdd0afe0166aa5       kubelet                 Created                   <none>
Pod          mattermost-preview-545948544b-h9wdh.17cdd0afe37f13a6       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-h9wdh.17cdd0b003d7f0b5       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-h9wdh.17cdd0b385d579f0       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-h9wdh.17cdd0b6494301ea       kubelet                 BackOff                   <none>
Pod          mattermost-preview-545948544b-h9wdh.17cdd0ba468f5b0c       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-vwszd.17cdd0665f75e3f9       <none>                  Scheduled                 <none>
Pod          mattermost-preview-545948544b-vwszd.17cdd0668dcfe1d9       kubelet                 Pulled                    <none>
Pod          mattermost-preview-545948544b-vwszd.17cdd06690fd8cc9       kubelet                 Created                   <none>
Pod          mattermost-preview-545948544b-vwszd.17cdd06696c1c61b       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-vwszd.17cdd066b439e729       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-vwszd.17cdd06a2fac142d       kubelet                 Failed                    <none>
Pod          mattermost-preview-545948544b-vwszd.17cdd06d2d5e4764       kubelet                 BackOff                   <none>
Pod          mattermost-preview-545948544b-vwszd.17cdd0703b0db6e5       kubelet                 Failed                    <none>
ReplicaSet   mattermost-preview-545948544b.17cdd040e6b502bb             replicaset-controller   SuccessfulCreate          <none>
ReplicaSet   mattermost-preview-545948544b.17cdd0665dbfe474             replicaset-controller   SuccessfulCreate          <none>
ReplicaSet   mattermost-preview-545948544b.17cdd0afafac6c21             replicaset-controller   SuccessfulCreate          <none>
Pod          mattermost-preview-5fdd7db8bb-vp9bt.17cdd0c4bbe2f5ff       <none>                  Scheduled                 <none>
Pod          mattermost-preview-5fdd7db8bb-vp9bt.17cdd0c4e76bc14a       kubelet                 Pulling                   <none>
Pod          mattermost-preview-5fdd7db8bb-vp9bt.17cdd0d404adcf40       kubelet                 Pulled                    <none>
Pod          mattermost-preview-5fdd7db8bb-vp9bt.17cdd0d4089e466f       kubelet                 Created                   <none>
Pod          mattermost-preview-5fdd7db8bb-vp9bt.17cdd0d4199b7fe2       kubelet                 Started                   <none>
Pod          mattermost-preview-5fdd7db8bb-vp9bt.17cdd1a76ae0da5f       kubelet                 SandboxChanged            <none>
Pod          mattermost-preview-5fdd7db8bb-vp9bt.17cdd1a7c5f330b0       kubelet                 Pulling                   <none>
Pod          mattermost-preview-5fdd7db8bb-vp9bt.17cdd1a83e386e7a       kubelet                 Pulled                    <none>
Pod          mattermost-preview-5fdd7db8bb-vp9bt.17cdd1a84543d4b5       kubelet                 Created                   <none>
Pod          mattermost-preview-5fdd7db8bb-vp9bt.17cdd1a8515396ac       kubelet                 Started                   <none>
ReplicaSet   mattermost-preview-5fdd7db8bb.17cdd0c4bb4b0187             replicaset-controller   SuccessfulCreate          <none>
Deployment   mattermost-preview.17cdd040e5daa65c                        deployment-controller   ScalingReplicaSet         <none>
Deployment   mattermost-preview.17cdd0665d2f0290                        deployment-controller   ScalingReplicaSet         <none>
Deployment   mattermost-preview.17cdd0afaf4aff9d                        deployment-controller   ScalingReplicaSet         <none>
Deployment   mattermost-preview.17cdd0c4ba4a1b4b                        deployment-controller   ScalingReplicaSet         <none>
Node         minikube.17cdd1a3f21da130                                  kubelet                 Starting                  <none>
Node         minikube.17cdd1a3f9612814                                  kubelet                 NodeHasSufficientMemory   <none>
Node         minikube.17cdd1a3f9613688                                  kubelet                 NodeHasNoDiskPressure     <none>
Node         minikube.17cdd1a3f9613ddb                                  kubelet                 NodeHasSufficientPID      <none>
Node         minikube.17cdd1a400bd0a39                                  kubelet                 NodeAllocatableEnforced   <none>
Node         minikube.17cdd1a7f4dcab8e                                  <none>                  Starting                  <none>
Node         minikube.17cdd1ac80588a62                                  node-controller         RegisteredNode            <none>

ログレベルを上げてさらに kubectl と Kubernetes API の関係を把握する