KubernetesとAWSサービスを使用するチュートリアル
目次
- はじめに
- AWSにおけるKubernetes(Amazon EKS)
- Kubernetesの基本コンポーネント
- AWSサービスとの統合
- 実践チュートリアル:EKS, RDS, S3, IAMの統合
- トラフィックのルーティングとネットワーク
- Pod内のコンテナ間の通信
- 質疑応答
- 終わりに
はじめに
Kubernetes(K8s)の基本
Kubernetes(K8s)は、コンテナ化されたアプリケーションのデプロイ、スケーリング、および運用を自動化するオープンソースのプラットフォームです。K8sによって、アプリケーションはスケーラブルで耐障害性があり、デプロイメントが容易になります。
AWSサービスの概要
AWS(Amazon Web Services)は、Amazon.comが提供するクラウドコンピューティングプラットフォームです。本チュートリアルでは、Amazon EKS, Amazon RDS, Amazon S3, Amazon IAMなどのサービスを利用します。
AWSにおけるKubernetes(Amazon EKS)
Amazon EKSの利点
Amazon EKS(Elastic Kubernetes Service)は、AWSが提供するマネージドKubernetesサービスです。以下に、EKSを使用する利点を挙げてみましょう。
- 完全にマネージドされたKubernetesコントロールプレーン
- AWSリソースとの統合が容易
- セキュリティとコンプライアンスの要求に対応
Amazon EKSの構成
Amazon EKSのクラスタは、コントロールプレーンとワーカーノードで構成されます。コントロールプレーンはAWSが管理し、ワーカーノードはユーザーが管理します。
-- 以下補足 --
コントロールプレーン
コントロールプレーンは、Kubernetesクラスタの管理と制御を行います。コントロールプレーンの主要なコンポーネントには以下のものが含まれます。
-
kube-apiserver
- クラスタのAPIサーバで、ユーザーやシステムコンポーネントとやりとりを行います。
-
etcd
- クラスタの状態を保持するための軽量な分散データストアです。
-
kube-scheduler
- Podをノードにスケジューリング(割り当て)するコンポーネントです。
-
kube-controller-manager
- クラスタ内の様々なコントローラを実行するコンポーネントです。コントローラは、クラスタの状態を監視し、必要に応じて変更を加えます。
-
cloud-controller-manager
- クラウドプロバイダーと連携し、クラウドプロバイダーのAPIを使用して基盤を管理します。
ワーカーノード
ワーカーノードは、アプリケーションのコンテナが動作するノードです。ワーカーノードは、クラスタ内でのワークロードの実行を担当します。主なコンポーネントは以下の通りです。
-
kubelet
- 各ノード上で動作し、Podの実行を管理します。
-
kube-proxy
- Kubernetes Serviceに基づいて、各Nodeでネットワークプロキシを実行します。
-
Container Runtime
- コンテナを実行するためのソフトウェアです(例: Docker, containerd)。
[コントロールプレーン] <----> [ワーカーノード]
(kube-apiserver, etcd, ...) (kubelet, kube-proxy, ...)
これらのコンポーネントが連携することで、Kubernetesクラスタはアプリケーションのデプロイ、スケーリング、管理などを効果的に行えます。
Kubernetesの基本コンポーネント
Node
Nodeは、Kubernetesクラスタ内のワーカーマシンです。これは、VM(仮想マシン)または物理マシンである可能性があります。各Nodeは、Podをホストします。
Pod
Podは、Kubernetesでのデプロイ単位です。これは、1つ以上のコンテナを含むことができます。Pod内のコンテナは、同じネットワークおよびストレージ(ボリューム)を共有します。
Container
Containerは、アプリケーションのランタイムです。これは、アプリケーションとその依存関係を包含し、ホストOSから隔離されます。
Service
Serviceは、Podの動的な性質に対処し、消費者からPodへのネットワークトラフィックをルーティングします。Serviceは、消費者が一貫したアドレスでPodにアクセスできるようにします。
Deployment
Deploymentは、Podのデプロイメントとスケーリングを管理します。これにより、アプリケーションのアップデートとロールバックが容易になります。
AWSサービスとの統合
Amazon RDS
Amazon RDS(Relational Database Service)は、AWSが提供するマネージドリレーショナルデータベースサービスです。これにより、データベースの設定、運用、スケーリングが容易になります。
Amazon S3
Amazon S3(Simple Storage Service)は、インターネットを通じてストレージを提供するサービスです。S3バケットを使用して、任意の量のデータを保存および取得できます。
Amazon IAM
Amazon IAM(Identity and Access Management)は、AWSリソースへのアクセスをセキュアにコントロールできるサービスです。IAMを使用して、ユーザーおよびグループを作成し、アクセス許可を使用してAWSリソースへのアクセスを許可または拒否できます。
Amazon CloudWatch
Amazon CloudWatchは、AWSおよびオンプレミスのアプリケーション、サービス、リソースのモニタリングおよび管理を可能にするサービスです。
実践チュートリアル:EKS, RDS, S3, IAMの統合
セットアップ
AWS CLI、kubectl、eksctlなど、必要なツールをインストールします。また、AWSアカウントと、AWS CLIで使用する認証情報を設定します。
aws configure
EKSクラスタの作成
eksctlを使用して、EKSクラスタを作成します。
eksctl create cluster --name my-cluster
RDSインスタンスの作成
AWS Management ConsoleまたはAWS CLIを使用して、RDSインスタンスを作成します。セキュリティグループとサブネットを適切に設定し、DBインスタンスにアクセスできるようにします。
aws rds create-db-instance --db-instance-identifier mydbinstance --db-instance-class db.t2.micro --engine mysql --master-username admin --master-user-password password --allocated-storage 20
S3バケットの作成
AWS CLIまたはAWS Management Consoleを使用して、S3バケットを作成します。
aws s3api create-bucket --bucket my-bucket-name --region us-west-2
IAMロールとKubernetes Service Accountの関連付け
IAMロールをKubernetesのService Accountに関連付けることで、クラスタ内のPodがAWSのサービスへアクセスできるようになります。以下に、IAMロールとKubernetes Service Accountの関連付けの手順を示します。
-
IAMロールの作成
AWS Management ConsoleまたはAWS CLIを使用して、IAMロールを作成します。aws iam create-role --role-name MyEKSRole --assume-role-policy-document file://trust-policy.json
-
ポリシーのアタッチ
必要なポリシーをIAMロールにアタッチします。aws iam attach-role-policy --role-name MyEKSRole --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
-
OIDC IDプロバイダーの作成
EKSクラスタに対してOIDC IDプロバイダーを作成します。aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text
-- 以下補足 --
OIDCは、OpenID Connectの略で、認証情報の安全な伝達を可能にするプロトコルです。IDプロバイダー(Identity Provider、IdP)は、ユーザーのIDを提供するサービスで、OIDC IDプロバイダーは、OpenID Connectプロトコルを用いてID情報を提供するサービスを指します。
認証情報はkubernetesリソースへのアクセスにの際に使用されます。
-
Service Accountの作成
関連付けるService AccountをKubernetesクラスターに作成します。apiVersion: v1 kind: ServiceAccount metadata: name: my-serviceaccount namespace: default
kubectl apply -f serviceaccount.yaml
-
IAMロールとService Accountの関連付け
IAMロールとService Accountを関連付けます。eksctl create iamserviceaccount --region us-west-2 --name my-serviceaccount --namespace default --cluster my-cluster --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess --approve
アプリケーションのデプロイ
アプリケーションのデプロイは、コンテナ化されたアプリケーションをKubernetesクラスターに展開するプロセスです。以下に、EKSクラスターにアプリケーションをデプロイする具体的な手順を示します。
1. コンテナイメージのビルド
まず、Dockerを使用してアプリケーションのコンテナイメージをビルドします。以下は、Dockerfile
を使用してイメージをビルドし、Amazon ECRにプッシュする例です。
# Dockerイメージをビルド
docker build -t myapp .
# ECRリポジトリにログイン
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com
# イメージをECRリポジトリにタグ付け
docker tag myapp:latest <account-id>.dkr.ecr.<region>.amazonaws.com/myapp:latest
# イメージをECRにプッシュ
docker push <account-id>.dkr.ecr.<region>.amazonaws.com/myapp:latest
2. デプロイメントの作成
次に、Kubernetesデプロイメントを作成します。デプロイメントは、アプリケーションのインスタンスを管理し、スケーリングとアップデートを行います。以下は、デプロイメントのYAMLマニフェストの例です。
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: <account-id>.dkr.ecr.<region>.amazonaws.com/myapp:latest
serviceAccountName: myapp-service-account
このマニフェストをmyapp-deployment.yaml
として保存し、kubectl apply
コマンドを使用してクラスターにデプロイします。
kubectl apply -f myapp-deployment.yaml
3. サービスの作成
最後に、作成したデプロイメントにアクセスするためのKubernetesサービスを定義します。以下は、サービスのYAMLマニフェストの例です。
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
このマニフェストをmyapp-service.yaml
として保存し、kubectl apply
コマンドを使用してクラスターにデプロイします。
kubectl apply -f myapp-service.yaml
これで、アプリケーションがEKSクラスターにデプロイされ、外部からアクセス可能になります。
テストと検証
アプリケーションのデプロイが成功したら、テストと検証を行います。
-
エンドポイントの確認
ServiceやIngressを使用してエクスポーズされたアプリケーションのエンドポイントを確認します。kubectl get service my-service
-
アプリケーションへのアクセス
エンドポイントにアクセスしてアプリケーションの動作を確認します。ブラウザやcurlコマンドを使用してHTTPリクエストを送信できます。curl http://<ServiceのIPまたはドメイン>
-
ログの確認
Podのログを確認して、アプリケーションの動作やエラーを確認します。kubectl logs <Podの名前>
トラフィックのルーティングとネットワーク
トラフィックの基本的な流れ
Kubernetesでは、トラフィックのルーティングはServiceオブジェクトを通じて行われます。Serviceは、クラスタ内外からのトラフィックを適切なPodにルーティングします。
NodePortとは
NodePortは、外部トラフィックをクラスタ内の特定のServiceにルーティングする一つの方法です。NodePortは、各Nodeの特定のポートを外部からアクセス可能にし、そのトラフィックをServiceに転送します。
iptablesとipvs
iptablesとipvsは、Linuxカーネルのネットワーク機能です。これらは、トラフィックの転送や負荷分散など、トラフィックのルーティングに利用されます。
Pod内のコンテナ間の通信
Pod内のネットワーク
Pod内のコンテナは同じネットワーク名前空間を共有し、localhost
を通じて互いに通信できます。また、Pod内の各コンテナは、別々のネットワークポートを割り当てられます。
コンテナ間の通信の例
Pod内に複数のコンテナが存在する場合、例えば、コンテナAが80番ポートを使用している場合、コンテナBは80番ポートを使用できません。コンテナBは別のポート(例:8080)を使用する必要があります。
質疑応答
PodとContainerの関係
Podは、1つ以上のコンテナをホストすることができ、これらのコンテナは同じネットワークとストレージを共有します。
NodeとPodの関係
Nodeは、Kubernetesクラスタ内のワーカーマシンであり、Podをホストします。Podは、Node上でスケジュールされ、実行されます。
Serviceの役割
Serviceは、動的に変化するPodのIPアドレスを抽象化し、一貫したエンドポイントを提供します。これにより、クライアントはServiceのIPアドレスとポートを使用して、バックエンドのPodにアクセスできます。
Pod内のルーティング
Pod内のコンテナ間のルーティングは、ポート番号を使用して行われます。各コンテナは異なるポート番号を持ち、これを使用して通信します。
終わりに
まとめ
本チュートリアルでは、KubernetesとAWSサービス(Amazon EKS、RDS、S3、IAM)を組み合わせて使用する方法を学びました。これにより、スケーラブルでセキュアなアプリケーションの構築とデプロイが可能になります。
Kubernetesのデプロイメントによって、アプリケーションはクラスタ内の異なるノードに分散配置され、高可用性とスケーラビリティが実現されます。Serviceを使用することでアプリケーションは外部からアクセス可能となり、IAMロールとService Accountの関連付けによって、PodからAWSサービスへの安全なアクセスが可能になります。
RDSを使用することで、データベースは分離され、管理が容易になります。また、S3を使用することで、大量のオブジェクトデータのストレージと管理が可能となります。これらのサービスを適切に組み合わせることで、効率的で効果的なアプリケーションの運用が可能です。
蛇足
Kubernetesの構成要素は、いくつかの階層や層を形成しており、それぞれが異なる役割を果たします。以下は、Kubernetesの主要な構成要素をツリー図で表現したものです。
Kubernetes Cluster
│
├── Node
│ │
│ ├── Pod
│ │ │
│ │ ├── Container
│ │ └── Service Account
│ │
│ └── Kubelet (Node Agent)
│
├── Service
│ └── Selector (PodのLabelを指定)
│
├── Deployment
│ └── ReplicaSet
│ └── Pod
│ └── Container
│
└── Namespace
├── Pod
├── Service
├── Deployment
└── Service Account
-
Node:
- クラスタ内の個々のマシンを表します。これは、VMまたは物理マシンである可能性があります。
-
Pod:
- 1つ以上のコンテナを含むKubernetesの最小実行単位です。
-
Container:
- コンテナ化されたアプリケーションが実行される場所です。
-
Service Account:
- PodがKubernetes APIにアクセスする際のアイデンティティです。
-
Kubelet:
- Node上で実行されるエージェントで、Node上のPodの実行を管理します。
-
Service:
- ネットワーク経由でPodにアクセスするための抽象化された手段を提供します。
-
Deployment:
- アプリケーションのデプロイやスケーリング、アップデートを管理するためのリソースです。
-
ReplicaSet:
- Podのコピーを一定数維持することを保証します。
-
Namespace:
- クラスタ内のリソースを論理的に分割するためのメカニズムです。
このツリー図を使用して、Kubernetesの各コンポーネントとその関連性を視覚的に理解することができます。