쿠버네티스 정리 - Kim-Taesu/study GitHub Wiki
쿠버네티스 설치하기
컨테이너
- 호스트 운영체제 위에 도커가 있고 바로 애플리케이션이 위치
- 가상머신보다 컨테이너가 구조상 레이어가 더 간단하므로 가상 머신보다 성능을 높이기 쉽다.
- 도커를 사용하면 간단한 명령으로 컨테이너 이미지를 만들고 저장소에 저장할 수 있다.
- 도커를 설치한 호스트에 해당 컨테이너 이미지를 다운로드해서 컨테이너를 실행할 수 있다.
컨테이너 오케스트레이션
- 컨테이너를 이용하면 개발 환경과 운영 환경의 차이 때문에 일어나는 많은 장애를 막을 수 있다.
- 개발 환경에서 실행했던 컨테이너를 컨테이너 런타임(도커)만 있다면 실제 서버 어디에서든지 실행할 수 있다.
- 컨테이너 오케스트레이션 시스템을 사용하면 수동 제어 부분 모두를 자동화하므로 시스템 운영이 훨씬 수월해진다.
- 컨테이너 오케이스트레이션 시스템으로 상용 서비스에 사용할 서버들을 클러스터로 구성하면 컨테이너를 한 번의 명령으로 서버 n대에 자동 배포할 수 있다.
- 사용중인 클럿스터 일부테 장애가 발생하면 오케스트레이션 시스템은 알아서 장애가 발생한 서버에 있는 컨테이너들을 정상 운영 중인 다른 서버로 옮겨서 실행시킨다.
쿠버네티스의 특징 - 선언적 API
- 컨테이너가 어떤 상태이길 원하는지만 쿠버네티스에 설정하면 지속해서 컨테이너의 상태를 확인한다.
- 설정한 상태가 아니라면 그것에 맞게 맞춘다는 개념
- 선언적 API로 인해 사용하는 컴포넌트들의 구현 또한 단순하다.
- 컴포넌트를 여러 개 실행해둘 수 있으므로 SPOF가 없다.
- 앱 재시작 같은 단순한 작업은 쿠버네티스에서 할 수 없다.
- 쿠버네티스 입장에서는 같은 설정, 즉 기존 설정과 비교했을 때 변경 사항이 없는 앱은 재시작 하지 않아도 된다 생각
- kubectl 1.15부터는 Deployment, Statefulset, Daemonset에 재시작 기능이 추가
쿠버네티스 클러스터를 직접 구성하는 도구 - Kubeadm
- 쿠버네티스에서 공식 제공하는 클러스터 생성/관리 도구
- 여러 대 서버를 쿠버네티스 클러스터로 손쉽게 구성할 수 있다.
쿠버네티스 클러스터를 직접 구성하는 도구 - KUBESpray
- 상용 서비스에 적합한 보안성과 고가용성이 있는 쿠버네티스 클러스터를 배포하는 오픈 소스 프로젝트
- 서버 환경 설정 자동화 도구인 ANSIBLe 기반으로 개발했다
- 설정에 따라 사용자에게 맞는 다양한 형식으로 쿠버네티스 클러스터를 구성할 수 있으므로 온프레미스 환경에서 상용 서비스의 쿠버네티스 클러스터를 구성할 때 유용하다.
쿠버네티스로 컨테이너 실행하기
kubectl
- 쿠버네티스 클러스터를 관리하는 동작 대부분은 kubectl이라는 커맨드라인 인터페이스로 실행할 수 있다.
- 쿠버네티스의 자원들의 생성, 업데이트 삭제 (create, update, delete)
- 디버그, 모니터링, 트러블 슈팅 (log, exec, cp, top, attach)
- 클러스터 관리 (cordon, top, drain, taint)
kubectl 사용
- 형식 :
kubectl [command] [TYPE] [NAME] [flags
- command : 자원에 실행하려는 동작
- create, get, delete 등을 사용
- TYPE: 자원 타입
- pod, service, ingress
- NAME : 자원 이름
- FLAG : 부가적으로 설정할 옵션을 입력
- command : 자원에 실행하려는 동작
Deployment를 사용하여 컨테이너 실행하기
- 쿠버네티스를 이용해서 컨테이너를 실행하는 방법에는 크게 두 가지가 있다.
kubectl run
명령으로 직접 컨테이너를 실행- YAML 형식의 템플릿으로 컨테이너를 실행
- 버전 관리 시스템과 연동해서 자원 정의 변동 사항을 추적하기 쉽다.
kubectl get deployments
- NAME : 클러스터에 배포한 디플로이먼트 이름
- READY : 사용자가 최종 배포한 파드 개수와 디플로이먼트를 이용해 현재 클러스터에 실제로 동작시킨 파드 개수를 X/X 형태로 표시
- UP-TO-DATE : 디플로이먼트 설정에 정의한 대로 동작 중인 신규 파드 개수
- AVAILABLE : 서비스 가능한 파드 개수
- AGE : Deployment 생성 후 얼마나 지났는지 시간을 표시
- YAML 템플릿을 사용할 경우
kubectl apply -f ngingx-app.yaml
클러스터 외부에서 클러스터 내부 앱에 접근
- 쿠버네티스 내부에서 실행한 컨테이너를 외부에서 접근하려면 쿠버네티스의 SERVICE를 사용 해야한다.
- 서비스 타입
- ClusterIP
- NodePort
- LoadBalancer
- ExternalName
- 서비스 목록 조회
kubectl get service
- 서비스 상세 조회
kubectl describe service nginx-app
Endpoints
항목으로 서비스에 몇 개의 컨테이너가 연결되어 있는지 확인 가능
쿠버네티스 아키텍처
쿠버네티스 클러스터 전체 구조
- 크게 두 종류의 서버로 구성
- 마스터 : 클러스터를 관리
- 노드 : 실제 컨테이너를 실행
- 마스터 서버에 실행되는 컴포넌트
- ectd
- kube-apiserver
- kube-scheduler
- kube-controller-manager
- kubelet
- kube-proxy
- docker
- 컴포넌트 각각이 다른 마스터나 노드 서버에서 별개로 실행되어도 실제 쿠버네티스 클러스터를 운영하는 데 이상은 없다.
- 마스터는 보통 고가용성을 만족하거자 서버 3대 정도 구성해서 운영
- 노드 서버에 실행되는 컴포넌트
- kubelet
- kube-proxy
- docker
- 실제 사용하는 컨테이너 대부분은 노드에서 실행
마스터와 노드의 구성과 통신
- 쿠버네티스의 모든 통신은 kube-apiserver가 중심
- kube-apiserver를 거처 다른 컴포넌트가 서로 필요한 정보를 주고 받는다.
- etcd에는 kube-apiserver만 접근 가능
- 마스터 서버의 kubelet이 마스터에 있는 도커를 관리
- 도커 안에는 쿠버네티스 관리용 컴포넌트가 있다.
- kube-scheduler
- kube-controller-manager
- kube-apiserver
- kube-proxy
- 관리용 컴포넌트는 모두 하이버큐브라는 바이너리 파일로 컴파일되었고 실행할 때 옵션을 설정해 각 컴포넌트의 역할을 수행
- etcd는 컨테이너가 아니라 별도의 프로세스로 설정되어 있다.
- 도커 안에는 쿠버네티스 관리용 컴포넌트가 있다.
- 노드 역시 kubelet으로 도커를 관리
- kubelet은 마스터의 kube-apiserver와 통신하면서 파드의 생성, 관리, 삭제를 담당
- 노드의 kube-proxy는 마스터와는 다르게 컨테이너가 아니라 서버 프로세스로 실행할 수 있다.
쿠버네티스의 주요 컴포넌트
- 쿠버네티스의 컴포넌트는 세 가지로 구분한다.
- 마스터용 컴포넌트
- 노드용 컴포넌트
- 애드온용 컴포넌트
마스터용 컴포넌트
- etcd
- 코어 OS에서 개발한 고가용썽을 제공하는 key-value 저장소
- 쿠버네티스에서는 필요한 모든 데이터를 저장하는 데이터베이스 역할
- 서버 하나당 프로세스 1개만 사용할 수 있다.
- 보통 etcd 자체를 클러스터링한 후 여러 개 마스터 서버에 분산해서 실행해 데이터의 안전성을 보장하도록 구성
- kube-apiserver
- 쿠버네티스 클러스터의 API를 사용할 수 있도록 하는 컴포넌트
- 클러스터로 온 요청이 유효한지 검증
- 쿠버네티스에 보내는 모든 요청은 kube-apiserver를 이용해서 다른 컴포넌트로 전달
- kube-scheduler
- 현재 클러스터 안에서 자원 할당이 가능한 노드 중 알맞은 노드를 선택해서 새롭게 만든 파드를 실행
- kube-controller-manager
- 쿠버네티스는 파드들을 관리하는 컨트롤러가 있는데, 이 컨트롤러 각각을 실행하는 컴포넌트이다.
노드용 컴포넌트
- kubelet
- 클러스터 안 모든 노드에서 실행되는 에이전트
- 파드 컨테이너들의 실행을 직접 관리
- PodSpecs라는 조건이 담긴 설정을 전달받아서 컨테이너를 실행하고 컨테이너가 정상적으로 실행되는지 헬스 체크를 진행
- 노드 안에 있는 컨테이너라도 쿠버네티스가 만들지 않은 컨테이너 관리하지 않는다.
- kube-proxy
- 쿠버네티스는 클러스터 안에 별도의 가상 네트워크를 설정하고 관리
- kube-proxy는 이런 가상 네트워크의 동작을 관리하는 컴포넌트이다.
쿠버네티스 오브젝트와 컨트롤러
- 쿠버네티스는 크게 오브젝트와 오브젝트를 관리하는 컨트롤러로 나눈다.
- 사용자는 템플릿 등으로 쿠버네티스에 자원의
desired state
를 정의하고 컨트롤러는 바라는 상태와 현재 상태가 일치하도록 오브젝트들을 생성/삭제한다. - 오브젝트에는
pod
,service
,volume
,namespace
등이 있다. - 컨트롤러에는
ReplicaSet
,Deployment
,StatefulSet
,DaemonSet
,Job
이 있다.
네임 스페이스
- 쿠버네티스 클러스터 하나를 여러 개 논리적인 단위로 나눠서 사용하는 것
- 네임스페이스별로 별도의 쿼터를 설정해서 특정 네임스페이스의 사용량을 제한할 수 있다.
- 네임스페이스 확인 :
kubectl get namespaces
- 기본 네임스페이스
- default : 기본 네임스페이스
- kube-system : 쿠버네티스 시스템에서 관리하는 네임스페이스
- kube-public : 클러스터 안 모든 사용자가 읽을 수 있는 네임스페이스
- kube-node-lease : 각 노드의 임대 오브젝트들을 관리하는 네임스페이스
- pod, namespace 확인
kubectl get pods --all-namespaces
템플릿
- 쿠버네티스 클러스터의 오브젝트나 컨트롤러가 어떤 상태여야 하는지를 적용할 때는 YAML 형식의 템플릿을 사용
- 기본 형식
- apiVersion : 사용하려는 쿠버네티스 API 버전을 명시
kubectl api-versions
으로 현재 클러스터에서 사용 가능한 API 버전을 확인할 수 있다.
- kind : 어떤 종류의 오브젝트 혹은 컨트롤러에 작업인지 명시
- metadata : 메타데이터를 설정
- spec : 파드가 어떤 컨테이너를 갖고 실행하며, 실행할 때 어떻게 동작해야 할지 명시
- apiVersion : 사용하려는 쿠버네티스 API 버전을 명시
- 어떤 필드가 있는지 확인하기 위해
kubectl explain
으로 확인할 수 있다.-
kubectl explain pods
-
kubectl explain pods.metadata
-
kubectl explain pods --recursive
--- apiversion: v1 kind: Pod metadata: spec:
-
파드
파드 개념
- 쿠버네티스는 실제로 파드라는 단위로 컨테이너를 묶어서 관리하므로 보통 컨테이너 하나가 아닌 여러 개 컨테이너로 구성된다.
- 파드 하나 안에 있는 컨테이너들이 IP 하나를 공유한다.
파드 사용하기
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-simple-pod # 파드의 이름을 설정
labels:
app: kubernetes-simple-pod # 오브젝트를 식별하는 레이블을 설정, 파드가 앱 컨테이너고, kubernetes-simple-pod라고 식별한다고 설정
spec:
containers:
- name: kubernetes-simple-pod # 컨테이너의 이름을 설정
image: arisu1000/simple-container-app:latest # 컨테이너에서 사용할 이미지를 설정
ports:
- containerPort: 8080 # 해당 컨테이너에 접속할 포트 번호를 설정
- pod 실팽
kubectl apply -f pod-sample.yaml
- pod 확인
kubectl get pods
파드 생명 주기
- Pending
- 쿠버네티스 시스템에 파드를 생성하는 중
- 컨테이너 이미지를 다운로드한 후 전체 컨테이너를 실행하는 도중
- Running
- 파드 안 모든 컨테이너가 실행 중인 상태
- 1개 이상의 컨테이너가 실행 중이거나 시작 또는 재시작 상태일 수 있다.
- Succeeded
- 파드 안 모든 컨테이너가 정상 실행 종료된 상태로 재시작되지 않는다.
- Failed
- 파드 안 모든 컨테이너 중 정상적으로 실행 종료되지 않은 컨테이너가 있는 상태
- 컨테이너 종료 코드가 0이 아니면 비정상 종료이거나 시스템이 직접 컨테이너를 종료한 상태
- Unknown
- 파드의 상태를 확인할 수 없는 상태
- 파드 생명주기 확인
kubectl describe pods [Pod Name]
실행 후Status
항목에서 확인- Status의 Type 정보
- Initialized : 모든 초기화 컨테이너가 성공적으로 시작 완료
- Ready : 파드는 요청들을 실행할 수 있고 연결된 모든 서비스의 로드밸런싱 풀에 추가되어야 한다는 뜻
- ContainersReady : 파드 안 모든 컨테이너가 준비 상태
- PodScheduled : 파드가 하나의 노드로 스케줄을 완료했다는 뜻
- Unschedualbe : 스케줄러가 자원의 부족이나 다른 제약 등으로 지금 당장 파드를 스케줄 할 수 없다는 뜻
kubelt으로 컨테이너 진단하기
- 컨테이너가 실행된 후에는 kubelet가 컨테이너를 주기적으로 진단한다.
- libenessProbe
- 컨테이너가 실행됐는지 확인한다.
- 이 진단이 실패하면 KUBelet은 컨테이너를 종료시키고, 재시작 정책에 따라서 컨테이너를 재시작한다.
- 컨테이너에 libenessProbe를 어떻게 할지 명시되지 않았다면 기본 상태 값은
Success
이다.
- readinessProbe
- 컨테이너가 실행된 후 실제로 서비스 요청에 응답할 수 있는지 진단
- 이 진단이 실패하면 엔드포인트 컨트롤러는 해당 파드에 연결된 모든 서비스를 대상으로 엔드포인트 정보를 제거한다.
- 첫 번째 readinessProbe를 하기 전까지의 기본 상태 값은 Failure이다.
- readinessProbe를 지원하지 않는 컨테이너라면 기본 상태 값은
Success
이다.
- readinessProbe를 지원하는 컨테이너라면 컨테이너가 실행된 다음 바로 서비스에 투입되어서 트래픽을 받지 않는다.
- 실제 트래픽을 받을 준비가 되었음을 확인한 후 트래픽을 받을 수 있다.
- 컨테이너 진단은 컨테이너가 구현한 핸들러를 kubelet이 호출해서 실행한다.
- ExecAction : 컨테이너 안에 지정된 명령을 실행하고 종료 코드가 0일때 Success라고 진단한다.
- TCPSocketAction : 컨테이너 안에 지정된 IP와 포트로 TCP 상태를 확인하고 포트가 열려있으면 Success라고 진단한다.
- HTTPGetAction : 컨테이너 안에 지정된 IP, 포트, 경로로 HTTP GET 요청을 보낸다.
- 응답 상태 코드가 200에서 400 사이면 Success라고 진단
- 컨테이너 진단 결과
- Success : 컨테이너 진단 성공
- Failure : 컨테이너 진단 실패
- Unknown : 진단 자체가 실패해서 컨테이너 상태를 알 수 없음
초기화 컨테이너
- 앱 컨테이너가 실행되기 전 파드를 초기화 한다.
- 보안상 이유로 앱 컨테이너 이미지와 같이 두면 안되는 앱의 소스 코드를 별도로 관리할 때 유용
- 초기화 컨테이너는 여러개를 구성할 수 있고, 파드 템플릿에 명시한 순서대로 초기화 컨테이너가 실행된다
- 초기화 컨테이너 실행이 실패하면 성공할 때까지 재시작한다.
- 초기화 컨테이너가 모두 실행된 후 앱 컨테이너 실행이 시작된다.
- 초기화 컨테이너는 readinessProbe를 지원하지 않는다.
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-simple-pod
labels:
app: kubernetes-simple-pod
spec:
initContainers:
- name: init-myservice # 초기화 컨테이너의 이름 설정
image: arisu1000/simple-container-app:latest
command: ['sh', '-c', 'sleep 2; echo helloworld01;']
- name: init-mydb
image: arisu1000/simple-container-app:latest
command: ['sh', '-c', 'sleep 2; echo helloworld02;']
containers:
- name: kubernetes-simple-pod
image: arisu1000/simple-container-app:latest
command: ['sh', '-c', 'echo The app is running! sleep 3600']
파드의 인프라 컨테이너
- 쿠버네티스에서는 모든 파드에서 항상 실행되는
pause
라는 컨테이너가 있다. pause
를 파드 인프라 컨테이너라고 한다.pause
는 파드 안 기본 네트워크로 실행되며, 프로세스 식별자가 1로 설정되므로 다른 컨테이너의 부모 컨테이너 역할을 한다.- 파드 안 다른 컨테이너는 pause 컨테이너가 제공하는 네트워크를 공유해서 사용한다.
- 파드 안 다른 컨테이너가 재시적됐을 때는 파드의 IP를 유지하지만, pause 컨테이너가 재시작되면 파드 안 모든 컨테이너도 재시작한다.
파드에 CPU와 메모리 자원 할당
- 파드에는 CPU와 메모리를 대상으로 자원 사용량을 설정할 수 있는
.limits
와.requests
필드가 있다. - 메모리는 바이트 단위로 측정된다.
- 별도로 용량을 나타내는 기호를 사용하지 않ㄴ흔다면 기본 단위는 바이트
- CPU는 CPU 코어 하나의 연산 능력을 기준으로 설정
- 1을 설정했다면 코어 하나의 연산 능력을 온전히 사용할 수 있도록 설정
- 0.1로 설정했다면 CPU 코어 하나의 연산량의 10% 만큼 연산 능력을 할당
- 자원을 최대로 얼마까지 상요할 수 있는지 제한
.spec.containers[].resources.limits.cpu
.spec.containers[].resources.limits.memory
- 최소 자원 요구량을 표시
.spec.containers[].resources.requests.cpu
.spec.containers[].resources.requests.memory
- 요구하는 만큼의 여유 자원이 있는 노드가 없다면 파드는 PENding 상태로 실행되지 않는다. (클러스터 안에 자원 여유가 생길 때까지 대기)
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-simple-pod # 파드의 이름을 설정
labels:
app: kubernetes-simple-pod # 오브젝트를 식별하는 레이블을 설정, 파드가 앱 컨테이너고, kubernetes-simple-pod라고 식별한다고 설정
spec:
containers:
- name: kubernetes-simple-pod # 컨테이너의 이름을 설정
image: arisu1000/simple-container-app:latest # 컨테이너에서 사용할 이미지를 설정
resources:
requests:
cpu: 0.1
memory: 200M
limits:
cpu: 0.5
memory: 1G
ports:
- containerPort: 8080 # 해당 컨테이너에 접속할 포트 번호를 설정
파드에 환경 변수 설정
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-simple-pod # 파드의 이름을 설정
labels:
app: kubernetes-simple-pod # 오브젝트를 식별하는 레이블을 설정, 파드가 앱 컨테이너고, kubernetes-simple-pod라고 식별한다고 설정
spec:
containers:
- name: kubernetes-simple-pod # 컨테이너의 이름을 설정
image: arisu1000/simple-container-app:latest # 컨테이너에서 사용할 이미지를 설정
ports:
- containerPort: 8080 # 해당 컨테이너에 접속할 포트 번호를 설정
env:
- name: TESTENV01 # 사용할 환경 변수의 이름을 설정
value: "testvalue01" # 문자열이나 숫자 형식의 값을 설정
- name: HOSTNAME
valueFrom: # 값을 직접 할당하는 것이 아니라 어딘가 다른 곳에서 참조하는 값을 설정
fieldRef: # 파드의 현재 설정 내용을 값으로 설정
fieldPath: spec.nodeName # .fieldRef에서 어디서 값을 가져올 것인지를 지정. 값을 참조하려는 항목의 위치를 지정
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: CPU_REQUEST
valueFrom:
resourceFieldRef: # 컨테이너에 CPU, 메모리 사용량을 얼마나 할당했는지에 관한 정보를 가져온다.
containerName: kubernetes-simple-pod # 환경 변수 설정을 가져올 컨테이너 이름 설정
resource: requests.cpu # 어떤 자원의 정보를 가져올지 설정
- name: CPU_LILMIT
valueFrom:
resourceFieldRef:
containerName: kubernetes-simple-pod
resource: limits.cpu
파드 구성 패턴
- 사이드카 패턴
- 원래 사용하려던 기본 컨테이너의 기능을 확장하거나 강화하는 용도의 컨테이너를 추가
- 기본 컨테이너는 원래 목적의 기능에만 충실하도록 구성하고, 나머지 공통 부가 기능들은 사이드가 컨테이너를 추가해서 사용
- 앰배서드 패턴
- 파드 안에서 프록시 역할을 하는 컨테이너를 추가하는 패턴
- 파드 안에서 외부 서버에 접근할 때 내부 프록시에 접근하도록 설정하고 실제 외부와의 연결은 프록시에서 알아서 처리한다.
- 파드의 트래픽을 더 세밀하게 제어할 수 있다.
- 어댑터 패턴
- 파드 외부로 노출되는 정보를 표준화하는 어댑터 컨테이너를 사용한다는 뜻
- 어댑터 컨테이너로 파드의 모니터링 지표를표준화한 형식으로 노출시키고, 외부의 모니터링 시스템에서 해당 데이터를주기적으로 가져가서 모니털이하는데 이용
컨트롤러
컨트롤러
- 파드들을 관리한느 역할
- 오랜 시간동안 계속 실행되어야 하는 파드들을 관리할 때
- 레플리케이션 컨트롤러, 레플리카세트, 디플로이먼트를 사용
- 클러트서의 전체 노드에 같은 파드를 실행할 때
- 데몬 세트
- 상태가 있는 앱을 실행할 때 사용할 때
- 스테이트풀세트
- 1회성 작업을 할 때 사용하는 잡, 주기적인 배치 작업을 실행할 때 사용할 때
- 크론잡
레플리케이션 컨트롤러
- 지정한 숫자만큼의 파드가 항상 클러스터 안에서 실행되도록 관리
- 요즘은 비슷한 역할을 하는 레플리카세트를 사용하는 추세
- 앱의 배포에는 디플로이먼트를 주로 사용
레플리카세트
- 지정한 숫자만큼의 파드가 항상 클러스터 안에서 실행되도록 관리
- set-based의 selector를 지원하는 차이점이 있다.
- equal, in, notin, exists 연산자 지원
- rolling-update를 사용할 수 없어서 필요할 때는 디플로이먼트를 사용해야 한다.
- 레플리카세트와 파드의 정보를 한꺼번에 조회
kubectl get replicaset,pods
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
spec:
template: # 레플리카세트가 어떤파드를 실행할지에 관한 정보를 설정
metadata:
name: nginx-replicaset # 파드 이름으로 nginx-replicaset 설정
labels:
app: nginx-replicaset # 오브젝트를 식별하는 레이블이 앱 컨테이너이고 nginx-replicaset라고 식별한다고 설정
spec:
containers:
- name: nginx-replicaset
image: nginx
ports:
- containerPort: 80
replicas: 3 # 파드를 몇 개 유지할지 개수를 설정 (기본 값은 1)
selector: # 어떤 레이블(.labels)의 파드를 선택해서 관리할지를 설정 (.spec.template.metadata.labels의 하위 필드 설정과 .spec.selector.matchLabels의 하위 필드 설정이 같아야 한다.),
matchLabels: # 템플릿에 별도의 .spec.selector 설정이 없으면 .spec.template.metadata.labels.app에 있는 내용을 기본 값으로 설정한다.
app: nginx-replicaset
디플로이먼트
- 쿠버네티스에서 상태가 없는 앱을 배포할 때 사용하는 가장 기본적인 컨트롤러
- 레플리카세트를 관리하면서 앱 배포를 더 세밀하게 관리
- 파드 개수 유지, 롤링 업데이트, 앱 배포 도중 잠시 멈췄다가 다시 배포할 수 있다.
- 디플로이먼트 실행 여부 확인
kubectl get deploy,rs,rc,pods
- rs : 레플리카세트
- rc : 레플리케이션 컨트롤러
- 배포 중 디플로이먼트 상태 체크
kubectl rollout status
- 진행(Progressing) 상태
- 디플로이먼트가 새로운 레플리카세트를 만들 때
- 디플로이먼트가 새로운 레플리카세트의 파드 개수를 늘릴 때
- 디플로이먼트가 예전 레플리카세트의 파드 개수를 줄일 때
- 새로운 파드가 준비 상태가 되거나 이용 가능한 상태가 되었을 때
- 완료(Complete) 상태
- 배포가 이상없이 끝남
- 종료 코드가 0으로 표시
- 디플로이먼트가 관리하는 모든 레플리카세트가 업데이트 완료되었을 때
- 모든 레플리카세트가 사용 가능해졌을 때
- 예전 레플리카세트가 모두 종료되었을 때
- 실패(Fail) 상태
- 쿼터 부족
- readinessProbe 진단 실패
- 컨테이너 이미지 가져오기 에러
- 권한 부족
- 제한 범위 초과
- 앱 실행 조건을 잘못 지정
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
replicas: 3 # 파드를 몇 개 실행할 것인지 실정
selector:
matchLabels:
app: nginx-deployment # .spec.selector.matchLabels의 하위 필드는 .metadata.labels의 하위 필드와 같은 설정을 해야 한다.
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
서비스
서비스
- 여러 개 파드에 접근할 수 있는 IP 하나를 제공
- 본질적으로 로드밸런서 역할
서비스의 개념
- 동저긍로 변하는 파드들에 고정적으로 접근할 때 사용하는 방법이 쿠버네티스의 서비스이다.
- 서비스는 주로 L4 영역에서 통신할 때 사용하고 인그레스는 L7 영역에서 통신할 때 사용한다는 차이점이 있다.
서비스 타입
- ClusterIP
- 기본 서비스 타입이며 쿠버네티스 클러스터 안에서만 사용 가능
- 클러스터 안 노드나 파드에서는 클러스터 IP를 이용해서 서비스에 연결된 파드에 접근
- 클러스터 외부에서는 이용할 수 없다.
- NodePort
- 서비스 하나에 모든 노드의 지정된 포트를 할당
- 노드에 상관없이 서비스에 지정된 포트 번호만 사용하면 파드에 접근할 수 있다.
- 노드의 포트를 사용하므로 클러스터 안 뿐만 아니라 클러스터 외부에서도 접근할 수 있다.
- 클러스터 외부에서 클러스터 안 파드로 접근할 때 사용할 수 있는 가장 간단한 방법
- LoadBalancer
- 클라우드에서 제공하는 로드밸런서와 파드를 연결한 후 해당 로드밸런서의 IP를 이용해 클러스터 외부에서 파드에 접근할 수 있도록 해준다.
kubectl get service
명령으로 서비스상태를 확인하면EXTERNAKL-IP
항목에 로드밸런서 IP를 표시한다.
- ExternalName
- 서비스를 .spec.externalName 필드에 설정한 값과 연결한다.
- 클러스터 안에서 외부에 접근할 때 주로 사용
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP # 서비스 타입을 설정 (기본 값은 ClusterIP)
clusterIP: 10.0.10.10 # 클러스터 IP를 직접 설정. 설정하지 않으면 자동으로 IP 값이 할당
selecttor: # 서비스와 연결할 파드에 설정한 .labels 필드 값을 설정
app: MyApp
ports: # 서비스에서 한꺼번에 포트 여러 개를 외부에 제공할 때는 .spec.ports[] 하위에 필드 값을 설정
- protocol: TCP
port: 80
targetPort: 9376
kubectl get svc
명령으로 서비스가 만들어졌는지 확인- 좀더 자세한 정보를 보려면
kubectl describe service [서비스이름]
명령을 실행- Name : 서비스의 이름
- Namespace : 서비스가 어떤 네임스페이스에 속했는지 표시
- Selector : 레이블이
app={label}
인 파드를 선택하라고 설정 - Endpoints : 실제로 서비스에 연결된 파드들의 IP가 표시
- 현재 실행 중인 파드 들의 IP 조회
kubectl get pods -o wide
레이블과 애너테이션
- 레이블과 애너테이션은 쿠버네티스에서 자원들의 메타데이터를 관리하는 데 사용
- 레이블은 셀렉터와 함께 특정 레이블이 있는 자원들을 선택할 때 주로 사용
- 애너테이션은 주석 성격의 메타데이터를 기록하는 데 사용
- 레이블은 쿠버네티스 클러스터 안에서 사용자가 오브젝트를 구분하는 용도
- 사용자가 임의로 원하는 값을 지정해서 사용
- 애너테이션은 쿠버네티스 시스템에서 필요한 정보들을 표시하는 데 사용
레이블
- key-value 쌍으로 구성
- 사용자가 클러스터 안에 오브젝트를 만들 때 메타데이터로 설정
- 레이블의 키는 쿠버네티스 안에서 컨트롤러들이 파드를 관리할 때 자신이 관리해야할 파드를 구분하는 역할
- 레이블 key, value 네이밍 규칙
- 63 글자를 넘지 않아야 함
- 시작과 끝 문자는 알파벳 대소문자 및 숫자([a-z0-9A-Z])여야함
- 중간에는 -, _, ., 숫자 등이 올 수 있음
- 레이블의 key 이름 앞에는 /로 구분해서 접두어를 사용할 수도 있다.
레이블 셀렉터
- 특정 레이블을 선택할 때 사용
- 등호 기반(equality-based)
environment=develop
release=stable
- 집합 기반(set-based)
- 여러 개 값을 조건으로 설정한 다음 해당 키가 있는 레이블 값이 조건에 속하는지 아닌지 확인, 존재하는지의 조건도 설정 가능
environment in (dev, stage)
release notin (lastest, canary)
gpu
!gpu
컨피그 맵
- 컨테이너에 필요한 환경 설정을 컨테이너와 분리해서 제공하는 기능
apiVersion: v1
kind: ConfigMap
metadata:
name: config-dev
namespace: default
data: # .data의 하위 필드로 실제 사용하려는 환경 설정값을 넣는다.
DB_URL: localhost
DB_USER: myuser
DB_PASS: mypass
LOG_LEVEL: debug
kubectl describe configmap [컨피그맵이름]
명령으로 설정 내용이 제대로 들어갔는지 확인 가능
컨피그맵 설정 중 일부만 사용
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
replicas: 3 # 파드를 몇 개 실행할 것인지 실정
selector:
matchLabels:
app: nginx-deployment # .spec.selector.matchLabels의 하위 필드는 .metadata.labels의 하위 필드와 같은 설정을 해야 한다.
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
env:
- name: LOG_LEVEL # 환경 변수 값 설정
valueFrom:
configMapKeyRef: # 어떤 컨피그맵의 어떤 키를 가져올 것인지를 지정
name: config-dev
key: LOG_LEVEL
컨피그맵 설정 전체 사용
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
replicas: 3 # 파드를 몇 개 실행할 것인지 실정
selector:
matchLabels:
app: nginx-deployment # .spec.selector.matchLabels의 하위 필드는 .metadata.labels의 하위 필드와 같은 설정을 해야 한다.
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
envFrom: # 환경 변수를 어디에서 가져올 것인지를 설정
- configMapRef: # 어떤 컨피그맵을 참조해서 환경 변수들을 불러올 것인지를 설정
name: config-dev
컨피그맵을 볼륨에 불러와서 사용
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
replicas: 3 # 파드를 몇 개 실행할 것인지 실정
selector:
matchLabels:
app: nginx-deployment # .spec.selector.matchLabels의 하위 필드는 .metadata.labels의 하위 필드와 같은 설정을 해야 한다.
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
volumeMounts: # config-volume라는 볼륨을 생성해서 config-dev 컨피그맵의 .data 하위 필드 4개를 컨테이너의 /etc/config 디렉터리에 필드 이름 형태의 파일로 저장
- name: config-volume
mountPath: /etc/config
volumes: # config-volume 볼륨을 사용하는 컨피그맵 config-dev를 설정
- name: config-volume
configMap:
name: config-dev
시크릿
- 비밀번호와 같은 민감한 정보들을 저장하는 용도
- 컨테이너 안에 저장하지 않고 별도로 보관했다가 실제 파드를 실행할 때의 템플릿으로 컨테이너에 제공
시크릿 만들기
- 내장 시크릿과 사용자 정의 시크릿이 있다.
- 내장 시크릿
- 쿠버네티스 클러스터 안에서 쿠버네티스 API에 접근할 때 사용
- 사용자 정의 시크릿
- 사용자가 직접 만든 시크릿
템플릿으로 시크릿 만들기
apiVersion: v1
kind: Secret
metadata:
name: user-pass-yaml
type: Opaque # 시크릿 타입 설정
data:
username: username # base64 문자 인코딩 값을 설정해야 한다. echo n 명령으로 만들 수 있다.
password: password
시크릿의 타입
- Opaque
- 기본 값
- key-value 형식으로 임의의 데이터를 설정 가능
- kubernetes.io/service-account-token
- 쿠버네티스 인증 토큰을 저장함
- kubernetes.io/dockerconfigjson
- 도커 저장소 인증 정보를 저장함
- kubernetes.io/tls
- TLS 인증서를 저장함
파드의 환경 변수로 시크릿 사용하기
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
replicas: 3 # 파드를 몇 개 실행할 것인지 실정
selector:
matchLabels:
app: nginx-deployment # .spec.selector.matchLabels의 하위 필드는 .metadata.labels의 하위 필드와 같은 설정을 해야 한다.
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
env:
- name: SECRET_USERNAME # 환경 변수 값 설정
valueFrom:
secretKeyRef: # 어떤 시크릿의 어떤 키를 가져올 것인지를 지정
name: user-pass-yaml # 시크릿 이름 설정
key: username
- name: SECRET_PASSWORD # 환경 변수 값 설정
valueFrom:
secretKeyRef:
name: user-pass-yaml
key: password
볼륨 형식으로 파드에 시크릿 제공하기
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
replicas: 3 # 파드를 몇 개 실행할 것인지 실정
selector:
matchLabels:
app: nginx-deployment # .spec.selector.matchLabels의 하위 필드는 .metadata.labels의 하위 필드와 같은 설정을 해야 한다.
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
volumeMounts: # volume-secret라는 볼륨을 생성해서 volume-secret 시크릿의 .data 하위 필드를 컨테이너의 /etc/volume-secret 디렉터리에 필드 이름 형태의 파일로 저장
- name: volume-secret
mountPath: "/etc/volume-secret"
readOnly: true # 볼륨을 읽기 전용으로 사용
volumes:
- name: volume-secret
secret:
secretName: user-pass-yaml # 시크릿 설정
로깅
파드 로그 확인하기
kubectl logs -f [파드이름]
- 실행 중인 로그를 지속해서 수집하는 TAILING을 실행
헬름
헬름 소개
- 헬름은 템플릿 파일들의 집합(차트)을 관리하는 쿠버네티스 패키지 매니저 도구
- 헬름은 차트와 차트 압축 파일을 만들 수 있다.
- 차트가 저장된 차트 저장소와 연결해 쿠버네티스 클러스터에 차트를 설치하거나 삭제할 수 있다.
주요 개념
- 차트(chart) : 쿠버네티스에서 실행할 애플리케이션을 만드는 데 필요한 정보 묶음
- 컨피그(config) : 패키지한 차트에 넣어서 배포 가능한 오브젝트를 만들 때 사용할 수 있는 설정이 있다.
- 릴리즈(release) : 특정 컨피그를 이용해 실행 중인 차트의 인스턴스
헬름 차트의 구조
mysql
- charts/ # 이 차트와 관련 있는 차트들을 포함한 디렉토리
- templates/ # 쿠버네티스 메니페스트 파일들로 변환될 템플릿을 포함한 디렉터리
- Chart.yaml # 차트 정보 파일
- values.yaml # 이 차트에서 사용하는 기본 설정