일단 간단하게 1개 PC(단일 노드(Single Node) 구조)에서의 Kubernetes를 체험해 보자.
※ Minikube는 보통 노드가 1개뿐입니다. 내 PC가 꺼지거나 Minikube 프로세스에 문제가 생기면 서비스 전체가 중단됩니다. (고가용성 부족)

Node
- 정의: 쿠버네티스가 돌아가는 하나의 작업 서버 (물리 PC 또는 가상 머신).
- 클러스터는 이러한 노드들의 집합을 의미합니다.
- IP: 실제 PC의 IP(Host IP)를 사용하지만, Minikube 같은 가상 환경에서는 별도의 가상 IP(예: 192.168.49.2)가 할당됩니다
- NodePort: 외부 접속을 위한 문 번호입니다. 직접 지정하지 않으면 30000~32767 범위에서 자동 할당됩니다.
- 접속: 브라우저에서 http://[노드 IP]:[NodePort]로 접속합니다.
Service : frontend / redis-leader / redis-follower
- 역할: 여러 개의 Pod를 하나로 묶어주는 고정된 관문이자 로드 밸런서.
- YAML의 selector 항목에 적힌 라벨과 Pod의 labels가 일치하는 것들을 서비스가 묶어서 관리합니다.
- 고정 IP: 클러스터 내부용 Virtual(Cluster) IP를 가집니다. Pod가 죽어서 IP가 바뀌어도 서비스 IP는 변하지 않습니다.
- 포트: port: 80은 서비스 자체가 내부에서 사용하는 포트입니다.
Pod : frontend pod / redis-leader pod / redis-follower pod
- 정의: 실제 앱(컨테이너)이 실행되는 단위. 주로 Docker 이미지 형태입니다.
- 관리: Deployment 설정을 통해 실행 개수가 유지되며, Pod가 죽으면 자동으로 새 Pod가 생성(Self-healing)됩니다.
- IP: 생성될 때마다 새로운 내부 IP를 부여받는 휘발성 주소입니다.
- 포트: targetPort: 80은 실제 앱이 컨테이너 내부에서 열고 있는 포트입니다.
통신 원리 (중요)
- 내부 통신: Pod끼리 통신할 때는 상대방 서비스의 이름을 사용합니다. (예: http://redis-leader).
- DNS 역할: 쿠버네티스 내부 DNS가 서비스 이름을 고정된 Virtual IP로 해석하여 전달합니다.
- 흐름: 외부 사용자 → Node IP:NodePort → Service(VIP):Port → Pod:TargetPort.
Minikube 설치 (로컬PC에서 kubernetes의 개념을 잡고 테스트하는 용도)
| # docker 설치 sudo apt update sudo apt install -y docker.io sudo usermod -aG docker $USER # Minikube 설치 curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikube # kubectl (kubernetes와 소통하는 CLI 툴) 설치 curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" sudo install kubectl /usr/local/bin/kubectl |
클러스터 시작과 확인
| minikube start --driver=docker kubectl cluster-info kubectl get nodes |
guestbook.yaml 화일 생성 ※ 복수의 yaml 을 하나의 yaml 내에 "---" 를 사용해 분리 통합
| # Redis leader (primary) apiVersion: apps/v1 kind: Deployment metadata: name: redis-leader spec: replicas: 1 selector: matchLabels: app: redis role: leader template: metadata: labels: app: redis role: leader spec: containers: - name: redis image: redis:7 ports: - containerPort: 6379 --- apiVersion: v1 kind: Service metadata: name: redis-leader spec: selector: app: redis role: leader ports: - port: 6379 targetPort: 6379 --- # Redis followers (replicas) apiVersion: apps/v1 kind: Deployment metadata: name: redis-follower spec: replicas: 2 selector: matchLabels: app: redis role: follower template: metadata: labels: app: redis role: follower spec: containers: - name: redis image: gcr.io/google_samples/gb-redisslave:v3 ports: - containerPort: 6379 --- apiVersion: v1 kind: Service metadata: name: redis-follower spec: selector: app: redis role: follower ports: - port: 6379 targetPort: 6379 --- # Frontend web app apiVersion: apps/v1 kind: Deployment metadata: name: frontend spec: replicas: 3 selector: matchLabels: app: guestbook template: metadata: labels: app: guestbook spec: containers: - name: guestbook image: gcr.io/google_samples/gb-frontend:v5 ports: - containerPort: 80 env: - name: GET_HOSTS_FROM value: "dns" --- apiVersion: v1 kind: Service metadata: name: frontend spec: type: NodePort selector: app: guestbook ports: - port: 80 targetPort: 80 |
- Deployment 직원을 채용하고 관리하는 인사팀
-> "이 업무를 할 직원 3명을 유지해라"
-> "직원이 퇴사하면 새로 채용한다"
kind: Deployment # "앱 실행 관리자를 만들겠다"
metadata:
name: redis-leader # "이름은 redis-leader이다"
spec:
replicas: 1 # "Pod 1개를 유지해라"
template: # "이 설계도로 Pod를 만들어라"
spec:
containers:
- image: redis:7 # "redis:7 이미지를 실행해라" - Service 고객이 전화하는 대표번호
-> 대표번호는 항상 같다 (고정 DNS/IP)
-> 전화하면 근무 중인 직원 중 한 명에게 연결된다 (로드밸런싱)
-> 직원이 바뀌어도 대표번호는 그대로다 (Pod 변경에 무관)
kind: Service # "네트워크 접속 창구를 만들겠다"
metadata:
name: redis-leader # "이 창구의 이름은 redis-leader이다"
spec:
selector:
app: redis # "app=redis, role=leader 라벨을 가진
role: leader # Pod로 연결해라"
ports:
- port: 6379 # "6379 포트로 요청을 받아라"
targetPort: 6379 # "받은 요청을 Pod의 6379 포트로 전달해라" - Deployment 와 Service 에 기술되어 있는 selector 의 의미는 자신이 관리하는 Pod의 식별자
Deployment는 replicas 설정숫자의 Pod를 생성하고 감시해야 하기 때문에 그 Pod의 식별자가 필요
Service는 로드밸랜싱을 하기위해 관리하는 Pod의 식별자가 필요 - Deployment 에만 정의되어 있는 template labels 의 의미는 Pod생성시에 자신에 붙이는 식별자
예) Pod는 redis-leader-abc-123 / redis-leader-abc-124 와 같이 레벨을 가지고 생성
그러면 Deployment 와 Service는 자신이 관리하는 Pod를 redis-leader로 식별
| # 적용 kubectl apply -f guestbook.yaml # pods의 생성, 실시간 스케쥴링 보기 kubectl get pods -w # 생성된 모든 리소스 보기 kubectl get all # 앱 액세스 minikube service frontend |
오케스트레이션 행동 테스트
| # 자체 힐링 # pods 리스크 kubectl get pods # 특정 pod 삭제 kubectl delete pod frontend-xxxxx-xxxxx # 즉시 새로운 pod가 대체되는 것 보기 kubectl get pods -w # 스케일링 # frontend 를 3개에서 5개로 늘리기 kubectl scale deployment frontend --replicas=5 # 늘려진 pod들 보기 kubectl get pods -w # 2개로 줄이기 kubectl scale deployment frontend --replicas=2 kubectl get pods -w # 업데이트 # frontend image 업데이트(v5에서 v4로 다운그레이딩) kubectl set image deployment/frontend guestbook=gcr.io/google_samples/gb-frontend:v4 # 업데이트 보기 kubectl rollout status deployment/frontend # 롤백(다시 되돌리기) kubectl rollout undo deployment/frontend kubectl rollout status deployment/frontend # 제거 kubectl delete -f guestbook.yaml minikube stop |