このページでは、Google Kubernetes Engine(GKE) クラスタ内で Kubernetes Service を作成する方法について説明します。 Service を使用すると、一連の Pod エンドポイントを 1 つのリソースにグループ化できます。このグループにアクセスするさまざまな方法を構成できます。
このドキュメントでは、いくつかの演習を行います。各演習では、Service を作成して Pod を公開します。その後、その Service に HTTP リクエストを送信します。
このドキュメントの対象
組織のネットワーク アーキテクト、ネットワーク エンジニア、ネットワーク管理者、あるいはネットワーク アーキテクチャの定義、実装、メンテナンスを担当する他のチームと協力して、Ingress の構成を計画し、設計することをおすすめします。
デフォルトの GKE 構成
デフォルトでは固定クラスタ IP アドレスを取得し、クラスタ内のクライアントはそれを使って Service 内の Pod と通信できます。クライアントがこの IP アドレスにリクエストを送信すると、リクエストが Service 内の Pod の 1 つにルーティングされます。
Service には、次の 5 つのタイプがあります。
- ClusterIP(デフォルト)
- NodePort
- LoadBalancer
- ExternalName
- Headless
デフォルトでは、Autopilot クラスタは一般公開されます。限定公開の Autopilot クラスタを使用する場合は、Cloud NAT を構成して、アウトバウンド インターネット接続(DockerHub からのイメージの pull など)を行う必要があります。
始める前に
始める前に、次の作業が完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
ClusterIP タイプの Service の作成
このセクションでは、ClusterIP
タイプの Service を作成します。Kubernetes は、クラスタ内のノードからアクセスできる固定の IP アドレスを ClusterIP
タイプの Service に作成します。詳しくは、ClusterIP
をご覧ください。
kubectl apply
Deployment
のマニフェストは次のとおりです。Deployment は、最新の Pod テンプレートを含む 3 つのレプリカを作成する Kubernetes コントローラです。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
selector:
matchLabels:
app: metrics
department: sales
replicas: 3
template:
metadata:
labels:
app: metrics
department: sales
spec:
containers:
- name: hello
image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
このマニフェストを my-deployment.yaml
という名前のファイルにコピーして Deployment を作成します。
kubectl apply -f my-deployment.yaml
次のようにして、3 つの Pod が実行中であることを確認します。
kubectl get pods
出力に、実行中の 3 つの Pod が表示されます。
NAME READY STATUS RESTARTS AGE
my-deployment-dbd86c8c4-h5wsf 1/1 Running 0 7s
my-deployment-dbd86c8c4-qfw22 1/1 Running 0 7s
my-deployment-dbd86c8c4-wt4s6 1/1 Running 0 7s
ClusterIP
タイプの Service のマニフェストは次のとおりです。
apiVersion: v1
kind: Service
metadata:
name: my-cip-service
spec:
type: ClusterIP
# Uncomment the below line to create a Headless Service
# clusterIP: None
selector:
app: metrics
department: sales
ports:
- protocol: TCP
port: 80
targetPort: 8080
この Service には、次の 2 つのラベルを指定するセレクタがあります。
app: metrics
department: sales
事前に作成した Deployment 内の各 Pod は、これら 2 つのラベルを有しています。そのため、Deployment 内の Pod はこの Service のメンバーになります。
マニフェストを my-cip-service.yaml
という名前のファイルにコピーして、Service を作成します。
kubectl apply -f my-cip-service.yaml
Kubernetes が固定内部アドレスを Service に割り当てるまで待ってから、次のようにして Service を表示します。
kubectl get service my-cip-service --output yaml
出力に、clusterIP
の値が表示されます。
spec:
clusterIP: 10.59.241.241
後で使用できるように、clusterIP
の値をメモしておきます。
コンソール
Deployment
を作成します。Deployment は、最新の Pod テンプレートを含む 3 つのレプリカを作成する Kubernetes コントローラです。
Google Cloud コンソールの [ワークロード] ページに移動します。
[add_box デプロイ] をクリックします。
[コンテナの指定] で [既存のコンテナ イメージ] を選択します。
[イメージパス] に「
us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
」と入力します。[完了]、[続行] の順にクリックします。
[構成] の [アプリケーション名] に「
my-deployment
」と入力します。[ラベル] で、次のラベルを作成します。
- キー:
app
、値:metrics
- キー:
department
、値:sales
- キー:
[クラスタ] で、Deployment を作成するクラスタを選択します。
[デプロイ] をクリックします。
Deployment の準備が整うと、[デプロイの詳細] ページが開きます。[マネージド Pod] で、Deployment に 1 つ以上の実行中の Pod があることを確認できます。
Deployment
を公開する Service を作成します。Deployment は、最新の Pod テンプレートを含む 3 つのレプリカを作成する Kubernetes コントローラです。
- 上の [デプロイの詳細] ページで、list [アクション] > [公開] をクリックします。
[公開] ダイアログの [ポート マッピング] で、次の値を設定します。
- ポート:
80
- ターゲット ポート:
8080
- プロトコル:
TCP
- ポート:
[サービスタイプ] プルダウン リストから [クラスタの IP] を選択します。
[公開] をクリックします。
Service の準備が整うと、[サービスの詳細] ページが開き、Service に関する詳細情報が表示されます。[Cluster IP] で、Kubernetes によって Service に割り当てられた IP アドレスをメモしておきます。これは、内部クライアントが Service を呼び出すために使用できる IP アドレスです。
コンソールではヘッドレス Service を作成できません。
Service にアクセスする
メンバー Pod ごとに、TCP ポート 8080 でリッスンするコンテナがあります。次のセクションでは、コンテナがポート 8080 でリッスンしないようにします。アプリの Dockerfile とソースコードを見ると、hello-app
がポート 8080 でリッスンしていることがわかります。
次のコマンドを実行して、実行中の Pod を一覧表示します。
kubectl get pods
出力で、my-deployment
で始まる Pod 名のうち 1 つをコピーします。
NAME READY STATUS RESTARTS AGE
my-deployment-dbd86c8c4-h5wsf 1/1 Running 0 2m51s
次のようにして、実行中のいずれかのコンテナでシェルを起動します。
kubectl exec -it POD_NAME -- sh
POD_NAME
は、my-deployment
内のいずれかの Pod の名前に置き換えます。
シェルで、curl
をインストールします。
apk add --no-cache curl
コンテナから、クラスタの IP アドレスとポート 80 を使用して Service へのリクエストを行います。80 は、Service の port
フィールドの値であるのでご注意ください。Service のクライアントが使用するポートです。
curl CLUSTER_IP:80
CLUSTER_IP
は、Service 内の clusterIP
の値に置き換えます。
TCP ポート 8080 でリッスンするコンテナが各メンバー Pod に存在することを、事前に確認しておく必要があります。この演習では、コンテナがポート 8080 でリッスンするような操作は何も行いませんでした。アプリの Dockerfile とソースコードを見ると、hello-app
がポート 8080 でリッスンしていることがわかります。
レスポンスには hello-app
の出力が含まれます。
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-h5wsf
コンテナのシェルを終了するには、「exit
」と入力します。
リクエストは、TCP ポート 80 上のいずれかのメンバー Pod(targetPort
フィールドの値)に転送されます。
NodePort タイプの Service の作成
このセクションでは、NodePort
タイプの Service を作成します。NodePort
は、Kubernetes が固定のポート値を割り当てる Service のタイプです。NodePort Service には、nodePort 値を持つ任意のノードの IP アドレスを使用してアクセスできます。詳しくは、NodePort
をご覧ください。
kubectl apply
Deployment
のマニフェストは次のとおりです。Deployment は、最新の Pod テンプレートを含む 3 つのレプリカを作成する Kubernetes コントローラです。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment-50000
spec:
selector:
matchLabels:
app: metrics
department: engineering
replicas: 3
template:
metadata:
labels:
app: metrics
department: engineering
spec:
containers:
- name: hello
image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
env:
- name: "PORT"
value: "50000"
マニフェスト内の env
オブジェクトに注目してください。env
オブジェクトでは、実行中のコンテナの PORT
環境変数の値が 50000
になることを指定しています。hello-app
アプリケーションは、PORT
環境変数で指定されたポートでリッスンします。つまり、この演習では、ポート 50000 でリッスンするようコンテナに指示しています。
このマニフェストを my-deployment-50000.yaml
という名前のファイルにコピーし、次のようにして Deployment を作成します。
kubectl apply -f my-deployment-50000.yaml
次のようにして、3 つの Pod が実行中であることを確認します。
kubectl get pods
NodePort タイプの Service のマニフェストは次のとおりです。
apiVersion: v1
kind: Service
metadata:
name: my-np-service
spec:
type: NodePort
selector:
app: metrics
department: engineering
ports:
- protocol: TCP
port: 80
targetPort: 50000
マニフェストを my-np-service.yaml
という名前のファイルにコピーして、Service を作成します。
kubectl apply -f my-np-service.yaml
Service を表示します。
kubectl get service my-np-service --output yaml
出力に、nodePort
の値が表示されます。
...
spec:
...
ports:
- nodePort: 30876
port: 80
protocol: TCP
targetPort: 50000
selector:
app: metrics
department: engineering
sessionAffinity: None
type: NodePort
...
ファイアウォール ルールを作成して、ノードポートの TCP トラフィックを許可します。
gcloud compute firewall-rules create test-node-port \
--allow tcp:NODE_PORT
NODE_PORT
は、Service の nodePort
フィールドの値に置き換えます。
コンソール
Deployment
を作成します。Deployment は、最新の Pod テンプレートを含む 3 つのレプリカを作成する Kubernetes コントローラです。
Google Cloud コンソールの [ワークロード] ページに移動します。
[add_box デプロイ] をクリックします。
[コンテナの指定] で [既存のコンテナ イメージ] を選択します。
[イメージパス] に「
us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
」と入力します。[add 環境変数を追加] をクリックします。
[キー] に「
PORT
」、[値] に「50000
」と入力します。[完了]、[続行] の順にクリックします。
[構成] の [アプリケーション名] に「
my-deployment-50000
」と入力します。[ラベル] で、次のラベルを作成します。
- キー:
app
、値:metrics
- キー:
department
、値:engineering
- キー:
[クラスタ] で、Deployment を作成するクラスタを選択します。
[デプロイ] をクリックします。
Deployment の準備が整うと、[デプロイの詳細] ページが開きます。[マネージド Pod] で、Deployment に 1 つ以上の実行中の Pod があることを確認できます。
Deployment
を公開する Service を作成します。
- 上の [デプロイの詳細] ページで、list [アクション] > [公開] をクリックします。
[公開] ダイアログの [ポート マッピング] で、次の値を設定します。
- ポート:
80
- ターゲット ポート:
50000
- プロトコル:
TCP
- ポート:
[サービスのタイプ] プルダウン リストから [ノードポート] を選択します。
[公開] をクリックします。
Service の準備が整うと、[サービスの詳細] ページが開き、Service に関する詳細情報が表示されます。[ポート] で、Kubernetes によって Service に割り当てられた [ノードポート] をメモしておきます。
ノードポート用のファイアウォール ルールを作成します。
Google Cloud コンソールの [ファイアウォール ポリシー] ページに移動します。
[add_box ファイアウォール ルールを作成] をクリックします。
[名前] に「
test-node-port
」と入力します。[ターゲット] プルダウン リストから [ネットワーク上のすべてのインスタンス] を選択します。
[送信元 IPv4 範囲] に「
0.0.0.0/0
」と入力します。[プロトコルとポート] で [指定したプロトコルとポート] を選択します。
[tcp] チェックボックスをオンにして、メモしたノードポートの値を入力します。
[作成] をクリックします。
ノードの IP アドレスを取得する
いずれかのノードの外部 IP アドレスを見つけます。
kubectl get nodes --output wide
出力は次のようになります。
NAME STATUS ROLES AGE VERSION EXTERNAL-IP
gke-svc-... Ready none 1h v1.9.7-gke.6 203.0.113.1
すべてのクラスタにノード用の外部 IP アドレスがあるわけではありません。たとえば、プライベート クラスタ内のノードは外部 IP アドレスを持ちません。
Service にアクセスする
ブラウザのアドレスバーに次のように入力します。
NODE_IP_ADDRESS:NODE_PORT
次のように置き換えます。
NODE_IP_ADDRESS
: 前のタスクでサービスを作成したときに見つかった、いずれかのノードの外部 IP アドレスです。NODE_PORT
: ノードポートの値。
出力は次のようになります。
Hello, world!
Version: 2.0.0
Hostname: my-deployment-50000-6fb75d85c9-g8c4f
LoadBalancer タイプの Service の作成
このセクションでは、LoadBalancer
タイプの Service を作成します。LoadBalancer
Service は、GKE コントローラが外部パススルー ネットワーク ロードバランサをプロビジョニングして構成する Service のタイプです。詳しくは、LoadBalancer
をご覧ください。
kubectl apply
Deployment のマニフェストは次のとおりです。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment-50001
spec:
selector:
matchLabels:
app: products
department: sales
replicas: 3
template:
metadata:
labels:
app: products
department: sales
spec:
containers:
- name: hello
image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
env:
- name: "PORT"
value: "50001"
この Deployment のコンテナは、ポート 50001 でリッスンすることに注意してください。
このマニフェストを my-deployment-50001.yaml
という名前のファイルにコピーし、次のようにして Deployment を作成します。
kubectl apply -f my-deployment-50001.yaml
次のようにして、3 つの Pod が実行中であることを確認します。
kubectl get pods
LoadBalancer
タイプの Service のマニフェストは次のとおりです。
apiVersion: v1
kind: Service
metadata:
name: my-lb-service
spec:
type: LoadBalancer
selector:
app: products
department: sales
ports:
- protocol: TCP
port: 60000
targetPort: 50001
マニフェストを my-lb-service.yaml,
という名前のファイルにコピーし、Service を作成します。
kubectl apply -f my-lb-service.yaml
コントローラがネットワーク ロードバランサを構成して固定 IP アドレスを生成するまで、少し待ちます。
Service を表示します。
kubectl get service my-lb-service --output yaml
出力の loadBalancer:ingress
の下に固定の外部 IP アドレスが表示されます。
...
spec:
...
ports:
- ...
port: 60000
protocol: TCP
targetPort: 50001
selector:
app: products
department: sales
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 203.0.113.10
コンソール
Deployment
を作成します。Deployment は、最新の Pod テンプレートを含む 3 つのレプリカを作成する Kubernetes コントローラです。
Google Cloud コンソールの [ワークロード] ページに移動します。
[add_box デプロイ] をクリックします。
[コンテナの指定] で [既存のコンテナ イメージ] を選択します。
[イメージパス] に「
us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
」と入力します。[add 環境変数を追加] をクリックします。
[キー] に「
PORT
」、[値] に「50001
」と入力します。[完了]、[続行] の順にクリックします。
[構成] の [アプリケーション名] に「
my-deployment-50001
」と入力します。[ラベル] で、次のラベルを作成します。
- キー:
app
、値:products
- キー:
department
、値:sales
- キー:
[クラスタ] で、Deployment を作成するクラスタを選択します。
[デプロイ] をクリックします。
Deployment の準備が整うと、[デプロイの詳細] ページが開きます。[マネージド Pod] で、Deployment に 1 つ以上の実行中の Pod があることを確認できます。
Service を作成して Deployment を公開する
- 上の [デプロイの詳細] ページで、list [アクション] > [公開] をクリックします。
[公開] ダイアログの [ポート マッピング] で、次の値を設定します。
- ポート:
60000
- ターゲット ポート:
50001
- プロトコル:
TCP
- ポート:
[サービスのタイプ] プルダウン リストから、[ロードバランサ] を選択します。
[公開] をクリックします。
Service の準備が整うと、[サービスの詳細] ページが開き、Service に関する詳細情報が表示されます。[ロードバランサ] で、ロードバランサの外部 IP アドレスをメモしておきます。
Service にアクセスする
GKE がロードバランサを構成するまで数分待ちます。
ブラウザのアドレスバーに次のように入力します。
LOAD_BALANCER_ADDRESS:60000
LOAD_BALANCER_ADDRESS
は、ロードバランサの外部 IP アドレスに置き換えます。
レスポンスには hello-app
の出力が含まれます。
Hello, world!
Version: 2.0.0
Hostname: my-deployment-50001-68bb7dfb4b-prvct
ExternalName タイプの Service の作成
このセクションでは、ExternalName
タイプの Service を作成します。ExternalName
タイプの Service は、外部 DNS 名のための内部エイリアスを提供します。内部クライアントは、内部 DNS 名を使用してリクエストを行い、そのリクエストは外部名にリダイレクトされます。詳しくは、ExternalName
をご覧ください。
ExternalName
タイプの Service のマニフェストは次のとおりです。
apiVersion: v1
kind: Service
metadata:
name: my-xn-service
spec:
type: ExternalName
externalName: example.com
上記の例で、DNS 名は my-xn-service.default.svc.cluster.local
です。内部クライアントが my-xn-service.default.svc.cluster.local
にリクエストを送信すると、そのリクエストは example.com にリダイレクトされます。
kubectl expose
を使用した Service の作成
Service マニフェストを作成する代わりに、kubectl expose
コマンドを使用して Deployment を公開することもできます。このドキュメントで説明した my-deployment
を公開するには、次のコマンドを入力します。
kubectl expose deployment my-deployment --name my-cip-service \
--type ClusterIP --protocol TCP --port 80 --target-port 8080
my-deployment-50000
を公開するには、このトピックで説明したように、次のコマンドを入力します。
kubectl expose deployment my-deployment-50000 --name my-np-service \
--type NodePort --protocol TCP --port 80 --target-port 50000
my-deployment-50001
を公開するには、このドキュメントで説明したように、次のコマンドを入力します。
kubectl expose deployment my-deployment-50001 --name my-lb-service \
--type LoadBalancer --port 60000 --target-port 50001
クリーンアップ
このページの演習を完了したら、アカウントで不要な請求が発生しないように、以下の手順でリソースを削除します。
kubectl apply
Service を削除する
kubectl delete services my-cip-service my-np-service my-lb-service
Deployment を削除する
kubectl delete deployments my-deployment my-deployment-50000 my-deployment-50001
ファイアウォール ルールを削除する
gcloud compute firewall-rules delete test-node-port
Console
Service を削除する
Google Cloud コンソールで [サービス] ページに移動します。
このチュートリアルで作成した Service を選択し、[delete 削除] をクリックします。
確認のメッセージが表示されたら、[削除] をクリックします。
Deployment を削除する
Google Cloud コンソールの [ワークロード] ページに移動します。
このチュートリアルで作成した Deployment を選択し、[delete 削除] をクリックします。
確認を求められたら、[Delete Horizontal Pod Autoscalers associated with selected Deployments] チェックボックスをオンにして、[削除] をクリックします。
ファイアウォール ルールを削除する
Google Cloud コンソールの [ファイアウォール ポリシー] ページに移動します。
test-node-port チェックボックスをオンにして、[delete 削除] をクリックします。
確認のメッセージが表示されたら、[削除] をクリックします。
次のステップ
- Service のコンセプトや種類の説明については、Service をご覧ください。
- Service
- StatefulSet
- 上り(内向き)
- Ingress を使用した HTTP 負荷分散