> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ale.run/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS EKSクラスター設定

> eksctlを活用したAWS EKSクラスター作成ガイドです。

***

## eksctl YAML仕様の作成

> 以下の内容を参考に、作成するEKSクラスターのYAML仕様を作成し、保存します。

```yaml theme={null}
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: $CLUSTER_NAME
  version: "1.30"
  region: ap-northeast-2

iam:
  withOIDC: true

vpc:
  clusterEndpoints:
    publicAccess: true
    privateAccess: true

addons:
  - name: vpc-cni
    version: 1.18.1
    attachPolicyARNs:
    - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
    configurationValues: |-
      enableNetworkPolicy: "true"
  - name: coredns
  - name: kube-proxy

managedNodeGroups:
  - name: node-group-01
    amiFamily: AmazonLinux2
    instanceType: t3.large
    minSize: 2
    desiredCapacity: 2
    maxSize: 4
    privateNetworking: true
    disableIMDSv1: true
    volumeSize: 100
    labels:
      purpose: system
    iam:
      withAddonPolicies:
        albIngress: true
        ebs: true
        efs: true
        externalDNS: true
```

## クラスター&ノードグループの作成

> 以下のコマンドを実行してEKSクラスターを作成します。

```bash theme={null}
envsubst < [1で作成したyamlファイル名] | eksctl create cluster -f -
# ローカルに保存したマニフェストYAMLファイルを使用
```

## Nginx Ingress Controller

> Helmを使用してNginx Ingress Controllerをインストールします。

```bash theme={null}
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
```

```bash theme={null}
helm install ingress-nginx ingress-nginx/ingress-nginx \
  --version 4.11.2 \
  --namespace ingress-nginx --create-namespace \
  --set controller.service.type=LoadBalancer \
  --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-type"="nlb" \
  --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-scheme"="internet-facing" \
  --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-nlb-target-type"="ip" \
  --set controller.allowSnippetAnnotations=true \
  --set controller.admissionWebhooks.enabled=false
```

## Cert Manager

> Helmを使用してCert Managerをインストールします。

```bash theme={null}
helm repo add jetstack https://charts.jetstack.io
helm repo update
```

```bash theme={null}
helm install \
      cert-manager jetstack/cert-manager \
      --namespace cert-manager \
      --create-namespace \
      --version v1.15.3 \
      --set crds.enabled=true
```

## ストレージ

> AWSでは多様なストレージオプションが提供されており、`エール`の基本ストレージとしてAmazon Elastic File System (EFS)およびElastic Block Store (EBS)の中から、使用目的に応じて選択して利用できます。

<AccordionGroup>
  <Accordion title="AWS EBS CSIのインストール">
    **1.** クラスターIAM OIDCプロバイダーの作成有無を確認し、まだ作成されていない場合は新規作成します。

    ```bash theme={null}
    # クラスターにOIDCプロバイダーが作成されているか確認
    aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5
    aws iam list-open-id-connect-providers | grep $OIDC_ID | cut -d "/" -f4
    ```

    ```bash theme={null}
    # クラスターにOIDCプロバイダーが作成されていない場合、以下のコマンドで作成
    aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | cut
    eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve
    OIDC_ID=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
    ```

    **2.** EBS CSIドライバー用IAMロールを作成します。

    ```bash theme={null}
    eksctl create iamserviceaccount \
        --name ebs-csi-controller-sa \
        --namespace kube-system \
        --cluster ${CLUSTER_NAME} \
        --role-name AmazonEKS_EBS_CSI_DriverRole \
        --role-only \
        --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
        --approve
    ```

    **3.** EKSアドオンとしてEBS CSIドライバーを適用します。

    ```bash theme={null}
    export ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text | xargs -L 1)
    ```

    ```bash theme={null}
    eksctl create addon \
        --name aws-ebs-csi-driver \
        --cluster ${CLUSTER_NAME} \
        --service-account-role-arn arn:aws:iam::${ACCOUNT_ID}:role/AmazonEKS_EBS_CSI_DriverRole \
        --force
    ```

    **4.** gp2に設定されているデフォルト設定を解除します。

    ```bash theme={null}
    kubectl patch storageclass gp2 \
    	-p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
    ```

    **5.** 新しいStorage Class(gp3)を作成します。`storageclass.kubernetes.io/is-default-class: "true"`アノテーションを使用してデフォルト設定として指定します。

    ```bash theme={null}
    cat <<EOF | kubectl apply -f -
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: gp3
      annotations:
        storageclass.kubernetes.io/is-default-class: "true"
    allowVolumeExpansion: true
    provisioner: ebs.csi.aws.com
    volumeBindingMode: Immediate
    parameters:
      type: gp3
      allowAutoIOPSPerGBIncrease: 'true'
      encrypted: 'true'
    EOF
    ```

    **6.** PVC作成テストのために次のコマンドを実行します。

    ```bash theme={null}
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-test
    spec:
      accessModes:
        - ReadWriteOnce
      storageClassName: gp3
      resources:
        requests:
          storage: 1Gi
    EOF
    ```

    **7.** 作成したPVCの状態を確認します。正常に作成されると、STATUSはBoundになります。

    ```bash theme={null}
    kubectl get pvc pvc-test
    ```

    ```bash theme={null}
    NAME       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
    pvc-test   Bound    pvc-bf3fcf47-b712-4ae4-acd9-9d9aefc72e84   1Gi        RWO            gp3            <unset>                 3s
    ```
  </Accordion>
</AccordionGroup>

<AccordionGroup>
  <Accordion title="AWS EFS CSIのインストール">
    **1.** クラスターIAM OIDCプロバイダーの作成有無を確認し、まだ作成されていない場合は新規作成します。

    ```bash theme={null}
    # クラスターにOIDCプロバイダーが作成されているか確認
    aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5
    aws iam list-open-id-connect-providers | grep $OIDC_ID | cut -d "/" -f4
    ```

    ```bash theme={null}
    # クラスターにOIDCプロバイダーが作成されていない場合、以下のコマンドで作成
    aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | cut
    eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve
    OIDC_ID=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
    ```

    **2.** EBS CSIドライバー用IAMロールを作成してポリシーを適用します。

    ```bash theme={null}
    eksctl create iamserviceaccount \
        --name efs-csi-controller-sa \
        --namespace kube-system \
        --cluster ${CLUSTER_NAME} \
        --role-name AmazonEKS_EFS_CSI_DriverRole \
        --role-only \
        --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy \
        --approve
    ```

    ```bash theme={null}
    TRUST_POLICY=$(aws iam get-role --role-name AmazonEKS_EFS_CSI_DriverRole --query 'Role.AssumeRolePolicyDocument' | \
        sed -e 's/efs-csi-controller-sa/efs-csi-*/' -e 's/StringEquals/StringLike/')
    ```

    ```bash theme={null}
    aws iam update-assume-role-policy --role-name AmazonEKS_EFS_CSI_DriverRole --policy-document "$TRUST_POLICY"
    ```

    **3.** EKSアドオンとしてEFS CSIドライバーを適用します。

    ```bash theme={null}
    export ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text | xargs -L 1)
    ```

    ```bash theme={null}
    eksctl create addon \
        --name aws-efs-csi-driver \
        --cluster ${CLUSTER_NAME} \
        --service-account-role-arn arn:aws:iam::${ACCOUNT_ID}:role/AmazonEKS_EFS_CSI_DriverRole \
        --force
    ```

    **4.** EFSファイルシステムを作成するための情報を取得し、環境変数として設定します。

    ```bash theme={null}
    VPC_ID=$(aws eks describe-cluster \
        --name $CLUSTER_NAME \
        --query "cluster.resourcesVpcConfig.vpcId" \
        --output text)
    ```

    ```bash theme={null}
    CIDR_RANGE=$(aws ec2 describe-vpcs \
        --vpc-ids $VPC_ID \
        --query "Vpcs[].CidrBlock" \
        --output text \
        --region $AWS_REGION)
    ```

    **5.** セキュリティグループを作成し、2049(NFS)ポートのインバウンドルールを追加します。

    ```bash theme={null}
    SECURITY_GROUP_ID=$(aws ec2 create-security-group \
        --group-name EfsSecurityGroup \
        --description "EFS security group" \
        --vpc-id $VPC_ID \
        --output text)
    ```

    ```bash theme={null}
    aws ec2 authorize-security-group-ingress \
        --group-id $SECURITY_GROUP_ID \
        --protocol tcp \
        --port 2049 \
        --cidr $CIDR_RANGE
    ```

    **6.** AWS EFSファイルシステムを作成します。

    ```bash theme={null}
    aws efs create-file-system \
        --region $AWS_REGION \
        --performance-mode generalPurpose \
        --query 'FileSystemId' \
        --output text
    ```

    **7.** AWS EFS管理コンソールで作成されたファイルシステムページにアクセスし、`Network`タブで`Manage`ボタンをクリックします。

    <Frame>
      <img className="block rounded-md" src="https://files.cloudtype.io/ale-docs/setup/eks/images/02_01.png" />
    </Frame>

    **8.** Kubernetesクラスターのノードが配置されているAZ（アベイラビリティゾーン）に基づいてマウントターゲットを追加し、各ノードのパブリックサブネットを選択します。その後、2049ポートのインバウンド通信を許可するルールが追加されたEFSセキュリティグループを選択して保存します。

    <Frame>
      <img className="block rounded-md" src="https://files.cloudtype.io/ale-docs/setup/eks/images/02_02.png" />
    </Frame>

    **9.** 新しいStorage Class(efs-sc)を作成します。`storageclass.kubernetes.io/is-default-class: "true"`アノテーションを使用してデフォルト設定として指定します。

    ```bash theme={null}
    cat <<EOF | kubectl apply -f -
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: efs-sc
      annotations:
        storageclass.kubernetes.io/is-default-class: "true"
    provisioner: efs.csi.aws.com
    parameters:
      basePath: /dynamic_provisioning
      provisioningMode: efs-ap
      fileSystemId: [File System ID]
      directoryPerms: "755"
      gid: "1001"
      uid: "1001"
    EOF
    ```

    **10.** PVC作成テストのために次のコマンドを実行します。

    ```bash theme={null}
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-test
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: efs-sc
      resources:
        requests:
          storage: 1Gi
    EOF
    ```

    **11.** 作成したPVCの状態を確認します。正常に作成されると、STATUSはBoundになります。

    ```bash theme={null}
    kubectl get pvc pvc-test
    ```

    ```bash theme={null}
    NAME       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
    pvc-test   Bound    pvc-bf3fcf47-b712-4ae4-acd9-9d9aefc72e84   1Gi        RWX            efs-sc         <unset>                 3s
    ```
  </Accordion>
</AccordionGroup>

## Kubernetes Metrics Server

> クラスター内のコンテナリソース情報を収集するため、Metrics Serverをインストールします。

Kubernetes Metrics Serverをインストールするには、以下のコマンドを実行します。

```bash theme={null}
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm repo update
```

```bash theme={null}
helm install metrics-server metrics-server/metrics-server -n kube-system --set "args={--kubelet-insecure-tls}"
```

Metrics Serverが正常に動作しているかを確認するため、以下のコマンドを実行します。

```bash theme={null}
kubectl get pods -n kube-system -l app.kubernetes.io/name=metrics-server
```
