Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Fargate ?

AWS Fargate는 컨테이너 기반 애플리케이션을 실행하기 위한 서버리스 컴퓨팅 엔진으로 사용자는 서버나 클러스터를 직접 프로비저닝하거나 관리할 필요 없이 컨테이너만 정의하고 실행할 수 있도록 지원한다.

기존 Amazon ECS 또는 Amazon EKS에서 클러스터를 운영하기 위해 EC2 인스턴스를 직접 구성하고 관리하던 방식과 달리 Fargate는 이러한 인프라를 완전히 추상화하고 컨테이너 단위의 리소스 할당과 실행을 제공한다.

Fargate는 컨테이너 하나하나를 독립된 경량 가상 머신에서 실행되도록 설계되어 있는데 AWS에서 “Firecracker”라는 자체 하이퍼바이저 기술을 기반으로 구현하였으며 이 기술 덕분에 각 Fargate 작업(Pod 또는 Task)은 완전히 분리된 환경에서 실행된다.

이러한 구조는 멀티 테넌시 환경에서도 보안 리스크를 줄이는 데 유리하며 동시에 리소스를 효율적으로 사용하며 부트 타임 측면에서도 뛰어난 성능을 확보할 수 있다.

Fargate 장점

Fargate를 사용할 때 가장 큰 이점 중 하나는 오토스케일링과 비용 최적화 측면이다.

사용자는 컨테이너가 필요한 리소스(cpu, memory)만 정의하면 되고 실제 컴퓨팅 자원은 Fargate가 그에 맞게 할당한다. 정해진 리소스를 초과하거나 유휴 인스턴스에 대한 비용을 고민할 필요가 없으며 사용한 만큼만 과금되는 구조이기 때문에 스팟 인스턴스를 사용하지 않더라도 비용 예측이 용이하다. 특히, 워크로드가 일정하지 않고 일시적으로 폭증하거나 갑작스럽게 감소하는 환경에서 Fargate가 적합한 아키텍처라고 볼 수 있다.

EKS에서 Fargate를 사용하는 경우, 클러스터 내 일부 네임스페이스나 특정 레이블 조건에 맞는 파드들만 Fargate에서 실행되도록 설정할 수 있다. 이를 위해 Fargate Profile을 정의하며 이 안에서 어떤 네임스페이스와 어떤 레이블 셀렉터를 가진 파드가 Fargate에서 실행될지를 명시한다.

Fargate 파드는 일반 EC2 노드에서 동작하는 파드와 달리 Pod당 1개의 경량 VM이 자동으로 생성되고, 고유한 ENI(Elastic Network Interface)가 할당된다. 이 구조는 Pod 간 네트워크 격리를 강화하며 IP 충돌 없이 대규모 분산 환경에서 안정적인 통신이 가능하도록 해준다.

애플리케이션의 주요 워크로드를 서버리스 환경으로 마이그레이션하고자 할 때 Fargate를 사용하는 것이 좋다. AWS Fargate는 인프라의 복잡성을 줄이고 컨테이너 중심의 애플리케이션 운영을 단순화하는 데 최적화된 서비스다.

보안, 자동화, 확장성, 그리고 비용 효율성 측면에서 뛰어난 이점을 제공하며 특히 DevOps나 MLOps 환경처럼 빠른 배포와 민첩성이 중요한 경우 활용도가 더욱 높아진다.

Fargate 사용 시 주의 사항

파드는 반드시 지정된 리소스(cpu, memory)를 명확히 선언해야 하며 볼륨 마운트 방식에 제한이 있어 EFS 외의 퍼시스턴트 볼륨 사용이 어려울 수 있다.

노드별로 하나씩 실행되어야 하는 로그 수집 에이전트와 같은 데몬셋은 Fargate에서 직접 실행할 수 없기 때문에 이러한 워크로드는 EC2 노드 기반으로 병행 운영해야 한다.

Fargate 배포 실습

terraform state list
data.aws_availability_zones.available
module.vpc.aws_default_network_acl.this[0]
module.vpc.aws_default_route_table.default[0]
module.vpc.aws_default_security_group.this[0]
module.vpc.aws_eip.nat[0]
module.vpc.aws_internet_gateway.this[0]
module.vpc.aws_nat_gateway.this[0]
module.vpc.aws_route.private_nat_gateway[0]
module.vpc.aws_route.public_internet_gateway[0]
module.vpc.aws_route_table.private[0]
module.vpc.aws_route_table.public[0]
module.vpc.aws_route_table_association.private[0]
module.vpc.aws_route_table_association.private[1]
module.vpc.aws_route_table_association.private[2]
module.vpc.aws_route_table_association.public[0]
module.vpc.aws_route_table_association.public[1]
module.vpc.aws_route_table_association.public[2]
module.vpc.aws_subnet.private[0]
module.vpc.aws_subnet.private[1]
module.vpc.aws_subnet.private[2]
module.vpc.aws_subnet.public[0]
module.vpc.aws_subnet.public[1]
module.vpc.aws_subnet.public[2]
module.vpc.aws_vpc.this[0]

AWS EKS Fargate 기반 클러스터의 동작 방식

aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml
k get nodes
NAME                                                      STATUS   ROLES    AGE     VERSION
fargate-ip-10-10-13-33.ap-northeast-2.compute.internal    Ready    <none>   7m34s   v1.30.8-eks-2d5f260
fargate-ip-10-10-23-214.ap-northeast-2.compute.internal   Ready    <none>   7m33s   v1.30.8-eks-2d5f260
fargate-ip-10-10-28-33.ap-northeast-2.compute.internal    Ready    <none>   7m43s   v1.30.8-eks-2d5f260
fargate-ip-10-10-32-126.ap-northeast-2.compute.internal   Ready    <none>   7m34s   v1.30.8-eks-2d5f260

4개의 노드들은 Fargate 기반 Pod가 실행될 때 마다 생성된 Micro VM이다.

INTERNAL-IP가 Pod IP와 1:1로 같은데 Fargate에서는 파드당 1개의 ENI를 할당하므로, Pod = Node = ENI 1개로 매핑된다.

k get po -A -o wide
NAMESPACE     NAME                                            READY   STATUS    RESTARTS   AGE    IP             NODE                                                      NOMINATED NODE   READINESS GATES
kube-system   aws-load-balancer-controller-849b7f6bbf-5q2wv   1/1     Running   0          8m7s   10.10.13.33    fargate-ip-10-10-13-33.ap-northeast-2.compute.internal    <none>           <none>
kube-system   aws-load-balancer-controller-849b7f6bbf-zrl9f   1/1     Running   0          8m7s   10.10.28.33    fargate-ip-10-10-28-33.ap-northeast-2.compute.internal    <none>           <none>
kube-system   coredns-64696d8b7f-4dxzj                        1/1     Running   0          8m9s   10.10.23.214   fargate-ip-10-10-23-214.ap-northeast-2.compute.internal   <none>           <none>
kube-system   coredns-64696d8b7f-7nczc                        1/1     Running   0          8m9s   10.10.32.126   fargate-ip-10-10-32-126.ap-northeast-2.compute.internal   <none>           <none>

aws-load-balancer-controller 파드인데 파드의 ip가 노드와 동일한 것을 확인할 수 있다.

Fargate는 파드 단위로 격리된 경량 VM을 생성하는데 그 VM이 노드로 등록되며, 파드 IP = 노드 IP = ENI IP 로 같다.

K8s API Service - Endpoints

kubectl get svc,ep
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   172.20.0.1   <none>        443/TCP   28m
 
NAME                   ENDPOINTS                       AGE
endpoints/kubernetes   10.0.44.211:443,10.0.7.38:443   28m

IP들은 EKS에서 관리하는 ENI (Elastic Network Interface) 에 붙어있는것이고, EKS control plane이 사용하는 IP이며

Fargate 노드들이랑은 별도의 것이다.

k get csr
NAME        AGE     SIGNERNAME                      REQUESTOR                                                             REQUESTEDDURATION   CONDITION
csr-54dhq   7m52s   kubernetes.io/kubelet-serving   system:node:fargate-ip-10-10-32-126.ap-northeast-2.compute.internal   <none>              Approved,Issued
csr-9596h   8m1s    kubernetes.io/kubelet-serving   system:node:fargate-ip-10-10-28-33.ap-northeast-2.compute.internal    <none>              Approved,Issued
csr-kp54q   7m53s   kubernetes.io/kubelet-serving   system:node:fargate-ip-10-10-13-33.ap-northeast-2.compute.internal    <none>              Approved,Issued
csr-zwr9v   7m51s   kubernetes.io/kubelet-serving   system:node:fargate-ip-10-10-23-214.ap-northeast-2.compute.internal   <none>              Approved,Issued
kubectl describe node | grep eks.amazonaws.com/compute-type
                    eks.amazonaws.com/compute-type=fargate
Taints:             eks.amazonaws.com/compute-type=fargate:NoSchedule
                    eks.amazonaws.com/compute-type=fargate
Taints:             eks.amazonaws.com/compute-type=fargate:NoSchedule
                    eks.amazonaws.com/compute-type=fargate
Taints:             eks.amazonaws.com/compute-type=fargate:NoSchedule
                    eks.amazonaws.com/compute-type=fargate
Taints:             eks.amazonaws.com/compute-type=fargate:NoSchedule
kubectl get pdb -n kube-system
NAME                           MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
aws-load-balancer-controller   N/A             1                 1                     72m
coredns                        N/A             1                 1                     79m
kubectl get apiservices.apiregistration.k8s.io | grep eks
v1.metrics.eks.amazonaws.com           kube-system/eks-extension-metrics-api   True        80m

EKS가 자체적으로 설치한 metrics.eks.amazonaws.com API를 통해 파드와 노드의 메트릭을 수집한다.

표준 metrics-server와 비슷한 역할을 하며, kubectl top pod, kubectl top node 같은 명령어가 동작하기 위해 필요하다.

EKS 확장 메트릭 API의 리소스 정보

kubectl get --raw "/apis/metrics.eks.amazonaws.com/v1" | jq
{
  "kind": "APIResourceList",
  "apiVersion": "v1",
  "groupVersion": "metrics.eks.amazonaws.com/v1",
  "resources": [
    {
      "name": "kcm",
      "singularName": "kcm",
      "namespaced": false,
      "kind": "KCM",
      "verbs": []
    },
    {
      "name": "kcm/metrics",
      "singularName": "",
      "namespaced": false,
      "kind": "KCM",
      "verbs": [
        "get"
      ]
    },
    {
      "name": "ksh",
      "singularName": "ksh",
      "namespaced": false,
      "kind": "KSH",
      "verbs": []
    },
    {
      "name": "ksh/metrics",
      "singularName": "",
      "namespaced": false,
      "kind": "KSH",
      "verbs": [
        "get"
      ]
    }
  ]
}

이 API는 EKS 관리형 컨트롤 플레인(KCM, Scheduler)의 내부 메트릭을 노출하는 AWS EKS 전용 확장 기능이다.

Kube Controller Manager의 컨트롤러 큐 지연, 리소스 리컨사일을 나타내는 메트릭과, Kube Scheduler 스케줄링 시간, 실패율 매트릭을 의미한다.

EKS에서 사용자에게 관리형 컨트롤 플레인의 성능 정보를 제공하며 Prometheus/CloudWatch 등에서 모니터링을 가능하게 한다.

kube-system 네임스페이스 내 ConfigMap 목록

kubectl get cm -n kube-system
NAME                                                   DATA   AGE
amazon-vpc-cni                                         7      80m
aws-auth                                               1      76m
aws-load-balancer-controller-leader                    0      72m
coredns                                                1      80m
extension-apiserver-authentication                     6      81m
kube-apiserver-legacy-service-account-token-tracking   1      81m
kube-proxy                                             1      80m
kube-proxy-config                                      1      80m
kube-root-ca.crt                                       1      81m
 
kubectl get cm -n kube-system aws-auth -o yaml
data:
  mapRoles: |
    - rolearn: arn:aws:iam::<계정번호>:role/app_wildcard-<랜덤값>
      username: system:node:
      groups:
        - system:bootstrappers
        - system:nodes
        - system:node-proxier
 
    - rolearn: arn:aws:iam::<계정번호>:role/kube-system-<랜덤값>
      username: system:node:
      groups:
        - system:bootstrappers
        - system:nodes
        - system:node-proxier

aws-auth ConfigMap은 EKS의 핵심 설정으로, IAM Role → K8s 사용자/그룹 매핑을 정의한다.

여기서 등록된 IAM Role들은 EKS Fargate Profile에 의해 자동으로 생성된 것이고 system:node, system:node-proxier 권한이 있어야 노드 역할을 하고 서비스/엔드포인트 등에 접근할 수 있게 된다.

kubectl rbac-tool lookup system:node-proxier
  SUBJECT             | SUBJECT TYPE | SCOPE       | NAMESPACE | ROLE                | BINDING
----------------------+--------------+-------------+-----------+---------------------+-------------------------
  system:node-proxier | Group        | ClusterRole |           | system:node-proxier | eks:kube-proxy-fargate

EKS Fargate에서는 kube-proxy는 컨트롤 플레인에서 관리되는 형태라 직접 파드로 띄우지 않고 실제 트래픽 라우팅은 AWS VPC CNI에 의해 ENI 단에서 처리된다.

netshoot 디플로이먼트

kubectl create ns study-aews
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: netshoot
  namespace: study-aews
spec:
  replicas: 1
  selector:
    matchLabels:
      app: netshoot
  template:
    metadata:
      labels:
        app: netshoot
    spec:
      containers:
      - name: netshoot
        image: nicolaka/netshoot
        command: ["tail"]
        args: ["-f", "/dev/null"]
        resources: 
          requests:
            cpu: 500m
            memory: 500Mi
          limits:
            cpu: 2
            memory: 2Gi
      terminationGracePeriodSeconds: 0
EOF
study-aews    netshoot-84558cd8d9-l5k7d                       1/1     Running   0          72s

파드가 뜨기까지 1분 10초 정도 소요되었다.

 netshoot-84558cd8d9-l5k7d  ~  ip -c a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
4: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default qlen 1000
    link/ether 6e:fe:81:61:4a:54 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.10.21.243/20 brd 10.10.31.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::6cfe:81ff:fe61:4a54/64 scope link
       valid_lft forever preferred_lft forever

AWS EKS에서 Fargate 기반으로 생성된 netshoot 파드는 AWS가 제공하는 경량 가상머신(마이크로VM) 위에서 실행된다.

먼저 네트워크 구성을 보면, ip a 명령 결과를 통해 파드는 eth0@if6 인터페이스를 통해 10.10.21.243/20이라는 IP를 할당받고 있다.

이는 AWS VPC CNI 플러그인을 통해 자동으로 VPC 서브넷의 프라이빗 IP 주소가 할당된 것으로, Fargate는 파드당 ENI(Elastic Network Interface)를 하나씩 부여한다. 이로 인해 파드는 EC2 인스턴스 없이도 고유한 VPC 네트워크 상의 IP를 갖고 있으며, 다른 리소스들과 동일한 네트워크 내에서 통신할 수 있다

netshoot-84558cd8d9-l5k7d  ~  cat /etc/resolv.conf
search study-aews.svc.cluster.local svc.cluster.local cluster.local ap-northeast-2.compute.internal
nameserver 172.20.0.10
options ndots:5

이 파드는 /etc/resolv.conf 파일을 통해 DNS 설정을 172.20.0.10으로 사용하고 있다. 이는 클러스터 내 CoreDNS의 ClusterIP이며, search 도메인으로 study-aews.svc.cluster.local, cluster.local, ap-northeast-2.compute.internal 등이 설정되어 있어 쿠버네티스 내부 서비스 디스커버리를 지원한다.

 netshoot-84558cd8d9-l5k7d  ~  curl ipinfo.io/ip
15.164.5.221#

실제로 curl ipinfo.io/ip 명령을 통해 외부에서 볼 수 있는 퍼블릭 IP는 15.164.5.221이며 이는 NAT Gateway를 통해 인터넷으로 나가는 출구 IP를 의미한다.

 netshoot-84558cd8d9-l5k7d  ~  ping -c 1 10.10.32.126
PING 10.10.32.126 (10.10.32.126) 56(84) bytes of data.
64 bytes from 10.10.32.126: icmp_seq=1 ttl=125 time=1.26 ms
 
--- 10.10.32.126 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.264/1.264/1.264/0.000 ms

다른 파드로의 핑 또한 정상적으로 통신 확인이 된다.

 netshoot-84558cd8d9-l5k7d  ~  df -Th
Filesystem           Type            Size      Used Available Use% Mounted on
overlay              overlay        29.4G     11.8G     16.0G  43% /
tmpfs                tmpfs          64.0M         0     64.0M   0% /dev
tmpfs                tmpfs           1.9G         0      1.9G   0% /sys/fs/cgroup
overlay              overlay        29.4G     11.8G     16.0G  43% /etc/hosts
overlay              overlay        29.4G     11.8G     16.0G  43% /dev/termination-log
/dev/nvme1n1         ext4           29.4G     11.8G     16.0G  43% /etc/hostname
/dev/nvme1n1         ext4           29.4G     11.8G     16.0G  43% /etc/resolv.conf
shm                  tmpfs          64.0M         0     64.0M   0% /dev/shm
tmpfs                tmpfs           2.0G     12.0K      2.0G   0% /run/secrets/kubernetes.io/serviceaccount
tmpfs                tmpfs           1.9G         0      1.9G   0% /proc/acpi
tmpfs                tmpfs          64.0M         0     64.0M   0% /proc/kcore
tmpfs                tmpfs          64.0M         0     64.0M   0% /proc/keys
tmpfs                tmpfs          64.0M         0     64.0M   0% /proc/latency_stats
tmpfs                tmpfs          64.0M         0     64.0M   0% /proc/timer_list
tmpfs                tmpfs          64.0M         0     64.0M   0% /proc/sched_debug
tmpfs                tmpfs           1.9G         0      1.9G   0% /sys/firmware
 
 netshoot-84558cd8d9-l5k7d  ~  cat /etc/fstab
/dev/cdrom	/media/cdrom	iso9660	noauto,ro 0 0
/dev/usbdisk	/media/usb	vfat	noauto,ro 0 0

디스크 정보를 보면 lsblk 및 df -Th 명령어를 통해 / 루트 파일 시스템과 여러 overlay 마운트 포인트가 확인된다. Fargate에서는 각 파드를 실행할 때 독립된 ephemeral storage가 제공된다.

/dev/nvme1n1 디바이스가 마운트되어 ext4 포맷으로 포맷된 상태다. 루트 파일 시스템 및 /etc/hostname, /etc/resolv.conf 같은 주요 설정 파일도 이 디스크 상에 overlay 파일시스템 형태로 마운트되어 있으며, 이는 파드 간 격리와 보안 유지를 위한 구조다.

Fargate는 기본적으로 최대 20GiB의 ephemeral storage를 제공하고 사용량은 df 명령을 통해 43%로 확인되며 11.8GiB를 사용 중임을 보여준다. /etc/fstab에는 cdrom, usb 관련 마운트 설정만 존재하며 이는 컨테이너 기반 이미지에 포함된 디폴트 항목일 가능성이 높다.

파드 권한 탈취 시도

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: root-shell
  namespace: study-aews
spec:
  containers:
  - command:
    - /bin/cat
    image: alpine:3
    name: root-shell
    securityContext:
      privileged: true
    tty: true
    stdin: true
    volumeMounts:
    - mountPath: /host
      name: hostroot
  hostNetwork: true
  hostPID: true
  hostIPC: true
  tolerations:
  - effect: NoSchedule
    operator: Exists
  - effect: NoExecute
    operator: Exists
  volumes:
  - hostPath:
      path: /
    name: hostroot
EOF
pod/root-shell created

파드의 SecurityContext 설정을 악용하여 호스트 네임스페이스를 탈취할 수 있는 시나리오이다.

kubectl get pod -n study-aews root-shell
NAME         READY   STATUS    RESTARTS   AGE
root-shell   0/1     Pending   0          7s
 
kubectl describe pod -n study-aews root-shell | grep Events: -A 10
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  12s   fargate-scheduler  Pod not supported on Fargate: fields not supported: HostNetwork, HostPID, HostIPC, volumes not supported: hostroot is of an unsupported volume Type, invalid SecurityContext fields: Privileged

AWS Fargate의 보안 모델 상의 제약사항이 작동하여 위와 같은 파드 실행을 원천적으로 차단한다:

Fargate는 컨테이너 단위로 microVM을 생성하므로 호스트 네임스페이스 공유 자체가 불가능하며, hostPath 타입의 볼륨은 Fargate에서 지원하지 않는다.

privileged: true 같은 보안 위험 설정은 Fargate에서 금지된 필드로 간주되어 실행되지 않으며 Fargate는 완전한 격리 환경을 전제로 설계되었기 때문에, 이런 설정은 지원되지 않는 필드로 처리되어 스케줄러 단계에서 거부된다.

AWS ALB로 게임 디플로이먼트 배포

public.ecr.aws/l6m2t8p7/docker-2048:latest 이미지를 기반으로 2048 게임을 실행하는 파드 2개를 생성해본다.

Service 리소스는 생성된 파드들을 내부적으로 하나의 논리적 엔드포인트로 연결 후 클러스터 내부에서는 service-2048이라는 이름을 통해 포트 80으로 트래픽을 전달받게 하고, Ingress 리소스를 통해 외부에서 2048 게임에 접속할 수 있도록 한다.

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: study-aews
  name: deployment-2048
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: app-2048
  replicas: 2
  template:
    metadata:
      labels:
        app.kubernetes.io/name: app-2048
    spec:
      containers:
      - image: public.ecr.aws/l6m2t8p7/docker-2048:latest
        imagePullPolicy: Always
        name: app-2048
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  namespace: study-aews
  name: service-2048
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: ClusterIP
  selector:
    app.kubernetes.io/name: app-2048
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: study-aews
  name: ingress-2048
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: service-2048
              port:
                number: 80
EOF
kubectl get ingress,svc,ep,pod -n study-aews
NAME                                     CLASS   HOSTS   ADDRESS                                                                       PORTS   AGE
ingress.networking.k8s.io/ingress-2048   alb     *       k8s-studyaew-ingress2-08c53ee834-445593286.ap-northeast-2.elb.amazonaws.com   80      56s
 
NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/service-2048   ClusterIP   172.20.222.46   <none>        80/TCP    56s
 
NAME                     ENDPOINTS                         AGE
endpoints/service-2048   10.10.29.119:80,10.10.37.110:80   56s
 
NAME                                  READY   STATUS    RESTARTS   AGE
pod/deployment-2048-85f8c7d69-hjpcb   1/1     Running   0          56s
pod/deployment-2048-85f8c7d69-k26dp   1/1     Running   0          56s
pod/netshoot-84558cd8d9-l5k7d         1/1     Running   0          13m
 
kubectl get targetgroupbindings -n study-aews
NAME                               SERVICE-NAME   SERVICE-PORT   TARGET-TYPE   AGE
k8s-studyaew-service2-0f181eccc6   service-2048   80             ip            72s
kubectl describe ingress -n study-aews ingress-2048
Name:             ingress-2048
Labels:           <none>
Namespace:        study-aews
Address:          k8s-studyaew-ingress2-08c53ee834-445593286.ap-northeast-2.elb.amazonaws.com
Ingress Class:    alb
Default backend:  <default>
Rules:
  Host        Path  Backends
  ----        ----  --------
  *
              /   service-2048:80 (10.10.37.110:80,10.10.29.119:80)
Annotations:  alb.ingress.kubernetes.io/scheme: internet-facing
              alb.ingress.kubernetes.io/target-type: ip
Events:
  Type    Reason                  Age   From     Message
  ----    ------                  ----  ----     -------
  Normal  SuccessfullyReconciled  92s   ingress  Successfully reconciled
kubectl get ingress -n study-aews ingress-2048 -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' | awk '{ print "Game URL = http://"$1 }'
 
Game URL = http://k8s-studyaew-ingress2~~.com

EKS Ingress를 통해 생성된 AWS ALB 확인

사용자가 ALB DNS에 접속하게 되면 ALB의 리스너가 / 경로 패턴 규칙에 따라 트래픽을 서비스로 전달한다.

서비스는 대상 그룹인 파드들로 트래픽을 포워딩하며 두 파드는 각각 포트 80에서 응답하고 ALB는 요청을 분산 처리하여 로드밸런싱 역할을 수행하게 된다.

리소스 삭제

kubectl delete ingress ingress-2048 -n study-aews
kubectl delete svc service-2048 -n study-aews && kubectl delete deploy deployment-2048 -n study-aews

Fargate job

cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: Job
metadata:
  name: busybox1
  namespace: study-aews
spec:
  template:
    spec:
      containers:
      - name: busybox
        image: busybox
        command: ["/bin/sh", "-c", "sleep 10"]
      restartPolicy: Never
  ttlSecondsAfterFinished: 60 # <-- TTL controller
---
apiVersion: batch/v1
kind: Job
metadata:
  name: busybox2
  namespace: study-aews
spec:
  template:
    spec:
      containers:
      - name: busybox
        image: busybox
        command: ["/bin/sh", "-c", "sleep 10"]
      restartPolicy: Never
EOF
kubectl get job,pod -n study-aews
NAME                 STATUS    COMPLETIONS   DURATION   AGE
job.batch/busybox1   Running   0/1           25s        25s
job.batch/busybox2   Running   0/1           25s        25s
 
NAME                            READY   STATUS    RESTARTS   AGE
pod/busybox1-b86hr              0/1     Pending   0          25s
pod/busybox2-d2lpt              0/1     Pending   0          25s
pod/netshoot-84558cd8d9-l5k7d   1/1     Running   0          23m
 
kubectl get job,pod -n study-aews
NAME                 STATUS     COMPLETIONS   DURATION   AGE
job.batch/busybox1   Complete   1/1           58s        60s
job.batch/busybox2   Complete   1/1           56s        60s
 
NAME                            READY   STATUS      RESTARTS   AGE
pod/busybox1-b86hr              0/1     Completed   0          60s
pod/busybox2-d2lpt              0/1     Completed   0          60s
pod/netshoot-84558cd8d9-l5k7d   1/1     Running     0          24m
 
kubectl get job,pod -n study-aews
NAME                 STATUS     COMPLETIONS   DURATION   AGE
job.batch/busybox2   Complete   1/1           56s        2m48s
 
NAME                            READY   STATUS      RESTARTS   AGE
pod/busybox2-d2lpt              0/1     Completed   0          2m49s
pod/netshoot-84558cd8d9-l5k7d   1/1     Running     0          26m

파드를 배포하면 60초 전까지는 Pending이였다가 60초 이후부터는 파드가 실행되며 완료된 시점부터는 삭제되는 것을 확인할 수 있다.

Fargate Logging

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
  namespace: study-aews
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        ports:
        - containerPort: 80
          name: http
        resources:
          requests:
            cpu: 500m
            memory: 500Mi
          limits:
            cpu: 2
            memory: 2Gi
---
apiVersion: v1
kind: Service
metadata:
  name: sample-app
  namespace: study-aews
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  type: ClusterIP
EOF
kubectl get pod -n study-aews -l app=nginx
NAME                          READY   STATUS    RESTARTS   AGE
sample-app-7596c66778-7j6mb   1/1     Running   0          74s
sample-app-7596c66778-msd9z   1/1     Running   0          74s
kubectl exec -it deploy/netshoot -n study-aews -- curl sample-app | grep title
while true; do kubectl exec -it deploy/netshoot -n study-aews -- curl sample-app | grep title; sleep 1; echo ; date; done;
<title>Welcome to nginx!</title>
<title>Welcome to nginx!</title>
 
2025년 3월 23일 일요일 04시 33분 42초 KST
<title>Welcome to nginx!</title>
 
2025년 3월 23일 일요일 04시 33분 44초 KST
<title>Welcome to nginx!</title>
 
2025년 3월 23일 일요일 04시 33분 45초 KST
<title>Welcome to nginx!</title>