TIL(2020.12.20)

Awesome·2020년 12월 20일
0

TIL

목록 보기
45/46

Docker

udemy - Docker Mastery: with Kubernetes +Swarm from a Docker Captain

환일님 깃허브 - contianer regitries
준수님 노션 - swap app lifecycle

Section 8: Swarm Basic Features and How to Use Them in Your Workflow

overlay network

최초 swarm init(초기화)을 하면 두 개의 네트워크가 자동 생성된다.

  • ingress : overlay nerwork 드라이버이며, swarm service 기본 드라이버로 데이터 트래픽 통제 역할
  • docker_gwbridge : swarm 에 참여한 docker deamon 들을 연결시켜주는 역할(분산 환경에 참여한 호스트 연결)

overlay network 란 docker deamon host 간의 분산 네트워크를 만들어준다. 하나의 swarm 안에서 여러 호스트의 컨테이너 통신을 연결한다고 볼 수 있다. 각각의 통신은 암호화 된다.

docker network create --driver overlay <name>

routing mesh

service 내의 여러 container 들끼리 혹은 외부 traffic이 들어올 경우, 어떻게 적절한 port 에 적절한 container 로 request를 전달할 수 있을까?

swarm mode 에서 그러한 역할을 해주는 것을 routing mesh 라고 한다.

routing mesh 는 리눅스 커널의 IPVS(IP Virtual Server)를 기반으로 하며, 로드 밸런싱 역할과 함께 외부로부터의 통신을 적절한 포트와 task 에 분산시켜주는 역할을 한다.

첫 번째 케이스는 swarm 내의 container 간의 통신 예시이다.
overlay network 내에서 service 이름으로 DNS mapping 된 위와 같은 service에 VIP가 할당되어 있다. 해당 VIP로 들어오는 통신에 대해 각 container에 적절히 분배하는 로드 밸런싱이 이루어진다. DNS 관련 어떠한 것도 신경 쓸 필요 없이, 마치 로드 밸런싱 하드 웨어를 사용하는 것처럼 VIP 에 의존할 수 있다.

또 다른 케이스는 외부 traffic이 published port 로 들어오는 경우이다. 8080 port 로 request 가 들어오는 경우, routing mesh 가 traffic 충돌을 감안하여, 적절한 active node 에 분배한다.

routing mesh 와 관련하여 좀 더 깊게 알아보면, 위와 같다.

먼저, stateless 라는 뜻은 request 에 대하여 session 정보를 추적하지 않는다는 것이다. 즉, 모든 통신을 동일하게 취급한다. 빠르고 자원 소모가 크지 않다는 장점이 있지만, 반대로 load distribution에 대한 문제가 발생할 수 있다. 초당 100개의 request 를 보내는 client 와 5개를 보내는 client를 동일하게 취급하기 때문이다. 그 이유는 무엇인가?

위의 그림을 보면 stateless LB 의 경우, client ip와 source ip 를 hashing 하여 연결한다. hashing 되어 나온 결과 값으로 적절히 request 들을 분산하여 server로 연결하는데, 만약 한 명이 100개의 request를 보낼 경우, 하나의 server 로만 연결되기 때문에 distribution 의 효율이 떨어지는 문제가 발생하는 것이다.

반면 stateful의 경우에는 session 정보를 계속해서 추적하기 때문에 이러한 session table을 바탕으로 여러 알고리즘을 구현하고, 이 알고리즘을 기반으로 load distribution을 수행한다. 그 중에서도 Round-Robin(RR) 알고리즘이 있으며, 운영체제의 프로세스 스케줄링에서도 나오는 내용과 같다.
RR 은 도착시간을 기준으로 각 서버에 돌아가면서 통신을 할당하는 방식이다. 각 request 가 거의 동일한 소요 시간을 갖는 경우에 주로 사용한다.


다음으로 routing mesh는 OSI 계층 중에서 TCP/IP를 기반으로 한 layer 4(transport layer) 의 Load Balancer 이다. 위의 설명에서는 layer3 이라고 나와 있는데 아마 OSI 7 계층 기준이 아닌, 단순화한 4계층 기준으로 보인다.

Layer 4 LB는 traffic을 ip주소와 포트, 프로토콜 기반으로 분산시킨다. 따라서 Swarm 내에서 동일 포트, 동일 server ip 로는 여러 웹사이트를 running 시킬 수 없다. 이를 해결하는 방법은 Nginx, HAProxy 와 같은 프록시 서버를 사용하는 것이다.

Nginx 는 layer 4, layer 7(application layer) 기반의 LB 가 있으며, layer 7의 경우 http contents 를 보고 이에 맞는 서버로 분산시키는 역할을 한다.

혹은 Docker Enterprise Edition 을 사용하는 방법도 있다.

Stacks: Production Grade Compose

Docker-compose 의 docker-compose.yml 기반으로 docker swarm 에서는 stack 을 통해서 swarm으로 deploy 할 수 있다.

stack 을 사용하면 network나 volume 을 따로 만들 필요 없이 전부 처리가 가능하다. 여러 service에 대한 metadata를 설정할 수 있다.
stack은 build 를 하지 않는다. deploy 를 위한 것이므로 내가 만든 app 을 deploy 하고 싶다면, docker hub registry 에 push 한 뒤에 해당 registry 이름/경로를 image 옵션에 입력해야 한다.
(예시: 127.0.0.1:5000/stackdemo)

기존 compose 파일과 거의 유사하지만 stack을 사용하기 위해서는 version 이 3 이상이어야 하며, deploy 옵션이 추가되어 있다.

해당 yml 파일을 기반으로

docker stack deploy -c ~.yml <stack name>

-c 옵션은 --compose-file 의 줄임이다.
yml file을 업데이트 한 경우에는 따로 update하는 것이 아닌 위의 deploy command를 다시 한번 실행하면 자동으로 반영된다.

Secrets Storage

username, password, SSH keys 등 노출되지 않기를 원하는 값들을 Swarm 에서 관리할 수 있다.

swarm 을 사용하는 경우에만 docker secret create 구문으로 secret을 사용할 수 있으며, 그렇지 않은 경우에도 접근은 file형태로 접근은 가능하지만 보안 효과는 없다.

Swarm 내에 secret을 생성하는 방법은 secret value 를 전달하거나 file을 전달하는 방식이다. 아래의 command 를 사용한다.

docker secret create <name> <filename>
echo "value" | docker secret create <name> -

file 을 전달하는 방법은 server의 하드 드라이브에 파일이 저장되어 있다는 단점이 있다. 따라서 local 에서 remote API 를 통해 전달하는 방식을 사용하는 것이 좋다.

echo로 value를 전달하는 방식은 root user의 bash file history에 기록이 남는 문제가 발생한다.

따라서 secret 정보를 다룰 때에는 이러한 잠재적 위협을 고려해야 한다.

저장된 정보는 파일 형태로 남아있는 것처럼 보이지만, 사실은 휘발성 파일이며, service 종료와 함께 사라진다.

secret 정보를 적용할 때에는 create 할 때, secret 옵션을 사용한다. secret 정보는 보통 환경변수에 적용되는 일이 많으며, 생성 시에 -e 옵션으로 경로를 지정한다. secret 은 위에서 보이는 바와 같이 /run/secrets/<filename> 경로로 지정된다.

docker servicer create --secret <name> -e POSTGRES_PASSWORD_FILE=/run/secrets/psql_pwd

service 가 이미 생성된 상태에서는 다음의 command line 을 사용한다.

docker service update --secret-rm (삭제) --secret-add(추가)

secret 정보가 추가, 변경, 삭제되는 경우 container 는 자동으로 redeploy 된다.

stack 을 사용해서 secret을 생성할 수 있다.
이 때, version 은 3.1 이어야 한다. 앞선 stack이 version3 이었고, secret을 사용하기 위해서는 3.1 version을 적용해야 한다.
services 내에 secrets 옵션과 함께 secrets 내에 각 값을 정의해야 한다. 또한 stack을 제거할 경우, secret 도 함께 제거되어 개별 secret을 따로 삭제시키지 않아도 된다.

profile
keep calm and carry on

0개의 댓글