1. 마스터노드와 워커노드
마스터노드 - 쿠버네티스 노드를 제어하는 머신. 여기에서 모든 태스크 할당이 시작 됨
워커노드 - 할당된 태스크를 요청대로 수행하는 시스템. 쿠버네티스 마스터가 이러한 노드를 제어한다.
클러스터의 구조
- 클러스터 전체를 관리하는 컨트롤러로써 마스터가 존재하고, 컨테이너가 배포되는 머신(가상머신이나 물리적인 서버머신)인 노드가 존재한다.
2. 오브젝트
가장 기본적인 구성단위가 되는 기본 오프젝트(Basic object)와 이 기본 오브젝트를 생성하고 관리하는 추가적인 기능을 가진 컨트롤러(Controller)로 이루어진다. 그리고 이러한 오브젝트의 스펙(설정)이외에 추가정보인 메타 정보들로 구성이 된다고 보면 된다.
2-1. 오브젝트 스펙(Object Spec)
오브젝트들은 모두 오브젝트의 특성(설정 정보)을 기술한 오브젝트 스펙(Object Spec)으로 정의가되고, 커맨드 라인을 통해서 오브젝트 생성시 인자로 전달하여 정의를 하거나 또는 yaml이나 json파일로 스펙을 정의할 수 있다.
2-2. 기본 오브젝트(Basic Object)
쿠버네티스에 의해서 배포 및 관리되는 가장 기본적인 오브젝트는 컨테이너화되어 배포되는 애플리케이션의 워크로드를 기술하는 오브젝트로, Pod, Service, Volume, Namespace 4가지가 있다.
간단하게 보자면
- Pod - 컨테이너화된 어플리케이션
- Volume - 디스크
- Service - 로드밸런서
- Namespace - 패키지명
2-2-1. Pod
쿠버네티스에서 가장 기본적인 배포 단위로, 컨테이너를 포함하는 단위
쿠버네티스의 특징 중 하나는 컨테이너를 개별적으로 하나식 배포하는 것이 아니라 Pod 라는 단위로 배포하는데, Pod는 하나 이상의 컨테이너를 포함한다.
간단한 Pod를 정의한 오브젝트 스펙 예시
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 8090
- apiVersion은 이 스크립트를 실행하기 위한 쿠버네티스 API 버전.
- kind에는 리소스의 종류를 정의하는데, Pod를 정의하려고 하기 때문에 Pod를 넣는다
- metadata에는 이 리소스의 각종 메타데이타를 넣는데, 라벨(뒤에서 설명함)이나 리소스의 이름 등 각종 메타데이터를 넣는다.
- spec부분에 리소스에 대한 상세한 스펙을 정의
- Pod는 컨테이너를 가지고 있기 때문에, container를 정의. 이름은 nginx로 하고 도커이미지 nginx:1.7.9를 사용하고 컨테이너 포트 8090을 오픈한다.
Pod의 특징
Pod안에 한 개 이상의 컨테이너를 가지고 있을 수 있다고 했는데 왜 개별적으로 하나씩 컨테이너를 배포하지 않고 여러개의 컨테이너를 Pod 단위로 묶어서 배포하는 것인가?
- Pod내의 컨테이너는 IP와 Port를 공유한다.
- 두 개의 컨테이너가 하나의 Pod를 통해서 배포되었을 때, localhost를 통해서 통신이 가능하다.
- ex) 컨테이너 A가 8080, 컨테이너 B가 7001로 배포가 되었을 때, B에서 A를 호출할때는 localhost:8080으로, A에서 B를 호출할때는 localhost:7001로 호출하면 된다.
- Pod내에 배포된 컨테이너간에는 디스크 볼륨을 공유할 수 있다.
- 근래 애플리케이션들은 실행할 때 애플리케이션만 올라가는 것이 아니라 Reverse proxy, 로그 수집기 등 다양한 주변 솔루션이 같이 배포되는 경우가 많고, 특히 로그 수집기의 경우에는 애플리케이션 로그 파일을 읽어서 수집한다.
- 애플리케이션(Tomcat, node.js)과 로그 수집기를 다른 컨테이너로 배포할 경우, 일반적인 경우에는 컨테이너에 의해서 파일 시스템이 분리되기 때문에 로그 수집기가 애플리케이션이 배포된 컨테이너의 로그파일을 읽는 것이 불가능 하지만, 쿠버네티스의 경우 하나의 Pod 내에서는 컨테이너들끼리 볼륨을 공유할 수 있기 때문에 다른 컨테이너의 파일을 읽어올 수 있다.
2-2-2. Volumn
Pod가 기동할때 디폴트로 컨테이너마다 로컬 디스크를 생성해서 기동되는데, 이 로컬 디스크의 경우에는 영구적이지 못하다.
즉, 컨테이너가 리스타트 되거나 새로 배포될 때마다 로컬 디스크는 Pod설정에 따라서 새롭게 정의되서 배포되기 때문에 디스크에 기록된 내용이 유실된다.
데이터 베이스와 같이 영구적으로 파일을 저장해야 하는 경우에는 컨테이너 리스타트에 상관 없이 파일을 영속적으로 저장해야 하는데 이러한 형태의 스토리지를 볼륨이라 한다.
ex) 웹 서버를 배포하는 Pod가 있을 때, 웹 서비스를 서비스하는 Web server 컨테이너, 그리고 컨텐츠의 내용(/htdocs)를 업데이트하고 관리하는 Content mgmt 컨테이너, 그리고 로그 메세지를 관리하는 Logger라는 컨테이너가 있다고 하자.
- Web Server 컨테이너는 htdocs 디렉토리의 컨테이너를 서비스하고 /logs 디렉토리에 웹 엑세스 기록을 기록한다.
- Content 컨테이너는 htdocs 디렉토리의 컨텐트를 업데이트하고 관리한다.
- Logger 컨테이너는 logs 디렉토리의 로그를 수집한다.
이 경우 htdocs 컨텐츠 디렉토리는 WebServer와 Content 컨테이너가 공유해야 하고, logs디렉토리는 Web Server와 Logger 컨테이너가 공유해야 한다.
이러한 시나리오에서 볼륨을 사용할 수 있다.
2-2-3. Service
Pod와 볼륨을 이용하여 컨테이너들을 정의한 후에 Pod를 서비스로 제공할 때, 일반적인 분산환경에서는 하나의 Pod로 서비스하는 경우는 드물고, 여러개의 Pod를 서비스하면서, 이를 로드밸런서를 이용해 하나의 IP와 포트로 묶어서 서비스를 제공한다.
Pod의 경우 동적으로 생성이 되고 장애가 생기면 자동으로 리스타트 되면서 그 IP가 바뀌기 때문에 로드밸런서에서 Pod의 목록을 지정할 때 IP주소를 이용하는 것은 어렵다. 또한 오토 스케일링으로 인하여 Pod가 동적으로 추가 또는 삭제되기 때문에 이렇게 추가/삭제된 Pod목록을 로드 밸런서가 유연하게 선택해줘야 한다.
그래서 사용하는 것이 라벨(label)과 라벨 셀렉터(label selector)라는 개념
라벨과 라벨 셀렉터
- 라벨 셀렉터 : 서비스를 정의할 때 어떤 Pod를 서비스로 묶을 것인지 정의하는 것
- 라벨 검색 조건에 따라 특정 라벨을 가지고 있는 리소스만을 선택할 수 있다.
- 라벨은 metadata 섹션에 키/값 쌍으로 정의가 가능하며, 하나의 리소스에는 여러 라벨을 동시에 적용할 수 있다.
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
- 셀렉터는 오브젝트 스펙에서 selector 라고 정의하고 라벨 조건을 적어서 사용
- 쿠버네티스에서는 두 가지 셀렉터를 제공
- Equaility based selector
- 같냐 다르냐와 같은 조건을 이용하여 리소스를 선택
- ex) environment = dev , tier != frontend
- Set based selector
- 집합의 개념을 사용하여 리소스를 선택
- ex) environment in (production, qa) 는 environment가 production 또는 qa인 경우이고
- tier notin (frontend, backend) 는 environment가 frontend도 아니고 backend도 아닌 리소스를 선택
예시
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 9376
- 리소스의 종류 : Service, 메타데이터에 서비스 이름을 my-service로 지정
- spec부분에 서비스에 대한 스펙을 정의
- selector에서 라벨이 app: myapp인 Pod만을 선택해서 서비스에서 서비스를 제공하게 한다.
- 포트는 TCP를 이용하고 서비스는 80포트로 서비스를 하되, 서비스의 80 포트의 요청을 컨테이너의 9376 포트로 연결해서 서비스를 제공한다.
2-2-4. Name Space
한 쿠버네티스 클러스터내의 논리적인 분리단위
Pod, Service 등은 네임 스페이스 별로 생성이나 관리가 될 수 있고, 사용자의 권한 역시 이 네임 스페이스 별로 나눠서 부여할 수 있다.
즉, 하나의 클러스터 내에 개발 / 운영 / 테스트 환경이 있을 때 클러스터를 개발 / 운영 / 테스트 3개의 네임 스페이스로 나눠서 운영할 수 있다.
네임스페이스로 할 수 있는 것은
- 사용자별로 네임스페이스별 접근 권한을 다르게 운영할 수 있다.
- 네임스페이스별로 리소스의 쿼타(할당량)을 지정할 수 있다. 개발계 - cpu 100, 운영계 - cpu 400, gpu 100의 식으로 사용 가능한 리소스의 수를 지정할 수 있다.
- 네임 스페이스별로 리소스를 나눠서 관리할 수 있다. (Pod, Service 등)
주의 사항
- 네임 스페이스는 논리적인 분리 단위이지 물리적이나 기타 장치를 통해서 환경을 분리한 것이 아니다.
- 따라서 다른 네임 스페이스 간의 Pod라도 통신은 가능하다.
- 물론 네트워크 정책을 이용하여 네임 스페이스간의 통신을 막을 수 있지만 높은 수준의 분리 정책을 원하는 경우에는 쿠버네티스 클러스터 자체를 분리하는 것을 권장한다.
출처
https://bcho.tistory.com/1256