과거 용어
원래 Control Plane은 Master라고 불렸고, Node들은 Minion이라고 불렸대.
그러다가 Minion -> Worker Node -> Node.
문서에 따라서 다르게 쓰더라도 같은 용어임!
그래서 실제 운영 환경에서는 Multi Control Plane 구성/ 3대 정도로 권장하고 있대.
[Control Plane]
- kube-apiserver
- Kubernetes Cluster의 API 요청을 처리하는 컴포넌트 (얘가 모든걸 다처리해주는건 아님. 컨테이너를 모니터링. 직접 제어는 하지 않음. 다른 구성요소에게 전달해서 대신 처리하게끔 함.)
- 클러스터로 전달된 요청이 유효한 요청인지 검증하는 역할을 수행 (kubectl 할 때 config안에 key 넣어줬듯이. 내가 kubectl 설치한다고 아무 쿠버 클러스터를 제어할 수 있는게 아냐. 쿠버 클러스터에 접근할 수 있는 권한을 가져야만 제어할 수 있는거야. 그 검증을 kube-apiserver가 해주는거구.)
ex. 쿠버네티스 클러스터의 네임스페이스와 리소스에 대한 권한이 맞는지 확인한대...? 먼솔? ㅋㅋ
- etcd (엣씨디 라구 한대. et cetra d?? etc daemon의 약자인가?? ㅋㅋㅋ)
- Kubernetes Cluster의 정보를 관리하는 중앙 데이터베이스
- Key-Value 쌍으로 데이터를 저장함
쿠버네티스 클러스터에 어떤 리소스가 생기면, 그 리소스에 대한 정보를 api server가 etcd에 저장을 해서 항상 최신의 정보를 반영함. 만약 쿠버네티스 클러스터에 장애가 생기면, etcd에 저장된 내용을 바탕으로 복구함. 근데 우리는 다루지는 않는대. ㅜ 예를 들어, control plane에 문제가 생기면, etcd에 저장된걸루 복구한다구.
- kube-scheduler
- Kubernetes Cluister 내에서 자원 할당이 가능한 노드 중 적절한 노드로 파드를 생성하도록 배치하는 역할을 수행하는 컴포넌트 (상대적으로 한가한 노드로 pod을 배치)
- kube-controller-manager (Controller Manager)
- Controller를 관리하기 위한 컴포넌트
- cloud-controller-manager (원래는 쿠버 구성 요소에 포함 안되어있었는데, 이제 포함됨. 이게 ccm임)
- Kubernetes Cluster와 클라우드 서비스를 연동하는 컴포넌트
클라우드 컨트롤러 (Control Plane) 안에 있는 4가지의 구성요소
- Node Controller
- 클라우드 서비스 내에서 노드 관리
- Route Controller
- 클라우드 서비스 내에서 네트워크 라우팅 관리
- Service Controller
- 클라우드 서비스에서 제공하는 로드밸런서를 관리
- Volume Controller
- 클라우드 서비스에서 생성한 볼륨을 노드에 연결하는 등의 볼륨 연동 관리
+ 기본적으로 Control Plane도 Node라서 kubelet과 kube-proxy 존재함
[Node]
- kubelet
- Kubernetes Cluster 내의 모든 노드에서 실행되는 에이전트
- 파드 및 컨테이너 실행 등을 직접 관리
- Pod Spec에 따라 컨테이너를 실행하고 컨테이너가 정상 실행되는지 여부를 체크
- kube-proxy
- Kubernets Cluster의 네트워크 연결 관리하는 컴포넌트 (예를 들면, pod끼리 통신 관리)
- 호스트 레벨의 네트워크 규칙 관리 및 연결 전달 등의 역할을 수행
Add-on
- Networking Add-on
- CNI(Container Network Interface)
ex) calico
- DNS Add-on
- Kubernetes Cluster 내에서 동작하는 DNS 서버로 Cluster 내의 DNS 서비스를 제공하는 Add-on
- Kubernetes Cluster 내에서 동작하는 컨테이너는 자동으로 DNS에 등록됨
ex) CoreDNS
- Dashboard Add-on
웹 형태의 dashboard 제공해줌. 그런데... dashboard가 모니터링을 솔루션처럼 제공x
테스트 목적이라 사용 서비스 고려해서 만들어진게 아님.
가급적이면 사용 안하는 것이 좋다.
Object
- Kubernetes에서 관리하는 대상
- Pod, ReplicationController, Replicaset, Volume, Configmap, Secret 등
Manifest File
- Kubernetes 리소스에 대해 정의하는 파일
- 주로 YAML 언어로 작성됨
- apiVersion : Object가 사용하는 API Version (Object마다 사용할 수 있는 API version이 정해져있어)
- kind : Object 종류
- metadata : Object의 이름, 레이블 등을 지정
- spec : Object의 세부 내용 정의
질문)
어제 선언형 파일로 nginx 가동 시킨 것 말고 명령어로 pod 생성했을 때는 따로 api 구분이 없었는데 따로 기능이 없는 api 버전이 자동 적용된건가요?
-> 해당 리소스가 사용하는 api version이 자동으로 적용된 것입니다. 명령어일 때만 그렇고 manifest를 작성할 때는 반드시 작성해줘야 합니다.
kubectl SUBCOMMAND [OBJECT] [ARG]
Kubernetes Object 관리
1. 명령형 커멘드
- kubectl 명령어에 인수와 옵션을 사용해서 애플리케이션을 관리함
- 1회성 작업 수행에서 주로 사용됨
kubectl run test-pod --image test-pod-img
kubectl create replicaset test-rs --image test-rs-img:ver1.0
2. 명령형 오브젝트 구성
오브젝트를 Manifest File로 정의함
kubectl create -f MANIFEST
3. 선언형 오브젝트 구성
특정 디렉터리에 모든 오브젝트 파일을 배치하여 관리함
kubectl create -f DIR
-----
파드(Pod) (굳이 pod로 컨테이너를 감싼 이유가 뭘까?)
- 하나 이상의 컨테이너로 구성된 단위
- 파드 내의 컨테이너는 네트워크 및 저장소를 공유함
샘플 파드 실행
vim을 하기 전에...
yaml은 들여쓰기가 너무 중요해.
개꿀팁)
vim ~/.vimrc
syntax on
autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab autoindent
들여쓰기 자동으로 해준다.
모든 파일에 적용되는건 아니고 yaml 파일한테만 적용됨.
vim pod-sample.yaml
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-simple-pod
labels:
app: kubernetes-simple-pod
spec:
containers:
- name: kubernetes-simple-pid
image: arisu1000/simple-container-app:latest
ports:
- containerPort: 8080 (책에 다 있음. 127쪽 ㅋㅋ)
kubectl create -f pod-sample.yaml (f는 manifest 파일 정해주기 위한 옵션)
파드 목록 확인
kubectl get pods
파드에 대한 자세한 정보 확인
kubectl describe pod POD_NAME
파드의 생명주기 및 상태
- Pending
- 파드가 생성이 되는 과정
- Running
- 파드 내의 모든 컨테이너가 성공적으로 실행 중인 상태
- 1개 이상의 컨테이너가 실행중이거나 시작 또는 재시작 상태일 수도 있음
- Succeeded (먼가 이게 정상 종료된걸 뜻하니까 이상하네)
- 파드가 성공적으로 종료가 된 상태로 파드 내의 컨테이너가 모두 정상 종료된 상태
(= Pod 내에 있는 모든 컨테이너가 정상 종료 된 상태)
- Failed
- 파드 내의 컨테이너 중 정상 종료 되지 않은 컨테이너가 있는 상태
- Unknown
- 파드 상태를 확인할 수 없는 상태
Conditions
Initialized : 모든 초기화 컨테이너가 성공적으로 시작 완료됨
Ready : 파드가 준비된 상태
ContainersReady : 파드 내의 모든 컨테이너가 준비된 상태
PodScheduled : 파드가 노드에 스케쥴링됨
UnSchedulable : 노드에 파드가 스케쥴링 될 수 없는 상태
레이블
Kubernetes 오브젝트에 대한 부가적인 정보를 표시할 때 사용하는 것
(리소스가 어떤 리소스다 라고 이름을 붙이는거임. 용도 구분. 이 Pod는 Public Web Pod or Internal-Mail-Pod 이렇게
Dev-Pod, Prod-Pod 이렇게 ㅋㅋ)
Pod 뿐만 아니라, 여러 리소스에 일케 이름을 붙이는거임. (속성 값을 하나 붙이는거임)
Q) 리소스가 오브젝트보다 더 큰 개념이겠쥐???
파드의 목록에 레이블 표시
kubectl get pods --show-labels
yaml 새로 만들어봤어 아래는 일케 수정하고
파드의 목록에 레이블을 필드로 지정하여 확인
kubectl get pods -L LABEL_KEY
파드에 레이블 지정 및 수정
kubectl label pods POD_NAME LABEL_KEY=LABEL_VALUE
(새롭게 추가하는건 되는데, 수정은 안되던데.... )
아 이거 --overwrite위치가 되게 절묘하네. 이 곳에 해야만 덮어씌우기가 됨 ㅋㅋㅋ
레이블 셀렉터
- Kubernetes 오브젝트에 지정된 레이블을 식별하고 검색할 수 있도록 하는 연산자
레이블 검색 방법
- 특정 키가 있는/없는 대상
- 특정 키와 값이 있는/없는 대상
레이블 셀렉터 검색 방법
- 일치성 기준 검색
- =
- ==
- !=
- 집합성 기준 검색
- in
- notin
레이블 조건 지정 검색
kubectl get pods --show-labels -l LABEL_EXPRESSION
레이블 키 지정 검색
kubectl get pods --show-labels -l 'LABEL_KEY'
지정한 레이블 키를 제외한 검색
kubectl get pods --show-labels -l '!LABEL_KEY'
레이블 키와 값을 지정한 검색
kubectl get pods --show-labels -l 'LABEL_KEY=LABEL_VALUE'
레이블 키에 지정한 값이 아닌 레이블 검색
kubectl get pods --show-labels -l 'LABEL_KEY!=LABEL_VALUE'
레이블 키에 특정 값이 포함되는 레이블 검색
kubectl get pods --show-labels -l 'LABEL_KEY in (LABEL_VALUE)'
레이블 키에 특정 값이 포함되는 레이블 검색
kubectl get pods --show-labels -l 'env in (LABEL_VALUE1,LABEL_VALUE2)'
어노테이션(Annotations)
- Kubernetes에 비식별 메타데이터를 기록하는 것 (주석같은 개념인데, annotation은 속성 값이라, 이 값에 따라 오브젝트가 만들어지는데 영향을 미칠 수 있다.) ex. time stamp, 디버깅 정보, 프로젝트 책임자, 등등 적어두는 용도.
- Label과 같이 Kubernetes 오브젝트를 식별하는 용도로 사용되지 않으나 리소스에 대한 부가적인 정보를 기록하는데 사용됨
파드에 어노테이션 지정
kubectl annotate OBJECT OBJECT_NAME ANNOTATION_KEY=VALUE
kubectl annotate pod kubernetes-simple-pod pod-owner="Hong Gildong"
즉, label은 컨테이너들을 한번에 손쉽게 검색해서 관리/운영하기 위한 목적이고
annotation은 "속성으로 저장되는" 주석의 목적. 혹은 태그의 목적인듯.
네임스페이스
- Kubernetes Cluster를 논리적으로 나누는 구획
여러 조직이 쿠버네티스를 한 번에 사용할 때 사용
개발 부서, 쇼핑몰 부서, 경영 부서, ...
ㄴ 만약에 하나의 클러스터 내에서 pod들이 다 섞이면?
ㄴ 실수로 개발자가 쇼핑몰 pod를 내려버리면? 서비스가 중지되겠지.
하나의 클러스터를 독립된 여러 클러스터 사용하는 것처럼 해주는 것
질문)
서로 다른 클러스터를 사용하는거랑 네임스페이스를
-> 하드웨어 리소스는 공유하면서 쿠버네티스 오브젝트/리소스는 격리해주는 개념 이용하는거랑 어떤 장단점?
예컨대, 리소스를 조금 먹는걸 위해 두 클러스터 만드는건 낭비기도 함.
장점 : 나눠서 사용하면? 관리의 문제가 줄어든다. 쿠버네티스 클러스터 하나로 운영해도 된다.
단점 : 지금 머리아파서 못적음
pod 몇 개 안쓰면 namespace 나눠서 하는게 효율적일 수 있고
많이 쓰면 아예 클러스터 여러 개 운영하는게 나을 수도 있음.
네임스페이스 설명
- default
- 기본 네임스페이스로 별도의 네임스페이스 미지정시 기본으로 사용됨
- kube-system
- Kubernetes Cluster의 핵심 리소스가 위치하는 네임스페이스
- kube-public
- 모든 사용자가 읽기 권한으로 접근 가능한 네임스페이스
- kube-node-lease
- Kubernetes Cluster Nodes의 가용성 점검을 위한 네임스페이스
네임스페이스 목록 확인
kubectl get namespaces
기본 네임스페이스에 있는 오브젝트 확인(Namespace 생략)
kubectl get pods
특정 네임스페이스 지정하여 오브젝트 확인
kubectl get pods -n NAMESPACE
kubectl get pods -n default 하면 default를 바라보는거윔. ㅎ
Kubernetes Cluster의 모든 네임스페이스의 오브젝트 확인
kubectl get pods --all-namespaces
kubectl get pods -A
네임스페이스 생성
방법1. kubectl create 명령어로 생성
kubectl create namespace NAMESPACE
방법2. Manifest File로 생성
vim ns-test2.yaml
---------
apiVersion: v1
kind: Namespace
metadata:
name: test2
---------
kubectl create -f ns-test2.yaml
kubectl get namespaces
그냥 kubectl get pods하면 안보여. 왜? 이건 default namespace에 있는 pods을 보여주기 때문에.
그래서 -n test1을 뒤에 붙여서 namespace를 지정해줘야돼.
리소스 삭제
kubectl delete OBJECT OBJECT_NAME
네임스페이스 삭제
kubectl delete namespace NAMESPACE
참고)
리소스들은 기본적으로 네임스페이스 안에 속하게 됨.
ex) pod, replicaset
그래서 namespace를 지우면 그 안에 있는 리소스들이 다 지워지게 됨
근데
namespace 안에 있는 리소스를 지우고, namespace를 지우는게 순서상으로 맞아.
파드 삭제
kubectl delete pod PODNAME
kubelet으로 컨테이너 진단
Probe 종류 (probe = 조사/정찰)
- livenessProbe
- 컨테이너가 실행되었는지 확인하는 프로브
- readinessProbe
- 컨테이너가 실행된 후 애플리케이션이 실제 서비스를 제공할 수 있는지 여부를 확인하는 프로브
- 진단에 실패하는 경우 네트워크 엔드포인트에서 파드의 IP 주소를 제거함
ㄴ 예를 들어서, 로드밸런서 밑에 pod 3개를 물렸다구 하자. 그럴 때 그 중 한 개가 정상작동 안하는데 그대로 연결되어 있으면 정상적인 서비스를 제공 못하잖아. 그 때는 빼줘야지. readinessProbe가 이걸 감지하고 있다가, 정상 작동 안하는건 배제를 하는거야.
- startupProbe
- 컨테이너가 실행된 후 애플리케이션이 시작되었는지 확인하는 프로브
- startupProbe가 사용되는 경우 startupProbe가 성공하기 전까지 다른 프로브를 활성화하지 않음.
Probe Handler(Probe 방법)
- ExecAction
- 컨테이너 내의 실행파일이 정상적으로 실행되면 Success로 진단함
- TCPSocketAction
- 컨테이너로 TCP 통신이 정상적으로 되면 Success로 진단함
- HTTPGetAction
- HTTP Status Code가 200 ~ 400 범위이면 Success로 진단함
Probe 상태
- Success
- Failure
- Unknown
초기화 컨테이너 (init container)
- 파드에서 메인 컨테이너가 실행되기 전에 실행되어 파드 초기화 작업을 수행하는 컨테이너
- initContainers 하위에 초기화 컨테이너가 정의됨
의문)
이거 왜 쓰는거임? 전혀 이유를 모르겠음.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
-> 두 init 컨테이너가 켜져야만, 앱이 켜지는거야. (근데 myservice랑 mydb 합친게 앱 아냐? myapp-container는 모임?)
'System Engineering > Kubernetes' 카테고리의 다른 글
kubernetes 5/17 (0) | 2022.03.26 |
---|---|
kubernetes 4/17 (0) | 2022.03.25 |
kubernetes 2/17 (0) | 2022.03.24 |
yaml 파일 작성법 참고 (0) | 2022.03.24 |
kubernetes 1/17 (docker 6/6과 같은 날 강의) (0) | 2022.03.23 |
최근댓글