クラウドで話題のコンテナ技術「Kubernetes」を使ってみた!

2020年3月27日掲載

目次

こんにちは!

ホワイトクラウド ASPIRE(以下ASPIRE)で、Kubernetesのテンプレートが公開されましたので、早速使ってみました。今回はそのレポートをお届けします。

コンテナ、Kubernetesとは

コンテナは、アプリケーションとそのアプリケーションを実行するために必要なライブラリをまとめてパッケージ化し、アプリケーションの独立した環境を提供する技術です。
パッケージにすることでアプリケーションの可搬性が高まり、新規開発はもとより、既存環境へのデプロイや運用時のメンテナンス操作が柔軟になります。
そのような特性から、いわゆる「DevOps」との親和性が非常に高い技術です。

従来物理環境、仮想マシン環境、コンテナ環境との違いは下図の通りです。

非常にメリットの多いコンテナですが、複数作成していくと管理が非常に複雑になるという問題があります。
それらを統合管理して、より簡単に扱うためのツールとして使われるのがKubernetesです。

Kubernetesをデプロイすると、クラスタが構築されます。
クラスタは、マスターノードとワーカーノードの2種類で構成されています。
ワーカーノードはコンテナの実行環境を提供します。
マスターノードはワーカーノードとコンテナを管理します。
1つのマスターノードと1つのワーカーノードがクラスタの最小構成です。

評価環境の構成

今回試した環境は下図の通り、マスターノードVM1台、ワーカーノードVM2台のでクラスタを構成します。
クラスタはkubernetesのkubeadmコマンドを使って自動構築します。そのため、マスターノードとワーカーノードから、インターネットにアクセスできる環境が必要です。

役割VM名IPアドレスDocker
Version
Kubernetes
Version
マスターノードmaster192.168.1.10319.031.17
ワーカーノード#1worker01
192.168.1.104
19.031.17
ワーカーノード#2worker02192.168.1.10519.031.17

Kubernetesクラスタの構築

ASPIRE上でKubernetesクラスタを構築するステップは以下の通りです。

  1. 仮想マシングループを作成します。
  2. 仮想マシングループにマスターノードとワーカーノードをデプロイします。
  3. クラスタを初期化します。
  4. クラスタにネットワークアドオンをインストールします。
  5. ワーカーノードをクラスタに追加します。


では、クラスタを構築しましょう!

1) 仮想マシングループを作成します。

ASPIREセルフポータルにログインし、テナント内に仮想マシングループを作成、インターネットに接続しているテナントネットワークを仮想マシングループに追加します。
 

2) 仮想マシングループにマスターノードとワーカーノードをデプロイします。

a)マスターノードのデプロイ

テンプレート「NonSupport Kubernetes」([カタログ] > [テンプレート]から確認可能です。)を利用してマスターノードをデプロイし、仮想マシングループネットワークに接続して、ゲストOSのカスタマイズを行います。

ASPIREのテナントにテンプレートからデプロイする方法は「ホワイトクラウド ASPIRE サービスご利用ガイド」-「限定公開カタログから仮想マシンを作成する(Red Hat Enterprise Linux)」をご参照ください。

b) ワーカーノード#1のデプロイ
テンプレート[NonSupport Kubernetes]を利用してワーカーノード#1をデプロイし、仮想マシングループネットワークに接続して、ゲストOSのカスタマイズを行います。

c) ワーカーノード#2のデプロイ
テンプレート[NonSupport Kubernetes]を利用してワーカーノード#2をデプロイし、仮想マシングループネットワークに接続して、ゲストOSのカスタマイズを行います。

 

3) クラスタを初期化します。

マスターノードにログイン、下記のコマンドを実行し、クラスタを初期化します。

# kubeadm init --pod-network-cidr=10.244.0.0/16 --token-ttl 0 | tee kubeadm-init.log

“Your Kubernetes control-plane has initialized successfully !” というメッセージが出ればコマンドが正常に終了しました。

続いて、クラスタを管理するための事前準備を行います。

# tail -2 kubeadm-init.log | sed '1s/^/\#\!\/bin\/sh\n/' > kubeadm-join.sh
# mkdir -p $HOME/.kube
# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# chown $(id -u):$(id -g) $HOME/.kube/config


4) クラスタにネットワークアドオンをインストールします。

# kubectl apply -f \ 
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

ステータスが”Ready”になっていれば、マスターノードは正常にクラスタに参加できています。
 

5) ワーカーノードをクラスタに追加します。

ワーカーノード#1にログインし、下記のコマンドでクラスタに参加させます。

# scp root@192.168.1.103:/root/kubeadm-join.sh ./
# sh -x kubeadmin-join.sh
# ssh root@192.168.1.103 “kubectl get nodes”

ステータスが”Ready”になっていれば、ワーカーノードは正常にクラスタに参加できています。

6) ワーカーノード#2をクラスタに追加します。

ワーカーノード#2にログインし、下記のコマンドでクラスタに参加させます。

# scp root@192.168.1.103:/root/kubeadm-join.sh ./
# sh -x kubeadmin-join.sh
# ssh root@192.168.1.103 “kubectl get nodes”

同じく、ステータスが”Ready”で登録されていることを確認します。

Podの作成

PodとはKubernetesでデプロイする最小単位です。
KubernetesはPod単位で作成、開始、停止、削除といった操作を行います。Podを作成する基本ルールとして1Podの中に1コンテナで構成します。1Podには複数のコンテナで構成することも可能です。
Podの作成は、マニフェストファイル(設定ファイル)を作成し、適用することで自動的に行われます。そのため、マニフェストファイルを管理することが、Podの構成管理ということになります。

それでは、マニフェストファイルを使ってPodを作成してみましょう!
 

1) マスターノードにて、マニフェストファイルを作成します。

# vi sample_pod.ym

--------------------------------------------
apiVersion: v1
kind: Pod
metadata:
  name: nginx #Podの名前
spec:
  containers:
  - name: nginx
    image: nginx:latest #nginxのバージョン
    ports:
    - containerPort: 80 #Podのポート番号指定
--------------------------------------------


2) 作成したマニフェストを読み込みます。

構文に問題がなければ、Podが生成・起動します。

# kubectl create -f sample_pod.yaml

生成したPodのステータスが”Running”になっていることを確認します。

# kubectl get pods

生成したPodのステータスが”Running”になっていることを確認します。

# kubectl describe pods/nginx
  • Node:Podが稼働しているノード
  • IP:Podに割り当てされたIPアドレス


3) 上述で確認したPodのIPアドレスで動作を確認します。

Pod(nginx)からデフォルトのコンテンツが返ってくれば問題ありません。

# curl http://10.244.1.2

ReplicaSetとDeploymentの作成

Kubernetesでは、複数のPodを保持し冗長構成を実現するため、ReplicaSetという機能を持っています。例えば、Podのレプリカを3つ設定すると、ReplicaSetが3つのPodを起動します。
さらに、KubernetesにはReplicaSetを管理するためのDeploymentという機能もあります。
ReplicaSetは直接利用もできますが、Deploymentから利用するのが一般的です。

それでは、ここからReplicaSetとDeploymentを作成してみましょう!!
 

1) マスターノードにて、Deploymentのマニフェストを作成します。

# vi sample_deployment.yaml

-------------------------------------------------------
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-nginx-deployment #Deploymentの名前
  labels:
    app: nginx
spec:
  replicas: 3 #3つのレプリカPodを作成する
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx #Podに付けたラベル
    spec:
      containers:
      - name: nginx #Podの名前
        image: nginx:latest
        ports:
        - containerPort: 80
-------------------------------------------------------


2) 作成したDeploymentを適用します。

# kubectl apply -f sample_deployment.yaml
# kubectl get deployment
  • NAME:クラスタ内のdeploymentの名前
  • UP-TO-DATE:アップデートが完了したレプリカ数
  • AVAILABLE:ユーザが利用可能なレプリカ数
  • AGE:アプリケーションが稼働してからの時間


3) デプロイされたPodの数を確認します。

# kubectl get pods


4) DeploymentでReplicaSetの数を3つに指定しているので、もし何かの理由でPodがダウンしても、自動的にPodが再生成されます。

ここで手動でPod(sample-nginx-deployment-59c9f8dff-8t77)を削除してみます。
新たなPodが生成・起動することを確認します。

# kubectl delete pod sample-nginx-deployment-59c9f8dff-8t77
# kubectl get pods

Pod(sample-nginx-deployment-59c9f8dff-8t77)を削除した結果、
新しいPod(sample-nginx-deployment-59c9f8dff-rrdkk)が作成されていることが確認できました。

Serviceの作成

ServiceはPodで実行されているアプリケーションをネットワークサービスとして公開する機能です。
Kubernetesでは、可用性を高めるために同じPodを複数構成にすることが一般的な使われ方です。
DeploymentでPodをデプロイすると、指定した数のPodが動的に作成・削除されます。
その時、PodにアサインされるIPアドレスも動的に変わってしまいます。そのため、固定されたIPアドレスでサービスを公開することができません。
Serviceを利用することで、その問題を解決することができます。

Serviceには以下4つのタイプがあります。

  • ClusterIP: クラスタ内部のIPでServiceを公開します。このタイプはデフォルトのタイプです。

  • NodePort: 各ノードのIPにて、静的なポート上でServiceを公開します。
    <NodeIP>:<NodePort>にアクセスすることによってNodePort Serviceにアクセスできます。
    デフォルトポート番号:30000-32767

  • LoadBalancer: クラウドプロバイダーのロードバランサを使用して、Serviceを外部に公開します。

  • ExternalName: CNAMEレコードを返すことにより、externalNameフィールドに指定したコンテンツとServiceを紐づけます。

今回はNodePortタイプでサービスを公開してみます。
 

1) Serviceのマニフェストファイルを作成します。

# vi sample_service_NodePort.yaml
-------------------------------------------------------
apiVersion: v1
kind: Service
metadata:
  name: sample-service-np
spec:
  selector:
    app: nginx #上述でDeploymentで作成したPodのラベルを指定
  ports:
  - port: 80 #Podのポート番号
  type: NodePort #NodePortタイプを指定
-------------------------------------------------------
# kubectl apply -f sample_service_NodePort.yaml
# kubectl get svc


2) デプロイしたServiceの詳細を確認します。

NodePort:各ノードにポート31926が応答するようになる
 

3) ワーカーノード#1にアクセスし、応答があることを確認します。

# curl http://192.168.1.104:31926


4) ワーカーノード#2にアクセスし、応答があることを確認します。

# curl http://192.168.1.105:31926


5) 外部ネットワークにワーカーノードのIPアドレスを公開してみます。

ASPIREで提供するグローバルIPアドレスを利用して、作成したServiceを公開します。

<重要>外部ネットワークにServiceを公開するのはセキュリティリスクを伴いますので、適切なファイアウォールルールを設定するようにお願いいたします。
 

1) Edgeゲートウェイにワーカーノード#1のIPアドレスとグローバルIPのDNAT設定を入れます。

EdgeゲートウェイのDNATの設定とファイアウォールの設定は「ホワイトクラウド ASPIRE サービスご利用ガイド」-「NAPTの受信用アドレス(DNAT)を設定する」「ファイアウォールを設定する」をご参照ください。
 

2)インターネットより以下のURLにアクセスし、応答があることを確認します。

URL: http://<グローバルIPアドレス>:31926

無事にnginxの画面を見ることができました。

今回は、ASPIRE上に公開されているKubernetesテンプレートを使って、簡単なコンテナサービスを作ってみました。Kubernetesに興味があり、短時間で簡単にKubernetes環境を用意したい!というお客様は、ぜひ本テンプレートをご利用いただければと思います。

関連サービス

ホワイトクラウド ASPIRE

IaaS市場において最高クラスの信頼性と柔軟性の高いネットワーク構成が可能なソフトバンクのパブリッククラウドサービスです。

おすすめの記事

条件に該当するページがございません