[第1回]Kubernetesの公式チュートリアルをやって基本を押さえる -アプリのデプロイ-
コンニチハ、千葉です。
Kubernetesを勉強中です。Kubernetesは簡単に使えて、かつコンテナのデプロイや可用性を向上することができます。高度なことを簡単に使えるようにテクノロジーが注ぎ込まれています。 チュートリアルでは、クラスタの起動からアプリケーションのデプロイ、確認、公開、アップデートまで基本的なライフサイクルを身につけられます。分量が多いので数回に分けて、チュートリアルをやっていきましょう。
範囲
*の箇所が第1回の範囲です。
- *クラスターの作成
- *アプリケーションのデプロイ
- *アプリケーションの状態確認
- アプリケーションの公開
- アプリケーションのスケールアウト
- アプリケーションのアップデート
他の回はこちら
環境の用意
チュートリアルを実施するKubernetesの環境を用意します。 Kubernetesのベーシックチュートリアルでは、Web上でターミナル環境が用意されておりコマンドを打って試すことができます。そのため、特に環境を用意する必要がありませんが、私はガチャガチャ触りたかったのでMinikubeを使ってローカルに環境を用意し試しました。
クラスターの作成
この章では、クラスターの起動と状態の確認を行います。チュートリアルではMinikubeを利用しています。
クラスターの起動と状態確認
Minikubeを利用するのでバージョン確認します。
$ minikube version minikube version: v0.26.1
Minikubeを利用しKubernetesクラスタを起動します。
$ minikube start Starting local Kubernetes v1.10.0 cluster... Starting VM... Getting VM IP address... Moving files into cluster... Setting up certs... Connecting to cluster... Setting up kubeconfig... Starting cluster components... Kubectl is now configured to use the cluster. Loading cached images from config file.
クラスターのバージョン確認
Kubernetes APIを実行するコマンドラインツール kubectl
のバージョンとマスターノードのKubernetesバージョンの確認します。
$ kubectl version Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.0", GitCommit:"925c127ec6b946659ad0fd596fa959be43f0cc05", GitTreeState:"clean", BuildDate:"2017-12-16T03:16:50Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"darwin/amd64"} Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.0", GitCommit:"fc32d2f3698e36b93322a3465f63a14e9f0eaead", GitTreeState:"clean", BuildDate:"2018-03-26T16:44:10Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
クラスターの詳細確認
クラスターの詳細情報を取得します。
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'.
マスターノードとダッシュボードが起動しています。ダッシュボードとは実行しているアプリケーションを確認できるUI。このチュートリアルでは、CLIを使います。
ちなみにminikube dashboard
でダッシュボードにアクセスできます。
すべてのノード情報を取得。ただしMinikube環境では1つのノードのみ実行されています。ノードとはホスト(物理または仮想ホスト)です。
kubectl get nodes NAME STATUS ROLES AGE VERSION minikube Ready master 5d v1.10.0
Kubernetesはクラスターを管理するマスターとアプリケーション(コンテナ)を実行するノードの2種類があります。Minikubeではマスターのみ起動している状態になります。
アプリケーションのデプロイ
この章では、kubectlを使ってアプリケーション(コンテナ)のデプロイを行います。デプロイされるとアプリケーションは監視され、ホストが停止しても自動復旧するようになります。
アプリのデプロイ
kubectl run
を使用してアプリを起動します。run
は新しいデプロイを作成します。デプロイの名前とアプリケーションイメージ(Docker Hubやプライベートレポジトリなど)、ポート番号を指定します。
$ kubectl run kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --port=8080 deployment "kubernetes-bootcamp" created
デプロイを作成すると、いくつかのことが実行されます
- アプリケーションを実行するノードを探す
- アプリケーションを探したノードで実行するようにスケジュールする
- 必要に応じてクラスターを構成し、新しいノードでアプリケーションを実行するうように再スケジュールする。つまり、ノードが停止してもアプリケーションが起動するように維持されます。
デプロイのリストを表示します。インスタンスはDockerコンテナとしてノードで実行されます。
$ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE kubernetes-bootcamp 1 1 1 1 23s
アプリへの通信
デプロイを作成すると、KubernatesはPodを作成しアプリケーションインスタンス(コンテナ)をホストします。Podは、1つまたは複数のアプリケーションコンテナのグループです。今回のチュートリアルでのデプロイは1つのコンテナですが、PodではDocker Compose 的な感じで複数コンテナをグルーピングすることもできます。
デプロイされたPodは、プライベートネットワークで分離されています。デフォルトでは、Kubernetesクラスター内のみ通信ができますが、外との通信はできません。
外部ネットワークとPodを通信させるためには、proxyまたはexposeを利用します。*exposeは第2回でやるのでそちらで説明します。
kubectl proxy
を実行すると、KubernetesのAPIエンドポイント経由でアプリケーションにアクセスできます。kubectlがapiエンドポイントへのリバースプロキシとして動作します。
kubectl proxy(ローカル端末) > Kubernetesクラスターで起動しているAPIエンドポイント > Podというイメージです。
プロキシを起動します。プロセスが起動するので停止したい場合はcontrol-Cを入力します。
$ kubectl proxy Starting to serve on 127.0.0.1:8001
別のターミナルを起動し、ローカルで起動しているプロキシ経由でAPIエンドポイントへアクセスし、バージョン情報を取得します。取得した情報を見るとkubectl version
で取得したサーバー情報と同じ内容が取得できてますね!
$ curl http://localhost:8001/version { "major": "1", "minor": "10", "gitVersion": "v1.10.0", "gitCommit": "fc32d2f3698e36b93322a3465f63a14e9f0eaead", "gitTreeState": "clean", "buildDate": "2018-03-26T16:44:10Z", "goVersion": "go1.9.3", "compiler": "gc", "platform": "linux/amd64" }
また、APIサーバーはPodへアクセスするためのエンドポイントを自動で作成します。Pod名を取得し、APIサーバー経由でアプリケーションにアクセスしてみます。
$ export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') $ echo Name of the Pod: $POD_NAME Name of the Pod: kubernetes-bootcamp-5c69669756-gp797 $ curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/ Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-5c69669756-gp797 | v=1
ローカルで起動しているプロキシ経由でデプロイしたアプリケーションにアクセスできてます!
アプリケーションの状態確認
この章では、kubernetesアプリケーションのトラブルシューティングの仕方について学習します。kubectl get, describe, logs and exec commandsを利用します。
アプリケーションの構成情報確認
実行されているPodのを取得します。1つのPodが起動されています。
$ kubectl get pods NAME READY STATUS RESTARTS AGE kubernetes-bootcamp-5c69669756-gp797 1/1 Running 1 1d
コンテナの詳細情報(IP、ポート、ライフサイクル)などなど。見説明の情報も出力されてますが、チュートリアル終了時には内容がわかるでしょう。
$ kubectl describe pods Name: kubernetes-bootcamp-5c69669756-gp797 Namespace: default Node: minikube/10.0.2.15 Start Time: Sun, 06 May 2018 10:01:08 +0900 Labels: pod-template-hash=1725225312 run=kubernetes-bootcamp Annotations: <none> Status: Running IP: 172.17.0.4 Controlled By: ReplicaSet/kubernetes-bootcamp-5c69669756 Containers: kubernetes-bootcamp: Container ID: docker://decd7e0506b562586a7b5bcfd63792d49f2f965b64d5c167636ee002d693d347 Image: gcr.io/google-samples/kubernetes-bootcamp:v1 Image ID: docker-pullable://gcr.io/google-samples/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af Port: 8080/TCP State: Running Started: Mon, 07 May 2018 21:32:01 +0900 Last State: Terminated Reason: Error Exit Code: 137 Started: Sun, 06 May 2018 10:01:08 +0900 Finished: Mon, 07 May 2018 16:48:47 +0900 Ready: True Restart Count: 1 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-bbmpz (ro) Conditions: Type Status Initialized True Ready True PodScheduled True Volumes: default-token-bbmpz: Type: Secret (a volume populated by a Secret) SecretName: default-token-bbmpz Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulMountVolume 45m kubelet, minikube MountVolume.SetUp succeeded for volume "default-token-bbmpz" Normal SandboxChanged 45m kubelet, minikube Pod sandbox changed, it will be killed and re-created. Normal Pulled 45m kubelet, minikube Container image "gcr.io/google-samples/kubernetes-bootcamp:v1" already present on machine Normal Created 45m kubelet, minikube Created container Normal Started 45m kubelet, minikube Started container
ターミナルからアプリケーションを確認
プロキシを使ったアプリケーションへのアクセスです。
$ kubectl proxy Starting to serve on 127.0.0.1:8001
もうひとつのターミナルで実行します。
$ export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') $ echo Name of the Pod: $POD_NAME Name of the Pod: kubernetes-bootcamp-5c69669756-gp797 $ curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/ Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-5c69669756-gp797 | v=1
コンテナログを確認
コンテナのSTDOUTに出力されているログを確認します。STDOUTに出力されている起動ログと、アクセスログが確認できます。
$ kubectl logs $POD_NAME Kubernetes Bootcamp App Started At: 2018-05-07T12:32:01.991Z | Running On: kubernetes-bootcamp-5c69669756-gp797 Running On: kubernetes-bootcamp-5c69669756-gp797 | Total Requests: 1 | App Uptime: 1860.883 seconds | Log Time: 2018-05-07T13:03:02.874Z Running On: kubernetes-bootcamp-5c69669756-gp797 | Total Requests: 2 | App Uptime: 3229.955 seconds | Log Time: 2018-05-07T13:25:51.946Z
コンテナ上でコマンド実行
起動しているコンテナに対して直接コマンドを実行します。exec
を使います。
$ kubectl exec $POD_NAME env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=kubernetes-bootcamp-5c69669756-gp797 KUBERNETES_PORT_443_TCP_PROTO=tcp KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1 KUBERNETES_SERVICE_HOST=10.96.0.1 KUBERNETES_SERVICE_PORT=443 KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT=tcp://10.96.0.1:443 KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443 NPM_CONFIG_LOGLEVEL=info NODE_VERSION=6.3.1 HOME=/root
今度はbashセッションを開始します。
$ kubectl exec -ti $POD_NAME bash root@kubernetes-bootcamp-5c69669756-gp797:/# cat server.js var http = require('http'); var requests=0; var podname= process.env.HOSTNAME; var startTime; var host; var handleRequest = function(request, response) { response.setHeader('Content-Type', 'text/plain'); response.writeHead(200); response.write("Hello Kubernetes bootcamp! | Running on: "); response.write(host); response.end(" | v=1\n"); console.log("Running On:" ,host, "| Total Requests:", ++requests,"| App Uptime:", (new Date() - startTime)/1000 , "seconds", "| Log Time:",new Date()); } var www = http.createServer(handleRequest); www.listen(8080,function () { startTime = new Date();; host = process.env.HOSTNAME; console.log ("Kubernetes Bootcamp App Started At:",startTime, "| Running On: " ,host, "\n" ); }); root@kubernetes-bootcamp-5c69669756-gp797:/# curl localhost:8080 Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-5c69669756-gp797 | v=1 root@kubernetes-bootcamp-5c69669756-gp797:/# exit exit
sshのようにコンテナに接続してコマンド実行ができました。
さいごに
Minikubeを利用し、クラスターやPodの情報取得、Kubernetes上にコンテナを起動して、接続や直接コマンド実行を行いました。 初めて触りましたが、Kubernetesの雰囲気がつかめました。第2回では、アプリケーションの公開をやります!
他の回はこちら