😇

Kindを利用したクラスター環境でK8s Podを起動

2023/04/16に公開

はじめに

  • AWSのVM内で以下のアプリケーションをインストールし、Kindを利用してK8sクラスターを構築する。
    • docker, kubectl, Kind
  • nginxのPodをデプロイした後、内部公開するまで実践し、K8s環境での環境構築がどのようなものであるか、把握することを目的とする。
  • 起動したPodをServiceでまとめること等により、複数のPodを統合して管理できることがわかる。1つのPodがdeleteされても、再度Podが自動作成されて、サービスを継続することができる。
  • サービス提供者は、設定ファイル(マニフェスト)にサービス継続のためのあるべき状態を記述し、Kindはそれを実現しようと動作するため、運用をよしなに任せることが出来る。Kindを利用することで、ローカル環境でKubernatesクラスタを作成できる。
  • 但し、ログ吐き出し等のディスク領域不足による起動不可等、Podが起動できなくなる状態や、起動しているが、Pod上のアプリケーションがおかしい状態等、アプリケーションレイヤで異常が発生している場合は検知できないため、アプリケーション監視や、スケールの監視は必要である認識。

クラスター実行環境構築

  • ホストOS
# cat /etc/system-release
Amazon Linux release 2 (Karoo)
  • dockerインストール
    • yum経由でパッケージインストールして、自動起動を有効化
# yum update -y
# yum install docker
# amazon-linux-extras | grep docker
 20  docker=latest            enabled      \
# systemctl start docker
# systemctl status docker
# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
# systemctl is-enable docker
Unknown operation 'is-enable'.
# systemctl is-enabled docker
enabled
  • kubectlをインストール
    • バイナリファイルを取得して、実行権を付与。
# curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
# chmod +x kubectl
# mv kubectl /usr/local/bin/
# kubectl version
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.  Use --output=yaml|json to get the full version.
Client Version: version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.1", GitCommit:"8f94681cd294aa8cfd3407b8191f6c70214973a4", GitTreeState:"clean", BuildDate:"2023-01-18T15:58:16Z", GoVersion:"go1.19.5", Compiler:"gc", Platform:"linux/amd64"}
Kustomize Version: v4.5.7
Server Version: version.Info{Major:"1", Minor:"25", GitVersion:"v1.25.3", GitCommit:"434bfd82814af038ad94d62ebe59b133fcb50506", GitTreeState:"clean", BuildDate:"2022-10-25T19:35:11Z", GoVersion:"go1.19.2", Compiler:"gc", Platform:"linux/amd64"}
  • kindインストール
    • 同様にバイナリをダウンロードし、実行権を付与。
# curl -Lo ./kind https:/kind.sigs.k8s.io/dl/v0.17.0/kind-linux-amd64
# chmod +x ./kind
# mv ./kind /usr/local/bin/kind
# kind version
kind v0.17.0 go1.19.2 linux/amd64
  • kind経由でクラスター作成
# kind create cluster
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.25.3) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind
  • kind-control-planeがKubernetesのcontrol-planeとして起動したことが確認できる。
    • デフォルトではシングルノードのクラスターして起動する。設定ファイルに指定することでマルチノードのクラスター化を指定することもできるが、今回は起動すればOK。
# kubectl cluster-info --context kind-kind
Kubernetes control plane is running at https://127.0.0.1:36025
CoreDNS is running at https://127.0.0.1:36025/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

# kubectl get nodes -o wide
NAME                 STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION                CONTAINER-RUNTIME
kind-control-plane   Ready    control-plane   56d   v1.25.3   172.18.0.2    <none>        Ubuntu 22.04.1 LTS   5.15.90-54.138.amzn2.x86_64   containerd://1.6.9

クラスター上にnginxのPodをデプロイ

  • Podを動作させるクラスター基盤が完成したので、nginxのPodをデプロイする。
    • deploymentコントローラ名nginxでPodを起動する。
  • IPアドレス10.244.0.13を持ったnginxのPodが起動したことが確認できる。
# kubectl get po -o wide
No resources found in default namespace.
# kubectl create deploy nginx --image=nginx:1.23.3
deployment.apps/nginx created
# kubectl get po -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE                 NOMINATED NODE   READINESS GATES
nginx-6495f4c786-v8l5p   1/1     Running   0          25s   10.244.0.13   kind-control-plane   <none>           <none>
  • シングルノードのクラスターとしてPodは起動しているため、削除してもあるべき状態(=シングルノードで起動している状態、Podは常に1起動している状態)に収束する。
  • 設定ファイルであるべき状態を定義した上で、その状態をK8sが自動的に維持するようにする手法は宣言的APIと呼ばれる。
    • 削除しても、再度Podが立ち上がっているため、NAME, IPアドレスが変わっている。
    • なので、常にPodが1つ立ち上がる状態となる、それはどう頑張ってもPodが削除できない状態であるとも言える。
# kubectl delete po nginx-6495f4c786-v8l5p
pod "nginx-6495f4c786-v8l5p" deleted
# kubectl get po -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE                 NOMINATED NODE   READINESS GATES
nginx-6495f4c786-wwvs7   1/1     Running   0          5s    10.244.0.14   kind-control-plane   <none>           <none>
  • どのように削除するかというと、deploymentコントローラを削除することでPodの削除が可能となる。
# kubectl get deployment -o wide
NAME    READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES         SELECTOR
nginx   1/1     1            1           7m1s   nginx        nginx:1.23.3   app=nginx
# kubectl delete deployment nginx
deployment.apps "nginx" deleted
# kubectl get po -o wide
No resources found in default namespace.

Serviceを使ってnginxを内部公開

  • nginx用のServiceを作成する。
  • Serviceを作成することによって、上記のようにPod再作成がおこっても、ServiceにアサインされるClusterIPでアクセスするため、同じIPもしくはService名経由でアクセスし続けることが可能となる。
# kubectl expose deploy nginx --port 80
service/nginx exposed
# kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   56d
nginx        ClusterIP   10.96.137.213   <none>        80/TCP    3m23s
  • Serviceを作成すると仮想IP(ClusterIP)はアサインされる。
  • 恒久的にアサインされたIPアドレス「10.96.137.213」でアクセスすれば良い。

内部公開したnginxにクライアントからアクセス

  • クライアントとしてcurlをキックするためのPodをdeployment名nginx-clientとしてデプロイする。(curlがキックできれば何でもよい)
# kubectl create deploy nginx-client --image=nginx:1.23.3
deployment.apps/nginx-client created
# kubectl get po -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP            NODE                 NOMINATED NODE   READINESS GATES
nginx-6495f4c786-6xjqj          1/1     Running   0          45m     10.244.0.15   kind-control-plane   <none>           <none>
nginx-client-75749dcb46-z9zwv   1/1     Running   0          4m46s   10.244.0.16   kind-control-plane   <none>           <none>
  • nginx-clientのPodより、ClusterIPもしくはService名経由でアクセスしレスポンスを確認する。
# kubectl exec -it nginx-client-75749dcb46-z9zwv -- curl http://10.96.137.213/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

# kubectl exec -it nginx-client-75749dcb46-z9zwv -- curl http://nginx/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

まとめ

  • VM1台用意すれば上記のようにK8sのマイクロサービスの動作は確認できるので、次はアプリケーションの改修を具体的にどのように実践するか含めて確認したい。
    • アプリケーション改修する手順を検討する。今回はデプロイ時にイメージを指定(--image=nginx:1.23.3)したが、自リポジトリの場合はどのようにするべきか等。
  • (VM1台あればK8sマイクロサービスの動作ロジック確認できるなんで、良い時代になったなあ、なんて思っていたら、WebAssemblyのFaaSの流れきてるし、いよいよおじさん世代はついていけなくなるのであろうか。)

Discussion