はじめに
OpenStandiaアドベントカレンダー、22日目になります。今年も去年に引き続き、LocalStackに焦点を当てています。最近、Kubernetesに触れる機会が増え、LocalStackを使用してEKSを構築できないか考えていました。今回はその手順をご紹介します。
過去のLocalStackに関する記事はこちらです。
AWS CDK + LocalStackでAWSサーバーレス環境をローカルに構築してみた
LocalStackを使ってローカル環境でS3を立ち上げ、Lambdaでファイルをアップロードしてみた
LocalStack
LocalStackはAWSのクラウド環境を模倣したローカル環境を提供し、開発およびテストを行う際にAWSのサービスを利用できるようにします。
pipやdockerを用いて簡単に環境構築が可能です。
LocalStackの環境構築については、公式ドキュメントを参照してください。
LocalStack起動
今回はEKSを起動するので、有料版のLocalStackが必要になります。
無料と有料版で使用できるサービスの違いは以下になります。
無料 | 有料 |
---|---|
ACM API Gateway CloudFormation CloudWatch CloudWatchLogs DynamoDB DynamoDB Streams EC2 Elasticsearch Service EventBridge Firehose IAM Kinesis KMS Lambda Redshift Route53 S3 SecretsManager SES StepFunctions |
Amplify AppConfig Application AutoScaling AppSync Athena Backup Batch CloudFront CloudTrail CodeCommit Cognito Identity ECR ECS EKS ElastiCache EFS EMR Managed Streaming for Kafka (MSK) Neptune DB QLDB RDS / Aurora Serverless |
詳細や料金については以下のページを参照してください。
有料版のLocalStackを起動するためには事前にAPI Keyを発行しておきます。
API KEYを環境変数に格納した後、localstack start
コマンドでLocal Stackを起動します。
% export LOCALSTACK_API_KEY=<発行したAPI KEY>
% localstack start
__ _______ __ __
/ / ____ _________ _/ / ___// /_____ ______/ /__
/ / / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/
/ /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,<
/_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_|
💻 LocalStack CLI 2.2.0
[21:51:29] starting LocalStack in Docker mode 🐳 localstack.py:409
──────────────────── LocalStack Runtime Log (press CTRL-C to quit) ─────────────────────
LocalStack version: 2.2.1.dev20230817092311
LocalStack Docker container id: 04db20caff3b
.
.
.
EKSの起動
さっそく、公式ドキュメントに沿って、EKSを起動します。
CreateCluster APIを使用して新しいクラスタを作成するために以下のコマンドを実行します。
awslocal eks create-cluster \
--name cluster1 \
--role-arn "arn:aws:iam::000000000000:role/eks-role" \
--resources-vpc-config "{}"
{
"cluster": {
"name": "cluster1",
{
"cluster": {
"name": "cluster1",
"name": "cluster1",
"arn": "arn:aws:eks:us-east-1:000000000000:cluster/cluster1",
"createdAt": "2023-11-14T21:52:17.767000+09:00",
"version": "1.22",
"roleArn": "arn:aws:iam::000000000000:role/eks-role",
"resourcesVpcConfig": {
"securityGroupIds": [],
"endpointPublicAccess": true,
"endpointPrivateAccess": false,
"publicAccessCidrs": [
"0.0.0.0/0"
]
},
"identity": {
"oidc": {
"issuer": "https://localhost.localstack.cloud/eks-oidc"
}
},
"status": "CREATING",
"platformVersion": "eks.5",
"tags": {}
}
}
...skipping...
{
"cluster": {
"name": "cluster1",
"arn": "arn:aws:eks:us-east-1:000000000000:cluster/cluster1",
"createdAt": "2023-11-14T21:52:17.767000+09:00",
"version": "1.22",
"roleArn": "arn:aws:iam::000000000000:role/eks-role",
"resourcesVp
docker CLI のコマンドでコンテナが作成されたことを確認できます。
% docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
00a92a10d55b ghcr.io/k3d-io/k3d-tools:5.4.9 "/app/k3d-tools noop" 10 seconds ago Up 9 seconds k3d-cluster1-tools
909c1c06a7e9 rancher/k3s:v1.22.6-k3s1 "/bin/k3d-entrypoint…" 10 seconds ago Up 7 seconds
クラスターの作成後、以下のコマンドで作成したクラスターの詳細を確認することができます。
% awslocal eks describe-cluster --name cluster1
{
"cluster": {
"name": "cluster1",
"arn": "arn:aws:eks:us-east-1:000000000000:cluster/cluster1",
"createdAt": "2023-11-16T22:03:12.140000+09:00",
"version": "1.22",
"endpoint": "https://localhost.localstack.cloud:4510",
"roleArn": "arn:aws:iam::000000000000:role/eks-role",
"resourcesVpcConfig": {
"securityGroupIds": [],
"endpointPublicAccess": true,
"endpointPrivateAccess": false,
"publicAccessCidrs": [
"0.0.0.0/0"
]
},
"identity": {
"oidc": {
"issuer": "https://localhost.localstack.cloud/eks-oidc"
}
},
"status": "ACTIVE",
"certificateAuthority": {
kubectlのuse-contextの変更
UpdateKubeconfig API を使用して kubectl をLocalStackのEKSクラスターに設定できます。以下のコマンドを実行してください。
awslocal eks update-kubeconfig --name cluster1 && \
kubectl config use-context arn:aws:eks:us-east-1:000000000000:cluster/cluster1
Added new context arn:aws:eks:us-east-1:000000000000:cluster/cluster1 to /Users/syasoda/.kube/config
Switched to context "arn:aws:eks:us-east-1:000000000000:cluster/cluster1".
また、以下のコマンドで現在のcontextがどれかを確認することができます。
kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
arn:aws:eks:us-east-1:000000000000:cluster/cluster1 arn:aws:eks:us-east-1:000000000000:cluster/cluster1 arn:aws:eks:us-east-1:000000000000:cluster/cluster1
* docker-desktop docker-desktop docker-desktop
アプリケーションのデプロイ
試しに、kubernetesの公式が提供しているサンプルのアプリケーションをデプロイします。
RedisマスターのDeploymentの作成
GuestBookアプリケーションはRedisサーバとwebサーバに分かれています。
まずはRedisサーバからデプロイします。
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-deployment.yaml
以下のコマンドで作成できているか確認します。
kubectl get pods
NAME READY STATUS RESTARTS AGE
redis-leader-55b556899d-7f742 1/1 Running 0 6s
Redisマスターの Serviceの作成
次にRedisポッドへのトラフィックをプロキシするサービスを適用します。
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-service.yaml
以下のコマンドで作成できているか確認します。
kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-leader ClusterIP 10.108.131.61 <none> 6379/TCP 5s
RedisスレーブのDeploymentの作成
ここまでのRedisleaderは単一のPodですが、数個のRedisレプリカを追加することで、可用性を高めてトラフィック需要に対応することができます。
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-deployment.yaml
以下のコマンドで作成できているか確認します。
kubectl get pods
NAME READY STATUS RESTARTS AGE
redis-follower-86546888fd-kc8bb 0/1 ContainerCreating 0 6s
redis-follower-86546888fd-mt7gb 0/1 ContainerCreating 0 6s
RedisスレーブのServiceの作成
アプリケーションがデータを読み込むためにRedisフォロワーと通信する必要があるため、
Redis followerのServiceを作成します。
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-service.yaml
以下のコマンドで作成できているか確認します。
kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-follower ClusterIP 10.109.131.130 <none> 6379/TCP 8s
redis-leader ClusterIP 10.108.131.61 <none> 6379/TCP 4m40s
フロントエンド用のDeploymentの作成
次にGuestBookアプリケーションのWebサーバーを起動します。
フロントエンド用のDeploymentを作成します。
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
以下のコマンドで3つのフロントエンドのレプリカが実行中になっていることを確認します。
kubectl get pods -l app=guestbook -l tier=frontend
NAME READY STATUS RESTARTS AGE
frontend-d6778b77f-hl7r4 1/1 Running 0 18s
frontend-d6778b77f-k4f2r 1/1 Running 0 18s
frontend-d6778b77f-kz8kw 1/1 Running 0 18s
フロントエンド用のServiceの作成
次にフロントエンド用のServiceを作成します。
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
以下のコマンドで作成できているか確認します。
kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend ClusterIP 10.111.170.145 <none> 80/TCP 7s
redis-follower ClusterIP 10.109.131.130 <none> 6379/TCP 20m
redis-leader ClusterIP 10.108.131.61 <none> 6379/TCP 25m
アプリケーションにアクセスできるようにするために、`kubectl port-forwardを使用してサービスにアクセスできます。
以下のコマンドを実行して、ローカルマシンのポート8080をサービスのポート80に転送します。
kubectl port-forward svc/frontend 8080:80
http://localhost:8080/
にアクセスすると、GuestBookアプリケーションが表示されます。
構築環境の削除
削除は以下のコマンドで実行します。
kubectl delete deployment -l app=redis
kubectl delete service -l app=redis
kubectl delete deployment frontend
kubectl delete service frontend
最後に
今回、初めて有料版のLocalStackを使用しました。
LocalStack上でEKSクラスタを構築することで、実際のAWS環境を利用することなく、Kubernetesの開発およびテストを行うことができるかなと思いました。
有料版になるとEKS以外のサービスも使えるようになるので、色々他のサービスも検証したいなと思います。