컨테이너/도커

Ochestration : 멀티호스트 환경에서의 컨테이너 관리

비니화이팅 2022. 10. 18. 02:05

클러스터링

  • 여러 대의 서버나 하드웨어를 모아서 한 대처럼 보이게 하는 기술
  • 컨테이너는 보통 멀티호스트 환경(여러개의 물리머신 또는 여러개의 가상머신)으로 구축
  • 가용성, 확장성 장점

오케스트레이션 툴

  • 멀티 호스트 환경에서 컨테이너들의 클러스터링을 수행
  • 멀티호스트로 구성된 환경을 클러스터 구성으로 가동시키려면 컨테이너의 시작, 정지 / 호스트 간 네트워크 연결, 스토리지 관리 / 컨테이너를 어떤 호스트에서 가동시킬지와 같은 스케줄링 기능 / 컨테이너가 정상적으로 작동하고 있는지 감시하는 기능이 필요
  • Kubernetes, Docker Swarm

Kubernetes

  • 여러 개의 호스트를 하나로 묶어 도커를 이용하기 위한 오케스트레이션 툴
  • 오케스트레이션 툴을 온프레미스 환경에 도입 시 인프라 환경 구축과 더불어 컨테이너 오케스트레이션 툴, 감시 툴의 사용법이나 운용 및 장애 대응 등 여러 분야에 걸친 기술이 필요하므로 퍼블릭 클라우드가 제공하는 서비스를 이용하는 것을 추천
    • Amazon EKS, Azure AKS, Google GKE

주요 기능

  • 여러 서버들에서의 컨테이너 관리
  • 컨테이너 간 네트워크 관리
  • 컨테이너 부하분산
  • 컨테이너 감시
  • 무정지로 업데이트

Kubernetes의 서버 구성

마스터 서버(Kubernetes Master)

  • 쿠버네티스 클러스터 안의 컨테이너 조작
  • kubect1 명령을 사용하여 클러스터를 구성 또는 리소스 조작
    • 리소스 조작 시 커맨드로부터 리퀘스트를 받아 처리
  • 쿠버네티스 클러스터 안에 있는 노드의 리소스 사용 상황을 확인하고 컨테이너를 시작할 노드를 자동으로 선택
  • etcd에 있는 구성정보를 바탕으로 여러 노드나 컨테이너 관리
  • 다중화 검토 필요

API Server

  • 리소스 정보를 관리하기 위한 프론트엔드 REST API
  • 각 컴포넌트로부터 리소스 정보를 받아 데이터 스토어(etcd)에 저장
  • 다른 컴포넌트는 API Server를 통해 etcd의 정보에 액세스
  • 프로그래머가 API Server에 액세스하려면 웹의 GUI 툴이나 kubectl 명ㄹ쳥 사용
  • 인증 및 인가 기능도 갖고 있음

Scheduler

  • Pod을 어떤 노드에서 작동시킬지 제어
  • 노드에 할당되어 있지 않은 Pod에 대해 쿠버네티스 클러스터의 상태를 확인하고 빈 영역을 가진 노드를 찾아 Pod을 실행

Controller Manager

  • 쿠버네티스 컬러스터의 상태를 항상 감시하는 백엔드 컴포넌트
  • 정의 파일에서 정의한 것과 실제 노드나 컨테이너에서 움직이고 있는 상태 모아서 관리

백엔드 데이터베이스(etcd)

  • 클러스터의 구성정보를 관리
  • 어떤 pod을 어떻게 배치할 지와 같은 구성정보 및 설정정보가 들어 있음
  • 데이터베이스를 마스터 서버 상에 구축하는 경우도 있음
  • 다중화 검토 필요

manifest 파일

  • 클러스터의 구성 정보를 YAML 및 JSON 형식의 파일로 관리
  • 젠킨스와 같은 소프트웨어 버전관리 시스템과 연계 가능

노드

  • 도커 컨테이너를 작동시키는 서버
  • 클라우드에서는 가상머신의 인스턴스가 노드

kubelete

  • 노드에서 작동하는 에이전트
  • pod의 정의 파일에 따라 도커 컨테이너를 실행하거나 스토리지를 마운트
  • 노드의 상태를 정기적으로 검사하여 변경 시 API Server에게 통지

애플리케이션 구성 관리(Pod, ReplicaSet, Deployment)

Pod

  • 한 개의 노드에 있는 여러 개의 컨테이너를 모아서 pod로 관리
  • 반드시 동일한 노드 상에 동시에 전개
  • 노드 안에는 여러 개의 pod이 배치
  • 애플리케이션의 전개단위가 되어 pod 단위로 컨테이너 작성/시작/정지/삭제와 같은 조작 수행
    • 웹 프론트 서버와 데이터베이스 서버와 같이 역할이 다른 기능을 하나의 pod에 저장하면 안 됨

배포방식

ReplicaSet-Deployment

ReplicaSet

  • 클러스터 상에 정해진 수의 pod을 반드시 실행
  • 실행중인 pod을 감시하여 정지된 경우 해당 pod을 삭제하고 새로운 pod을 실행
  • 리플리카 수 : pod을 실행시킬 개수
  • pod 수를 동적으로 변경하여 오토스케일 구현 가능

Deployment

  • pod과 replicaset을 모은 것
  • replicaset의 이력을 관리
    • pod 안의 컨테이너 버전업을 하고 싶을 때 시스템을 정지시키지 않고 롤링 업데이트를 할 수 있거나 이력을 바탕으로 이전 세대로 롤백 가능
  • replicaset의 템플릿을 가지고 pod의 구성을 정의하여 해당 템플릿을 따르는 replicaset을 만듬
  • 리플리카 수를 유지하는 것이 replicaset, replicaset의 작성이나 갱신을 정의하는 것이 deployment

DaemonSet

  • 노드별로 감시 에이전트와 같은 특정 pod을 반드시 배치하고 싶을 때 사용

StatuefulSets

  • 스테이트풀 애플리케이션 지원
  • Pod마다 고유의 ID와 상태를 가질 수 있음
    • 웹 서버와 DB 서버가 연결되는 애플리케이션 등에서 사용을 검토하면 좋음
    • 도커는 스테이트리스한 애플리케이션을 효율적으로 실행하는 데 적합한 툴이므로 영구 데이터의 관리에는 적합하지 않음

Job-CronJob

  • 웹 서버와 같은 상주 서비스가 아니라 수치 연산 처리와 같이 프로그램의 시작부터 종료까지로 완료되는 프로그램을 pod에서 실행
//cronjob.yaml 파일
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: showdate
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: showdate
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello Docker
          restartPolicy: OnFailure

kubectl create -f config/cronjob.yaml
  • 잡을 한번만 실행하는 Jobs도 있음

Replication Controller

쿠버네티스 클러스터 구축

명령어

  • 노드 확인(kubectl get nodes)
  • 정의파일 지정 및 전개(kubectl create -f [파일])
  • pod 확인(kubectl get pods)
  • pod 정지(kubctl delete pod [Pod Name])
  • pod 모두 정지(kubctl delete -f [deployment 파일])
  • 서비스 비공개(kubectl delete -f [서비스 정의 파일])
  • job 삭제(kubectl delete -f [cronjob 정의 파일])
  • 서비스 상태 확인(kubctl get services)
  • cronjob 확인(kubectl get cronjob)
  • gronjob 실행 내용(kubectl get jobs —watch)

애플리케이션 설정 정보 관리(kind: ConfigMap, kind: Secrets)

  • 설정 정보나 외부 서비스를 이용하기 위한 API 키 등은 환경에 의존하기 때문에 분산 환경에서 작동하는 도커 컨테이너 안에서 관리하는 것이 아니라 다른 방법으로 관리하는 것이 바람직

애플리케이션 프로퍼티 정보(kind: ConfigMap)

  • 애플리케이션에서 공통으로 사용하는 프로퍼티 정의
  • 설정한 값은 etcd에서 플레인 텍스트로 관리
//config/configmap.yaml 파일
apiVersion: v1
kind: ConfigMap
metadata:
    name: projectid
data:
    project.id: "hello-docker"

// configmap 정의파일 지정
kubectl create -f config/configmap.ymal

기밀 데이터(kind: Secret)

  • 다른 시스템에서 호출하여 사용하는 API 키나 데이터베이스 연결을 위한 ID 및 비밀번호와 같은 기밀 데이터 관리
  • etcd에서 플레인 텍스트로 관리하기 때문에 base64로 인코딩할 필요가 있음
    • base64 인코딩은 암호화가 아니기 때문에 Secrets 설정 파일의 관리는 인터넷 상의 공개 리포지토리에 놓지 말고 다른 곳에서 적절히 관리해야 함
    hbeen@DESKTOP-EDC39JU:~$ echo -n "test" | base64
    dGVzdA==
    
//config/secrets.yaml 파일
apiVersion: v1
kind: Secret
metadata:
  name: apikey
type: Opaque
data:
  id: YXNh
  key: YUJjRDEyMw==

// secrets 정의파일 지정
kubectl create -f config/configmap.ymal

앱 전개(kind: Deployment)

  • pod에 대한 설정
//deployment-blue.yaml 파일
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: webserver-blue
spec:
  replicas: 3           //pod 수
  template:
    metadata:
      labels:           //라벨 설정
        type: webserver
        color: blue
    spec:
      containers:
      - image: gcr.io/<PROJECT_ID>/imageview:blue           //이미지 취득
        name: webserver-container
        env:                                               //환경변수 정의
        - name: PROJECT_ID
          valueFrom:
            configMapKeyRef:
              name: projectid
              key: project.id
        - name: SECRET_ID
          valueFrom:
            secretKeyRef:
              name: apikey
              key: id
        - name: SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: apikey
              key: key
        ports:                                               //포트 정의
        - containerPort: 80
          name: http-server

//deployment-green.yaml 파일
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: webserver-green
spec:
  replicas: 3           //pod 수
  template:
    metadata:
      labels:
        type: webserver
        color: green
    spec:
      containers:
      - image: gcr.io/<PROJECT_ID>/imageview:green
        name: webserver-container
        env:
        - name: PROJECT_ID
          valueFrom:
            configMapKeyRef:
              name: projectid
              key: project.id
        - name: SECRET_ID
          valueFrom:
            secretKeyRef:
              name: apikey
              key: id
        - name: SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: apikey
              key: key
        ports:
        - containerPort: 80
          name: http-server

//애플리케이션 정의 파일 지정(전개)
kubctl create -f config/deployment-blue.ymal
kubctl create -f config/deployment-green.ymal

Label

  • 리소스를 식별하기 위한 key-value형으로 된 임의의 문자열
  • Label이 붙은 리소스를 참조하려면 selector로 지정
  • 하나의 리소스에 여러 개 설정 가능
  • 쿠버네티스 정의 파일인 매니페스트 파일을 참조할 때도 사용
  • 논리적인 그룹핑 가능

네트워크 관리(service)

  • Load Balancer : 서비스에 대응하는 IP 주소 + 포트번호에 액세스하여 pod에 대한 레이어 4레벨의 부하분산
  • Cluster IP : 클러스터 안의 pod끼리 통신하기 위한 프라이빗 IP 주소
    • 클러스터 안의 pod에서 cluster IP로 보내는 패킷은 노드 상의 proxy 데몬이 받아 수신 pod으로 전송
  • External IP : 외부 클라이언트가 연결하기 위한 퍼블릭 IP 주소
//service.yaml 파일
apiVersion: v1
kind: Service
metadata:
  name: webserver
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    type: webserver
    color: blue          // blue -> green으로 변경하면 요청 전송처가 변경되므로 앱 버전업 가능(green pod에 문제 발생 시 Blue로 전송처를 되돌릴 수 있음)

//서비스 정의 파일 지정하여 서비스 공개
kubectl create -f config/service.yaml

Ingress

  • pod에 대한 통신을 제어
  • 서비스와 연결되어 통신 내용을 프록시
  • 레이어7에서 작동하기 때문에 세세한 네트워크 제어 가능