DMM.comの、一番深くておもしろいトコロ。

Kubernetesを始めよう!

Kubernetesを始めよう!

f:id:ornew:20180413101559p:plain

はじめまして、CTO室の古川です。

ここ数年で、Dockerなどのコンテナエンジンが開発現場でも広く用いられるようになってきました。クラウドサービスのサポートも進み、すでにコンテナ化されたアプリケーションでマイクロサービス開発をしている方も多いかと思います。

コンテナは多くの恩恵をもたらしますが、コンテナエンジン自体はプリミティブな仮想化の機能を提供するものであるため、管理するコンテナが増えてくるとワークロードが複雑になってきます。そこで、コンテナ管理を自動化するための様々なコンテナオーケストレーションシステムが開発されてきました。Kubernetesもその一つです。

この記事は、「これからKubernetesを始めたい!」という方のための入門記事となります。

Kubernetesとは?

Kubernetesは、コンテナ化されたアプリケーションの展開、スケーリング、および管理を自動化するためのオープンソースシステムです。コンテナアプリケーションのワークロードを自動化することで、開発の生産性を向上させ、柔軟な運用を容易にします。

Kubernetesの生みの親であるGoogleでは、10年以上前から3つのコンテナ管理システムを構築・運用しており、その経験から得た教訓を公開しています(Borg, Omega, and Kubernetes)。それらの教訓は、Kubernetesにフィードバックされています。また、オープンソースとすることでコミュニティの中で様々なアイデアやノウハウを取り込み、日々進化しています。

Kubernetesの始めかた

Kubernetesは、複数のマシンから形成されるクラスタで動作します。

すぐに始めたい場合は、Google Kubernetes EngineやAmazon Elastic Container Service for Kubernetesなどのマネージドサービスを利用してクラスタを作成するのが簡単です。

試すだけであれば、ローカルVM上でシングルノードのKubernetesクラスタを稼働するminikubeを使うのがおすすめです。

Kubernetesはあらゆるプラットフォームをサポートしているため、環境ごとのセットアップ方法は"Picking the Right Solution"を参考にしてください。

Kubernetesでアプリケーションを動かそう!

習うより慣れろ」といいますし、まずはKubernetesクラスタ上にアプリケーションをデプロイしてみましょう。

Kubernetesクラスタでは、マスターノードでAPIサーバが動作しています。APIサーバに接続可能であれば、クラスタの外部からでもKubernetesを操作できます。

kubectlというコマンドラインツールを用いることで、簡単にAPIを操作することができます。kubectlのインストール方法は、ドキュメントを参考にしてください。

kubectlを使う

まずはローカルマシンがクラスタに接続できているかを確認してみましょう。

$ kubectl cluster-info
Kubernetes master is running at https://192.168.99.100:8443

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

minikubeの場合は、インストール後にminikube startを実行することでクラスタが起動します。自動でkubectlの設定が更新されるため、何もしなくてもクラスタ情報が正常に取得できると思います。クラウドのマネージドサービスを用いる場合も、ドキュメントに従っていれば自動で設定されることが多いでしょう。

その他の方法でクラスタを構築した場合は、~/.kube/configファイルに設定を書きましょう。また、ローカルマシンがクラスタのマスターノードにネットワーク経由で到達可能であることを確認してください。

例としてminikubeの場合は、下記のような設定ファイルが自動生成されているはずです。

kind: Config
apiVersion: v1
clusters:
- cluster:
    certificate-authority: /home/ornew/.minikube/ca.crt
    server: https://192.168.99.100:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
preferences: {}
users:
- name: minikube
  user:
    as-user-extra: {}
    client-certificate: /home/ornew/.minikube/client.crt
    client-key: /home/ornew/.minikube/client.key

Dashboard(Web UI)をデプロイする

kubectlを使って、Kubernetesクラスタ上にDashboardアプリケーションをデプロイしてみましょう。

$ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

kubectl createは、クラスタに「オブジェクト」を作成するコマンドです。「オブジェクト」が何なのかはいったん置いておき、まずは作成されたアプリケーションを確認してみましょう。

作成したDashboardは、クラスタ外部に公開されていません。接続にはプロキシを使います。

$ kubectl proxy
Starting to serve on 127.0.0.1:8001

上記コマンドを実行した状態で、Webブラウザからhttp://127.0.0.1:8001/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxyにアクセスしてみましょう。

f:id:ornew:20180326142248p:plain

Webアプリケーションが表示されれば成功です。見てのとおり、DashboardはKubernetesを管理するユーザインタフェースです。Dashboardを使うと、Kubernetesのひととおりの機能をWeb上から操作することができます。

  • アプリケーションの作成、編集、削除
  • アプリケーションのスケール、アップデート
  • コンテナ内のシェルに接続、ログの表示
  • リソース使用状況の確認
  • など

kubectlやDashboardを始めとして、Kubernetesは様々な方法で操作することができます。

  • API:プログラムからの自動制御向き
  • コマンド(kubectl):人の手による細かい動的な制御向き
  • ファイル:バージョン管理が可能、静的な制御向き
  • Dashboard:直感的な操作が可能

開発においては、おそらくコマンドとファイルを扱うことが多いと思います。先ほどkubectl createに渡したのも、ファイル(のURL)です。

ファイルに書かれているのは「オブジェクト」の定義です。オブジェクトの定義ファイルさえあれば1コマンドでアプリケーションがデプロイできます

オブジェクトとは

オブジェクトは、クラスタに関する構造化データを格納する方法です。Kubernetesに展開されるアプリケーションや、アプリケーションを制御する方法、単純な設定ファイルまで、すべてはオブジェクトとして定義されます。

オブジェクトは様々なものが存在しますが、最初に理解したい基本的なオブジェクトは以下の3つです。

  • 論理的なアプリケーションの単位であるポッド
  • ポッドを制御する幾つかのコントローラ
  • ポッドをクラスタ内部または外部に公開するサービス

f:id:ornew:20180413104022p:plain

ポッド

ポッド(Pod)は、Kubernetesによって制御される最も基本的なオブジェクトです。アプリケーションプログラムの実行環境であるコンテナと、それを取り巻くボリュームやネットワークなどのリソースをまとめた独立したプロセスです。

ポッドには様々なリソースが含まれています。

  • コンテナ:ポッドには複数のコンテナを含むことが可能1
  • ボリューム:ネットワークストレージを永続ボリュームとしてマウントすることが可能
  • ネットワーク:クラスタ内部から到達可能なIPが自動で割り当てられます
  • など

ポッド内のコンテナは、ボリュームとネットワーク名前空間を共有します。

ポッドは論理的なアプリケーションの単位として機能します。Kubernetesでは、レプリケーションなどの制御を、コンテナではなくポッド単位で行います。

ポッドを始めとするすべてのオブジェクトは、yaml(またはjson)形式のファイルで定義できます。

# pod.yaml
# Podオブジェクトの定義例
kind: Pod
apiVersion: v1
metadata:
  name: example-app
  labels:
    app: example-app
spec:
  containers:
  - name: example-app
    image: nginx:1.7.9
    ports:
    - containerPort: 80

すべてのオブジェクトは、オブジェクトの種類を示すkindapiVersionと、オブジェクトのメタ情報を定義するmetadataを必ず含みます。

ポッドオブジェクトの場合は、spec以下にポッドの定義を示します。コンテナ、ボリューム、ネットワーク、実行ポリシーのオプションなどを含むことができます。

作ったオブジェクト定義ファイルを、kubectlやDashboardからKubernetesへ与えることで、実際にクラスタ上のいずれかの適切なノードにオブジェクトが作成されます。ノードアフィニティを制御することも可能ですが、そこにはこの記事では触れません。

kubectlを使って上記pod.yamlからポッドを作成してみましょう。クラスタ上のオブジェクトの情報は、kubectl getで取得できます。kubectlからオブジェクトを操作する時は、オブジェクトのmetadata.name(この場合、example-app)を識別子として使います。

$ kubectl create -f pod.yaml
pod "example-app" created

$ kubectl get pods
NAME            READY     STATUS    RESTARTS   AGE
example-app     1/1       Running   0          15s

example-appという名前のポッドが一つ実行されていることがわかります。

kubectl describeでポッドの詳細を表示できます。

$ kubectl describe pods/example-app
Name:         example-app
Namespace:    default
Node:         minikube/192.168.99.100
Start Time:   Mon, 26 Mar 2018 01:16:42 +0900
Labels:       app=example-app
Annotations:  <none>
Status:       Running
IP:           172.17.0.4
Containers:
  example-app:
    Container ID:   docker://e10c300bd895c12cd3d059c2285e73e1118ae1b959b3b92a5d7cc68317ce7fd1
    Image:          nginx:1.7.9
    Image ID:       docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
    Port:           80/TCP
    State:          Running
      Started:      Mon, 26 Mar 2018 01:16:43 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-bmtf4 (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          True
  PodScheduled   True
Volumes:
  default-token-bmtf4:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-bmtf4
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     <none>
Events:
  Type    Reason                 Age   From               Message
  ----    ------                 ----  ----               -------
  Normal  Scheduled              30s   default-scheduler  Successfully assigned example-app to minikube
  Normal  SuccessfulMountVolume  30s   kubelet, minikube  MountVolume.SetUp succeeded for volume "default-token-bmtf4"
  Normal  Pulled                 29s   kubelet, minikube  Container image "nginx:1.7.9" already present on machine
  Normal  Created                29s   kubelet, minikube  Created container
  Normal  Started                29s   kubelet, minikube  Started container

オブジェクトはkubectl deleteで削除できます。

$ kubectl delete pods/example-app
pod "example-app" deleted

基本的に、どのようなオブジェクトも同じコマンドで作成・取得・削除できます。

コントローラ

ポッドは単一のアプリケーションを定義しますが、ポッド単体では再起動程度の単純な制御しかできません。ポッドのスケール、アップデートといった、同時に複数のポッドを制御する必要がある場合は、コントローラと呼ばれるオブジェクトを介してポッドを操作します。

  • Deployment:レプリケーション、ローリングアップデートなど、ポッドのデプロイに関する複雑な制御
  • StatefulSet:Deploymentに加え、順序と一意性の保証
  • Job:完了状態を持つ単発的なジョブとして実行する
  • CronJob:定期実行されるジョブ
  • など

このようなポッドの管理・制御を行うオブジェクトコントローラといいます。

コントローラは、与えられた「希望する状態」になるように、自動的に継続して駆動する構成可能な独立した制御プロセスです。私たちは「希望の状態」をオブジェクトで定義し、Kubernetesに与えます。

代表的なコントローラとして、Deploymentを紹介します。

Deployment

デプロイメントは、ステートレスアプリケーションを提供するポッドのデプロイを制御します。ポッドのレプリケーションを行い、ポッドの定義が更新されると自動でロールアウトします。

  • レプリケーションの制御
    • レプリカの過不足を自動で修正する
    • スケールアップ/スケールダウンができる
  • ポッドが更新された際のロールアウト/ロールバックの制御
    • ポッドテンプレートが更新された際に、自動でロールアウトする
    • ロールバックができる

コントローラもポッドと同じくオブジェクトとして定義できます。

# deployment.yaml
# Deploymentの定義例
kind: Deployment
apiVersion: apps/v1
metadata:
  name: example-app-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
      - name: example-app-deploy
        image: nginx:1.7.9
        ports:
        - containerPort: 80

デプロイメントが制御するポッドは、ポッドのメタ情報に基いて選択できます。上記例では、「ラベルがapp: example-appと一致するポッドが、レプリカ数3で展開される」ように制御することを意味します。

ポッドの時と同じように、kubectl createで作成できます。または、ポッドのコンテナが一つの場合はkubectl runで簡単に作ることもできます。

$ kubectl run example-app-deploy -l phase=DEV --replicas=3 --image=nginx:1.7.9 --port=80
deployment "example-app-deploy" created

$ kubectl get deployments
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
example-app-deploy   3         3         3            3           57s

$ kubectl get pods
NAME                                  READY     STATUS    RESTARTS   AGE
example-app-deploy-7c89587d58-hsvsg   1/1       Running   0          1m
example-app-deploy-7c89587d58-rqscv   1/1       Running   0          1m
example-app-deploy-7c89587d58-w29fq   1/1       Running   0          1m

自動でポッドが3つにレプリケーションされているのが確認できます。

スケーリング

コントローラは、定義が更新されると新しい希望の状態になるように自動的に制御が行われます。例えば、kubectlからデプロイメントのレプリカ数を変更すると、デプロイメントは自動的にポッドをスケールします。

$ kubectl scale deployments/example-app-deploy --replicas=4
deployment "example-app-deploy" scaled

$ kubectl get deployments
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
example-app-deploy   4         4         4            4           40s

$ kubectl get pods
NAME                                  READY     STATUS    RESTARTS   AGE
example-app-deploy-7c89587d58-fdxs9   1/1       Running   0          6s
example-app-deploy-7c89587d58-hsvsg   1/1       Running   0          2m
example-app-deploy-7c89587d58-rqscv   1/1       Running   0          2m
example-app-deploy-7c89587d58-w29fq   1/1       Running   0          2m

明示的なスケーリングだけでなく、ノードの障害などでレプリカが減少した場合でも、デプロイメントはポッドの数を維持するために新しいポッドを自動でデプロイします。ポッドは定期的に死活監視されているため、自動で異常終了を検知し、正常な状態に自己修復することができます。

水平スケーリングを有効にすると、CPU使用率などをもとにオートスケールすることもできます。オートスケーリングにの詳細については"Horizontal Pod Autoscaler Walkthrough"などを参考にしてください。

$ kubectl autoscale deployment example-app-deploy --min=10 --max=15 --cpu-percent=80
deployment "example-app-deploy" autoscaled
ロールアウト

ポッドテンプレートが更新されると、デプロイメントは新しいポッドをロールアウトします。

特に指定していない場合、少しずつポッドを入れ替えていくローリングアップデート方式が用いられます。kubectl describeコマンドでデプロイメントを確認すると、アップデート方式が確認できます。

$ kubectl describe deploy/example-app-deploy | grep StrategyType
StrategyType:           RollingUpdate

試しに、ポッドテンプレートのコンテナイメージをnginx:1.7.9からnginx:1.9.1にアップデートしてみましょう。kubectl set imageを用いることで、ポッドテンプレートのコンテナのイメージを更新できます。

$ kubectl set image deployments/example-app-deploy example-app-deploy=nginx:1.9.1
deployment "example-app-deploy" image updated

$ # 注:確認のタイミングによって状態は変わります
$ kubectl get deployments
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
example-app-deploy   4         5         3            2           25s

$ kubectl get deployments
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
example-app-deploy   4         4         4            4           2m

ローリングアップデート方式では、以下のような流れでポッドが新しいものに置き換えられていきます。

  1. ポッドテンプレートのイメージを1.7.9から1.9.1に更新する。
  2. 新しいバージョンのポッドが作られ、正常に起動した場合は古いバージョンのポッドを削除する。
  3. 少しずつ入れ替えながらアップデートを行っていく。

万が一、ロールアウト中にエラーが発生した場合は、その時点でアップデートは停止します。よって、ローリングアップデート方式では、レプリカ数が十分であればポッドアプリケーションをダウンさせることなくポッドをアップデートできます。

わざとロールアウトが失敗するように1.9.11.91にしてみましょう。

$ kubectl set image deployments/example-app-deploy nginx=nginx:1.91
deployment "example-app-deploy" image updated

デプロイメントはイメージをPULLしようとしますが、1.91というタグは存在しないので、ロールアウトは失敗します。この時も、一つ前のバージョンのポッドが3つ正常に稼働しているのが確認できます。

$ # しばらく待っても以下のままになるはずです
$ kubectl get deployments
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
example-app-deploy   4         5         2            3           2m

$ # 2つのポッドが作られてはエラーで失敗するのが確認できます
$ kubectl get pods
NAME                                  READY     STATUS              RESTARTS   AGE
example-app-deploy-6cf7bb4d7b-8w5ql   1/1       Running             0          38s
example-app-deploy-6cf7bb4d7b-mfj2f   1/1       Running             0          39s
example-app-deploy-6cf7bb4d7b-wgnzz   1/1       Running             0          39s
example-app-deploy-7b94f7d694-6fdxq   0/1       ErrImagePull        0          6s
example-app-deploy-7b94f7d694-7g8hf   0/1       ContainerCreating   0          6s

ロールアウトに問題があっても、すぐにロールバックすることができます。

$ kubectl rollout undo deployments/example-app-deploy
deployment "example-app-deploy" rolled back

$ kubectl get deployments
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
example-app-deploy   4         4         4            4           6m

$ kubectl get pods
NAME                                  READY     STATUS        RESTARTS   AGE
example-app-deploy-6cf7bb4d7b-8w5ql   1/1       Running       0          2m
example-app-deploy-6cf7bb4d7b-k4jb9   1/1       Running       0          6s
example-app-deploy-6cf7bb4d7b-mfj2f   1/1       Running       0          2m
example-app-deploy-6cf7bb4d7b-wgnzz   1/1       Running       0          2m

このように、コントローラを用いることで、ポッドの複雑な制御を簡単に実現できます。

サービス

デプロイメントでクラスタ上にポッドを展開・管理することができました。しかし、どうやってアプリケーションにアクセスすれば良いのでしょうか。

Kubernetesポッドは、クラスタ内部から到達可能なプライベートIPアドレスを必ず割り当てられます(IP-per-Pod)。また、クラスタ内のポッドはすべてのポッドと通信可能であることを仮定しています。より詳細には、Kubernetesは以下の条件が満たされていることを前提に動作します。なお、ポッド内のコンテナは同じネットワーク名前空間を共有するので、以下の「コンテナ」は「ポッド」に読み替えても同じことが言えます。

  • すべてのコンテナはNATなしで他のすべてのコンテナと通信できる
  • すべてのノードはNATなしですべてのコンテナと通信できる(逆も同様)
  • コンテナIPはどのコンテナから見ても同じである

("Cluster Networking"より引用、翻訳 2018/3/18)

しかし、ポッドはコントローラによって動的に作成・更新・削除される可能性があり、ポッドのインスタンスに割り当てられるIPアドレスは一意ではありません。

サービスは、クラスタの内部または外部から、目的のポッドにアクセス可能な経路をなんらかの手段で提供します。

  • ClusterIP(デフォルト): ポッドにリダイレクトするエンドポイントをクラスタ内部プライベートIPで公開する
  • NodePort: ノードの静的ポートをクラスタIPにNATする
  • LoadBalancer: クラウドプロバイダなどの外部ロードバランサが、ノードのポートとクラスタIPにルーティングするようにプロビジョニングする
  • ExternalName: DNSアドオンを使うことで、サービスに外部名を与える

種類が多いため、各詳細はこちらのドキュメントを参考にしてください。

# service.yaml
# Serviceの定義例
# デフォルトでClusterIPとみなされます
kind: Service
apiVersion: v1
metadata:
  name: example-service
spec:
  selector:
    app: example-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

サービスは、spec.selectorに指定されたラベルを持つポッドにトラフィックをリダイレクトします。

デプロイメントが存在する場合、kubectl exposeで簡単にサービスを作成することもできます。

$ kubectl expose deployments/example-app-deploy
service "example-app-deploy" exposed

$ kubectl get services
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
example-app-deploy   ClusterIP   10.98.214.101   <none>        80/TCP    17s
kubernetes           ClusterIP   10.96.0.1       <none>        443/TCP   19h

services/example-app-deployに、クラスタ内プライベートIPアドレス10.98.214.101が割り当てられたのが確認できます。このIPにアクセスすると、deployments/example-app-deployのいずれかのポッドにリダイレクトされます。

クラスタIPにはクラスタネットワーク内部からしかアクセスできないので、最初のDashboardと同じように、プロキシでサービスにアクセスしてみましょう。

$ # 既に実行中なら不要です
$ kubectl proxy
Starting to serve on 127.0.0.1:8001

http://127.0.0.1:8001/api/v1/namespaces/default/services/example-app-deploy/proxy/

f:id:ornew:20180326142351p:plain

「Welcom to nginx!」が表示されれば成功です。上記で作成したサービスはClusterIPですが、NodePortLoadBalancerを使えば、クラスタ外部へポッドを公開することができます。

単純なアプリケーションをKubernetesに展開する

ここまで、ポッド、コントローラ、サービスの3つの基本的なオブジェクトを解説しました。この3つだけでも、簡単にアプリケーションを構築することができます。

yamlのオブジェクト定義ファイルは、---で区切ることで複数のオブジェクトを1つのファイルで定義できます。例で扱ったnginxアプリケーションも、一つのファイルで作成できます。

# nginx.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.9.1
        ports:
        - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
$ kubectl create -f nginx.yaml
deployment "nginx" created
service "nginx-svc" created

$ kubectl get all
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deploy/nginx   3         3         3            3           2m

NAME                  DESIRED   CURRENT   READY     AGE
rs/nginx-5964dfd755   3         3         3         2m

NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deploy/nginx   3         3         3            3           2m

NAME                  DESIRED   CURRENT   READY     AGE
rs/nginx-5964dfd755   3         3         3         2m

NAME                        READY     STATUS    RESTARTS   AGE
po/nginx-5964dfd755-624n7   1/1       Running   0          2m
po/nginx-5964dfd755-fw82q   1/1       Running   0          2m
po/nginx-5964dfd755-jkjxf   1/1       Running   0          2m

NAME             TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
svc/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP   20h
svc/nginx-svc    ClusterIP   10.99.43.51   <none>        80/TCP    2m

Kubernetesを使うと、アプリケーションで構成されるサービスを、宣言的なオブジェクトの定義で簡単に展開し、柔軟に制御することができます。

ところで、ここまでのアプリケーション作成の話において、インフラに関する話題が出なかったことにお気づきでしょうか。従来のマシン指向インフラがマシンを管理するものであったのに対し、Kubernetesが管理しているのはマシンではなくコンテナです。コンテナはインフラからランタイムを分離し、Kubernetesはコンテナとインフラの間のワークロードを自動化します。ゆえに、コンテナアプリケーションはインフラに依存する必要がありません。これは、アプリケーション開発者とインフラ運用者の関心を適切に分離します。

記事冒頭で紹介した"Borg, Omega, and Kubernetes"では、マシンではなくコンテナを管理対象とすることによる利点が以下のように述べられています:

Building management APIs around containers rather than machines shifts the "primary key" of the data center from machine to application. This has many benefits: (1) it relieves application developers and operations teams from worrying about specific details of machines and operating systems; (2) it provides the infrastructure team flexibility to roll out new hardware and upgrade operating systems with minimal impact on running applications and their developers; (3) it ties telemetry collected by the management system (e.g., metrics such as CPU and memory usage) to applications rather than machines, which dramatically improves application monitoring and introspection, especially when scale-up, machine failures, or maintenance cause application instances to move.

(acmqueue | january-february 2016 "Borg, Omega, and Kubernetes" p.76より引用)

Kubernetesは、コンテナプラットフォームであると同時に、アプリケーション指向のインフラでもあるのです。

おわりに

この記事では、最も基本的な3つのオブジェクトを通してKubernetesのデザインを紹介しました。

  • Kubernetesは、コンテナオーケストレーションシステムです
  • ポッドは、コンテナアプリケーションの単位です
  • デプロイメントコントローラは、ポッドの展開を自動で制御します
  • サービスは、ポッドをクラスタ内外へ公開します
  • これらのオブジェクトでシンプルなアプリケーションを構築しました

Kubernetesでのアプリケーション開発に興味が湧いたなら、オブジェクトについての理解を深めてみましょう。

  • ポッドのライフサイクルの理解、リソース制御、死活監視の設定
  • サービス、DNSアドオン、ネットワークポリシーを用いたポッド間通信の制御
  • コンフィグマップの活用、シークレットによる機密情報の管理
  • 永続ボリュームの利用、動的プロビジョニング
  • ステートフルアプリケーションのデプロイ
  • ジョブの活用

Kubernetesの導入を検討したり、クラスタを運用する必要があれば、Kubernetesクラスタの管理について学んでみると良いでしょう。

  • KuberntesクラスタノードとAPIのセキュリティ保護
  • 監視、ロギングシステムの構築と管理、ノードのヘルスチェック方法
  • クラスタ証明書の管理方法
  • リソース割り当ての制限、スケジューラの制御
  • クラスタの拡張方法

詳細については、ドキュメントを読むか、コミュニティに参加して学んでみてください。

コンテナアプリケーション開発は、Kubernetesの成熟により今後さらに加速していくでしょう。この記事がKubernetesを始める足がかりとなれば幸いです。

以上、Kubernetes入門でした。

採用情報

現在、CTO室では、エンジニアメンバーを募集しております! 興味のある方はぜひ下記募集ページをご確認下さい! dmm-corp.com


  1. コンポジットコンテナを用いるパターンについては、"The Distributed System ToolKit: Patterns for Composite Containers“に紹介されています。