リソースの管理
アプリケーションをデプロイし、Serviceを介して外部に公開できました。さて、どうしますか?Kubernetesは、スケーリングや更新など、アプリケーションのデプロイを管理するための多くのツールを提供します。 我々が取り上げる機能についての詳細は設定ファイルとラベルについて詳細に説明します。
リソースの設定を管理する
多くのアプリケーションではDeploymentやServiceなど複数のリソースの作成を要求します。複数のリソースの管理は、同一のファイルにひとまとめにしてグループ化すると簡単になります(YAMLファイル内で---
で区切る)。
例えば:
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
複数のリソースは単一のリソースと同様の方法で作成できます。
kubectl apply -f https://k8s.io/examples/application/nginx-app.yaml
service/my-nginx-svc created
deployment.apps/my-nginx created
リソースは、ファイル内に記述されている順番通りに作成されます。そのため、Serviceを最初に指定するのが理想です。スケジューラーがServiceに関連するPodを、Deploymentなどのコントローラーによって作成されるときに確実に拡散できるようにするためです。
kubectl apply
もまた、複数の-f
による引数指定を許可しています。
kubectl apply -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
個別のファイルに加えて、-fの引数としてディレクトリ名も指定できます:
kubectl apply -f https://k8s.io/examples/application/nginx/
kubectl
は.yaml
、.yml
、.json
といったサフィックスの付くファイルを読み込みます。
同じマイクロサービス、アプリケーションティアーのリソースは同一のファイルにまとめ、アプリケーションに関するファイルをグループ化するために、それらのファイルを同一のディレクトリに配備するのを推奨します。アプリケーションのティアーがDNSを通じて互いにバインドされると、アプリケーションスタックの全てのコンポーネントをひとまとめにして簡単にデプロイできます。
リソースの設定ソースとして、URLも指定できます。githubから取得した設定ファイルから直接手軽にデプロイができます:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx created
kubectlによる一括操作
kubectl
が一括して実行できる操作はリソースの作成のみではありません。作成済みのリソースの削除などの他の操作を実行するために、設定ファイルからリソース名を取得することができます。
kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted
2つのリソースだけを削除する場合には、コマンドラインでリソース/名前というシンタックスを使うことで簡単に指定できます。
kubectl delete deployments/my-nginx services/my-nginx-svc
さらに多くのリソースに対する操作では、リソースをラベルでフィルターするために-l
や--selector
を使ってセレクター(ラベルクエリ)を指定するのが簡単です:
kubectl delete deployment,services -l app=nginx
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted
kubectl
は同様のシンタックスでリソース名を出力するので、$()
やxargs
を使ってパイプで操作するのが容易です:
kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service)
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx-svc LoadBalancer 10.0.0.208 <pending> 80/TCP 0s
上記のコマンドで、最初にexamples/application/nginx/
配下でリソースを作成し、-o name
という出力フォーマットにより、作成されたリソースの名前を表示します(各リソースをresource/nameという形式で表示)。そして"service"のみgrep
し、kubectl get
を使って表示させます。
あるディレクトリ内の複数のサブディレクトリをまたいでリソースを管理するような場合、--filename,-f
フラグと合わせて--recursive
や-R
を指定することでサブディレクトリに対しても再帰的に操作が可能です。
例えば、開発環境用に必要な全てのマニフェストをリソースタイプによって整理しているproject/k8s/development
というディレクトリがあると仮定します。
project/k8s/development
├── configmap
│ └── my-configmap.yaml
├── deployment
│ └── my-deployment.yaml
└── pvc
└── my-pvc.yaml
デフォルトでは、project/k8s/development
における一括操作は、どのサブディレクトリも処理せず、ディレクトリの第1階層で処理が止まります。下記のコマンドによってこのディレクトリ配下でリソースを作成しようとすると、エラーが発生します。
kubectl apply -f project/k8s/development
error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin)
代わりに、下記のように--filename,-f
フラグと合わせて--recursive
や-R
を指定してください:
kubectl apply -f project/k8s/development --recursive
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created
--recursive
フラグはkubectl {create,get,delete,describe,rollout}
などのような--filename,-f
フラグを扱うどの操作でも有効です。
また、--recursive
フラグは複数の-f
フラグの引数を指定しても有効です。
kubectl apply -f project/k8s/namespaces -f project/k8s/development --recursive
namespace/development created
namespace/staging created
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created
kubectl
についてさらに知りたい場合は、kubectlの概要を参照してください。
ラベルを有効に使う
これまで取り上げた例では、リソースに対して最大1つのラベルを適用してきました。リソースのセットを他のセットと区別するために、複数のラベルが必要な状況があります。
例えば、異なるアプリケーション間では、異なるapp
ラベルを使用したり、ゲストブックの例のようなマルチティアーのアプリケーションでは、各ティアーを区別する必要があります。frontendというティアーでは下記のラベルを持ちます。:
labels:
app: guestbook
tier: frontend
Redisマスターやスレーブでは異なるtier
ラベルを持ち、加えてrole
ラベルも持つことでしょう。:
labels:
app: guestbook
tier: backend
role: master
そして
labels:
app: guestbook
tier: backend
role: slave
ラベルを使用すると、ラベルで指定された任意の次元に沿ってリソースを分割できます。
kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
NAME READY STATUS RESTARTS AGE APP TIER ROLE
guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend <none>
guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master
guestbook-redis-slave-2q2yf 1/1 Running 0 1m guestbook backend slave
guestbook-redis-slave-qgazl 1/1 Running 0 1m guestbook backend slave
my-nginx-divi2 1/1 Running 0 29m nginx <none> <none>
my-nginx-o0ef1 1/1 Running 0 29m nginx <none> <none>
kubectl get pods -lapp=guestbook,role=slave
NAME READY STATUS RESTARTS AGE
guestbook-redis-slave-2q2yf 1/1 Running 0 3m
guestbook-redis-slave-qgazl 1/1 Running 0 3m
Canary deployments カナリアデプロイ
複数のラベルが必要な他の状況として、異なるリリース間でのDeploymentや、同一コンポーネントの設定を区別することが挙げられます。よく知られたプラクティスとして、本番環境の実際のトラフィックを受け付けるようにするために、新しいリリースを完全にロールアウトする前に、新しいカナリア版のアプリケーションを過去のリリースと合わせてデプロイする方法があります。
例えば、異なるリリースバージョンを分けるためにtrack
ラベルを使用できます。
主要な安定板のリリースではtrack
ラベルにstable
という値をつけることがあるでしょう。:
name: frontend
replicas: 3
...
labels:
app: guestbook
tier: frontend
track: stable
...
image: gb-frontend:v3
そして2つの異なるPodのセットを上書きしないようにするため、track
ラベルに異なる値を持つ(例: canary
)ようなguestbookフロントエンドの新しいリリースを作成できます。
name: frontend-canary
replicas: 1
...
labels:
app: guestbook
tier: frontend
track: canary
...
image: gb-frontend:v4
frontend Serviceは、トラフィックを両方のアプリケーションにリダイレクトさせるために、両方のアプリケーションに共通したラベルのサブセットを選択して両方のレプリカを扱えるようにします。:
selector:
app: guestbook
tier: frontend
安定版とカナリア版リリースで本番環境の実際のトラフィックを転送する割合を決めるため、双方のレプリカ数を変更できます(このケースでは3対1)。 最新版のリリースをしても大丈夫な場合、安定版のトラックを新しいアプリケーションにして、カナリア版を削除します。
さらに具体的な例については、tutorial of deploying Ghostを参照してください。
ラベルの更新
新しいリソースを作成する前に、既存のPodと他のリソースのラベルの変更が必要な状況があります。これはkubectl label
で実行できます。
例えば、全てのnginx Podを frontendティアーとしてラベル付けするには、下記のコマンドを実行するのみです。
kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled
これは最初に"app=nginx"というラベルのついたPodをフィルターし、そのPodに対して"tier=fe"というラベルを追加します。 ラベル付けしたPodを確認するには、下記のコマンドを実行してください。
kubectl get pods -l app=nginx -L tier
NAME READY STATUS RESTARTS AGE TIER
my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe
my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe
my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe
このコマンドでは"app=nginx"というラベルのついた全てのPodを出力し、Podのtierという項目も表示します(-L
または--label-columns
で指定)。
さらなる情報は、ラベルやkubectl labelを参照してください。
アノテーションの更新
リソースに対してアノテーションを割り当てたい状況があります。アノテーションは、ツール、ライブラリなどのAPIクライアントによって取得するための任意の非識別メタデータです。アノテーションの割り当てはkubectl annotate
で可能です。例:
kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx'
kubectl get pods my-nginx-v4-9gw19 -o yaml
apiVersion: v1
kind: pod
metadata:
annotations:
description: my frontend running nginx
...
さらなる情報は、アノテーション や、kubectl annotateを参照してください。
アプリケーションのスケール
アプリケーションの負荷が増減するとき、kubectl
を使って簡単にスケールできます。例えば、nginxのレプリカを3から1に減らす場合、下記を実行します:
kubectl scale deployment/my-nginx --replicas=1
deployment.apps/my-nginx scaled
実行すると、Deploymentによって管理されるPod数が1となります。
kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
my-nginx-2035384211-j5fhi 1/1 Running 0 30m
システムに対してnginxのレプリカ数を自動で選択させるには、下記のように1から3の範囲で指定します。:
kubectl autoscale deployment/my-nginx --min=1 --max=3
horizontalpodautoscaler.autoscaling/my-nginx autoscaled
実行すると、nginxのレプリカは必要に応じて自動でスケールアップ、スケールダウンします。
さらなる情報は、kubectl scale、kubectl autoscale and horizontal pod autoscalerを参照してください。
リソースの直接的アップデート
場合によっては、作成したリソースに対して処理を中断させずに更新を行う必要があります。
kubectl apply
開発者が設定するリソースをコードとして管理しバージョニングも行えるように、設定ファイルのセットをソースによって管理する方法が推奨されています。
この場合、クラスターに対して設定の変更をプッシュするためにkubectl apply
を使用できます。
このコマンドは、リソース設定の過去のバージョンと、今適用した変更を比較し、差分に現れないプロパティーに対して上書き変更することなくクラスターに適用させます。
kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx configured
注意として、前回の変更適用時からの設定の変更内容を決めるため、kubectl apply
はリソースに対してアノテーションを割り当てます。変更が実施されるとkubectl apply
は、1つ前の設定内容と、今回変更しようとする入力内容と、現在のリソースの設定との3つの間で変更内容の差分をとります。
現在、リソースはこのアノテーションなしで作成されました。そのため、最初のkubectl paply
の実行においては、与えられたにゅうチョクト、現在のリソースの設定の2つの間の差分が取られ、フォールバックします。この最初の実行の間、リソースが作成された時にプロパティーセットの削除を検知できません。この理由により、プロパティーの削除はされません。
kubectl apply
の実行後の全ての呼び出しや、kubectl replace
やkubectl edit
などの設定を変更する他のコマンドではアノテーションを更新します。kubectl apply
した後の全ての呼び出しにおいて3-wayの差分取得によってプロパティの検知と削除を実施します。
kubectl edit
その他に、kubectl edit
によってリソースの更新もできます。:
kubectl edit deployment/my-nginx
このコマンドは、最初にリソースをget
し、テキストエディタでリソースを編集し、更新されたバージョンでリソースをapply
します。:
kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml
vi /tmp/nginx.yaml
# yamlファイルを編集し、ファイルを保存します。
kubectl apply -f /tmp/nginx.yaml
deployment.apps/my-nginx configured
rm /tmp/nginx.yaml
このコマンドによってより重大な変更を簡単に行えます。注意として、あなたのEDITOR
やKUBE_EDITOR
といった環境変数も指定できます。
さらなる情報は、kubectl editを参照してください。
kubectl patch
APIオブジェクトの更新にはkubectl patch
を使うことができます。このコマンドはJSON patch、JSON merge patch、戦略的merge patchをサポートしています。
kubectl patchを使ったAPIオブジェクトの更新やkubectl patchを参照してください。
破壊的なアップデート
一度初期化された後、更新できないようなリソースフィールドの更新が必要な場合や、Deploymentによって作成され、壊れている状態のPodを修正するなど、再帰的な変更を即座に行いたい場合があります。このようなフィールドを変更するため、リソースの削除と再作成を行うreplace --force
を使用してください。このケースでは、シンプルに元の設定ファイルを修正するのみです。:
kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force
deployment.apps/my-nginx deleted
deployment.apps/my-nginx replaced
サービス停止なしでアプリケーションを更新する
ある時点で、前述したカナリアデプロイのシナリオにおいて、新しいイメージやイメージタグを指定することによって、デプロイされたアプリケーションを更新が必要な場合があります。kubectl
ではいくつかの更新操作をサポートしており、それぞれの操作が異なるシナリオに対して適用可能です。
ここでは、Deploymentを使ってアプリケーションの作成と更新についてガイドします。
まずnginxのバージョン1.14.2を稼働させていると仮定します。:
kubectl create deployment my-nginx --image=nginx:1.14.2
deployment.apps/my-nginx created
レプリカ数を3にします(新旧のリビジョンは混在します)。:
kubectl scale deployment my-nginx --current-replicas=1 --replicas=3
deployment.apps/my-nginx scaled
バージョン1.16.1に更新するには、上述したkubectlコマンドを使って.spec.template.spec.containers[0].image
の値をnginx:1.14.2
からnginx:1.16.1
に変更するだけでできます。
kubectl edit deployment/my-nginx
できました!Deploymentはデプロイされたnginxのアプリケーションを宣言的にプログレッシブに更新します。更新途中では、決まった数の古いレプリカのみダウンし、一定数の新しいレプリカが希望するPod数以上作成されても良いことを保証します。詳細について学ぶにはDeployment pageを参照してください。
次の項目
- アプリケーションの調査とデバッグのための
kubectl
の使用方法について学んでください。 - 設定のベストプラクティスとTIPSを参照してください。