配置制約と配置優先度を持つサービスを作成する
このステップでは、配置制約(placement constraints)と配置優先度(placement preferences)を使用して、Docker Swarm 内でサービスタスクをどこにデプロイするかを制御する方法を学びます。配置制約は、タスクをノードにスケジュールするためにノードが満たさなければならない厳格な要件です。配置優先度は、スケジューリングに影響を与える柔軟な要件であり、優先度を満たすノードがない場合でもタスクのスケジューリングを妨げません。
まず、現在のノードのラベルを確認しましょう。ラベルは、ノードにメタデータを付与するために関連付けることができるキーと値のペアです。
docker node inspect self --format '{{ .Spec.Labels }}'
このコマンドは、現在のノード(self
で識別)を調査し、出力をフォーマットしてラベルを表示します。デフォルトでは、カスタムラベルは存在しない場合があります。
現在のノードにラベルを追加しましょう。node_type=app
というラベルを追加します。
docker node update --label-add node_type=app self
このコマンドは、現在のノードを更新し、node_type=app
というラベルを追加します。
次に、ラベルが追加されたことを確認しましょう。
docker node inspect self --format '{{ .Spec.Labels }}'
出力に map[node_type:app]
が表示されるはずで、これはラベルが正常に追加されたことを示します。
では、ノードが node_type=app
というラベルを持っていることを配置制約として要求する my-constrained-service
という名前のレプリケート型サービスを作成しましょう。nginx
イメージを使用します。
docker service create \
--name my-constrained-service \
--replicas 1 \
--constraint 'node.labels.node_type == app' \
nginx:latest
このコマンドは、制約を持つサービスを作成します。--constraint 'node.labels.node_type == app'
は、このサービスのタスクは node_type
ラベルが app
と等しいノードにのみスケジュールできることを指定します。このラベルを現在のノードに追加したので、タスクはこのノードにスケジュールされるはずです。
サービスの状態とタスクを確認します。
docker service ls
docker service ps my-constrained-service
my-constrained-service
が一覧表示され、そのタスクが現在のノードで実行されているのが見えるはずです。
次に、配置優先度を持つ別のサービスを作成しましょう。配置優先度は、スケジューラをガイドするために使用されますが、厳密に強制されるわけではありません。busybox
イメージを使用し、node_type=database
というラベルを持つノードを優先します。現在のノードにこのラベルがないため、タスクは依然として現在のノードにスケジュールされますが、そのラベルを持つ他のノードがあれば、スケジューラはそれらを優先します。
まず、busybox
イメージを取得します。
docker pull busybox:latest
次に、配置優先度を持つサービスを作成します。
docker service create \
--name my-preferred-service \
--replicas 1 \
--placement-pref 'spread=node.labels.node_type' \
busybox:latest sleep infinity
--placement-pref 'spread=node.labels.node_type'
オプションは、スケジューラに node_type
ラベルの値に基づいてタスクをノード間で分散させるよう指示します。異なる node_type
ラベルを持つマルチノードの Swarm では、これによりタスクがより均等に分散されます。この単一ノードの環境では、タスクは利用可能なノードに単純にスケジュールされます。
サービスの状態とタスクを確認します。
docker service ls
docker service ps my-preferred-service
my-preferred-service
が一覧表示され、そのタスクが現在のノードで実行されているのが見えるはずです。