Pod 리소스
[ Pod 특징 ]
[ 1개 이상의 컨테이너 실행 ]
- Pod는 1개 이상의 컨테이너를 가질 수 있다
- 보통은
1개
/ 상황에 따라 2개
/ 정말 많으면 3개
까지 실행
=> 그 이상으로 넘어가는 경우는 거의 없다
[ 고유의 Pod IP ]
- 노드 IP와 별개로 Pod는 클러스터 내에서 접근 가능한
고유의 IP
를 할당받음
- k8s에서는 다른 노드에 위치한 Pod더라도 NAT(
Network Address Translation
) 없이 Pod IP
로 접근 가능
- 같은 Pod에 있는 컨테이너는 모두
동일한 IP
를 가진다 => port
로 컨테이너 구분
[ Volume 공유 ]
- Pod 안의 컨테이너끼리 동일한 볼륨으로 연결 가능
- 파일 시스템을 기반으로 서로 파일을 주고 받을 수 있다
[ Pod의 생성 과정 ]
- 사용자가
kubectl
명령을 통해 Pod 정의서
를 k8s 마스터(Api Server)
에게 전달
- k8s는 Pod의
YAML정의
의 유효성 체크
kube-scheduler
를 통해 특정 노드에 할당
하고 사용자의 요청에 따라 컨테이너 실행하도록 명령
- 명령을 전달받은 노드의
kubelet
은 요청 스펙에 맞춰 실제 컨테이너를 노드에 생성
[ 라벨링 시스템 ]
[ 개요 ]
- key-value 형태의 라벨을 활용한 매커니즘
- 특정 리소스 참조 / Pod에 트래픽 전달 등의 목적으로 사용
- 라벨링 자체는 Pod의 metadata property에 문자열을 추가하는 것에 불과
[ 라벨 부여 방법 ]
- label 명령어 (명령형 스타일)
- command 형식 :
kubectl label pod <NAME>=<VALUE>
- ex )
kubectl label pod mynginx hello=world
/* Pod 정의서 */
apiVersion: v1
kind: Pod
metadata:
labels:
hello: world // hello=world 라벨 지정
...
[ 라벨 정보 확인 ]
kubectl get pod mynginx -L run
kubectl get pod mynginx --show-labels
kubectl get pod -l run
kubectl get pod -l run=mynginx
[ nodeSelector ]
- Pod는 기본적으로 노드에 할당될 때 명시하지 않으면
kube-scheduler
가 알아서 할당
nodeSelector
property를 통해 특정 노드에 Pod 할당 가능
1) Node에 Label 추가
2) Pod 정의 YAML에 nodeSelector
를 이용해 1)에서 추가한 Label 지정
- 만약 동일한 노드에 동일한 라벨이 있다면 ?
- k8s가 노드의 상태 (
리소스 사용량
등)을 확인하여 최적의 노드 선택
/* 노드의 라벨 전체 조회 */
kubectl get node --show-labels
/* 1) worker 노드에 라벨 추가 */
kubectl label worker disktype=ssd
/* 1-1) 추가된 라벨 확인 */
kubectl get node worker disktype=ssd
/* 2) Pod의 YAML 정의서에 nodeSelector로 매핑 */
apiVersion: v1
kind: Pod
metadata:
name: node-selector
spec:
nodeSelector:
disktype: ssd
...
/* 3) Pod 생성 */
kubectl apply -f node-selector.yaml
/* 4) Pod가 어떤 노드에 할당되었는지 확인 : -o wide 옵션 */
kubectl get pod node-selector -o wide
[ 실행 명령 및 파라미터 지정 ]
- Pod 생성시 실행 명령(
command
)과 파라미터(args
)를 전달할 수 있다
apiVersion: v1
kind: Pod
...
spec:
restartPolicy: OnFailure
containers:
-name: nginx
image: nginx
command: ["/bin/echo"]
args: ["hello"]
apiVersion
- 리소스의 이름이 동일할 경우, 이름충돌을 피하기 위한 목적
- 즉, 리소스의 scope를 정의
kind
metadata
labels
: 리소스의 라벨정보
name
: 리소스의 이름
spec
: 리소스의 스펙 정의
containers
: 1개 이상의 컨테이너 정의
name
: 컨테이너 이름
image
: 컨테이너 이미지 주소
command
: 컨테이너의 시작 실행명령을 지정 (docker의 ENTRYPOINT
와 대응)
args
: 실행 명령에 넘겨줄 파라미터 (docker의 CMD
와 대응)
- restartPolicy : Pod의 재시작 정책
Always
: Pod 종료시 항상 재시작
Never
: 재시작 시도 X
OnFailure
: 실패 시에만 재시작 시도
[ 환경변수 설정 ]
spec > containers > env
에 name
과 value
를 추가하여 환경변수 설정 가능
apiVersion: v1
kind: Pod
...
spec:
containers:
-name: nginx
image: nginx
env:
-name: profile
value: cbt
[ Volume 연결 ]
- Pod 내부 스토리지는 Pod가 사라지면 데이터도 함께 삭제된다
- 가장 기본이 되는 host Volume과 연결하여 데이터를 유지할수 있다
apiVersion: v1
kind: Pod
...
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: /container-volume
name: my-volume
volumes:
- name: my-volume
hostPath:
path: /home
volumeMounts
mountPath
: 연결할 컨테이너 내부의 mountPath
name
: 연결할 host volume의 name
volumes
name
: host volume의 이름 (volumeMounts > name
과 대응되는 property
)
hostPath
: host의 연결 위치(volume
)
emptyDir
- Pod 내에 임시로 생성되는 공간 (
임시 volume
)
- 주로
컨테이너끼리 파일 데이터를 주고 받을 때
사용 => 큰 특징
[ 리소스 관리 ]
[ request / limits ]
- 컨테이너 실행에 필요한 리소스를 제약할 수 있는 property
- requests : 최소 리소스 사용량 보장
- limits : 최대 리소스 사용량 제한
apiVersion: v1
kind: Pod
...
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "250m"
memory: "500Mi"
limits:
cpu: "500m"
memory: "1Gi"
[ 상태 확인 - liveness / readness ]
[ livenessProbe / readnessProbe ]
apiVersion: apps/v1
kind: Deployment
metadata:
name: harmony-internship-app
namespace: default
spec:
selector:
matchLabels:
app: internship-app
replicas: 1
template:
metadata:
labels:
app: internship-app
spec:
containers:
- name: internship-app
image: {image 주소}
imagePullPolicy: Always
readinessProbe:
httpGet:
path: /actuator/health
port: 8090
initialDelaySeconds: 60
periodSeconds: 5
livenessProbe:
httpGet:
path: /actuator/health
port: 8090
initialDelaySeconds: 60
periodSeconds: 5
timeoutSeconds: 2
lifecycle:
preStop:
exec:
command: [ "/bin/sleep","10" ]
Http Status code
가 2xx ~ 3xx
인 경우 정상으로 판단
livenessProbe
이 정상적인 응답을 받지 못하면
restartPolicy
에 의해 재시작 수행
restartPolicy = Always(기본값)
/ OnFailure
/ Never
$ kubectl get pod
수행시 나오는 RESTARTS
값이 재시작 횟수를 의미
- HTTP 통신 뿐만 아니라, 명령 실행(
exec
)을 통해서도 livenessProbe
/ readnessProbe
설정 가능
- return 값이
0
이외의 값이면 모두 비정상으로 인식
[ Pod 디자인 패턴 ]
- Pod 내 Container의 실행순서는 보장되지 않는다
=> initContainer
프로퍼티로 초기화 작업(initalize
) 수행 가능
- SideCar 패턴
- 기본 컨테이너의 기능을 확장하거나 강화하는 용도로 컨테이너를 추가하는 패턴
- 하나의 Pod에 여러개의 Container가 존재하게 된다
- 로그수집 등등을 목적으로 많이 사용하는 k8s 패턴
- Adapter 패턴
- pod 내 proxy 역할을 하는 컨테이너를 추가하는 패턴
- pod 내에서 외부 서버에 접근할 때 내부 proxy에 접근하고, 실제 외부 연결은 proxy에서 처리
- Ambassador 패턴
- Pod 외부로 노출되는 정보를 표준화 하는 역할을 하는 컨테이너를 추가하는 패턴
- 주로 pod 모니터링 지표를 어댑터 컨테이너를 통해 표준화 형식으로 노출시키고,
외부의 모니터링 시스템에서 데이터를 주기적으로 가져가서 모니터링에 이용
ConfigMap 리소스
[ ConfigMap 기본 ]
- k8s에서 설정값들을 따로 모아두고 필요할 때 꺼내 사용할 수 있는 리소스
- 설정값을 가져와서 Pod에서 사용할 수 있다
[ cli를 통한 ConfigMap 생성 ]
$ kubectl create configmap test-config --from-file=test.propertis
$ kubectl get cm test-config -o yaml
$ kubectl create configmap special-config \
--from-literal=special.power=10 \
--from-literal=speical.strength=20
[ yaml을 통한 ConfigMap 생성 ]
apiVersion: v1
kind: ConfigMap
metadata:
name: test-config
namespace: default
data:
name: hue
age: 27
money: 10000
[ ConfigMap 활용 ]
[ Pod와 Volume 연결 ]
apiVersion: v1
kind: Pod
metadata:
name: game-volume
spec:
restartPolicy: OnFailure
containers:
- name: game-volume
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "cat /etc/config/game.properties" ]
volumeMounts:
- name: game-volume
mountPath: /etc/config
volumes:
- name: game-volume
configMap:
name: game-config
- volumes > configMap 프로퍼티에 특정 configMap을 연결해서 볼륨으로 사용
[ Pod의 환경변수에 등록 - 특정 값만 ]
apiVersion: v1
kind: Pod
metadata:
name: special-env
spec:
restartPolicy: OnFailure
containers:
- name: special-env
image: k8s.gcr.io/busybox
command: [ "printenv" ]
args: [ "special_env" ]
env:
- name: special_env
valueFrom:
configMapKeyRef:
name: special-config
key: special.power
[ Pod의 환경변수에 등록 - ConfigMap 자체를 ]
apiVersion: v1
kind: Pod
metadata:
name: monster-env
spec:
restartPolicy: OnFailure
containers:
- name: monster-env
image: k8s.gcr.io/busybox
command: [ "printenv" ]
envFrom:
- configMapRef:
name: monster-config
Secret 리소스
[ Secret 기본 ]
- ConfigMap과 유사하지만, 민감 데이터를 저장하는데 특화된 리소스
- 각 노드에서 사용될 때 디스크에 저장되지 않고, tmpfs 라는 메모리 기반 파일시스템을 사용하여 보안에 강하다
- Secret 리소스를 사용자가 조회할 때 base64로 한번 인코딩 되어 표시된다 (암호화는 X)
[ yaml을 통한 Secret 생성 ]
apiVersion: v1
kind: Secret
metadata:
name: user-info
type: Opaque
data:
username: YWRtaW4=
password: cGFzc3dvcmQxMjM=
- 직접 사용자가 base64로 인코딩해서 넣을 수도 있지만, k8s에서 대신 처리하길 원한다면 stringData 프로퍼티를 사용하면 된다
apiVersion: v1
kind: Secret
metadata:
name: user-info-stringdata
type: Opaque
stringData:
username: admin
password: password123
[ Secret 활용 ]
[ Pod와 Volume 연결 ]
apiVersion: v1
kind: Pod
metadata:
name: secret-volume
spec:
restartPolicy: OnFailure
containers:
- name: secret-volume
image: k8s.gcr.io/busybox
command: [ "sh" ]
args: ["-c", "ls /secret; cat /secret/username"]
volumeMounts:
- name: secret
mountPath: "/secret"
volumes:
- name: secret
secret:
secretName: user-info
[ Pod의 환경변수에 등록 - 특정 값만 ]
apiVersion: v1
kind: Pod
metadata:
name: secret-env
spec:
restartPolicy: OnFailure
containers:
- name: secret-env
image: k8s.gcr.io/busybox
command: [ "printenv" ]
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: user-info
key: username
- name: PASSWORD
valueFrom:
secretKeyRef:
name: user-info
key: password
[ Pod의 환경변수에 등록 - ConfigMap 자체를 ]
apiVersion: v1
kind: Pod
metadata:
name: secret-envfrom
spec:
restartPolicy: OnFailure
containers:
- name: secret-envfrom
image: k8s.gcr.io/busybox
command: [ "printenv" ]
envFrom:
- secretRef:
name: user-info