どこにでもいるSEの備忘録

たぶん動くと思うからリリースしようぜ

Dockerについて勉強してみた(その3 : Kubernetes)

この前はこんな感じのことをやっていました。

nogawanogawa.hatenablog.com

今回もDocker関連をやっていきます。 今回はオーケストレーションをやっていきます。

参考にさせていただいたのはこちら。

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門

オーケストレーション

Dockerを使用する際、下記を参考にすると、こんな感じのことも考えないといけません。

thinkit.co.jp

  • 複数のDockerホストの管理
  • コンテナのスケジューリング
  • ローリングアップデート
  • スケーリング / オートスケーリング
  • コンテナの死活監視
  • 障害時のセルフヒーリング
  • サービスディスカバリ
  • ロードバランシング
  • データの管理
  • ワークロードの管理
  • ログの管理
  • Infrastructure as Code
  • その他エコシステムとの連携や拡張

平たく言うと、コンテナの周りの管理を考えないといけないってことですね。

そこで、コンテナオーケストレーションが必要になってきます。

cn.teldevice.co.jp

こうした多数のコンテナに対する運用管理作業を一般に“コンテナオーケストレーション”と呼びます。そしてKubernetesをはじめとするコンテナオーケストレーションツールは、こうした作業を自動化してくれるのです。正確な表現ではありませんが、コンテナを基盤とした分散環境を実現するOSのような位置づけと言ってもいいでしょう。

Kubernetes

余談

Kubernatesの中身に入る前に、余談にはなりますがこの間のGoogle Cloud Next '19でも、 Kubernetesのセッションが非常に多かった印象でした。 言いすぎかもしれないですが、 Kubernetesは使って当たり前というような雰囲気すらありました。

印象としては、Kubernetesを使う前提で、マルチクラウド・ハイブリッドクラウドでどうやってシステムを管理していくかがポイントな気がしました。

概要

さて、Kubernatesの概要に入ります。 本書によるとKubernetesは下記のように書かれています。

KubernatesはGoogle社主導で開発された、コンテナの運用を自動化するためのコンテナオーケストレーションシステムです。

だそうです。

概念

Kubernetesの構成のイメージはこんな感じです。

f:id:nogawanogawa:20190804114619j:plain:w500

下から見ていくと、複数のNodeにまたがって、Kubernetesクラスタと呼ばれるKubernetesの様々なリソースを管理する集合体が形成されます。 各Nodeは一つのKubernetesクラスタによって管理されます。 このときNodeには、必ずMaster Nodeが少なくとも一つは配置されます。 Nodeの上に複数のコンテナを束ねたPodと呼ばれる集合が乗っかるような構成になります。

PodはNodeは必ず一つのNodeに帰属する形になり、またぐことはできないようになっています。

f:id:nogawanogawa:20190804114646j:plain:w500

MasterNodeには、下記のようなもので構成されているようです。

  • kube-apisetver
  • etcd
  • kube-scheduler
  • kube-controller-manager

試しに使ってみる

使いながら勉強ということで、こちらのリポジトリを使わせていただきました。

github.com

勉強に使うなら、公式のチュートリアルもあるので、そっちも見ながらやると良いかもしれないです。

kubernetes.io

Dashboardを使う

下記のコマンドでインストールできます。

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml

次に、ダッシュボードへのプロキシサーバを起動します。

kubectl proxy

試しにアクセスしてみます。

http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/.

認証画面が出てくるので、

kubectl -n kube-system get secret

で”default-token-***”ってやつを探して

kubectl -n kube-system describe secret default-token-***

トークンを取れます。 これを入力するとこんな感じ。

f:id:nogawanogawa:20190804145835p:plain:w500

Googleっぽいダッシュボードが見れました。

操作

Kubernetesで実行されるアプリケーションは、デプロイの構成要素であるリソースと協調して動作しています。 リソースは平たく言えば、デプロイ時の設定みたいなもんですかね。

何はともあれ、写経しながら確認します。

Pod

Podは上で書いたように、コンテナの集合体です。 その設定を記載して適用することで、Kubernetesクラスタの中にPodがデプロイされます。

kubectl apply -f simple-pod.yaml

これでpodがデプロイされるらしいです。

kubectl get pod

確認してみます。

simple-examples $kubectl get pod
NAME          READY   STATUS    RESTARTS   AGE
simple-echo   2/2     Running   0          11s

確かに起動していることがわかります。

一旦、podを停止します。

kubectl delete -f simple-pod.yaml

ReplicaSet

次は複数のpodを束ねたReplicasetを定義・適用します。

$kubectl apply -f simple-replicaset.yaml
replicaset.apps/echo created

$kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
echo-lbpd9   2/2     Running   0          21s
echo-m42v4   2/2     Running   0          21s
echo-wvcdr   2/2     Running   0          21s

3つpodができています。 ということで、停止。

simple-examples $kubectl delete -f simple-replicaset.yaml
replicaset.apps "echo" deleted

Deployment

DeploymentはRepliacasetと似ていますが、世代管理が可能になっています。

$kubectl apply -f simple-deployment.yaml  --record
deployment.apps/echo created

確認してみると、こんな感じです。

$kubectl get pod,replicaset,deployment --selector app=echo
NAME                       READY   STATUS    RESTARTS   AGE
pod/echo-957c45956-bmfjd   2/2     Running   0          103s
pod/echo-957c45956-cswbh   2/2     Running   0          103s
pod/echo-957c45956-jg98p   2/2     Running   0          103s
pod/echo-957c45956-v4hd4   2/2     Running   0          103s

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.extensions/echo-957c45956   4         4         4       103s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/echo   4/4     4            4           103s

リビジョン(世代)を確認してみると、1となっています。

$kubectl rollout history deployment echo
deployment.extensions/echo
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=simple-deployment.yaml --record=true

コンテナ定義を書き換えて再び適用してみると、

$kubectl apply -f simple-deployment.yaml  --record
deployment.apps/echo configured
$kubectl rollout history deployment echo
deployment.extensions/echo
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=simple-deployment.yaml --record=true
2         kubectl apply --filename=simple-deployment.yaml --record=true

世代が一つ追加されています。

ロールバックはこんな感じらしいです。

$kubectl rollout undo deployment echo
deployment.extensions/echo rolled back

Service

ServiceはPodの集合に経路やサービスディスカバリを提供するリソースです。 今回の例では、特定のコンテナからだけリクエストをできるようにします。

$kubectl apply -f simple-replicaset-with-label.yaml
replicaset.apps/echo-spring created
replicaset.apps/echo-summer created

$kubectl get pod -l app=echo -l release=spring
NAME                READY   STATUS    RESTARTS   AGE
echo-spring-t25sj   2/2     Running   0          38s
$kubectl get pod -l app=echo -l release=summer
NAME                READY   STATUS    RESTARTS   AGE
echo-summer-wh7v9   2/2     Running   0          46s
$kubectl run -i --rm --tty debug --image=gihyodocker/fundamental:0.1.0 --restart=Never -- bash -i;
If you don't see a command prompt, try pressing enter.
bash-4.4# curl http://echo/
Hello Docker!!

各podのログを見てみると

$kubectl logs -f echo-spring-t25sj -c echo
2019/08/04 10:11:56 start server
2019/08/04 10:17:03 received request

$kubectl logs -f echo-summer-wh7v9 -c echo
2019/08/04 10:11:58 start server

となっており、片方のpodだけにリクエストが飛ぶように設定が反映されていることがわかりました。

Ingress

ServiceをKubernetesの外へ公開する設定とHttpのルーティングの設定がIngressリソースです。

$kubectl apply -f simple-ingress.yaml
ingress.extensions/echo created
$kubectl get ingress
NAME   HOSTS              ADDRESS   PORTS   AGE
echo   ch05.gihyo.local             80      13s

これで80番ポートが外に開放され、外部からアクセスできるようです。

その他のリソース

cronとかJobとかいろいろありましたが、このへんは細かいのでしっかりアプリケーションを組む際にもっかいやります。 というわけで今回は省略。

感想

なんかkubernetesが起動しなかったり、ダッシュボードのログイン方法がわかんなかったりして時間食いましたが、なんとか動作は確認できました。

一応、コンテナ技術については、一通りかいつまんで勉強してきました。 特にKubernetesなんかは、使ってなんぼだと思いますので、頑張って使っていきたいと思います。