Kubernetes
쿠버네티스의 이해
v1.23
- Overview
- 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있고 확장 가능한 오픈소스 플랫폼이다.
- 선언적 구성과 자동화를 모두 용이하게 해준다.
- 크고 빠르게 성장하는 생태계를 가지고 았으며 k8s 서비스, 기술 지원 및 도구는 어디서나 쉽게 이용가능하다.
- 키잡이(helmsman) 나 파일럿을 뜻하는 그리스어에서 유래되었다.
쿠버네티스 아키텍처
Control Plane Components
- 클러스터에 관한 전반적인 결정(Ex. 스케줄링)을 수행하고 클러스터 이벤트를 감지하고 반응
- 클러스터내 어떠한 머신에서든지 동작 가능
- 간결성을 위해, 구성 스크립트는 보통 동일 머신 상에 모든 컨트롤 플레인 컴포넌트를 구동시키고, 사용자 컨테이너를 해당 머신 상에 동작 시키지 않음.
- Control Plane -> Master 노드
- kube-apiserver - Kubernetes 컨트롤 플레인의 프런트 엔드로서 여러 인스턴스를 실행하고 해당 인스턴스 간에 트래픽의 균형을 조정
- etcd - 모든 클러스터 데이터에 대한 Kubernetes의 백업 저장소로 사용되는 일관되고 가용성이 높은
key-value
저장소
- kube-scheduler - 새로 생성된 Pod(하나 이상의 컨테이너 그룹)를 감시하고 노드에 할당(; 실행할 노드를 선택)
- kube-controller-manager - 여러개의 컨트롤러를 관리
- 논리적으로 각 컨트롤러는 별도의 프로세스이지만 복잡성을 줄이기 위해 모두 단일 바이너리로 컴파일되고 단일 프로세스에서 실행
노드 컨트롤러
: 노드가 다운되었을 때 통지와 대응에 관한 책임
레플리케이션 컨트롤러
: 시스템의 모든 레플리케이션 컨트롤러 오브젝트에 대해 알맞은 수의 파드들을 유지시켜주는 책임
엔드포인트 컨트롤러
: 엔드포인트 오브젝트를 채운다. (서비스와 포드 간의 연결 제공)
서비스 어카운트 & 토큰 컨트롤러
: 새로운 네임스페이스에 대한 기본 계정과 API 접근 토큰을 생성
- cloud-controller-manager - 클라우드별 컨트롤 로직을 포함하는 쿠버네티스 컨트롤 플레인 컴포넌트이다. 클라우드 컨트롤러 매니저를 통해 클러스터를 클라우드 공급자의 API에 연결하고, 해당 클라우드 플랫폼과 상호 작용하는 컴포넌트와 클러스터와만 상호 작용하는 컴포넌트를 구분할 수 있게 해준다. (CSP가 제공)
노드 컨트롤러
: 노드가 응답을 멈춘 후 클라우드 상에서 삭제되었는지 판별하기 위해 클라우드 제공 사업자에게 확인하는 것
라우트 컨트롤러
: 기본 클라우드 인프라에 경로를 구성하는 것
서비스 컨트롤러
: 클라우드 제공 사업자 로드밸런서를 생성, 업데이트 그리고 삭제하는 것
Node Components
kubelet
- 클러스터의 각 노드에서 실행되는 에이전트(; API 요청 받아 처리)로서
Pods
에서 컨테이너가 확실하게 동작하도록 관리
- 각 파드 내부에는 컨테이너가 있으며, kubelet 은 일반적으로 도커를 통해 이러한 작업을 실행한다(이미지 가져오기, 컨테이너 시작 및 중지 요청 등).
- 파드 스펙(PodSpec)의 집합을 받아서 컨테이너가 해당 파드 스펙에 따라 컨테이너를 관리
- 파드 : 클러스터에서 실행중인 컨테이너 집합
- 컨테이너 : 가볍고 휴대성 높은 실행 가능한 이미지
kube-proxy
- 클러스터의 각 노드에서 실행되는 네트워크 프록시
- 내부 네트워크 세션이나 클러스터 바깥에서 파드로 네트워크 통신을 할 수 있도록 도움.
- 운영 체제에 가용한 패킷 필터링 계층이 있는 경우, 이를 사용한다. 그렇지 않으면, kube-proxy는 트래픽 자체를 포워드(forward)한다.
- 수정 필요: 호스트에서 네트워크 규칙을 유지하고 연결 포워딩을 수행하는 노드의 메인 네트워크. 또한 서비스의 모든 Pod 간의 부하 분산을 담당합니다.
container runtime
- 컨테이너 실행을 담당하는 소프트웨어
- 쿠버네티스는 Docker,
containerd
, CRI-O
와 같은 컨테이너 런타임 및 모든 Kubernetes CRI (컨테이너 런타임 인터페이스) 구현한 모든 소프트웨어
용어
네임스페이스
- Namespaces
- 단일 클러스터 내에서의 리소스 그룹 격리 메커니즘을 제공
- 리소스의 이름은 네임스페이스 내에서 유일해야 하며, 네임스페이스 간에서 유일할 필요는 없다.
- 여러 개의 팀이나, 프로젝트에 걸쳐 많은 사용자가 있는 환경에서 사용하도록 만들어짐. 사용자가 거의 없거나, 수 십명 정도 되는 경우에는 네임스페이스를 전혀 고려할 필요가 없고, 네임스페이스가 제공하는 기능이 필요할 때 사용 가능
- 네임스페이스별로 별도의 쿼터를 설정해서 특정 네임스페이스의 사용량을 제한 가능
파드
- 파드 : 쿠버네티스에서 배포할 수 있는 가장 작은 단위
- 한 개 이상의 컨테이너와 스토리지, 네트워크 속성을 가집니다.
- Pod에 속한 컨테이너는 스토리지와 네트워크를 공유하고 서로 localhost로 접근할 수 있습니다.
- 컨테이너를 하나만 사용하는 경우도 반드시 Pod로 감싸서 관리합니다.
서비스
- 서비스 : 네트워크와 관련된 리스소
- Pod을 외부 네트워크와 연결해주고 여러 개의 Pod를 바라보는 내부 로드밸런서를 생성할 때 사용
- 내부 DNS에 서비스 이름을 도메인으로 등록하기 떄문에 서비스 디스커버리 역할도 수행
쿠버네티스 오브젝트
쿠버네티스 오브젝트 이해하기
- 쿠버네티스 오브젝트 는 쿠버네티스 시스템에서 영속성을 가지는 오브젝트, 클러스터의 상태를 나타냄 (명세서)
- 어느 노드에서 어떤 컨테이너화된 애플리케이션이 동작중인지
- 이 애플리케이션이 이용할 수 있는 리소스
- 이 애플리케이션이 어떻게 재구동, 업그레이드, 내고장성과 같은 것에 동작해야 하는지에 대한 정책
- 생성이든, 수정이든, 또는 삭제든 쿠버네티스 오브젝트를 동작시키려면, 쿠버네티스 API를 이용(
kubectl
CLI 이용)
오브젝트 명세(spec)와 상태(status)
- 오브젝트의 구성을 결정해주는 두개의 중첩된 오브젝트 필드
- 오브젝트
spec
과 오브젝트 status
spec
을 가진 오브젝트는 오브젝트를 생성할 때 리소스에 원하는 특징(의도한 상태)에 대한 설명을 제공해서 설정
- status 는 쿠버네티스 시스템과 컴포넌트에 의해 제공되고 업데이트된 오브젝트의 현재 상태 를 설명
쿠버네티스 컨트롤 플레인은 모든 오브젝트의 실제 상태를 사용자가 의도한 상태와 일치시키기 위해 끊임없이 그리고 능동적으로 관리
오브젝트 기술하기
- 대부분의 경우 정보를 .yaml 파일로
kubectl
에 제공하며 kubectl은 API 요청이 이루어질 때, JSON 형식으로 정보를 변환시켜 준다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
- 적용은
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
- 출력
deployment.apps/nginx-deployment created
요구되는 필드
apiVersion
- 이 오브젝트를 생성하기 위해 사용하고 있는 쿠버네티스 API 버전이 어떤 것인지
kind
- 어떤 종류의 오브젝트를 생성하고자 하는지
metadata
- 이름 문자열, UID, 그리고 선택적인 네임스페이스를 포함하여 오브젝트를 유일하게 구분지어 줄 데이터
spec
- 오브젝트에 대해 어떤 상태를 의도하는지
오브젝트 spec에 대한 정확한 포맷은 모든 쿠버네티스 오브젝트마다 다르고, 그 오브젝트 특유의 중첩된 필드를 포함하기 때문에 쿠버네티스 API 레퍼런스를 참고하여 spec 포멧을 참고한다.
권장 레이블
권장 레이블
- 권장 레이블은 지원 도구 외에도 쿼리하는 방식으로 애플리케이션을 식별하게 한다.
- 메타데이터는 애플리케이션 의 개념을 중심으로 정리, 메타데이터들은 권장하는 레이블이다. 애플리케이션을 보다 쉽게 관리할 수 있지만 코어 도구에는 필요하지 않다.
키 | 설명 | 예시 | 타입 |
---|
app.kubernetes.io/name | 애플리케이션 이름 | mysql | 문자열 |
app.kubernetes.io/instance | 애플리케이션의 인스턴스를 식별하는 고유한 이름 | mysql-abcxzy | 문자열 |
app.kubernetes.io/version | 애플리케이션의 현재 버전 (예: a semantic version, revision hash 등.) | 5.7.21 | 문자열 |
app.kubernetes.io/component | 아키텍처 내 구성요소 | database | 문자열 |
app.kubernetes.io/part-of | 이 애플리케이션의 전체 이름 | wordpress | |
app.kubernetes.io/managed-by | 애플리케이션의 작동을 관리하는 데 사용되는 도구 | helm | 문자열 |
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app.kubernetes.io/name: mysql
app.kubernetes.io/instance: mysql-abcxzy
app.kubernetes.io/version: "5.7.21"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: wordpress
app.kubernetes.io/managed-by: helm
애플리케이션과 애플리케이션 인스턴스
- 애플리케이션의 이름과 애플리케이션 인스턴스 이름은 별도로 기록된다.
예를 들어 WordPress는 애플리케이션 이름으로 app.kubernetes.io/name 이라는 레이블에 wordpress 라는 값을 가지며, 애플리케이션 인스턴스 이름으로는 app.kubernetes.io/instance 라는 레이블에 wordpress-abcxzy 라는 값을 가진다. 이를 통해 애플리케이션과 애플리케이션 인스턴스를 식별할 수 있다. 모든 애플리케이션 인스턴스는 고유한 이름을 가져야 한다.
서비스
서비스 퍼블리싱(ServiceTypes) : 정리가 필요
- 서비스 퍼블리싱 (ServiceTypes)
- 애플리케이션 중 일부(예: 프론트엔드)는 서비스를 클러스터 밖에 위치한 외부 IP 주소에 노출하고 싶은 경우 쿠버네티스
ServiceTypes
로 원하는 서비스 종류 지정
Type 의 종류
ClusterIP
- 서비스를 클러스터-내부 IP에 노출.
- 클러스터 내에서만 서비스에 도달가능
- ServiceTypes 의 기본 값
NodePort
- 고정 포트 (NodePort)로 각 노드의 IP에 서비스를 노출
- NodePort 서비스가 라우팅되는 ClusterIP 서비스가 자동으로 생생
<NodeIP>:<NodePort>
를 요청하여, 클러스터 외부에서 NodePort 서비스에 접속 가능하다.
- Ex. (Node Host IP) 192.168.2.46:30080
LoadBalancer
- 클라우드 공급자의 로드 밸런서를 사용하여 서비스를 외부에 노출
- 외부 로드 밸런서가 라우팅되는 NodePort 와 ClusterIP 서비스가 자동으로 생성된다.
ExternalName
- 값과 함께 CNAME 레코드를 리턴하여, 서비스를 externalName 필드의 콘텐츠 (예:foo.bar.example.com)에 매핑
- 어떤 종류의 프록시도 설정 ❌
- 💨 cf. ExternalName 유형을 사용하려면 kube-dns 버전 1.7 또는 CoreDNS 버전 1.7 이상이 필요하다.
디플로이먼트
- 디플로이먼트
- 애플리케이션 인스턴스를 어떻게 생성하고 업데이트하는지 지시하는 역할
- 디플로이먼트가 만들어지면, "쿠버네티스 컨트롤 플레인" 이 해당 디플로이먼트에 포함된 애플리케이션 인스턴스가 클러스터의 개별 노드에서 실행되도록 스케줄한다.
- 머신의 장애나 정비에 대응할 수 있는 자동 복구(self-healing) 메커니즘을 제공
- 애플리케이션 인스턴스가 생성되면, 쿠버네티스 디플로이먼트 컨트롤러는 지속적으로 이들 인스턴스를 모니터링
- 인스턴스를 구동 중인 노드가 다운되거나 삭제되면, 디플로이먼트 컨트롤러가 인스턴스를 클러스터 내부의 다른 노드의 인스턴스로 교체
- 파드 하나를 배포하더라도 디플로이먼트로 배포한다.
템플릿(매니페스트)정의
리소스 할당(resource quota)
- 파드 및 컨테이너 리소스 관리
- 파드가 실행 중인 노드에 사용 가능한 리소스가 충분하면, 컨테이너가 해당 리소스에 지정한
request
보다 더 많은 리소스를 사용할 수 있도록 허용된다. 그러나, 컨테이너는 리소스 limit
보다 더 많은 리소스를 사용할 수는 없다.
- CPU 리소스 단위
- 쿠버네티스에서 CPU 리소스를
1m
보다 더 정밀한 단위로 표기할 수 없다. 이 때문에, CPU 단위를 1.0
또는 1000m
보다 작은 밀리 CPU 형태로 표기하는 것이 유용하다.
- 예를 들어,
0.005
보다는 5m
으로 표기하는 것이 좋다.
- 메모리 리소스 단위
정리할 목록
$ kubectl scale --current-replicas=4 --replicas=6 deployment/nginx-deployment
$ kubectl scale --replicas=6 deployment/nginx-deployment
-
Ingress 알아보기
-
ConfigMap 알아보기
-
Namespace 알아보기
-
리밋 레인지(LimitRange) 알아보기