Container management tool 활용 및 Container monitoring

2019-10-10

.

Data_Engineering_TIL_(20190810)

study program : https://www.fastcampus.co.kr/dev_camp_devb

[학습목표]

  • 각종 오픈소스를 활용한 Container orchestration 구현

[학습기록]

  • traefik는 컨테이너 환경에서 널리 쓰이고 있는 API 게이트웨이 및 컨테이너 리버스 프록시 툴이자 로드벨런싱 툴이다. 도커서비스가 등록이 되면 감지해서 자동으로 컨테이너 리버스 프록시 및 로드밸런싱을 담당하는 컨테이너 API게이트웨이다.

  • 80포트는 보통 http 프로토콜 담당, 443포트는 https 프로토콜을 담당한다.

  • nginx conf로 리버스 프록시를 할때 가장 불편한점은 서비스가 추가가 될때마다 각 포트에 대한 리버시 프록시 룰을 nginx conf에 넣어주고 reloading을 해줘야 한다. 반면에 traefik은 서비스 요청을 받았을때 해당 컨테이너의 정보를 가져와서 리버스 프록시를 해준다. 무슨말이냐면 docker service create --name web --replicas 3 --network external --with-registry-auth --label traefik.port=80 --label traefik.frontend.rule=Host:web.local.dev {aws-ecr-web-repo}:{tag} 명령어를 예를들어보자. 네트워크 external이라는 오버레이 네트워크 생성하고, 리플리카 3개에 서비스 이름은 web이라고 하고 ECR에서 이미지 가져와야 하니까 --with-registry-auth 옵션까지 사용했었다. 거기에 추가적으로 label이라는 것이 있는데 우리가 띄울 3개의 컨테이너에 traefik 80 port와 traefik frontend rule은 Host:web.local.dev라는 정보를 넣어주는 것이다. 이 정보들을 넣어주고 service create해주면 traefik에서 reloading이나 갱신없이 자동으로 3개의 컨테이너에 해당 룰에 맞게 리버스 프록시를 해주게 된다.

[실습목표]

[실습상세]

step 1) 도커 클러스터 형성

step 1-1) 가상머신 2대 생성(마스터노드 1대, 워커노드 1대)

아래 그림과 같이 마스터노드 1개, 워커노드 1개를 생성하고 각각의 노드에서 도커를 설치해준다.

** 참고사항 : 인스턴스 유형을 t2.large로 한것은 추후에 일라스틱서치를 사용할 것이기 때문에 자원을 조금 큰것으로 잡아준 것이다.

1

step 1-2) 각각의 노드에 접속하여 아래 그림과 같이 똑같은 과정으로 도커를 설치하고 실행해준다.

2

step 1-3) 도커 클러스터 생성

아래 그림과 같이 마스터 노드의 프라이빗 아이피를 확인한다.

3

마스터 노드에서 아래 그림과 같이 명령어를 실행한다.

4

워커노드에서 아래 그림과 같이 명령어를 실행한다.

5

step 2) 마스터 노드에서 보안자격 증명

아래 그림과 같이 AWS 콘솔에서 액세스 키를 발급받고, 마스터노드에서 AWS configure 설정을 해준다.

6

step 3) Elasticsearch 사용을 위한 버츄얼 메모리 설정

리눅스커널 파라미터값으로 재부팅 없이 조정이 가능하다. 주의할 점은 설정 적용을 위해 root 계정으로 해야한다.

그래서 아래 그림과 같이 마스터노드와 워커노드 모두 접속하여 아래 그림과 같은 명령어를 실행해준다.

7

step 4) traefik 도커 서비스 구동

마스터 노드에서 아래 그림과 같이 명령어들을 실행

8

  • constraint : 서비스 구축 시 어떤 노드에만 배치할 것인지 선택. 여기서는 깡통역할 중에 매니저노드에만 해당 컨테이너를 배포하겠다는 의미다.(--constraint 'node.role == manager' = 매니저인 노드한테만 traefik 컨테이너를 배포하겠다.)

  • mount : volume, Host의 특정 디렉토리와 컨테이너 내의 디렉토리 연결. 현재 과정에서는 Traefik service는 swarm manager의 기능을 사용하기 때문에 docker.sock 연결

  • 위의 명령어에서 mount 옵션을 보면 호스트에 있는 디렉토리와 컨테이너 내의 디렉토리를 물려주겠다는 것이다. 소스는 호스트에 있는 도커데몬인 docker.sock과 타겟은 컨테이너 내에 있는 도커데몬인 docker.sock이다. 이말은 지금 배포하고 있는 traefik이라는 컨테이너는 호스에 있는 도커데몬에 계속 사용하겠다는 의미이다.

  • traefik이 하고 있는 기능이 특정 프론트앤드 룰에 따라서 컨테이너한테 리버스 프록시 및 로드밸런싱을 해주는데 얘에 대한 아이피나 포트에 대한 정보를 가지고 와야한다. 그 기능을 해줄수 있는 것은 마스터노드에 있는 도커 데몬밖에 없다.

  • 정리하면 컨테이너의 정보를 traefik이 가져오기 위해서 호스트에 있는 도커데몬과 물려준 것이다.(기능을 갖다 쓰겠다는 것이다.)

  • 그러면 왜 위와 같이 명령을해야하냐. 각 클러스터에 분산배치되어 있는 컨테이너 정보를 가지고 올 수 있는 얘는 매니저 노드밖에 없다. traefik이라는 얘는 각 클러스터에 배포되어 있는 컨테이너 정보를 가지고 와야한다. 그래서 해당 traefik이라는 컨테이너가 매니저노드에만 배치를 시키기 위해서 해당 옵션을 적용한 것이다. 위의 경우처럼 특정역할을 가지고 있는 노드에만 해당 컨테이너를 배포해야 하는 경우가 자주 있다.

  • 또한 traefik은 정말 많은 설정을 할 수 있고, 매우 유연한 오픈소스 솔루션 중 하나이다. 포트옵션 80과 8080을 맵핑을 해주고 있다. 이제부터는 웹서비스를 80포트로 띄울 수는 없다. 지금부터는 traefik만 호스트의 80포트를 점유할 것이다. 이렇게해도 되는 이유는 웹서비스 배포할때 포트옵션을 따로 부여하지 않을 것이기 때문이다. 포트옵션이 없는 상태여도 리버스 프록시가 잘 이루어지는 것을 확인할 수 있다.

  • 일반적으로 swarm 클러스터가 5대가 되면 그중에 3대는 매니저노드로 배치를 하는 것이 일반적이다. 쿠버네티스도 마찬가지다.

위의 작업을 정상적으로 수행했으면 웹브라우저에서 마스터노드 퍼블릭아이피:8080으로 접속해서 아래 그림과 같이 전시가 되는지 확인

9

step 5) web 도커 서비스 구동

step 5-1) AWS ECR repo 생성 및 계정인증

아래 그림과 같이 ECR repo를 생성하고 마스터노드에서 계정인증을 해준다.

10

step 5-2) 사전에 미리 구현되어진 웹 컨테이너 이미지를 외부에서 다운받아서 위에서 생성한 나의 ECR repo로 push해준다.

마스터노드에서 아래 그림과 같이 명령어를 실행한다.

11

step 5-3) 다운받은 웹 컨테이너 이미지를 기반으로 web 도커 서비스를 구동한다.

마스터노드에서 아래 그림과 같이 명령어를 실행한다.

12

  • 스웜 클러스터 내부에서 통신하기 위해서 2377포트나 6379포트를 사용하고 있지만 그 외에 서비스포트는 더이상 열어놓을 필요가 없다. 80과 8080 http와 https 프로토콜을 각각 traefik이 물고 있고, traefik이 각각의 컨테이너들의 정보를 찾아와서 만약에 web.local.dev라고 요청을 받으면 컨테이너 서비스 중에 traefik frontend 룰이라는 라벨을 가지고 있고, 내가 받은 요청과 동일한 도메인정보(URL정보)를 갖고 있는 컨테이너들에게 리버스 프록시 및 로드밸런싱을 자동으로 해준다.

아무노드에서 아래 그림과 같이 curl 명령어를 실행해서 정상적으로 컨테이너가 응답을 해주는지 확인한다.

여기에서 -H 옵션으로 호스트값을 넣어줬다. http 프로토콜로 보낼때 http 헤더값이 있는데 마치 web.local.dev에 요청을 보낸것처럼 localhost(자기자신)에게 보내준것이다.

13

마스터노드의 퍼블릭아이피:8080으로 다시 접속해보면 아래 그림과 같은 화면을 확인할 수 있다.

14

그리고 마스터노드에서 아래 그림과 같은 명령어를 실행해서 결과를 확인해보자

15

step 6) counter 서비스 구동

마스터노드에서 아래그림과 같이 명령어를 실행하여 counter 서비스를 구동하고, 웹브라우저의 traefik 대시보드(마스터노드 퍼블릭URL:8080)를 열어서 counter 서비스가 traefik에 등록이 된 것을 확인해본다.

16

step 7) visualizer와 portainer 서비스 구동

마스터노드에서 아래 그림과 같이 명령어를 실행하여 비쥬얼라이저, 포테이너 서비스를 구동한다.

비쥬얼라이저라는 툴의 기능은 아래 그림과 같다. 비쥬얼라이저 서비스를 아래 명령어처럼 구동하고 웹브라우저에서 매니저또는워커노드 퍼블릭 URL:8081으로 접속하면 확인할 수 있다.

17

마찬가지로 웹브라우저에서 매니저또는워커노드 퍼블릭 URL:9000으로 접속하여 포테이너의 기능들을 확인해본다. 포테이너는 스웜클러스터에서 각각의 스텍, 서비스, 컨테이너, 컨테이너 네트워크 등을 관리하는 매니지먼트 툴이라고 할 수 있다. 여러 노드로 이루어진 클러스터의 전체적인 현황을 파악함으로써 중앙집중적으로 관리할 수 있게 도와준다.

  • Portainer 개요

1) Docker swarm management tool

2) 명령어 대신 UI를 통해 Docker service, network, stack 등 Swarm manager node 역할 수행

3) Swarm 내 운영 중인 Container log, metric monitoring 및 ssh shell 접속 기능

4) Swarm cluster 내 node 별 Container 관리를 수행해야 하는 경우 Portainer agent를 설치/운영해야 함

재미있는 기능은 예를들어서 아래 그림중에 메뉴에서 containers에서 web이라는 서비스를 검색했을때 나오는 컨테이너들 목록에서 원하는 특정 컨테이너의 쉘로 접속이 가능하도록 GUI로 제공해준다.

35

41

사실 이런식으로 포테이너를 띄우면 실제로는 모니터링이 잘 안될것이다. 일반적으로는 여러노드들을 한방에 관리하기 위해서 main container와 agent를 제공하는것이 일반적이다. 에이전트가 각노드에 뿌려져서 거기서 정보를 가지고와서 사용하는 것이 보통의 경우다.

에이전트는 그래서 한대의 머신에서 두대이상 필요가 없다. 그냥 딱 하나만 있으면 된다. 이때 사용할 수 있는 명령어 옵션이 global mode이다. 포테이너라는 매니저 컨테이너가 스웜매니저 노드에 띄워져 있고, 에이전트 컨테이너가 각 노드에 1개씩 뿌려져 있는 것이다.

이 에이전트도 권한에 따라 컨테이너를 접근/수정 할 수 있기 때문에, 접근권한 관리를 경우에 따라 잘해줘야 한다. 사용자별로 권한부여를 잘 해줘야한다. 이런 매니지먼트 툴들은.

  • Docker swarm stack이란

1) 여러 개의 Docker service를 관리하기 위해 docker-compose를 사용하여 관리하는 단위

2) .yaml/.yml(ex. docker-compose.yaml)로 Source code로 docker service를 구성함으로써 실수를 줄이거나 확장성에 용이하도록 사용할 수 있음

도커스웜에 도커스택은 여러개의 도커서비스를 관리하기 위한 도커 compose를 사용해서 관리하는 단위다. yaml 파일 또는 yml 파일을 만들어서 소스코드를 베이스로 컨테이너 as a code를 구현할 수 있다. 그래서 위에서 했던것처럼 명령어를 일일히 치는것이 아니라 yaml로 코드를 짠다음에 이 yaml을 내 클러스터에서 실행할 것이다. 실행하게 되면 여러개의 서비스가 쭉 구동되는 것을 확인할 수 있다.

step 8) 현재까지 구동한 모든 도커서비스 삭제

마스터노드에서 아래 그림과 같이 지금까지 구동하였던 도커 서비스들의 목록을 확인하고, 모두 삭제해준다.

42

step 9) docker-compose.yaml 을 이용한 도커스텍 구동

마스터노드에서 스텝8에서 삭제했던 도커 서비스들을 아래 그림과 같은 명령어를 실행하여 docker-compose.yaml로 다시 띄워보자

docker-compose.yaml 파일을 다운받아서 docker stack deploy 명령어를 통해서 docker-compose.yaml을 참조해서 도커 스텍을 구동한 것이다.

43

실행한 docker-compose.yaml 의 내용은 아래 그림과 같다.

바로 아래 그림에서 version : "3.7"은 도커 compose의 버전을 의미한다. 도커 compose의 버전에 따라 쓸 수 있는 기능이 약간씩 다르다.

volums : 컨테이너의 데몬.sock이 매니저노드의 docker 데몬을 사용하기 위해서 mount를 해주는 것. 컨테이너의 볼륨과 호스트의 볼륨을 물려주는것

constraints : 노드.role은 매니저노드에만 배치시키라는 옵션

restart_policy : 특정 서비스에 들어있는 컨테이너가 컨디션이 어떨때 재시작을 해줄것이냐를 설정

43-2

그런 다음에 아래 그림과 같이 명령어들을 실행하여 스텍이 잘 생성되었는지 확인한다.

참고로 여기까지 수행을 하면 웹서비스는 뜨지는 않을것이다.

45

docker-compose는 단일노드에서 컨테이너간의 연계나 컨테이너를 어떻게 띄울것이냐를 결정해서 실행할 수 있는 파일이었다. docker swarm에서는 docker-compose라는 툴을 이용해서 여러노드에서 컨테이너를 어떻게 배포하고, 배치하고 컨테이너 간의 연계는 어떻게 시킬것인지 등을 기술할 수 있다.

step 10) docker-compose.yaml 에 API 서비스를 추가해서 도커스텍을 재구동

  • docker-compose.yaml 수정사항

1) 해당 file에 api service를 구성하기 위한 source code 작성 (api-service는 external이 아닌 internal network에 위치)

2) 기존 web-service에 구성되던 docker image 업데이트(nginx reverse proxy, api 요청 URL이 들어온다면 http://api(api-service-name):8080으로 요청 전달하는 web:0.2로 업데이트 후 web service(현 stack에선fastcampus-web) update 진행

3) Etc…

그래서 먼저 마스터노드에 docker-compose.yaml가 설치된 곳으로 이동해서 vim docker-compose.yaml 명령어를 실행한다.

그 다음에 아래 그림과 같이 yaml 파일에 내용을 추가해준다.

46

step 11) ELK 스텍 정보가 들어있는 도커 컴포즈파일을 찾아서 다운을 받고 deploy를 해보자

매니저노드든 워커 노드든 git이 없기 때문에 먼저 깃을 설치하고, elk-stack 관련 파일을 특정 깃 레포에서 다운받아서 아래 그림과 같은 명령어를 이용해서 deploy를 해본다.

docker stack deploy -c elk/elk-stack.yaml elk 명령어까지 실행하고 나면 docker service ls | grep elk를 검색하면 elk 스텍에 들어있는 일라스틱, 키바나, 로그스테시 정보가 나오는데 이게 처음에 띄울때는 무겁기 때문에 시간이 오래걸릴것이다. elk가 전부 띄워지는게 완료되는 것을 확인하면 docker stack deploy -c beats/beat-stack.yaml beats 명령어를 실행해서 beats 스텍을 실행해주면 된다.

명령어 실행은 전부 마스터 노드에서 진행한다.

47

아래 그림과 같이 키바나에 접속해서 로그와 메트릭을 볼 수 있는 대시보드를 확인할 수 있고, 여기에 index 패턴을 생성해서 또 데이터를 볼 수 있다.

55