[DevOps] Kubernetes 주요 요소별 실습 가이드

이지연·2026년 3월 16일

DevOps

목록 보기
23/24

개요

Kubernetes의 핵심 리소스들을 실습 중심으로 정리했다.
Namespace, Pod, Service, ReplicaSet, Deployment, Ingress까지 실제 명령어와 YAML 예제를 통해 단계별로 실습해볼 수 있도록 구성되어있다.


Namespace 생성

  • 네임스페이스란 클러스터 내의 리소스를 분리된 그룹으로 나누는 단위

네임스페이스 생성

kubectl create namespace my-namespace

전체 네임스페이스 목록 조회

kubectl get namespaces

네임스페이스 내의 pod, service 등 자원 조회

kubectl get pods -n my-namespace
kubectl get services -n my-namespace

Pod 생성 및 적용

  • Pod는 쿠버네티스에서 배포할 수 있는 가장 작은 단위이며, 1개 이상의 컨테이너로 구성된 배포 단위

Pod 생성 스크립트 예시

apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    app: mypod
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 80
  - name: redis-container
    image: redis
    ports:
    - containerPort: 6379
  • 위와 같이 1개의 파드 내에 여러개의 도커 컨테이너 구성 가능
    • Pod는 네트워크적으로 하나의 IP를 가지는 단일 유닛
    • Pod 안의 컨테이너들은 localhost (127.0.0.1) 기준으로 서로 통신이 가능
  • 일반적으로, 하나의 Pod 내에 여러 컨테이너를 배치해야 하는 상황은 주로 그 컨테이너들이 밀접하게 협력하며, 서로 간에 높은 내부 통신이 필요할 때
    • 예를 들어) 특정 container의 로그정보 수집, health check, redis와 같은 third party 등 여러개의 컨테이너를 배치하는 경우
  • image 에서 이미지 이름만 명시하면, 기본적으로 도커허브에서 이미지를 검색

Pod 실습1. 명령어를 통한 POD 생성 및 삭제

nginx pod생성

kubectl run my-nginx --image=nginx --port=80
  • 이때의 80포트는 container의 내부포트
  • Pod 자체에는 외부 포트를 직접 지정할 수는 없음
  • 네임스페이스 지정시 --namespace=my-namespace 추가
    • 별도의 네임스페이스 지정이 없을경우 모든 pod, service 등의 자원은 default 네임스페이스에 생성
    • default 네임스페이스는 별도의 --namespace 옵션 없이 조회

pod조회

kubectl get pods
kubectl get pods -o wide          # 상세조회
kubectl get pods -A              # 모든 네임스페이스에서 pod 조회

pod삭제시

kubectl delete pod my-nginx

Pod 실습2. 스크립트를 통한 pod 생성 및 관리

test_pod1.yml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: my-namespace  # 네임스페이스 지정시, 여기에 지정
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
kubectl apply -f test_pod1.yml

테스트

  • pod 내 컨테이너에 접속
    kubectl exec -it nginx-pod -n my-namespace -- /bin/sh
    • 별다른 옵션이 없다면 여러 컨테이너 중 첫번째 컨테이너에 접속
  • "curl http://localhost" 로 http요청

test_pod2.yml (멀티 컨테이너)

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pinger-pod
  namespace: my-namespace  # 네임스페이스 지정시, 여기에 지정
  labels:
    app: nginx-pinger
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
  
  - name: http-pinger
    image: busybox
    command: ['sh', '-c', 'while true; do wget -qO- http://localhost:80; sleep 5; done']
  • 주기적으로 nginx에 요청을 보내는 busybox와 함께 실행

테스트

kubectl logs -f nginx-pinger-pod -n my-namespace
  • 별다른 옵션이 없다면 여러 컨테이너 중 첫번째 컨테이너 로그 출력

Service 생성

  • Service는 클러스터 내에서 실행 중인 Pod들에 대한 네트워크 접근 방법을 제공

Service 예시

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: my-namespace
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  • pod는 동적으로 생성되고 주소 변경 가능성이 높고, 라우팅의 어려움 존재
  • service는 서비스 디스커버리 기능 역할 수행
    • 같은 네트워크 내에서 통신시에 http://my-service:port 엔드포인트로 통신
    • 만약 다른 네임스페이스에서 접근하려면, my-service.<namespace-name>.svc.cluster.local 로 접근

주요 구성 요소

  • selector.app의 이름을 label로 가지는 pod에 해당 네트워크 정보 전파

    • 만약 여러개의 pod가 service의 selector.app과 매핑되면 자동으로 로드밸런싱
  • port ⭐

    • Service가 클러스터 내부에서 리슨(listen)하는 포트
    • 즉, 클러스터 내부의 다른 컴포넌트나 Pod들이 이 Service와 통신하기 위해 사용하는 포트
  • targetPort

    • Service가 포워딩(forward)하는 대상 Pod의 포트
    • 즉, Service로 들어온 요청을 실제로 요청을 처리하는 Pod컨테이너로 전달하기 위한 target포트
  • Type

    • ClusterIP(default): 클러스터 내부에서만 접근 가능
    • NodePort: 각 Node의 IP에 30000~32767 범위의 포트가 OPEN, NodeIP:NodePort 형식으로 외부 접근 가능
    • LoadBalancer: 클라우드 환경(AWS, GCP, Azure 등)에서 LoadBalancer 생성, 외부 접근 가능

서비스 호출 테스트

  • pod내 컨테이너에 접속
    kubectl exec -it <pod-name> -n <namespace> -- /bin/sh
  • pod 내부에서 같은 namespace service 호출
    curl http://<service-name>:<port>

ReplicaSet

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
  • ReplicaSet는 지정된 수의 파드 복제본이 항상 실행되도록 보장해주는 k8s의 리소스

주요 요소

  • selector의 matchLabels

    • matchLabelsreplicaSet이 관리해야 할 파드를 결정하는 데 사용
    • app: nginx 이 경우, nginx 라벨을 가진 Pod만을 관리
  • template metadata의 labels

    • template새로운 Pod를 생성할 때 사용하는 템플릿이고, 이 템플릿에 따라 새로운 Pod가 생성
    • metadata.labels새로 생성되는 Pod에 부여될 라벨의 이름을 정의
    • 새로 생성하는 모든 Pod에 nginx라는 라벨을 자동으로 부여
    • 이 라벨은 위에서 설명한 selector.matchLabels와 일치해야함
    • 이 라벨은 service의 selector.app과 일치해야함

실습1) service를 통한 2개의 pod로의 로드밸런싱 테스트

  • 각 pod의 /usr/share/nginx/html/index.html 파일을 수정하여 로드밸런싱 확인
  • service의 기본 라우팅 알고리즘은 라운드 로빈
  • 다만, 캐싱 등의 이유로 공평하게 라우팅이 되지 않기도 함

실습2) pod를 삭제하여도 다시 생성되는지 여부 확인


Deployment

  • Deployment는 ReplicaSet과 기본기능은 동일
  • Deployment 적용시 ReplicaSet을 만들어 내고, ReplicaSet을 통해 Pod를 생성
  • 특징
    • Deployment를 통해 Replicaset 자원을 버전별로 생성(Revision)
      • spec.template의 값이 변경될때 새로운 Replicaset을 생성
      • 이때 새로운 Pod를 생성한 후, 기존 Pod를 순차적으로 종료
      • k8s의 Deployment의 기본 배포 전략은 롤링 업데이트
    • Deployment는 무중단배포(롤링업데이트), 롤백, 버전 관리 등 고급 기능을 제공

Deployment를 통한 2개의 pod 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

실습1)롤백 테스트

kubectl rollout undo deployment <deployment명>

실습2)새로운 ReplicaSet 생성 및 revision 생성 실습

테스트1

  • templateimage 변경 후 apply

테스트2

kubectl rollout restart deployment <deployment명>
  • restart의 경우 Deployment의 template에 변화가 없더라도, 내부적으로 강제로 새로운 ReplicaSet을 생성
  • 이를 통해 latest 태그를 그대로 사용하더라도 새로운 revision 생성
  • latest태그인 경우, imagePullPolicy정책은 Always가 디폴트

Ingress

Ingress와 ingress-controller

역할1

  • Ingress는 쿠버네티스 클러스터 외부에서 내부의 service로 라우팅 규칙을 정의
    • prefix 단위로 service 마다 라우팅이 될 수 있도록 규칙 설정 가능
  • ingress-controller가 Ingress리소스를 해석하고 실제로 service로의 라우팅 수행

역할2

  • Ingress는 도메인을 지정하여 외부에서 도메인 기반 접근
  • Ingress 리소스에 도메인(host)을 지정하면, ingress-controller는 도메인별로 적절한 Ingress로 라우팅을 수행

ingress-controller

  • ingress-controller(nginx)의 경우 별도 설치 필요
    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/aws/deploy.yaml
  • incress-controller설치시 aws에 자동으로 LB가 생성
    • 생성된 LB의 주소를 route53에 라우트 설정하여 도메인으로 접근가능하도록 설정

결론

  • Ingress는 규칙정보정의, ingress-controller는 실질적인 라우팅을 수행
  • 도메인이 다른 Ingress가 여러 개 있어도 incress-controller는 하나만 있어도 되고, controller가 여러 Ingress 리소스를 참조하여 라우팅을 수행

k8s 주요 명령어

kubectl run nginx --image=nginx                    # pod생성 명령어
kubectl get pods                                  # pod목록 조회
kubectl get pods -A                               # 모든 네임스페이스 pod조회
kubectl delete pod <pod명 또는 service명 >       # pod 삭제 (deployment 있는 경우 다시 생성)
kubectl apply -f my-deployment.yaml               # 특정 yaml파일을 apply할때
kubectl delete -f my-deployment.yaml              # 적용했던 yaml 리소스를 삭제할때
kubectl logs <pod명>                              # pod에서 실행중인 컨테이너의 로그 출력
kubectl logs -f <pod명>                           # 실시간 로그 조회
kubectl describe pod nginx-pod                    # pod의 상태, 설정, 최근의 이벤트 등의 정보 출력
kubectl get deployment <deployment명> -o yaml     # 기 apply됐던 리소스의 yaml파일을 확인할때
profile
Eazy하게

0개의 댓글