카테고리 보관물: Container

CKAD Ingress 문제 후기 – 20250618

개요

CKAD 시험에서 출제된 Ingress 문제 풀이를 기록합니다. 기존 Service를 백엔드로 연결하는 Ingress를 YAML 파일로 작성하여 도메인 기반 라우팅을 구성하는 문제입니다.

출제 문제

※ 기억에 의존해 복기하는 문제라 오류가 있을 수 있습니다.
참고만 부탁 드립니다.

  • 사용자가 www.example.com URL로 접속할 때 라우팅이 가능하도록 Ingress를 생성
  • 기생성 Service 의 name과 port를 참고 하여 Ingress 반영
    service name : service1
    port : 80
  • Ingress name은 ingressWeb으로 할 것
  • YAML파일을 작성하여 생성할 것

해결 방법

# ingress.yaml 생성

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingressWeb
spec:
  rules:
  - host: "www.example.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: service1
            port:
              number: 80

# Ingress 생성 및 상태 확인
$ kubectl apply -f ingress.yaml
$ kubectl get ingress
$ kubectl describe ingress ingressWeb

Ingress 개념 — NodePort/LoadBalancer와 비교

Kubernetes에서 외부 트래픽을 Pod로 전달하는 방법으로 NodePort, LoadBalancer, Ingress 세 가지가 있습니다. NodePort는 노드 IP + 고정 포트로 직접 접근하며 관리가 번거롭고, LoadBalancer는 서비스마다 외부 IP를 하나씩 할당하므로 클라우드 환경에서 비용이 발생합니다. Ingress는 단일 진입점(IngressController)에서 도메인 이름과 경로 기반으로 여러 서비스를 라우팅할 수 있어 HTTP/HTTPS 트래픽 관리에 가장 적합합니다.

Ingress 리소스 자체는 라우팅 규칙을 정의하는 API 오브젝트이며, 실제 트래픽 처리는 클러스터에 배포된 IngressController(Nginx, Traefik, HAProxy 등)가 담당합니다. IngressController가 설치되지 않은 환경에서는 Ingress를 생성해도 동작하지 않습니다.

# 클러스터에 설치된 IngressClass 확인
kubectl get ingressclass

# Ingress 상태 확인 (ADDRESS 할당 여부)
kubectl get ingress -A

# Ingress 이벤트 및 백엔드 상태 확인
kubectl describe ingress ingressWeb

CKAD 시험에서 Ingress 문제는 대부분 기존 Service에 연결하는 YAML 작성 문제입니다. spec.rules[].host에 도메인, spec.rules[].http.paths[].backend.service.name/port에 Service 정보를 정확히 기입하는 것이 핵심이며, pathType: PrefixpathType: Exact의 차이도 숙지해두면 좋습니다.

경로 기반 라우팅과 TLS 설정

Ingress는 도메인 기반 라우팅 외에도 URL 경로 기반 라우팅을 지원합니다. 동일한 도메인에서 /api는 백엔드 서비스로, /static은 프런트엔드 서비스로 각각 라우팅하는 구성이 가능합니다. pathType: Prefix는 지정된 경로로 시작하는 모든 URL을 매칭하고, pathType: Exact는 정확히 일치하는 경우만 처리합니다.

HTTPS를 적용하려면 spec.tls 섹션에 도메인과 TLS Secret을 지정합니다. TLS Secret은 kubernetes.io/tls 타입으로 인증서(tls.crt)와 개인키(tls.key)를 포함해야 합니다. IngressController가 TLS Termination을 처리하면 백엔드 서비스는 HTTP로 통신하면서 외부에는 HTTPS로 노출됩니다. cert-manager와 연동하면 Let’s Encrypt 인증서를 자동으로 발급하고 갱신하는 파이프라인을 구성할 수 있습니다.

CKAD 시험에서는 기존 Service를 IngressClass가 지정된 클러스터에 연결하는 Ingress YAML 작성 문제가 자주 출제됩니다. ingressClassName 필드를 누락하면 IngressController가 Ingress를 처리하지 않을 수 있으므로, 시험 환경에서 kubectl get ingressclass로 사용 가능한 IngressClass 이름을 먼저 확인하는 습관을 들이는 것이 좋습니다.

참고

참고 문서: kubectl create ingress · ingress-nginx → Traefik 마이그레이션 — Traefik v3.7.5 구성

CKAD Secrets 문제 후기 – 20250618

개요

CKAD 시험에서 출제된 Kubernetes Secret 문제 풀이를 기록합니다. Deployment의 환경변수(ENV)에 하드코딩된 민감 정보를 Secret 리소스로 분리하고, Deployment에서 Secret을 envFrom 또는 env.valueFrom으로 참조하도록 수정하는 문제입니다.

출제 문제

※ 기억에 의존해 복기하는 문제라 오류가 있을 수 있습니다.
참고만 부탁 드립니다.

  • postgres deployment의 env에 하드코딩 된 argument를 참고하여 secret 생성
    secret name : postgres
    namespace : devops
    key name : username, database, password
  • 생성된 postgres secret을 postgres deployment의 env에 하드코딩 된 argument를 수정 반영
    ※ postgres deployment YAML파일을 제공하고 수정해서 재배포하라고 나왔을 수 있음

해결 방법

# postgres deployment의 env 확인
$ kubectl describe deployment -n devops postgres | grep -A3 Environment
    Environment:
      PG_USERNAME:       pgadmin
      PG_DATABASE:       pgdatabase
      PG_PASSWORD:       pgpwd1234
# Secret 생성
$ kubectl create secret generic postgres --from-literal=username=pgadmin --from-literal=database=pgdatabase --from-literal=password=pgpwd1234 -n devops

$ kubectl get secrets -n devops
# 제공된 postgres deployment의 yaml 수정 및 저장
$ vi postgres-deployment.yaml
...
spec:
  containers:
  - name: postgres
    image: postgres:stable
    env:
    - name: PG_USERNAME
      valueFrom:
        secretKeyRef:
          name: postgres
          key: username
    - name: PG_DATABASE
      valueFrom:
        secretKeyRef:
          name: postgres
          key: database
    - name: PG_PASSWORD
      valueFrom:
        secretKeyRef:
          name: postgres
          key: password
...
# deployment 재배포
$ kubectl apply -f postgres-deployment.yaml

# Environment 값 확인
$ kubectl describe deployment -n devops postgres

Secret 타입과 주입 방식 이해

Kubernetes Secret은 민감한 데이터(비밀번호, API 키, 인증서 등)를 Pod 스펙에서 분리하여 관리하는 리소스입니다. 기본 타입은 Opaque이며 kubectl create secret generic으로 생성합니다. 그 외에 TLS 인증서를 위한 kubernetes.io/tls, 이미지 풀 인증을 위한 kubernetes.io/dockerconfigjson 등 특수 목적 타입도 있습니다.

Pod에 Secret을 주입하는 방식은 두 가지입니다. env.valueFrom.secretKeyRef는 Secret의 특정 키 하나를 지정한 환경변수 이름으로 주입합니다. envFrom.secretRef는 Secret의 모든 키를 그대로 환경변수로 주입합니다. 이 문제처럼 하드코딩된 ENV를 Secret으로 교체할 때는 키 이름이 환경변수 이름과 달라질 수 있으므로 valueFrom 방식으로 이름을 명시적으로 매핑하는 것이 안전합니다.

# Secret 생성 확인 (값은 base64로 저장됨)
kubectl get secret postgres -n devops -o yaml

# Secret 값 디코딩 확인
kubectl get secret postgres -n devops   -o jsonpath='{.data.password}' | base64 -d

# Secret 전체 키를 envFrom으로 주입하는 방식 (키 이름 = ENV 이름)
# spec.containers[].envFrom:
# - secretRef:
#     name: postgres

Secret은 기본적으로 etcd에 base64 인코딩으로 저장됩니다(암호화 아님). 운영 환경에서 실질적인 보안을 위해서는 etcd encryption at rest 활성화, RBAC으로 Secret 접근 제한, Vault 같은 외부 시크릿 관리 솔루션 연동을 고려해야 합니다.

Secret 보안 강화와 운영 주의사항

Kubernetes Secret은 기본적으로 etcd에 base64 인코딩 상태로 저장되며, 이는 암호화가 아닙니다. RBAC으로 Secret 리소스에 대한 get/list 권한을 최소화하고, 시험 환경 외 운영 환경에서는 POSTGRES_PASSWORD: pgpwd1234 같은 테스트용 비밀번호를 절대 사용해서는 안 됩니다.

Secret은 생성 후 값 변경이 어렵고 애플리케이션을 재시작해야 반영됩니다. 이를 보완하기 위해 Secrets Store CSI Driver와 HashiCorp Vault, AWS Secrets Manager 같은 외부 시크릿 관리 솔루션을 연동하면 Secret 값을 동적으로 교체하고 감사 로그를 남기는 것이 가능합니다. CKAD 시험 범위 밖이지만, 실무에서는 Secret 관리 방식이 보안 성숙도의 중요한 지표가 됩니다.

참고

참고 문서: kubectl로 Secret 관리 · Pod에 Secret 주입하기

CKAD Cronjob 문제 후기 – 20250618

개요

CKAD 시험에서 출제된 Kubernetes CronJob 문제 풀이를 기록합니다. 특정 스케줄로 동작하는 CronJob을 작성하고, 성공/실패 history 보관 수, activeDeadlineSeconds, restartPolicy 등 세부 옵션을 지정하며, 테스트용 Job도 별도로 생성합니다.

출제 문제

※ 기억에 의존해 복기하는 문제라 오류가 있을 수 있습니다.
참고만 부탁 드립니다.

  • 30분 마다 job을 스케쥴 처리할 수 있는 cronjob 생성
  • cronjob 이름은 grep, namespace는 devops 사용할 것
  • 성공 history는 64개, 실패 history는 160개 보관
  • job이 실행되고 8초 이내에 완료 되지 못하면 중단할 것
  • pod가 중단 되더라도 재실행 되지 않을 것
  • container 이름: busybox
    image: busybox:stable,
    command: [“grep”, “-i”, “NAMESERVER”, “/etc/resolv.conf”]
  • cronjob 테스트를 위해 job을 별도로 생성해볼 것
    job 이름: grep-test
    namespace: devops

해결 방법

# cronjob-grep.yaml 생성

apiVersion: batch/v1
kind: CronJob
metadata:
  name: grep
  namespace: devops
spec:
  schedule: "*/30 * * * *"
  successfulJobsHistoryLimit: 64
  failedJobsHistoryLimit: 160
  jobTemplate:
    spec:
      activeDeadlineSeconds: 8
      template:
        spec:
          containers:
          - name: busybox
            image: busybox:stable
            imagePullPolicy: IfNotPresent
            command: ["grep", "-i", "NAMESERVER", "/etc/resolv.conf"]
          restartPolicy: Never
# job-grep-test.yaml 생성

apiVersion: batch/v1
kind: Job
metadata:
  name: grep-test
  namespace: devops
spec:
  activeDeadlineSeconds: 8
  template:
    spec:
      containers:
      - name: busybox
        image: busybox:stable
        imagePullPolicy: IfNotPresent
        command: ["grep", "-i", "NAMESERVER", "/etc/resolv.conf"]
      restartPolicy: Never
# cronjob 생성 및 상태 확인
$ k apply -f cronjob-grep.yaml
$ k get cronjob -n devops
$ k describe cronjob -n devops grep

# job 생성 및 실행 상태 확인
$ k apply -f job-grep-test.yaml
$ k get job -n devops
$ k describe job -n devops grep-test
$ k get po -n devops # pod의 Completed 상태 확인

CronJob 주요 필드 설명

CronJob은 주기적으로 Job을 생성하는 Kubernetes 리소스입니다. spec.schedule은 Linux cron 문법(*/분 시 일 월 요일)을 따르며, */30 * * * *는 30분마다 실행을 의미합니다. 시험에서는 schedule 문법과 Job/Pod 레벨 옵션을 조합하는 문제가 자주 출제됩니다.

주요 필드와 역할은 다음과 같습니다. successfulJobsHistoryLimitfailedJobsHistoryLimit는 보관할 완료/실패 Job 수를 제한해 클러스터 리소스 낭비를 방지합니다. jobTemplate.spec.activeDeadlineSeconds는 Job 실행 시작 후 제한 시간이며, 이 시간을 초과하면 실행 중인 Pod를 강제 종료합니다. restartPolicy: Never는 Pod 실패 시 재시작하지 않고 새 Pod를 생성하는 방식으로, 반복 실행 가능한 Job에 적합합니다.

# CronJob 상태 및 다음 실행 시간 확인
kubectl get cronjob grep -n devops

# CronJob이 생성한 Job 목록 확인
kubectl get jobs -n devops

# 특정 Job이 생성한 Pod 확인 및 로그 조회
kubectl get pods -n devops --selector=job-name=grep-test
kubectl logs -n devops -l job-name=grep-test

CronJob을 즉시 테스트하려면 kubectl create job --from=cronjob/grep grep-test -n devops로 기존 CronJob 스펙을 기반으로 Job을 수동 실행할 수 있습니다. 이 방법이 YAML 파일을 별도로 작성하는 것보다 간결하고 오타 위험이 없어 시험 환경에서 유용합니다.

concurrencyPolicy와 startingDeadlineSeconds

CronJob에는 이전 Job이 아직 실행 중일 때 새 Job을 어떻게 처리할지 결정하는 concurrencyPolicy 필드가 있습니다. Allow(기본값)는 동시 실행을 허용하고, Forbid는 이전 Job이 완료될 때까지 새 Job 생성을 건너뜁니다. Replace는 실행 중인 Job을 취소하고 새 Job으로 교체합니다. Job 실행 시간이 스케줄 간격보다 길어질 수 있는 경우 Forbid를 설정해야 중복 실행으로 인한 리소스 낭비를 방지할 수 있습니다.

startingDeadlineSeconds는 스케줄된 시간을 놓쳤을 때 허용하는 지연 시간입니다. 클러스터가 일시적으로 중단되었다가 복구될 때, 누락된 스케줄을 이 시간 안에서 복구 실행합니다. 이 값을 설정하지 않으면 100번 이상 스케줄을 놓친 경우 CronJob 컨트롤러가 Job 생성을 포기하므로, 장기 유지보수 후 복구 시 Jobs가 실행되지 않는 상황에 주의해야 합니다.

참고

참고 문서: Kubernetes Job 공식 문서 · kubectl create cronjob