設定のベストプラクティス
このドキュメントでは、ユーザーガイド、入門マニュアル、および例を通して紹介されている設定のベストプラクティスを中心に説明します。
このドキュメントは生ものです。このリストには載っていないが他の人に役立つかもしれない何かについて考えている場合、IssueまたはPRを遠慮なく作成してください。
一般的な設定のTips
-
構成を定義する際には、最新の安定したAPIバージョンを指定してください。
-
設定ファイルは、クラスターに反映される前にバージョン管理システムに保存されるべきです。これによって、必要に応じて設定変更を迅速にロールバックできます。また、クラスターの再作成や復元時にも役立ちます。
-
JSONではなくYAMLを使って設定ファイルを書いてください。これらのフォーマットはほとんどすべてのシナリオで互換的に使用できますが、YAMLはよりユーザーフレンドリーになる傾向があります。
-
意味がある場合は常に、関連オブジェクトを単一ファイルにグループ化します。多くの場合、1つのファイルの方が管理が簡単です。例としてguestbook-all-in-one.yamlファイルを参照してください。
-
多くの
kubectlコマンドがディレクトリに対しても呼び出せることも覚えておきましょう。たとえば、設定ファイルのディレクトリでkubectl applyを呼び出すことができます。 -
不必要にデフォルト値を指定しないでください。シンプルかつ最小限の設定のほうがエラーが発生しにくくなります。
-
よりよいイントロスペクションのために、オブジェクトの説明をアノテーションに入れましょう。
"真っ裸"のPod に対する ReplicaSet、Deployment、およびJob
-
可能な限り、"真っ裸"のPod(ReplicaSetやDeploymentにバインドされていないPod)は使わないでください。Nodeに障害が発生した場合、これらのPodは再スケジュールされません。
明示的に
restartPolicy: Neverを使いたいシーンを除いて、DeploymentはPodを直接作成するよりもほとんど常に望ましい方法です。Deploymentには、希望する数のPodが常に使用可能であることを確認するためにReplicaSetを作成したり、Podを置き換えるための戦略(RollingUpdateなど)を指定したりできます。Jobのほうが適切な場合もあるかもしれません。
Service
-
対応するバックエンドワークロード(DeploymentまたはReplicaSet)の前、およびそれにアクセスする必要があるワークロードの前にServiceを作成します。Kubernetesがコンテナを起動すると、コンテナ起動時に実行されていたすべてのServiceを指す環境変数が提供されます。たとえば、fooという名前のServiceが存在する場合、すべてのコンテナは初期環境で次の変数を取得します。
FOO_SERVICE_HOST=<the host the Service is running on> FOO_SERVICE_PORT=<the port the Service is running on>これは順序付けの必要性を意味します -
PodがアクセスしたいServiceはPod自身の前に作らなければならず、そうしないと環境変数は注入されません。DNSにはこの制限はありません。 -
(強くお勧めしますが)クラスターアドオンの1つの選択肢はDNSサーバーです。DNSサーバーは、新しい
ServiceについてKubernetes APIを監視し、それぞれに対して一連のDNSレコードを作成します。クラスター全体でDNSが有効になっている場合は、すべてのPodが自動的にServicesの名前解決を行えるはずです。 -
どうしても必要な場合以外は、Podに
hostPortを指定しないでください。PodをhostPortにバインドすると、Podがスケジュールできる場所の数を制限します、それぞれの<hostIP、hostPort、protocol>の組み合わせはユニークでなければならないからです。hostIPとprotocolを明示的に指定しないと、KubernetesはデフォルトのhostIPとして0.0.0.0を、デフォルトのprotocolとしてTCPを使います。デバッグ目的でのみポートにアクセスする必要がある場合は、apiserver proxyまたは
kubectl port-forwardを使用できます。ノード上でPodのポートを明示的に公開する必要がある場合は、hostPortに頼る前にNodePortの使用を検討してください。
-
hostPortの理由と同じくして、hostNetworkの使用はできるだけ避けてください。 -
kube-proxyのロードバランシングが不要な場合は、headless Service(ClusterIPがNone)を使用してServiceを簡単に検出できます。
ラベルの使用
{ app: myapp, tier: frontend, phase: test, deployment: v3 }のように、アプリケーションまたはデプロイメントの セマンティック属性 を識別するラベルを定義して使いましょう。これらのラベルを使用して、他のリソースに適切なPodを選択できます。例えば、すべてのtier:frontendを持つPodを選択するServiceや、app:myappに属するすべてのphase:testコンポーネント、などです。このアプローチの例を知るには、ゲストブックアプリも合わせてご覧ください。
セレクターからリリース固有のラベルを省略することで、Serviceを複数のDeploymentにまたがるように作成できます。 Deploymentにより、ダウンタイムなしで実行中のサービスを簡単に更新できます。
オブジェクトの望ましい状態はDeploymentによって記述され、その仕様への変更が 適用 されると、Deploymentコントローラーは制御された速度で実際の状態を望ましい状態に変更します。
- デバッグ用にラベルを操作できます。Kubernetesコントローラー(ReplicaSetなど)とServiceはセレクターラベルを使用してPodとマッチするため、Podから関連ラベルを削除すると、コントローラーによって考慮されたり、Serviceによってトラフィックを処理されたりすることがなくなります。既存のPodのラベルを削除すると、そのコントローラーはその代わりに新しいPodを作成します。これは、「隔離」環境で以前の「ライブ」Podをデバッグするのに便利な方法です。対話的にラベルを削除または追加するには、
kubectl labelを使います。
コンテナイメージ
imagePullPolicyとイメージのタグは、kubeletが特定のイメージをpullしようとしたときに作用します。
-
imagePullPolicy: IfNotPresent: ローカルでイメージが見つからない場合にのみイメージをpullします。 -
imagePullPolicy: Always: kubeletがコンテナを起動する度に、kubeletはコンテナイメージレジストリに問い合わせて、イメージのダイジェストの名前解決を行います。もし、kubeletが同じダイジェストのコンテナイメージをローカルにキャッシュしていたら、kubeletはそのキャッシュされたイメージを利用します。そうでなければ、kubeletは解決されたダイジェストのイメージをダウンロードし、そのイメージを利用してコンテナを起動します。 -
imagePullPolicyのタグが省略されていて、利用してるイメージのタグが:latestの場合や省略されている場合、Alwaysが適用されます。 -
imagePullPolicyのタグが省略されていて、利用してるイメージのタグはあるが:latestでない場合、IfNotPresentが適用されます。 -
imagePullPolicy: Never: 常にローカルでイメージを探そうとします。ない場合にもイメージはpullしません。
備考:
コンテナが常に同じバージョンのイメージを使用するようにするためには、そのコンテナイメージのダイジェストを指定することができます。<image-name>:<tag>を<image-name>@<digest>で置き換えます(例:image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2)。このダイジェストはイメージの特定のバージョンを一意に識別するため、ダイジェスト値を変更しない限り、Kubernetesによって更新されることはありません。備考:
どのバージョンのイメージが実行されているのかを追跡するのが難しく、適切にロールバックするのが難しいため、本番環境でコンテナをデプロイするときは:latestタグを使用しないでください。備考:
ベースイメージのプロバイダーのキャッシュセマンティクスにより、imagePullPolicy:Alwaysもより効率的になります。たとえば、Dockerでは、イメージがすでに存在する場合すべてのイメージレイヤーがキャッシュされ、イメージのダウンロードが不要であるため、pullが高速になります。kubectlの使い方
-
kubectl apply -f <directory>を使いましょう。これを使うと、ディレクトリ内のすべての.yaml、.yml、および.jsonファイルがapplyに渡されます。 -
getやdeleteを行う際は、特定のオブジェクト名を指定するのではなくラベルセレクターを使いましょう。ラベルセレクターとラベルの効果的な使い方のセクションを参照してください。 -
単一コンテナのDeploymentやServiceを素早く作成するなら、
kubectl create deploymentやkubectl exposeを使いましょう。一例として、Serviceを利用したクラスター内のアプリケーションへのアクセスを参照してください。