こんにちは。KOUKIです。k8s学習中のWebエンジニアです。
KubernetesでMicroservicesのデプロイ方法を学びましょう。
本記事では、PodとServiceの立ち上げ方法を解説します。
尚、今回もMinikubeを使いますので、以下の記事でインストール&起動してください。
※ MacおよびChromeで検証します。
参考
Udemyの「Kubernetes Hands-On – Deploy Microservices to the AWS Cloud」コースを参考にしています。
解釈は私が勝手に付けているので、本物をみたい場合は受講してみてください。
Docker Hubはこちらです。richardchesterwood/k8s-fleetman-webapp-angular
API OVERVIEWも参考になります。
Podとは
Podは、Kubernetesアプリケーションの基本的な実行単位です。クラスターで実行されているプロセスを表します。
このPodの中には単一もしくは複数のDockerコンテナが動いていて、Podはそれらを包むカプセルのような働きをします。
開発の規模が大きくなってくると、このPodの数が増えていくことになるの為、管理が必要になります。
それを担うのがKubernetesの各マネージドサービスというわけです。

Podの作成
Pod v1 coreを参考に、Podを作成してみましょう。
1 2 |
# ファイルを用意する touch first-pod.yml |
1 2 3 4 5 6 7 8 |
apiVersion: v1 kind: Pod # 種別はPodを指定 metadata: name: webapp # podの名前 spec: # 管理するコンテナを記述する(複数書ける) containers: - name: webapp # コンテナ名 image: richardchesterwood/k8s-fleetman-webapp-angular:release0 # コンテナのイメージ名 |
これがPodを起動する最小単位です。Podの中に単一なコンテナが一つ起動するイメージです。
Podの起動
下記のコマンドでPodを起動します。
1 2 |
# 起動 kubectl apply -f first-pod.yml |
起動確認コマンドは以下です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ kubectl get all NAME READY STATUS RESTARTS AGE pod/webapp 1/1 Running 1 22h # podがwebapp名で起動 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23h # コンテナ名の確認 $ kubectl describe pods webapp ... Containers: webapp: # コンテナ名 Container ID: docker://cd66f8c6f4d0850991b917941235ce3d3ae423bd438681d8f2d71494713e528c Image: richardchesterwood/k8s-fleetman-webapp-angular:release0 ... |
Podの削除
下記のコマンドで、Podを削除します。
1 2 3 4 5 6 |
# 削除 kubectl delete -f first-pod.yml $ kubectl get all NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23h |
簡単ですね。
Pod内でコンテナを複数起動する
次に、Pod内でコンテナを複数起動してみましょう。
1 2 3 4 5 6 7 8 9 10 |
apiVersion: v1 kind: Pod # 種別はPodを指定 metadata: name: app # podの名前 spec: # 管理するコンテナを記述する(複数書ける) containers: - name: webapp # コンテナ名 image: richardchesterwood/k8s-fleetman-webapp-angular:release0 # コンテナのイメージ名 - name: webapp2 image: richardchesterwood/k8s-fleetman-webapp-angular:release0 |
containersにもう一つコンテナを追加しました。また、metadataのnameをappにしています。
webappのままだと複数コンテナ時にはエラーが発生するようです。
1 |
error: a container name must be specified for pod webapp, choose one of: [webapp webapp2] |
applyします。
1 2 3 4 5 6 |
kubectl apply -f first-pod.yml $ kubectl get pods NAME READY STATUS RESTARTS AGE app 2/2 Running 0 6s |
しかし、現在は複数のコンテナを起動する必要はないので設定は戻しておきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# podを削除して kubectl delete -f first-pod.yml # 設定を戻して # applyし直す kubectl apply -f first-pod.yml $ kubectl get all NAME READY STATUS RESTARTS AGE pod/webapp 1/1 Running 0 46s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 46hv |
通信確認
下記のコマンドでminikubeのipアドレスを取得してください。
1 2 |
$ minikube ip 192.168.99.102 |
これをブラウザに打ち込んでみます。

Podにアクセスできませんね。
実は、ローカルPCとMinikubeの間には防波堤のようなものがあって、今のままだと通信ができません。

ただし、Pod内に入ることはできます。
1 2 3 |
$ kubectl exec -it webapp sh / # ls bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var |
Podの中からだとhttp://localhost:80にアクセスできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# index.htmlを取得 / # wget http://localhost:80 Connecting to localhost:80 (127.0.0.1:80) index.html 100% |**********************************************************************************************| 585 0:00:00 ETA # 中身を表示 / # cat index.html <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Fleet Management</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.png"> </head> <body> <app-root></app-root> <script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body> </html> |
Podから抜けるには、「exit」コマンドを叩いてください。
Service
ブラウザからPod内のアプリケーションにアクセスすることはできない一方、Pod内からはアクセス可能であることはわかりました。
それでは、どうやってブラウザからアクセスすれば良いのでしょうか?
その答えは、KubernetesのServiceにあります。これは、Podの集合で実行されているアプリケーションをネットワークサービスとして公開する一般的な方法です。

Serviceの作成
公式リファレンスを参考に、Serviceを作成しましょう。
1 |
touch webapp-service.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# webapp-service.yml kind: Service apiVersion: v1 metadata: name: fleetman-webapp spec: ports: - name: http port: 80 # Minikubeと接続するPort targetPort: 80 # Podコンテナと接続するPort # どのpodがこのサービスに定義されるのか紐付ける # Serviceはネットワークのエンドポイントになる(他のServiceに対しても) # 或いは、ブラウザとのコネクトの架け橋になる selector: app: webapp # podのwebappを指定 # typeにはClusterIP, NodePort, LoadBalancerの3つがある type: NodePort |
Serviceの公開タイプには、以下の3つがあります。(公式参照)
ClusterIP
: クラスター内部のIPでServiceを公開する。このタイプではServiceはクラスター内部からのみ疎通性があります。このタイプはデフォルトのServiceType
です。NodePort
: 各NodeのIPにて、静的なポート(NodePort
)上でServiceを公開します。そのNodePort
のServiceが転送する先のClusterIP
Serviceが自動的に作成されます。<NodeIP>:<NodePort>
にアクセスすることによってNodePort
Serviceにアクセスできるようになります。LoadBalancer
: クラウドプロバイダーのロードバランサーを使用して、Serviceを外部に公開します。クラスター外部にあるロードバランサーが転送する先のNodePort
とClusterIP
Serviceは自動的に作成されます。
ここでは、NodePortを指定しました。
下記のコマンドで、Serviceを作成します。
1 2 3 4 5 6 7 8 9 10 |
$ kubectl apply -f webapp-service.yml service/fleetman-webapp created $ kubectl get all NAME READY STATUS RESTARTS AGE pod/webapp 1/1 Running 0 109s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/fleetman-webapp NodePort 10.107.115.27 <none> 80:30665/TCP 9s service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47h |
以下のコマンドで、アプリケーションを起動することができます。
1 2 3 4 5 6 7 |
$ minikube service fleetman-webapp |-----------|-----------------|-------------|-----------------------------| | NAMESPACE | NAME | TARGET PORT | URL | |-----------|-----------------|-------------|-----------------------------| | default | fleetman-webapp | http/80 | http://192.168.99.102:30511 | |-----------|-----------------|-------------|-----------------------------| 🎉 Opening service default/fleetman-webapp in default browser... |

Labelの設定
ServiceとPodを紐づけるために、Pod側の設定にLabelを入れておきましょう。
この機能は後々重要になってきます。
1 2 3 4 5 6 7 8 9 10 |
apiVersion: v1 kind: Pod metadata: name: webapp labels: # Serviceのselectorに指定した「key: value」と同じものをつける app: webapp spec: containers: - name: webapp image: richardchesterwood/k8s-fleetman-webapp-angular:release0 |
applyします。
1 2 |
$ kubectl apply -f first-pod.yml pod/webapp configured |
下記のコマンドを使って、ブラウザからアプリが表示できるか確認してください。
1 |
$ minikube service fleetman-webapp |
新しいバージョンをリリースする方法
新しいDockerイメージのアプリをリリースする方法を確認しましょう。
Selectorを使えば、簡単です!
まず、新しいPodを追加します。
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 |
# first-pod.yml apiVersion: v1 kind: Pod metadata: name: webapp labels: app: webapp release: "0" # 新しくLabelをつける spec: containers: - name: webapp image: richardchesterwood/k8s-fleetman-webapp-angular:release0 # --- で区切ることで、新たにPodやDeployment、Serviceの記述ができる --- apiVersion: v1 kind: Pod metadata: name: webapp-release-0-5 labels: app: webapp release: "0-5" spec: containers: - name: webapp image: richardchesterwood/k8s-fleetman-webapp-angular:release0-5 |
コメントにも書きましたが、「—」で区切ることで複数記述できます。
また、ここではLabelsが重要です。新しく「release」ラベルを追加しました。
このラベルをService側で指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# webapp-service.yml kind: Service apiVersion: v1 metadata: name: fleetman-webapp spec: ports: - name: http port: 80 targetPort: 80 selector: app: webapp release: "0-5" # 新しいversionのpodのラベルを指定 type: NodePort |
以下のコマンドで、PodとServiceを更新してください。
1 2 3 4 5 6 7 8 9 10 11 |
kubectl apply -f first-pod.yml kubectl apply -f webapp-service.yml $ kubectl get all NAME READY STATUS RESTARTS AGE pod/webapp 1/1 Running 0 29m pod/webapp-release-0-5 1/1 Running 0 14m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/fleetman-webapp NodePort 10.102.14.32 <none> 80:32019/TCP 7m29s service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d23h |
以下のコマンドで、アプリケーションを立ち上げてください。
1 |
minikube service fleetman-webapp |

これだけで新しいバージョンのアプリを起動できます。すごく便利ですよね^^
切り戻しも簡単です。
1 2 3 4 5 6 7 8 |
# webapp-service.yml kind: Service ... selector: app: webapp release: "0" # <<< 切り戻すアプリケーションのラベル type: NodePort |
1 2 |
# Serviceを更新 kubectl apply -f webapp-service.yml |
ブラウザにはキャッシュが残っているので、スーパーリロードでキャッシュクリアをすると切り戻したバージョンのアプリケーションが確認できます。※Macの場合は「command + r」でスーパーリロードができます

PodにLabelを付けてServiceのSelectorでそれを指定する、そういった流れですね。
ラベルを確認したいときは、下記のコマンドが便利です。
1 2 3 4 5 6 7 8 |
$ kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS webapp 1/1 Running 0 30m app=webapp,release=0 webapp-release-0-5 1/1 Running 0 15m app=webapp,release=0-5 $ kubectl get pod --show-labels -l release=0-5 NAME READY STATUS RESTARTS AGE LABELS webapp-release-0-5 1/1 Running 0 16m app=webapp,release=0-5 |
次回
次回は、ActiveMQのPodとServiceを構築しましょう。
コメントを残す
コメントを投稿するにはログインしてください。