こんにちは。KOUKIです。k8s学習中のWebエンジニアです。
前回は、Networkingを学ぶため、開発環境の構築を行いました。
今回は、NetworkingをDeploymentやServiceを作成しつつ学んでいこうと思います。
<目次>
実行環境について
筆者の環境では、k8sはminikube上で動いています。
実行環境については、こちらの記事を参考にしてください。
minikubeスタート
次のコマンドで、minikubeを起動しましょう。
1 2 |
// minikube 起動 minikube start |
Docker Hub – レポジトリ作成
筆者の環境で起動したk8sは、Virtualbox上で動いています。これはローカル環境から切り離されているので、ローカル上のDocker imageを使うことができません。
そのため、Docker HubにDocker imageをPushしておき、イメージを使う時は、そこからPullするようにします。
Docker Hub上で次のレポジトリを作成しておきましょう。
- kub-demo-users
- kub-demo-auth
- kub-demo-tasks
users api
最初に、users apiの環境を構築しましょう。
Deploymentの作成
Deploymentを作成します。
まずは、users-apiのイメージを作成し、Docker Hubへpushします。
1 2 3 4 5 6 |
# users-apiフォルダへ移動 cd users-api # ビルド docker build -t <docker hubのアカウント名>/kub-demo-users . # DockerHubへPush docker push <docker hubのアカウント名>/kub-demo-users |
「docker hubのアカウント」には、Docker Hubの登録時に作成したアカウント名を指定してください。
次に、deployment.ymlファイルを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# ルートフォルダに戻る cd .. # 設定ファイル格納用フォルダを作成 mkdir kubernetes // 設定ファイルを作成 touch kubernetes/users-deployment.yml $ tree . ├── auth-api │ ├── Dockerfile │ ├── go.mod │ ├── go.sum │ └── main.go ├── docker-compose.yml ├── kubernetes <<<<<<<<< │ └── users-deployment.yml <<<<<<<<<<<<< ├── tasks-api │ ├── Dockerfile │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── tasks │ └── tasks.txt └── users-api ├── Dockerfile ├── go.mod ├── go.sum └── main.go |
users-deployment.ymlの設定内容は、以下です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# users-deployment.yml apiVersion: apps/v1 kind: Deployment metadata: name: users-deployment spec: replicas: 1 selector: matchLabels: app: users template: metadata: labels: app: users spec: containers: - name: users image: <docker hubのアカウント名>/kub-demo-users |
この設定ファイルを元に、Deploymentを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# users-apiのdeploymentを作成 $ kubectl apply -f=kubernetes/users-deployment.yml deployment.apps/usersdeployment created # 状態確認 $ kubectl get pods NAME READY STATUS RESTARTS AGE usersdeployment-544844b988-qq56d 1/1 Running 0 2m24s # ログの確認 $ kubectl logs usersdeployment-544844b988-qq56d go: downloading github.com/labstack/echo v3.3.10+incompatible ... ____ __ / __/___/ / ___ / _// __/ _ \/ _ \ /___/\__/_//_/\___/ v3.3.10-dev High performance, minimalist Go web framework https://echo.labstack.com ____________________________________O/_______ O\ ⇨ http server started on [::]:8080 |
OKですね。モジュールのインストールなどしているので、Podの立ち上がりは遅めです。
Serviceの作成
クラスタ内に構築したDeploymentは、外部(私たちの環境)とは隔絶されており、リクエストを送ることができないため、穴を開ける必要があります。
そこで、Serviceを作って外部間通信を可能にします。
1 2 |
# serviceファイルの作成 touch kubernetes/users-service.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# users-service.yml apiVersion: v1 kind: Service metadata: name: users-service spec: selector: app: users # deploymentのusersを指定 type: LoadBalancer ports: - protocol: TCP port: 8080 targetPort: 8080 |
ServiceのTypeには、「LoadBalancer」を指定しました。タイプは3つあり、LoadBalancerは、次の特性を持っています。
公式サイトより
LoadBalancer
: クラウドプロバイダーのロードバランサーを使用して、Serviceを外部に公開します。クラスター外部にあるロードバランサーが転送する先のNodePort
とClusterIP
Serviceは自動的に作成されます。
これで、クラスタ内外と通信ができるはずです。
動作確認
動作確認をしましょう。
1 2 3 4 5 6 |
# users serviceの作成 $ kubectl apply -f=kubernetes/users-service.yml service/users-service created # 下記のコマンドで、users-serviceをstart minikube service users-service |
「minikube service」で、Serviceが起動します。
筆者の環境だと起動後に「http://192.168.99.100:30499/」のURLが割り当てられたので、次のエンドポイントにリクエストを送ってみます。
エンドポイント: http://192.168.99.100:30499/signup

現状、他のAPIが起動していないので500エラーになりますが、ローカルからリクエストが送れることは確認できたと思います。
Pod内に複数のコンテナを起動させる
先ほど作成したusers-apiのPodにauth-apiを追加します。一つのPod上で2つのコンテナが動くイメージですね。
事前準備
auth-apiをビルドして、Docker Hubにpushしておきます。
1 2 3 4 5 6 7 8 |
# auth-apiフォルダへ移動 cd auth-api/ # ビルド docker build -t <docker hubのアカウント名>/kub-demo-auth . # Docker HubへPush docker push <docker hubのアカウント名>/kub-demo-auth |
Deploymentの修正
続いて、users-deployment.ymlファイルを修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# users-deployment.yml apiVersion: apps/v1 ... spec: replicas: 1 selector: ... containers: - name: users image: <docker hubのアカウント名>/kub-demo-users:latest # latestタグ追加 env: - name: AUTH_SERVICE_SERVICE_HOST # 環境変数を設定 value: localhost # auth pod追加 - name: auth image: <docker hubのアカウント名>/kub-demo-auth:latest |
deployment.ymlのcontainersにauth podの設定を追加しました。これだけで同じPod上で複数のコンテナを動作させることができます。
また、AUTH_SERVICE_SERVICE_HOST(環境変数)を設定しました。同一のPod上で動くコンテナ間通信は「localhost」で通信可能なので、このような設定にしています。
AUTH_SERVICE_SERVICE_HOSTは環境変数なので、Goで値を取得しています。
1 2 3 |
var ( authAddr = os.Getenv("AUTH_SERVICE_SERVICE_HOST") // docker-compose.ymlに設定した環境変数 ) |
動作確認
Deploymentをアップデートして、動作確認をしましょう。単純に、applyをかければOKです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# deploymentをupdate $ kubectl apply -f=kubernetes/users-deployment.yml deployment.apps/usersdeployment configured # Updateの様子 # => ContainerCreating $ kubectl get pods NAME READY STATUS RESTARTS AGE usersdeployment-544844b988-qq56d 1/1 Running 4 27h usersdeployment-75cf9f5fd5-nszn7 0/2 ContainerCreating 0 6s # => Running $ kubectl get pods NAME READY STATUS RESTARTS AGE usersdeployment-544844b988-qq56d 0/1 Terminating 4 27h usersdeployment-75cf9f5fd5-nszn7 2/2 Running 0 17s # => 以前のPod削除 $ kubectl get pods NAME READY STATUS RESTARTS AGE usersdeployment-75cf9f5fd5-nszn7 2/2 Running 0 63s |
READYが「2/2」となっているので、Podが2つ起動していることがわかります。
さて、準備は整ったので、先ほどと同じエンドポイントにリクエストを送ってみましょう。
エンドポイント: http://192.168.99.100:30499/signup

今度は無事にリクエストが送れました。
auth api
次は、auth apiの環境を構築します。
Deploymentを作成
users-apiとauth-apiのコンテナを同一のPod上で作成しましたが、やはり別々のPod上で動かした方が良さそうです。authもDeploymentを作成しましょう。
1 |
touch kubernetes/auth-deployment.yml |
auth-deployment.ymlの中身は、users-apiをほぼ同じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# auth-deployment.yml apiVersion: apps/v1 kind: Deployment metadata: name: auth-deployment spec: replicas: 1 selector: matchLabels: app: auth template: metadata: labels: app: auth spec: containers: - name: auth image: <docker hubのアカウント名>/kub-demo-auth:latest |
users-deployment.ymlからもauth-apiコンテナを削除しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# users-deployment.yml apiVersion: apps/v1 kind: Deployment metadata: name: users-deployment spec: replicas: 1 selector: matchLabels: app: users template: metadata: labels: app: users spec: containers: - name: users image: <docker hubのアカウント名>/kub-demo-users:latest # latestタグ追加 env: - name: AUTH_SERVICE_SERVICE_HOST value: localhost |
Serviceの作成
auth-apiのServiceも作成しましょう。
1 |
touch kubernetes/auth-service.yml |
これもusers-service.ymlの設定とほとんど同じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# auth-service.yml apiVersion: v1 kind: Service metadata: name: auth-service spec: selector: app: auth # deploymentのauthを指定 type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 80 |
ただし、typeに「ClusterIP」を指定しています。このサービスは、クラスター内部で通信するためのIPアドレスを自動で付与してくれるサービスです。
公式サイトより
ClusterIP
: クラスター内部のIPでServiceを公開する。このタイプではServiceはクラスター内部からのみ疎通性があります。このタイプはデフォルトのServiceType
です。
auth-apiは、唯一他のAPIからのみアクセスされるAPIなので、外部に公開する必要はありません。それ故に、ClusterIPで問題ありません。
applyしてみましょう。
1 2 3 4 5 6 7 |
# auth service/deploymentをapply kubectl apply -f=kubernetes/auth-service.yml -f=kubernetes/auth-deployment.yml # Service確認 $ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE auth-service ClusterIP 10.101.21.185 <none> 80/TCP 31s |
サービスを確認すると「10.101.21.185」のIPアドレスが振り分けられていることがわかります。
このIPアドレスを、users-deployment.ymlに設定していた「localhost」と入れ替えます。
1 2 3 4 5 |
# users-deployment.yml env: - name: AUTH_SERVICE_SERVICE_HOST # 環境変数を設定 value: "10.101.21.185" <<< localhostからIPアドレスに変更 |
これで、同一クラスタ内のPod間通信が可能なはずです。
users-apiのDeploymentを更新します。
1 2 3 4 5 6 7 8 9 |
# 更新 $ kubectl apply -f=kubernetes/users-deployment.yml deployment.apps/users-deployment created $ kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE auth-deployment 1/1 1 1 5m1s users-deployment 1/1 1 1 81s usersdeployment 1/1 1 1 45h |
Deploymentが作成されていることがわかりますね。usersdeployment(名前間違えた)は、前回起動したDeploymentです。
これはもういらないので、下記のコマンドで削除しておきます。
1 2 |
$ kubectl delete deployment usersdeployment deployment.apps "usersdeployment" deleted |
ClusterIPの不便な点
実は、ClusterIPには一つ不便な点があります。auth-apiのServiceを下記のコマンドで再作成してください。
1 2 3 4 5 6 7 8 9 10 11 12 |
# Service削除 $ kubectl delete -f=kubernetes/auth-service.yml service "auth-service" deleted # Service作成 $ kubectl apply -f=kubernetes/auth-service.yml service/auth-service created # Service情報取得 $ kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE auth-service ClusterIP 10.110.246.90 <none> 80/TCP 5s |
今度は、「10.110.246.90」のIPアドレスが割り当てられました。ClusterIPサービスは、サービスが再作成されるたびに新しいIPアドレスを割り当てます。
これは、超不便です。ここの例で言うとusers-deployment.ymlに設定したIPアドレスを手作業で書き換えないといけません。
IPアドレスを動的に割り当てる
実は、回避策があります。
kubernetesでは、ClusterIPのIPアドレスを変数で取得できます。命名ルールがちょっと難しいですが、このサンプルの例では以下のように指定すると取得できます。
1 2 |
# 命名ルール -> {SVCNAME}_SERVICE_HOST AUTH_SERVICE_SERVICE_HOST |
AUTH_SERVICEは、auth-service.ymlに設定したmetadataのnameです。詳しくは、「ここ」を参照してください。
既にGoコード(users-api/main.go)には、「authAddr = os.Getenv(“AUTH_SERVICE_SERVICE_HOST”)」の設定がされているのでDeploymentを作成し直す必要はありません。
しかし、今回のようにdeployment.ymlを変更せず、ソースファイル(Go言語)のみ変更した場合は、普通にapplyしても変更内容を読み込んでくれないので、一旦deploymentを削除し、再び作成する必要があります。
1 2 3 4 5 |
# Deploymentを削除 $ kubectl delete -f=kubernetes/users-deployment.yml # Deploymentを作成 $ kubectl create -f=kubernetes/users-deployment.yml |
動作確認
先ほどのエンドポイントにリクエストを送り、通信ができるか確認してみましょう。
エンドポイント: http://192.168.99.100:30499/signup

OKですね。
DNSを導入
DNS(Domain Name System)を使って、Pod間通信が可能か確認したいと思います。
kubernetesのDNSについて
kubernetesのDNSは、「service name + . + ネームスペース」で取得できるようです。※自動的に作成してくれる
namespaceは、クラスター内部の環境を仮想的に分割する役割を持っており、デフォルトでは、「default」のnamespaceでDeploymentやServiceが起動します。
1 2 3 4 5 6 7 |
# namespaceの取得 $ kubectl get namespace NAME STATUS AGE default Active 45d <<<<<<<< デフォルトでは、ここで動く kube-node-lease Active 45d kube-public Active 45d kube-system Active 45d |
users-deployment.ymlに設定したIPアドレスをDNSに書き換えてみましょう。
1 2 3 4 5 |
# users-deployment.yml ... env: - name: AUTH_ADDRESS # AUTH_SERVICE_SERVICE_HOST -> AUTH_ADDRESSに変更 value: "auth-service.default" # service name + . + ネームスペース |
これで、DNSが使えるようです。
DeploymentをUpdateします。
1 2 |
$ kubectl apply -f=kubernetes/users-deployment.yml deployment.apps/users-deployment configured |
DNSが有効か確認する手順(やらなくて良い)
DNSを導入したので、一応確認する手段を書いておきます。
Goコード(users-api/main.go)の中で、「authAddr = os.Getenv(“AUTH_SERVICE_SERVICE_HOST”)」のAUTH_SERVICE_SERVICE_HOSTをAUTH_ADDRESSに書き換えてください。
続いて、次のコマンドを入力してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# users-apiフォルダへ移動 cd users-api/ # ビルド docker build -t <docker hubのアカウント名>/kub-demo-users . # Docker HubへPush docker push <docker hubのアカウント名>/kub-demo-users # rootに戻る cd .. # Deploymentを削除 kubectl delete -f=kubernetes/users-deployment.yml # Deploymentを作成 kubectl create -f=kubernetes/users-deployment.yml |
ここまで完了したら、以下のエンドポイントにリクエストを送ってみましょう。
エンドポイント: http://192.168.99.100:30499/signup

OKですね。kubernetes Serviceが自動的に作る環境変数とDNS、どちらも使えそうですね。
tasks api
tasks-apiの環境も整えていきましょう。
Docker HubへPush
tasks-apiのビルドイメージもDocker HubへPushしておきます。
1 2 3 4 5 6 7 8 |
# tasks-apiフォルダへ移動 cd tasks-api/ # ビルド docker build -t <docker hubのアカウント名>/kub-demo-tasks . # Docker HubへPush docker push <docker hubのアカウント名>/kub-demo-tasks |
Deploymentの作成
tasks-apiのDeploymentを作成しましょう。
1 |
touch kubernetes/tasks-deployment.yml |
users-apiのDeploymentを参考に、Deploymentの設定を行いましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# tasks-deployment.yml apiVersion: apps/v1 kind: Deployment metadata: name: tasks-deployment spec: replicas: 1 selector: matchLabels: app: tasks template: metadata: labels: app: tasks spec: containers: - name: tasks image: <docker hubのアカウント名>/kub-demo-tasks:latest env: - name: AUTH_ADDRESS value: "auth-service.default" - name: TASKS_FOLDER # tasksフォルダへのパス value: "./tasks/tasks.txt" |
Serviceの作成
tasks-apiのServiceも作成します。
1 |
touch kubernetes/tasks-service.yml |
こちらもusers-apiのServiceを参考に、設定をしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# tasks-service.yml apiVersion: v1 kind: Service metadata: name: tasks-service spec: selector: app: tasks # deploymentのtasksを指定 type: LoadBalancer ports: - protocol: TCP port: 8000 targetPort: 8000 |
動作確認
次のコマンドで、動作確認を行いましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# ServiceとDeploymentを作成 $ kubectl apply -f=kubernetes/tasks-service.yml -f=kubernetes/tasks-deployment.yml service/tasks-service created deployment.apps/tasks-deployment created # Deploymentの確認 $ kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE auth-deployment 1/1 1 1 25h tasks-deployment 1/1 1 1 40s users-deployment 1/1 1 1 18h $ kubectl get pods NAME READY STATUS RESTARTS AGE auth-deployment-6bf7ccbc-lltgk 1/1 Running 4 25h tasks-deployment-78c79484b7-7g49p 1/1 Running 0 33s users-deployment-6596ffc5-4dxdm 1/1 Running 2 18h # tasks-api service起動 $ minikube service tasks-service |-----------|---------------|-------------|-----------------------------| | NAMESPACE | NAME | TARGET PORT | URL | |-----------|---------------|-------------|-----------------------------| | default | tasks-service | 8000 | http://192.168.99.100:32287 | |-----------|---------------|-------------|-----------------------------| 🎉 Opening service default/tasks-service in default browser... |
「http://192.168.99.100:32287」のURLで、tasks-apiが起動しました。
これにより、以下のエンドポイントに向けて、リクエストが送れるようになりました。
エンドポイント: http://192.168.99.100:32287/tasks

OKですね。
注意点としては、Headerに「Authorization」と「Bearer abc」を設定する必要があります。
次回
次回は、フロントエンド(React)を導入してみましょう。
コメントを残す
コメントを投稿するにはログインしてください。