とほほのKubernetes入門

目次

Kubernetesとは

Kubernetes の構築には通常1台のマスターサーバ、3台以上のノードサーバが必要ですが、学習用にに1台のサーバ上で Kubenetes を動かすことができる Minikube が提供されています。また、Hello Minikube ではブラウザから学習用の Minikube 環境にアクセスすることも可能です。以後の説明ではローカルの1台の VM に Minikube をインストールして使用する流れを説明します。

インストール

下記に従って Minikube をインストールします。選択肢は [Linux] [x86-64] [Stable] [Binary download] を選択します。

Minikube をインストールするには下記のスペックが必要ですが、最低スペックだとちょっと辛いかも。

CPU:2個以上
メモリ:2GB以上
ディスク:20GB以上

今回は VirtualBox 上の Rocky Linux 8.6 の VM に Minikube をインストールしてみました。

ハイパーバイザ:VirtualBox 6.1.40
ホストOS:Windows 10
ゲストOS:Rocky Linux 8.6
  CPU:8CPU
  メモリ:8GB
  ディスク:100GB
  コンテナエンジン:Podman v4.2.0
  Minikube:minikube v1.28.0
  Kubenetes: Kubenetes v1.25.3
# dnf -y install podman
# curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
# sudo install minikube-linux-amd64 /usr/local/bin/minikube
# useradd yamada
# visudo
# 末尾に下記を追加
yamada ALL=(ALL) NOPASSWD: /usr/bin/podman
# su - yamada
$ echo 'alias kubectl="minikube kubectl --"' >> ~/.bashrc
$ source ~/.bashrc
$ minikube version
$ kubectl version

クラスタ(Cluster)

クラスタ は Kubernetes の実行環境です。クラスタは、制御サーバである マスター と実行サーバである複数台の ノード から構成されます。minikube では 1台のホストにマスターと1台のノードが同居しています。下記コマンドでクラスタを作成します。「Error downloading kic artifacts: not yet implemented, see issue #8426」のエラーが出ることがありますが無視してもよいようです。

$ minikube start

下記コマンドでクラスタの状態を確認できます。

$ minikube status
$ kubectl cluster-info

デプロイメント(Deployment)

Deployment は Kubernetes で管理するアプリケーションの単位です。例えば Nginx v1.22.1 アプリケーションを test-app という名前で作成してみましょう。

$ kubectl create deployment test-app --image=docker.io/nginx:1.22.1
deployment.apps/test-app created

下記で Deployment の一覧や詳細を表示することができます。

$ kubectl get deployments
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
test-app   1/1     1            1           100s
$ kubectl describe deployment/test-app
Name:                   test-app
Namespace:              default
  :

ポッド(Pod)

Deployment が作成されると、アプリケーションを実行するノードが自動的に選択(スケジュール)され、実行されます。この実行の単位を Pod と呼びます。

$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
test-app-67f5d58b6-jqzvw   1/1     Running   0          43s
$ kubectl describe pods/test-app-67f5d58b6-jqzvw
Name:             test-app-67f5d58b6-jqzvw
Namespace:        default
  :

可用性や性能を考慮してひとつの Deployment を複数の Pod で実行することもできます。Pod は適切なノードに配布され、実行されます。ノードがダウンすると Kubernetes が検知し、代わりに別のノードで Pod を実行させます。

$ kubectl scale deployments/test-app --replicas=4
deployment.apps/test-app scaled
$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
test-app-67f5d58b6-5l9ph   1/1     Running   0          7s
test-app-67f5d58b6-bvndt   1/1     Running   0          7s
test-app-67f5d58b6-jfwcq   1/1     Running   0          7s
test-app-67f5d58b6-jqzvw   1/1     Running   0          2m7s

サービス(Service)

アプリケーション(Deployment)を外部に公開するには Service を作成します。Service の公開方法には下記などがあります。

下記では NodePort を用いてサービスを公開する方法を示します。

$ kubectl expose deployment/test-app --type=NodePort --port 80
service/test-app exposed
$ kubectl get services
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        24m
test-app     NodePort    10.104.214.208   <none>        80:31829/TCP   10s
$ kubectl describe service/test-app
Name:                     test-app
Namespace:                default
  :
$ kubectl port-forward service/test-app --address=0.0.0.0 8080:80
Forwarding from 0.0.0.0:8080 -> 80

別端末から下記にアクセスすると Nginx 1.22.1 にアクセスできていることが確認できます。

$ curl -i http://localhost:8080/
HTTP/1.1 200 OK
Server: nginx/1.22.1

ローリングアップデート

Kubernetes を用いると、サービスを停止することなく、複数台稼働している Pod をひとつずつアップデートしていくことができます。下記の例では、Nginx のバージョンを 1.22.1 から 1.23.2 にバージョンアップしています。

$ kubectl set image deployments/test-app nginx=docker.io/nginx:1.23.2
deployment.apps/test-app image updated
$ kubectl get pods
NAME                        READY   STATUS              RESTARTS   AGE
test-app-674b5f97fb-cj5j6   0/1     ContainerCreating   0          7s
test-app-674b5f97fb-dpksg   0/1     ContainerCreating   0          7s
test-app-67f5d58b6-5l9ph    1/1     Running             0          112s
test-app-67f5d58b6-jfwcq    1/1     Running             0          112s
test-app-67f5d58b6-jqzvw    1/1     Running             0          3m52s
$ kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
test-app-674b5f97fb-cj5j6   1/1     Running   0          34s
test-app-674b5f97fb-dpksg   1/1     Running   0          34s
test-app-674b5f97fb-fmxmb   1/1     Running   0          19s
test-app-674b5f97fb-lhvgv   1/1     Running   0          15s

下記にアクセスすると、1.23.2 にバージョンアップできていることが確認できます。

$ curl -i http://localhost:8080/
HTTP/1.1 200 OK
Server: nginx/1.23.2

ロールバック

アプリケーションのバージョンを 1.100 にあげてみましょう。Nginx に 1.100 というバージョンのタグは存在しないため、イメージを pull することができず、Pod 状態が ErrImagePull や ImagePullBackOff となります。

$ kubectl set image deployments/test-app nginx=docker.io/nginx:1.100
deployment.apps/test-app image updated
$ kubectl get pods
NAME                        READY   STATUS         RESTARTS   AGE
test-app-5b557ddb96-5fkk5   0/1     ErrImagePull   0          8s
test-app-5b557ddb96-8wnj8   0/1     ErrImagePull   0          8s
test-app-674b5f97fb-cj5j6   1/1     Running        0          3m3s
test-app-674b5f97fb-dpksg   1/1     Running        0          3m3s
test-app-674b5f97fb-lhvgv   1/1     Running        0          2m44s

上記の様にリリースに失敗した場合は、下記の様にロールバックして元のバージョンに戻すことができます。

$ kubectl rollout undo deployments/test-app
deployment.apps/test-app rolled back
$ kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
test-app-674b5f97fb-cj5j6   1/1     Running   0          6m45s
test-app-674b5f97fb-dpksg   1/1     Running   0          6m45s
test-app-674b5f97fb-lhvgv   1/1     Running   0          6m26s
test-app-674b5f97fb-wxsrt   1/1     Running   0          3s

その他いろいろ

Minikubeのメモリを増やす

Minikube 環境はデフォルトで 2GB のメモリが割り当てられますが不足することがあります。minikube start する前に下記を実行することで使用するメモリを増やすことができます。

$ minikube config set memory 4096
$ minikube config view
- memory: 4096

Kubernetes APIにアクセスする

# APIアクセスのためのプロキシを起動する
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
# 別端末でAPIにアクセス
$ curl http://127.0.0.1:8001/version

イメージの一覧を表示する

$ minikube image ls

Minikubeのログを表示する

$ minikube logs

Podのログを表示する

$ kubectl logs test-app-674b5f97fb-cj5j6

Podにシェル接続する

$ kubectl exec -it test-app-674b5f97fb-cj5j6 -- /bin/bash

Podにラベルをつける

# Podにラベルを設定する
$ kubectl label pods test-app-674b5f97fb-cj5j6 foo=baa
pod/test-app-674b5f97fb-cj5j6 labeled
# ラベルを確認する
$ kubectl describe pod/test-app-674b5f97fb-cj5j6
Labels:           app=test-app
                  foo=baa
                  pod-template-hash=674b5f97fb
# ラベルを指定してPod一覧を得る
$ kubectl get pods -l foo=baa
NAME                        READY   STATUS    RESTARTS   AGE
test-app-674b5f97fb-cj5j6   1/1     Running   0          107m
# ラベルを削除する (ラベル名の後ろにハイフンをつける)
$ kubectl label pods test-app-674b5f97fb-cj5j6 foo-
pod/test-app-674b5f97fb-cj5j6 unlabeled

minikubeコマンド

minikube は下記のコマンドをサポートしています。詳細は minikube コマンド名 --help を参照してください。

# 基本コマンド
minikube start		# クラスターを起動
minikube status		# クラスター状態を表示
minikube stop		# クラスターを停止
minikube delete		# クラスターを削除
minikube dashboard	# クラスターのダッシュボードにアクセス
minikube pause		# Kubernetes を一時停止
minikube unpause	# Kubernetes を再開

# イメージ関連
minikube docker-env	# Dockerを使用する手順を表示
minikube podman-env	# Podmanを使用する手順を表示
minikube cache		# イメージキャッシュを操作
minikube image		# イメージを操作

# コンフィグレーション
minikube addons		# アドオンを管理
minikube config		# コンフィグ値を管理
minikube profile	# プロファイルを表示
minikube update-context	# IPアドレス・ポート番号変更時に Kubernetes を更新

# ネットワークと接続
minikube service	# サービスに接続するためのURLを表示
minikube tunnel		# LoadBarancerサービスに接続

# アドバンスドコマンド
minikube mount		# minikubeにディレクトリをマウント
minikube ssh		# minikubeにSSHログイン
minikibe kubectl	# kubectlを実行
minikube node		# ノードを管理
minikube cp		# minikubeにファイルをコピー

# トラブルシューティング
minikube ssh-key	# 指定ノードのSSH鍵パスを表示
minikube ssh-host	# 指定ノードのSSHホスト鍵を取得
minikube ip		# 指定ノードのIPアドレスを表示
minikube logs		# デバッグログを表示
minikube update-check	# minikubeの最新バージョンを表示
minikube version	# minikubeのバージョンを表示
minikube options	# minikubeのオプションを管理
minikube license	# ライセンスを表示

# その他
minikube completion	# シェル補完用コードを生成

kubectlコマンド

kubectrl は下記のコマンドをサポートしています。

# ヘルプ
kubectl --help		# kubectlのヘルプを表示
kubectl command --help	# 指定したコマンドのヘルプを表示

# 表示
kubectl cluster-info	# クラスター情報を表示
kubectl get pods	# Pod一覧を表示
kubectl get nodes	# ノード一覧を表示
kubectl get deployments	# Deployment一覧を表示
kubectl get services	# サービス一覧を表示

# 基本コマンド(初級)
kubectl create		# Deploymentなどのリソースを作成
kubectl expose		# サービスを公開
kubectl run		# 指定したイメージをクラスターで実行
kubectl set		# 指定した機能をオブジェクトに設定

# 基本コマンド(中級)
kubectl explain		# リソースに関するドキュメントを表示
kubectl get		# リソースを表示
kubectl edit		# リソースを編集
kubectl delete		# リソースを削除

# デプロイコマンド
kubectl rolloout	# ローリングアップデート
kubectl scale		# スケールアップ/スケールダウン
kubectl autoscale	# オートスケール

# クラスター管理
kubectl certificate	# 証明書を管理
kubectl cluster-info	# クラスター情報を表示
kubectl top		# リソースの利用状況(上位)を表示
kubectl cordon		# ノードをスケジュール不可状態にする
kubectl uncordon	# ノードをスケジュール可能状態にする
kubectl drain		# ノードをメンテナンスモードにする
kubectl taint		# ノードにスケジュール制御のためのTaintを設定/設定解除

# トラブルシュートとデバッグ
kubectl describe	# リソースの詳細を表示
kubectl logs		# Podのログを表示
kubectl attach		# コンテナにアタッチ
kubectl exec		# コンテナでコマンドを実行
kubectl port-forward	# ポートフォワード
kubectl proxy		# Kubernetes API Serverへのプロキシを起動
kubectl cp		# コンテナとのファイルコピー
kubectl auth		# 認可検査
kubectl debug		# デバッギングセッションを作成

# アドバンスドコマンド
kubectl diff		# 現バージョンと新バージョンの差異を表示
kubectl apply		# コンフィグレーション情報をリソースに設定
kubectl patch		# リソースの一部を変更
kubectl replace		# リソースを置換
kubectl wait		# リソースの状態待ち
kubectl kustomize	# カスタマイズターゲットを生成

# セッティングコマンド
kubectl label		# リソースにラベルを設定
kubectl annotate	# リソースのアノテーションを設定
kubectl completion	# シェル補完用コードを生成

# その他コマンド
kubectl alpha		# アルファバージョンのコマンドを表示
kubectl api-resources	# リソース種別の一覧を表示
kubectl api-versions	# APIバージョンを表示
kubectl config		# コンフィグ管理
kubectl plugin		# プラグインを管理
kubectl version		# kubectlのバージョンを表示