AWS EKS 盛り盛り構成インストールガイド (Apache2 + PHP7.4 + EFS + ALB + HTTPS)

# EKS構築手順

## 前提
  **ちょっとだけ中級者向け(AWSで一般的な環境が構築できる方以上向けの記事)です**
  

## やりたいこと
  1. 既存PrivateVPCでEKSを使いたい
  1. ALBも使いたい
  1. EFSも使うんだ
  1. **Apache + PHP7.4** のいわゆるWEBサーバを作る(CacheやDBはElasticacheやらRDSを使う)
  1. HTTPSも使いたい
  1. AutoScalingを考えるとコンテンツはNASに置いておきたい

## 作業の流れ
  1. **[事前]** AWSでPrivateVPCをつくる
    → 172.16.0.0/16 → 既存のIPを使っているだけなので、読み替えてください

  1. **[事前]** Public-subnetとPrivate-subnetをつくる
    → Public-subnet(ap-northeast-1a:172.16.1.0/24, ap-northeast-1c:172.16.51.0/24) グローバルIP付与可能＋InternetGateWayあり
    → Private-subnet(ap-northeast-1a:172.16.101.0/24, ap-northeast-1c:172.16.151.0/24) プライベートのみアクセス可能だが外部への通信はNatgatewayを介して可能

  1. **[事前]** Public-SubnetにEKSをコントロールするためのEC2を配置
  1. **[事前]** eksctlのインストール
    → https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/getting-started-eksctl.html

  1. **[この記事]** Cluster作成
  1. **[この記事]** aws-load-balancer-controllerのインストール
  1. **[この記事]** EFSドライバーのインストール
  1. **[次回]** 満を持してPodを作成していく

## clusterの作成
### taterole-test.yaml ファイルを配置
  1. taterole-test.yaml

    ```taterole-test.yaml
    apiVersion: eksctl.io/v1alpha5
    kind: ClusterConfig
    
    metadata:
      name: taterole-test
      region: ap-northeast-1
      version: "1.18"
    
    vpc:
      id: "vpc-0cb0c0d9201725a89"
      cidr: "172.16.0.0/16"
      subnets:
        private: ## NATGatewayあり
          ap-northeast-1a:
            id: "subnet-0351c84fd49393355"
            cidr: "172.16.101.0/24"
          ap-northeast-1c:
            id: "subnet-07b2bfb24b1154028"
            cidr: "172.16.151.0/24"
        public: ## InternetGateWayあり
          ap-northeast-1a:
            id: "subnet-0f281e8620e7368bf"
            cidr: "172.16.1.0/24"
          ap-northeast-1c:
            id: "subnet-01b715a5b4dd43efc"
            cidr: "172.16.51.0/24"
    
    managedNodeGroups:
      - name: web1
        instanceType: t3.small  ## K8sワーカーノードの設定です。任意のインスタンスタイプにしてください。
        desiredCapacity: 1 ## 希望台数です。任意の台数にしてください
        minSize: 1 ## 最小台数です。任意の台数にry
        maxSize: 1 ## 最大台数です。任意のry
        privateNetworking: true
        ssh:
          publicKeyName: ssh-key-file ## なんかあったときのために、ワーカーノードにログインする為のSSH鍵を指定しておく
          allow: true
        labels: {role: worker}
        tags:
          Type: eks-worker ## タグを好きにつけられます 
    ```

### clusterの立ち上げ
  1. eksctlコマンドでclusterをつくる

    ```bash
    $ eksctl create cluster -f taterole-test.yaml --with-oidc
      → 20分くらいかかる
    ```

## aws-load-balancer-controllerのインストール
  1. iam-policy.jsonのダウンロード

    ```bash
    $ curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/main/docs/install/iam_policy.json
    ```
  1. iamポリシーの作成

    ```bash
    $ aws iam create-policy \
      --policy-name AWSLoadBalancerControllerIAMPolicy \
      --policy-document file://iam-policy.json
    ```
  1. サービスアカウントの作成

    ```bash
    $ eksctl create iamserviceaccount \
      --cluster=taterole-test \
      --namespace=kube-system \
      --name=aws-load-balancer-controller \
      --attach-policy-arn=arn:aws:iam::<YOUE-AWS-ID>:policy/AWSLoadBalancerControllerIAMPolicy \
      --approve
    [!] no IAM OIDC provider associated with cluster, try 'eksctl utils associate-iam-oidc-provider --region=ap-northeast-1 --cluster=taterole-test'
    と、怒られた場合は以下を実行する
    $ eksctl utils associate-iam-oidc-provider --region=ap-northeast-1 --cluster=taterole-test --approve
    ```

  1. cert-managerのインストール

    ```bash
    $ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.2/cert-manager.yaml
    ```

  1. AWS Load Balancer Controller のインストール
    以下の部分をviで修正する
    --cluster-name の部分を自分の my-cluster-name を、自分の設定したいCluster名に変更
    ServiceAccountのセクションをまるごと削除

    ```bash
    $ curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/main/docs/install/v2_0_1_full.yaml
    $ vi v2_0_1_full.yaml
    $ kubectl apply -f v2_0_1_full.yaml
    ```

  1. インストールの確認

    ```bash
    $ kubectl get pods -n kube-system | grep aws-load-balancer-controller
    aws-load-balancer-controller-594b77dc87-cmwgp   1/1     Running   0          91m
    ```

## EFSドライバーのインストール
  1. Amazon EFS CSI ドライバーをデプロイ

    ```bash
    $ kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/?ref=master"
      → 下記のように、efs-csi-controllerが再起動を繰り返しインストールが完了しない不具合があるので、helmでインストールする
    $ kubectl get pod --all-namespac
    NAMESPACE     NAME                                  READY   STATUS             RESTARTS   AGE
    kube-system   aws-node-jwqzh                        1/1     Running            0          101m
    kube-system   coredns-86f7d88d77-5tpzk              1/1     Running            0          105m
    kube-system   coredns-86f7d88d77-sjxwp              1/1     Running            0          105m
    kube-system   efs-csi-controller-5c8f98ddfd-rf5jd   2/3     CrashLoopBackOff   7          14m
    kube-system   efs-csi-controller-5c8f98ddfd-xqvsb   2/3     CrashLoopBackOff   7          14m
    kube-system   efs-csi-node-prjmd                    3/3     Running            0          14m
    kube-system   kube-proxy-fw8wd
    ```

  1. helmのインストール

    ```bash
    $ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                   Dload  Upload   Total   Spent    Left  Speed
             100 11213  100 11213    0     0  37754      0 --:--:-- --:--:-- --:--:-- 37627
    
    $ chmod 700 get_helm.sh
    $ ./get_helm.sh
    WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /home/ec2-user/.kube/config
    WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /home/ec2-user/.kube/config
    Helm v3.5.0 is available. Changing from version v3.4.2.
    Downloading https://get.helm.sh/helm-v3.5.0-linux-amd64.tar.gz
    Verifying checksum... Done.
    Preparing to install helm into /usr/local/bin
    helm installed into /usr/local/bin/helm
    ```

  1. helm で Amazon EFS CSI ドライバーをデプロイ

    ```bash
    $ helm install aws-efs-csi-driver https://github.com/kubernetes-sigs/aws-efs-csi-driver/releases/download/v0.3.0/helm-chart.tgz
    WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /home/ec2-user/.kube/config
    WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /home/ec2-user/.kube/config
    NAME: aws-efs-csi-driver
    LAST DEPLOYED: Thu Jan 21 17:16:16 2021
    NAMESPACE: default
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    To verify that aws-efs-csi-driver has started, run:

        kubectl get pod -n kube-system -l "app.kubernetes.io/name=aws-efs-csi-driver,app.kubernetes.io/instance=aws-efs-csi-driver"
    $ kubectl get pod -n kube-system -l "app.kubernetes.io/name=aws-efs-csi-driver,app.kubernetes.io/instance=aws-efs-csi-driver"
    NAME                 READY   STATUS    RESTARTS   AGE
    efs-csi-node-glkgs   3/3     Running   0          44m
    ```

  1. クラスターのVPCID取得

    ```bash
    $ aws eks describe-cluster --name taterole-test --query "cluster.resourcesVpcConfig.vpcId" --output text
    vpc-0cb0c0d9201725a89
    ```

  1. VPIのCIDR範囲を取得

    ```bash
    $ aws ec2 describe-vpcs --vpc-ids vpc-0cb0c0d9201725a89 --query "Vpcs[].CidrBlock" --output text
    172.16.0.0/16
    ```
    
  1. EKSクラスター→EFSセキュリティグループの作成

    ```bash
    $ aws ec2 create-security-group --description taterole-efs-test-sg --group-name taterole-efs-sg --vpc-id vpc-0cb0c0d9201725a89
    {
        "GroupId": "sg-091e5e23e775a4f4b"
    }
    ```
    
  1. EFSインバウンドルールを追加して、VPC のリソースが EFS と通信できるようにする

    ```bash
    $ aws ec2 authorize-security-group-ingress --group-id sg-091e5e23e775a4f4b --protocol tcp --port 2049 --cidr 172.16.0.0/16
    ```

  1. EFSファイルシステムの作成

    ```bash
    $ aws efs create-file-system --creation-token taterole-efs
    {
        "OwnerId": "<YOUE-AWS-ID>",
        "CreationToken": "taterole-efs",
        "FileSystemId": "fs-5b708f7b",
        "FileSystemArn": "arn:aws:elasticfilesystem:ap-northeast-1:<YOUE-AWS-ID>:file-system/fs-5b708f7b",
        "CreationTime": "2021-01-21T17:03:50+09:00",
        "LifeCycleState": "creating",
        "NumberOfMountTargets": 0,
        "SizeInBytes": {
            "Value": 0,
            "ValueInIA": 0,
            "ValueInStandard": 0
        },
        "PerformanceMode": "generalPurpose",
        "Encrypted": false,
        "ThroughputMode": "bursting",
        "Tags": []
    }
    ```
    
  1. EFSマウントターゲットの作成 ap-northeast-1a (サブネット毎に実行する)

    ```bash
    $ aws efs create-mount-target --file-system-id fs-5b708f7b --subnet-id subnet-0351c84fd49393355 --security-group sg-091e5e23e775a4f4b
    {
        "OwnerId": "<YOUE-AWS-ID>",
        "MountTargetId": "fsmt-e09902c1",
        "FileSystemId": "fs-5b708f7b",
        "SubnetId": "subnet-0351c84fd49393355",
        "LifeCycleState": "creating",
        "IpAddress": "172.16.101.9",
        "NetworkInterfaceId": "eni-03a2229e1a0a08857",
        "AvailabilityZoneId": "apne1-az4",
        "AvailabilityZoneName": "ap-northeast-1a",
        "VpcId": "vpc-0cb0c0d9201725a89"
    }
    ```

  1. EFSマウントターゲットの作成 ap-northeast-1c (サブネット毎に実行する)

    ```bash
    $ aws efs create-mount-target --file-system-id fs-5b708f7b --subnet-id subnet-07b2bfb24b1154028 --security-group sg-091e5e23e775a4f4b
    {
        "OwnerId": "<YOUE-AWS-ID>",
        "MountTargetId": "fsmt-e69902c7",
        "FileSystemId": "fs-5b708f7b",
        "SubnetId": "subnet-07b2bfb24b1154028",
        "LifeCycleState": "creating",
        "IpAddress": "172.16.151.53",
        "NetworkInterfaceId": "eni-0e51080afba62675e",
        "AvailabilityZoneId": "apne1-az1",
        "AvailabilityZoneName": "ap-northeast-1c",
        "VpcId": "vpc-0cb0c0d9201725a89"
    }
    ```

---

あとはPodを作成してサービス提供の準備をしていくだけです。
今回はとりあえずここまで