Kubernetes

Kubernetesとは

  • Dockerコンテナのクラスタ管理を始めとしたオーケストレーションを行うサービスのこと.
  • ホスト間の連携やデプロイについても総括的に管理できる(ここがDocker Composeと違うところ).
  • Kubernetesの大きな特徴の1つに宣言的設定がある.
  • 宣言的設定とは, イミュータブルなインフラを作るための基本的な考え方で, 「システムのあるべき姿」を設定ファイルに宣言する!という考え方.
  • Kubernetesは設定ファイルに書いたとおりのインフラを維持するように設計されている.
  • ので, 設定ファイル(yamlファイル)をたくさん書く事になる.
  • Reference: Docker Compose利用者から見た Kubernetes 開発環境構築入門
  • GitHubリポジトリ: https://github.com/kubernetes

他のオーケストレーションと違うところ

① 様々なOSSと組み合わせることにより, 柔軟に機能拡張なところ.

  • コンテナ運用を更に効率化 / 高速化
  • 詳細なメトリック監視と可視化・・・Prometheus + Grafana
  • コンテナのログの転送収集・・・Fluentd / Fluent Bit
  • ネットワークトラフィックの制御・・・ Istio + Envoy
  • Kubernetesの適応領域の拡大
  • 機械学習プラットフォーム・・・Kubeflow
  • 分散ストレージ・・・Rook
  • 分散型データベース・・・Vitess

② 本格的な宣言的オペレーションとInfrastructure as Codeを実現可能

③ クラスター上にデプロイするシステムの構成をコード(マニフェストファイル)によって定義できる

  • 運用オペレーションはコードの変更によって実施し, 作業を簡素化する.
  • 複数Kubernetesクラスターでの相互運用を実現する

Reference: Kubernetesの基礎

Docker Composeとの違い

Docker Composeは動作させるコンテナを意識するだけでほとんど良かったが, Kubernetesではそれに加えて動作させるホスト(Node)やコンテナのグループ化(Pod), その複製(ReplicaSet)と公開(Service, Ingress)といったインフラレベルで意識していたことも全て設定ファイルの1つとして管理できる.
Reference: Docker Compose利用者から見た Kubernetes 開発環境構築入門

項目 Docker Compose Kubernetes
Image 各エントリーは, イメージを構築するためにオプションでdocker-composeを取得できる. すべてのイメージがすでに構築されているとする.
Container 各エントリーが作成したいコンテナを表す. 作成したいオブジェクト(Kubernetesクラスタ上で機能する構成要素のこと. Pod, Service, Volume, Namespace, Controllerのこと.)ごとに1つの設定ファイル
Network 各エントリーがネットワーク要件を定義する. 手動ですべてのネットワークを設定する必要がある.

用語集

用語 説明
Node コンテナが動作するサーバのこと.Master(Master Node): 全Nodeを管理する.Node(Woker Node): 各リソースを動かす.
Pod 関連したコンテナの集まりを1つにしたもの.
ReplicaSet 対象Podのクラスタ全体における生成・管理を行う.PodTemplateと呼ばれるPodのテンプレートをもとに、Podを指定された数(レプリカ数)に調整・管理を行う仕組み.そうすることで, Podのセルフヒーリングを行う.
Deployment ReplicaSetの生成・管理を行う.ローリングアップデートやロールバックといったデプロイ管理の仕組みを提供する.
Service Podへのアクセス経路を提供する.OSI参照モデルのL4層まで扱える.- クラスタ内部のみで利用できるService(ClusterIP)や,- クラスタ外部からアクセス可能なService(NodePort)などを作成することができる.
Ingress Serviceの上位リソース.OSI参照モデルのL7層レベルまで扱える.
ConfigMap 環境変数のような設定値, また設定ファイル情報そのものを管理する.Key-Value形式.
Secret パスワードのような秘匿情報を扱う際に利用する.
PersistentVolume ボリューム領域を定義する.EBSやNFSのような外部ストレージも定義できる.
PersistentVolumeClaim 利用するボリューム領域の要求を定義する.PersistentVolumeとPodを紐付けるために利用する.
Namespace 仮想的なKubernetesクラスタの分離機能.default: デフォルトのNamespacekube-system: Kubernetesクラスタのコンポーネントやaddonが展開されるNamespacekube-public: 全ユーザが利用できるConfigMapなどを配置するNamespace

yaml内の用語集

用語 意味
apiVersion リソースで利用するAPIのバージョンを指定.
kind リソースの種別を指定.(Deployment, Serviceとか)
metadata リソースへ付与可能なメタデータ.主に名称やラベルを付与する.
spec リソース固定の設定を指定.
data ConfigMapやSecretなどの設定データを記述するリソースで使用される.
label Kubernetes上のオブジェクト(Podなど)に付けることができるKey/Valueペアの文字列で, オブジェクトに任意のメタ情報のようなものを持たせることができる.
selector Labelの集合をもとにKubernetesオブジェクトをフィルタリングすることができる.

apiVersionの調べ方

kubectl api-resources # リソースとAPIGROUPの対応を調べる
kubectl api-versions # APIGROUPで利用可能なversionを調べる
APIGROUPあるなし 書き方
APIGROUPがあるとき apiVersion: (APIGROUP)/(APIVERSION)
APIGROUPがないとき(= Core groupに属する) apiVersion: v1
Reference: Kubernetesの apiVersion に何を書けばいいか

ServiceのType4種類

  • ClusterIp
  • クラスタ内のIPにServiceを公開する.
  • この値ではServiceはクラスタ内からのみアクセス可能.
  • デフォルトはこれ.
  • NodePort
  • 各ノードのIP上のServiceを静的ポート(NordPort)に公開する.
  • NodePort ServiceがルーティングするClusterIP Serviceが自動的に作成される.
  • NodeIp: NordPortを要求することで, クラスタ外からNordPort Serviceにアクセスできる.
  • LoadBalancer
  • クラウドプロバイダのロードバランサを使用して外部にServiceを公開する.
  • 外部ロードバランサがルーティングするNordPort ServiceとClusterIP Serviceが自動的に作成される.
  • ExternalName
  • 値を含むCNAMEレコードを返すことにより, ServiceをexternalNameフィールドのコンテンツ(たとえば, foo.bar.example.com)にマッピングする.
  • この場合, どのような種類のプロキシも設定されない.
  • この型を使うには, バージョン1.7以上のkube-dnsが必要.

Reference: Kubernetesの Service についてまとめてみた

PersistentVolumeClaimのaccessModes3種類

  • PeadWriteOnce
  • 1つのノードが読み書き可能
  • ReadOnlyMany
  • 複数のノードが読み込みだけ可能
  • ReadWriteMany
  • 複数のノードから読み書き可能

StorageClassの一覧

volumeMountsのsubPath

subPathを指定してあげるとvolumeをルートディレクトリからマウントしないで, サブディレクトリからマウントする. volumeをそんなに使わない時にオススメ.

Reference: 永続ストレージのサブディレクトリにマウントする方法

Macのローカル環境で動かす

  1. https://brew.sh からbrewをインストールする.

Ubuntuのローカル環境で動かす

  1. kubectlをインストールする.

minikubeの使い方

minikube status # 動いているか確認
minikube start # minikubeをスタート
minikube ip # ipを確認
minikube dashboard # ダッシュボード出現
minikube docker-env # 環境変数を出力

kubectlの使い方

kubectl apply -f client-pod.yaml # オブジェクトの新規作成・差分反映
kubectl get pods # 動いているpodを確認
kubectl get deployments # 動いているdeploymentを確認
kubectl describe <object type> <object name> # オブジェクトの詳細表示
kubectl delete -f client-pod.yaml # オブジェクトが存在すれば削除
kubectl delete deployment client-deployment # deploymentの削除
kubectl delete pod client-node-port # podの削除
kubectl api-resources # リソースとAPIGROUPの対応を調べる
kubectl api-versions # APIGROUPで利用可能なversionを調べる
kubectl get storageclass # 管理者が提供するストレージのクラスを表示
kubectl get pv # PersistentVolumeの一覧を表示
kubectl get pvc # PersistentVolumeClaimの一覧を表示
# 以下3つはパスワードを設定する時に使用
kubectl create secret generic pgpassword --from-literal PGPASSWORD=******** # パスワードを生成
kubectl create secret generic <secret_name> --from-literal <key=value> # パスワードを生成
kubectl get secret # secret一覧を表示
# 以下2つはGKEでユーザーの権限を与える時に使用
kubectl create serviceaccount --namespace kube-system tiller # tillerというサービスアカウントを作成
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-ad
min --serviceaccount=kube-system:tiller

自分のPCからVMにアクセスしてDockerコンテナを見る方法

eval $(minikube docker-env)
docker ps

1度デプロイしたイメージのバージョンアップ方法

Kubernetesではlatestタグイメージの運用は適切なロールバックを行うことが難しいので推奨されていない.
ので, できる限りVsersion, もしくはdigestでイメージ指定を行うようにする.

以下のようにDocker Hubにバージョンを指定してpushし,

docker build -t solareenlo/multi-client:v5
docker push solareenlo/multi-client:v5

以下のようにコマンドラインからイメージのバージョンアップを行う.

kubectl set image deployment/client-deployment client=solareenlo/multi-client:v5

イメージのバージョンにgitのshaを使う

以下の様に.travis.yml$SHAを設定して,

sudo: required
services:
  - docker
env:
  global:
    - SHA=$(git rev-parse HEAD)

以下の様にbuild, push, setを行うと良い.

docker build -t solareenlo/multi-client:latest -t solareenlo/multi-client:$SHA -f ./client/Dockerfile ./client
docker build -t solareenlo/multi-server:latest -t solareenlo/multi-server:$SHA -f ./server/Dockerfile ./server
docker build -t solareenlo/multi-worker:latest -t solareenlo/multi-worker:$SHA -f ./worker/Dockerfile ./worker

docker push solareenlo/multi-client:latest
docker push solareenlo/multi-server:latest
docker push solareenlo/multi-worker:latest

docker push solareenlo/multi-client:$SHA
docker push solareenlo/multi-server:$SHA
docker push solareenlo/multi-worker:$SHA

kubectl apply -f k8s
kubectl set image solareenlo/server-deployment server=solareenlo/multi-server:$SHA
kubectl set image solareenlo/client-deployment client=solareenlo/multi-client:$SHA
kubectl set image solareenlo/worker-deployment worker=solareenlo/multi-worker:$SHA

ローカルで動かした例

GKEで動かした例

TLS

良書

Helm

  • Kubernetesのパッケージ管理ツール.
  • デフォルトで使用可能なChartはkubernetes/chartsstableディレクトリで確認可能.
  • GitHubリポジトリ: https://github.com/helm/helm
用語 意味 役割
helm 船のかじ Kubernetesのパッケージマネージャー.
chart 海図 Kubernetesのマニフェストのテンプレートをまとめたもの.
tiller 舵柄 デプロイを担うサーバーコンポーネント.
package - 1つのアプリケーションとして成り立つchartの単位.この単位でデプロイを行う.
release - packageがデプロイされて, k8s上でpodとして実際に動作しているもの.
repository - chartの置き場所. yumのリポジトリのようなイメージ.