환경변수 대신 파일로 메타데이터를 노출하려는 경우 downwwardAPI 볼륨을 정의해서 컨테이너에 마운트할 수 있다.
downward라는 볼륨을 정의하고 컨테이너의 /etc/downward 아래에 마운트하는 예제
apiVersion: v1
kind: Pod
metadata:
name: downward
labels: # 이 레이블과 어노테이션은 downwardAPI 볼륨으로 노출된다.
foo: bar
annotations:
key1: value1
key2: |
multi
line
value
spec:
containers:
- name: main
image: busybox
command: ["sleep", "9999999"]
resources:
requests:
cpu: 15m
memory: 100Ki
limits:
cpu: 100m
memory: 20Mi
volumeMounts: # downward 볼륨 /etc/downward에 마운트
- name: downward
mountPath: /etc/downward
volumes:
- name: downward # downwardAPI 볼륨 정의
downwardAPI:
items:
- path: "podName" # metadata.name에 정의한 이름은 podName 파일에 기록된다.
fieldRef:
fieldPath: metadata.name
- path: "podNamespace"
fieldRef:
fieldPath: metadata.namespace
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
- path: "containerCpuRequestMilliCores"
resourceFieldRef:
containerName: main
resource: requests.cpu
divisor: 1m
- path: "containerMemoryLimitBytes"
resourceFieldRef:
containerName: main
resource: limits.memory
divisor: 1
# pod 생성
kubectl create -f downward-api-volume.yaml
# pod 데이터 확인
kubectl exec downward -- ls -al /etc/downward/
kubectl exec downward -- cat /etc/downward/labels
kubectl exec downward -- cat /etc/downward/annotations
레이블과 어노테이션 업데이트
파드가 실행되는 동안 레이블, 어노테이션 값을 업데이트될 수 있다.
downwardAPI 볼륨을 이용하는 경우에는 업데이트시에도 최신 데이터를 볼수 있다.
환경변수를 사용하는 경우에는 나중에 업데이트할 수 없다.
볼륨 스펙에서 컨테이너 수준의 메타데이터 참조
리소스 제한 또는 요청(resourceFieldRef)과 같은 컨테이너 수준의 메타데이터를 노출하는 경우 리소스 필드를 참조하는 컨테이너의 이름을 필수로 지정해야 한다.(컨테이너가 하나인 파드에서도 필수 지정)
# batch/v1 리소스 유형
curl http://localhost:8001/apis/batch/v1
{
"kind": "APIResourceList", # batch/v1 API 그룹 내의 API 리소스 목록
"apiVersion": "v1",
"groupVersion": "batch/v1",
"resources": [ # 이 그룹의 모든 리소스 유형을 담는 배열
{
"name": "jobs",
"singularName": "",
"namespaced": true, # 네임스페이스에 속하는 리소스라는 의미 ( persistentvolumes같은 것들은 false)
"kind": "Job",
"verbs": [ # 이 리소스와 함꼐 사용할 수 있는 제공되는 API(단일, 여러개를 한꺼번에 추가 삭제할수 있고, 검색, 감시 업데이트 할수 있음)
"create",
"delete",
"deletecollection",
"get",
"list",
"patch",
"update",
"watch"
],
"categories": [
"all"
],
"storageVersionHash": "mudhfqk/qZY="
},
{
"name": "jobs/status", # 리소스의 상태를 수정하기 위한 특수한 REST 엔드포인트
"singularName": "",
"namespaced": true,
"kind": "Job",
"verbs": [
"get",
"patch",
"update"
]
}
]
}
클러스터 안에 있는 모든 잡 인스턴스 나열하기
items 하위에 나열된다.
# job 생성
kubectl create -f my-job.yaml
# 모든 잡 인스턴스 조회
curl http://localhost:8001/apis/batch/v1/jobs
이름별로 특정 잡 인스턴스 검색
# api를 통한 job 조회
curl http://localhost:8001/apis/batch/v1/namespaces/default/jobs/my-job
# job 정보 조회
kubectl get job my-job -o json
# 위 2가지 결과는 같다.
8.2.2 파드 내에서 APi 서버와 통신
파드 내에서 통신하려면 APi 서버의 위치를 찾아야하고, 서버로 인증을 해야 한다.
API 서버와의 통신을 시도하기 위해 파드 실행
# curl을 위한 파드 생성
kubectl create -f curl.yaml
# 파드의 shell 접근
kubectl exec -it curl bash
API 서버 주소 찾기
실제 애플리케이션에서는 서버 인증서 확인을 절대로 건너뛰면 안된다. 중간자 공격(man-in-the-middle attack)으로 인증 토큰을 공격자에게 노출할수 있기 때문
중간자 공격(man-in-the-middle attack)은 통신을 연결하는 두 사람 사이에 중간자가 침입해 두 사람은 상대방에 연결했다고 생각하지만 실제로는 두 사람은 중간자에게 연결돼 있으며, 중간자가 한쪽에서 전달된 정보를 도청 및 조작한 후 다른쪽으로 전달하는 방식
# kubernetes 서비스
kubectl get svc
# KUBERNETES_SERVICE_HOST, KUBERNETES_SERVICE_PORT 변수를 통해 얻을수 있다.
env | grep KUBERNETES_SERVICE
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT_HTTPS=443
# FQDN을 이용한 방법(403)
curl https://kubernetes -k
서버의 아이덴티티 검증
각 컨테이너의 /var/run/secrets/kubernetes.io/serviceaccount/에 마운트되는 자동 생성된 default-token-xyz 라는 이름의 시크릿을 기준으로 처리할수 있다.
# 컨테이너 내부에서 조회
ls /var/run/secrets/kubernetes.io/serviceaccount/
ca.crt namespace token
# --cacert 옵션을 통해 인증서 지정 ( 여전히 403)
curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://kubernetes
# 환경변수 지정
export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
# 재호출
curl https://kubernetes
API 서버로 인증
Authorization HTTP 헤더 내부에 토큰을 전달하여 토큰을 인증된 것으로 인식하여 적절한 응답을 받을 수 있다.
이런 방식을 통해 네임스페이스 내에 있는 모든 파드를 조회할 수 있다. 그러나 먼저 curl 파드가 어떤 네임스페이서에서 실행중인지 알아야 한다.
8. 애플리케이션에서 파드 메타데이터와 그 외의 리소스에 엑세스하기
8.1 Downward API로 메타데이터 전달
8.1.1 사용 가능한 메타데이터 이해
메타데이터 종류
8.1.2 환경변수로 메타데이터 노출하기
8.1.3 downwardAPI 보륨에 파일로 메타데이터 전달
레이블과 어노테이션 업데이트
볼륨 스펙에서 컨테이너 수준의 메타데이터 참조
Downward API 사용 시기 이해
8.2 쿠버네티스 API 서버와 통신하기
8.2.1 쿠버네티스 REST API 살펴보기
kubectl proxy로 API 서버 엑세스하기
배치 api 그룹의 REST 엔드포인트 살펴보기
클러스터 안에 있는 모든 잡 인스턴스 나열하기
이름별로 특정 잡 인스턴스 검색
8.2.2 파드 내에서 APi 서버와 통신
API 서버와의 통신을 시도하기 위해 파드 실행
API 서버 주소 찾기
서버의 아이덴티티 검증
API 서버로 인증
역할 기반 엑세스 제어(RBAC) 비활성화
파드가 실행중인 네임스페이스 얻기
파드가 쿠버네티스와 통신하는 방법 정리
82.3 앰배서더 컨테이너를 이용한 API 서버 통신 간소화
앰배서더 컨테이너 패턴 소개
추가적인 앰배서더 컨테이너를 사용한 curl 파드 실행
8.2.4 클라이언트 라이브러리를 사용해 API 서버와 통신
Java 예제 ( https://github.com/kubernetes-client/java/ )
스웨거와 Open API를 사용해 자신의 라이브러리 구축
스웨거 UI로 API 살펴보기
API 서버를 --enable-swagger-ui=true
옵션으로 실행하면 활성화된다.8.3 요약