🐡

ゼロからわかるKubernetes 2章(Pod, PVC編)

2024/04/26に公開

1章の続きです
https://zenn.dev/macori/articles/a3344cc9212ae8

Podについての概要

Podとはコンテナ群の仕様を記述するリソースです。コンテナを起動するためにデプロイ可能な最小単位のリソースと覚えておくと良いかと思います。複数のサービスを同一のPodに含めることもできます。
マニフェストファイル(yaml)に仕様を記載して、applyすることで、設定できます。

Podで何ができるの?

基本的には上述の内容通りです。とあるサービスをデプロイして、そのサービスのログを別のプログラムで取得したい、という場合に、1つのPodにまとめてデプロイや管理が可能です。
ただし注意点として、複数のPodをデプロイしまくって管理の手間が増える、という状況は避けましょう。(このように複数Podを管理するときは3章で説明するReplicaSetを使います)

で、動かすには何をすればいいの?

まずはマニフェストファイルを作り、その中に仕様を記述します。

Pod_example.yaml
apiVersion: v1 # k8sAPIのバージョンを指定
kind: Pod # リソースの種類を指定(今回はPod)
metadata:
  name: xxxxx # 一意なリソースの名前
  namespace: yyyyy # Podが所属するnamespaceを指定
spec: # 実際にPodの仕様を定義するセクション
  containers: # Pod内で実行されるコンテナのリストが以下に記述される
  - name: xxxxx # コンテナ名
    image: docker .io/library/xxxxx # コンテナのイメージを指定(ここではDocker Hubから取得)
    ports: # コンテナがリッスンするポートのリストを記述
    - containerPort: 8080 # コンテナのポート

他にも記述方法はたくさんあるので、適宜調べつつやるのが吉です。

マニフェストファイルを作成し、保存したら、以下のコマンドで適用させます。
引数fにはPodの名前を、引数nにはnamespaceの名前を渡してあげます。

kubectl apply -f Pod_example.yaml -n yyyyy

デプロイしたら、以下のコマンドで確認できます。

kubectl get pods -n yyyyy

また、Podだけでなくnamespaceなども含めて、以下のようにcreateコマンドでもリソースを作成できます。が、マニフェストファイルを作成する方が断然楽、かつ正確なので非推奨です。

kubectl create pods

Podを間違って作った、はじめから作り直したいという場合は、以下のように削除できます。

kubectl delete -f /hoge/fuga/Pod_example.yaml

Podをデプロイした後でちょっとだけ編集したい、という場合には、以下の手順のようにvimで編集可能です。

cat /hoge/fuga/Pod_example.yaml
vi /hoge/fuga/Pod_example.yaml
kubectl apply -f /hoge/fuga/Pod_example.yaml

また、k8s上の環境に入るには、以下のexecコマンドを使用します。

kubectl -n yyyyy exec -it xxxxx -- /bin/bash
kubectlコマンドが使えないとき

「kubectlコマンドが使えない!」という場合は以下の手順でインストールできます。

  • Homebrewのインストール(https://brew.sh/ja/)

  • 環境に応じてPathも設定します

  • kubectlのインストール

    brew install kubectl
    
  • インストールされているかのバージョン確認

    kubectl version --client
    

PVCについての概要

PVCとはPersistent Volume Claimです。直訳すると永続的・持続的なボリューム要求書です。
つまり、PVCとはk8s上で持続的(Persistent)にデータを保持するための要求書や仕様書のことを意味します。

PVCは何のためのもの?

通常、Pod内に持っているデータは、Podを一度削除すると同時に消えてしまいます。しかし、PVCによってPV(Persistent Volume)を定義しておくことで、Podが削除されてもデータを保持できます。
PVにデータを保持しておくと、Podのライフサイクルやクラスタの状態に依存しない(疎結合)状態を保てます。この、PVを作成するためにPVCを作成し、applyするのです。

ここで、まだ説明していない種類のリソースも含みますが、他のリソースとPVCの関連性についても説明します。

  • Namespace
    • PVCはNamespaceに属する
    • 他のNamespaceからアクセスするには別のストレージを使うなどする必要がある
  • Pod
    • PodはPVCを利用して特定のPVにアクセスする
    • Pod定義内にはPVCへの参照を記載する
  • ReplicaSet
    • 複数Podで同一のPVCを共有する場合は同時書き込みによる矛盾に注意
    • なので基本的には1Podにつき、1PVC

今の時点では、「へーそうなんだあ」くらいで大丈夫です。ただし、「Pod定義内にはPVCへの参照を記載する」は覚えておいてください。

中身は何て書けば良いの?

では実際にPVCの中身にはどんなことを書けば良いか説明します。Podと同じくマニファストファイルで記載しますし、書き方も似ています。以下が実際の例です。

PVC_example.yaml
apiVersion: v1
kind: PersistentVolumeClaim # リソースの種類を指定
metadata:
  name: xxxyyy # xxxyyyという名前でPVCを作成
  namespace: yyyyy  # namespaceを指定
spec:
  accessModes:
    - ReadWriteOnce # 書き込みの制限(制限しない場合はReadWriteMany)
  resources:
    requests:
      storage: 10Gi # ストレージのサイズを指定

最も注意すべき点はaccessModesかなと思います。機械学習や深層学習のプログラムを回して、何度か違う内容で上書きするときに、ReadWriteOnceで制限しているとエラーが起きる可能性もあります。
また、ストレージサイズも、環境や一緒に作業している人と相談して決めましょう。

適用したPVCは以下のコマンドで確認できます。

kubectl get pvc -n yyyyy

それでは最後に、上記のPVCの内容への参照を定義したPodのマニフェストファイルを記載します。

Pod_example.yaml
apiVersion: v1
kind: Pod
metadata:
  name: xxxxx
  namespace: yyyyy
spec:
  volumes:  # ボリュームの定義を追加
    - name: my-storage  # ボリュームの名前
      persistentVolumeClaim:
        claimName: xxxyyy  # 以前に定義したPVCの名前を参照
  containers:
    - name: xxxxx
      image: docker.io/library/xxxxx
      ports:
        - containerPort: 8080
      volumeMounts:  # コンテナにボリュームをマウントする
        - name: my-storage  # 上で定義したボリューム名
          mountPath: "/data"  # コンテナ内のマウントポイント

主にspec > volumes と、spec > containers > volumeMountsの記載が増えています。
マウントパスに指定したディレクトリ以下にPVが作成されます。なので、保存しておきたいデータ(機械学習のモデルなど)はこのパス以下に保存しておきます。

次回は、複数のPodを管理するためのReplicaSetとDeploymentについて解説します。

Discussion