파일을 통해 컨테이너에 파드 정보 노출하기
파일을 통해 컨테이너에 파드 정보 노출하기 (Expose Pod Information to Containers Through Files)
이 페이지는 파드가 downwardAPI 볼륨을 사용해 파드 자신에 대한 정보를 파드 안에서 실행되는 컨테이너에 노출하는 방법을 보여 줘요. downwardAPI 볼륨은 파드 필드와 컨테이너 필드를 노출할 수 있어요.
쿠버네티스에는 실행 중인 컨테이너에 파드·컨테이너 필드를 노출하는 두 가지 방법이 있어요.
- 환경 변수 (environment variables)
- 볼륨 파일 (volume files) — 이 작업에서 설명하는 방법
이 두 가지를 함께 파드·컨테이너 필드 노출 방식을 downward API라고 불러요.
출처: 문서
본문
시작하기 전에
쿠버네티스 클러스터가 필요하고, kubectl 명령줄 도구가 클러스터와 통신하도록 설정돼 있어야 해요. 이 튜토리얼은 제어 플레인 호스트 역할을 하지 않는 노드가 최소 두 개 있는 클러스터에서 실행하는 것을 권장해요. 아직 클러스터가 없다면 minikube를 사용하거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용해 만들 수 있어요.
- iximiuz Labs
- Killercoda
- KodeKloud
파드 필드 저장하기
이 연습 부분에서는 컨테이너가 하나인 파드를 만들고, 파드 수준 필드를 실행 중인 컨테이너에 파일로 투영(project)해요. 파드의 매니페스트는 다음과 같아요.
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: registry.k8s.io/busybox:1.27.2
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
if [[ -e /etc/podinfo/annotations ]]; then
echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
매니페스트에서 파드가 downwardAPI 볼륨을 가지며, 컨테이너가 그 볼륨을 /etc/podinfo에 마운트하는 것을 볼 수 있어요.
downwardAPI 아래의 items 배열을 보세요. 배열의 각 요소는 downwardAPI 볼륨을 정의해요. 첫 번째 요소는 파드의 metadata.labels 필드의 값이 labels라는 파일에 저장되어야 함을 지정해요. 두 번째 요소는 파드의 annotations 필드의 값이 annotations라는 파일에 저장되어야 함을 지정해요.
참고:
파드를 만들어요.
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume.yaml
파드의 컨테이너가 실행 중인지 확인해요.
kubectl get pods
컨테이너의 로그를 확인해요.
kubectl logs kubernetes-downwardapi-volume-example
출력은 labels 파일과 annotations 파일의 내용을 보여 줘요.
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
build="two"
builder="john-doe"
파드에서 실행 중인 컨테이너로 셸을 얻어요.
kubectl exec -it kubernetes-downwardapi-volume-example -- sh
셸에서 labels 파일을 확인해요.
/# cat /etc/podinfo/labels
출력은 파드의 모든 라벨이 labels 파일에 기록되었음을 보여 줘요.
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
마찬가지로 annotations 파일을 확인해요.
/# cat /etc/podinfo/annotations
/etc/podinfo 디렉터리의 파일을 확인해요.
/# ls -laR /etc/podinfo
출력에서 labels와 annotations 파일이 임시 하위 디렉터리에 있음을 볼 수 있어요. 이 예시에서는 ..2982_06_02_21_47_53.299460680이에요. /etc/podinfo 디렉터리에서 ..data는 그 임시 하위 디렉터리를 가리키는 심볼릭 링크예요. 또한 /etc/podinfo 디렉터리에서 labels와 annotations는 심볼릭 링크예요.
drwxr-xr-x ... Feb 6 21:47 ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 ..data -> ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 annotations -> ..data/annotations
lrwxrwxrwx ... Feb 6 21:47 labels -> ..data/labels
/etc/..2982_06_02_21_47_53.299460680:
total 8
-rw-r--r-- ... Feb 6 21:47 annotations
-rw-r--r-- ... Feb 6 21:47 labels
심볼릭 링크를 사용하면 메타데이터의 동적 원자 새로고침(atomic refresh)이 가능해요. 업데이트는 새 임시 디렉터리에 기록되고, ..data 심볼릭 링크는 rename(2)으로 원자적으로 업데이트돼요.
참고:
셸을 종료해요.
/# exit
컨테이너 필드 저장하기
앞선 연습에서는 downward API를 사용해 파드 수준 필드에 접근할 수 있게 했어요. 이번 연습에서는 파드 정의의 일부이지만 파드 전체가 아니라 특정 컨테이너에서 가져온 필드를 전달할 거예요. 다시 컨테이너가 하나뿐인 파드의 매니페스트는 다음과 같아요.
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example-2
spec:
containers:
- name: client-container
image: registry.k8s.io/busybox:1.27.2
command: ["sh", "-c"]
args:
- while true; do
echo -en '\n';
if [[ -e /etc/podinfo/cpu_limit ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_limit; fi;
if [[ -e /etc/podinfo/cpu_request ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_request; fi;
if [[ -e /etc/podinfo/mem_limit ]]; then
echo -en '\n'; cat /etc/podinfo/mem_limit; fi;
if [[ -e /etc/podinfo/mem_request ]]; then
echo -en '\n'; cat /etc/podinfo/mem_request; fi;
sleep 5;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "cpu_limit"
resourceFieldRef:
containerName: client-container
resource: limits.cpu
divisor: 1m
- path: "cpu_request"
resourceFieldRef:
containerName: client-container
resource: requests.cpu
divisor: 1m
- path: "mem_limit"
resourceFieldRef:
containerName: client-container
resource: limits.memory
divisor: 1Mi
- path: "mem_request"
resourceFieldRef:
containerName: client-container
resource: requests.memory
divisor: 1Mi
매니페스트에서 파드가 downwardAPI 볼륨을 가지며, 그 파드의 단일 컨테이너가 그 볼륨을 /etc/podinfo에 마운트하는 것을 볼 수 있어요.
downwardAPI 아래의 items 배열을 보세요. 배열의 각 요소는 downward API 볼륨에서 파일을 정의해요.
첫 번째 요소는 client-container라는 컨테이너에서 limits.cpu 필드의 값이 1m이 지정하는 형식으로 cpu_limit라는 파일에 게시되어야 함을 지정해요. divisor 필드는 선택 사항이며 기본값은 1이에요. divisor가 1이면 CPU 리소스에서는 코어를, 메모리 리소스에서는 바이트를 의미해요.
파드를 만들어요.
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume-resources.yaml
파드에서 실행 중인 컨테이너로 셸을 얻어요.
kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh
셸에서 cpu_limit 파일을 확인해요.
# 컨테이너 안의 셸에서 이 명령을 실행하세요
cat /etc/podinfo/cpu_limit
cpu_request, mem_limit, mem_request 파일도 비슷한 명령으로 볼 수 있어요.
키를 특정 경로와 파일 권한으로 투영하기
키를 파일별로 특정 경로와 특정 권한으로 투영할 수 있어요. 자세한 내용은 Secret 문서를 참고하세요.
더 알아보기 (Learn more)
- 파드의 spec API 정의를 읽어 보세요. 여기에는 (파드의 일부인) Container의 정의가 포함돼 있어요.
- downward API로 노출할 수 있는 사용 가능한 필드 목록을 읽어 보세요.
- 레거시 API 참조에서 볼륨에 대해 읽어 보세요.
- 컨테이너가 접근할 파드의 일반 볼륨을 정의하는 Volume API 정의를 확인하세요.
- Downward API 정보를 포함하는 볼륨을 정의하는 DownwardAPIVolumeSource API 정의를 확인하세요.
- Downward API 볼륨의 파일을 채우기 위한 객체 또는 리소스 필드에 대한 참조를 포함하는 DownwardAPIVolumeFile API 정의를 확인하세요.
- 컨테이너 리소스와 그 출력 형식을 지정하는 ResourceFieldSelector API 정의를 확인하세요.