본문 바로가기

책/도커, 쿠버네티스를 활용한 컨테이너 개발 실전 입문

컨테이너 실전 구축 및 배포

애플리케이션과 시스템 내 단일 컨테이너의 적정 비중

컨테이너 1개 = 프로세스 1개?

 - 1개 이상의 프로세스를 실행하는 컨테이너를 허용하는 쪽이 간결한 형태를 유지할 수 있는 경우가 많다

 - 자식 프로세스를 너무 의식하지 말자

 - 컨테이너 하나가 한가지 역할이나 문제 영역에만 집중하도록 하자


컨테이너의 이식성

도커에서 사용하는 컨테이너형 가상화 기술은 호스트 운영 체제와 커널 리소스를 공유한다

 - 도커 컨테이너를 실행하려면 호스트가 특정 CPU 아키텍처 혹은 운영 체제를 사용해야 한다

애플리케이션이 어떤 라이브러리를 사용하느냐에 따라 이식성을 해침

 - 네이티브 라이브러리를 동적 링크해 사용하는 경우

 - 되도록 네이티브 라이브러리를 정적 링크해 빌드하는 것이 좋음


도커 친화적인 애플리케이션

환경 변수 활용

 - 실행 시 인자

    - 외부에서 값을 주입받을 수 있다는 장점이 있음

    - 실행 시 인자가 너무 많아지면 애플리케이션에서 인자를 내부 변수로 매핑해주는 처리가 복잡해짐

    - CMD 및 ENTRYPOINT 인스트럭션 내용을 관리하기가 어려워짐 

 - 설정 파일

    - 실행할 애플리케이션에 dev/prod와 같이 환경 이름을 부여하고 그에 따라 설정 파일을 바꿔가면 사용하는 방식

    - 설정 파일을 도커 이미지에 포함시키면 이식성을 해치게 됨(환경에 따라 설정 파일이 추가 되면 이미지를 새로 빌드해야 됨)

 - 애플리케이션 동작을 환경 변수로 제어

    - 매번 이미지를 다시 빌드하지 않아도 됨

    - 외부에서 값을 주입받을 수 있음

    - 계층적 데이터 구조를 갖는 설정 파일보다 애플리케이션 쪽에서 매핑을 처리하는 데 수고가 더 많이 든다

 - 설정 파일에 환경 변수를 포함

    - 환경별 설정 파일을 애플리케이션에 포함하는 대신 설정 파일 템플릿에 환경 변수를 포함

    - 환경 변수의 장점과 설정 파일의 장점을 모두 취할 수 있음


퍼시스턴스 데이터를 다루는 방법

데이터 볼륨

 - 컨테이너와 호스트 사이에 디렉터리를 공유

 - 도커 컨테이너 안의 디렉터리를 디스크에 퍼시스턴스 데이터를 남김

 - 컨테이너를 파기해도 디스크에 남으므로 상태를 갖는 애플리케이션을 실행하는 데 적합함

 - 호스트 안의 특정 경로에 의존성이 생기기 때문에 호스트쪽 데이터 볼륨을 잘 못 다루면 애플리케이션에 부정적 영향을 미칠 수 있음

데이터 볼륨 컨테이너

 - 컨테이너 간에 디렉터리를 공유

 - 도커에서 관리하는 호스트 머신의 /var/lib/docker/volumes/ 아래에 위치

 - 도커가 관리하는 디렉터리 영역에만 영향을 미침

 - 호스트 머신이 컨테이너에 미치는 영향을 최소한으로 억제함

 - 컨테이너 안의 애플리케이션과 데이터의 결합이 느슨하므로 컨테이너와 데이터를 쉽게 교체할 수 있다


컨테이너 배치 전략

도커 스웜

 - 여러 도커 호스트를 클러스터로 묶어주는 컨테이너 오케스트레이션 도구의 한 종류

 - 클러스터를 관리하는 매니저 컨테이너가 필요

 - 매니저 컨테이너에 docker container exec -it docker swarm init 명령을 통해 스웜의 매니저 역할을 맡김

 - docker container exec -it <참여할 컨테이너명> swarm join 명령을 통해 스웜 클러스터에 등록

 이름

 역할

 대응하는 명령어

 컴포즈

 여러 컨테이너로 구성된 도커 애플리케이션을 관리(주로 단일 호스트)

 docker-compose

 스웜

 클러스터 구축 및 관리(주로 멀티 호스트)

 docker swarm

 서비스

 스웜에서 클러스터 안의 서비스(컨테이너 하나 이상의 집합)를 관리

 docker service

 스택

 스웜에서 여러 개의 서비스를 합한 전체 애플리케이션을 관리

 docker stack

서비스

 - 도커 호스트에 대한 컨테이너 배포는 docker container run 명령으로 컨테이너를 일일히 실행하거나 컴포즈를 사용해 여러 컨테이너를 동시에 실행하는 방법이 있음

 - 스웜을 사용하는 경우에는 매니저 컨테이너에서 docker container exec -it manager docker service create 명령을 통해 서비스를 생성

 - docker container exec -it manager docker service scale echo=<컨테이너 수>를 통해 스케일 인/아웃을 처리

스택

 - 하나이상의 서비스를 그룹으로 묶은 단위로 애플리케이션 전체 구성을 정의

 - 스웜에서 동작하는 스케일 인/아웃, 제약 조건 부여(컨테이너 실행 조건을 제약)가 가능한 컴포즈

 - 스택을 사용한 배포된 서비스 그룹은 overlay 네트워크(여러 도커 호스트에 걸쳐 배포된 컨테이너 그룹을 같은 네트워크에 배치하기 위한 기술)에 속함

 - overlay 네트워크를 설정하지 않으면 스택마다 서로 다른 overlay 네트워크를 생성하고 그 안에 서비스 그룹이 속하게 됨

    - 서비스가 다른 overlay 네트워크에 속한 다른 서비스를 발견할 수 없으므로 통신이 불가능함

 스택 하위 명령 

 내용

 deploy

 스택을 새로 배포, 혹은 업데이트 함

 ls

 배포된 스택의 목록을 출력

 ps

 스택에 의해 배포된 컨테이너의 목록을 출력

 rm

 배포된 스택을 삭제

 services

 스택에 포함된 서비스 목록을 출력


 - 매니저 컨테이너에서 docker container exec -it manager docker network create --driver=overlay --attach <네트워크명>으로 생성

 - 스웜 클러스터에 스택을 배포하려면 docker container exec -it manager docker stack deploy [options] <스택명>으로 배포

    - -c 옵션 : 스택 정의 파일 경로


스웜 클러스터 외부에서 서비스 사용하기

서비스 클러스터 외부에서 오는 트래픽을 목적 서비스로 보내주는 프록시 서버가 있어야 함

HAProxy를 프록시 서버로 사용해 스웜 클러스터 외부에서 echo_nginx 서비스에 접근할 수 있게 해줌

 - dockercloud/haproxy 이미지를 사용

 - 이 이미지로 만든 컨테이너는 컨테이너 외부에서 서비스에 접근할 수 있게 해주고 서비스가 배치된 노드에 로드 밸런싱 기능을 제공

스택 디렉터리에 ingress 설정 파일을 두고 HAProxy 설정을 하고 서비스 설정에 SERVICE_PORT를 추가

사용할 서버가 있는 스택을 배포하고 스택 ingress도 배포

 - docker container exec -it manager docker stack deploy -c <스택 정의 파일 경로> <스택명> 

 - docker container exec -it manager docker stack deploy -c <인그레스 정의 파일 경로> <인그레스 스택명> 

쿠버네티스의 스웜과 비슷한 개념

 - 서비스는 레플리카(컨테이너) 수를 조절해 컨테이너를 쉽게 복제할 수 있고 여러 노드에 레플리카를 배추할 수 있음(스케일 아웃에 유리)

 - 서비스로 관리되는 레플리카는 서비스명으로 네임 레졸루션 되므로 서비스에 대한 트래픽이 각 레플리카로 분산됨

 - 스웜 클러스터 외부에서 스웜에 배포된 서비스를 이용하려면 서비스에 트래픽을 분산시키기 위한 프록시를 갖춰야 됨

 - 스택은 하나 이상의 서비스를 그룹으로 묶을 수 있으며, 여러 서비스로 구성된 애플리케이션을 배포할 때 유용