Amazon EKS

DevOpsコンテナKubernetesAWSマネージドサービスクラウドエンタープライズ

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障害時の可用性への影響

主要リンク

書き方の例

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