docker-compose는 여러개의 container를 실행할 때 유용하다.

docker run simple-webapp
docker run mongodb
docker run redis:alpine
docker run ansible

다음과 같은 docker-compose.yml 파일 하나로 여러개의 container를 동시에 실행할 수 있다.

# docker-compose.yml

web:
    image: "simple-webapp"
database:
    image: "mongodb"
messaging:
    image: "redis:alpine"
orchestration:
    image: "ansible"

만약 투표앱을 만드는 상황을 가정해보자.

  • voting-app : python
  • in-memory DB : redis
  • worker : .NET
  • db : PostgreSQL
  • result-app : Node.js
docker run -d --name=redis redis
docker run -d --name=db
docker run -d --name=vote -p 5000:80 voting-app
docker run -d --nameresult -p 5001:80 result-app
docker run -d --name=worker worker

그러나 위와 같이 container를 실행했을 때, 제대로 동작하지 않는다. 그 이유는 컨테이너 간의 통신은 연결되어 있지 않기 때문이다. 이 문제는 --link flag를 이용하여 각 컨테이너를 연결해줄 수 있다.

docker run -d --name=redis redis
docker run -d --name=db postgres:9.4
docker run -d --name=vote -p 5000:80 --link redis:redis voting-app
docker run -d --nameresult -p 5001:80 --link db:db result-app
docker run -d --name=worker --link db:db --link redis:redis worker

이렇게 하면 다음과 같이 컨테이너가 연결되게 된다.

 

그러나 해당 앱을 실행할 때 마다 위의 명령어를 입력하는 것은 매우 번거롭고 비효율적인 작업이다. 따라서 해당 작업을 자동화 한다면 더 효율적인 업무가 가능할 것이다. 바로 이럴 때 docker-compose 를 사용하는 것이다.

위의 container들을 docker-compose로 다시 작성해보면 다음과 같다.

# docker-compose.yml

redis:
    image: redis
    
db:
    image: postgres:9.4

vote:
    image: voting-app
    ports:
      - 5000:80
    links:
      - redis

result:
    image: result-app
    ports:
      - 5001:80
    links:
      - db

worker:
    image: worker
    links:
      - redis
      - db

각 service를 정의하고, 해당 속성에 맞는 요소들을 작성해주기만 하면 된다.

해당 앱을 실행할 때는 docker-compose up 명령어를 이용한다.

만약 DockerHub의 이미지가 아닌 local의 Docker 이미지를 사용하고 싶다면 image: 대신 build: ./DockerfileDirectory를 사용한다.

# docker-compose.yml

redis:
    image: redis
    
db:
    image: postgres:9.4

vote:
    build: ./vote
    ports:
        - 5000:80
    links:
        - redis

result:
    build: ./result
    ports:
        - 5001:80
    links:
        - db

worker:
    build: ./worker
    links:
        - redis
        - db

docker-compose version에 대하여

위에서 작성한 내용은 docker-compose version 1의 문법이다.

docker-compose version 2의 문법은 docker-compose.yml파일의 최상단에 version을 명시해주고, 기존의 항목들이 services의 하위 블록으로 들어오게 된다. 또한 같은 services 내에 있는 service라면 link 옵션을 지정하지 않아도 하나의 네트워크로 묶이게 된다.

depends_on 옵션을 사용하여 dependency를 지정할 수 있다.

# docker-compose.yml
version: "2"
services:
    redis:
        image: redis
        
    db:
        image: postgres:9.4

    vote:
        build: ./vote
        ports:
            - 5000:80
        depends_on:
            - redis

    result:
        build: ./result
        ports:
            - 5001:80

    worker:
        build: ./worker

version 3에서는 더 많은 것들이 바뀌었으니 참고

 

설치 환경

  • Windows 10 WSL2
    • Ubuntu : 20.04 LTS
    • Docker : v20.10.6
    • kuberenetes, kubectl : v1.19.7
    • Kubeflow : kfctl_k8s_istio.v1.0.0.yaml
    • kfctl: v1.2.0-0-gbc038f9
  • 단일 사용자가 로컬에서만 사용할 경우 : kfctl_k8s_istio
  • 여러 사용자가 사용해야 해서 인증이 필요한 경우 : kfctl_istio_dex

(istio_dex를 사용할 경우) kubernetes 설정 수정

Kubeflow를 설치하기 위해서는 kubernetes API server를 수정해야 하는데, Docker Desktop을 통해 kubernetes를 사용하고 있기 때문에 설정 파일이 로컬에 존재하지 않는다.

$ cat /etc/kubernetes/manifests/kube-apiserver.yaml cat: /etc/kubernetes/manifests/kube-apiserver.yaml: No such file or directory

따라서, 다음 방법을 이용하여 API server를 수정한다.

# Edit kube-apiserver.yaml in docker-desktop 
# docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh 
# vi /var/lib/kubeadm/manifests/kube-apiserver.yaml 
# ADD FOLLLOWING: spec.containers.command 
# - --service-account-signing-key-file=/run/config/pki/sa.key 
# - --service-account-issuer=kubernetes.default.svc 
# - --feature-gates=TokenRequest=true # - --feature-gates=TokenRequestProjection=true

sa.key 파일이 해당 위치에 없을 수도 있으므로 /etc/kubernetes/pki/sa.key 등에 있다면 해당 경로에 맞춰 내용을 수정한다.

kfctl 설치

wget https://github.com/kubeflow/kfctl/releases/download/v1.2.0/kfctl_v1.2.0-0-gbc038f9_linux.tar.gz
tar -xvf kfctl_v1.2.0-0-gbc038f9_linux.tar.gz
sudo mv kfctl /usr/local/bin/
rm kfctl_v1.2.0-0-gbc038f9_linux.tar.gz
kfctl version # kfctl_v1.2.0-0-gbc038f9

/usr/local/bin 으로 이동시키지 않을 경우 $PATH에 추가해서 사용할 수도 있다.

Kubeflow 설치

  • k8s_istio
wget https://raw.githubusercontent.com/kubeflow/manifests/v1.2-branch/kfdef/kfctl_k8s_istio.v1.2.0.yaml
kfctl apply -f kfctl_k8s_istio.v1.0.0.yaml -V
  • istio_dex
wget https://raw.githubusercontent.com/kubeflow/manifests/v1.2-branch/kfdef/kfctl_istio_dex.v1.2.0.yaml
kfctl apply -f kfctl_istio_dex.v1.0.0.yaml -V

설치가 완료되면 port-forward 명령어로 8080 포트로 접속할 수 있도록 한다.

kubectl port-forward svc/istio-ingressgateway -n istio-system 8080:80

istio_dex의 경우 초기 아이디와 비밀번호는 admin@kubeflow.org / 12341234 이다.

유저를 추가하는 방법에 대해서는 document에 나와있다.

localhost:8080 으로 접속하여 Kubeflow Dashboard에 접속했다면 설치 완료!

설치 완료 후 초기 컨테이너 image를 pull하고 running 하느라 시간이 다소 걸릴 수 있다. kubectl get pods -n kubeflow 에서 모든 pod 가 생성되어 동작할 때 까지 기다린다.

  • 1.2.0 버전에서 pipeline으로 바로 전송 시 에러가 발생하여 1.0.0 버전을 설치하였다.

+ Recent posts