쿠버네티스:
컨테이너화된 워크로드와 서비스를 관리하기 위한 이식 & 확장 가능한 오픈소스 플랫폼
선언적 구성 & 자동화 모두 용이
오케스트레이션:
여러 대상을 조율하여 하나의 큰 작업을 수행하는 것
일반적으로 컴퓨팅에서 사용되며, 여러 대상을 조정하여 복잡한 작업을 자동화하거나 관리하는 것.
pod:
컨테이너 어플리케이션의 기본 단위, 1개 이상의 컨테이너로 구성된 컨테이너 집합
kuberctl
명령어나 .yaml
를 이용하여 리소스 오브젝트를 정의하고 생성한다.ip 주소가 있어 클러스터 내부까지 접근 가능하고 exec 명령으로 접속이 가능하며 logs 명령으로 로그도 확인이 가능하다. -> container와 동일해보임
pod으로는 여러 linux namespaces를 공유하는 여러 컨테이너들을 추상화된 집합을 사용하는 것이 가능하기 때문에 pod을 씀
pod 내 container들은 같은 리눅스 네임스페이스를 동일하게 공유함.
ex) pod 내에서 설정 파일을 갱신해주는 프로세스, 로그 수집 프로세스 등 부가 기능하는 컨테이너를 sidecar 컨테이너를 같이 운영할 수도 있는 것임.
즉, pod은 구조 및 원리에 따라 여러 개의 컨테이너가 모여 하나의 완전한 애플리케이션으로서 동작할 수 있음.
일정 개수의 파드를 유지하는 컨트롤러
정해진 수의 동일한 파드가 항상 실행되도록 관리해줌.
노드 장애 등의 이유로 파드를 사용할 수 없다면 다른 노드에서 파드를 다시 생성함.
프로덕션 환경에서 사용하는 파드는 단순 yaml로 정의해서 생성하는 방식으로는 운영하기 어려움.
# 레플리카셋 정의
$ vi k8s_yaml/replicaset-nginx.yaml
$ cat k8s_yaml/replicaset-nginx.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset-nginx
spec:
replicas: 3 # replica를 몇 개 유지할 것인지 정함
selector:
matchLabels:
app: my-nginx-pods-label
template: # pod 생성 템플릿. (동일한 pod을 1번만 정의)
metadata:
name: my-nginx-pod
labels:
app: my-nginx-pods-label
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
# 적용
$ kubectl apply -f k8s_yaml/replicaset-nginx.yaml
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
replicaset-nginx-9jxj8 0/1 Pending 0 6s
replicaset-nginx-bbqbp 0/1 Pending 0 6s
replicaset-nginx-kthmc 0/1 Pending 0 6s
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
replicaset-nginx 3 3 0 75s
여러 개의 레플리카셋을 관리하기 위한 오브젝트
실제 프로덕션 환경에서는 레플리카셋을 직접 구현하는 게 아니라 더 상위개념인 Deployment를 정의해서 레플리카셋을 사용한다.
# 디플로이먼트 정의
$ vi k8s_yaml/deployment-nginx.yaml
$ cat k8s_yaml/deployment-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-nginx
template:
metadata:
name: my-nginx-pod
labels:
app: my-nginx
spec:
containers:
- name: nginx
image: nginx:1.10
ports:
- containerPort: 80
디플로이먼트를 통해 생성한 파드를 연결하여 외부에 노출해주는 오브젝트
pod의 ip는 영속적이지 않고 동일 대역폭 간 통신만 가능함.
여러 개의 deployment를 하나의 완벽한 앱으로 연동 ⇒ pod ip가 아닌 서로를 발견(Discovery)할 수 있는 다른 방법이 필요
apiVersion: v1
kind: Service
metadata:
name: hostname-svc-clusterip
spec:
ports: # 서비스 ip에 접근할 떄 사용할 포트
- name: web-port
port: 8080
targetPort: 80 # 접근 대상 파드들이 내부적으로 사용하고 있는 포트
# 파드 템플릿의 containerPort와 같은 값.
selector: # 접근할 수 있는 서비스 지정.(파드의 라벨명으로)
app: webserver
type: ClusterIP
pod, replicaset, deployment, service는 쿠버네티스에서 애플리케이션을 배포하기 위한 필수 오브젝트.
이외에 많이 사용하는 리소스로는 Namespace, Configmap, Secret 등이 있음.
리소스를 논리적으로 구분하는 장벽
파드, 레플리카셋, 디플로이먼트, 서비스 등과 같은 쿠버네티스 리소스들이 묶여있는 하나의 가상 공간이라고 이해하면 됨.
kube-system이라는 네임스페이스에 생성된 파드들 확인
** kube-system: 쿠버네티스 클러스터 구성에 필수적인 컴포넌트들과 설정값 등이 존재하는 네임스페이스
$ kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
anetd-8xwnw 1/1 Running 0 135m
antrea-controller-horizontal-autoscaler-6fb4bf7847-mbzhr 1/1 Running 0 17h
egress-nat-controller-799976cbcb-9smgm 1/1 Running 0 17h
event-exporter-gke-857959888b-wsjgx 2/2 Running 0 17h
filestore-node-2nz5n 3/3 Running 0 135m
...
YAML 파일과 설정값을 분리할 수 있도록 하는 오브젝트
네임스페이스 별로 컨피그맵이 있음.
# kubectl create configmap [컨피그맵 이름] [설정값]
$ kubectl create configmap log-level-configmap --from-literal LOG_LEVEL=DEBUG
# configmap 확인
$ kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 25h
log-level-configmap 1 42m
$ kubectl get cm log-level-configmap -o yaml
apiVersion: v1
data:
LOG_LEVEL: DEBUG
kind: ConfigMap
metadata:
creationTimestamp: "2023-04-20T05:56:56Z"
name: log-level-configmap
namespace: default
resourceVersion: "989329"
uid: 95962cc4-a75b-4489-87f3-c80bdf0b980e
컨피그맵의 데이터를 컨테이너 환경변수로 가져오기
envForm
: 컨피그맵에 존재하는 모든 key-value 쌍을 가져옴
...
envForm:
- configMapRef:
name: log-level-configmap
- configMapRef:
name: start-k8s
valueFrom
과 configMapKeyRef
: 컨피그맵에 존재하는 key-value 쌍 중에서 원하는 데이터만 선택적으로 가져옴.
...
env:
- name: ENV_KEYNAME_1 # (1.1) 컨테이너에 새롭게 등록될 환경 변수 이름
valueFrom: # 여러 개의 key-value 가 들어있는 컨피그맵에서 특정 데이터만들 선택해 환경변수로 가져올 수 있음.
configMapKeyRef:
name: log-level-configmap
key: LOG_LEVEL
- name: ENV_KEYNAME_2 # (1.2) 컨테이너에 새롭게 등록될 환경 변수 이름
valueFrom:
configMapKeyRef:
name: start-k8s # (2) 참조할 컨피그맵의 이름
key: k8s # (3) 가져올 데이터 값의 키
# 최종 결과 -> ENV_KEYNAME_2=$(k8s 키에 해당하는 값)
# ENV_KEYNAME_2=kubernetes
컨피그맵 값을 파드 내부의 파일로 마운트하여 사용
...
spec:
containers:
...
volumnMounts:
- name: configmap-volume # volumes에서 정의한 컨피그맵 볼륨 이름
mountPath: /etc/config # 컨피그맵의 데이터가 위치할 경로
volumes: # 사용할 볼륨 목록 정의
- name: configmap-volume # 컨피그맵 볼륨 이름
configMap:
name: start-k8s
# 컨피그맵을 파일로 마운트 하면 키 이름으로 파일이 생성됨.
$ kubectl exec configmap-volume-pod ls /etc/config
container # 키
k8s # 키
$ kubectl exec configmap-volume-pod cat /ect/config/k8s
kubernetes # 값
컨피그맵처럼 설정값을 저장해주는 오브젝트. 단, 비밀번호와 같이 민감한 정보를 저장함.
$ kubectl create generic my-password --from-literal password=1q2w3e4r
...
envFrom:
- secretRef:
name: my-password
파드의 데이터를 영속적으로 저장하기 위해 PV를 이용하여 프로비저닝을 함.