💡

EC2ノードインスタンスで EKS on Fargete のように振る舞うためのPod配置戦略

2025/01/20に公開

前提

  • AWS
  • EKS
  • Kubernetes 1.30
  • NodeManagement : Cluster Autoscaler

やりたいこと

EKSでEC2ノードインスタンスに特定のPodを1台だけ起動させたい。
※DeamonSetを除く

実現方法

1. ManagedNodeGroupsにec2-node-groupを追加する

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
...
managedNodeGroups:
  # Start
  - name: ec2-node-group
  # End

2. NodeにTaintsを設定する

Tolerationsを設定したPod以外スケジュールを許可しない。

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
...
managedNodeGroups:
  - name: ec2-node-group
    # Start
    taints:
      - key: runOnEc2Node
        value: "true"
        effect: NoSchedule
    # End

3. Nodeに任意のLabelを設定する

PodのnodeSelectorで指定するためのLabelを設定する。

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
...
managedNodeGroups:
  - name: ec2-node-group
    taints:
      - key: runOnEc2Node
        value: "true"
        effect: NoSchedule
    # Start
    labels:
      nodeGroupName: ec2-node-group
    # End

4. PodにTolerationsを設定する

このPodのみStep1でTaintsを設定したNodeにスケジュール可能になる。

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      # Start
      tolerations:
      - key: "runOnEc2Node"
        operator: "Equal"
        value: "true"
        effect: "NoSchedule"
      # End

5. PodにNodeSelectorを設定する

Step2で設定したラベルを指定する。

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      tolerations:
      - key: "runOnEc2Node"
        operator: "Equal"
        value: "true"
        effect: "NoSchedule"
      # Start
      nodeSelector:
        nodeGroupName: ec2-node-group
      # End

6. PodにpodAntiAffinityを設定する

Labelapp: PodAが設定されているPodがいるNodeにはスケジューリングされなくなる。つまり同一NodeにPodAが複数台起動しなくなる。

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    metadata:
      labels:
        app: PodA
    spec:
      tolerations:
      - key: "runOnEc2Node"
        operator: "Equal"
        value: "true"
        effect: "NoSchedule"
      nodeSelector:
        nodeGroupName: ec2-node-group
      # Start
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - PodA
              topologyKey: kubernetes.io/hostname
      # End

7. DeamonSetにTolerationsを設定する

Step1で設定したTailtsの影響で、Tolerationsが設定されていないDeamonSetがec2-node-groupのNodeに起動しなくなります。Tolerationsを設定しましょう。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonSetA
spec:
  selector:
    matchLabels:
      app: daemonSetA
  template:
    spec:
      tolerations:
          - operator: Exists

Step1~Step7までの設定により、Node(ec2-node-group) : PodA = 1 : 1でスケジューリングされるようになりました。

Discussion