https://kubernetes.io/docs/tutorials/kubernetes-basics/
公式のチュートリアルを実際に動かしたいと思います。
このチュートリアルでは Katakoba を利用していますが、今回は yaml
を書いて動かします。
Environment
- Master *1 (Ubuntu Server 18.04 on ESXi)
- Worker *8 (Ubuntu Server 18.04 on ESXi)
- Kubernetes v1.17.0
このチュートリアルではネームスペースk8s-tutorial
にすべてのリソースを作成します。
What Learn
- コンテナ化されたアプリケーションをクラスターにデプロイ
- Deploymentのスケーリング
- 新しいソフトウェアのバージョンでコンテナ化されたアプリケーションをアップデート
- コンテナ化されたアプリケーションのデバッグ
Create Kubernetes Cluster
別記事にて紹介済みのため省略
Create Namespace
apiVersion: v1
kind: Namespace
metadata:
name: k8s-tutorial
$ kubectl apply -f ns.yml
namespace/k8s-tutorial created
Deploy Application
$ kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1
このコマンドを yaml
に起こして投入します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-bootcamp
namespace: k8s-tutorial
spec:
selector:
matchLabels:
app: kubernetes-bootcamp
template:
metadata:
labels:
app: kubernetes-bootcamp
spec:
containers:
- name: kubernetes-bootcamp
image: gcr.io/google-samples/kubernetes-bootcamp:v1
resources:
limits:
memory: "128Mi"
cpu: "500m"
$ kubectl apply -f deploy_01.yml
deployment.apps/kubernetes-bootcamp created
created
が出ずにエラーになった場合は deploy_01.yml
を確認してください。
deployment
の状況を確認してみます。
$ kubectl get deploy -n k8s-tutorial -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
kubernetes-bootcamp 1/1 1 1 2m47s kubernetes-bootcamp gcr.io/google-samples/kubernetes-bootcamp:v1 app=kubernetes-bootcamp
READY
が 1/1
になっているので無事にデプロイされました。
一応、 Pod
も確認してみましょう。
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-ncxfr 1/1 Running 0 54s
STATUS
が RUNNING
になっていますね。
この章はこれで終了ですのでお掃除しておきましょう。
$ kubectl delete -f deploy_01.yml
deployment.apps "kubernetes-bootcamp" deleted
今回は1つだけでしたが Deployment
を増やしたり Pod
の SideCar
を適用したりすることでこの図のような Kubernetes Cluster
を作り上げていくことが可能です。
Executed to Pod
対象の Pod 名を環境変数にセット
$ export POD_NAME = kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'
対象の Pod 内の環境変数を表示
$ kubectl exec -n k8s-tutorial $POD_NAME env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=kubernetes-bootcamp-5b48cfdcbd-2wq82
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
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
NPM_CONFIG_LOGLEVEL=info
NODE_VERSION=6.3.1
HOME=/root
対象の Pod 内で bash
を起動
$ kubectl exec -n k8s-tutorial $POD_NAME -it bash
root kubernetes-bootcamp-xxxxxxxxxx-xxxxx:/# #このプロンプトは Pod 内の bash によるもの
Pod 内のファイルを確認
root kubernetes-bootcamp-xxxxxxxxxx-xxxxx:/# ls -la
total 460
drwxr-xr-x 1 root root 4096 Jan 17 06:28 .
drwxr-xr-x 1 root root 4096 Jan 17 06:28 ..
-rwxr-xr-x 1 root root 0 Jan 17 06:28 .dockerenv
drwxr-xr-x 2 root root 4096 Jun 8 2016 bin
drwxr-xr-x 2 root root 4096 May 30 2016 boot
-rw------- 1 root root 393216 Jun 9 2016 core
drwxr-xr-x 5 root root 360 Jan 17 06:28 dev
drwxr-xr-x 1 root root 4096 Jan 17 06:28 etc
drwxr-xr-x 2 root root 4096 May 30 2016 home
drwxr-xr-x 1 root root 4096 Jun 9 2016 lib
drwxr-xr-x 2 root root 4096 Jun 8 2016 lib64
drwxr-xr-x 2 root root 4096 Jun 8 2016 media
drwxr-xr-x 2 root root 4096 Jun 8 2016 mnt
drwxr-xr-x 2 root root 4096 Jun 8 2016 opt
dr-xr-xr-x 217 root root 0 Jan 17 06:28 proc
drwx------ 1 root root 4096 Jul 22 2016 root
drwxr-xr-x 1 root root 4096 Jan 17 06:28 run
drwxr-xr-x 2 root root 4096 Jun 8 2016 sbin
-rw-r--r-- 1 root root 742 Jul 29 2016 server.js
drwxr-xr-x 2 root root 4096 Jun 8 2016 srv
dr-xr-xr-x 13 root root 0 Jan 17 06:28 sys
drwxrwxrwt 1 root root 4096 Jul 22 2016 tmp
drwxr-xr-x 1 root root 4096 Jul 22 2016 usr
drwxr-xr-x 1 root root 4096 Jul 22 2016 var
# 実際に Pod 内で動いているコード(Node.js)
root kubernetes-bootcamp-xxxxxxxxxx-xxxxx:/# 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-xxxxxxxxxx-xxxxx:/# curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-xxxxxxxxxx-xxxxx | v=1
# 抜け出す
root kubernetes-bootcamp-xxxxxxxxxx-xxxxx:/# exit
$ # Pod から脱出
Access to kubernetes-bootcamp
先程の deploy_01.yml
でデプロイした kubernetes-bootcamp
は 8080/tcp
を受けていますので、それに対応した Service
を作成します。
apiVersion: v1
kind: Service
metadata:
name: kubernetes-bootcamp
namespace: k8s-tutorial
spec:
selector:
app: kubernetes-bootcamp
type: NodePort
ports:
- port: 80
targetPort: 8080
$ kubectl apply -f svc_01.yml
service/kubernetes-bootcamp created
$ kubectl get svc -n k8s-tutorial
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-bootcamp NodePort 10.96.46.6 <none> 80:32767/TCP 40s
http://[MasterのIP]:[外部公開ポート]
にアクセスします。
上記の例だと Master
の IP アドレスは 10.0.0.230
なので http://10.0.0.230:32767
になります。
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-xxxxxxxxxx-xxxxx| v=1
exec
した時に確認したものと同じ出力結果のはずです。
Scale In/Out
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-8w268 1/1 Running 0 85m
現在 kubernetes-bootcamp
の Pod 数は 1 ですが、これは増減させることができます。
$ kubectl scale -n k8s-tutorial deploy kubernetes-bootcamp --replicas 10
deployment.apps/kubernetes-bootcamp scaled
これで kubernetes-bootcamp
の Pod 数を 10 に増やしました。
Deployment
と Pod
を確認してみましょう。
$ kubectl get deploy -n k8s-tutorial kubernetes-bootcamp
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 10/10 10 10 113m
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-8w268 1/1 Running 0 95m
kubernetes-bootcamp-64cd8bd759-cbbk5 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-mtl5p 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-ndk55 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-tdp4f 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-tg5cx 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-wx2v6 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-xgqlt 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-zhzql 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-zqjlx 1/1 Running 0 3m10s
Deployment
では 10/10
になっており、 Pod
では10個の Pod が出力されました。
では次は増やしたものを減らしてみましょう。
$ kubectl scale -n k8s-tutorial deploy kubernetes-bootcamp --replicas 3
deployment.apps/kubernetes-bootcamp scaled
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-mtl5p 1/1 Running 0 9m37s
kubernetes-bootcamp-64cd8bd759-wx2v6 1/1 Running 0 9m37s
kubernetes-bootcamp-64cd8bd759-zhzql 1/1 Running 0 9m37s
先程と同じコマンドでレプリカ数を変更するだけで完了します。
Load Balancing
先程1つの Pod に対してアクセスを行いました。では Pod が複数存在した状態で同様にアクセスした場合はどうなるのでしょうか。
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-mtl5p 1/1 Running 0 52m
kubernetes-bootcamp-64cd8bd759-wx2v6 1/1 Running 0 52m
kubernetes-bootcamp-64cd8bd759-zhzql 1/1 Running 0 52m
3つの Pod があります。実際にアクセスしてみましょう。
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-64cd8bd759-wx2v6 | v=1
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-64cd8bd759-zhzql | v=1
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-64cd8bd759-mtl5p | v=1
Master に対してアクセスしているのに3つの Pod に振り分けられています。
Service
を作成する際に spec.type
を NodePort
にしたのでいい具合に分散してくれるようになっています。
Rolling Update
このチュートリアルでは kubernetes-bootcamp:v1
を使用してきました。ここでは v1
から v2
にイメージを更新します。
$ kubectl set image deploy kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2 -n k8s-tutorial
deployment.extensions/kubernetes-bootcamp image updated
set image
で jocatalin/kubernetes-bootcamp:v2
に更新しました。
実際に Pod
を確認してみましょう。
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-8686fc5f77-5wggs 1/1 Running 0 97s
kubernetes-bootcamp-8686fc5f77-bsxbb 1/1 Running 0 90s
kubernetes-bootcamp-8686fc5f77-znnq4 1/1 Running 0 103s
LoadBalancing の章で確認したときは kubernetes-bootcamp-64cd8bd759-xxxxx
でしたが、イメージを更新したため Pod が作り直されて kubernetes-bootcamp-8686fc5f77-xxxxx
になりました。 AGE
も新しい時刻になっています。
使用されているイメージを確認するには --output wide
や describe
します。
$ kubectl get deploy -n k8s-tutorial -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
kubernetes-bootcamp 3/3 3 3 4h52m kubernetes-bootcamp jocatalin/kubernetes-bootcamp:v2 app=kubernetes-bootcamp
確かに IMAGES
が jocatalin/kubernetes-bootcamp:v2
になっています。
v2
イメージに更新できたので実際にアクセスしてみましょう。
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-8686fc5f77-znnq4 | v=2
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-8686fc5f77-5wggs | v=2
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-8686fc5f77-bsxbb | v=2
v=2
になっています。
set
でイメージ更新を行った場合、不具合等でもとのイメージに戻したくなったらコマンド1つで戻すことができます。
$ kubectl rollout undo deploy kubernetes-bootcamp -n k8s-tutorial
deployment.apps/kubernetes-bootcamp rolled back
これでもとに戻すことができます。
実際に確認してみましょう。
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-4bl2s 1/1 Running 0 12s
kubernetes-bootcamp-64cd8bd759-g4grz 1/1 Running 0 14s
kubernetes-bootcamp-64cd8bd759-ng69z 1/1 Running 0 17s
kubernetes-bootcamp-8686fc5f77-5wggs 1/1 Terminating 0 14m
kubernetes-bootcamp-8686fc5f77-bsxbb 1/1 Terminating 0 13m
kubernetes-bootcamp-8686fc5f77-znnq4 1/1 Terminating 0 14m
v2
が適用された kubernetes-bootcamp-8686fc5f77-xxxxx
が削除されて、もとの v1
が適用された kubernetes-bootcamp-64cd8bd759-xxxxx
が作成されています。
ここまでで Kubernetes を使用すると簡単にデプロイ・公開・アップデート・ロールバックが行えることがわかりました。
以上で公式チュートリアルは終了です。今後もサンプルアプリ等を用いながら Kubernetes の機能を学習していきます。