Skip to content

필사 모드: Kubernetes CKAD 자격증 실전 연습 문제 (55문제 + 실기 시뮬레이션 10개)

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

CKAD 자격증 개요

CKAD(Certified Kubernetes Application Developer)는 CNCF에서 주관하는 Kubernetes 애플리케이션 개발자를 위한 실기 중심 자격증입니다.

| 항목 | 내용 |

| --------------- | ------------------ |

| 시험 시간 | 120분 |

| 문제 수 | 15-20문제 (실기형) |

| 합격 기준 | 66% 이상 |

| 시험 방식 | 온라인 원격 감독 |

| 유효 기간 | 3년 |

| Kubernetes 버전 | 최신 안정 버전 |

도메인별 출제 비율

| 도메인 | 비율 |

| ------------------------------------------------- | ---- |

| Application Design & Build | 20% |

| Application Deployment | 20% |

| Application Observability & Maintenance | 15% |

| Application Environment, Configuration & Security | 25% |

| Services & Networking | 20% |

개발자 관점 kubectl 치트시트

ConfigMap 생성

kubectl create configmap app-config --from-literal=key=value

kubectl create configmap app-config --from-file=config.properties

kubectl create configmap app-config --from-env-file=.env

Secret 생성

kubectl create secret generic db-secret --from-literal=password=mypassword

kubectl create secret docker-registry regcred \

--docker-server=REGISTRY \

--docker-username=USER \

--docker-password=PASS

롤아웃 관리

kubectl rollout status deployment myapp

kubectl rollout history deployment myapp

kubectl rollout undo deployment myapp

kubectl rollout pause deployment myapp

kubectl rollout resume deployment myapp

리소스 제한

kubectl set resources deployment myapp --limits=cpu=200m,memory=512Mi

kubectl set resources deployment myapp --requests=cpu=100m,memory=256Mi

환경 변수 설정

kubectl set env deployment myapp ENV=production

kubectl set env deployment myapp --from=configmap/app-config

라벨 관리

kubectl label pod mypod env=production

kubectl label pod mypod env- # 라벨 제거

임시 컨테이너 (디버깅)

kubectl debug -it POD_NAME --image=busybox --target=CONTAINER_NAME

Helm 기본 명령어

helm repo add stable https://charts.helm.sh/stable

helm install myrelease stable/nginx

helm upgrade myrelease stable/nginx --set image.tag=latest

helm rollback myrelease 1

helm uninstall myrelease

helm list

dry-run으로 YAML 생성

kubectl create deployment myapp --image=nginx --dry-run=client -o yaml > deploy.yaml

kubectl run mypod --image=nginx --dry-run=client -o yaml > pod.yaml

개념 이해 문제 (Q1 ~ Q55)

도메인 1: Application Design & Build

A) Sidecar는 메인 컨테이너를 대체하고, Ambassador는 보조 기능을 제공한다

B) Sidecar는 메인 컨테이너의 기능을 확장(로깅, 모니터링)하고, Ambassador는 외부 서비스와의 통신을 프록시한다

C) 두 패턴은 동일하다

D) Ambassador는 Kubernetes 1.25에서 제거되었다

**정답**: B

**설명**: Sidecar 패턴은 메인 컨테이너와 함께 로그 수집, 모니터링, 보안 기능을 추가합니다. Ambassador 패턴은 메인 컨테이너가 외부 서비스와 통신할 때 중간 프록시 역할을 합니다. Adapter 패턴은 메인 컨테이너의 출력 형식을 변환합니다.

A) 메인 컨테이너와 동시에 실행된다

B) 메인 컨테이너가 시작되기 전에 순서대로 실행되고, 완료 후 메인 컨테이너가 시작된다

C) 실패하면 Pod가 Running 상태를 유지한다

D) 무한정 실행된다

**정답**: B

**설명**: Init Container는 메인 컨테이너가 시작되기 전에 순서대로 실행됩니다. 모든 Init Container가 성공적으로 완료된 후에만 메인 컨테이너가 시작됩니다. Init Container가 실패하면 Pod의 restartPolicy에 따라 재시작됩니다. DB 마이그레이션, 설정 파일 준비 등에 활용됩니다.

A) Job의 최대 실행 시간을 지정한다

B) Job 실패 시 재시도 횟수를 지정한다

C) 동시 실행 Pod 수를 제한한다

D) 완료된 Job을 자동으로 삭제한다

**정답**: B

**설명**: `backoffLimit`은 Job 실패 시 재시도하는 최대 횟수입니다. 기본값은 6입니다. 재시도 간격은 지수적으로 증가합니다(10초, 20초, 40초...). `activeDeadlineSeconds`는 Job의 최대 실행 시간을 제한합니다.

A) 빌드 속도를 높인다

B) 최종 이미지 크기를 줄이고 불필요한 빌드 도구를 제외할 수 있다

C) 캐싱을 비활성화한다

D) 여러 OS에서 동시에 빌드할 수 있다

**정답**: B

**설명**: 멀티 스테이지 빌드는 빌드 환경(컴파일러, 빌드 도구)과 실행 환경을 분리합니다. 첫 번째 스테이지에서 빌드 아티팩트를 생성하고, 두 번째 스테이지(경량 베이스 이미지)에서 아티팩트만 복사합니다. 이를 통해 이미지 크기를 대폭 줄일 수 있습니다.

A) 이전 Job이 완료되지 않은 경우 새 Job을 동시에 실행한다

B) 이전 Job이 아직 실행 중이면 새 Job을 건너뛴다

C) 이전 Job을 강제 종료하고 새 Job을 시작한다

D) 모든 Job을 큐에 저장한다

**정답**: B

**설명**: `concurrencyPolicy: Forbid`는 이전 Job이 아직 실행 중일 때 새 Job 생성을 건너뜁니다. `Allow`(기본값)는 동시 실행을 허용합니다. `Replace`는 이전 실행 중인 Job을 종료하고 새 Job을 시작합니다.

A) 모든 RUN 명령을 하나로 합친다

B) 자주 변경되는 명령(COPY 소스 코드)을 Dockerfile 아래에 배치한다

C) FROM 명령을 여러 번 사용한다

D) LABEL 명령을 많이 사용한다

**정답**: B

**설명**: Docker 레이어 캐싱 최적화를 위해 자주 변경되지 않는 명령(패키지 설치 등)을 위에 배치하고, 자주 변경되는 명령(소스 코드 복사)을 아래에 배치합니다. 이렇게 하면 소스 코드 변경 시 패키지 레이어 캐시를 재사용할 수 있습니다.

A) Always - Job에서 권장

B) OnFailure 또는 Never - Job과 CronJob에서 사용

C) OnSuccess - Job에서만 사용 가능

D) Never - 모든 경우에 권장

**정답**: B

**설명**: Job과 CronJob의 Pod에는 `OnFailure`(실패 시 재시작) 또는 `Never`(재시작 없음)를 사용해야 합니다. `Always`는 Deployment, DaemonSet 등 장기 실행 워크로드에 사용합니다. Job Pod에 `Always`를 사용하면 Job이 완료되어도 Pod가 계속 재시작됩니다.

A) StatefulSet은 더 많은 레플리카를 지원한다

B) StatefulSet은 순서가 있는 Pod 이름, 안정적인 네트워크 ID, 개별 PVC를 제공한다

C) Deployment는 상태 저장 앱에 더 적합하다

D) StatefulSet은 롤링 업데이트를 지원하지 않는다

**정답**: B

**설명**: StatefulSet은 상태 저장 애플리케이션을 위해 설계되었습니다: 1) 예측 가능한 Pod 이름(app-0, app-1), 2) 안정적인 네트워크 ID(헤드리스 서비스 통해), 3) 각 Pod별 독립적인 PVC(volumeClaimTemplates), 4) 순서 있는 배포/업데이트/삭제. 데이터베이스, Kafka, ZooKeeper 등에 적합합니다.

도메인 2: Application Deployment

A) Recreate는 더 많은 리소스를 사용한다

B) Recreate는 기존 Pod를 모두 삭제 후 새 Pod를 생성하여 다운타임이 있고, RollingUpdate는 점진적으로 교체하여 다운타임이 없다

C) RollingUpdate는 대규모 클러스터에서만 가능하다

D) 둘 다 동일한 방식으로 동작한다

**정답**: B

**설명**: `Recreate`는 기존 ReplicaSet의 Pod를 모두 삭제한 후 새 Pod를 생성합니다. 다운타임이 발생하지만 이전/새 버전이 동시에 실행되지 않습니다. `RollingUpdate`는 점진적으로 Pod를 교체하여 서비스 중단 없이 배포합니다. maxSurge와 maxUnavailable로 속도를 조절합니다.

A) Pod를 일시 중지/재개한다

B) 롤아웃을 일시 중단하여 일부 Pod만 새 버전으로 실행한 후 검증하고, 문제없으면 재개하는 카나리 배포 방식

C) Deployment를 완전히 중지한다

D) 자동 스케일링을 일시 중지한다

**정답**: B

**설명**: `kubectl rollout pause deployment`는 진행 중인 롤아웃을 일시 중단합니다. 이를 통해 일부 Pod만 새 버전으로 교체된 상태에서 카나리 테스트를 수행할 수 있습니다. 문제없으면 `kubectl rollout resume`으로 나머지를 계속 업데이트합니다.

A) Helm 차트의 필수 구성 요소 목록

B) 차트 배포 시 사용되는 기본 설정값을 정의한다

C) Kubernetes 매니페스트 파일

D) Helm 저장소 인증 정보

**정답**: B

**설명**: `values.yaml`은 Helm 차트의 기본 설정값을 정의합니다. `helm install`이나 `helm upgrade` 시 `--set` 또는 `-f custom-values.yaml`로 재정의할 수 있습니다. 템플릿 파일에서 `{{ .Values.image.tag }}`와 같이 참조합니다.

A) overlay는 base와 동일한 파일이다

B) base는 공통 설정을, overlay는 환경별(dev/staging/prod) 변경사항을 정의한다

C) overlay는 base를 완전히 대체한다

D) Kustomize는 overlay를 지원하지 않는다

**정답**: B

**설명**: Kustomize에서 base는 공통 Kubernetes 리소스 정의를 포함합니다. overlay는 base를 참조하고 환경별(개발, 스테이징, 운영) 패치와 변경사항을 추가합니다. `kubectl apply -k overlays/production/`처럼 사용합니다. Helm 차트 없이도 멀티 환경 배포가 가능합니다.

A) kubectl set image deployment/myapp \*=nginx:1.26

B) kubectl set image deployment/myapp nginx=nginx:1.26

C) kubectl update image deployment/myapp nginx:1.26

D) kubectl patch image deployment/myapp nginx=nginx:1.26

**정답**: B

**설명**: `kubectl set image deployment/DEPLOY_NAME CONTAINER_NAME=IMAGE:TAG` 형식으로 특정 컨테이너만 업데이트합니다. 예: `kubectl set image deployment/myapp nginx=nginx:1.26`. 여러 컨테이너를 동시에 업데이트하려면 공백으로 구분하여 나열합니다.

A) 보관할 롤아웃 히스토리(이전 ReplicaSet)의 수를 지정한다

B) 최대 Pod 수를 제한한다

C) 자동 롤백 횟수를 제한한다

D) 이전 버전 유지 기간을 시간으로 지정한다

**정답**: A

**설명**: `revisionHistoryLimit`은 Deployment가 보관할 이전 ReplicaSet의 수를 지정합니다. 기본값은 10입니다. 롤백에 사용 가능한 이전 버전 수와 직접 연관됩니다. 0으로 설정하면 이전 ReplicaSet을 바로 삭제합니다.

A) helm undo myrelease

B) helm rollback myrelease REVISION

C) helm revert myrelease

D) helm restore myrelease

**정답**: B

**설명**: `helm rollback myrelease REVISION_NUMBER`로 특정 리비전으로 롤백합니다. `helm history myrelease`로 릴리스 히스토리와 리비전 번호를 확인할 수 있습니다. 리비전을 지정하지 않으면 가장 최근의 이전 버전으로 롤백됩니다.

A) Deployment의 Recreate 전략 사용

B) 두 개의 Deployment(blue/green)를 운영하고 Service의 selector를 전환하여 트래픽 전환

C) StatefulSet으로 구현

D) DaemonSet으로 구현

**정답**: B

**설명**: Blue/Green 배포: 1) blue Deployment(현재 운영)와 green Deployment(새 버전)를 함께 운영, 2) green Deployment 테스트 완료 후, Service의 `selector`를 blue에서 green으로 변경하여 즉시 트래픽 전환, 3) 문제없으면 blue 제거. 즉각적인 전환이 가능하고 롤백도 빠릅니다.

도메인 3: Application Observability & Maintenance

A) Pod를 삭제하고 재생성한다

B) 컨테이너를 재시작한다

C) Pod를 다른 노드로 이동한다

D) 알림을 보낸다

**정답**: B

**설명**: Liveness Probe가 실패하면 Kubernetes는 해당 컨테이너를 재시작합니다(Pod 전체가 아닌 컨테이너). 재시작 정책(restartPolicy)이 적용됩니다. `failureThreshold`번 연속 실패하면 재시작이 시작됩니다. 애플리케이션 데드락이나 무한 루프 감지에 사용됩니다.

A) 컨테이너가 재시작된다

B) Pod가 서비스의 엔드포인트에서 제거된다

C) Pod가 삭제된다

D) 새로운 Pod가 생성된다

**정답**: B

**설명**: Readiness Probe가 실패하면 해당 Pod가 Service의 엔드포인트에서 제거되어 트래픽을 받지 않게 됩니다. 컨테이너는 재시작되지 않습니다. Probe가 다시 통과하면 엔드포인트에 다시 추가됩니다. 배포 중 준비되지 않은 Pod에 트래픽이 가는 것을 방지합니다.

A) 컨테이너 초기화 시간이 오래 걸리는 레거시 앱에서 Liveness Probe 시작 전 애플리케이션이 준비될 때까지 대기

B) 컨테이너 시작 전 환경 변수 초기화

C) 컨테이너 종료 후 정리 작업 수행

D) 외부 의존성 상태 확인

**정답**: A

**설명**: Startup Probe는 시작 시간이 긴 애플리케이션에서 Liveness Probe가 너무 이르게 실패하는 것을 방지합니다. Startup Probe가 성공할 때까지 Liveness와 Readiness Probe가 활성화되지 않습니다. 기존 모놀리식 앱을 컨테이너화할 때 특히 유용합니다.

A) 최근 1시간 내의 로그만 표시한다

B) 1시간 전부터 현재까지의 로그를 표시한다

C) 로그 파일의 처음 1시간 분량을 표시한다

D) 로그를 1시간 동안 스트리밍한다

**정답**: B

**설명**: `kubectl logs POD_NAME --since=1h`는 지난 1시간 내의 로그만 표시합니다. `--since-time=2024-01-01T00:00:00Z`로 특정 시간 이후의 로그를 가져올 수도 있습니다. `--tail=100`은 마지막 100줄만 표시합니다.

A) Prometheus가 설치되어 있어야 한다

B) Metrics Server가 클러스터에 설치되어 있어야 한다

C) Grafana가 설정되어 있어야 한다

D) kube-proxy가 IPVS 모드여야 한다

**정답**: B

**설명**: `kubectl top pod`와 `kubectl top node`는 Kubernetes Metrics Server를 통해 CPU와 메모리 사용량을 가져옵니다. Metrics Server는 별도로 설치해야 합니다. Prometheus나 다른 모니터링 도구는 `kubectl top` 명령어에 영향을 주지 않습니다.

A) 임시 Pod를 생성한다

B) 이미 실행 중인 Pod에 디버깅 도구가 없을 때 임시 컨테이너를 추가하여 디버깅한다

C) Pod를 일시 중지한다

D) 리소스 사용량을 줄인다

**정답**: B

**설명**: Ephemeral Container는 distroless나 slim 이미지처럼 셸이나 디버깅 도구가 없는 컨테이너를 디버깅할 때 사용합니다. `kubectl debug -it POD_NAME --image=busybox --target=CONTAINER`로 실행 중인 Pod에 임시 컨테이너를 추가합니다. Kubernetes 1.23+에서 GA입니다.

A) livenessProbe.tcpSocket 사용

B) livenessProbe.httpGet 사용

C) livenessProbe.exec 사용

D) livenessProbe.http 사용

**정답**: B

**설명**: HTTP Liveness Probe는 `httpGet`을 사용합니다. `path`와 `port`를 지정하고, 응답 코드가 200-399이면 성공으로 간주합니다. `tcpSocket`은 TCP 연결 확인, `exec`는 명령어 실행 후 종료 코드 0 여부로 확인합니다.

도메인 4: Application Environment, Configuration & Security

A) spec.containers.env.valueFrom.configMapKeyRef 사용

B) spec.containers.configmap 사용

C) spec.volumes.configmap 사용

D) spec.env.configmap 사용

**정답**: A

**설명**: ConfigMap을 환경 변수로 주입하는 두 가지 방법: 1) 특정 키만 주입: `env[].valueFrom.configMapKeyRef`로 특정 키-값 참조, 2) 전체 ConfigMap 주입: `envFrom[].configMapRef`로 모든 키를 환경 변수로 주입. 볼륨 마운트는 파일로 사용할 때 적합합니다.

A) AES-256으로 암호화되어 저장된다

B) 기본적으로 base64 인코딩만 되어 저장되며, etcd 암호화 설정을 별도로 해야 암호화된다

C) SHA-256 해시로 저장된다

D) 완전히 암호화되어 저장된다

**정답**: B

**설명**: Kubernetes Secret은 기본적으로 base64 인코딩만 되어 etcd에 저장됩니다(암호화 아님). etcd 저장 시 암호화를 위해 kube-apiserver에 `--encryption-provider-config`를 설정해야 합니다. Secret을 RBAC로 접근 제어하고, etcd 암호화를 활성화하는 것이 보안 모범 사례입니다.

A) 컨테이너를 root 사용자로 실행한다

B) 컨테이너가 root(UID 0)로 실행되려고 하면 시작을 거부한다

C) 컨테이너의 모든 파일을 읽기 전용으로 만든다

D) 네트워크 권한을 제거한다

**정답**: B

**설명**: `securityContext.runAsNonRoot: true`는 컨테이너가 root(UID 0)로 실행되려고 할 경우 컨테이너 시작을 거부합니다. `runAsUser: 1000`과 함께 사용하면 특정 UID로 실행을 강제할 수 있습니다. 컨테이너 탈출 공격 시 피해를 최소화하는 보안 Best Practice입니다.

A) PodSecurityContext는 특정 컨테이너에만 적용된다

B) spec.securityContext는 Pod 내 모든 컨테이너에 적용되고, 컨테이너 수준 설정은 해당 컨테이너에만 적용되며 Pod 설정을 재정의한다

C) 두 설정은 동일하다

D) 컨테이너 수준 SecurityContext는 Kubernetes 1.24에서 제거되었다

**정답**: B

**설명**: `spec.securityContext` (Pod 수준)는 Pod의 모든 컨테이너에 적용됩니다(runAsUser, fsGroup, supplementalGroups 등). `spec.containers[].securityContext` (컨테이너 수준)는 해당 컨테이너에만 적용되며 Pod 수준 설정을 재정의합니다(capabilities, readOnlyRootFilesystem 등).

A) 컨테이너에 모든 Linux capabilities를 추가한다

B) 컨테이너에서 모든 Linux capabilities를 제거하여 최소 권한으로 실행한다

C) 컨테이너를 privileged 모드로 실행한다

D) 네트워크 접근을 차단한다

**정답**: B

**설명**: `capabilities.drop: ["ALL"]`은 컨테이너에서 모든 Linux capabilities를 제거합니다. 필요한 capabilities만 `capabilities.add`로 다시 추가하는 방식으로 최소 권한 원칙을 적용합니다. 예를 들어 웹 서버는 NET_BIND_SERVICE만 필요할 수 있습니다.

A) 클러스터 전체 리소스 사용량을 제한한다

B) 네임스페이스 내 개별 Pod/Container의 기본 및 최대 리소스 요청/제한을 설정한다

C) PVC 크기를 제한한다

D) 사용자당 Pod 수를 제한한다

**정답**: B

**설명**: LimitRange는 네임스페이스 내에서 개별 리소스(Pod, Container, PVC)의 기본값(default), 최솟값(min), 최댓값(max)을 설정합니다. requests/limits를 명시하지 않은 컨테이너에 자동으로 기본값이 적용됩니다. ResourceQuota는 네임스페이스 전체 합산을 제한합니다.

A) 개별 Pod의 최대 CPU/메모리를 제한한다

B) 네임스페이스 전체에서 사용 가능한 리소스 합계를 제한한다

C) 노드의 리소스 사용량을 제한한다

D) 컨테이너의 네트워크 대역폭을 제한한다

**정답**: B

**설명**: ResourceQuota는 네임스페이스 전체에서 생성할 수 있는 리소스의 총량을 제한합니다. CPU, 메모리, Pod 수, PVC 수, LoadBalancer 서비스 수 등을 제한할 수 있습니다. 여러 팀이 클러스터를 공유할 때 특정 팀이 리소스를 독점하는 것을 방지합니다.

A) IfNotPresent는 항상 이미지를 새로 받고, Always는 캐시를 사용한다

B) IfNotPresent는 로컬에 이미지가 없을 때만 받고, Always는 항상 레지스트리에서 최신 이미지를 받는다

C) 두 옵션은 동일하다

D) IfNotPresent는 latest 태그에서만 동작한다

**정답**: B

**설명**: `IfNotPresent`: 노드에 이미지가 없을 때만 레지스트리에서 가져옵니다. 이미지가 있으면 기존 것을 사용합니다. `Always`: 매번 레지스트리에서 최신 이미지를 확인하고 가져옵니다. latest 태그나 다이제스트 없이 태그를 사용하는 경우 `Always`를 권장합니다.

A) spec.containers.env.value에 직접 값 입력

B) spec.containers.env.valueFrom.secretKeyRef 사용

C) spec.containers.args에 비밀 값 포함

D) ConfigMap에 Secret 값 포함

**정답**: B

**설명**: `env[].valueFrom.secretKeyRef`를 사용하여 Secret의 특정 키를 환경 변수로 주입합니다. `envFrom[].secretRef`로 Secret의 모든 키를 한 번에 주입할 수도 있습니다. Secret 값을 YAML에 직접 입력하거나 ConfigMap에 저장하는 것은 보안상 위험합니다.

A) /etc/kubernetes/

B) /var/run/secrets/kubernetes.io/serviceaccount/

C) /home/app/.kube/

D) /tmp/secrets/

**정답**: B

**설명**: ServiceAccount 토큰은 기본적으로 `/var/run/secrets/kubernetes.io/serviceaccount/` 경로에 자동 마운트됩니다. 이 경로에 `token`, `ca.crt`, `namespace` 파일이 있습니다. 자동 마운트가 필요없으면 `automountServiceAccountToken: false`로 비활성화합니다.

도메인 5: Services & Networking

A) Service가 오류를 반환한다

B) Service의 엔드포인트가 비어 있어 트래픽이 전달되지 않는다

C) 모든 Pod에 트래픽이 전달된다

D) Service가 자동으로 삭제된다

**정답**: B

**설명**: Service selector가 Pod label과 일치하지 않으면 Service에 엔드포인트가 없게 됩니다. `kubectl get endpoints SERVICE_NAME`으로 확인 시 "none"이 표시됩니다. `kubectl describe service`의 Endpoints 필드가 빈 것으로 확인할 수 있습니다.

A) path-based는 IP 주소 기반, host-based는 도메인 기반

B) path-based는 URL 경로(/api, /web)로 라우팅하고, host-based는 호스트 이름(api.example.com, web.example.com)으로 라우팅한다

C) 두 방식은 동일하다

D) host-based는 TLS를 지원하지 않는다

**정답**: B

**설명**: path-based routing은 동일한 도메인에서 경로별로 다른 서비스로 라우팅합니다(example.com/api → api-service, example.com/web → web-service). host-based routing은 다른 호스트명으로 다른 서비스로 라우팅합니다(api.example.com → api-service).

A) spec.ssl 필드 사용

B) spec.tls 필드에 secretName(TLS인증서를 포함하는 Secret)과 hosts를 지정

C) spec.annotations에 TLS 정보 포함

D) Ingress Controller 설정으로만 가능

**정답**: B

**설명**: Ingress TLS 설정: `spec.tls`에 `hosts`(TLS를 적용할 호스트 목록)와 `secretName`(TLS 인증서가 담긴 kubernetes.io/tls 타입의 Secret)을 지정합니다. Secret에는 `tls.crt`와 `tls.key` 키가 있어야 합니다.

A) 들어오는 트래픽을 제어한다

B) Pod에서 나가는 트래픽을 제어하여 의도하지 않은 외부 연결을 방지한다

C) 노드 간 통신을 제어한다

D) DNS 쿼리를 차단한다

**정답**: B

**설명**: egress 규칙은 Pod에서 나가는(outbound) 트래픽을 제어합니다. 예를 들어 데이터베이스 Pod가 인터넷에 연결되는 것을 방지하거나, 특정 포트(예: 5432 Postgres)로만 나가도록 제한할 수 있습니다. DNS 통신(포트 53)은 명시적으로 허용해야 합니다.

A) ClusterIP

B) NodePort

C) LoadBalancer

D) ExternalName

**정답**: D

**설명**: ExternalName 서비스는 클러스터 내부에서 외부 DNS 이름을 내부 서비스 이름처럼 사용할 수 있게 합니다. 예를 들어 `my-database.default.svc.cluster.local`을 `mysql.external.com`으로 CNAME 매핑합니다. 클러스터 외부 서비스를 내부에서 접근할 때 유용합니다.

A) 모든 트래픽이 기본적으로 차단된다

B) NetworkPolicy가 없으면 모든 Pod 간 통신이 허용된다

C) 같은 네임스페이스의 Pod만 통신 가능하다

D) Service를 통해서만 통신 가능하다

**정답**: B

**설명**: Kubernetes의 기본 네트워크 모델에서는 NetworkPolicy가 없으면 모든 Pod 간 통신이 허용됩니다. 특정 Pod에 NetworkPolicy가 적용되면 정책에 명시된 트래픽만 허용됩니다. 네임스페이스에 default-deny NetworkPolicy를 적용하고 필요한 통신만 허용하는 것이 보안 Best Practice입니다.

A) Prefix는 경로의 앞부분만 확인하고, Exact는 전체 경로가 정확히 일치해야 한다

B) Prefix는 정규식을 사용하고, Exact는 문자열을 비교한다

C) 두 타입은 동일하다

D) Exact는 대소문자를 구분하지 않는다

**정답**: A

**설명**: `Prefix`는 지정된 경로로 시작하는 모든 URL을 매칭합니다(/api는 /api/users, /api/posts도 매칭). `Exact`는 지정된 경로와 정확히 일치하는 URL만 매칭합니다(/api는 /api만 매칭, /api/users는 불일치). `ImplementationSpecific`은 Ingress Controller에 따라 동작이 다릅니다.

A) 같은 클라이언트 IP에서 오는 요청이 항상 같은 Pod로 라우팅된다

B) 세션이 만료된다

C) 모든 요청이 하나의 Pod로 집중된다

D) Load Balancer가 비활성화된다

**정답**: A

**설명**: `sessionAffinity: ClientIP`를 설정하면 동일한 클라이언트 IP에서 오는 요청이 항상 동일한 Pod로 라우팅됩니다(sticky session). `sessionAffinityConfig.clientIP.timeoutSeconds`로 세션 유지 시간을 설정할 수 있습니다. 기본값은 `None`(랜덤 라우팅)입니다.

A) service-name.cluster.local

B) service-name (또는 service-name.namespace.svc.cluster.local)

C) namespace.service-name

D) http://service-name:port

**정답**: B

**설명**: 같은 네임스페이스 내에서는 서비스 이름만으로 접근 가능합니다(`service-name`). 다른 네임스페이스에서 접근 시 `service-name.namespace` 또는 전체 FQDN인 `service-name.namespace.svc.cluster.local`을 사용합니다.

A) ClusterIP

B) NodePort와 LoadBalancer

C) headless service

D) ExternalName

**정답**: B

**설명**: NodePort는 모든 노드의 특정 포트(30000-32767)로 외부 접근을 허용합니다. LoadBalancer는 클라우드 프로바이더의 로드 밸런서를 자동으로 생성하여 외부 IP를 제공합니다. ClusterIP는 클러스터 내부에서만 접근 가능합니다.

A) Service의 포트를 영구적으로 변경한다

B) 로컬 포트를 Pod의 포트에 임시로 포워딩하여 클러스터 내부 서비스에 로컬에서 접근한다

C) 노드의 포트를 Pod에 매핑한다

D) Ingress 설정을 테스트한다

**정답**: B

**설명**: `kubectl port-forward pod/POD_NAME LOCAL_PORT:POD_PORT`는 로컬 머신의 포트를 Pod의 포트에 임시로 포워딩합니다. 개발 중에 클러스터 내부 서비스에 직접 접근하거나 디버깅할 때 유용합니다. 서비스에도 사용 가능: `kubectl port-forward service/SVC_NAME LOCAL_PORT:SVC_PORT`.

A) spec.networks 필드에 추가 네트워크 지정

B) Multus CNI를 사용하여 NetworkAttachmentDefinition으로 추가 인터페이스 설정

C) kube-proxy 설정 변경

D) 여러 개의 Service 생성

**정답**: B

**설명**: Multus CNI는 Pod에 여러 네트워크 인터페이스를 붙일 수 있는 메타 CNI 플러그인입니다. `NetworkAttachmentDefinition` CRD를 사용하여 추가 네트워크를 정의하고, Pod annotation으로 참조합니다. 텔레콤, NFV, 고성능 네트워킹이 필요한 환경에서 사용됩니다.

A) envFrom.configMapRef 사용

B) env[].valueFrom.configMapKeyRef.key로 특정 키 지정

C) volumeMounts 사용

D) spec.config.env 사용

**정답**: B

**설명**: 특정 키만 주입: `env[].valueFrom.configMapKeyRef`에 `name`(ConfigMap 이름)과 `key`(키 이름)를 지정합니다. 모든 키를 주입할 때는 `envFrom[].configMapRef.name`을 사용합니다. 특정 키만 가져오면 불필요한 환경 변수를 방지할 수 있습니다.

A) spec.terminationGracePeriodSeconds로 충분한 종료 시간 확보 및 컨테이너 내 SIGTERM 처리

B) restartPolicy: Never 설정

C) Liveness Probe 비활성화

D) privileged: true 설정

**정답**: A

**설명**: `spec.terminationGracePeriodSeconds`(기본 30초)는 SIGTERM 신호 후 강제 종료(SIGKILL) 전 대기 시간입니다. 애플리케이션은 SIGTERM 수신 시 진행 중인 요청 처리 완료 후 종료해야 합니다. Readiness Probe를 통해 종료 중인 Pod에 새 요청이 오지 않도록 합니다. `preStop` 훅으로 추가 정리 작업도 가능합니다.

A) alias kubectl=k

B) alias k=kubectl; export do="--dry-run=client -o yaml"

C) kubectl config set alias k=kubectl

D) export KUBECTL_ALIAS=k

**정답**: B

**설명**: `alias k=kubectl`과 `export do="--dry-run=client -o yaml"`는 시험 시간을 절약하는 핵심 설정입니다. 예: `k create deploy myapp --image=nginx $do > deploy.yaml`로 빠르게 YAML 템플릿을 생성할 수 있습니다. vim의 YAML 들여쓰기 설정도 중요합니다: `:set et ts=2 sw=2`.

A) 컨테이너가 파일을 읽을 수 없다

B) 컨테이너의 루트 파일시스템이 읽기 전용이 되어 런타임에 파일 수정이 불가능하다

C) 볼륨 마운트가 비활성화된다

D) 네트워크 접근이 차단된다

**정답**: B

**설명**: `readOnlyRootFilesystem: true`는 컨테이너의 루트 파일시스템을 읽기 전용으로 만듭니다. 공격자가 컨테이너에 침입해도 파일을 수정하거나 악성 코드를 설치하기 어려워집니다. 쓰기가 필요한 디렉토리는 emptyDir 볼륨으로 마운트합니다.

A) spec.hostPID, spec.hostNetwork, spec.hostIPC

B) spec.network.host = true

C) spec.containers.hostNamespace = true

D) spec.shareHostNamespace = true

**정답**: A

**설명**: `spec.hostPID: true`는 호스트의 PID 네임스페이스 공유, `spec.hostNetwork: true`는 호스트 네트워크 스택 사용, `spec.hostIPC: true`는 호스트 IPC 네임스페이스 공유를 설정합니다. 이 설정들은 보안 위험이 있으므로 필요한 경우에만 사용해야 합니다.

A) kubectl create는 YAML 파일을 지원하지 않는다

B) kubectl apply는 선언적 방식으로 변경사항만 적용하고 이미 존재하면 업데이트하며, kubectl create는 리소스가 이미 존재하면 오류를 반환한다

C) kubectl create는 더 빠르다

D) kubectl apply는 삭제도 수행한다

**정답**: B

**설명**: `kubectl apply`는 선언적 방식으로 리소스를 관리합니다. 존재하지 않으면 생성, 이미 존재하면 변경사항만 업데이트합니다. `kubectl create`는 명령형 방식으로 이미 존재하는 리소스에 대해 에러를 반환합니다. CI/CD 파이프라인에서는 `kubectl apply`를 권장합니다.

A) spec.volumes.emptyDir 사용

B) spec.volumes.hostPath 사용

C) spec.volumes.configMap 사용

D) spec.volumes.secret 사용

**정답**: B

**설명**: `hostPath` 볼륨은 노드의 파일시스템 경로를 컨테이너에 마운트합니다. Docker 소켓(`/var/run/docker.sock`), 노드 로그(`/var/log`)에 접근하는 등에 사용됩니다. 보안상 위험(노드 파일시스템 직접 접근)이 있으므로 주의가 필요합니다. `type` 필드로 Directory, File, Socket 등을 지정합니다.

A) kubelet이 실행 중인 노드의 IP

B) Pod 내부에서 Kubernetes API 서버에 접근하기 위한 ClusterIP (자동 주입됨)

C) etcd 서버의 주소

D) Ingress Controller의 주소

**정답**: B

**설명**: Kubernetes는 모든 Pod에 `KUBERNETES_SERVICE_HOST`와 `KUBERNETES_SERVICE_PORT` 환경 변수를 자동으로 주입합니다. 이 변수들은 Pod 내에서 Kubernetes API에 프로그래밍 방식으로 접근할 때 사용됩니다. ServiceAccount 토큰과 함께 사용하여 클러스터 내부에서 API를 호출할 수 있습니다.

A) 각각 최대 시간, 주기, 재시도 횟수를 설정한다

B) initialDelaySeconds: 첫 Probe 시작 전 대기 시간, periodSeconds: Probe 실행 주기, failureThreshold: 연속 실패 횟수 임계값

C) 모두 타임아웃 관련 설정이다

D) 데이터베이스 연결 관련 설정이다

**정답**: B

**설명**: `initialDelaySeconds`: 컨테이너 시작 후 첫 번째 Probe 실행까지 대기 시간(앱 초기화 시간 고려). `periodSeconds`: Probe를 실행하는 주기(기본 10초). `failureThreshold`: 이 횟수만큼 연속 실패하면 재시작(Liveness) 또는 트래픽 제외(Readiness). `timeoutSeconds`: 단일 Probe의 타임아웃.

A) 파일시스템 암호화 그룹을 지정한다

B) 마운트된 볼륨의 파일 소유권을 지정된 GID로 설정하여 그룹 기반 파일 접근을 가능하게 한다

C) 컨테이너 사용자를 지정한다

D) 네트워크 그룹을 지정한다

**정답**: B

**설명**: `spec.securityContext.fsGroup`은 Pod에 마운트된 볼륨(PVC 포함)의 파일 소유 그룹 GID를 지정합니다. 마운트된 볼륨의 파일 권한이 자동으로 해당 GID로 변경됩니다. 여러 컨테이너가 볼륨을 공유할 때 파일 접근 권한 문제를 해결하는 데 유용합니다.

실기 시뮬레이션 (P1 ~ P10)

P1. Multi-Container Pod with Sidecar

**시나리오**: nginx 메인 컨테이너와 busybox sidecar 컨테이너로 구성된 Pod를 생성하시오. Sidecar는 `/var/log/nginx/access.log`를 읽어 stdout으로 출력하시오. 두 컨테이너는 emptyDir 볼륨을 통해 로그 디렉토리를 공유해야 합니다.

cat <<EOF | kubectl apply -f -

apiVersion: v1

kind: Pod

metadata:

name: nginx-with-sidecar

labels:

app: nginx-sidecar

spec:

containers:

- name: nginx

image: nginx:latest

volumeMounts:

- name: log-volume

mountPath: /var/log/nginx

- name: log-sidecar

image: busybox:latest

command: ['sh', '-c', 'tail -f /var/log/nginx/access.log']

volumeMounts:

- name: log-volume

mountPath: /var/log/nginx

volumes:

- name: log-volume

emptyDir: {}

EOF

사이드카 컨테이너 로그 확인

kubectl logs nginx-with-sidecar -c log-sidecar -f

P2. ConfigMap과 Secret을 사용하는 Deployment

**시나리오**: `db-config` ConfigMap과 `db-secret` Secret을 생성하고, 이를 환경 변수로 주입한 Deployment를 생성하시오.

ConfigMap 생성

kubectl create configmap db-config \

--from-literal=DB_HOST=mysql-service \

--from-literal=DB_PORT=3306 \

--from-literal=DB_NAME=myapp

Secret 생성

kubectl create secret generic db-secret \

--from-literal=DB_USER=admin \

--from-literal=DB_PASSWORD=secretpassword

Deployment 생성

cat <<EOF | kubectl apply -f -

apiVersion: apps/v1

kind: Deployment

metadata:

name: myapp

spec:

replicas: 2

selector:

matchLabels:

app: myapp

template:

metadata:

labels:

app: myapp

spec:

containers:

- name: myapp

image: nginx:latest

envFrom:

- configMapRef:

name: db-config

env:

- name: DB_USER

valueFrom:

secretKeyRef:

name: db-secret

key: DB_USER

- name: DB_PASSWORD

valueFrom:

secretKeyRef:

name: db-secret

key: DB_PASSWORD

EOF

환경 변수 확인

kubectl exec -it deploy/myapp -- env | grep -E "DB_"

P3. Probe 설정

**시나리오**: nginx Deployment에 Liveness Probe(HTTP, /healthz, 포트 80), Readiness Probe(HTTP, /ready, 포트 80), Startup Probe를 설정하시오.

cat <<EOF | kubectl apply -f -

apiVersion: apps/v1

kind: Deployment

metadata:

name: nginx-with-probes

spec:

replicas: 2

selector:

matchLabels:

app: nginx-probes

template:

metadata:

labels:

app: nginx-probes

spec:

containers:

- name: nginx

image: nginx:latest

ports:

- containerPort: 80

startupProbe:

httpGet:

path: /

port: 80

failureThreshold: 30

periodSeconds: 10

livenessProbe:

httpGet:

path: /

port: 80

initialDelaySeconds: 10

periodSeconds: 15

failureThreshold: 3

timeoutSeconds: 5

readinessProbe:

httpGet:

path: /

port: 80

initialDelaySeconds: 5

periodSeconds: 10

failureThreshold: 3

successThreshold: 1

EOF

P4. Rolling Update 및 Rollback

**시나리오**: `webapp` Deployment를 생성하고 이미지를 업데이트하며 롤아웃 상태를 모니터링하시오. 업데이트 후 롤백하시오.

초기 Deployment 생성

kubectl create deployment webapp \

--image=nginx:1.24 \

--replicas=4

배포 전략 설정

kubectl patch deployment webapp -p \

'{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":1}}}}'

이미지 업데이트

kubectl set image deployment/webapp nginx=nginx:1.25

롤아웃 모니터링

kubectl rollout status deployment/webapp

히스토리 확인

kubectl rollout history deployment/webapp

일시 중지하여 카나리 테스트

kubectl rollout pause deployment/webapp

Pod 상태 확인 (일부는 새 버전, 일부는 이전 버전)

kubectl get pods -l app=webapp -o wide

문제 없으면 재개

kubectl rollout resume deployment/webapp

또는 롤백

kubectl rollout undo deployment/webapp

P5. SecurityContext 설정

**시나리오**: 다음 보안 요구사항을 가진 Pod를 생성하시오:

- 사용자 ID 1000으로 실행

- root로 실행 불가

- 읽기 전용 루트 파일시스템

- 모든 Linux capabilities 제거

cat <<EOF | kubectl apply -f -

apiVersion: v1

kind: Pod

metadata:

name: secure-pod

spec:

securityContext:

runAsUser: 1000

runAsNonRoot: true

fsGroup: 2000

containers:

- name: app

image: nginx:latest

securityContext:

readOnlyRootFilesystem: true

allowPrivilegeEscalation: false

capabilities:

drop:

- ALL

volumeMounts:

- name: tmp-dir

mountPath: /tmp

- name: var-cache

mountPath: /var/cache/nginx

- name: var-run

mountPath: /var/run

volumes:

- name: tmp-dir

emptyDir: {}

- name: var-cache

emptyDir: {}

- name: var-run

emptyDir: {}

EOF

보안 설정 확인

kubectl exec secure-pod -- id

kubectl exec secure-pod -- cat /proc/1/status | grep Cap

P6. Init Container 사용

**시나리오**: Init Container를 사용하여 메인 컨테이너가 시작되기 전에 데이터베이스 연결을 확인하는 Pod를 생성하시오.

cat <<EOF | kubectl apply -f -

apiVersion: v1

kind: Pod

metadata:

name: app-with-init

spec:

initContainers:

- name: wait-for-db

image: busybox:latest

command: ['sh', '-c',

'until nc -z mysql-service 3306; do echo "Waiting for MySQL..."; sleep 5; done; echo "MySQL is ready!"']

- name: migrate-db

image: busybox:latest

command: ['sh', '-c', 'echo "Running DB migration..."; sleep 2; echo "Migration complete"']

containers:

- name: app

image: nginx:latest

ports:

- containerPort: 80

EOF

Init Container 로그 확인

kubectl logs app-with-init -c wait-for-db

kubectl logs app-with-init -c migrate-db

Pod 상태 확인

kubectl get pod app-with-init

kubectl describe pod app-with-init

P7. ResourceQuota와 LimitRange 설정

**시나리오**: `team-dev` 네임스페이스에 ResourceQuota(CPU 4코어, 메모리 8Gi, Pod 10개)와 LimitRange(컨테이너당 기본 CPU 100m/메모리 128Mi, 최대 CPU 1/메모리 1Gi)를 설정하시오.

kubectl create namespace team-dev

cat <<EOF | kubectl apply -f -

apiVersion: v1

kind: ResourceQuota

metadata:

name: team-quota

namespace: team-dev

spec:

hard:

requests.cpu: "4"

requests.memory: 8Gi

limits.cpu: "8"

limits.memory: 16Gi

pods: "10"

services: "5"

apiVersion: v1

kind: LimitRange

metadata:

name: container-limits

namespace: team-dev

spec:

limits:

- type: Container

default:

cpu: 200m

memory: 256Mi

defaultRequest:

cpu: 100m

memory: 128Mi

max:

cpu: "1"

memory: 1Gi

min:

cpu: 50m

memory: 64Mi

EOF

확인

kubectl describe resourcequota team-quota -n team-dev

kubectl describe limitrange container-limits -n team-dev

P8. Ingress with TLS

**시나리오**: TLS를 사용하는 Ingress를 설정하여 `secure.example.com`으로 https 접근이 가능하게 하시오.

자체 서명 인증서 생성

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \

-keyout /tmp/tls.key \

-out /tmp/tls.crt \

-subj "/CN=secure.example.com/O=myorg"

TLS Secret 생성

kubectl create secret tls secure-tls \

--cert=/tmp/tls.crt \

--key=/tmp/tls.key

서비스 생성 (테스트용)

kubectl create deployment secure-app --image=nginx --replicas=2

kubectl expose deployment secure-app --port=80 --name=secure-app-service

TLS Ingress 생성

cat <<EOF | kubectl apply -f -

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

name: secure-ingress

annotations:

nginx.ingress.kubernetes.io/ssl-redirect: "true"

spec:

ingressClassName: nginx

tls:

- hosts:

- secure.example.com

secretName: secure-tls

rules:

- host: secure.example.com

http:

paths:

- path: /

pathType: Prefix

backend:

service:

name: secure-app-service

port:

number: 80

EOF

kubectl get ingress secure-ingress

P9. NetworkPolicy 이그레스 제어

**시나리오**: `backend` Pod가 포트 5432(PostgreSQL)의 `database` Pod에만 트래픽을 보낼 수 있도록 egress NetworkPolicy를 설정하시오. DNS 쿼리는 허용해야 합니다.

cat <<EOF | kubectl apply -f -

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

name: backend-egress-policy

namespace: default

spec:

podSelector:

matchLabels:

app: backend

policyTypes:

- Egress

egress:

- to:

- podSelector:

matchLabels:

app: database

ports:

- protocol: TCP

port: 5432

- ports:

- protocol: UDP

port: 53

- protocol: TCP

port: 53

EOF

NetworkPolicy 확인

kubectl get networkpolicy backend-egress-policy

kubectl describe networkpolicy backend-egress-policy

P10. Job과 CronJob

**시나리오**: 1부터 10까지의 합계를 계산하는 Job을 생성하고, 매 분마다 현재 시간과 호스트 이름을 출력하는 CronJob을 생성하시오.

합계 계산 Job

cat <<EOF | kubectl apply -f -

apiVersion: batch/v1

kind: Job

metadata:

name: sum-calculator

spec:

completions: 1

parallelism: 1

backoffLimit: 3

template:

spec:

containers:

- name: calculator

image: busybox:latest

command:

- /bin/sh

- -c

- |

sum=0

for i in 1 2 3 4 5 6 7 8 9 10; do

sum=$((sum + i))

done

echo "Sum of 1 to 10 is: $sum"

restartPolicy: OnFailure

EOF

CronJob 생성

cat <<EOF | kubectl apply -f -

apiVersion: batch/v1

kind: CronJob

metadata:

name: heartbeat

spec:

schedule: "* * * * *"

concurrencyPolicy: Forbid

successfulJobsHistoryLimit: 3

failedJobsHistoryLimit: 1

jobTemplate:

spec:

template:

spec:

containers:

- name: heartbeat

image: busybox:latest

command:

- /bin/sh

- -c

- echo "Heartbeat at $(date) from $(hostname)"

restartPolicy: OnFailure

EOF

Job 로그 확인

kubectl logs -l job-name=sum-calculator

CronJob 확인

kubectl get cronjob heartbeat

kubectl get jobs --watch

시험 팁

1. **도메인 파악**: Application Environment, Configuration & Security(25%)가 가장 높은 비중

2. **YAML 빠른 생성**: `--dry-run=client -o yaml`로 템플릿 생성

3. **probe 필드 암기**: initialDelaySeconds, periodSeconds, failureThreshold 기억

4. **SecurityContext 레벨 구분**: Pod 수준 vs 컨테이너 수준

5. **ConfigMap vs Secret**: 민감 정보는 반드시 Secret 사용

6. **kubectl explain 활용**: `kubectl explain pod.spec.containers.securityContext`로 필드 확인

현재 단락 (1/727)

CKAD(Certified Kubernetes Application Developer)는 CNCF에서 주관하는 Kubernetes 애플리케이션 개발자를 위한 실기 중심 자격증입니다...

작성 글자: 0원문 글자: 23,796작성 단락: 0/727