Amazon EKS
DevOpsツール
Amazon EKS
概要
Amazon EKSは、AWSのマネージドKubernetesサービスです。Kubernetesクラスターの運用管理を自動化し、AWSサービスとの深い統合により、エンタープライズレベルのコンテナ運用を実現します。
詳細
Amazon Elastic Kubernetes Service(Amazon EKS)は、2018年にAWSが一般提供を開始したフルマネージドKubernetesサービスです。Kubernetesコントロールプレーンの運用、パッチ適用、バックアップ、災害復旧をAWSが完全管理し、利用者はワーカーノードとアプリケーションの管理に集中できます。複数のアベイラビリティゾーンにまたがる高可用性構成を自動提供し、AWS IAM、VPC、Security Groups、ELB、EBS、EFS等との密な統合により、エンタープライズレベルのセキュリティと運用性を実現。Fargate統合によるサーバーレスKubernetes、GPU対応ワーカーノード、Auto Scaling、Spot Instance対応により、多様なワークロードに最適化。Amazon ECR、CloudWatch、CloudTrail、Systems Manager等のAWSサービス群との連携で、コンテナイメージ管理から監視・ログまでを統一管理。現在では多くの企業でクラウドネイティブアプリケーション開発の中核インフラとして採用され、AWS環境でのKubernetes運用の標準選択肢となっています。
メリット・デメリット
メリット
- フルマネージド: コントロールプレーンの運用不要
- 高可用性: マルチAZ構成での自動冗長化
- AWS統合: IAM、VPC、CloudWatch等との密な連携
- セキュリティ: AWS標準のセキュリティ機能を継承
- スケーラビリティ: オートスケーリングとSpot Instance活用
- Fargate対応: サーバーレスKubernetesの実現
- エンタープライズ機能: 監査ログ、暗号化、コンプライアンス対応
- 運用負荷軽減: パッチ適用、バックアップの自動化
デメリット
- コスト: 管理プレーン料金 + EC2/Fargateコスト
- AWS依存: マルチクラウド戦略での制約
- カスタマイズ制限: コントロールプレーンへのアクセス不可
- 学習コスト: Kubernetes + AWS サービスの知識が必要
- ネットワーク複雑性: VPC、サブネット設計の重要性
- リージョン制限: 特定リージョンでのサービス利用制約
- バージョン管理: EKSサポートバージョンへの追従
- 障害影響: AWS障害時の可用性への影響
主要リンク
- Amazon EKS公式サイト
- Amazon EKS公式ドキュメント
- EKS Workshop
- AWS Container Blog
- eksctl公式サイト
- AWS Load Balancer Controller
書き方の例
eksctlでのクラスター作成
# eksctlインストール
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
# クラスター作成(基本)
eksctl create cluster \
--name production-cluster \
--version 1.28 \
--region us-west-2 \
--nodegroup-name standard-workers \
--node-type m5.large \
--nodes 3 \
--nodes-min 1 \
--nodes-max 4 \
--managed
# kubectl設定更新
aws eks update-kubeconfig --region us-west-2 --name production-cluster
設定ファイル使用(cluster.yaml)
# cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: production-cluster
region: us-west-2
version: "1.28"
vpc:
subnets:
private:
us-west-2a: { id: subnet-0123456789abcdef0 }
us-west-2b: { id: subnet-0123456789abcdef1 }
us-west-2c: { id: subnet-0123456789abcdef2 }
managedNodeGroups:
- name: standard-workers
instanceType: m5.large
minSize: 1
maxSize: 10
desiredCapacity: 3
privateNetworking: true
ssh:
allow: true
publicKeyName: my-key-pair
iam:
withAddonPolicies:
autoScaler: true
cloudWatch: true
ebs: true
efs: true
alb-ingress: true
tags:
Environment: production
Team: platform
- name: spot-workers
instanceTypes: ["m5.large", "m5.xlarge", "m4.large"]
spot: true
minSize: 0
maxSize: 5
desiredCapacity: 2
fargateProfiles:
- name: fp-default
selectors:
- namespace: default
- namespace: kube-system
addons:
- name: vpc-cni
version: latest
- name: coredns
version: latest
- name: kube-proxy
version: latest
- name: aws-ebs-csi-driver
version: latest
cloudWatch:
clusterLogging:
enable: ["*"]
# 設定ファイルでクラスター作成
eksctl create cluster -f cluster.yaml
AWS Load Balancer Controller設定
# IAM OIDC Identity Provider作成
eksctl utils associate-iam-oidc-provider \
--region us-west-2 \
--cluster production-cluster \
--approve
# ServiceAccount作成
eksctl create iamserviceaccount \
--cluster production-cluster \
--namespace kube-system \
--name aws-load-balancer-controller \
--attach-policy-arn arn:aws:iam::aws:policy/ElasticLoadBalancingFullAccess \
--override-existing-serviceaccounts \
--approve
# Helm経由でController インストール
helm repo add eks https://aws.github.io/eks-charts
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=production-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
Ingress設定(ALB使用)
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/ssl-redirect: '443'
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:123456789012:certificate/abc123
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/healthcheck-path: /health
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
EFS StatefulSet設定
# efs-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: fs-0123456789abcdef0
directoryPerms: "0755"
---
# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-app
spec:
serviceName: web-app
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: nginx:latest
volumeMounts:
- name: efs-storage
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: efs-storage
spec:
accessModes: [ "ReadWriteMany" ]
storageClassName: efs-sc
resources:
requests:
storage: 1Gi
Cluster Autoscaler設定
# cluster-autoscaler.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
labels:
app: cluster-autoscaler
spec:
selector:
matchLabels:
app: cluster-autoscaler
template:
metadata:
labels:
app: cluster-autoscaler
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: '8085'
spec:
serviceAccountName: cluster-autoscaler
containers:
- image: k8s.gcr.io/autoscaling/cluster-autoscaler:v1.21.0
name: cluster-autoscaler
resources:
limits:
cpu: 100m
memory: 300Mi
requests:
cpu: 100m
memory: 300Mi
command:
- ./cluster-autoscaler
- --v=4
- --stderrthreshold=info
- --cloud-provider=aws
- --skip-nodes-with-local-storage=false
- --expander=least-waste
- --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/production-cluster
Fargate Profile設定
# Fargate Profile作成
eksctl create fargateprofile \
--cluster production-cluster \
--name fargate-profile \
--namespace fargate-ns \
--labels app=serverless
# Fargate用Pod設定
kubectl create namespace fargate-ns
kubectl label namespace fargate-ns app=serverless
# fargate-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fargate-app
namespace: fargate-ns
spec:
replicas: 2
selector:
matchLabels:
app: fargate-app
template:
metadata:
labels:
app: fargate-app
spec:
containers:
- name: app
image: nginx:alpine
resources:
requests:
cpu: 250m
memory: 512Mi
モニタリング設定(CloudWatch Container Insights)
# CloudWatch エージェント設定
curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluentd-quickstart.yaml | sed "s/{{cluster_name}}/production-cluster/;s/{{region_name}}/us-west-2/" | kubectl apply -f -
# Prometheus設定
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/prometheus-eks.yaml
AWS CLI & kubectl操作
# クラスター情報取得
aws eks describe-cluster --name production-cluster --region us-west-2
# ノードグループ情報
aws eks describe-nodegroup \
--cluster-name production-cluster \
--nodegroup-name standard-workers \
--region us-west-2
# kubeconfig更新
aws eks update-kubeconfig \
--region us-west-2 \
--name production-cluster
# アドオン管理
aws eks list-addons --cluster-name production-cluster --region us-west-2
aws eks describe-addon --cluster-name production-cluster --addon-name vpc-cni --region us-west-2
# クラスター削除
eksctl delete cluster --name production-cluster --region us-west-2