-
[따배쿠] Kubernets 개념 정리Kubernetes/쿠버네티스 기본개념 2025. 12. 1. 22:21
1. 쿠버네티스의 구조
- 마스터(컨트롤 플레인): 클러스터의 두뇌. 상태 관리, 스케줄링, 제어.
- 워커 노드: 실제로 파드(Pod)와 컨테이너가 돌아가는 손발
- 쿠버네티스의 동작 원리
1) 애플리케이션을 컨테이너 이미지로 빌드
2) 빌드된 컨테이너 이미지를 Docker 명령어를 사용해 Docker Hub 같은 이미지 레지스트리에 업로드
3) kubectl 명령어 통해 클러스터에 해당 컨테이너 실행해달라고 컨트롤 플레인에 요청
4) 컨트롤 플레인의 API Server는 이 요청을 수신한뒤, 어떤 워커노드에서 실행하는 것이 적절한지 Scheduler에 판단 요청
5) Scheduler는 클러스터 상태와 리소스를 고려해 최적의 워커노드 선택하고, 그 결과를 API Server에 전달
6) API Server는 선택된 워커노드의 Kubelet(에이전트)에게 컨테이너 실행 지시 내림
7) kubelet은 이 실행 지시를 컨테이너 런타임(Docker)이 이해할 수 있는 명령으로 변환하여 Docker 데몬에 전달
8) Docker 데몬은 Docker Hub에서 이미지 존재하는지 확인후, 이미지를 내려받아 컨테이너 실행
9) 이때 실행되는 컨테이너의 실행단위를 Pod라고 함
[요약]
[사용자] kubectl
↓
[kube-apiserver] (마스터)
↓
[etcd] 에 상태 저장
+ [scheduler] 어느 노드에 배치할지 결정
+ [controller-manager] 원하는 상태로 맞추도록 감시 ex) nginx는 반드시 1개이상 pod가 떠있어야함
↓
[선택된 워커 노드의 kubelet]
↓
[컨테이너 런타임(Docker 등)] 컨테이너 생성/삭제
2. 마스터 컴포넌트
2-1. ETCD
- 역할: 쿠버네티스의 DB 역할을 하는 Key-Value 저장소
- 저장하는 것들
- 어떤 네임스페이스가 있는지
- 어떤 파드/디플로이먼트/서비스가 생성되어 있는지
- 각 노드의 상태 정보 (Ready, NotReady 등)
- 리소스 사용량(간접적으로) 및 각종 설정 정보 등
워커 노드에서 kubelet + cAdvisor가 수집한 정보가 마스터로 전달되고, 마스터는 이 상태를 etcd에 저장함
2-2. Kube-apiserver
- 역할: 쿠버네티스의 정문(Front Door)
- 우리가 kubectl로 보내는 모든 요청은 결국 kube-apiserver를 통해 들어감
- 요청 검증
- 요청 형식이 맞는지 (YAML 스키마, 필수 필드 등)
- 권한이 있는 사용자/서비스 계정인지 (RBAC/인증/인가)
- 요청 처리
- 새로운 리소스 생성(Deployment, Pod, Service 등)
- 기존 리소스 조회, 수정, 삭제
- 필요한 경우 etcd에 기록하거나 읽어옴
- 다른 컴포넌트와의 허브 역할
- scheduler, controller-manager, kubelet도 모두 kube-apiserver를 통해 통신
2-3. Kube-scheduler
- 역할: 파드(Pod)를 어느 노드에 배치할지 결정하는 ‘스케줄링 담당자’
- 사용자가 Deployment나 Pod를 생성 → kube-apiserver에 요청
- 파드는 아직 “어느 노드에도 배치되지 않은 상태”로 etcd에 저장
- kube-scheduler가 이 파드를 보고,
- 각 노드의 CPU/메모리 사용량
- 파드에 걸린 제약조건(노드 셀렉터, taint/toleration, affinity 등)
- 기타 정책들
을 고려해서 가장 적합한 노드를 선택
- 그 결과를 다시 kube-apiserver에 알려주면, 해당 노드의 kubelet이 파드를 실제로 띄움
2-4. Kube-controller-manager
- 역할: 클러스터가 원하는 상태(Desired State)를 유지하도록 감시하고 맞춰주는 컨트롤러 묶음
- -예: replicas: 3이라고 선언 → “항상 파드 3개 유지시키겠다”는 의미
- kube-controller-manager 안에는 여러 가지 컨트롤러가 돌아감
- ReplicationController / ReplicaSet Controller
- “파드 3개 유지”라고 되어 있는데 실제 파드가 2개뿐이면 → 1개 더 생성
- 반대로 4개가 떠 있으면 → 1개 제거
- Node Controller
- 노드가 죽거나 응답이 없으면 → 노드 상태를 NotReady 등으로 표시하고 파드를 다른 노드로 재스케줄링
- Job / CronJob Controller
- 완료형 작업(Job)이나 주기 작업(CronJob) 상태 관리
3. 워커 노드 컴포넌트
3-1. Kubelet
- 역할: 해당 노드의 관리인(에이전트)
- 하는 일:
- kube-apiserver를 통해 전달된 “이 노드에 이런 파드를 띄워라”라는 명령을 받음
- 컨테이너 런타임(Docker, containerd 등)에게 실제 컨테이너 생성/삭제 요청
- 파드 및 컨테이너 상태를 주기적으로 체크
- 상태/리소스 정보를 마스터(컨트롤 플레인)로 보고
- 여기서 cAdvisor(컨테이너 모니터링 툴)가 kubelet에 포함되어, CPU/메모리, 파일 시스템 사용량 같은 메트릭을 수집
3-2. Kube-proxy
- 역할: 워커 노드에서 서비스(Service)와 파드 간 네트워크 트래픽을 라우팅해 주는 컴포넌트
구체적으로는:
- Service가 갖고 있는 ClusterIP, NodePort 등으로 들어온 트래픽을
- 실제 파드들의 IP/포트로 로드밸런싱하여 전달
- 내부적으로 iptables, IPVS 등을 사용해 패킷을 적절히 분배
3-3. 컨테이너 런타임 (Docker, containerd 등)
현재는 Docker뿐만 아니라 containerd, CRI-O 등 다양한 런타임이 사용됩니다.
- kubelet이 “이 이미지로 컨테이너 하나 띄워줘”라고 요청하면,
- 컨테이너 런타임이 실제로
- 이미지를 풀(Pull)하고
- 컨테이너 프로세스를 만들고
- 네트워크/볼륨 등을 설정한 뒤 실행
4. 네임스페이스
- 클러스터를 논리적으로 분리하는 공간
- 실제로는 물리장비를 나눠쓰는거지만, 독립된것 처럼 kubectl 명령어를 사용할 수 있음
ex) 하나의 클러스터를 여러 팀/환경이 같이 쓰는 경우
kubectl create namespace orange --dry-run=client -o yaml
kubectl create namespace blue --dry-run=client -o yaml
kubectl create namespace red --dry-run=client -o yaml
- --dry-run=client
- 실제로 네임스페이스를 생성하지 않고, “생성했다면 어떤 리소스가 만들어질지”를 클라이언트 측에서 미리 보여줌
- -o yaml
- 결과를 YAML 형태로 출력 → 이걸 파일로 저장해서 나중에 kubectl apply -f로 쓸 수 있음
# 네임스페이스 생성 kubectl create namespace blue # dry-run을 통해 확인 kubectl create namespace blue --dry-run -o yaml > blue.yaml # 파일로 네임스페이스 생성 kubectl create -f blue.yaml # 실행파일에도 네임스페이스 지정할 수 있음 metadata: name : mypod namespace : blue
5. Kubectl config & context 관리
- KubeConfig?
> kubectl이 쿠버네티스 클러스터에 접속하기 위한 설정 파일
> ~/.kube/config
- cluster : 접속할 쿠버네티스 서버 주소
- user : 어떤 사용자(인증 정보)로 접속할지- Context?
> context : cluster + user + namespace 묶음
> dev-cluster에 dev-user로 접속해서 default 네임스페이스에서 작업하겠다
# config 목록 확인 kubectl config view # 현재 context 확인 kubectl config current-context # context 목록 확인 kubectl config get-contexts # context 변경 kubectl config use-context cluster name # 컨텍스트 생성 kubectl config set-context test@kubenetes --cluster=test-cluster --user=minikube --namespace=test6. Yaml 템플릿과 API
- Yaml 템플릿?
> 사람이 쉽게 읽을 수 있는 데이터 직렬화 양식
> key-value 타입임
> 띄어쓰기 주의
- API Version?
> Kuernetes Object 정의 시 apiVersion이 필요
- api object의 종류: Deployment/ Pod/ ReplicaSet/ ReplicationController/ Service/ PersistentVolume
- api 버전 알 수 있는 명령어 : kubectl explain pod
7. Pod (파드)
- 컨테이너(들)을 표현하는 쿠버네티스 API의 최소 단위
- Pod에는 한개 혹은 여러개의 컨테이너가 포함될 수 있음
- 컨테이너 == 애플리케이션
- 파드 세부정보 확인
kubectl get pods web1 -o json | grep -i podip7-1) Single Container Pod 생성 방법
- CLI 직접 실행 : kubectl run webserver --image=nginx:1.14
- Yaml 파일 만들어서 실행
# pod-nginx.yaml apiVersion : v1 kind : Pod metadata : name : webserver spec : containers: - name : nginx-container image : nginx:1.14 imagePullPolicy : - containerPort : 80 protocol : TCP # 생성 kubectl create -f pod-nginx.yaml7-2) Multi Container Pod 생성 방법
- 하나의 Pod 에 컨테이너 여러개!
- 컨테이너의 IP는 동일함
> cat pod-multi.yaml ✔ apiVersion: v1 kind: Pod metadata: name: multipod spec: containers: - name: nginx-container image: nginx:1.14 ports: - containerPort: 80 - name: centos-container image: centos:7 command: - sleep - "10000"7-3) nginx-container 접속
kubectl exec multipod -c nginx-container -it -- /bin/bash7-4) pod 로그 및 정보 확인
# 싱글파드 kubectl logs nginx-container # 멀티파드 (파드명 - 컨테이너) kubectl logs multipod -c nginx-containerkubectl describe pod pod명7-5) pod 동작 flow
> kubectl get pods -o wide --watch > pending > containercreating > running > terminating7-6) livenessProbe를 이용해 Self-healing Pod 만들기
Self-healing ?
>건강한 컨테이너로 어플리케이션이 동작하도록 보장함
livenessProbe?
> pod가 계속 실행할 수 있음을 보장
apiVersion: v1 kind: Pod metadata: name: webserver spec: containers: - name: nginx-container image: nginx:1.14 livenessProbe: httpGet: path: / port: 80 # http 80의 /으로 접속해서, 응답 여부에 다라 건강상태 판단> 컨테이너 별로 검진 방법이 다를 수 있음

건강하지 않다고 판단되면?
- 해당 컨테이너를 죽이고, 허브에서 이미지를 받아서 다시 실행함
- 이때 파드가 아닌 컨테이너를 다시 실행하는거라 IP는 그대로
7-7) Init Container
- 메인 컨테이너 실행 전에 미리 동작시킬 컨테이너
- 메인 컨테이너가 실행되기 전에 사전 초기화 작업이 필요한 경우 실행
- init container -> main 컨테이너가 실행
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app.kubernetes.io/name: MyApp spec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]7-8) Infra Container (Pause)
- 파드 안에 아무것도 하지 않는 Pasue가 생김, 파드마다 생기고 사라지는...
- 파드에 대한 인프라를 관리하고 생성해
7-9) Static Pod
- api 서버 없이, 특정 워커노드에 있는 kubelet demon으로 만들어지는 컨테이너
- /etc/kubernetes/manifests 디렉토리에 yaml파일 저장하면 실행함
7-10) Pod에 Resource 할당하기 (cpu, memory)
- 컨트롤 플레인의 스케쥴러가 pod를 노드에 배치할 때 무슨 기준으로?
Resource Requests
> 파드를 실행하기 위한 최소 리소스양을 요청
> 최소한의 cpu,mem이 보장되는 곳에 배치 요청 (yaml파일에서 설정)
> 없으면 파드가 배치되지 않음
Resource Limits
> 파드가 사용할 수 있는 최대 리소스양을 제한
> memory limit을 초과해서 사용되는 파드는 종료되고, 다시 스케줄링
> 여기까지만 써라.. 이런느낌, 노드에 남는자원 있어도 더 못씀
1MB = 1000KB (사람이 쓰는 단위, 메가바이트)
lMi = 1024Ki (컴퓨터 기준 단위, 메비바이트)
apiVersion: v1 kind: Pod metadata: name: nginx-pod-env spec: containers: - name: nginx-container image: nginx:1.14 ports: - containerPort: 80 protocol: TCP env: - name: MYVAR value: "testvalue" resources: requests: memory: 500Mi # Mi로 해주면 cpu: 200m # 용량으로 하거나 limits: memory: 1Gi cpu: 1 # 갯수로 하거나7-11) Pod 환경변수 설정과 실행 패턴
# pod-nginx-resouces.yaml apiVersion: v1 kind: Pod metadata: name: nginx-pod-env spec: containers: - name: nginx-container image: nginx:1.14 ports: - containerPort: 80 protocol: TCP env: # 환경 변수 설정 - name: MYVAR value: "testvalue"실행 패턴의 종류
- 사이드 카 : 주 컨테이너 옆에서 보조 작업만 함
ex) 주 컨테이너 : 웹서버 / 사이드 카 컨테이너 : 로그 수집(fluentd), 프록시(istio), 인증
- 어댑터 : 형식이 다른 데이터를 번역해주는 중간 변환기, 데이터 가공/변환, 외부 시스템이 이해할 수 있게..ex) 주 컨테이너 : 앱 / 어댑터 컨테이너 : 표준 포맷으로 변환 (prometheus 메트릭)
- 앰버서더 : 외부 통신 대신 처리
ex) 주 컨테이너 : 앱 / 앰버서더 : 프록시, 라우터, API Gateway, 외부 <-> 내부 통신 중
8. Controller
- Pod의 개수를 보장

8-1) Replication Controller
- 요구하는 파드의 개수를 보장함
- 요구하는 pod의 개수보다 부족 -> template을 이용해 Pod를 추가함
- labels와 동일한 selector를 봄
# 정보 확인 kubectl get rc # 자세하게 확인 kubectl describe rc rc-nginx # 라벨 붙이기 kubectl run redis --image=redis --labels=app=webui --dry-run -o yaml > redis.yaml # 실행중인 라벨 kubectl get pods --show-labels # edit로 레플리카 늘리기 kubectl edit rc rc-nginx # scale로 kubectl scale rc rc-nginx --replicas=2- selector, replicas, template
apiVersion: v1 kind: ReplicationController metadata: name: rc-nginx spec: replicas: 3 selector: app: webui template: metadata: name: nginx-pod labels: app: webui spec: containers: - name: nginx-container image: nginx:1.14- kubectl edit 에서 템플릿 이미지를 바꾸면?
> 아무일도 안 일어남. selector만 보고 움직이기 때문...
8-2) ReplicaSet
# ReplicationSelector selector: app: webui version: "2.1" # ReplicaSet selector: matchLabels: app: webui matchExpressions: - {key: version, operator: In, value: ["2.1", "2.2"]}- IN : key와 value를 지정하여 key,value가 일치하는 pod만 연결
- NotIn: key는 일치하고 value는 일치하지 않는 Pod에 연결
- Exists: Key에 맞는 label의 Pod를 연결
- DoesNotExist: Key와 다른 label의 Pod를 연결
8-3) Deployment
- ReplicaSet을 컨트롤해서 Pod수를 조절함 (업데이트/롤백/롤링업데이트)
- Rolling Update & Rolling back을 위함
- Deployment가 ReplicaSet을 어떻게 다루는지?
- 기존 ReplicaSet(A)이 Pod를 N개 유지 중
- 업데이트 발생 → Deployment가 새 ReplicaSet(B) 생성
- RollingUpdate 정책에 따라
- B의 Pod를 조금씩 늘리고
- A의 Pod를 조금씩 줄임
- 안정화되면 A는 0개로 줄어들지만 RS 자체는 남겨서 롤백 가능
rollout
- history
- pause
- restart
- resume
- status
- undo
# Deployment: web, RelicaSet : web-xxx, pod : web-xxx-abcde kubectl create deployment web --image=nginx:1.25 --replicas=3 # 상세 확인 kubectl describe deployment web kubectl describe rs -l app=web # 스케일 조정 kubectl scale deployment web --replicas=5 # 이미지 업데이트 kubectl set image deployment/web nginx=nginx:1.26 # 진행상태 (업데이트하면 새로운 RS가 생기고, 기존 RS는 롤백용으로 남음) kubectl rollout status deployment/web- RollingUpdate 옵션 (maxSurge / maxUnavailable)
- maxSurge: 업데이트 중 추가로 더 띄워도 되는 Pod 수/비율
- maxUnavailable: 업데이트 중 일시적으로 내려가도 되는 Pod 수/비율
예: replicas=10일 때
- maxSurge=2 → 최대 12개까지 띄우며 교체 가능
- maxUnavailable=1 → 업데이트 중 동시에 1개까지는 내려가도 됨
(이 값은 YAML의 spec.strategy.rollingUpdate에 설정)
8-4) DaemonSet
- 클러스터의 각 노드마다 Pod를 1개씩 실행되도록 보장하는 컨트롤러
- 노드가 새로 추가되면 → 그 노드에도 자동으로 Pod가 하나 더 배치
- 노드가 빠지면 → 해당 노드의 Pod도 같이 사라짐
대표 사례
- 로그 수집기: Fluent Bit, Fluentd
- 모니터링 에이전트: node-exporter, Datadog agent
- 네트워크/스토리지 플러그인 구성요소: CNI, CSI node plugin 등
- 노드 단위로 항상 붙어 있어야 하는 것들
kubectl get ds -A kubectl describe ds <ds-name> -n <ns> kubectl get pods -o wide -n <ns> # 노드별로 하나씩 뜨는지 확인
8-5) StatefulSet
1. Pod 이름(Identity) 고정
- Pod 이름이 myapp-0, myapp-1 처럼 순서(ordinal) 기반으로 고정
- 재시작/재스케줄돼도 동일한 identity를 유지하려고 함
2. 안정적인 네트워크 ID
- 보통 Headless Service와 같이 써서 myapp-0.<svc-name> 같은 고정 DNS로 접근 가능
3. 스토리지(PV)와의 1:1 결합
- volumeClaimTemplates로 Pod마다 PVC를 따로 만들고
- Pod가 재생성되어도 “그 Pod의 디스크”를 다시 붙여줌
대표 사례
- DB/메시지큐/분산시스템:
- MySQL, PostgreSQL, MongoDB
- Kafka, Zookeeper(또는 etcd 계열)
- “데이터 + 순서 + 고정 식별자”가 중요한 서비스
Deployment와 차이
- Deployment는 Pod 이름이 랜덤 해시로 바뀌어도 OK인 Stateless 서비스에 적합
- StatefulSet은 순서대로 생성/종료(기본 동작) 같은 특성이 있어서
롤링 업데이트/스케일 방식이 더 신중함
kubectl get sts -A kubectl describe sts <name> -n <ns> kubectl get pods -n <ns> -o wide kubectl get pvc -n <ns>
8-6) Kubernetes Job Controller
핵심 개념
- Job은 한 번 실행해서 끝나는 작업(배치)을 위한 컨트롤러
- Pod가 성공적으로 종료(Exit 0)하면 Job은 완료(Complete)
- 실패하면 조건에 따라 재시도하여 성공 완료를 보장
Job 생성 예시
kubectl create job sleep-job --image=busybox -- sh -c "sleep 5"상태 확인:
kubectl get job kubectl describe job sleep-job kubectl get pods --selector=job-name=sleep-job kubectl logs -l job-name=sleep-job중요한 옵션
- backoffLimit: 실패 재시도 횟수
- activeDeadlineSeconds: 최대 실행 시간(타임아웃)
- ttlSecondsAfterFinished: 완료 후 Job/Pod 자동 정리
- completions: 성공 완료 횟수(예: 10번 성공해야 끝)
- parallelism: 동시에 실행할 Pod 수(병렬 배치)
8-7) Kubernetes CronJob
- CronJob은 스케줄 기반으로 Job을 주기적으로 생성하는 컨트롤러
- 즉, CronJob → (시간마다) Job 생성 → Pod 실행 → 완료
분 시 일 월 요일예시:
- 매일 02:30
- 30 2 * * *
- 매 5분마다
- */5 * * * *
- 매주 월요일 09:00
- 0 9 * * 1
kubectl create cronjob hello-cron --image=busybox --schedule="*/5 * * * *" -- sh -c "date; echo hello"확인:
kubectl get cronjob kubectl describe cronjob hello-cron kubectl get jobs --watch kubectl logs -l job-name=<생성된 job 이름>- concurrencyPolicy
- Allow(기본): 겹쳐도 실행
- Forbid: 이전 작업이 아직이면 다음 스킵
- Replace: 이전 작업을 죽이고 새로 실행
- startingDeadlineSeconds: 지연 허용 시간(스케줄 놓쳤을 때)
- successfulJobsHistoryLimit, failedJobsHistoryLimit: Job 기록 보관 개수
- Job 쪽 옵션(backoffLimit, ttlSecondsAfterFinished)도 같이 중요
9. Service
- pod는 언제든지 재시작될수 있고, ip가 계속 바뀜.
- pod들로 트래픽을 보내는 고정 진입점이 필요함
- service란 pod 그룹을 라벨로 묶어서 하나의 고정 진입점 (가상Ip + dns)으로 제공하는 리소스
9-1) Cluster IP
- 클러스터 내부에서만 접근 가능한 서비스
- 기본 타입으로, 명시안하면 그냥 이거임
- 서비스가 clusterip(가상ip)를 갖고, 그 ip로 들어온 트래픽을 selector로 매칭된 Pod들로 분산
- 내부 마이크로서비스 통신에서 흔함
apiVersion: v1 kind: Service metadata: name: clusterip-service spec: type: ClusterIP clusterIP: 10.100.100.100 selector: app: webui ports: - protocol: TCP port: 80 targetPort: 80 # 적용 확인 kubectl apply -f clusterip-nginx.yaml kubectl get svc clusterip-service kubectl get endpoints clusterip-service # 테스트 kubectl run testpod --image=busybox:1.36 -it --rm -- sh # 내부에서 실행 wget -qO- http://clusterip-service # 또는 wget -qO- http://10.100.100.1009-2) NodePort
- 모든 노드의 특정 포트를 열고, NodeIp: Nodeport로 들어온 트래픽을 Service->Pod로 전달함
- 개발/테스트 또는 간단한 외부노출에 사용 (실무에서는 보통 LB, Ingress)
apiVersion: v1 kind: Service metadata: name: nodeport-service spec: type: NodePort clusterIP: 10.100.100.200 selector: app: webui ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 30200 # 적용/확인 kubectl apply -f nodeport-nginx.yaml kubectl get svc nodeport-service -o wide ### 특정노드가 아니라 모든 노드에서 포트가열려서 외부에서 접근이 가능함9-3) LoadBalancer
- 클라우드(AWS,GCP)에서 외부 LB 생성후 Service로 연결해줌
- EXTERNAL-IP가 할당되어 외부에서 접속 가능
apiVersion: v1 kind: Service metadata: name: loadbalancer-service spec: type: LoadBalancer selector: app: webui ports: - protocol: TCP port: 80 targetPort: 809-4) ExternalName
- 쿠버네티스 서비스 이름을 외부 도메인으로 매핑
- 실제로는 DNS Cname같은 역할
- 이름만 연결
apiVersion: v1 kind: Service metadata: name: externalname-svc spec: type: ExternalName externalName: google.com9-5) Headless Service (clusterIP: None)
- 단일 진입점 (clusterIP)이 필요없을떄 씀
- ClusterIP: None
- servcie에 ip가 없고, Pod 각각의 엔드포인트 정보가 DNS로 제공됨
apiVersion: v1 kind: Service metadata: name: headless-service spec: clusterIP: None selector: app: webui ports: - protocol: TCP port: 80 targetPort: 809-6) kube-proxy:
- 실제 트래픽을 Pod로 보내려면 노드 레벨에서 라우팅/룰이 필요
- Service VIP(ClusterIP)로 들어온 트래픽을 실제 Pod Endpoint로 보내기 위한 규칙을 만든다
- 구현 방식
-> iptables 모드
-> ipvs 모드
NodePort 접근도 결국 kube-proxy가 규칙을 만들어 Pod로 연결되게 하는것
*** Service + DNS(CoreDNS) 동작 흐름
- Pod는 IP가 바뀌니까, 우리는 서비스 이름(DNS) 으로 접속하고, CoreDNS가 그 이름을 IP로 바꿔준다.
- http://web.default.svc.cluster.local 로 접속
- CoreDNS가 “web 서비스”의 ClusterIP 를 알려줌
- 패킷이 ClusterIP로 들어감
- kube-proxy가 규칙(iptables/ipvs)으로 실제 Pod IP들 중 하나로 보내줌
- Pod가 응답
즉,
DNS(CoreDNS)는 “이름 → 서비스 IP”
kube-proxy는 “서비스 IP → Pod IP”*** Headless Service는 뭐가 달라?
ClusterIP가 없음(clusterIP: None)
CoreDNS가 서비스 IP 대신 Pod들의 IP(Endpoint들)를 직접 응답해줌
→ “단일 진입점”이 아니라 “Pod 개별 주소 목록”을 주는 느낌10. Ingress
- 파드, 컨트롤러, 서비스와 같은 종류의 api임
- http나 https를 통해 클러스터 내부의 서비스를 외부로 노출
- service에 외부 url을 제공 (웹서비스에 유용)
- 트래픽을 로드밸런싱
- SSL 인증서 처리
- virtual hosting 을 지정
- 그렇담 loadbalancer랑 ingress의 차이..?
1) LoadBalancer(Service 타입) = “가게 앞에 전용 입구 하나 달아주는 것”
상황: 우리 서비스(예: webui) 하나를 인터넷에 공개하고 싶다.
- Service type: LoadBalancer를 만들면
- 클라우드(AWS/GCP/Azure)가 외부용 로드밸런서(LB) 를 하나 만들어주고
- 그 LB가 딱 그 서비스 하나로 트래픽을 보내준다.
외부 사용자 → (클라우드 LB 1개) → (Service 1개) → (Pod 여러 개)
2) Ingress = “건물 정문 하나로 들어와서, 안내데스크가 목적지로 보내주는 것”
상황: 외부에 공개할 서비스가 여러 개다.
- /api는 api 서비스로
- /web은 web 서비스로
- a.com은 A 서비스로
- b.com은 B 서비스로
이걸 서비스마다 LoadBalancer로 만들면 LB가 여러 개 생김.
외부 사용자 → (정문 1개) → (규칙으로 분기) → (여러 Service) → (각 Pod들)
>> Ingress의 핵심은 “L7 규칙(HTTP 기준: 도메인/경로)” 으로 나눠준다는 것!
>> 외부 진입점(주소) 하나로 여러 서비스를 깔끔하게 운영
>> URL/도메인 기반 라우팅, TLS(HTTPS) 같은 웹 기능을 다루기 좋음예:
- example.com/api → api-service
- example.com/ → web-service
3) 그럼 Ingress Controller??
Ingress는 사실 “규칙 문서”일 뿐이고, 실제로 트래픽을 받아서 규칙대로 보내주는 프로그램이 필요
그 프로그램이 Ingress Controller.
- Ingress: “이 경로는 어디로 보내라”라고 적어둔 설정(리소스)
- Ingress Controller: 그 설정을 읽고 실제로 동작하는 실행 엔진(프록시/L7 LB)
대표 Ingress Controller:
- NGINX Ingress Controller
- Traefik
- (AWS라면) AWS Load Balancer Controller(ALB Ingress 등)
외부 사용자 → (Ingress Controller가 만든 LB/프록시) → (Ingress 규칙 적용) → (Service들) → (Pods)
따배쿠 강의들으면서 정리한 필기 + ChatGPT를 활용하여 내용 추가...
'Kubernetes > 쿠버네티스 기본개념' 카테고리의 다른 글
[Udemy CKA] Practice Test - ReplicaSets (0) 2024.06.30 [Udemy CKA] Practice Test - Pods (2) 2024.06.24 [Kubernetes] 쿠버네티스의 기본 구조 (0) 2024.06.09