まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:kubectl

Windows 10 で kubernates の開発環境を構築する際の方法の1つとして、以下のケースで構築する場合のメモです:
・Kubernetes 本体は minikube を使って Windows 10 に導入
・kubectl は WSL から利用


Kubernetes 本体はローカルで動く minikube を使ってシングルノード環境を構築します。この部分は正しく導入できていさえすれば Windows だろうが、Linux だろうが、Mac だろうが、システム環境の違いを意識することはあまりないと思っています。 ただ実際に利用する段になって kubectl コマンドを実行する環境としては Windows よりもより実践に近い Linux を使いたくなります。というわけで、Windows 10 の WSL (今回は Ubuntu を想定)から利用できるようにしました。

なお、この環境構築をする場合のマシンスペックとして、メモリ 8GB だと構築して minikube start した時点でほぼメモリを使い尽くしてしまいます。動作確認するだけならいいのですが、本格的に開発して動作確認してテストして・・・という段階まで考えるとやはり 16GB くらいはほしいところです。


【前提条件】
- Windows 10
- WSL(Ubuntu 18.0.4) 導入済み


【VirtualBox のインストール】
Windows 10 で minikube を動かす場合、仮想環境のハイパーバイザーが必要です。今回は VirtualBoxを使います。VirtualBox 自体のインストールはごく普通に公式ページから Windows 版をダウンロードし、デフォルト設定のままインストールすればOKです。


【Windows 版 minikube のインストール】
minikube の Github ページから、Windows/amd64 版の minikube 単体をダウンロードします:
2019090801


ダウンロードしたファイルは minikube-windows-amd64.exe というファイル名になっていますが、これを minikube.exe とリネームしてファイルシステムの適当なフォルダに保存します(以下は C:\MyApps\minikube\ というフォルダを作成して、その中に C:\MyApps\minikube\minikube.exe という名前で保存しているものと仮定して以下を続けます)。

このフォルダに PATH を通します。Windows + S キーを押して検索ボックスに「システムの詳細設定」と入力すると「システムの詳細設定の表示」が見つかるので、これを選択します:
2019090802


システムのプロパティウィンドウが表示されたら、「詳細設定」タブを選択し、「環境変数」ボタンをクリック:
2019090803


ユーザー環境変数の Path を選択してから「編集」ボタンをクリック:
2019090804


そして「新規」に minikube.exe が保存されたフォルダ名を追加して、最後に OK ボタンをクリック。これで minikube.exe に PATH が通りました:
2019090805


念の為、動作確認してみます。コマンドプロンプトを起動して、 "minikube version" と入力して実行します。minikube のバージョン番号が表示されれば、ここまでの手順は OK です:
2019090801


【minikube の起動】
コマンドプロンプトから "minikube start" と入力して、minikube を起動します。自動的に必要な VM イメージを見つけて(初回はダウンロードして)自動構築します。通常は minikube が kubectl を見つけてくれるのですが、この方法だと(Windows 版 kubectl を使わない&インストールしていないので)見つからない、という警告が表示されますが、今回は WSL 側に kubectl を用意するので無視します:
2019090802


【WSL に kubectl をインストール】
WSL を起動し、以下のコマンドを入力して kubectl を(/usr/local/bin/ 以下に)導入します:
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl

$ chmod 755 kubectl

$ sudo mv kubectl /usr/local/bin

最後に "kubectl version" を実行して動作確認します(初回は Client Version が表示されれば OK です):
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.3", GitCommit:"2d3c76f9091b6bec110a5e63777c332469e0cba2", GitTreeState:"clean", BuildDate:"2019-08-19T11:13:54Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"linux/amd64"}

【minikube のエンドポイント情報の取得】
コマンドプロンプトに戻って、"minikube status" を実行し、minikube のエンドポイント情報を確認します。以下の例では 192.168.99.100 というアドレスが表示されていますが、これにポート番号 8443 を加えたもの(192.168.99.100:8443)がエンドポイントとなり、以下で利用することになります:
2019090803


【kubectl の設定】
上記で取得したエンドポイント情報を使って kubectl の設定を行います。WSL から以下のコマンドを順次実行します。なお以下で <コマンドプロンプト実行時のユーザー名> と表示されている部分にはコマンドプロンプト実行時のユーザー名がフォルダ名の一部になっているのでそれをそのまま指定します(上記の画像例の場合であれば、ここには KEIKIMURA が入ります)、また 192.168.99.100:8443 部分は上記で取得したエンドポイント情報です:
$ kubectl config set-credentials minikube --client-certificate=/mnt/c/Users/<コマンドプロンプト実行時のユーザー名>/.minikube/client.crt --client-key=/mnt/c/Users/<コマンドプロンプト実行時のユーザー名>/.minikube/client.key

$ kubectl config set-cluster minikube --server=https://192.168.99.100:8443 --certificate-authority=/mnt/c/Users/<コマンドプロンプト実行時のユーザー名>/.minikube/ca.crt

$ kubectl config set-context minikube --user=minikube --cluster=minikube

$ kubectl config use-context minikube

最後に WSL で "kubectl cluster-info" コマンドを実行して動作を確認し、エンドポイントで正しくクラスタ状態が取得できれば kubectl の設定完了です。シングルノードの kubernetes (kubectl) がローカルの WSL から使えるようになりました:
$ kubectl cluster-info

Kubernetes master is running at https://192.168.99.100:8443
KubeDNS is running at https://192.168.99.100:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.



(参考)
https://dokupe.hatenablog.com/entry/20180408/1523116886

これらの記事の続きです:
IBM Cloud の無料版 Kubernetes サービスを使ってみた(1)
IBM Cloud の無料版 Kubernetes サービスを使ってみた(2)


IBM Cloud の Kubernetes サービスを使って、無料のワーカーノードにアプリケーションをデプロイして、(いったん)削除する所までを紹介しました。最終回である今回は実際にアプリケーションにアクセスしたり、デプロイしたアプリケーションをスケールさせてみたり、外部(インターネット)に公開してみたりします。

今回の作業も基本的にすべて Web Terminal から行います。というわけで、まず Web Terminal を起動します:
2019041109


改めてアプリケーションをデプロイします。が、今回は後述の RC(ReplicatoinController) としてデプロイするため、デプロイ用のファイル(rc.yaml)を作成します:
apiVersion: v1
kind: ReplicationController
metadata:
  name: kubernetes-bootcamp
spec:
  replicas: 1
  selector:
    app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: myk8x
        image: gcr.io/google-samples/kubernetes-bootcamp:v1
        ports:
        - containerPort: 8080

デプロイ時にはこのファイル(rc.yaml)を指定して、以下のコマンドを実行します:
$ kubectl create -f rc.yaml
replicationcontroller/kubernetes-bootcamp created

このコマンドで前回とほぼ同様に kubernetes-bootcamp アプリケーションを1つのポッドにデプロイします。また app: web というセレクターを指定していますが、この後で使います。

この時点で kubernetes-bootcamp アプリケーションが1つのポッドにデプロイされます。一応ポッドと、そして(詳しくは後述の)サービスの状態を確認しておきます(緑字はコメント):
$ kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
kubernetes-bootcamp-jfswt   1/1     Running   0          41s  1ポッド

$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   172.21.0.1   <none>        443/TCP   3d21h  ここはクラスタサービスなので無視、つまり起動したサービスなし

この時点で1つのポッドにアプリケーションがデプロイされたことが確認できました。しかしこのポッドはまだコンテナの外部からアクセスすることができません。コンテナの外部からでもアクセスできるように紐付けるサービスを作成します。

作成するサービスのための設定ファイル(service.json)を以下の内容で用意します:
{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "my-service"
    },
    "spec": {
        "selector": {
            "app": "web"
        },
        "ports": [
            {
                "protocol": "TCP",
                "port": 80,
                "targetPort": 8080,
                "nodePort": 30000
            }
        ],
        "type" : "NodePort"
    }
}

"spec" 内で app:web のラベルをセレクターに指定しています。これが先程作成したデプロイメント時の指定内容となっていて、kubernetes-bootcamp に紐づく形になります。また 8080 番ポートをターゲットに接続し、80 番ポートで公開する、という指定も行い、"my-service" という名前でサービスを作るよう指示しています。

ではこのファイル(service.json)を使ってサービスを作成します。同時に再びポッドとサービスの内容を照会してみます:
$ kubectl create -f service.json
service/my-service created

$ kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
kubernetes-bootcamp-jfswt   1/1     Running   0          13m  1ポッド

$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   172.21.0.1   <none>        443/TCP   3d21h
my-service   NodePort    172.21.30.70 <none>        80:30000/TCP   94s 追加されたサービス

サービスの追加に成功しました。またその追加されたサービスはクラスター内の内部 IP アドレスである 172.21.30.70:80 上で稼働していることがわかりました。

ではこのサービスを使ってアプリケーションにアクセスしてします:
$ curl http://172.21.30.70/
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-jfswt | v=1

アプリケーションにコンテナ外部からアクセスでき、正しく動作していることも確認できました。ただし、この時点ではまだあくまで内部ネットワーク内からのアクセスが確認できただけで、まだインターネットからはアクセスできません(後述します)。


コンテナの外部からアプリケーションにアクセスできることは確認できましたが、せっかくなので Kubernetes っぽい挙動もさせてみます。現在1つのポッドで動作しているこのアプリケーションをスケールアウトして複数の(今回は2つの)ポッドで起動するようにしてみます:
$ kubectl scale -f rc.yaml --replicas=2
replicationcontroller/kubernetes-bootcamp scaled

この状態で再びポッドとサービスの状態を確認します。ポッドが2つになっていることがわかります。(一方、サービスは何も変わっていません):
$ kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
kubernetes-bootcamp-kqkhp   1/1     Running   0          14s スケールアウトして新しく増えたポッド
kubernetes-bootcamp-jfswt   1/1     Running   0          109s

$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   172.21.0.1      <none>        443/TCP        3d23h
my-service   NodePort    172.21.30.70    <none>        80:30000/TCP   5m16s

ではこのアプリケーションをインターネットに公開してみます。以下のコマンドを実行します:
$ kubectl expose rc kubernetes-bootcamp --type=NodePort --name=web
service/web exposed

$ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   172.21.0.1       <none>        443/TCP          4d20h
my-service   NodePort    172.21.199.105   <none>        80:30000/TCP     4m30s
web          NodePort    172.21.64.253    <none>        8080:30703/TCP   4m9s

"web" という名称のサービスが追加され、kubernetes-bootcamp の rc が expose(外部公開)されました。公開先のポート番号が 30703 になっていることも確認できます。

また、公開先の IP アドレスはワーカーノードのパブリック IP アドレスになっています。ダッシュボードから確認するか、または以下のコマンドを実行します:
2019041601
$ ibmcloud cs workers mycluster (最後のパラメーターはクラスタ名)

ID                                                 Public IP       Private IP       Machine Type   State    Status   Zone    Version   
kube-mel01-pa351ddd2ea19441a689a49159389f9d45-w1   168.1.149.201   10.118.243.103   free           normal   Ready    mel01   1.12.7_1548*


この例だと、パブリック IP アドレスが 168.1.149.201 となっているので、この 30703 番ポートに対してウェブブラウザでアクセスし、期待通りの結果になることを確認します:
2019041602


最後に、サービスとポッドを削除する場合は以下のコマンドを実行します:
$ kubectl delete svc web
service "web" deleted

$ kubectl delete -f service.json
service "my-service" deleted

$ kubectl delete -f rc.yaml
replicationcontroller "kubernetes-bootcamp" deleted


IBM Cloud の(無料の)Kubernetes サービスを使って、アプリケーションのデプロイ、スケール、動作確認、ウェブ公開、といった一連の作業ができることが確認できました。すでに Kubernetes 環境を手元に持っているような人であればともかく、これから Kubernetes を使ってみようと思う人にとっては面倒な準備作業も不要で気軽に始められて、スケールやウェブ公開といった一通りの作業ができるところまで使える環境としてとても便利だと思いました。





この記事の続きです。

IBM Cloud の無料版 Kubernetes サービスで、Kubernetes クラスタを立ち上げる所までを紹介しました。 今回は(ベータ版の)Web Terminal 機能を使って、この Kubernetes サービスの状態を確認したり、アプリケーションをデプロイしてみます。

IBM Cloud を操作する場合、一般的には ibmcloud コマンドを使います。また Kubernetes クラスタの状態を確認する場合、一般的には kubectl コマンドを使うことが多いと思っています。普段使っているマシンに ibmcloud コマンドや kubectl コマンドがすでにセットアップされているような場合はそれらのコマンドを使えばいいのですが、まだ導入されていないようなケースでは別途セットアップしてから利用する必要があります。 今回紹介する Web Terminal はそういった導入をしなくてもウェブブラウザ内のコンソールから ibmcloud コマンドや kubectl コマンドを使って操作できる方法です。現時点(2019/04/15)でベータ版なので今後どういう形になるかわかりませんが、使ってみて便利だったので紹介させていただくことにしました。

では以下に実際の手順を紹介します。まず前回の記事の内容が正しく実行されて、"mycluster" という名称の Kubernetes クラスタが稼働している状態になっていることを確認します:
2019041107


"Worker Nodes" タブでワーカーノード(今回は1つ)が正しく動いている点も確認します(この画面では IP アドレスをモザイクにしていますが、実際にはモザイクなしに表示されます):
2019041108


ではまずはこのワーカーノードの状態を Web Terminal からも確認してみます。画面内の "Web Terminal" と書かれたボタンをクリックします:
2019041109


最初にクリックした時だけ、「Kubernetes Terminal をインストールする」という確認のダイアログが表示されます。「Install」ボタンをクリックすると Kubernetes Terminal がインストールされます(少し時間がかかります、十数秒くらい?):
2019041110


(Kubernetes Terminal をインストールした場合は十数秒程度待って)改めて "Web Terminal" ボタンをクリックします。するとブラウザ画面下部からターミナルが現れます:
2019041111


このターミナルのプロンプトで、画面内に書かれたセットアップ手順を順に実行していきます。ibmcloud コマンドは特にインストールしていませんが、この Web Terminal 内では導入済みなので普通にそのまま使うことができます(赤字はコメント):
2019041112
$ ibmcloud login -a https://cloud.ibm.com ログイン

$ ibmcloud ks region-set ap-south サービスのリージョンを(作成したリージョンに)指定

$ ibmcloud ks cluster-config mycluster Kubernetes の環境設定用ファイルを生成してダウンロード

最後のコマンドを実行すると KUBECONFIG 環境変数を設定するためのコマンドが表示されます。そこに書かれた内容をそのままコピー&ペーストして、Web Terminal 上で KUBECONFIG 環境変数を設定します:
$ export KUBECONFIG=/home/IBMid-31000086FP/.bluemix/plugins/container-service/clusters/mycluster/kube-config-mel01-mycluster.yml

 

ここまでの作業が完了すると Web Terminal から kubectl コマンドを実行できるようになり、コマンドを通じてワーカーノードの状態を確認することもできるようになります。この kubectl コマンドも特にセットアップすることなく、Web Terminal 上でそのまま実行できます:
$ kubectl get nodes

1つだけ動いているワーカーノードが、名称や状態とあわせて Web Terminal 上に表示されます:

2019041113


先程ウェブ画面で確認したものと同じ内容が表示されました。これでこの Web Terminal 上から Kubernetes クラスタを操作できることが確認できました。


では続けてこのノードにアプリケーションをデプロイしてみます。Kubernetes の公式チュートリアルで紹介されている内容と全く同じ操作を Web Terminal から行ってみます。

デプロイメントの名前(以下の例では kubernetes-bootcamp)とアプリケーションイメージの Docker Hub リポジトリ URL (同 gcr.io/google-samples/kubernetes-bootcamp:v1)、実行ポート番号(同 8080)を指定して kubectl run コマンドを実行し、アプリケーションイメージを Kubernetes クラスタにデプロイします:
$ kubectl run kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --port=8080

このコマンドが実行されると、アプリケーションが実行可能なノード(今回ははじめから1つしか用意してないので、その1つ)を探し、アプリケーションの実行がスケジュールされてデプロイが実行されます。

実行後に以下のコマンドでデプロイメントの状態を確認してみます。以下のような感じで、1つのアプリケーションが実行されている状態になればデプロイは成功しています:
$ kubectl get deployments
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   1         1         1            1           16s

また、この時点で Pod の状態も確認しておきます。デプロイ時に特にレプリカ数を指定していなかったので、1つの Pod が起動され、その上でアプリケーションが起動しているはずです:
$ kubectl get pod
NAME                                   READY   STATUS    RESTARTS   AGE
kubernetes-bootcamp-598f57b95c-w2k4b   1/1     Running   0          2m7s

次の段階に進む前に、いったん作成した Pod を削除しておきます。作成時に指定した名前(kubernetes-bootcamp)を指定してデプロイメントを削除します:
$ kubectl delete deployment kubernetes-bootcamp
deployment.extensions "kubernetes-bootcamp" deleted

$ kubectl get deployments
No resources found.

$ kubectl get pod
No resources found.

↑念の為、デプロイメントと Pod が存在しなくなっていることも確認できました。次回、最終回に改めてアプリケーションをデプロイして、スケールさせたりした上で使ってみることにします。

このページのトップヘ