Kubernetes(k8s)を学ぼう!

こんにちは。KOUKIです。とある企業でWebエンジニアをしています。

最近、Kubenetes(以下k8s)を触る機会があったので、備忘を残したいと思います。

とりあえずセットアップ

公式のセットアップ手順にしたがって、minikube上でk8sを動かす環境を作成しましょう!

前提条件として、Mac環境にdockerとvirtualbox, Homebrewがインストールされている程で記載します。

以下のコマンドを実行すると、minikube上にk8sクラスタを構築します。

Dashboardの表示

minikube dashboardコマンドを実行すると、k8sのリソース情報が確認できます。

サンプルコードの実装

k8s上で動かす簡単なアプリケーションを作成します。

アプリは、Go言語で書きます。

プログラムを実行すると以下のように表示されます。

続いて、Dockerfileを書きましょう。golangのイメージは、DockerHubから確認できます。

以下のコマンドで、Dockerイメージを作成しましょう。

k8s操作 ~コマンド編~

Deploymentオブジェクトの作成

Dockerイメージを作成したので、Deploymentオブジェクトを作成しましょう。

次のコマンドを実行してください。

k8sの最小構成単位はPodになりますが、DeploymentはこのPodを管理し、Replica Setを作成して、Podのオートスケーリングを可能にします。

ステータスを確認します。

READYが、0/1になっていますね。起動に失敗しているようです。別のコマンドを実行して原因を探って見ましょう。

ErrImagePullになっていますね。ローカルで作成した「kub-first-app」をpullできていないようです。

実は、minikubeは、Virtualbox上で動作しているので、ローカルに作成したイメージを引っ張ってくることができません。

回避策は、Docker HubにイメージをPushして、そこからイメージを取得できるようにします。

私は、「kub-first-app」レポジトリを作成して、そこにイメージをPushしようと思います。

Pushが完了したらDeploymentを作り直しましょう!

今度の–imageには、DockerHubのレポジトリに格納しているイメージを指定しています。

状態を確認して見ましょう。

OKですね!

Serviceを作ろう

Deploymentを作成し、DashboardからIPアドレスを確認できるようになりました。

さぁ、アプリケーションにアクセスしよう!」という感じになるかもしれませんが、このままでは通信ができません。

アプリケーションは、Virtualboxのminikube上のクラスタで稼働しており、ローカルと通信することができないからです。

そこで、解決策としてServiceを作りましょう。

Serviceは、ClusterIP/NodePort/LoadBalancerの3つのタイプがありますが、ここではLoadBalancerを使用しています。

それぞれ違いがありますが、LoadBalancerは、L4レベルのロードバランサーを用意して、クラスタ内外に通信を可能にするサービスです。

以下のコマンドで状態を確認できます。

Serviceの稼働を確認したら以下のコマンドを使って、アプリケーションと通信してみましょう。

「http://192.168.99.100:30884/」にて、アプリケーションのURLが公開されているようですね。

Podの自動修復

次のコマンドを実行してください。

現在のステータスは、Running状態ですね。

それでは、「http://192.168.99.100:30884/error」にアクセスして、プログラムをクラッシュさせてみます。

Podのステータスを確認してみましょう。

エラーなりましたね。このまましばらく、ステータスを表示させてみます。

Error -> CrashLoopBackOff -> Runningになりましたね。

この様に、DeploymentはPodを監視しており、問題が発生した場合は自動で再起動してくれます。

オートスケール

k8sの利点の一つは、簡単にPodをオートスケールできることにあります。実際に体験してみましょう。

簡単ですね!

試しに、「http://192.168.99.100:30884/error」にアクセスして、Podを一つ機能不全にしましょう。

上記の画像は、DashboardのPodの状態を示していますが、エラーになっているPodがあっても他のPodで処理を捌けるので、アプリケーションが落ちません。

Pod数を減らしたい場合も先ほどのコマンドでPod数を指定すばOKです。

イメージの更新

k8sでは、イメージの更新も簡単です。

挙動を確認するために、Goのアプリケーションを更新してみましょう。

アプリケーションを編集できたら、次に以下のコマンドを実行します。

「kub-first-app」の名前については、k8sのDashboardの「Pod」から確認できます。

一旦画面を表示してみましょう。

変更が反映されてませんね。Tagを変更してみましょう。

今度はどうでしょうか。

変更が反映されました!どうやら同じタグの場合、k8sは新しいイメージをダウンロードしないようですね(前回ダウンロードしたイメージをそのまま使い回す)。

Tagを新しくした場合、Pull imageされている

更新するときは、Tagの更新も忘れないようにしましょう

ロールバック

イメージ更新やアプリケーションの不具合で、以前のバージョン(ロールバック)に戻したい時もあるかと思います。

例えば、存在しなイメージversion3を使って、アップデートしてみましょう。

terminationになりましたね。Dashboardからもやばげな雰囲気が伝わってきます。

このような場合は、以下のコマンドで前回のイメージに戻すことが可能です。

履歴も確認できます。

Clean Up

ここまで作成したServiceとDeploymentは、以下のコマンドで削除することができます。

k8s操作 ~コンフィグファイル編~

Deploymentファイルの作成

先ほどまではkubectlコマンドでDeploymentなどを作成してましたが、本来はコンフィグファイルを作成して、その情報からDeploymentを起動した方が便利です。

詳しくは、公式サイトを参考にしてください。

コマンドで作成したDeploymentの設定情報をyamlファイルに書き出しました。

これを以下のコマンドで読み込みます。

Serviceファイルの作成

Serviceのコンフィグファイルも作成できます。公式サイトは、こちらです。

コンフィグファイルが定義できたら以下のコマンドでServiceを立ち上げます。

無事に立ち上がってますね。次のコマンドで、アプリケーションにアクセスしてみましょう。

コンフィグファイルを設定すれば、k8sの起動がかなり楽になりますね。

オートスケールやイメージの更新

コンフィグファイルで起動したPodの数の増減をするには、コンフィグファイルを更新して、applyすればOKです。

例えば…

簡単ですね。イメージの更新もコンフィグファイルを変更するだけです。

バージョンを戻したので「This is new!」が消えている

削除

削除は、以下のようにします。

マルチプルコンフィグファイル

応用的な使い方になりますが、「—」のセパレートで分ければ同じファイルの中にServiceとDeploymentのコンフィグ情報を記載することができます。

アプリケーションにアクセスします。

クリーンアップは、以下のコマンドです。

livenessProbeで自動復旧

Podがエラーで落ちると通常は再起動しないと回復できませんが、k8sはそれを自動修復するlivenessProbeという機能を持っています。

deployment.yamlに以下の設定を追加しましょう。

上記のlivenessProbe以下が、追加した設定です。また、状態を確認するためにPodのreplicasを1にしています。

以下のコマンドでリソースを作成しましょう。

リソースが作成できたらアプリケーションにアクセスします。

「http://XXXXX/error」にアクセスするとアプリケーションが落ちる仕様なっています。

そのあと、ルートにアクセスするとアプリケーションに接続できることがわかります。

livenessProbeが設定されていない場合は、アプリケーションには接続できない状態になります。まぁ、しばらくするとmasterが修復してくれますが。。。

imagePullPolicy ~常にイメージ更新~

先の「イメージの更新」の節で説明しましたが、tag情報を変更していない場合は、k8sは既存(キャッシュされたイメージ)をそのまま使いまわします。

しかし、imagePullPolicyを設定すると「イメージタグが変更していなくてもDocker imageをpullする」挙動になります。

imagePullPolicyの対象となるのは、imageに指定されたイメージ名です。

挙動を確認してみましょう。

main.goファイルを変更します。

terminal上で以下のコマンドを打ちます。

タグを変更しなくても更新されました!

最後にclean upしておきましょう。

おわりに

k8sは、覚えるべき用語も多いので最初はかなり難しく感じると思います。

しかし、バージョンアップのしやすさ、強固な障害対応、ロードバランサによる処理の振り分けなど、なかなか面白い機能が詰まっています。

ガンガン覚えていきたいですね。

それでは、また!

次回

次回は、Volumeを学びます。

記事まとめ