본문 바로가기
DevOps/Kubernetes

[5] 쿠버네티스 오브젝트 (2)

by 비어원 2022. 1. 2.
728x90

이번에는 쿠버네티스 오브젝트에서 공통적으로 가지는 항목에 대해 알아볼 것이다. 이 장에서는 쿠버네티스 오브젝트와 쿠버네티스 오브젝트의 메타데이터 항목인 네임스페이스, 레이블, 애노테이션에 대해 알아볼 것이다.

쿠버네티스 오브젝트

쿠버네티스 오브젝트는 쿠버네티스 시스템에서 영속성을 가지는 오브젝트이다. 쿠버네티스는 클러스터의 상태를 나타내기 위해 오브젝트를 이용하는데, 여기서 클러스터 상태라는 것은 다음과 같다.

  • 동작 중인 컨테이너 애플리케이션
  • 애플리케이션이 이용할 수 있는 리소스
  • 애플리케이션의 재구동, 업데이트, 내고장성과 같은 것에 대한 동작 정책

 

Spec, Status

대부분의 쿠버네티스 오브젝트는 오브젝트를 구성하기 위해 specstatus 라는 두 개의 필드를 가진다. spec 은 오브젝트에 대한 특성으로 오브젝트의 의도된 상태를 기술한다. 그리고 status 는 오브젝트의 현재 상태를 나타내며, 쿠버네티스 시스템및 해당 컴포넌트에 의해 제공되고 업데이트된다.
쿠버네티스 컨트롤 플레인은 모든 오브젝트의 현재 상태를 제공된 스펙에 해당하는 의도된 상태로 맞춰지도록 지속적으로 관리한다.

spec, status 확인하기

쿠버네티스 오브젝트의 status를 확인하는 방법은 kubectl의 get 명령어를 사용하면 된다.

$ kubectl get po
NAME                                READY   STATUS              RESTARTS   AGE
nginx-deployment-574b87c764-798d8   0/1     ContainerCreating   0          3s
  • get 뒤에는 상태를 확인하고자 하는 쿠버네티스 오브젝트 종류를 입력한다.
  • READY 여부와 STATUS 를 확인할 수 있다.
  • -o wide 플래그를 통해 더 자세한 정보를 확인할 수 있다.

조금 더 자세한 status를 확인하려면 describe 명령어를 사용해도 된다.

$ kubectl describe po nginx-deployment-574b87c764-798d8
...
Status:       Running
...
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
...
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  4m59s  default-scheduler  Successfully assigned default/nginx-deployment-574b87c764-798d8 to minikube
  • status, Event, conditions에 대한 정보를 확인하여 쿠버네티스 오브젝트에 대한 현재 상태, 이벤트 등을 확인할 수 있다.

spec을 확인하는 방법은 -o yaml 플래그를 추가하여 확인할 수 있다.

$ kubectl get po nginx-deployment-574b87c764-798d8 -o yaml
apiVersion: v1
kind: Pod
metadata:
  # ...
spec:
  containers:
    # ...
# ...
  • get 명령어 뒤에 오브젝트 이름을 추가하여 하나의 오브젝트에 대한 정보만을 확인할 수 있다.
  • spec 부분에서 버네티스 오브젝트에 대한 spec을 확인할 수 있다.

 

쿠버네티스 오브젝트 정의

쿠버네티스 오브젝트를 정의하려면 오브젝트에 대한 메타데이터와 의도된 상태를 기술하는 오브젝트 spec을 제시해야 한다. 메타데이터와 spec 등 쿠버네티스 오브젝트는 보통 yaml 형식의 메니페스트 파일로 정의한다. 예를 들어, 디플로이먼트는 다음과 같은 형식으로 오브젝트를 정의할 수 있다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

모든 쿠버네티스 오브젝트에 대한 공통적인 필수 필드는 아래와 같다.

  • apiVersion : 오브젝트를 생성하기 위해 사용하고 있는 쿠버네티스 API 버전
  • kind : 오브젝트의 종류
  • metadata : 오브젝트 이름(name), UID, namespace 를 포함한 메타데이터 정보 (annotation, label 도 자주 쓰인다.)
  • spec : 오브젝트에 대한 의도된 상태를 기술한다. 이는 kind마다 다르다.

 

쿠버네티스 오브젝트 생성, 수정, 삭제

모든 쿠버네티스 오브젝트는 쿠버네티스 API를 통해 생성, 수정 및 삭제를 할 수 있다. 보통은 메니페스트 파일(yaml)로 쿠버네티스 오브젝트를 명세하고 아래 명령어를 통해 오브젝트를 생성, 수정, 삭제한다.

$ kubectl create -f object.yaml   # 쿠버네티스 오브젝트 생성
$ kubectl replace -f object.yaml  # 쿠버네티스 오브젝트 업데이트
$ kubectl apply -f object.yaml    # 쿠버네티스 오브젝트 생성 or 업데이트 (upsert)
$ kubectl delete -f object.yaml   # 쿠버네티스 오브젝트 삭제

 

오브젝트 이름, ID

쿠버네티스 오브젝트는 해당 유형 (kind) 의 리소스에 대해 고유한 이름(name)을 가진다. 그리고 모든 쿠버네티스 오브젝트는 전체 클러스터에 걸처 고유한 UID 를 가진다.

오브젝트의 이름은 동일한 namespacekind 별로 유일해야 한다. 그리고 kubectl apply 명령어는 오브젝트 이름을 보고 메니페스트 파일과 같은 이름의 오브젝트가 존재한다면 업데이트하고 존재하지 않는다면 새로 생성한다.

 

 

네임스페이스

쿠버네티스의 물리 클러스터에는 여러 영역으로 나눌 수 있다. 네임스페이스 를 이용하여 여러 개의 영역으로 나눌 수 있는데, 이렇게 나눠진 가상의 영역을 가상 클러스터라고 불리기도 한다. 네임스페이스를 이용하여 여러 개의 논리적인 영역으로 나눌 수 있기 때문에, 여러 팀이 하나의 클러스터에서 사용하거나 하나의 클러스터에서 여러 프로젝트가 진행될 때 이를 구분짓기 위해 네임스페이스를 사용할 수 있다.

 

효과 및 특징

네임스페이스가 논리적인 영역을 분할하면서 가지는 효과 및 특징은 간단히 다음과 같다.

  • 쿠버네티스 자원에 대한 영역 제공
  • 서비스 DNS 이름
  • 네임스페이스당 사용 가능한 자원 설정
  • Configmap / Secret
  • 권한 설정

자원에 대한 영역 제공

네임스페이스는 이름의 범위를 제공하기 때문에 하나의 네임스페이스에서 쿠버네티스 오브젝트의 리소스 이름은 유일해야 한다. 즉, 다른 네임스페이스에 같은 오브젝트 리소스 이름은 겹쳐도 된다는 의미이다. 대신에 네임스페이스 이름은 하나의 클러스터에서는 중첩될 수 없다.

 

서비스 DNS 주소

네임스페이스는 서비스의 DNS 주소에도 영향을 끼친다. 서비스를 생성하면 DNS 주소가 생성되는데 이 DNS 이름은 <service-name>.<namespace-name>.svc.cluster.local 이다. 네임스페이스 이름은 해당 네임스페이스에 속한 모든 서비스의 URI에 존재하므로 네임스페이스의 이름을 잘 정해야 한다.

 

사용 가능한 자원 설정

ResourceQuota 를 통해 네임스페이스당 자원 소모량을 제한할 수 있는 제약조건을 정의할 수 있다. 이를 통해 네임스페이스 내 타입별 객체의 수량(파드, 서비스 ...)과 컴퓨팅 자원(CPU, RAM ... )을 제어할 수 있다.

네임스페이스는 쿠버네티스 자원에 대한 영역을 제공하고 권한과 정책을 클러스터 하위 섹션에 적용하는 메커니즘을 제공한다. 그리고 스테이징 (개발, 테스트, 통합테스트, 운영) 별로 네임스페이스를 통해 구분하게 할 수도 있는데 클러스터 전체 장애를 대비하여 운영 환경은 별도의 클러스터를 하나 만드는 것이 좋다.

 

Configmap / Secret

Configmap과 Secret에도 네임스페이스를 부여할 수 있는데, 파드가 Configmap과 Secret을 통해 볼륨을 생성하려 할 때 다른 네임스페이스에서는 Configmap과 Secret에 접근이 불가능하다. 그래서 Configmap이나 Secret을 사용하려는 파드는 항상 같은 네임스페이스에 있어야 한다.

 

권한 설정

RoleBinding, Role 을 통해서 ServiceAccount에 특정 네임스페이스에 있는 자원들에 대한 접근 권한을 설정할 수 있다.

 

Namespaced Object, Non-namespaced Object

대부분의 쿠버네티스 오브젝트는 네임스페이스에 속해있는다. 그래서 kubectl 명령어로 쿠버네티스 오브젝트를 조회하거나 조작할 때 -n {namespace-name 플래그를 추가하여 조작할 오브젝트의 네임스페이스를 정한다. 하지만 일부 오브젝트는 네임스페이스에 속해있지 않는다. 대표적으로는 네임스페이스 자체와 노드, 퍼시스턴트 볼륨 등이 있다. 네임스페이스에 속해있지 않는 객체는 클러스터 전반에서 사용되어야 할 객체라 가상 클러스터로 나뉠 수 없다고 생각하면 된다.

쿠버네티스의 수 많은 리소스 종류 중 네임스페이스에 속해있는지, 속해있지 않은지 확인하려면 다음 명령어를 통해 알 수 있다.

# 네임스페이스에 속하는 리소스
$ kubectl api-resources --namespaced=true

# 네임스페이스에 속하지 않는 리소스
$ kubectl api-resources --namespaced=false

 

네임스페이스 조회 및 삭제

한 클러스터에서 네임스페이스를 조회하는 명령어는 다음과 같다.

$ kubectl get namespace #ns
NAME              STATUS   AGE
default           Active   1d
kube-node-lease   Active   1d
kube-public       Active   1d
kube-system       Active   1d
  • namespace는 ns 로 짧게 쓸 수 있다.
  • 기본적으로 제공되는 네임스페이스는 4가지가 있다.
    • default: 네임스페이스를 지정하지 않은 오브젝트를 위한 기본 네임스페이스
    • kube-system: 쿠버네티스 시스템에서 생성한 오브젝트를 위한 네임스페이스
    • kube-public: 자동 생성되며 모든 사용자가 읽기 권한으로 접근할 수 있다. 클러스터 중에 공개적으로 읽을 수 있는 리소스를 위해 예약되어있다.
    • kube-node-lease: 클러스터가 스케일링될 때 노드 하트비트의 성능을 향상시키는 각 노드와 관련된 lease 오브젝트에 대한 네임스페이스

다음 명령어로 네임스페이스를 삭제할 수 있다.

$ kubectl delete namespace ${namespace-name}

 

레이블

레이블은 파드를 포함한 쿠버네티스 오브젝트에 첨부된 key-value 데이터이다. 레이블은 쿠버네티스의 오브젝트를 선택하는 데 사용되는데, 달리 말하면 쿠버네티스 오브젝트는 레이블을 통해 논리적인 그룹을 형성할 수 있다.

사용 용도를 간략하게 요약한다면 다음과 같다.

  • 스케줄링 (노드, 파드 셀렉터)
  • 서비스 디스커버리 (서비스)
  • 메타데이터 저장
  • istio 트래픽 제어 (Virtual Service)

구문

레이블은 key-value 구조로 되어있으며 metadata.labels 에서 레이블을 정의할 수 있다. 레이블 이름의 규칙은 다음과 같다.

  • 63자이하
  • 시작과 끝은 [a-z0-9A-Z] (alphanumeric)
  • 알파벳, 숫자를 포함하여 -, _, . 을 포함할 수 있다.

 

레이블 등록

쿠버네티스 오브젝트 메니페스트 파일에 레이블을 추가하려면 metadata.labels 항목을 추가하면 된다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  # ...

그리고 이미 등록되어있는 쿠버네티스 오브젝트에 레이블을 추가하거나 삭제하는 방법은 다음과 같다.

$ kubectl label po nginx-deployment-574b87c764-798d8 tier=backend
  • key=tier, value=backend 인 레이블이 추가된다.
$ kubectl label po nginx-deployment-574b87c764-798d8 tier-
  • key 뒤에 -를 붙이면 key 값에 대응되는 레이블이 삭제된다.

 

레이블 셀렉터

레이블 셀렉터라는 것을 통해 레이블을 이용하여 쿠버네티스 오브젝트를 식별할 수 있다. 레이블 셀렉터를 통해 파드를 세트로 쿼리하거나 식별하고 하나의 논리적 단위로 관리할 수 있다. 이를 통해 레이블을 선택하여 특정 리소스만 배포하거나 업데이트할 수 있고, 레이블로 선택된 리소스만 특정 서비스에 연결하거나 특정 레이블로 선택된 리소스에만 네트워크 접근 권한을 부여할 수도 있다.

레이블 셀렉터는 일치성 기준집합성 기준 이라는 두 종류의 셀렉터를 지원한다.

일치성 기준

일치성 기준은 셀렉터에 명시되어있는 키 값이 일치하는지 또는 불일치하는지에 대한 논리 연산을 지원한다. 연산자로는 =, ==, != 이라는 세 가지 연산자만 허용한다.

일치성 기준은 selector.matchLabels 에서 정의할 수 있다.

spec:
  selector:
    matchLabels:
     app: todo-list

 

집합성 기준

집합성 기준은 포함 (비포함) 여부에 대한 집합 연산을 지원한다. 연산자로는 in, notIn, exists 연산자가 있다.

집합성 기준은 selector.matchExpressions 에서 정의할 수 있다.

spec:
  selector:
    matchExpressions:
    - key: app
      operator: in
      values:
      - todo-list
      - scheduler
  • key: 레이블의 key
  • operator: 연산자, in, notIn, exists 중 하나를 지정하면 된다.
  • values: String 배열로 포함/비포함의 기준 value를 지정하면 된다. exists이면 생략한다.

 

애노테이션

애노테이션을 사용하여 식별 불가능한 메타데이터를 오브젝트에 추가할 수 있다. 이는 사용자보다는 프로그램을 위한 용도로 사용된다.

애노테이션은 주로 빌드 ID, 릴리스 ID, 이미지 정보, 타임스탬프, Git 브랜치명, PR 번호, 이미지 해시, 레지스트리 주소, 작성자 이름, 도구 정보 등에 쓰인다고 한다.

애노테이션은 레이블과 같이 key-value 구조의 맵 형태이다.

metadata:
  annotations:
    key1: value1
    key2: value2
  • key, value 모두 문자열 데이터여야 한다. Boolean, 숫자, 리스트 등의 다른 형식으로는 선언이 불가능하다.

 

마무리

이번 장에서는 쿠버네티스 오브젝트에서 공통적으로 가지는 항목에 대하여 알아보았다. 그 다음 장 부터는 3장에서 소개한 쿠버네티스 오브젝트 종류 하나하나에 대하여 조금 자세히 알아보는 시간을 가질 것이다. 다음 장에서는 쿠버네티스 오브젝트 중 파드에 대하여 알아볼 것이다. 

 

2022.01.05 - [DevOps/Kubernetes] - [5] 쿠버네티스 파드

 

728x90

댓글