Kubernetes運用前に勉強していること基礎編まとめ03-01

# Kubernetes運用前に勉強していること基礎編03-01

> **注意**  
> 本記事の内容は個人的な勉強・備忘録を目的としており、勤務先や関係者とは一切関係ありません。

---

## はじめに

Kubernetesの本番環境での運用を始めるにあたり、個人で勉強している内容を整理した記事です。構築や運用に必要な知識、注意点、実践して学んだことを随時更新していきます。基礎編の想定読者はコンテナの知識があり、Kubernetesでコンテナ運用したいがどうすればいいかを迷っている人です。今回はKubernetesのリソースカテゴリを学ぶことを目的としています。

## 勉強中の主な内容

- 基礎編
  - クラウドネイティブとは
  - Kubernetesのアーキテクチャ概要
  - <font color="Red">Kubernetesのリソース（今回の話）</font>

# Kubernetesのリソースカテゴリ

前回の記事では、Kubernetesのアーキテクチャ概要について説明しました。今回は具体的なKubernetesのリソースについて解説する。Kubernetesには多くのリソースが存在し、すべてを一度に理解することは難しいため、本記事では[『Kubernetes完全ガイド第二版』](https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-%E7%AC%AC2%E7%89%88-Top-Gear-%E9%9D%92%E5%B1%B1/dp/4295009792)で分類されているリソースカテゴリをベースに説明する。

| カテゴリ                                      | 概要                                   | 
| ------------------------------------------ | ------------------------------------ | 
| **Workload APIs**<br> | アプリケーション（コンテナ）の実行を管理するためのリソース        | 
| **Service APIs**<br> | Pod内のコンテナをネットワーク経由で公開し、アクセスを提供するリソース|
| **Config APIs**<br> | コンテナで利用する設定や機密情報を管理するためのリソース  | 
| **Storage APIs**<br> | コンテナで利用する永続化データを管理するためのリソース  | 
| **Cluster APIs**<br> | クラスタ内のリソースの運用や管理、セキュリティを制御するリソース     |
| **Metadata APIs**<br>        | クラスタ内の他リソースの操作や動的なメタデータ管理を行うリソース  |

# Workload APIs（ワークロード）

WorkloadカテゴリはPodやそれを管理するコントローラ（Deployment, StatefulSet, DaemonSet, Job, CronJobなど）を含み、コンテナ化されたワークロードのデプロイ・実行を担うオブジェクト群である。ユーザは望ましい状態（例えばPodの数や更新方法）を宣言し、Kubernetesのコントローラが実際の状態を調整（リコンシリエーション）する。下記の表では主要リソースについて説明している。

| リソース種類          | 説明とユースケース例      |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Pod**  | 最小のデプロイ単位（コンテナの集合）。単体で使うよりDeployment等で管理されることが多い  |
| **Deployment**  | ステートレスなアプリケーションの管理に使用。複数のPodレプリカを管理しローリングアップデートなどを提供する                                                     |
| **ReplicaSet**  | Deploymentから内部的に生成されるリソースで、Podの所定数維持を担う。通常は直接操作せずDeployment経由で使用する |
| **StatefulSet** | ステートフルなアプリケーションのためのリソース。各Podに安定した固有ID（ホスト名）と永続ボリュームを割り当て、順序付けたデプロイ/削除を保証する |
| **DaemonSet**   | 全て（または特定）のノード上で1つずつPodを実行するためのリソース。|
| **Job**         | 一時的なバッチ処理ジョブの実行に使用。完了すべきタスクをPodとして実行し、成功終了で完了とする  |
| **CronJob**     | 定期実行ジョブ。スケジュールに従いJobを作成する |

各リソースには上下関係があり、下記の図のような関係を持っている。

![ワークロードのリソース管理02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976553/d04b9638-b6ff-40ca-ad97-2a6a939b1c6a.png)

## Podの役割と内部アーキテクチャ

PodはKubernetesにおける最小のデプロイ単位であり、1つ以上のコンテナがストレージやネットワークを共有するグループである。単一のアプリケーションまたは関連する複数の機能を一つの単位として管理する際に使用される。Podは短命な存在であり、Pending（待機中）→ Running（実行中）→ Succeeded（正常終了）または Failed（異常終了）というライフサイクルになる。
図のようにPodは、同じノード上で稼働するコンテナ間の通信やストレージ共有（EmptyDirなど）を可能にし、密接に関連するサービスを一体的に提供する。Podには単一のネットワークインターフェース（NIC）が割り当てられ、各コンテナへのアクセスはポート番号で管理される。

![KubernetesのPodの構造と通信01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976553/a1fddfc8-1009-4676-92f6-7a0ff3e702ad.png)


### Podのデザインパターン

------
前提知識：
> 分散システム（Distributed System）とは、複数の独立したコンピュータ（ノード）がネットワークを通じて通信・協調し、一つのシステムとして機能する仕組みである。この仕組みにより、システム全体で処理を分散して効率化し、信頼性や可用性を高めることができ、シングルノードパターン（Single Node Pattern）とは、分散システムの設計において、個々のプロセスやコンポーネントを、それぞれ単一のノード上で、単独動作させる設計パターンである。これは「1つのノードに1つの主要な責務」を持たせる設計思想に基づいており、各ノードが明確に定義された機能だけを提供し、機能間の境界線が明確になるよう設計されている。
------

KubernetesにおけるPodは、シングルノードパターンの設計思想を体現しています。具体的には、1つのPodに1つの主要なアプリケーションを配置する「1 Pod 1 主機能」が推奨されており、責務が明確になっている。
複数のコンテナを同一Podに配置する場合でも、主機能のコンテナとそれを支援する補助コンテナ（Sidecar、Adapter、Ambassadorパターンなど）のように役割を明確に分けている。有名なPodのデザインパターンには主に次の3種類がある。

| デザインパターン名  | 役割                                 |
| ---------- | ---------------------------------- |
| サイドカーパターン  | メインコンテナにログ収集、メトリクス収集など補助的な機能を追加する  |
| アンバサダーパターン | Pod内部のコンテナと外部システムとの通信を代理する         |
| アダプターパターン  | Podへの外部からのアクセスを制御し、インターフェースとして機能する |

図のように、メインアプリケーションコンテナの横にログを収集するためのサイドカーコンテナを追加するケースや、外部のAPIサービスと安全に通信するためにアンバサダーコンテナを配置するケースがある。

![Kubernetes Podデザインパターン01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976553/f15d4a52-1a6b-4c79-b7b6-733a1dd532e6.png)

### PodのDNS設定（dnsPolicy）

KubernetesでPodに割り当てられるIPアドレスは、ノードのIPアドレスレンジとは異なる内部専用のレンジが使用され、通常は外部から直接アクセスできません。しかし、Podのネットワークをホストのネットワーク構成に合わせて設定することも可能です。

PodのDNS設定（dnsPolicy）には以下の4種類があります。

| 設定値 | 概要                                 |
| ---------- | ---------------------------------- |
| Default | Kubernetesクラスター内のDNS設定を継承 |
| ClusterFirst| KubernetesのDNSサービスを優先的に利用 |
| ClusterFirstWithHostNet| ホストネットワークを利用しつつClusterFirstのDNS設定を適用|
| None | 独自に設定したDNS設定を利用 |

### EKSに関する特定の事情

EKSでもPodの基本的な動作原則は標準的なKubernetesと同じですが、AWS特有の注意点がある。
* EKSのPodは、VPC内のIPアドレスが割り当てられ、AWS VPC CNIを使う場合にはVPCのIPアドレスレンジおよびENI（Elastic Network Interface）ごとのIP数に依存する
* Fargateを利用するとノードが抽象化され、DaemonSetタイプのPodを動かすことはできません。そのため、ログ収集やメトリクス収集のPodは、サイドカーや専用の収集サービスにより代替する必要がある
* EKSにおいては、Podごとに適切なリソース要求（requests）および制限（limits）を設定することが重要であり、リソース制限が設定されていないPodはノードのリソースを無制限に使用し、他のPodの動作に悪影響を与える可能性がある
* EKS環境ではPod自体は直接IAMと統合されませんが、Podに関連付けられたServiceAccountを利用してAWSリソースへのアクセス権限を制御できる（IRSA：IAM Roles for Service Accounts）ため、特定のPodのみAWSの特定のサービス（例えばS3、DynamoDBなど）にアクセス権を持たせることができ、他のPodからAWSリソースへの誤ったアクセスを防ぎ、最小特権の原則を実現できる

### セキュリティ・運用

Podのセキュリティは非常に重要であり、各コンテナに対してセキュリティコンテキスト（SecurityContext）を設定し、不必要な特権モードの有効化やホストパスへの無制限アクセスを避ける必要がある。
また、EKSを含むKubernetes環境ではPod Security（Privileged/Baseline/Restrictedモード）をNamespaceレベルで適用し、セキュリティポリシーを統一的に管理することが推奨される。さらに、Secretや機密情報は必ず暗号化やマスキングを行い、環境変数を介した機密情報の取り扱いは、ログへの出力などに特に注意する必要がある。
ネットワーク面ではNetworkPolicyを使用して、Pod間の通信を最小限に制限し、不必要なアクセス経路を遮断することがセキュリティ強化につながる。

# 個人の所感
Kubernetes（K8s）のリソースは説明が多いため、分割して説明を行います。今回は、リソースカテゴリとPodについて説明をしました。次の記事は引き続き、ワークロードの説明を行います。

# 参考文献

- [Kubernetes完全ガイド](https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-%E7%AC%AC2%E7%89%88-Top-Gear-%E9%9D%92%E5%B1%B1/dp/4295009792)
- [分散システムデザインパターン](https://www.oreilly.co.jp//books/9784873118758/)
- [Kubernetesパターン](https://www.oreilly.co.jp/books/9784814400881/)