Ingress 는 Service 가 그러하듯이 파드 오브젝트로 생성되어 동작하는 리소스가 아니다. Service 리소스를 오브젝트로 생성한다는 것은, kube-proxy 컴포넌트(파드)가 각 노드의 iptables 를 Service 에 명시된 규칙대로 조작하여 네트워크 라우팅 규칙을 설정하는 것이다. 비슷하게, Ingress 리소스는 rules 를 가지고 있는데 이것만으로는 동작하지 않고, nginx 와 같은 IngressController 오브젝트(파드)를 생성해야 작동한다. nginx 는 Ingress 에 설정한 규칙대로 로드밸런싱을 수행하는 것이다.
1. nginx ingress controller 의 구성요소
IngressController 는 여러가지 구현체가 있는데, 그 중에 흔히 쓰이는 것이 nginx ingress 이다. https://secjong.tistory.com/128 를 참고하여 helm 을 통해서 nginx ingress 를 설치하면 된다.
설치 후 클러스터에는 아래 구성요소들이 생성된다.
- NameSpace : "ingress-nginx"
- Service(type : LoadBalancer): "ingress-nginx-controller"
- Deployment : "ingress-nginx-controller"
- IngressClass: "nginx"
- ClusterRole: "ingress-nginx"
- ClusterRoleBinding: "ingress-nginx"
- ServiceAccount: "ingress-nginx"
하나씩 살펴보자.
2. NameSpace 확인
"ingress-nginx" 네임스페이스가 생성되었음을 알 수 있다.
$ kubectl get ns ingress-nginx
NAME STATUS AGE
ingress-nginx Active 12m
3. Service 확인
LoadBalancer 로 생성된 서비스를 조회해본다.
$ kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.104.104.52 <pending> 80:31080/TCP,443:31443/TCP 16m
ingress-nginx-controller-admission ClusterIP 10.102.98.136 <none> 443/TCP 16m
3. Deployment, Pod 확인
$ kubectl -n ingress-nginx get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
ingress-nginx-controller 1/1 1 1 18m
$ kubectl -n ingress-nginx get pods
NAME READY STATUS RESTARTS AGE
ingress-nginx-controller-7854678f64-mfcdn 1/1 Running 0 18m
4. IngressClass 확인
아래 커맨드처럼 생성된 IngressClass 를 확인한다. "nginx" 라는 이름으로 생성되었음을 알 수 있다. ingressclass.kubernetes.io/is-default-class: "true" 어노테이션으로 지정되어, Ingress 리소스에 ingressClass 미지정시 기본으로 사용되는 IngressClass 임을 알 수 있다.
$ kubectl get ingressclasses.networking.k8s.io nginx -o yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
annotations:
ingressclass.kubernetes.io/is-default-class: "true" # Ingress 리소스에 ingressClass 를 지정하지 않았을 시 본 ingressClass 가 기본으로 지정됨.
...
name: nginx
spec:
controller: k8s.io/ingress-nginx
아래 커맨드처럼 ingress-nginx-controller 파드에 지정한 ingress-class 를 확인하면 "nginx"로 지정된 것을 알 수 있다. 즉, nginx pod 가 "nginx" 라는 IngressClass 를 사용하는 것이다. 이렇게 함으로써 ingressClass: "nginx" 로 지정한 Ingress 의 규칙들이 이 컨트롤러에 적용되게 된다.
$ kubectl -n ingress-nginx get pods ingress-nginx-controller-7854678f64-mfcdn -o yaml | grep -C 10 ingress-class
uid: baf392a9-6db8-45cb-886b-413720112744
resourceVersion: "667784"
uid: 06a2c0b7-6a18-4bc6-b0ac-8ead5a6f61a7
spec:
containers:
- args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
- --election-id=ingress-nginx-leader
- --controller-class=k8s.io/ingress-nginx
- --ingress-class=nginx # 여기에서 ingress-class 명 파라미터를 주입
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
- --enable-metrics=false
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
5. ClusterRole 확인
아래 커맨드처럼 클러스터의 모든 Ingress, EndpointSlice 정보 조회가 포함된 ClusterRole 이 생성되었음을 확인한다.
$ kubectl get clusterrole ingress-nginx -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
...
name: ingress-nginx
...
rules:
...
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
...
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
- get
6. ClusterRoleBinding 확인
"ingress-nginx" ClusterRole 이 어떤 ServiceAccount 에서 사용되는지 아래 커맨드로 확인한다. "ingress-nginx"라는 이름의 SA 에서 사용됨을 알 수 있다.
$ kubectl get clusterrolebindings.rbac.authorization.k8s.io ingress-nginx -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
...
name: ingress-nginx
...
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
7. ServiceAccount 확인
아래 커맨드로 "ingress-nginx" SA 를 확인한다.
$ kubectl -n ingress-nginx get sa ingress-nginx
NAME SECRETS AGE
ingress-nginx 0 38m
아래 커맨드처럼 ingress-nginx-controller 파드에 지정한 serviceAccount 를 확인하면 "ingress-nginx" 로 지정된 것을 알 수 있다. 즉, nginx pod 는 "ingress-nginx" SA 를 통해 "ingress-nginx" 라는 ClusterRole 의 권한을 가지기 때문에 클러스터의 모든 Ingress, EndpointSlice 를 조회할 수 있다.
$ kubectl -n ingress-nginx get pods ingress-nginx-controller-7854678f64-mfcdn -o yaml
apiVersion: v1
kind: Pod
metadata:
...
name: ingress-nginx-controller-7854678f64-mfcdn
...
spec:
...
serviceAccount: ingress-nginx
...
8. 트래픽 전달 흐름
이렇게 생성된 nginx controller 를 통해 트래픽이 파드까지 전달되는 단계는 아래와 같다.
- 사용자 -> Router: 도메인(예: example.com)으로 DNS 에 질의하여 공인 IP에 HTTP/HTTPS 요청을 보냄
- Router -> NLB: 공인 IP가 할당된 Router 에서 트래픽을 받아 연결된 Gateway 에서 LoadBalancer type Service 로 생성된 NLB 로 트래픽을 보냄
- NLB -> NodePort: NLB가 트래픽을 받아서 쿠버네티스 워커 노드의 NodePort로 전달
- NodePort -> Nginx: 노드로 들어온 패킷을 Nginx Ingress Controller 파드(Pod)로 라우팅
- Nginx -> Pod: Ingress 리소스 규칙(Host, Path, Service)을 확인하여 요청을 전달할 타깃 ClusterIP Service 를 확인 후 EndpointSlices 를 조회하여 실제 파드 IP로 직접 트래픽 전달
5번에서 Nginx 가 Pod 의 IP 를 조회하여야 하는데, 먼저 Ingress 정보에서 Service 정보를 취득한 후, Service 정보로부터 EndpointSlice 의 Pod IP 정보를 취득하는 방식이다. 위에서 확인했던 ClusterRole 이 존재하고, Nginx Pod 에서 serviceAccount 를 통해 그 Role 을 사용하기 때문에 가능한 것이다.
실제로 Nginx Pod 는 Service IP 를 통해 Pod 로 트래픽을 로드밸런싱하지 "않고", 직접 Pod IP 로 트래픽을 쏜다. Service 는 단지 EndpointSlice 를 조회하는 용도로 사용된다. Service 를 생성함으로 설정되는 iptables 조차 라우팅에 관여하지 않는다.
'Kubernetes' 카테고리의 다른 글
| [KUBERNETES] Ingress 에서 SSL Redirect 하기 (0) | 2026.07.29 |
|---|---|
| [KUBERNETES] tls 인증서를 Ingress 에 적용하기 (0) | 2026.07.29 |
| [KUBERNETES] nginx ingress controller 의 두가지 버전 링크 정리 (0) | 2026.07.26 |
| [KUBERNETES] Pod 에서 특정 도메인을 IP 에 매핑하기 (0) | 2026.07.21 |
| [KUBERNETES] Pod 에서 바라보는 DNS 를 직접 지정하기 (0) | 2026.07.21 |