2020. 10. 15. 12:33ㆍDevOps/Kubernetes
쿠버네티스 설치가 끝났으면 드디어 사용해 볼 차례이다.
하지만
Kubernetes 난이도 어마어마하다. (필자는 비전공자라 더 그렇게 느끼지만 다행인건 도커의 깔고 들어가기때문에 비슷한게 많다.)
필자의 경우 그냥 인강만 주구장창 봐왔다. 그저 무식하게 실습만 했다는 것이다.
그렇게 보면서 느낀게 그져 끝없는 책만 읽을뿐 머리에 들어오지 않다는 것이다. (그래서 블로그 적으면서 정리하고 있다.)
그래도 못할건 없다. 차근차근 정리해가면서 익숙해지다보면 언젠가는 깨닫고 CKA도 따고 전문가의 길로 들어서게 될것이다.
이번 포스트는 앞에서 가볍게 얘기는 했지만 그래도 이번 기회에 큰그림부터 정리하려고 한다.
1. Kubernetes Architecture
2. Kubernetes Object
3. kubernetes Manifest
1. Kubernetes architecture
이 부분은 쿠버네티스 이해 편에서 언급한 적이 있다. 하지만 너무 중요해서 조금 더 자세하게 언급을 하려고 한다.
일단 위 그림은 보자 저게 무엇일까? 영어로 나왔듯이 쿠버네티스 클러스터를 나타내는 그림이다.
클러스터란 여러 대의 컴퓨터들이 연결 되어 하나의 시스템처럼 동작하는 컴퓨터들의 집합이다라는 정의를 가지고 있다.
이건 도커 스웜도 그렇고 쿠버네티스 클러스터도 마찬가지로 위 쿠버네티스 클러스터 내에 하나의 마스터pc 한대와
주변의 노드pc(=워커pc) 3대로 이루워져 있는 pc의 집합인 것이다. 온프레미스에선 직접 선을 연결시켜줘서 클러스터 구축하는데 비해
쿠버네티스 클러스터는 어떻게 여러 pc 상호간의 통신이나 명령을 내릴까? 아래 그림을 보자
결론 부터 말하면 마스터pc에는 컨트롤 플레인을, 노드pc에는 데이터 플레인(위 그림에서는 컴퓨터 머신이라 표기)을 즉 쿠버네티스 클러스터와 상호작용하려면 노드pc에 있는 명령줄 도구인 kubelet을 자세히 검토해야된다.
각각의 기능 설명은 [시작하세요 도커/쿠버네티스] 저자 블로그 arisu1000.tistory.com/27828 잘 설명되어있으니 참고바란다.
그렇다면 Kubelet은 어떤 녀석이길래 왜 주목을 해야되나 일단 kubelet의 역할은 다음과 같다.
- API 서버에서 파드 시크릿 다운로드
- 볼륨 마운트
- 컨테이너 런타임 인터페이스(CRI)로 파드 컨테이너 실행
- 노드와 각 파드의 상태 보고
- 컨테이너 라이프사이클 검사
kubelet은 쿠버네티스 에이전트다. API 서버와 통신하고 노드에서 파드(아래에서 자세히 설명)를 실행하고 관리하는 일을 담당하는 것이다.
사실 쿠버네티스의 이론 내용들을 처음보면 진짜 이해 안간다. 그나마 도커 스웜 구축이나 도커 컴포즈 짜봤으면 어느정도 되지만 그래도 어렵다. 그래서 준비한 비유가 있다.
[ex] 필자가 연대장이다. 1대대(쿠버네티스 클러스터) 대대장(API서버)한테 대대훈련브리핑(Yaml[매니페스트])해주고 실행하라 명령하달하였다면 대대장은 중대장(kubelet)에게 지시하여 중대장은 각 소대장(컨테이너 런타임)들에게 명령을 하달한다. 그러면 소대장은 또 분대장(pod)과 사병(컨테이너들)들은 훈련브리핑대로 훈련하게 될것이다.
참고로 kube-proxy는 본부중대 통신병이다. etcd는 보급관, 스케줄러는 작전과장, 컨트롤러 매니저는 행보관이라 보면 되겟다. 비유보고 위에 기능설명 보면 아~ 할것이다.
2. Kubernetes Object
위에(쿠버네티스 클러스터)도 중요하지만 여기가 젤 중요하다. 앞에서 얘기했듯이 훈련브리핑얘기를 했었다. 괄호안에 Yaml 매니페스트를 통해 보낸다고 했는데 이 yaml파일을 api서버로 보낼때 kubectl 명령어로 보낸는 것이다.
(yaml 매니페스트는 3번째 파트에서 조금더 자세히 설명함)
1
|
kubectl create -f nginx-pod.yaml
|
cs |
위 명령어를 보면 kubectl 명령어를 통해 nginx-pod라는 매니패스트 양식을 생성한다. 이 nginx-pod.yaml 안에는 이미지가 적혀져있는데 도커허브에서 끌어땡겨온다고 볼 수 있다.
이런식으로 kubectl 명령어를 통해 api 서버로 보냄으로써 클러스터 내에 컨테이너들을 오케스트레이션을 할 수 있다는 것이다.
사실 명령어 종류가 굉장히 많다.
여기서 다 설명(나중에 집중적으로 얘기한다.)은 못하고 원리 정도 파악할 수 있게 기본적인 것들만(자주 쓰이는 명령어) 소개 하겟다.
더 자세하게 알고 싶으면 아래 사이트를 (구문은 무조건 보고 오자)참고하자
kubernetes.io/ko/docs/reference/kubectl/overview/
kubectl 개요
Kubectl은 쿠버네티스 클러스터를 제어하기 위한 커맨드 라인 도구이다. 구성을 위해, kubectl 은 config 파일을 $HOME/.kube 에서 찾는다. KUBECONFIG 환경 변수를 설정하거나 --kubeconfig 플래그를 설정하여 ��
kubernetes.io
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
[Basic] #***********
kubectl --help # 사실 이게 젤 중요하다 명령어를 모두 외울수 없다. 그렇기에 중간중간 잘 써먹자
kubectl get pod/node # 일단 get이란 옵션은 리소스를 보여준다 또 다른 옵션으로 -w, -o wide 등 많으니 알아두자
kubectl create -f [FILENAME] # 두가지 생성 방법이 있다. 첫번째는 Yaml작성하고 그바탕으로 생성하거나 아니면 기본 이미지를 그냥 불러오는 것이다.
kubectl create deployment IMAGENAMETAG --image IMAGENAME --record=true
# 이런식으로 불러오면 된다. 뒤에 필자가 붙이 옵션 레코드 트루는 나중에 디플로이먼트 파트에서 설명은 할꺼지만
# 일단 중요해서 기입은 해놓았다. 나중에 롤링업테이트를 배울껀데 버전관리를 위해 꼭 기입되어야한다.
kubectl apply -f [FILENAME] # 파일이나 표준입력(stdin)으로부터 리소스에 구성 변경 사항을 적용한다.
# 쿠버네티스에서 리소스 변경할 방법이 방대하다. 몃가지 중요한건 꼭 기억하자.
---
[controller]
kubectl delete all --all # 학습하면서 젤 많이 쓰이는 것중 하나다 현재 명령은 모든 것으 삭제한다.(all 부분에 pod, deploy, svc 등 부분삭제)
kubectl run # 클러스터에서 지정된 이미지를 실행한다.
kubectl expose ~ --port --type LoadBalencer # 레플리케이션 컨트롤러, 서비스 또는 파드를 새로운 쿠버네티스 서비스로 노출한다. ***** 겁나 중요
# 특히 포트나 타입 지정해줘야 함으로 필수적인
---
[deploy command] # 배포파트인데 많이 쓰이고 중요하니 의미와 명령어들 미리 봐두는 것도 좋다.
kubectl rollout # 리소스의 롤아웃을 관리한다. 유효한 리소스 타입에는 디플로이먼트(deployment), 데몬셋(daemonset)과 스테이트풀셋(statefulset)이 포함된다.
kubectl scale # 지정된 레플리케이션 컨트롤러의 크기를 업데이트한다.
kubectl label # 하나 이상의 리소스 레이블을 추가하거나 업데이트한다.
---
[troubleshooting]
kubectl edit #기본 편집기를 사용하여 서버에서 하나 이상의 리소스 정의를 편집하고 업데이트한다.(** 중요하다)
kubectl describe #하나 이상의 리소스의 자세한 상태를 표시한다.(이벤트 나열하기 때문에 엄청 자주 쓰이니 꼭 기억하자.)
kubectl exec # 오브젝트 안의 컨테이너에 대해 명령을 실행
|
cs |
즉 명령어 모르면 help를 써가면서 보고 일단 yaml파일 작성하여 create로 만든다. 만든것을 get으로 확인하고 expose로 외부에 노출시킨다. 그리고 문제가 있을 시에 describe를 확인하여 apply나 edit로 업데이트 및 수정 한다.
명령어 종류와 흐름을 어느정도 알아봤으니 그렇다면 그 안에 생성하는 오브젝트는 뭐냐;
쿠버네티스를 이해하기 위해서 가장 중요한 부분이다. 그리고 가장 기본적인 구성단위가 되는 기본 오브젝트와 기본 오브젝트를 관리하는 컨트롤러로 이루어진다.
리스트로 나열하자면 이렇다.
- 기본 오브젝트
- POD
- Volume
- Service
- Namespace
- Label / Selector
- 컨트롤러
- ReplicaSet
- DaemonSet
- Job
- StatefulSet
- Deployment
쿠버네티스에 의해서 배포 및 관리되는 가장 기본적인 오브젝트는 컨테이너화되어 배포되는 애플리케이션의 워크로드를 기술하는 오브젝트이다.
Pod는 컨테이너화된 애플리케이션(가장 기본적인 배포 단위 - 하나 이상의 컨테이너 포함),
Volume는 디스크(클러스터 공부할 때 그림에서 오른쪽 사이드에 영구 저장소가 나오는데 그걸 가르킨다. 쿠버네티스의 볼륨은 pod내의 컨테이너 간 영구적으로 공유가 가능하다.),
Service는 로드밸런서(Pod를 서비스로 제공할 때 일반적인 분산환경에서는 하나의 pod로 서비스하는 경우는 드물고 여러개 pod를 서비스하면서 이를 로드밸런서를 이용해서 하나의 ip와 포트로 묶어서 서비스 제공),
Namespace는 패키지명(pod, service 등은 네임 스페이스 별로 생성, 관리 할수 있다. 즉 클러스터내의 논리적 분리단위이다),
Label/Selector는 오브젝트에 첨부된 키와 값의 쌍(쿠버네티스의 리소스 선택하는데 사용, 즉 라벨을 선택하여 특정 리소스만 배포하거나 업테이트할 수 있고 또는 라벨로 선택된 리소스만 Service에 연결하거나 네트워크 접근 권한을 부여하는 역할이다.) 정도로 생각하면 된다.
ReplicaSet 아래로는 컨트롤러라 한다. 컨트롤러는 애플리케이션을 설정하고 배포하는 것이 가능한데 이를 조금 더 편리하게관리하기 위해서 쿠버네티스는 컨트롤러라는 개념을 사용하고 있다. 즉 pod, Volume, Service 등 기본 오브젝트들을 생성하고 이를 관리하는 역할이라 보면 된다.
ReplicaSet은 pod를 관리해주는 역할을 하는데 지정된 숫자로 Pod를 기동 시키고, 관리하는 역할을 한다.(Set 기반의 selector이용)
Deployment는 레플리카셋의 좀더 상위 추상화 개념이다. 실제 운영에서는 레플리카셋을 바로 사용하는 것보다 좀더 추상화된 디플로이먼트를 사용한다. 조금더 짚어보겟다.
위 명령어중에 배포관련된 kubectl이 있다. rollout이 보일껀데 롤링업데이트를 관리하는 명령어다. 이게 뭐냐;
보통은 업데이트나 배포, 수정 과정에서 수동적으로 비정상적으로 끊어지고 예상치 못한 일들이 발생하는데
쿠버네티스에서는 이런 과정을 자동화하고 추상화하기위해 Deployment라는 개념을 만들었다. 즉 Pod 배포 위해 레플리카셋을 생성하고 관리하는 역할 하며 특히 롤백을 위한 기존 버전의 레플리카셋 등 여러가지 기능을 포괄적으로 포함하고 있다. ( 학습하다보면 굉장히 많이 쓰인다.)
Deamonset과 job은 고급 컨트롤러로 일반적인 워크로드 이외에 데이타베이스, 배치 작업, 데몬 서버와 같이 다양한 형태의 워크로드 모델이 존재하는데 이를 지우너하기 위해서 쿠버네티스느 다양한 컨트롤러를 제공함으로 pod의 운영을 다양한 시나리오에 맞게 지원하고 있다.
일단은 간단하게 설명하자면
Deamonset은 pod가 각각의 노드에서 하나씩만 돌게 하는 형태로 pod를 관리하는 컨트롤러이다. ( 레플리카셋에 의해서 관리하는 pod는 여러 노드의 상황에 따라서 일반적으로 비 균등하게 배포되지만, 데몬셋에 의해 관리 되는 pod은 모든 노드에 균등하게 하나씩 배포된다.)
job은 워크로드 모델중에서 배치나 한번 실행되고 끝나는 형태의 작업이 있을 수 있다. 이 때 job이 나서서 웹서버 처럼 계속 pod이 떠 있을 필요없이 작업 할 때만 pod을 띄우게 한다.
마지막으로 StatefulSet은 여태 오브젝트만 관리해온 컨트롤러들만 있었는데 유일한지 안한지 모르겟지만 필자 상식에서는 유일하게 데이타베이스와 같이 상태를 가지는 애플리케이션을 관리하는 컨트롤러이다. 그래서 데이타베이스등 과 같이 상태를 가지고 있는 pod을 지원하기 위해서 스테이트풀셋을 써야된다. 단 디스크 볼륨에 대해 필요하다.
3. kubernetes Manifest
사실 필자의 경우 이 부분이 젤 어려운 부분 이었다. 도커 컴포즈에서 맛본 Yaml파일, 그러나 쿠버네티스에서 메니페스트 형식은 많이 생소해 보였다. Json도 쓸 수 있다. 하지만 Yaml를 많이 쓰는 이유는 구성 파일에 대해 더 사용자 친화적이므로 사용한다.
하지만 들여쓰기를 굉장히 조심히 써야된다. 필자가 써본바로는 무조건 두칸 띄어야된다. 조금만 안맞아도 읽지를 못하더라;;(주의 꼭 하자!)
위 그림을 보면 매니페스트를 통해 배포자가 쿠버네티스로 적용시켜 쿠버네티스 안에서 앱을 실행시키는 원리를 담고있다.
그렇다면 매니페스트가 뭐냐;
사전적 의미로는 컴퓨팅에서 집합의 일부 또는 논리정연한 단위인 파일들의 그룹을 위한 메타데이터를 포함하는 파일이다.
즉 쿠버네티스에서는 오브젝트의 특성(설정정보)을 기술한 오브젝트 스펙(Object Spec)으로 정의가 되고 커맨드 라인을 통해서 오브젝트 생성시 인자로 전달하여 정의한다. 아래 코드를 보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
apiVersion: apps/v1
# 스크립트를 실행하기 위한 쿠버네티스 API버전이다. 보통 v1을 사용하고 alpha/beta 등 사용
kind: Deployment
# 리소스의 종류를 정의하는데 오브젝트를 기술한다.
metadata: #리소스의 각종 메타데이터를 넣는다. 라벨이나 리소스의 이름 등 각종 메타데이타 기입
name: my-nginx
# 여기서는 디플로이먼트 컨트롤러의 my-nginx라는 이름이다.(논리적 구분을 위해 label등 기입한다.)
spec: # 어쩌면 실질적인 메타데이터이다 리소스에 대한 상세한 스펙을 정의한다.
selector: #선택자인데 deployment 컨트롤러는 엄밀히 오브젝트가 아니기 때문에 오브젝트에 대한 label을 매치시켜줘야된다.
matchLabels:
run: my-nginx # 현재줄이랑 다음 메타데이터 레이블 보면 똑같은 이름이 보인다. 즉 매핑을 위해 똑같이 써줘야된다.
replicas: 2
# 나중에 설명해줄 것인데 레플리카셋 복제를 한다. 여기서는 2개를 복제할 것이다 명시해놓았다. (롤링업데이트를 돌아가면서 업데이트함 다운될일 없음)
template:
metadata:
labels:
run: my-nginx
spec:
containers: # 여기서 도커허브에 등록된 이미지를 땡겨온다.
- name: my-nginx
image: nginx
ports:
- containerPort: 80
# 포트는 필수
--- # 구분선이다. 1개 이상일 때 파트마다 꼭 써주자 // 구분선 기준으로 위에는 설명을 위해 띄워쓰기 한 것이고 실제로는 아래처럼 쓰자.
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
|
cs |
4. 정리
kubernetes에 대해서 간단하게 정리를 해보았는데 여기서 너무 세세하게 알면 더 헷갈리수 있다. 그래서 큰그림만 살펴보고 나중에 하나하나 세세하게 학습하면 된다. 특히 매니페스트 같은 경우 양식에 대해서 너무 신경쓰지는 말자 나중에 세세하게 또 다루게 될 것이다. 단 들여쓰기, 주석, 구분선은 꼭 기억해야된다.
어느정도 kubernetes의 원리나 구조를 알아보았다. 하지만 네트워크에 대해서 꼭 알아야되니 다음 파트에서 쿠버네티스 네트워크에 대해서 포스트 올리겠다.
내용이 틀리거나 피드백있을 시에 댓글 부탁용.
'DevOps > Kubernetes' 카테고리의 다른 글
Kubernetes 설치 2# (0) | 2020.10.10 |
---|---|
Kubernetes의 이해 1# (0) | 2020.10.10 |