Docker Compose 파일을 쿠버네티스 리소스로 변환하기

Docker Compose 파일을 쿠버네티스 리소스로 변환하기 (Translate a Docker Compose File to Kubernetes Resources)

Kompose란 무엇일까요? 모든 compose(Docker Compose)를 컨테이너 오케스트레이터(Kubernetes 또는 OpenShift)로 변환하는 변환 도구예요. 더 많은 정보는 Kompose 웹사이트 https://kompose.io/ 에서 찾을 수 있어요.

출처: 문서

본문

시작하기 전에 (Before you begin)

쿠버네티스 클러스터가 필요하고, kubectl 명령줄 도구가 클러스터와 통신하도록 구성돼 있어야 해요. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 두 개 이상 있는 클러스터에서 실행하는 것을 권장해요. 아직 클러스터가 없다면 minikube로 만들거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있어요.

  • iximiuz Labs
  • Killercoda
  • KodeKloud

버전을 확인하려면 kubectl version을 입력하세요.

Kompose 설치하기 (Install Kompose)

Kompose를 설치하는 방법은 여러 가지가 있어요. 우리가 선호하는 방법은 최신 GitHub 릴리스에서 바이너리를 다운로드하는 것이에요.

Kompose는 3주 주기로 GitHub를 통해 릴리스되며, 모든 현재 릴리스를 GitHub 릴리스 페이지에서 볼 수 있어요.

# Linux
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-linux-amd64 -o kompose

# macOS
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-darwin-amd64 -o kompose

# Windows
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-windows-amd64.exe -o kompose.exe

chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose

또는 tarball을 다운로드할 수도 있어요. go get으로 설치하면 최신 개발 변경 사항이 있는 master 브랜치에서 가져와요.

go get -u github.com/kubernetes/kompose

macOS에서는 Homebrew로 최신 릴리스를 설치할 수 있어요.

brew install kompose

Kompose 사용하기 (Use Kompose)

몇 단계로 Docker Compose에서 쿠버네티스로 이동할 거예요. 필요한 것은 기존 docker-compose.yml 파일뿐이에요.

docker-compose.yml 파일이 있는 디렉터리로 이동해요. 없으면 이 파일로 테스트하세요.

services:

  redis-leader:
    container_name: redis-leader
    image: redis
    ports:
      - "6379"

  redis-replica:
    container_name: redis-replica
    image: redis
    ports:
      - "6379"
    command: redis-server --replicaof redis-leader 6379 --dir /tmp

  web:
    container_name: web
    image: quay.io/kompose/web
    ports:
      - "8080:8080"
    environment:
      - GET_HOSTS_FROM=dns
    labels:
      kompose.service.type: LoadBalancer

docker-compose.yml 파일을 kubectl에서 사용할 수 있는 파일로 변환하려면 kompose convert를 실행한 다음 kubectl apply -f <output file>을 실행해요.

kompose convert

출력은 다음과 비슷해요.

INFO Kubernetes file "redis-leader-service.yaml" created
INFO Kubernetes file "redis-replica-service.yaml" created
INFO Kubernetes file "web-tcp-service.yaml" created
INFO Kubernetes file "redis-leader-deployment.yaml" created
INFO Kubernetes file "redis-replica-deployment.yaml" created
INFO Kubernetes file "web-deployment.yaml" created
 kubectl apply -f web-tcp-service.yaml,redis-leader-service.yaml,redis-replica-service.yaml,web-deployment.yaml,redis-leader-deployment.yaml,redis-replica-deployment.yaml

출력은 다음과 비슷해요.

deployment.apps/redis-leader created
deployment.apps/redis-replica created
deployment.apps/web created
service/redis-leader created
service/redis-replica created
service/web-tcp created

여러분의 deployment가 쿠버네티스에서 실행되고 있어요.

애플리케이션에 접근해 보세요. 개발 과정에서 minikube를 이미 사용 중이라면:

minikube service web-tcp

그렇지 않으면 서비스가 사용하는 IP를 찾아보세요.

kubectl describe svc web-tcp
 Name:                     web-tcp
 Namespace:                default
 Labels:                   io.kompose.service=web-tcp
 Annotations:              kompose.cmd: kompose convert
                           kompose.service.type: LoadBalancer
                           kompose.version: 1.33.0 (3ce457399)
 Selector:                 io.kompose.service=web
 Type:                     LoadBalancer
 IP Family Policy:         SingleStack
 IP Families:              IPv4
 IP:                       10.102.30.3
 IPs:                      10.102.30.3
 Port:                     8080  8080/TCP
 TargetPort:               8080/TCP
 NodePort:                 8080  31624/TCP
 Endpoints:                10.244.0.5:8080
 Session Affinity:         None
 External Traffic Policy:  Cluster
 Events:                   <none>

클라우드 제공자를 사용 중이라면 IP가 LoadBalancer Ingress 옆에 나열될 거예요.

curl http://192.0.2.89

정리 (Clean-up): 예시 애플리케이션 배포 테스트를 마친 후, 셸에서 다음 명령을 실행해 사용된 리소스를 삭제해요.

kubectl delete -f web-tcp-service.yaml,redis-leader-service.yaml,redis-replica-service.yaml,web-deployment.yaml,redis-leader-deployment.yaml,redis-replica-deployment.yaml

사용자 가이드 (User Guide)

  • CLI kompose convert
  • 문서
  • 대안적 변환
  • 라벨
  • 재시작
  • Docker Compose 버전

Kompose는 OpenShift와 Kubernetes 두 제공자를 지원해요. 전역 옵션 --provider를 사용해 대상 제공자를 선택할 수 있어요. 제공자를 지정하지 않으면 기본적으로 Kubernetes가 설정돼요.

kompose convert

Kompose는 V1, V2, V3 Docker Compose 파일의 Kubernetes 및 OpenShift 객체로의 변환을 지원해요.

Kubernetes kompose convert 예시
kompose --file docker-voting.yml convert
WARN Unsupported key networks - ignoring
WARN Unsupported key build - ignoring
INFO Kubernetes file "worker-svc.yaml" created
INFO Kubernetes file "db-svc.yaml" created
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "result-svc.yaml" created
INFO Kubernetes file "vote-svc.yaml" created
INFO Kubernetes file "redis-deployment.yaml" created
INFO Kubernetes file "result-deployment.yaml" created
INFO Kubernetes file "vote-deployment.yaml" created
INFO Kubernetes file "worker-deployment.yaml" created
INFO Kubernetes file "db-deployment.yaml" created
ls
db-deployment.yaml  docker-compose.yml         docker-gitlab.yml  redis-deployment.yaml  result-deployment.yaml  vote-deployment.yaml  worker-deployment.yaml
db-svc.yaml         docker-voting.yml          redis-svc.yaml     result-svc.yaml        vote-svc.yaml           worker-svc.yaml

여러 docker-compose 파일을 동시에 제공할 수도 있어요.

kompose -f docker-compose.yml -f docker-guestbook.yml convert
INFO Kubernetes file "frontend-service.yaml" created         
INFO Kubernetes file "mlbparks-service.yaml" created         
INFO Kubernetes file "mongodb-service.yaml" created          
INFO Kubernetes file "redis-master-service.yaml" created     
INFO Kubernetes file "redis-slave-service.yaml" created      
INFO Kubernetes file "frontend-deployment.yaml" created      
INFO Kubernetes file "mlbparks-deployment.yaml" created      
INFO Kubernetes file "mongodb-deployment.yaml" created       
INFO Kubernetes file "mongodb-claim0-persistentvolumeclaim.yaml" created
INFO Kubernetes file "redis-master-deployment.yaml" created  
INFO Kubernetes file "redis-slave-deployment.yaml" created   

여러 docker-compose 파일이 제공되면 구성이 병합돼요. 공통된 구성은 뒤따르는 파일에 의해 재정의돼요.

OpenShift kompose convert 예시
kompose --provider openshift --file docker-voting.yml convert
WARN [worker] Service cannot be created because of missing port.
INFO OpenShift file "vote-service.yaml" created             
INFO OpenShift file "db-service.yaml" created               
INFO OpenShift file "redis-service.yaml" created            
INFO OpenShift file "result-service.yaml" created           
INFO OpenShift file "vote-deploymentconfig.yaml" created    
INFO OpenShift file "vote-imagestream.yaml" created         
INFO OpenShift file "worker-deploymentconfig.yaml" created  
INFO OpenShift file "worker-imagestream.yaml" created       
INFO OpenShift file "db-deploymentconfig.yaml" created      
INFO OpenShift file "db-imagestream.yaml" created           
INFO OpenShift file "redis-deploymentconfig.yaml" created   
INFO OpenShift file "redis-imagestream.yaml" created        
INFO OpenShift file "result-deploymentconfig.yaml" created  
INFO OpenShift file "result-imagestream.yaml" created  

또한 서비스의 build 지시문에 대한 buildconfig 생성을 지원해요. 기본적으로 현재 git 브랜치의 원격 저장소를 빌드의 소스 저장소로, 현재 브랜치를 빌드의 소스 브랜치로 사용해요. --build-repo--build-branch 옵션을 각각 사용해 다른 소스 저장소와 브랜치를 지정할 수 있어요.

kompose --provider openshift --file buildconfig/docker-compose.yml convert
WARN [foo] Service cannot be created because of missing port.
INFO OpenShift Buildconfig using [email protected]:rtnpro/kompose.git::master as source.
INFO OpenShift file "foo-deploymentconfig.yaml" created     
INFO OpenShift file "foo-imagestream.yaml" created          
INFO OpenShift file "foo-buildconfig.yaml" created

참고: oc create -f로 OpenShift 아티팩트를 수동으로 푸시한다면, 이 OpenShift 이슈를 우회하기 위해 buildconfig 아티팩트보다 imagestream 아티팩트를 먼저 푸시해야 해요: https://github.com/openshift/origin/issues/4518

대안적 변환 (Alternative Conversions)

기본 kompose 변환은 yaml 형식의 Kubernetes Deployment와 Service를 생성해요. -j로 json을 생성하는 대안 옵션이 있어요. 또한 Replication Controller 객체, DaemonSet, 또는 Helm 차트를 생성할 수도 있어요.

kompose convert -j
INFO Kubernetes file "redis-svc.json" created
INFO Kubernetes file "web-svc.json" created
INFO Kubernetes file "redis-deployment.json" created
INFO Kubernetes file "web-deployment.json" created

*-deployment.json 파일은 Deployment 객체를 포함해요.

kompose convert --replication-controller
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "redis-replicationcontroller.yaml" created
INFO Kubernetes file "web-replicationcontroller.yaml" created

*-replicationcontroller.yaml 파일은 Replication Controller 객체를 포함해요. replicas(기본값 1)를 지정하려면 --replicas 플래그를 사용하세요: kompose convert --replication-controller --replicas 3.

kompose convert --daemon-set
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "redis-daemonset.yaml" created
INFO Kubernetes file "web-daemonset.yaml" created

*-daemonset.yaml 파일은 DaemonSet 객체를 포함해요.

Helm과 함께 사용할 Chart를 생성하려면 다음을 실행해요.

kompose convert -c
INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-deployment.yaml" created
INFO Kubernetes file "redis-deployment.yaml" created
chart created in "./docker-compose/"
tree docker-compose/
docker-compose
├── Chart.yaml
├── README.md
└── templates
    ├── redis-deployment.yaml
    ├── redis-svc.yaml
    ├── web-deployment.yaml
    └── web-svc.yaml

차트 구조는 Helm 차트를 만들기 위한 스켈레톤을 제공하는 것을 목표로 해요.

라벨 (Labels)

kompose는 변환 시 서비스의 동작을 명시적으로 정의하기 위해 docker-compose.yml 파일 안의 Kompose 특정 라벨을 지원해요.

kompose.service.type은 생성될 서비스의 유형을 정의해요. 예를 들어:

version: "2"
services:
  nginx:
    image: nginx
    dockerfile: foobar
    build: ./foobar
    cap_add:
      - ALL
    container_name: foobar
    labels:
      kompose.service.type: nodeport

kompose.service.expose는 서비스가 클러스터 외부에서 접근 가능하게 만들어야 하는지 여부를 정의해요. 값이 "true"로 설정되면 제공자가 엔드포인트를 자동으로 설정하고, 다른 값이면 값이 호스트네임으로 설정돼요. 서비스에 여러 포트가 정의되면 첫 번째가 노출되도록 선택돼요.

  • Kubernetes 제공자의 경우 ingress 리소스가 생성되고 ingress 컨트롤러가 이미 구성되어 있다고 가정해요.
  • OpenShift 제공자의 경우 route가 생성돼요.

예를 들어:

version: "2"
services:
  web:
    image: tuna/docker-counter23
    ports:
    - "5000:5000"
    links:
    - redis
    labels:
      kompose.service.expose: "counter.example.com"
  redis:
    image: redis:3.0
    ports:
    - "6379"

현재 지원되는 옵션은 다음과 같아요.

kompose.service.type nodeport / clusterip / loadbalancer
kompose.service.expose true / hostname

참고: kompose.service.type 라벨은 ports와 함께 정의해야 해요. 그렇지 않으면 kompose가 실패해요.

재시작 (Restart)

컨트롤러 없는 일반 파드를 만들고 싶다면 docker-compose의 restart 구성 요소를 사용해 그것을 정의할 수 있어요. 다음 표를 보면 restart 값에서 무슨 일이 일어나는지 알 수 있어요.

docker-compose restart kubectl의 restartPolicy 생성된 객체
"" Always 컨트롤러 객체
always Always 컨트롤러 객체
on-failure OnFailure Pod
no Never Pod

참고: 컨트롤러 객체는 deployment 또는 replicationcontroller가 될 수 있어요.

예를 들어, pival 서비스는 여기서 파드가 돼요. 이 컨테이너는 pi의 값을 계산해요.

version: '2'

services:
  pival:
    image: perl
    command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
    restart: "on-failure"
Deployment 구성에 대한 경고 (Warning about Deployment Configurations)

Docker Compose 파일이 서비스에 대해 volume을 지정하면, Deployment(Kubernetes) 또는 DeploymentConfig(OpenShift) 전략이 "RollingUpdate"(기본값) 대신 "Recreate"로 변경돼요. 이는 여러 인스턴스의 서비스가 동시에 볼륨에 접근하는 것을 피하기 위해서예요.

Docker Compose 파일에 _가 있는 서비스 이름(예: web_service)이 있으면 -로 바뀌고 서비스 이름이 그에 따라 변경돼요(예: web-service). Kompose는 "Kubernetes"가 객체 이름에서 _를 허용하지 않기 때문에 이렇게 해요. 서비스 이름 변경이 일부 docker-compose 파일을 망가뜨릴 수 있다는 점을 주의하세요.

Docker Compose 버전 (Docker Compose Versions)

Kompose는 Docker Compose 버전 1, 2, 3을 지원해요. 버전 2.1과 3.2는 실험적인 성격 때문에 제한적으로 지원해요. 세 버전 간 호환성의 전체 목록은 변환 문서에 나열돼 있으며, 호환되지 않는 모든 Docker Compose 키 목록도 포함돼 있어요.

더 알아보기 (Learn more)