オンプレミスのKubenetesクラスタで、公式ドキュメントのExposing an External IP Address to Access an Application in a Clusterを実行した場合、パブリック・クラウドのKubernetesサービスのように、クラウドのロードバランサーと連動できませんから、どのように動作を確認できるのか見ていきます。
ここで、オンプレミス環境として、著書の15Stepで習得 Dockerから入るKubernetes コンテナ開発からK8s本番運用までの学習環境2を使用します。この記事は読者サービスみたいですね(笑)
K8sクラスタ 1.17の環境設定
K8sクラスタを構築する為に、必要なファイル一式をGitHubからクローンします。前提となるソフトウェアの導入については、本書の付録、またはGitHubのREADME.mdを参照ください。
ここでは、Kubernetesの最新バージョンで動作を試してみます。 -b 1.17
を省略すると本書と同じバージョンがクローンされます。
tkr@luigi:~$ git clone -b 1.17 https://github.com/takara9/vagrant-kubernetes k8s-1.17
Cloning into 'k8s-1.17'...
remote: Enumerating objects: 370, done.
remote: Total 370 (delta 0), reused 0 (delta 0), pack-reused 370
Receiving objects: 100% (370/370), 54.34 KiB | 335.00 KiB/s, done.
Resolving deltas: 100% (229/229), done.
今回では、この作業はオプションで、実施する必要はありませんが、より大きなアプケーションを実行する際に、必要となる場合があります。
クラスタ環境の設定ファイルを変更して、メモリとCPUコア数を変更します。
tkr@luigi:~$ cd k8s-1.17
tkr@luigi:~/k8s-1.17$ vi Vagrantfile
変更箇所は、以下のvbox.cpusのコア数, vbox.memoryのメモリ容量(MB)部分です。メモリやCPUの少ないパソコン環境でも動作するように小さく設定してありますから、大きくしておくと、メモリ不足で動作不良を起こしたり、待ち時間を短くできます。
14 machine.vm.provider "virtualbox" do |vbox|
15 vbox.gui = false
16 vbox.cpus = 2
17 vbox.memory = 4096
18 end
<中略>
42 machine.vm.provider "virtualbox" do |vbox|
43 vbox.gui = false
44 vbox.cpus = 2
45 vbox.memory = 4096
<中略>
71 machine.vm.provider "virtualbox" do |vbox|
72 vbox.gui = false
73 vbox.cpus = 2
74 vbox.memory = 2048
75 end
K8sクラスタの起動
vagrant up
を実行することで、パソコン上(Windows10,macOS,LinuxいずれもOK)で、仮想サーバーを3台起動して、k8sクラスタを構築します。
tkr@luigi:~/k8s-1.17$ vagrant up
Bringing machine 'node1' up with 'virtualbox' provider...
Bringing machine 'node2' up with 'virtualbox' provider...
Bringing machine 'master' up with 'virtualbox' provider...
==> node1: Importing base box 'ubuntu/xenial64'...
<中略>
PLAY RECAP *********************************************************************
node1 : ok=7 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
node2 : ok=7 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
ネットワーク環境とパソコンの性能に依存するので、一概に起動時間を言えませんが、10〜20分で起動すると思います。
起動が完了したら、`vagrant ssh master`で、マスターノードにログインして、クラスタの起動状態を確認します。この時にユーザーとパスワードは必要ありません。
tkr@luigi:~/k8s-1.17$ vagrant ssh master
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-170-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
10 packages can be updated.
10 updates are security updates.
New release '18.04.3 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
既にkubectlコマンドが利用できる状態になっているので、ノードのステータスを確認します。全てReadyになっていれば、準備完了です。
vagrant@master:~$ kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready master 2m41s v1.17.0
node1 Ready <none> 2m5s v1.17.0
node2 Ready <none> 2m5s v1.17.0
ついでに、クラスタの情報も確認しておきます。
vagrant@master:~$ kubectl cluster-info
Kubernetes master is running at https://172.16.20.11:6443
KubeDNS is running at https://172.16.20.11:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://172.16.20.11:6443/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
チュートリアル の作業開始
Exposing an External IP Address to Access an Application in a Clusterの記載通りに、以下を実行します。
vagrant@master:~$ kubectl apply -f https://k8s.io/examples/service/load-balancer-example.yaml
deployment.apps/hello-world created
これで、ポッド、すなわち、コンテナのデプロイが始まります。 AVAILABLEの列が0なのは、コンテナが起動していないことを意味しています。
vagrant@master:~$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
hello-world 0/5 5 0 38s
詳細表示は、以下のようになりますが、細かくて解りにくいですよね。
vagrant@master:~$ kubectl describe deployment hello-world
Name: hello-world
Namespace: default
CreationTimestamp: Sat, 11 Jan 2020 01:45:40 +0000
Labels: app.kubernetes.io/name=load-balancer-example
Annotations: deployment.kubernetes.io/revision: 1
kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app.kubernetes.io/name":"load-balancer-example"},"name...
Selector: app.kubernetes.io/name=load-balancer-example
Replicas: 5 desired | 5 updated | 5 total | 0 available | 5 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app.kubernetes.io/name=load-balancer-example
Containers:
hello-world:
Image: gcr.io/google-samples/node-hello:1.0
Port: 8080/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
Progressing True ReplicaSetUpdated
OldReplicaSets: <none>
NewReplicaSet: hello-world-f9b447754 (5/5 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 57s deployment-controller Scaled up replica set hello-world-f9b447754 to 5
そこで、チュートリアルには書かれていませんが、ポッドの状態をリストしてみます。STATUSをみると、コンテナが作成中のポッドがある事がわかります。
vagrant@master:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-f9b447754-6pc2x 0/1 ContainerCreating 0 72s
hello-world-f9b447754-f7mmg 1/1 Running 0 72s
hello-world-f9b447754-jnl5d 1/1 Running 0 72s
hello-world-f9b447754-mndx9 0/1 ContainerCreating 0 72s
hello-world-f9b447754-n7h7k 0/1 ContainerCreating 0 72s
以下のように、STATUSが Runningになれば、アプリケーションの起動完了です。
vagrant@master:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-f9b447754-6pc2x 1/1 Running 0 2m38s
hello-world-f9b447754-f7mmg 1/1 Running 0 2m38s
hello-world-f9b447754-jnl5d 1/1 Running 0 2m38s
hello-world-f9b447754-mndx9 1/1 Running 0 2m38s
hello-world-f9b447754-n7h7k 1/1 Running 0 2m38s
これをデプロイメント・コントローラーで確認します。 AVAILABLE=5となって、ポッド数と同じになっています。
vagrant@master:~$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
hello-world 5/5 5 5 2m51s
普段意識することはありませんが、デプロイメント・コントローラーの下で動作するレプリカセットで確認します。
vagrant@master:~$ kubectl get replicasets
NAME DESIRED CURRENT READY AGE
hello-world-f9b447754 5 5 5 3m22s
アプリケーションの外部公開
ここからが、パブリック・クラウドと、パソコン上で動かすオンプレミスの違いになってきます。
チュートリアルどおり、以下のコマンドを実行します。パブリック・クラウドであれば、クラウドのロードバランサーや、外部IPアドレスの取得と連動して、インターネットから参照できるようになります。
vagrant@master:~$ kubectl expose deployment hello-world --type=LoadBalancer --name=my-service
service/my-service exposed
以下にサービス my-service の状態を表示したものです。 EXTERNAL-IPの列が pending となっていて、外部アドレスが取れないことを意味しています。つまり、クラウド環境ではないオンプレミス環境なので、公開用IPアドレスを獲得するなどの機能が無いためです。
でも、ガッカリすることはありません。ちゃんと、環境に応じた確認が実施できます。
vagrant@master:~$ kubectl get services my-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service LoadBalancer 10.32.0.155 <pending> 8080:30852/TCP 23s
現在、ここでは、マスターノードからアクセスしているので、CLUSTER-IPを使って、アプリケーションにアクセスできます。アクセス方法は以下の通りです。
curl http://CLUSTER-IP:PORT/です。 ポード番号は、先頭がクラスタ内部のポート、コロンの後は、ワーカノード上で公開しているポート番号です。
まずは、CLUSTER-IPでアクセスした結果です。
vagrant@master:~$ curl http://10.32.0.155:8080;echo
Hello Kubernetes!
ノード外部からのアクセス
今回の環境は、Linux の Vagrant と VirutalBoxを利用したので仮想マシンのホストに、kubectlコマンドをインストールして、このホストからアクセスします。
tkr@luigi:~/k8s-1.17$ sudo snap install kubectl --classic
kubectl 1.17.0 from Canonical✓ installed
環境変数に、コンフィグファイルのパスを設定することで、パソコンのkubectlコマンドから、仮想マシンのK8sクラスタを利用できます。
tkr@luigi:~/k8s-1.17$ export KUBECONFIG=`pwd`/kubeconfig/config
ノードをリストして、正常動作を確認しておきます。
tkr@luigi:~/k8s-1.17$ kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready master 16m v1.17.0
node1 Ready <none> 15m v1.17.0
node2 Ready <none> 15m v1.17.0
次に、ノードのIPアドレスをリストしておきます。
tkr@luigi:~/k8s-1.17$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master Ready master 16m v1.17.0 172.16.20.11 <none> Ubuntu 16.04.6 LTS 4.4.0-170-generic containerd://1.2.4
node1 Ready <none> 16m v1.17.0 172.16.20.12 <none> Ubuntu 16.04.6 LTS 4.4.0-170-generic containerd://1.2.4
node2 Ready <none> 16m v1.17.0 172.16.20.13 <none> Ubuntu 16.04.6 LTS 4.4.0-170-generic containerd://1.2.4
ノードのIPアドレスに、ノードで開放しているポート番号を付加して、アクセスすることで、ロードバランサーが無い環境でも、クラウス外部からアクセスできます。
tkr@luigi:~/k8s-1.17$ curl http://172.16.20.12:30852;echo
Hello Kubernetes!
既存のロードバランサーと連携する場合は、ノードのIPアドレスとポート番号を利用すれば良い事がわかると思います。ノード上に開くポート番号はAPIで指定できますから、ロードバランサーの設定と別々に作業ができると思います。
クリーンナップ
これはチュートリアルどおりです。
tkr@luigi:~/k8s-1.17$ kubectl delete services my-service
service "my-service" deleted
tkr@luigi:~/k8s-1.17$ kubectl delete deployment hello-world
deployment.apps "hello-world" deleted
まとめ
パブリッククラウドのように、インターネットのIPアドレス取得や外部ロードバランサーと自動的に連携する機能が無いオンプレミス環境でも、ノードのIPアドレスとポート番号を利用して、外部からアクセスできる事がわかりました。オンプレミスの環境では、外部DNSや外部ロードバランサー設定は手作業となりますが、問題なく利用できる事がわかると思います。
OpenShiftやIBM Cloud Paksをオンプレミス環境に導入する場合も、同様に外部ロードバランサーの考慮が必要となりますので、一つの参考になればと思います。