alt
Home 시작하세요! 도커 / 쿠버네티스 6장 쿠버네티스 시작하기
Post
Cancel

시작하세요! 도커 / 쿠버네티스 6장 쿠버네티스 시작하기


쿠버네티스란?

  • 도커 컨테이너, 스웜, 컴포즈와 같은 개념을 모두 사용 가능하다.
  • 사실상 표준으로 사용되는 컨테이너 오케스트레이션 도구이다. 클라우드 환경에 적합한 오픈소스를 관리하는 Cloud Native(CNCF - 오픈소스 단체)에 속해있다.
    • containerd, 프로메테우스 등이 CNCF 소속


장점

  • 클러스터링, MSA구조의 컨테이너 배포, 장애 복구 등 운영에 필요한 오케스트레이션 기능을 지원한다.
  • 구글, redhat을 비롯한 많은 오픈소스 진영에서 쿠버네티스에 기여하고 있다.
  • 영속적 볼륨, 스케줄링, 장애 복구, 오토 스케일링, 서비스 발견, ingress 등의 기능들을 개발자가 직접 설정할 수 있다.
  • 다른 클라우드 운영도구와 쉽게 연동


특징

  • 모든 리소스는 Object이다. kubectl api-resources를 통해 확인 가능하다.
  • 대부분 리소스는 YAML로 관리한다.
  • 여러 개의 컴포넌트가 컨테이너 형태로 구성되어 있다. -> 노드에 ssh 접속해서 docker ps로 확인 가능
    • 마스터 노드 - API 서버, 컨트롤러 매니저, 스케줄러, DNS 서버 등
    • 모든 노드 - 프록시(오버레이 네트워크 구성을 위한), 네트워크 플러그인


kubelet

: 모든 노드에는 컨테이너 생성, 삭제, 마스터와 워커 노드간 통신 담당하는 에이전트인 kubelet이 실행된다. 이 kubelet은 CRI(Container Runtime Interface)와 통신한다. 도커 컨테이너의 경우 runC라는 런타임을 제어하는 containerd는 자체적으로 CRI를 내장하고 있어, kubelet과 통신 가능하다. 이 CRI를 구현하는 컨테이너라면 다른 컨테이너를 사용해도 사실상 무방하다.


파드

  • 컨테이너를 다루는 기본 단위. 하나 이상의 컨테이너로 구성
  • 도커 네트워크 중 컨테이너 네트워크의 동작방식처럼 파드 내 컨테이너 간 리눅스 네임스페이스를 공유해, 서로 통신이 가능하다.
  • 하나의 파드는 하나의 완전한 애플리케이션이어야 한다.
    • e.g. 하나의 파드 내에 두개의 nginx 컨테이너를 띄우는 것은 적절하지 않다.
    • 보통 파드 내 사이드카로 로그수집이나 설정 리로딩 프로세스를 띄우는 경우도 있다.


레플리카셋

: Pod의 Lifecycle을 관리해주는 역할. 파드를 yaml로서만 관리하면 생성, 삭제와 같은 관리를 개발자가 직접해줘야 한다. 이러한 방식은 운영 단계에서 분명 한계점이 있는데, 레플리카셋은 이러한 한계점을 해결한다.

  1. 일정량의 동일한 파드가 항상 실행되도록 관리한다. 이미 일정량의 파드가 실행중이라도 설정을 변경하면 변경된 만큼 파드를 생성 or 삭제해준다.
  2. 노드 장애 발생 시 해당 노드의 파드를 다른 노드로 다시 실행한다.


동작방식

  • 레플리카셋은 라벨 셀렉터를 이용해 파드와 느슨하게 연결된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    ...
    spec:
      repolicas: 3
      selector:
        matchLabels:
          app: my-nginx-pod # 레플리카셋의 라벨 셀렉터
      template:
        metadata:
          name: nginx
          labels:
            app: my-nginx-pod # 파드의 라벨
    
    • 라벨은 단순히 메타데이터로써 부가정보만 표시하는 것이 아니라, 리소스를 분류할 때도 사용된다.
    • 이미 레플리카셋의 라벨 셀렉터에 셀렉팅 되는 파드가 있다면, 해당 파드를 포함해 생성해야 하는 숫자만큼 생성한다.
      • 만약 파드의 라벨이 바뀌면 더이상 해당 레플리카 셋에 의해 관리되지 않는다.


디플로이먼트

: 파드 + 레플리카셋을 정의한다.

  • 레플리카셋의 슈퍼셋이다. 공식적으로 디플로이먼트 사용이 권장된다.
  • 디플로이먼트를 통해 레플리카셋과 파드를 띄우면 각각 동일한 해시값을 갖는다. 이 해시값은 파드 템플릿으로부터 계산되어, 레플리카셋의 라벨 셀렉터에서 pod-template-hash라는 이름의 라벨값으로서 자동으로 설정된다.


디플로이먼트를 사용하는 이유

: 레플리카셋의 리비전을 남기고, 파드를 롤링업데이트하는 전략을 지정할 수 있다.

  • 파드를 업데이트하면 롤링 업데이트가 수행되는데, 그러면 해당 파드들을 셀렉팅하는 레플리카셋도 새롭게 띄워진다.
    • kubectl get replicasets 를 통해 확인하면, DESIRED, CURRENT 항목에 숫자가 입력된 레플리카셋(현재)과 숫자가 0인 레플리카셋(이전 버전)을 확인할 수 있다.
    • 당연히 --to-revision=1 과 같은 옵션을 통해 롤백도 가능하다.


서비스

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadate:
  name: hostname-svc
spec:
  ports:
    - name: port
      port: 8080
      targetPort: 80 # 실제 파드 내에서 실행되는 port
  selector:
    app: webserver # 서비스와 매칭할 pod
  type: NodePort # 서비스 타입
  • 파드는 클러스터 내에서 항상 접근 가능하지만, 파드 IP는 영속적이지 않아 매변 변하기 때문에 발견 가능한 방법이 필요한데, 서비스가 해결해준다.
    • 외부에서 접근하는 경우, 도커에서는 컨테이너를 외부로 직접 노출해 접근했는데, k8s에서는 서비스를 통해서 접근해야한다.
  • 서비스는 내부 DNS를 사용해 고유한 서비스 도메인 이름을 가질 수 있다.
    • 파드 간 상호작용이 필요할때 파드 IP를 알 필요 없이 서비스 이름만 알면 된다.
  • 요청받는 서비스는 각 파드들로 LB 해준다.
  • 마찬가지로 라벨 셀렉터를 통해 파드와 매칭한다. 매칭이 되면 엔드포인트라는 오브젝트가 생성된다.


종류

: 각각 파드에 접근하는 방식이 다르다.

  • ClusterIP: (쿠버네티스 내부에서만) ClusterIP를 프록싱해 파드에 접근하는 방식
  • NodePort: 모든 노드의 특정 포트를 개방하는 방식
    • 클러스터 외부에서 각 파드가 존재하는 노드의 적절한 port로 접근 가능하다.
    • ClusterIP의 기능을 포함하고 있기 때문에 마찬가지로 서비스의 CLUSTER-IP or DNS 이름으로 접근 가능하다. (내부 접근 가능)
    • 그런데 실제 운영 환경에서 사용하기엔 여러가지 문제가 있다. (라우팅) 노드가 스케일링, 장애 등의 이유로 IP가 변경되면 클라이언트도 수정되어야 하기도 하고, SSL 문제도 잇따른다.
  • LoadBalancer: 서비스 자체를 외부에 노출한다.
    • 클라우드 플랫폼 환경에서 사용할 수 있다.
    • 클라우드 플랫폼은 LoadBalancer 서비스에 EXTERNER-IP를 부여하는데, 이 주소 + 서비스 PORT로 파드에 접근이 가능하다.
    • NodePort와 같은 방식으로 노드로도 접근이 가능하다.
  • ExternalName: 외부 도메인으로 리다이렉트한다.


ExternalTrafficPolicy

  • 서비스는 기본적으로 externalTrafficPolicy가 Cluster로 설정된다. 이 경우 노드로 들어온 요청은 다른 노드의 파드로 리다이렉트 되는 경우가 있고, 이 때 네트워크 홉으로 인해 NAT가 발생하며 클라이언트 IP가 보존 불가해진다.
  • externalTrafficPolicy를 Local로 설정하면 파드가 위치한 노드만 포트를 개방한다. 그런데 이 때는 트래픽이 몰리는 경우도 있을 수 있으므로 잘 판단해 선택해야한다.



Reference)

시작하세요! 도커 / 쿠버네티스

This post is licensed under CC BY 4.0 by the author.