3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プライベートEKSクラスターの構築に必要な設定

Last updated at Posted at 2024-03-27

はじめに

Amazon Elastic Kubernetes Service (Amazon EKS) はAWS上でKubernetesを実行することができる。EKSはeksctlコマンドを用いることで簡単に作成できるが、デフォルトの設定では意外とインターネットアクセスを前提としている点が多い。私自身、インターネットアクセスをしないプライベートEKSの構築にとても苦労したので、その作成・設定方法を備忘録として残しておきたいと思い、本稿を記載する。

必要な設定

プライベートEKSクラスターの構築に必要な設定は大きく分けて3つある。

1.VPCエンドポイントの作成

EKSは内部で様々なAWSリソースにアクセスしており、それらはデフォルトではグローバルIP経由でアクセスしている。プライベートなEKSではグローバルIP経由でのアクセスは不可のため、AWSリソースにアクセスするためのVPCエンドポイントを、EKSと同じVPCに作成する必要がある。必要なVPCエンドポイントは以下の通り。

サービス エンドポイント
Amazon EC2 com.amazonaws.region-code.ec2
Amazon Elastic Container Registry (コンテナイメージの取得用) com.amazonaws.region-code.ecr.api、com.amazonaws.region-code.ecr.dkr、および com.amazonaws.region-code.s3
Application Load Balancerおよび ネットワークロードバランサー com.amazonaws.region-code.elasticloadbalancing
AWS X-Ray com.amazonaws.region-code.xray
Amazon CloudWatch Logs com.amazonaws.region-code.logs
AWS Security Token Service (サービスアカウントに IAM ロールを使用している場合に必要) com.amazonaws.region-code.sts
AWS Auto Scaling (EKSノードをオートスケールする場合に必要) com.amazonaws.region-code.autoscaling

参考文献:[1],[2]

2.EKSのプライベートエンドポイント設定

EKSにアクセスするためのAPIエンドポイントの設定が、デフォルトだとパブリックエンドポイントのみとなっており、プライベートネットワークからのアクセスが不可となっている。そのため、eksctlで構築する際に下記のような設定が必要となる。

vpc:
  sharedNodeSecurityGroup: sg-******* #EKSのAPIエンドポイントにアクセスするEC2インスタンスのSGを設定する
  clusterEndpoints:
    publicAccess:  false #パブリックNWからのアクセスを0にしたい場合はfalseにしておくとよい
    privateAccess: true 

もしくは

privateCluster:
  enabled: true #こちらの設定だとVPCエンドポイントをeksctlが自動で作成してくれる
  additionalEndpointServices:
  # For Cluster Autoscaler
  - "autoscaling"
  # CloudWatch logging
  - "logs"

参考文献:[1],[3],[4],[5]

3.ECRプライベートリポジトリの設定

EKS内で動作させるPodのDockerイメージの参照先は、デフォルトでは外部のレジストリを参照していることが多い。例えばCloudWatchにEKSのログを送るFluent-Bitのインストール設定ファイル「fluent-bit.yaml」のデフォルト設定は

...
spec:
  selector:
    matchLabels:
      k8s-app: fluent-bit
  template:
    ...
    spec:
      containers:
      - name: fluent-bit
        image: public.ecr.aws/aws-observability/aws-for-fluent-bit:stable
        imagePullPolicy: Always
...

のようにイメージ参照先(image)がpublic.ecr.awsとなっており、ここはインターネットアクセスが無いとアクセスできない。プライベートEKSにおいてこの設定をそのまま用いると、Dockerイメージをpull出来ず、Podが正常に立ち上がらない状態となってしまう。
したがって、プライベートなEKSでFluent-Bitを動作させるためには、
1.fluent-bit.yamlのimageの設定を自身のAWSアカウントのECRアドレスに設定する
2.public.ecr.awsにあるDockerイメージをpullし、自身のAWSアカウントのAmazon Elastic Container Registry(Amazon ECR)のプライベートリポジトリにpushする
といった手順が必要となる。

参考文献:[6]

以上の3つの設定を踏まえると以下のような構成図となる。
構成図.png
※EKS manageノードはEKS構築作業やkubectlを実行するマシンを意味している
※構成図におけるInternet gateway(IGW)はEKS構築作業に必須のため付けており、EKSおよびEKSノードはIGWを通らない

実際に構築してみた

プライベートEKSクラスターにFluent-Bitをインストールした環境を実際に構築してみた。

VPC、サブネットなど基盤部分

こちらは本稿の主題から外れるので構築手順は割愛。
作成したものは以下の通り。

  • VPC×1
  • プライベートサブネット×3
    • アベイラビリティゾーン3つ分
  • パブリックサブネット×1
  • ルートテーブル×4
    • プライベートサブネット用3つ+パブリックサブネット用1つ
  • IGW×1
  • ゲートウェイ型S3エンドポイント×1
    • ルートテーブル4つ全てに関連付ける
  • セキュリティグループ×1
    • EKS manageノード用
    • ローカルマシンからのSSH接続とVPC内のローカル通信用の設定を追加する
  • IAMロール
    • EKS manageノード用
      • 以下のポリシーを付与
        • AmazonEC2ContainerRegistryFullAccess
        • AmazonEC2FullAccess
        • AmazonEKSClusterPolicy
        • AmazonEKSServicePolicy
        • AmazonS3FullAccess
        • AmazonSSMFullAccess
        • AWSCloudFormationFullAccess
        • CloudWatchLogsFullAccess
        • IAMFullAccess
        • EKSへのフルアクセス(カスタマーポリシー)
          ...
          "Effect": "Allow",
          "Action": "eks:*",
          "Resource": "*"
          ...
          
  • EC2インスタンス×1(EKS manageノード)
    • AMI:Amazon Linux 2023
    • インスタンスタイプ:t2.xlarge
    • ストレージ:32GB
    • パブリックサブネットに配置
    • 作成したセキュリティグループおよびIAMロールを割り当てる

EKS構築

EKS manageノードで作業EKS構築を進めていく。

1.EKSノードへのssh接続用の公開鍵・秘密鍵作成

EKSノードにパスワード無しでssh接続するために、パスワード無しで鍵を作成する。

[ec2-user@ip-*-*-*-* ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
...
2.kubectlおよびeksctlのインストール

EKSを操作するためのkubectl、およびEKSを構築するためのeksctlを、文献[7]を参考にインストールする。

[ec2-user@ip-*-*-*-* ~]$ sudo curl -L -o /usr/local/bin/kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.29.0/2024-01-04/bin/linux/amd64/kubectl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 47.4M  100 47.4M    0     0  11.6M      0  0:00:04  0:00:04 --:--:-- 11.6M
[ec2-user@ip-*-*-*-* ~]$
[ec2-user@ip-*-*-*-* ~]$ sudo chmod +x /usr/local/bin/kubectl
[ec2-user@ip-*-*-*-* ~]$ kubectl version --client
Client Version: v1.29.0-eks-5e0fdde
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
[ec2-user@ip-*-*-*-* ~]$ curl -L "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 33.6M  100 33.6M    0     0  13.8M      0  0:00:02  0:00:02 --:--:-- 31.9M
[ec2-user@ip-*-*-*-* ~]$ sudo mv /tmp/eksctl /usr/local/bin
[ec2-user@ip-*-*-*-* ~]$ eksctl version
0.174.0
3.VPCエンドポイントの作成

本稿の最初に記載した3つの設定項目のうちの1つ「1.VPCエンドポイントの作成」に該当する箇所。
awsコマンドを使用して必要なVPCエンドポイントを作成する。

[ec2-user@ip-*-*-*-* ~]$ REGION=ap-northeast-1 # VPCのリージョン(以降の手順でもこの変数を使用する)
[ec2-user@ip-*-*-*-* ~]$ VPC_ID=vpc-**********
[ec2-user@ip-*-*-*-* ~]$ MANAGE_SG_ID=sg-********** # EKS manageノードに割り当てているSGのID
[ec2-user@ip-*-*-*-* ~]$ SUBNET_IDS="subnet-********** subnet-********** subnet-**********" # プライベートサブネット3つのID
[ec2-user@ip-*-*-*-* ~]$ for i in ec2 ecr.api ecr.dkr elasticloadbalancing xray logs sts autoscaling; do aws ec2 create-vpc-endpoint --vpc-endpoint-type Interface --vpc-id ${VPC_ID} --subnet-ids ${SUBNET_IDS} --security-group-ids ${MANAGE_SG_ID} --service-name com.amazonaws.${REGION}.${i} --output text; done

VPCENDPOINT     2024-03-20T10:04:23.494000+00:00        ipv4    ************    True    False   com.amazonaws.ap-northeast-1.ec2        pending vpce-**********  Interface       vpc-**********
DNSENTRIES      vpce-**********.ec2.ap-northeast-1.vpce.amazonaws.com   **********
DNSENTRIES      vpce-**********-ap-northeast-1d.ec2.ap-northeast-1.vpce.amazonaws.com   **********
DNSENTRIES      vpce-**********-ap-northeast-1c.ec2.ap-northeast-1.vpce.amazonaws.com   **********
DNSENTRIES      vpce-**********-ap-northeast-1a.ec2.ap-northeast-1.vpce.amazonaws.com   **********
DNSENTRIES      ec2.ap-northeast-1.amazonaws.com        ZONEIDPENDING
DNSOPTIONS      ipv4
GROUPS  sg-**********    eks-manage-sg
NETWORKINTERFACEIDS     eni-**********
NETWORKINTERFACEIDS     eni-**********
NETWORKINTERFACEIDS     eni-**********
SUBNETIDS       subnet-**********
SUBNETIDS       subnet-**********
SUBNETIDS       subnet-**********
... # 上記の出力の繰り返し

上記を実行すると以下のようにVPCエンドポイントが作成される。
vpc_endpoint_list.png

4.EKS構築設定ファイルを作成

本稿の最初に記載した3つの設定項目のうちの1つ「2.EKSのプライベートエンドポイント設定」に該当する箇所。
eks.yamlを以下のように作成する。
コメントを入れている箇所はそれぞれの環境・要件に合わせて修正すること。

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eks-test                       # EKSクラスター名
  region: ap-northeast-1               # リージョン
  version: "1.29"                      # 導入したいEKSのバージョン

vpc:
  sharedNodeSecurityGroup: sg-**********    # EKS manageノードに割り当てているSGのID
  clusterEndpoints:
    publicAccess:  false
    privateAccess: true
  id: "vpc-**********"                      # EKSを配置するVPCのID
  subnets:
    private:
      ap-northeast-1a:
          id: "subnet-**********"           # プライベートサブネット1(a)のID
      ap-northeast-1c:
          id: "subnet-**********"           # プライベートサブネット2(c)のID
      ap-northeast-1d:
          id: "subnet-**********"           # プライベートサブネット3(d)のID

managedNodeGroups:
  - name: eks-node-group1                          # ノードグループ名
    labels: { role:  test }                        # ラベル
    instanceType: t2.xlarge                        # EKSノードのインスタンスタイプ
    minSize: 2                                     # EKSノードの最小台数
    maxSize: 6                                     # EKSノードの最大台数
    desiredCapacity: 2                             # EKSノードの初期台数
    volumeSize: 20                                 # EKSノードのストレージ容量
    privateNetworking: true
    ssh:
      allow: true
      publicKeyPath: ~/.ssh/id_rsa.pub
    tags:
      nodegroup-role: test                         # EKSノードグループにつけるタグ

addons:                                            # 必要に応じてアドオンを追加
- name: vpc-cni
  version: latest
- name: coredns
  version: latest
- name: kube-proxy
  version: latest
- name: aws-ebs-csi-driver
  version: latest
5.EKS構築

eksctlコマンドおよび4で作成したeks.yamlを用いてEKSを構築する。

[ec2-user@ip-*-*-*-* ~]$ eksctl create cluster -f eks.yaml

2024-03-20 12:39:08 [?]  eksctl version 0.174.0
2024-03-20 12:39:08 [?]  using region ap-northeast-1
2024-03-20 12:39:08 [!]  warning, having public access disallowed will subsequently interfere with some features of eksctl. This will require running subsequent eksctl (and Kubernetes) commands/API calls from within the VPC.  Running these in the VPC requires making updates to some AWS resources.  See: https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html for more details
2024-03-20 12:39:08 [!]  security group rules may be added by eksctl; see vpc.manageSharedNodeSecurityGroupRules to disable this behavior
2024-03-20 12:39:08 [?]  using existing VPC (vpc-**********) and subnets (private:map[ap-northeast-1a:{subnet-********** ap-northeast-1a ********** } ap-northeast-1c:{subnet-********** ap-northeast-1c ********** } ap-northeast-1d:{subnet-********** ap-northeast-1d ********** }] public:map[])
2024-03-20 12:39:08 [!]  custom VPC/subnets will be used; if resulting cluster doesn't function as expected, make sure to review the configuration of VPC/subnets
2024-03-20 12:39:08 [?]  nodegroup "eks-node-group1" will use "" [AmazonLinux2/1.29]
2024-03-20 12:39:08 [?]  using SSH public key "/home/ec2-user/.ssh/id_rsa.pub" as "eksctl-eks-test-nodegroup-eks-node-group1-**********"
2024-03-20 12:39:08 [?]  using Kubernetes version 1.29
2024-03-20 12:39:08 [?]  creating EKS cluster "eks-test" in "ap-northeast-1" region with managed nodes
2024-03-20 12:39:08 [?]  1 nodegroup (eks-node-group1) was included (based on the include/exclude rules)
2024-03-20 12:39:08 [?]  will create a CloudFormation stack for cluster itself and 0 nodegroup stack(s)
2024-03-20 12:39:08 [?]  will create a CloudFormation stack for cluster itself and 1 managed nodegroup stack(s)
2024-03-20 12:39:08 [?]  if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=ap-northeast-1 --cluster=eks-test'
2024-03-20 12:39:08 [?]  Kubernetes API endpoint access will use provided values {publicAccess=false, privateAccess=true} for cluster "eks-test" in "ap-northeast-1"
2024-03-20 12:39:08 [?]  CloudWatch logging will not be enabled for cluster "eks-test" in "ap-northeast-1"
2024-03-20 12:39:08 [?]  you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=ap-northeast-1 --cluster=eks-test'
2024-03-20 12:39:08 [?]
2 sequential tasks: { create cluster control plane "eks-test",
    2 sequential sub-tasks: {
        2 sequential sub-tasks: {
            wait for control plane to become ready,
            1 task: { create addons },
        },
        create managed nodegroup "eks-node-group1",
    }
}
2024-03-20 12:39:08 [?]  building cluster stack "eksctl-eks-test-cluster"
2024-03-20 12:39:09 [?]  deploying stack "eksctl-eks-test-cluster"
2024-03-20 12:39:39 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:40:09 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:41:09 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:42:09 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:43:09 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:44:09 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:45:09 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:46:09 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:47:09 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:48:09 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:49:09 [?]  waiting for CloudFormation stack "eksctl-eks-test-cluster"
2024-03-20 12:51:11 [!]  OIDC is disabled but policies are required/specified for this addon. Users are responsible for attaching the policies to all nodegroup roles
2024-03-20 12:51:11 [?]  creating addon
2024-03-20 12:52:59 [?]  addon "vpc-cni" active
2024-03-20 12:52:59 [?]  building managed nodegroup stack "eksctl-eks-test-nodegroup-eks-node-group1"
2024-03-20 12:52:59 [?]  deploying stack "eksctl-eks-test-nodegroup-eks-node-group1"
2024-03-20 12:52:59 [?]  waiting for CloudFormation stack "eksctl-eks-test-nodegroup-eks-node-group1"
2024-03-20 12:53:30 [?]  waiting for CloudFormation stack "eksctl-eks-test-nodegroup-eks-node-group1"
2024-03-20 12:54:00 [?]  waiting for CloudFormation stack "eksctl-eks-test-nodegroup-eks-node-group1"
2024-03-20 12:55:13 [?]  waiting for CloudFormation stack "eksctl-eks-test-nodegroup-eks-node-group1"
2024-03-20 12:55:13 [?]  waiting for the control plane to become ready
2024-03-20 12:55:14 [?]  saved kubeconfig as "/home/ec2-user/.kube/config"
2024-03-20 12:55:14 [?]  no tasks
2024-03-20 12:55:14 [?]  all EKS cluster resources for "eks-test" have been created
2024-03-20 12:55:14 [?]  nodegroup "eks-node-group1" has 2 node(s)
2024-03-20 12:55:14 [?]  node "ip-*-*-*-*.ap-northeast-1.compute.internal" is ready
2024-03-20 12:55:14 [?]  node "ip-*-*-*-*.ap-northeast-1.compute.internal" is ready
2024-03-20 12:55:14 [?]  waiting for at least 2 node(s) to become ready in "eks-node-group1"
2024-03-20 12:55:14 [?]  nodegroup "eks-node-group1" has 2 node(s)
2024-03-20 12:55:14 [?]  node "ip-*-*-*-*.ap-northeast-1.compute.internal" is ready
2024-03-20 12:55:14 [?]  node "ip-*-*-*-*.ap-northeast-1.compute.internal" is ready
2024-03-20 12:55:15 [?]  creating addon
2024-03-20 12:55:26 [?]  addon "coredns" active
2024-03-20 12:55:26 [?]  creating addon
2024-03-20 12:56:05 [?]  addon "kube-proxy" active
2024-03-20 12:56:05 [!]  OIDC is disabled but policies are required/specified for this addon. Users are responsible for attaching the policies to all nodegroup roles
2024-03-20 12:56:05 [?]  creating addon
2024-03-20 12:57:06 [?]  addon "aws-ebs-csi-driver" active
2024-03-20 12:57:06 [?]  kubectl command should work with "/home/ec2-user/.kube/config", try 'kubectl get nodes'
2024-03-20 12:57:06 [?]  EKS cluster "eks-test" in "ap-northeast-1" region is ready

エラーが発生せずに処理がすべて完了していればOK

6.EKSのPod確認

正常に稼働しているかどうかを確認する。

[ec2-user@ip-*-*-*-* ~]$ kubectl get pods -A

NAMESPACE     NAME                                  READY   STATUS    RESTARTS   AGE
kube-system   aws-node-75cvj                        2/2     Running   0          61m
kube-system   aws-node-x8sq4                        2/2     Running   0          61m
kube-system   coredns-5877997cb7-6flrw              1/1     Running   0          61m
kube-system   coredns-5877997cb7-gw5t2              1/1     Running   0          61m
kube-system   ebs-csi-controller-7ff59ffbc6-cmq7l   6/6     Running   0          60m
kube-system   ebs-csi-controller-7ff59ffbc6-v59kb   6/6     Running   0          60m
kube-system   ebs-csi-node-6tkjf                    3/3     Running   0          60m
kube-system   ebs-csi-node-cql86                    3/3     Running   0          60m
kube-system   kube-proxy-cc9l8                      1/1     Running   0          60m
kube-system   kube-proxy-mb2xs                      1/1     Running   0          60m

全てのPodのステータスがRunningになっていればとりあえずOK

また、AWSコンソールのEKSサービスからもEKSが構築されていることを確認できる。
eks_network.png
上記画面で「APIサーバーエンドポイント」がプライベートとなっているため、EKSのパブリックエンドポイントは作成されておらず、プライベートエンドポイントのみが作成されていることも確認できる。

7.EKS用のOIDCプロバイダーの作成

EKS内のサービスアカウントがAWSのリソースにアクセスするためには、OIDCプロバイダーによりサービスアカウントとIAMロールを紐づける必要がある。
そのため、文献[8]を参考にEKS用のOIDCプロバイダーを作成する。

#変数設定
[ec2-user@ip-*-*-*-* ~]$ cluster_name=eks-test  # 作成したEKS名
[ec2-user@ip-*-*-*-* ~]$ oidc_id=$(aws eks describe-cluster --name $cluster_name --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)

#既存のOIDCプロバイダーがあるか確認(何も出力されなければOK)
[ec2-user@ip-*-*-*-* ~]$ aws iam list-open-id-connect-providers | grep $oidc_id | cut -d "/" -f4

#OIDCプロバイダー作成
[ec2-user@ip-*-*-*-* ~]$ eksctl utils associate-iam-oidc-provider --cluster $cluster_name --approve  --region ${REGION}

2024-03-20 15:43:15 [?]  will create IAM Open ID Connect provider for cluster "eks-test" in "ap-northeast-1"
2024-03-20 15:43:15 [?]  created IAM Open ID Connect provider for cluster "eks-test" in "ap-northeast-1"

最後の2行の出力が出ていれば基本的にOK

EKSのログ送信設定

CloudWatch LogsへEKSのログを送信するために、Fluent-BitをEKSに導入する。
参考文献:[6],[9]

1.Fluent-Bit用のNamespace作成

kubectlコマンドでNamespaceを作成する。

[ec2-user@ip-*-*-*-* ~]$ kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml

namespace/amazon-cloudwatch created
2.Fluent-bit設定

文献[6]を参考にFluent-Bitのconfigmapを作成する。

#configmapに使用する変数設定
[ec2-user@ip-*-*-*-* ~]$ ClusterName=eks-test  # 作成したEKS名
[ec2-user@ip-*-*-*-* ~]$ RegionName=${REGION}
[ec2-user@ip-*-*-*-* ~]$ FluentBitHttpPort='2020'
[ec2-user@ip-*-*-*-* ~]$ FluentBitReadFromHead='Off'
[ec2-user@ip-*-*-*-* ~]$ [[ ${FluentBitReadFromHead} = 'On' ]] && FluentBitReadFromTail='Off'|| FluentBitReadFromTail='On'
[ec2-user@ip-*-*-*-* ~]$ [[ -z ${FluentBitHttpPort} ]] && FluentBitHttpServer='Off' || FluentBitHttpServer='On'

#configmap作成
[ec2-user@ip-*-*-*-* ~]$ kubectl create configmap fluent-bit-cluster-info \
--from-literal=cluster.name=${ClusterName} \
--from-literal=http.server=${FluentBitHttpServer} \
--from-literal=http.port=${FluentBitHttpPort} \
--from-literal=read.head=${FluentBitReadFromHead} \
--from-literal=read.tail=${FluentBitReadFromTail} \
--from-literal=logs.region=${RegionName} -n amazon-cloudwatch

configmap/fluent-bit-cluster-info created
3.Fluent-bitインストール設定ファイルのダウンロードおよび編集

本稿の最初に記載した3つの設定項目のうちの1つ「3.ECRプライベートリポジトリの設定」に該当する箇所その1。
Fluent-BitをEKSにインストールするための設定ファイル「fluent-bit.yaml」のうち、imageの部分のレジストリURLおよびイメージタグを修正する。

# fluent-bit.yamlダウンロード
[ec2-user@ip-*-*-*-* ~]$ curl -o "fluent-bit.yaml" "https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit.yaml"

# 自身のアカウントのECRのURLを変数に格納
[ec2-user@ip-*-*-*-* ~]$ ECR_URL=************.dkr.ecr.${REGION}.amazonaws.com # *は自身のAWSアカウントIDが入る

# 修正前にコピーを取ってから、sedで該当箇所を修正
[ec2-user@ip-*-*-*-* ~]$ cp fluent-bit.yaml fluent-bit.yaml_origin
[ec2-user@ip-*-*-*-* ~]$ sed -i -e "s/public\.ecr\.aws/${ECR_URL}/g" fluent-bit.yaml
[ec2-user@ip-*-*-*-* ~]$ sed -i -e "s/aws-for-fluent-bit\:stable/aws-for-fluent-bit\:latest/g" fluent-bit.yaml

# diffで差分確認
[ec2-user@ip-*-*-*-* ~]$ diff fluent-bit.yaml fluent-bit.yaml_origin

264c264
<         image: ************.dkr.ecr.ap-northeast-1.amazonaws.com/aws-observability/aws-for-fluent-bit:latest
---
>         image: public.ecr.aws/aws-observability/aws-for-fluent-bit:stable

imageの部分が自身のAWSアカウントのECRのURL「************.dkr.ecr.ap-northeast-1.amazonaws.com」に、stableがlatestなっていればOK

4.Fluent-bitのDockerイメージをECRにプッシュ

本稿の最初に記載した3つの設定項目のうちの1つ「3.ECRプライベートリポジトリの設定」に該当する箇所その2。

最初にDockerをインストールする。

[ec2-user@ip-*-*-*-* ~]$ sudo yum -y install docker

Last metadata expiration check: 2:27:11 ago on Wed Mar 20 08:35:35 2024.
Dependencies resolved.
...
Complete!

次に自動起動の設定を追加して起動する。

#Dockerサービスの自動起動設定追加
[ec2-user@ip-*-*-*-* ~]$ sudo systemctl enable docker

Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.

#Dockerサービス起動
[ec2-user@ip-*-*-*-* ~]$ sudo systemctl start docker

#Dockerサービスの状態確認
[ec2-user@ip-*-*-*-* ~]$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: disabled)
     Active: active (running) since Wed 2024-03-20 11:06:30 UTC; 34s ago
...

さらにDockerのソケットファイルの所有権をec2-userに変更する。

[ec2-user@ip-*-*-*-* ~]$ sudo chown ec2-user:ec2-user /var/run/docker.sock

その後、ECRにdockerコマンドでログインをする。
ログインしないとdockerコマンドからECRにイメージをpushできない。

[ec2-user@ip-*-*-*-* ~]$ aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ECR_URL}

WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

Login Succeededと出力されればOK

イメージをpushするためのリポジトリをECRに作成する。

[ec2-user@ip-*-*-*-* ~]$ aws ecr create-repository --repository-name aws-observability/aws-for-fluent-bit
{
    "repository": {
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:************:repository/aws-observability/aws-for-fluent-bit",
        "registryId": "************",
        "repositoryName": "aws-observability/aws-for-fluent-bit",
        "repositoryUri": "************.dkr.ecr.ap-northeast-1.amazonaws.com/aws-observability/aws-for-fluent-bit",
        "createdAt": "2024-03-20T11:20:38.526000+00:00",
        "imageTagMutability": "MUTABLE",
        "imageScanningConfiguration": {
            "scanOnPush": false
        },
        "encryptionConfiguration": {
            "encryptionType": "AES256"
        }
    }
}

これでECRにFluent-Bit用のDockerイメージをpushする準備が完了。

次に、Fluent-Bit用のDockerイメージを「public.ecr.aws」からpullする。

[ec2-user@ip-*-*-*-* ~]$ docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:latest

latest: Pulling from aws-observability/aws-for-fluent-bit
e24f20ed38d8: Pull complete
d5ee7d0772fb: Pull complete
b3522e14c29a: Pull complete
7b5c60005c47: Pull complete
fa7ba58ca6bd: Pull complete
5d11aba8be65: Pull complete
ff5d63d2e5d0: Pull complete
22b4a48068bc: Pull complete
bf17f41befc5: Pull complete
8c197122eeba: Pull complete
1718c07e5d38: Pull complete
e748d46d06f9: Pull complete
971d80d73118: Pull complete
268c2b373127: Pull complete
94bc5e4d5abf: Pull complete
040dd57b0557: Pull complete
07456179860d: Pull complete
Digest: sha256:****

pullしたイメージをpushするためにタグ名を変更。

[ec2-user@ip-*-*-*-* ~]$ docker tag public.ecr.aws/aws-observability/aws-for-fluent-bit ${ECR_URL}/aws-observability/aws-for-fluent-bit
[ec2-user@ip-*-*-*-* ~]$ docker images -a

REPOSITORY                                                                               TAG       IMAGE ID       CREATED       SIZE
************.dkr.ecr.ap-northeast-1.amazonaws.com/aws-observability/aws-for-fluent-bit   latest    104b8ea43948   2 weeks ago   360MB
public.ecr.aws/aws-observability/aws-for-fluent-bit                                      latest    104b8ea43948   2 weeks ago   360MB

変更したタグ名を指定してDockerイメージをECRにpushする。

[ec2-user@ip-*-*-*-* ~]$ docker push ${ECR_URL}/aws-observability/aws-for-fluent-bit

Using default tag: latest
The push refers to repository [************.dkr.ecr.ap-northeast-1.amazonaws.com/aws-observability/aws-for-fluent-bit]
ddd392dfc7c6: Pushed
f5df5ebc7e75: Pushed
ec431e3e781f: Pushed
0bbcd3daa38c: Pushed
fb0ee3ea45a1: Pushed
9953ae53aca9: Pushed
5fe80e486609: Pushed
3b6930ee2680: Pushed
b27723df4f54: Pushed
1a20ab374a99: Pushed
f1697dcf9a9b: Pushed
a2986d8113f0: Pushed
ca4b98095e88: Pushed
0513a6f2e440: Pushed
f8cba6896692: Pushed
6c88c2627129: Pushed
644db467b0a2: Pushed
latest: digest: **** size: 4074

これによりECRのプライベートリポジトリにDockerイメージが格納される。
ecr_repo.png

5.Fluent-Bit用のサービスアカウント・IAMロール作成

文献[9]を参考に、eksctlコマンドを用いてFluent-Bit用のサービスアカウントとIAMロールを1度に作成する。※eksctlバージョン0.171.0以降でできるようになったらしい。
IAMロールにはCloudWatchLogsFullAccessの権限を付与している。
また、fluent-bit.yamlにてサービスアカウント名が「fluent-bit」とデフォルトで指定されているため、ここで作成するサービスアカウント名も「fluent-bit」に合わせている。

[ec2-user@ip-*-*-*-* ~]$ eksctl create iamserviceaccount --name fluent-bit --namespace amazon-cloudwatch --cluster ${cluster_name} --role-name eks-cloudwatchlogs-role --attach-policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess --approve --region ${REGION}

2024-03-20 17:17:26 [?]  1 iamserviceaccount (amazon-cloudwatch/fluent-bit) was included (based on the include/exclude rules)
2024-03-20 17:17:26 [!]  serviceaccounts that exist in Kubernetes will be excluded, use --override-existing-serviceaccounts to override
2024-03-20 17:17:26 [?]  1 task: {
    2 sequential sub-tasks: {
        create IAM role for serviceaccount "amazon-cloudwatch/fluent-bit",
        create serviceaccount "amazon-cloudwatch/fluent-bit",
    } }2024-03-20 17:17:26 [?]  building iamserviceaccount stack "eksctl-eks-test-addon-iamserviceaccount-amazon-cloudwatch-fluent-bit"
2024-03-20 17:17:26 [?]  deploying stack "eksctl-eks-test-addon-iamserviceaccount-amazon-cloudwatch-fluent-bit"
2024-03-20 17:17:26 [?]  waiting for CloudFormation stack "eksctl-eks-test-addon-iamserviceaccount-amazon-cloudwatch-fluent-bit"
2024-03-20 17:17:56 [?]  waiting for CloudFormation stack "eksctl-eks-test-addon-iamserviceaccount-amazon-cloudwatch-fluent-bit"
2024-03-20 17:17:56 [?]  created serviceaccount "amazon-cloudwatch/fluent-bit"
6.Fluent-Bitインストール

手順3で修正したfluent-bit.yamlを用いてFluent-Bitをインストールする。

[ec2-user@ip-*-*-*-* ~]$ kubectl apply -f fluent-bit.yaml

Warning: resource serviceaccounts/fluent-bit is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
serviceaccount/fluent-bit configured
clusterrole.rbac.authorization.k8s.io/fluent-bit-role created
clusterrolebinding.rbac.authorization.k8s.io/fluent-bit-role-binding created
configmap/fluent-bit-config created
daemonset.apps/fluent-bit created
7.動作確認

Podのステータスを確認する。

[ec2-user@ip-*-*-*-* ~]$ kubectl get pods -n amazon-cloudwatch

NAME               READY   STATUS    RESTARTS   AGE
fluent-bit-bp8z7   1/1     Running   0          2m29s
fluent-bit-jx8sv   1/1     Running   0          2m29s

RunningになっていればOK

また、イメージをECRからpull出来ていることをイベント等から確認できる。

[ec2-user@ip-*-*-*-* ~]$ kubectl events -n amazon-cloudwatch

...
18m         Normal   Pulled             Pod/fluent-bit-bp8z7   Successfully pulled image "************.dkr.ecr.ap-northeast-1.amazonaws.com/aws-observability/aws-for-fluent-bit:latest" in 6.614s (6.614s including waiting)
...

設定が正しければ、CloudWatchのロググループに

  • /aws/containerinsights/${eks_cluster_name}/application
  • /aws/containerinsights/${eks_cluster_name}/dataplane
  • /aws/containerinsights/${eks_cluster_name}/host

が作成されていることがAWSコンソール等で確認できる。
cloudwatch_logs.png

まとめ

プライベートEKSを構築するには、

  • VPCエンドポイントの作成
  • EKSのプライベートエンドポイント設定
  • ECRプライベートリポジトリの設定

の3つの工程が必要であり、その手順を実際に検証し、正常に動作することを確認できた。
プライベートな環境に構築することでセキュアなEKSとなるが、よりセキュアな構成にする場合は

  • VPCエンドポイントのポリシーの制限
  • EKS manageノードに割り当てているIAMロール等の権限最小化
  • EKSの暗号化

などを実施する必要がある。上記についてもいずれチャレンジしたい。

参考文献

[1] https://qiita.com/leomaro7/items/ae40ed156889d5c81e1c , アクセス: 2024-03-17.
[2] https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/private-clusters.html , アクセス: 2024-03-17.
[3] https://eksctl.io/usage/vpc-cluster-access/ , アクセス: 2024-03-17.
[4] https://eksctl.io/usage/eks-private-cluster/ , アクセス: 2024-03-17.
[5] https://eksctl.io/usage/vpc-configuration/#custom-shared-node-security-group , アクセス: 2024-03-17.
[6] https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-logs-FluentBit.html , アクセス: 2024-03-20.
[7] https://catalog.us-east-1.prod.workshops.aws/workshops/f5abb693-2d87-43b5-a439-77454f28e2e7/ja-JP/020_create_cluster/10_install_eksctl , アクセス: 2024-03-20.
[8] https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/enable-iam-roles-for-service-accounts.html , アクセス: 2024-03-20.
[9] https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/associate-service-account-role.html , アクセス: 2024-03-21.

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?