🤖

kubernetesの基礎を学ぼう!~第3章 Config, Storage API~

2024/01/31に公開

こんにちは!ヒロケイと申します!

ここ最近kubernetesに興味を持ち始め、基礎知識を蓄えてきました。

そこで、本シリーズからkubernetesの概要について、Dockerをほんのちょっと触ったことがある初学者でも分かるように解説していきます。

本シリーズでは特に、Kubernetesが提供しているAPIリソースでできることを網羅していきます。

以下のような読者を想定しています。

想定する読者

  • コンテナ技術については知っているが、複数のコンテナを管理、運用する方法を探している方
  • Kubernetesについて勉強したいけど、何から始めれば良いかわからない方
  • 公式ドキュメントや技術書を読むのが面倒くさくて、全体像を掴みたい方
    Dockerを使って開発環境を整えたりした経験があれば、難なく読み進められるかと思います。

このシリーズでKubernetesでできることについて大枠を理解していただき、公式ドキュメントや技術書、勉強会での理解のサポートができればとても嬉しく思います!

第1章~第4章まで理解すると得られるもの

  • Kubernetesを使うとできることの半分くらいが理解できる
  • 技術イベントや勉強会で出てくる言葉の意味を理解でき、内容が大体理解できるようになる。
  • PIリソースの全体像を掴むことができる

扱わないテーマ

  • kubernetes環境を構築する方法
  • コンテナオーケストレーションを実現する上でのテクニック
  • kubernetesが提供する詳細な機能
    こちらはKubernetesの基礎を学ぼう!の第3章です。

前回の記事はこちらからご覧ください。
https://zenn.dev/keigo_hirohara/articles/26885f9d9251af

Config, Storage API


まず、この記事で紹介するAPIの概要についてご紹介します。
Config, Storage APIの役割は、クラスタの細かい設定をするというものです。
WorkloadやService APIに関する設定や機密情報、データの永続化に使われます。
有するリソースは、

リソース名 機能
Secret 機密情報や認証情報などの秘密データを安全に格納
ConfigMap キーと値のペアで実行環境における設定値を格納
PersistentVolumeClaim Pod出管理する情報を永続化

です。

【基本】Podへ環境変数を設定する。

Config, Storage APIはリソースに情報を設定できるというものです。
まず前提として、Podへ情報を設定する方法の基本を学んでいきましょう。
こちらがサンプルマニフェストです。
Dockerにおけるコンテナやイメージに環境変数を渡せたように、Podにも設定することができます。

pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
    - name: myapp-container
      image: nginx
      env:
        - name: DATABASE_HOST
          value: "mysql.example.com"
        - name: DATABASE_PORT
          value: "3306"

nginxのPodを定義し、データベースと接続するためのHostとPortを環境変数に設定しています。
では、次のような状況になったとき、どうすれば良いのでしょうか?

  • 同じ設定値を複数のリソースに設定したい。
  • 大量(10個以上)の設定値を扱いたい。
  • AWS Seacrets Managerで管理するような機密性の高い情報を設定したい。

そんな時に使われるのが、Config, Storage APIです。
それぞれのリソースについて詳しく見ていきましょう。

Secret


まずはSecretです。
Secretは、機密情報や認証情報などの秘密データを安全に格納するためのリソースです。
例えば

  • データベースのユーザー名、パスワード
  • 外部のAPIに接続するためのAPIキーやトークンなど
  • SSH接続するための秘密鍵情報
    などがあります。

Podの環境変数として設定するのと何が違う?

もちろん、Podの環境変数として機密性の高い情報をセットすることも可能です。
しかし、Secretを使うことで、以下のようなことが可能になります。

  • 情報が暗号化された状態で保存することができる。
  • クラスタ内でのアクセス制御ができる(PodAはアクセス可、Bは不可といった具合)
    通常の環境変数は平文であり、セキュリティリスクを引き起こす可能性があります。
    セキュリティを意識したクラスタを作ろうとなった時に必要になるものですね!

作ってみる

では、実際にSecretの情報をPodに設定してみましょう!

secret.yaml
// Secretの定義
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
stringData:
  username: my-username
  password: my-password

---
// Podの定義
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
    - name: myapp-container
      image: nginx
      env:
        - name: USERNAME
          valueFrom:
            secretKeyRef:
              name: my-secret
              key: username
        - name: PASSWORD
          valueFrom:
            secretKeyRef:
              name: my-secret
              key: password
$ kubectl apply -f ./secret.yaml
secret/my-secret created
pod/myapp-pod created

// Pod内でコマンド実行すれば見れる!良いね!
$ kubectl exec -it myapp-pod -- env
~~~~
USERNAME=my-username
PASSWORD=my-password
~~~~

// もちろんSecretに設定された値は暗号化されている!良いね!
kubectl get secret my-secret -o yaml
~~~~
data:
  password: bXktcGFzc3dvcmQ=
  username: bXktdXNlcm5hbWU=
~~~~

ConfigMap


次に、ConfigMapです。
ConfigMapはキーと値のペアで構成され、アプリケーションが実行される環境における構成パラメータや設定値を格納するのに使用されます。
具体的な使用例としては、

  • データベース、外部サービスのホスト
  • 機密性のない環境変数(ポートとかフラグとか)
  • PodやServiceのリソース(CPUやメモリ)の制限値

があります。

Podの環境変数として設定するのと何が違う?

では、PodとConfigMapに環境変数を設定するのでは、どんな違いがあるのでしょうか?
ConfigMapを使うことで、以下のようなメリットがあります。

  • 設定に分離によって、複数のリソースで同じ設定値を共有できる→管理が楽!
  • 動的に値を更新できるので、設定先のリソースを再起動する必要なし→可用性良いね!
  • 環境変数の管理という一つの責務を任せられる→マニフェスト見やすい!

これらのメリットがあります。
(個人的には動的に値が更新できるところがすごいと思いましたw)

作ってみる

実際にConfigMapの情報をPodに設定してみましょう!

configmap.yaml
// ConfigMapの定義
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-configmap
data:
  my-key: my-value

---
// ConigMapの定義
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
    - name: myapp-container
      image: nginx
      env:
        - name: MY_ENV_VAR
          valueFrom:
            configMapKeyRef:
              name: my-configmap
              key: my-key

$ kubectl apply -f ./configmap.yaml
configmap/my-configmap created
pod/myapp-pod created

$ kubectl exec -it myapp-pod -- env
~~~~
MY_ENV_VAR=my-value
~~~~

PersistentVolumeClaim


最後に紹介するのが、PersistentVolumeです。
機能は、Podに保存するデータを永続化することができます。
PersistentVolumeClaimを使用することで、Podを再起動しても保存したデータが残ってくれているわけですね!

作ってみる

では実際に、PersistentVolumeClaimを定義してデータを永続化してみましょう!

pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  volumes:
    - name: myvolume
      persistentVolumeClaim:
        claimName: mypvc
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: myvolume
$ kubectl apply -f ./pvc.yaml
persistentvolumeclaim/mypvc created
pod/mypod created

$ kubectl exec -it mypod -- /bin/bash
root@mypod:/# echo "Hello, Persistent Storage!" > /usr/share/nginx/html/file.txt

// Podを再起動する
$ kubectl delete pod mypod && kubectl apply -f ./pvc.yaml
pod "mypod" deleted
pod/mypod created

// 再起動前に作ったファイルがまだある!
$ kubectl exec -it mypod -- /bin/bash
root@mypod:/# cat /usr/share/nginx/html/file.txt
Hello, Persistent Storage!

まとめ

いかがでしたでしょうか?

Config, Storage APIがないとクラスタが作れないわけではないですが、実務レベルになってくると重要になってくるリソースです!

次回は、Service APIです。
Podのネットワークを構築するために必要なAPIですので、ぜひ読んでみてくださいね!
kubernetesの基礎を学ぼう!~第2章 Service API~

Discussion