![[Kubernetes] Kubernetes 구성요소 완벽 정리: Pod, Service, 그리고 Controller](/static/c74a253a7fb9d36e6b982b7d688691ba/f6053/component.png)
오브젝트입니다.기본적인 구성단위가 되는 기본 오브젝트(Basic object) 를 생성하고 관리하는 추가적인 기능을 가진 컨트롤러(Controller)와 이러한 오브젝트의 스펙(설정)이외에 추가정 보인 메타 정보들로 구성이 된다고 보면 됩니다. yaml이나 json 파일로 스펙을 정의할 수 있습니다. 가장 기본적인 배포 단위로, 컨테이너를 포함하는 단위입니다. k8s의 특징중의 하나는 컨테이너를 하나씩 배포하는 것이 아니라 Pod 라는 단위로 배포하는데, Pod는 하나 이상의 컨테이너를 포함합니다.apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 8090
apiVersion : 이 스크립트를 실행하기 위한 Kubernetes API 버전 (보통 v1을 사용)kind : 리소스의 종류를 정의, (Pod)metadata : 리소스의 각종 메타 데이타 정의 라벨이나 리소스의 이름 등 각종 메타데이타를 넣습니다. spec : 리소스에 대한 상세한 스펙을 정의합니다.nginx 도커 이미지 nginx:1.7.9 를 사용 컨테이너 포트 8090을 오픈합니다.왜 POD 안에 한개 이상의 컨테이너를 가지는데, 개별적으로 하나씩 컨테 이너를 배포하지 않고 여러개의 컨테이너를 Pod 단위로 묶어서 배포할까?
Pod 내의 컨테이너는 IP와 Port를 공유합니다. 두 개의 컨테이너가 하나의 Pod를 통해서 배포되었을때 localhost를 통해서 통신이 가능합니다.A가 8080, 컨테이너 B가 7001로 배포가 되었을 때 B -> A를 호출 할 때 localhost:8080 으로 호출하면 되고 A -> B를 호출 할 때는 localhost:7001로 호출이 가능합니다. Pod 내에 배포된 컨테이너간에는 디스크 볼륨을 공유할 수 있습니다. 요즘 APP은 실행할때 APP만 올라가는것이 아니라 Reverse proxy, 로그 수집기등 다양한 주변 솔루션이 같이 배포 됩니다. APP(Tomcat, node.js)와 로그 수집기를 다른 컨테이너로 배포하면 일반적인 경우 컨테이너에 의해서 파일 시스템이 분리되기 때문에 로그 수집기가 APP 컨테이너의 로그파일을 읽는 것이 불가능합니다. 하지만 k8s는 하나의 Pod 내에서 컨테이너들끼리 볼륨을 공유할 수 있기 때문에 다른 컨테이너의 파일을 읽어올 수 있습니다.Pod와 볼륨을 이용하여, 컨테이너들을 정의하고, Pod를 서비스로 제공할 때 분산환경에서는 하나의 Pod로 서비스 하는 경우는 드물고 여러 Pod를 로드밸런서를 이용해서 하나의 IP와 포트로 묶어 서비스를 제공합니다.
Pod의 경우에는 동적으로 생성 되고, 장애가 생기면 자동으로 재시작 되며 IP가 바뀌기 때문에 로드밸런서에서 Pod의 목록을 지정할 때는 IP주소를 이용하는 것은 어렵다. 또 오토 스케일링으로 인하여 Pod 가 동적으로 추가 또는 삭제되기 때문에 이렇게 추가/삭제된 Pod 목록을 로드밸런서가 유연하게 선택해 줘야 합니다.
라벨(label)과 라벨 셀렉터(label selector) 라는 개념입니다.라벨 셀렉터(label selector) : 어떤 Pod를 서비스로 묶을 것인지 정의하면 각 Pod를 생성할때 메타데이타 정보 부분에 라벨을 정의할 수 있습니다. 결과적으로 서비스는 라벨 셀렉터에서 특정 라벨을 가지고 있는 Pod만 선택하여 서비스에 묶게 됩니다.
“myapp”인 서비스만 분류해 서비스에 넣는다. 분류된 Pod 간 로드밸런싱을 통하여 외부로 서비스를 제공합니다.kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 9376
kind : Service로 지정apiVersion : v1으로 정의metadate-name : my-service (서비스의 이름)spec : 서비스에 대한 스펙을 정의selector : 라벨 = app:myapp인 Pod 만을 선택해서 분류portsprotocol : TCPport : 80 포트로 서비스
targetPort : 80 포트 요청을 컨테이너의 9376 포트로 연결해 제공합니다 논리적인 분리 단위라고 보면 됩니다.
Pod,Service 등은 NameSpace 별로 생성이나 관리가 되고 사용자의 권한 역시 NameSpace 별로 나눠서 부여할 수 있습니다.개발/운영/테스트 환경이 있으면 클러스터를 개발/운영/테스트 3개의 NameSpace로 나눠 운영이 가능합니다.
네임스페이스 동작논리적인 분리 단위일뿐 물리적이나 장치를 통해서 환경을 분리(Isolation)한 것이 아니다.
리소스를 선택하는데 사용이 됩니다. 각 리소스는 라벨을 가질 수 있고 라벨 검색 조건에 따라서 특정 라벨을 가지고 있는 리소스만을 선택할 수 있습니다. 라벨을 선택하여 특정 리소스만 배포, 업데이트 할 수 있고 또는 라벨로 선택된 리소스만 Service에 연결하거나 특정 라벨로 선택된 리소스에만 네트워크 접근 권한을 부여하는 등이 가능합니다. 라벨은 metadata 섹션에 키/값 쌍으로 정의가 가능하며 하나의 리소스에는 하나의 라벨이 아니라 여러 라벨을 동시에 적용할 수 있습니다."metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
셀렉터를 사용하려면 오브젝트 스펙에서 selector 라고 정의하고 라벨 조건을 적어 놓으면 됩니다. Equaility based selector와 Set based selector 입니다.Equality based selector : 같냐, 다르냐와 같은 조건을 이용하여, 리소스를 선택하는 방법environment = dev tier != frontend
set based selector : Equality based 보다 향상된 셀렉터로 집합의 개념을 사용합니다.
- environment in (production,qa) 는 environment가 production 또는 qa 인 경우
- tier notin (frontend,backend)는 frontend도 아니고 backend도 아닌 리소스를 선택. 아래 nasa-service 라는 이름의 서비스를 정의했습니다.
셀렉터에서 app: myapp 정의해서 Pod의 라벨 app이 myapp 것만 골라 이 서비스에 바인딩해서 9376 포트로 서비스 합니다.
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Replication Controller : Pod를 관리해주는 역할, 지정된 숫자로 Pod를 기동, 관리하는 역할을 합니다.Replication Controller (RC)는 크게 3가지 파트로 구성되는데 아래와 같습니다.


블루/그린 배포
롤링 업데이트 방식
DaemonSet하나씩만 배포 됩니다. 이런 형태의 워크로드는 서버의 모니터링이나 로그 수집 용도로 많이 사용되는데 DS의 다른 특징중 하나는, 특정 Node들에만 Pod가 하나씩만 배포 되도록 설정이 가능합니다.

“node selector”를 이용해서 특정 노드만을 선택할 수 있게 지원합니다. 
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] <<<----#####
restartPolicy: Never
backoffLimit: 4
하지만 만약 Job이 끝나기 전에 비정상적으로 종료된다면 어떻게 될것인가?
- 장애시 다시 시작하게 하거나
- 장애시 다시 시작하지 않게 할 수 있습니다.
completion에 횟수 를 주면, 같은 작업을 completion 횟수만큼 순차적으로 반복합니다.
parallelism 에 동시 실행할 수 있는 Pod의 수를 주면 지정된 수 만큼 Pod를 실행하여 completion 횟수를 병렬로 처리합니다.
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
“schedule”이라는 항목이 있고 반복 조건을 unix cron과 같이 설정하면 됩니다.