AWS Cloud School 13기 77일차

Forever 김·2026년 4월 20일

AWS Cloud School

목록 보기
71/97

TIL

배운 내용

쿠버네티스(3) - Ingress Controller, PV/PVC, StorageClass, ConfigMap, Secret

오늘은 쿠버네티스의 핵심 리소스들을 집중적으로 다뤘다. Ingress Controller 설치부터 시작해서 영구 볼륨(PV/PVC), 스토리지 클래스, 그리고 설정값을 주입하는 ConfigMap과 Secret까지 쭉 이어졌다. 내용이 많았지만 하나하나 연결되는 흐름이 있어서 이해하기 좋았다.


Ingress Controller

지난 시간에 Ingress 개념을 배웠다면, 오늘은 실제로 Ingress Controller를 설치하고 path 기반 라우팅을 구성하는 실습을 했다.

Ingress는 그냥 규칙(Rule)을 정의하는 리소스고, 실제로 트래픽을 처리하는 건 Ingress Controller다. 우리는 nginx 방식을 사용했다.

rapa.com/httpd  →  svc-ipnginx  →  Pod (httpd)
rapa.com/h      →  svc-h        →  Pod (hnginx)

트래픽 흐름을 정리하면 이렇다.

사용자 → ingress-controller svc (External-IP) → Ingress (path 라우팅) → svc → Pod

Ingress 매니페스트 핵심

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ing-ip
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: "nginx"
  rules:
    - host: rapa.com
      http:
        paths:
        - path: /httpd
          pathType: Prefix
          backend:
            service:
              name: svc-ipnginx
              port:
                number: 80
        - path: /h
          pathType: Prefix
          backend:
            service:
              name: svc-h
              port:
                number: 80

몇 가지 중요한 포인트가 있다.

  • ingressClassName: "nginx" → 어떤 Ingress Controller를 쓸지 명시
  • rewrite-target: //httpd로 들어와도 실제 Pod에는 /로 전달
  • host는 반드시 영문 도메인이어야 한다. IP는 안 됨
  • DNS가 없으면 /etc/hosts에 직접 등록해서 테스트 가능

서비스의 이름을 마치 주소처럼 쓰고 있다는 게 핵심이다. 쿠버네티스 내부 DNS가 svc 이름을 IP로 해석해준다.


PV (Persistent Volume) / PVC (Persistent Volume Claim)

컨테이너는 기본적으로 삭제되면 내부 데이터도 사라진다. 이걸 해결하기 위한 게 PV/PVC다.

  • PV (Persistent Volume): 클러스터 입장에서 정의하는 물리적 스토리지 자원
  • PVC (Persistent Volume Claim): Pod(사용자 앱) 입장에서 스토리지를 요청하는 리소스

관계를 정리하면 이렇다.

관리자 → PV 생성 (실제 디스크 정의)
사용자 → PVC 생성 (스토리지 요청)
쿠버네티스 → 조건에 맞는 PV와 PVC를 자동으로 Bind
Pod → PVC를 참조해서 마운트

오늘 실습에서는 마스터 노드를 NFS 서버로 구성하고, 워커 노드들이 NFS 클라이언트로 마운트하는 방식을 사용했다.

# 마스터 노드 - NFS 서버 설정
mkdir /shared
apt install -y nfs-kernel-server
echo "/shared *(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
systemctl restart nfs-server

# 워커 노드 - NFS 클라이언트 설치
apt install -y nfs-common

PV 매니페스트

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /shared/pv1
    server: 211.183.3.100

PVC 매니페스트

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc1
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

PVC를 만들면 조건에 맞는 PV가 있을 때 자동으로 Bound 상태가 된다. PV를 직접 선택하는 게 아니라 조건(용량, accessMode)이 맞는 PV 중에서 선택된다는 점이 포인트다.

accessMode 종류

모드설명
ReadWriteOnce (RWO)단일 노드에서 읽기/쓰기
ReadOnlyMany (ROX)다수 노드에서 읽기만
ReadWriteMany (RWX)다수 노드에서 읽기/쓰기
ReadWriteOncePod (RWOP)단일 Pod에서만 읽기/쓰기

PV와 PVC의 accessMode는 반드시 일치해야 한다.

Reclaim 정책 (PVC 삭제 시 PV 처리 방식)

정책설명
RetainPVC 삭제 후 PV 유지, 재활용 불가
DeletePVC 삭제 시 PV도 함께 삭제
Recycle재활용 (현재는 정책상 사용 불가)

StorageClass

스토리지 등급을 정의하는 리소스다. HDD, SSD처럼 성격에 맞게 스토리지를 분류해놓은 것이다.

  • 관리자 입장: 용도에 맞게 스토리지를 분류
  • 사용자 입장: 원하는 StorageClass를 지정해서 PVC로 요청

AWS EKS에서 gp2, gp3 같은 스토리지 클래스가 바로 이 개념이다.

PV와 PVC에 storageClassName을 동일하게 지정하면 해당 클래스끼리만 Bind된다.

# PV에 storageClassName 지정
spec:
  storageClassName: manual-sc
  ...

# PVC에도 동일하게 지정
spec:
  storageClassName: manual-sc
  ...

프로비저닝 방식

방식설명
수동(Static) ProvisioningPVC 요청 전에 PV를 미리 생성해두는 방식
자동(Dynamic) ProvisioningPVC 요청이 오면 StorageClass가 자동으로 PV를 생성

오늘 실습은 수동 방식이었다. 자동 방식은 StorageClass에 provisioner를 지정해야 한다.


ConfigMap

클러스터에 존재하는 설정값이나 환경변수를 Pod에 주입할 때 사용하는 리소스다.

  • 환경변수 (DB 호스트, 유저명 등)
  • nginx.conf 같은 설정 파일 내용

Pod가 생성되기 전에 적용 가능한 값이라는 점이 핵심이다.

# ConfigMap 정의
apiVersion: v1
kind: ConfigMap
metadata:
  name: info
data:
  db_host: 211.183.3.100
  username: root
# Pod에서 ConfigMap 참조 (환경변수로 주입)
env:
- name: USERNAME
  valueFrom:
    configMapKeyRef:
      name: info
      key: username

설정 파일 자체를 Pod 안으로 마운트하는 것도 가능하다. subPath를 사용하면 컨테이너 내부의 기존 파일은 유지하면서 특정 파일만 추가/수정할 수 있다.


Secret

ConfigMap과 비슷하지만 민감한 정보(DB 비밀번호, API 키 등) 를 다루는 리소스다.

  • base64 방식으로 인코딩
  • etcd에 암호화되어 저장
  • kubectl get secret으로 조회해도 실제 값은 보이지 않음
apiVersion: v1
kind: Secret
metadata:
  name: sec
type: Opaque
stringData:
  password: test123
# Pod에서 Secret 참조
envFrom:
- secretRef:
    name: sec

ConfigMap과 Secret의 차이를 한 줄로 정리하면:

ConfigMap은 일반 설정값, Secret은 노출되면 안 되는 민감한 값


실습: WordPress + MySQL on Kubernetes

오늘 실습의 하이라이트였다. PV/PVC를 활용해서 WordPress와 MySQL을 쿠버네티스 위에 올렸다.

  • PV 2개 생성 (MySQL용, WordPress용)
  • MySQL Deployment + PVC 연결
  • WordPress Deployment + PVC 연결
  • WordPress에서 MySQL을 찾아갈 때 svc 이름으로 접근
# WordPress에서 MySQL 접근 시 svc 이름 사용
env:
- name: WORDPRESS_DB_HOST
  value: wordpress-mysql  # svc 이름이 곧 주소

쿠버네티스 내부 DNS가 svc 이름을 IP로 해석해주기 때문에 가능한 방식이다. 이 개념이 마이크로서비스 아키텍처에서 서비스 간 통신의 핵심이다.


오늘은 쿠버네티스의 스토리지와 설정 관리 파트를 집중적으로 다뤘다. PV/PVC의 Bind 과정, ConfigMap과 Secret의 차이, Ingress의 path 라우팅까지 실습으로 직접 확인하니까 개념이 훨씬 잘 잡혔다. 특히 svc 이름을 주소처럼 쓴다는 개념이 인상 깊었다.

이번 velog는 AWS Kiro를 통해 작성하였다.

profile
나를 한줄로

0개의 댓글