모험가

AEWS 2주차 - Networking(Service, kube-proxy mode, ingress) 본문

쿠버네티스/AEWS

AEWS 2주차 - Networking(Service, kube-proxy mode, ingress)

라리음 2025. 2. 13. 13:56



본 글은 가시다님이 진행하시는 AEWS(AWS EKS Workshop Study)를 참여하여 정리한 글입니다. 
모르는 부분이 많아서 틀린 내용이 있다면 말씀 부탁드리겠습니다!

 

 

 


Service

 

 

Service란?

 

파드 집합에서 실행중인 애플리케이션을 네트워크 서비스로 노출하는 추상화 방법입니다.

 

Pod는 재부팅하게되면 IP가 변동이 있습니다. 이때 만약 파드의 IP로 접근하던 애플리케이션이 있다면 해당 파드를 못찾게 되고 장애로 이어지게 됩니다.

 

이때 필요한 것이 서비스입니다. 엔드포인트를 생성하여 해당 규칙에 해당하는 파드들로 접근할 수 있게끔 만드는 오브젝트입니다. (또한 부하분산도 가능합니다.)

 

 

 

Service 타입은 다음과 같습니다.

 

Service 타입 설명 특징 및 용도
ClusterIP 기본값, 내부 네트워크에서만 접근 가능 - 클러스터 내부 통신용
- kubectl port-forward 등을 통해 로컬에서 접근 가능
NodePort 노드의 특정 포트(30000~32767)에서
외부 접근 가능
- 특정 노드의 IP + 포트를 통해 접근 가능
- 로드 밸런싱 기능 부족
- VPC 내부에서만 접근 가능
LoadBalancer AWS의 ALB 또는 NLB와 연동하여
외부에서 접근 가능
- AWS ALB 또는 NLB와 연결되어 자동으로 Load Balancer 생성
- ALB를 사용하면 HTTP(S) 기반 라우팅 가능
- 비용 발생 (ALB, NLB 요금)
ExternalName DNS 이름을 기반으로 외부 서비스와 연결 - CNAME 레코드를 사용하여 외부 서비스와 연결
- AWS RDS, 3rd Party API 등과 연동 시 유용

 

 

 

자세한 설명은 공식 문서에서 확인이 가능합니다.

https://kubernetes.io/ko/docs/concepts/services-networking/service/#proxy-mode-userspace

 

서비스

외부와 접하는 단일 엔드포인트 뒤에 있는 클러스터에서 실행되는 애플리케이션을 노출시키며, 이는 워크로드가 여러 백엔드로 나뉘어 있는 경우에도 가능하다.

kubernetes.io

 

 

 

 

 

 

서비스 종류에 따른 도식화 그림

 

 

 

ClusterIP

 

ClusterIP

 

 

장점
✔️ 기본값으로 설정되므로 별도 설정 없이 사용 가능.
✔️ 내부 네트워크에서만 접근 가능하여 보안이 뛰어남.

 

단점
❌ 외부에서 직접 접근할 수 없어서 추가적인 포트포워딩(kubectl port-forward) 필요.

 

 

 

NodePort

 

Nodeport

 

 

장점
✔️ VPC 내부의 다른 애플리케이션이나 Bastion Host에서 접근 가능.
✔️ 간단한 테스트 환경에서 유용함.

 

단점
❌ 특정 노드에 종속적이므로, 노드 장애 발생 시 문제 가능.
❌ 직접적인 부하 분산 기능이 없음(ALB, NLB 필요).

 

 

 

LoadBalancer

 

LoadBalancer

 

 

장점
✔️ AWS의 자동 스케일링 및 로드 밸런싱 기능 활용 가능.
✔️ ALB를 사용하면 HTTP(S) 기반 트래픽을 라우팅 가능.

 

단점
❌ 비용 발생(ALB/NLB 사용료).
❌ 생성 속도가 느릴 수 있음.

 

 


NLB배포

 

NLB 및 ALB를 배포하기 위해서는 AWS LoadBalancer Controller을 설치해야합니다. 

(기본값은 CLB입니다.)

 

NLB IP 모드 동작 흐름

 

 

 

AWS LoadBalancer Controller 배포

# 설치 전 CRD 확인
kubectl get crd

# Helm Chart 설치
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME


## 설치 확인
kubectl get crd
kubectl explain ingressclassparams.elbv2.k8s.aws
kubectl explain targetgroupbindings.elbv2.k8s.aws

kubectl get deployment -n kube-system aws-load-balancer-controller
kubectl describe deploy -n kube-system aws-load-balancer-controller
kubectl describe deploy -n kube-system aws-load-balancer-controller | grep 'Service Account'
  Service Account:  aws-load-balancer-controller
 
# 클러스터롤, 롤 확인
kubectl describe clusterrolebindings.rbac.authorization.k8s.io aws-load-balancer-controller-rolebinding
kubectl describe clusterroles.rbac.authorization.k8s.io aws-load-balancer-controller-role

 

 

결과 화면

 

설치하면 crd에 추가된 것을 확인할 수 있으며, aws-load-balancer-controller라는 SA를 사용함을 확인할 수 있습니다.

 

 

서비스/파드 배포 테스트 with NLB

# 디플로이먼트 & 서비스 생성
cat << EOF > echo-service-nlb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-echo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: deploy-websrv
  template:
    metadata:
      labels:
        app: deploy-websrv
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: aews-websrv
        image: k8s.gcr.io/echoserver:1.5
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: svc-nlb-ip-type
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
    service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: "8080"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
  type: LoadBalancer
  loadBalancerClass: service.k8s.aws/nlb
  selector:
    app: deploy-websrv
EOF
kubectl apply -f echo-service-nlb.yaml


# 확인
aws elbv2 describe-load-balancers --query 'LoadBalancers[*].State.Code' --output text
kubectl get deploy,pod
kubectl get svc,ep,ingressclassparams,targetgroupbindings
kubectl get targetgroupbindings -o json | jq

 

 

kube-ops-view 화면

 

 

kube-ops-view에는 2번, 3번 노드에 파드가 1개씩 뜬 것을 확인할 수 있습니다. 

 

이제 콘솔을 확인해봅니다.

 

 

NLB 화면

 

 

대상 그룹 화면

 

 

실제로 Target group에는 2번, 3번 노드에 떠 있는 pod ip로 전달하고 있음을 확인합니다.

 

 

 


kube-proxy 모드

 

 

 

kube-proxy는 서비스와 파드를 연결해주는 중요한 역할을 합니다.

 

kube-proxy 역할

 

 

 

kube-proxy 모드에는 여러가지가 있습니다.

 

저는 iptables 프로식 모드와 IPVS 프록시 모드에 대해서 조금만 공부하고 넘어가겠습니다.

 

 

 

 

 

0. User space 프록시 모드

 

user space mode

 

 

갑자기 User space 모드가 왜 나왔나 싶으실 수도 있습니다.

하지만 iptables 모드를 설명하기 위해서는 설명을 드려야 조금 더 이해가 빠르실 것 같아서 추가하였습니다.

 

User spce 모드의 순서는 아래와 같습니다.

1. Client 요청 -> 노드의 인터페이스 수신

2. 커널 영역의 netfilter에 의해서 정보를 확인후 사용자 영역의 kube-proxy로 전달

3. 목적지 정보를 확인하여 다시 해당 파드로 요청

 

이러한 과정에서는 커널 영역의 netfiter이 계속해서 사용자 영역의 kube-proxy와 통신을 하기때문에 비효율적인 성능 소모가 이루어집니다. (비용 포함)

 

이를 개선하기 위해서 iptables proxy, IPVS를 사용합니다.

 

 

 

1. iptables 프록시 모드

 

iptables proxy mode

 

 

 

iptables 프록시 모드는 kube-proxy가 통신 트래픽 전달 과정에 직접적으로 관여하지 않습니다.

 

kube-proxy는 서비스 설정 시 관련된 정보(iptables 규칙)을 netfilter에 적용해서 작동합니다.

* 그러면 커널 영역과 사용자 영역의 불필요한 통신이 줄어듭니다.

 

iptables 프록시 모드의 순서는 아래와 같습니다.

1. Client 요청 -> 노드의 인터페이스 수신

2. 커널 영역의 iptables 규칙이 포함된 netfilter에 의해서 바로 해당 파드로 요청

 

하지만 매우 많은 서비스가 생겨 규칙이 많아 질 경우 규칙들은 순번대로 평가하기 때문에 지연이 생깁니다.

이는 운영 관리에도 큰 영향을 끼칠 수 있습니다.

 

 

 

2. IPVS 프록시 모드

 

 

 

 

IPVS 프록시 모드는 커널 영역의 넷필터에서 동작하는 L4 로드밸랜서입니다.

 

또한 iptables과 다르게 해시 테이블 기반의 규칙 처리를 하므로 대량의 서비스도 빠르게 처리가 가능하며, 다양한 로드 밸런싱 알고리즘을 지원해 유연한 트래픽 분배가 가능합니다.

 

IPVS 프록시 모드의 순서는 아래와 같습니다.

1. Client 요청 -> 노드의 인터페이스 수신

2. 커널 영역의 IPVS 모듈이 서비스 테이블을 확인하여 바로 적절한 파드로 요청

 

iptables과 동일하게 사용자 영역을 거치지 않고 커널 영역에서 직접 전달합니다. 

하지만 아래와 같은 차이점이 있습니다.

 

📌 iptables vs IPVS 성능 차이

 

기능 iptables 모드 IPVS 모드
트래픽 처리 방식 netfilter의 iptables 규칙을 순차적으로 평가 커널 내장된 IPVS를 사용하여 해시 기반 라우팅
서비스 개수 증가 시 성능 서비스가 많아질수록 규칙 평가 지연 발생 대량의 서비스 처리에도 성능 저하 없음
로드 밸런싱 알고리즘 단순한 DNAT 방식 다양한 로드 밸런싱 알고리즘 지원(RR, WRR, LC 등)
운영 관리 규칙이 많아질수록 관리 어려움 대규모 트래픽을 안정적으로 처리 가능

 

 


 

Ingress

 

 

클러스터 내부의 서비스(ClusterIP, NodePort, Loadbalancer)를 외부로 노출(HTTP/HTTPS)할 수 있습니다.

AWS에서는 대표적으로 Ingress를 사용하여 ALB로 경로 기반 라우팅을 제공합니다.

 

 

ALB IP 모드 동작 흐름

 

 

서비스/파드 배포 테스트 with ALB

# 게임 파드와 Service, Ingress 배포
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: game-2048
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: game-2048
  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: game-2048
  name: service-2048
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: NodePort
  selector:
    app.kubernetes.io/name: app-2048
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: game-2048
  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 game-2048
kubectl get-all -n game-2048

# ALB 생성 확인
aws elbv2 describe-load-balancers --query 'LoadBalancers[?contains(LoadBalancerName, `k8s-game2048`) == `true`]' | jq

# ALB 생성 확인
aws elbv2 describe-load-balancers --query 'LoadBalancers[?contains(LoadBalancerName, `k8s-game2048`) == `true`]' | jq

# 게임 접속 : ALB 주소로 웹 접속
kubectl get ingress -n game-2048 ingress-2048 -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' | awk '{ print "Game URL = http://"$1 }'

# 파드 IP 확인
kubectl get pod -n game-2048 -owide

 

 

kube-ops-view 화면

 

 

이번 Pod는 노드 1번, 3번에 떴습니다. 동일하게 콘솔에서 확인해봅니다.

 

콘솔 화면

 

Target group 화면

 

 

대상 그룹에서도 노드 1번과 3번의 파드가 연결되어 있음을 확인할 수 있습니다.

 

 

서비스 화면

 

 

 

 

 

이렇게 Service, kube-proxy mode, ingress에 대해서 알아보았습니다.

 

 

 


출처

 

 

가시다님 강의노트

 

 

https://www.youtube.com/watch?si=wH7fGLTdRs2rPxKl&t=2521&v=E49Q3y9wsUo&feature=youtu.be

 

 

https://kschoi728.tistory.com/285

 

[9주차] AWS EKS : VPC CNI : 네트워크 정보

CloudNet@ 가시다님이 진행하는 쿠버네티스 네트워크 스터디 3기 ✅ AWS VPC CNIKubernetes 클러스터에서 Pod의 네트워크를 관리하기 위해 만들어진 네트워크 인터페이스 플러그인으로, Kubernetes가 클러

kschoi728.tistory.com

 

 

https://heea.tistory.com/entry/AEWS-2%EA%B8%B0-EKS-Networking

 

[AEWS 2기] EKS Networking

EKS 스터디 CloudNet@팀의 AEWS 2기에 작성된 자료를 베이스로 작성된 블로깅입니다. 저는 쿠버네티스를 접하고 사용안하고, 공부안한지 너무 오래되어서 개념을 익힐겸 핸즈온처럼 하나하나 해보았

heea.tistory.com