🎉 berenickt 블로그에 온 걸 환영합니다. 🎉
DevOps
Docker
10-Orchestration(조율)

1. 태스크, 서비스, 클러스터 개념정리

배포같은거 어떻게 하냐고 물어보시는데, 이미 여러분들 컴퓨터에서 서버가 잘 돌아가고 있기 때문에,

  • 다른 사람들이 “내아이피주소:8080”으로 들어가면 여러분들 서버를 만날 수 있습니다.
  • 근데 컴퓨터를 24시간 켜두기도 그렇고 개인 고객이면 IP주소도 자주 바뀌기 때문에,
  • AWS 이런 곳에서 컴퓨터를 빌려서 거기에 서버를 띄워놓는게 안정적입니다.

그래서 1. 환경셋팅하고 2. 코드짜고 3. 실행하고 그런 작업을

  • AWS에서 컴퓨터를 하나 빌려서 동일하게 하면 배포 끝입니다.
  • 하지만 직접 하는건 매우 귀찮기 때문에,
    • 내 코드를 이미지로 만들어서 AWS 컴퓨터로 보내 실행만 해두는 식으로 배포하면 편리할 수 있습니다.

1.1 마이크로서비스 등장

이미지로 배포하면 배포과정이 매우 쉬워집니다. 이미지 다운 받아서 실행누르면 끝이니까요. 근데 몸이 편해지면 사람들이 슬슬 이상한 짓을 하기 시작합니다.

docker_10-1

서버의 여러 기능들을 하나의 프로그램에 넣는게 아니라, 기능마다 별도의 프로그램으로 만들고 각각 따로 배포해버리기 시작했습니다. 그리고 각 서버는 필요할 때만 서로 통신하도록 설정합니다. 이런 방식을 마이크로서비스 아키텍처(MSA)라고 부릅니다.

그러다보니 컨테이너 수가 많아지고, 이걸 관리하기 위해서 container orchestration(조율; 오케스트레이션) 툴을 사용하는 경우가 늘어나고 있습니다.

  • 그래서 우리도 그걸 맛보도록 합시다.
  • 솔직히 컨테이너가 몇 개 없을 때는 별로 필요없는데,
    • 내 몸값에 거품을 만들고 싶다면 남들이 어려워하는 기술을 일부러라도 써보는게 좋습니다.

1.2 컨테이너 orchestration tool

orchestration 툴은 쿠버네티스가 가장 유명합니다. 직접 여러분이 컴퓨터에 설치해서 운영하고 그래도 되긴 하는데, 사이즈가 커지면 관리형 쿠버네티스 서비스를 쓰는 경우들이 많습니다.

docker_10-2

▲ 이런 상품들이 있는데 직접 셋팅하는 것 보다 편하게 쿠버네티스를 사용할 수 있습니다. 근데 이런 것도 입문하려면 새로 배울게 좀 많기 때문에, 훨씬 쉽고 간단한데 기능은 비슷한 ECS를 써서 입문해보도록 합시다. AWS에서 만든 orchestration 툴입니다.


1.3 실은 저런거 안써도 세상이 좋아짐

니면 서버를 만들고 있다면 그걸 더 쉽게 배포할 수 있는 방법이 요즘은 많습니다.

  • 이미지나 코드를 쉽게 배포해주는 상품 (Google cloud app engine, Google cloud run, AWS Elastic beanstalk)
  • 쿠버네티스를 쓰고 싶은데 관리하기 싫으면 쓰는 상품 (GKE autopilot)
  • AWS ECS를 쓰는데 명령어 한두개만으로 ECS에 배포해주는 툴 (AWS Copilot)
  • 아니면 배포를 더 쉽게 만들어주는 Fly.io, Heroku, Vercel같은 서비스도 나와있습니다.
    • 다만 한국 리전은 없는 경우도 있음

cf. Fly.io 같은 서비스는 이미지를 올리면 이미지를 해체해서 Firecracker같은 VM에 올려서 서비스합니다.

  • 왜냐면 컨테이너들은 같은 커널을 공유하기 때문에 보안이슈가 있을 수 있는데,
  • 그걸 원천차단하기 위해서 가벼운 VM을 쓰는 건데 그럴 수도 있다는걸 참고합시다.

1.4 서버를 만들었다고 가정해보자

실제 상황부터 한번 가정해봅시다. 마이크로서비스가 좋다니까 여러분이 1. 회원서버 2. 게시판서버를 개발해놓은겁니다. 이 마이크로서비스들을 배포하고 싶으면 어떻게 하냐면, 컴퓨터 2개 빌려서 각각 띄워둬도 되는데 우리는 AWS에 있는 ECS를 써볼겁니다. 그걸 쓰면 어떤 식으로 하냐면…

docker_10-3

▲ 클러스터 안에 서비스 안에 태스크 안에 컨테이너들을 띄웁니다.

  • 클러스터하나의 프로젝트
  • 서비스하나의 마이크로서비스 (e.g. 회원기능, 결제기능, 쇼핑기능, 댓글기능)
  • 태스크서로 붙어있어야할 컨테이너들을 묶는 단위입니다.

그래서 지금 우리는 마이크로서비스가 2개 있으니까 서비스를 2개 만들고,

  • 서비스마다 필요한 nginx, 웹서버, DB 이미지들을 태스크 안에 감싸서 띄우면 되는겁니다.
  • 태스크는 비유하자면 그냥 docker compose와 비슷한거라고 생각하면 되겠습니다.
  • cf. 태스크는 원하는 만큼 복제가 매우 쉽습니다.

docker_10-4

클러스터를 만들 때 컴퓨터를 몇대 빌릴지 예약할 수 있습니다.

  • 그래서 빌린 컴퓨터마다 태스크들을 퍼트려놓는 것도 가능합니다.
  • 그럼 컴퓨터 하나가 맛이가도 안전하겠군요.
  • 그리고 볼륨장착, 컨테이너간 통신, 서비스간 통신 이런 것도 당연히 가능합니다.

docker_10-5

▲ 근데 생각해보면 서비스라는 부분은 필요없을 것 같지 않습니까? 실은 그렇긴 합니다. 그래서 서비스 생략하고 태스크만 띄울 수도 있긴 한데, 서비스가 있으면

  • 태스크를 쉽게 복제해주고
  • 고장난 태스크는 새걸로 갈아치워주고
  • 다른 서비스끼리 통신하고

이런게 쉬워져서 사용하는 레이어라고 보면 되겠습니다.

cf. 쿠버네티스도 이거랑 비슷하게 동작하는데 직접 컨트롤할 수 있는게 더 많을 뿐입니다.


1.5 치킨집으로 비유하면

비유좋아하면 간단하게 치킨집으로 비유좀 해봅시다. 내가 치킨 밀키트를 만들었는데 그걸 고객들에게 맛을 보여주고 싶으면 어떻게 하겠습니까.

docker_10-6

▲ 치킨집 가맹본부 만들고 체인점을 만들고 그 안에서 치킨 밀키트를 조리하면 되겠습니다. 이번엔 피자 밀키트를 만들었으면, 피자집 가맹본부 만들고 체인점을 만들고 그 안에서 피자 밀키트를 조리하면 되겠습니다.

가맹본부에선

  • 체인점을 여러개 띄우고
  • 필요없는 체인점은 줄이고
  • 가맹본부끼리 콜라보하고

그런 행위가 가능합니다.


1.6 load balancer

근데 이런거 쓰다보면 자주 필요한게 하나 있습니다. 로드밸런서라는 것인데 잠깐 설명하고 지나갑시다. 위에서 설명한 환경에선 서버를 복제해두고 싶으면 태스크를 복제해두면 됩니다. 근데 그러면 유저가 서버로 접속하고 싶을 때 대체 몇번째 태스크로 접속해야하는지 모르지 않습니까. 그럴 때 로드밸런서를 앞에 붙일 수 있습니다.

docker_10-7

로드밸런서는 그냥 간단한 프로그램인데,

  • 유저가 나한테 들어왔을 때 내 뒤에 있는 컴퓨터나 태스크들에 균등하게 안내해주는 역할을 하는 프로그램입니다.
  • e.g. nginx도 “누가 나에게 들어오면 뒤에 있는 여러 웹서버 중에 하나로 안내해주세요” 라고 코드짜놓을 수 있어서,
    • 로드밸런서같은 짓을 할 수 있습니다.

특히 컨테이너들이 서버리스 형태로 자원을 사용하는 경우에도 로드밸런서가 필요하게 될텐데,

  • 그래서 로드밸런서 프로그램을 하나 만들어두고, 아무나 접속가능하게 만들고
  • 누가 로드밸런서에 들어오면 서비스나 태스크를 가리키게 하면 이제 유저가 서버들로 접속할 수 있게 됩니다.
  • 그래서 그것도 나중에 하나 만들어봅시다.

1.7 장단점

마이크로 서비스 형식으로 설계를 해두면 장점이 뭘까요.

  • 유저가 많이 몰리는 그런 서비스가 있으면 그것만 딱 찝어서 CPU 사용량 늘리고 그럴 수 있어서 자원 사용이 효율적임
  • 회원기능을 수정했으면 회원기능 서비스만 따로 배포하면 되니까 기능 업데이트도 매우 빨라짐

그래서 이딴 짓을 하는 겁니다.

단점은 뭐게요?

  • 마이크로 서비스끼리 통신해야하면 그게 좀 귀찮아짐
  • 마이크로 서비스가 많아지면 그걸 관리하는데 시간과 인력이 추가로 필요함
  • 서버비도 초반엔 비쌈

그래서 처음부터 모든걸 마이크로 서비스로 만드는 것 보다는

  • 기존처럼 한 프로그램에 모든걸 넣어서 개발하다가 기능이 너무 크고 비대해지는 부분이 있으면,
  • 그걸 마이크로 서비스로 슬쩍 빼보면서 시작하는게 좋은 관습입니다.

1.8 실제로 올려보기 전에 셋팅할게 있음

그래서 AWS ECS에 웹서버, nginx 만든걸 띄워볼 것인데 그 전에 셋팅할게 있습니다.

(1) 이미지들을 리포지토리에 미리 올려둡시다.

AWS ECR이라는곳도 있는데 docker hub 공짜니까 거기 퍼블릭 리포지토리에 올려둡시다. 어딘가에 올려둬야 쉽게 가져다가 배포할 수 있으니까요.

(2) 태스크 안에 있는 컨테이너들은 서로 http://localhost:포트로 통신해야합니다.

그래서 nginx가 웹서버 컨테이너를 부를 때 localhost:8080이런 식으로 부르도록 수정해봅시다.

1
server {
2
listen 80;
3
location / {
4
proxy_pass http://localhost:8080;
5
proxy_set_header Host $host;
6
proxy_set_header X-Real-IP $remote_addr;
7
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
8
proxy_set_header X-Forwarded-Proto $scheme;
9
}
10
}

웹서버는 8080번 포트에 띄워놨기 때문에,

  • 웹서버 부르려면 http://localhost:8080 이런 식으로 주소를 입력해야합니다.
  • 그래서 참고로 같은 태스크 안에 있는 컨테이너끼리 포트 번호가 겹치고 그러면 안됩니다.
  • 나중에 다른 서비스에 있는 태스크를 부르려면 localhost:8080 자리에 다른 서비스 이름을 적으면 됩니다.

아무튼 nginx, 웹서버 이미지들 빌드하고 docker hub에 올려놓읍시다.


2. 태스크 정의, health check

저번시간에 nginx랑 웹서버 이미지 2개를 Docker hub에 올려놓으라고했는데 그 상태에서 시작해보도록 합시다. 그리고 AWS 사이트 가입하고 카드등록까지 해옵시다.

docker_10-8

▲ AWS 사이트 방문하면 우측 상단에 지역을 선택할 수 있는데, 서울에서 서비스할거면 서울 고르고 검색창에서 ECS 검색해서 들어갑시다.


2.1 EC2 vs Fargate

컨테이너 띄우려면 1. 클러스터 만들고 2. 서비스 만들고 3. 태스크 만들면 됩니다.

  • 그래서 ECS 검색해서 들어가서 클러스터 생성부터 눌러봅시다.
  • 클러스터는 프로젝트 하나라고 생각하면 되는데,
  • 근데 정확하는 내가 컴퓨터를 몇대나 미리 점유할건지 정하려고 클러스터를 만드는겁니다.

docker_10-9

▲ 클러스터 하나 생성하려면 인프라부터 고르라고 되어있을 겁니다.

  • EC2는 컴퓨터를 직접 빌릴 수 있는 상품이고,
  • Fargate는 서버리스 형태로 CPU, RAM을 필요할 때만 꺼내쓰는 방식입니다.

docker_10-10

▲ 그래서 EC2를 고르면 컴퓨터를 원하는 용량과 갯수로 빌릴 수 있습니다. AWS 처음 카드등록하면 t2.micro 또는 t3.micro 라는 똥컴하나 1년무료 이용권주는데 그걸 쓸 수도 있습니다.

💡 cf. 이미지 만들 때 사용했던 CPU 아키텍쳐와 같은 컴퓨터를 빌려야 잘돌아갑니다.

  • 대부분 AMD64 (일명 x86-64) 라는 CPU 아키텍처로 만들었을거라 그게 표기된 컴퓨터를 빌려야합니다.
  • 드물게 ARM64로 이미지를 빌드했으면 그게 표기된 컴퓨터를 빌려서 씁시다.

근데 Fargate라는 옵션을 쓰면 컴퓨터를 미리 점유하는게 아니라, 여러분이 필요할 때 마다 컴퓨터자원을 마법처럼 끌어다가 쓸 수 있습니다.

  • EC2보다 요금이 20% 정도 더 비싸지만 편하니까 이걸 씁시다.
  • 서비스 만들어보고 바로 지우면 요금도 몇백원 나올까말까 하니까, 그냥 까까 사먹을 돈으로 이런거 경험해보도록 합시다.

아무튼 다른건 딱히 건드릴 필요 없고 클러스터 이름 아무거나 잘 지어서 생성이나 해봅시다.


2.2 태스크 정의 (task definition)

클러스터 → 서비스 → 태스크를 띄운다고 했는데, 참고로 서비스 없이 클러스터 → 태스크만 띄울 수도 있습니다. 1회성 작업같은걸 하는 이미지 띄울 때는 그래도 상관없음.

근데 지속적으로 안정적으로 실행되어야하는 이미지는 서비스 안에 넣는게 좋습니다. 왜냐면 서비스 안에 태스크를 넣으면, 하나가 망가졌을 때 자동으로 새로운 태스크로 갈아치우는 기능, 중단없이 태스크를 업데이트할 수 있는 기능 같은게 있어서 그렇습니다.

docker_10-11

▲ 아무튼 클러스터 안에서 서비스, 태스크를 실행할 수 있는데, 그 전에 태스크 정의라는게 있어야 서비스나 태스크를 실행할 수 있습니다. 어딘가에 있는 태스크 정의 만드는 버튼을 눌러봅시다.

태스크 정의는 태스크를 어떻게 띄울지 정의하는 파일입니다. “무슨 이미지들을 어떤 포트에 어떤 환경변수를 넣어서 띄울지” 쭉 작성하는 파일일 뿐이고, 실은 docker compose 파일이랑 똑같습니다. 하지만 ECS 문법에 따라 .json 형식으로 작성해야할 뿐인데, .json 그딴거 모르겠으면 웹페이지에서 클릭질로 작성할 수 있게 되어있습니다.

docker_10-12

▲ 태스크 정의 만들기 누르면 일단 인프라를 또 고르게 합니다. 클러스터에서 예약해놨던 컴퓨터를 태스크 1개가 얼마나 점유할 것인지 정하는 부분입니다. 그래서 이 태스크가 얼마의 CPU, 메모리가 필요한지 정하면 되겠습니다.

사진에선 CPU 1개, 메모리 2GB를 골라봤는데, 이 태스크 안에 컨테이너가 여러개 있을 예정이면 CPU 1개, 메모리 2GB를 컨테이너간 나눠써야합니다. 나중에 변경 가능하니까 대충합시다.


2.3 태스크 정의 안에 컨테이너 작성하기

docker_10-13

▲ 태스크 정의 안엔 컨테이너를 어떻게 띄울지 작성할 수 있습니다.

  • 우리는 nginx, 웹서버를 띄울 것이기 때문에 2개 띄운다고 작성하면 됩니다.
  • 일단 첫 컨테이너엔 웹서버 컨테이너 띄운다고 이름이랑 이미지 다운받을 수 있는 경로를 작성해봤습니다.
  • docker hub에 올려놨을 경우엔 docker.io/내아이디/리포지토리명:태그명 입력하면 됩니다.
  • 사진처럼 포트도 설정할 수 있습니다.
  • 근데 웹서버는 nginx에서 접속할거라 포트를 연결할 필요는 없어보여서 지워도 될듯 하군요.

docker_10-14

▲ 컨테이너마다 CPU, 메모리를 얼마나 할당할 것인지 정할 수 있습니다.

  • 아까 저는 태스크에 CPU 1개, 메모리 2GB를 할당했는데,
  • 그 안에서 nginx, 웹서버는 각각 얼마의 CPU, 메모리를 점유할지 맘대로 결정하면 됩니다.

메모리 제한도 설정할 수 있는데 soft limit은 메모리를 얼마나 미리 최소로 선점할지,

  • hard limit은 최댓값입니다.
  • hard limit 설정하면 그걸 도달하는 경우 컨테이너가 강제종료 될텐데 아마 비워도 상관없음
  • nodejs 서버의 경우에는 최소 메모리 1GB는 주는게 좋습니다.
  • 나중에 테스트해보면서 늘리거나 줄이거나 해도 됩니다.

이외에 환경변수, 로깅옵션 이런건 필요할 때 사용합시다. 처음엔 에러났을 때 상세히 볼게 필요하기 때문에 로깅하라고 해놓는게 좋습니다.


2.4 상태확인 (healthcheck)

새로운 개념 하나만 배우고 갑시다. 내 nodejs 웹서버 컨테이너가 잘 떠있는지 확인하고 싶으면 어떻게 하죠? 웹브라우저 켜서 들어가보면 되겠지만 포트 연결을 안해놨으면 그건 좀 어려울 수 있습니다. 가장 쉬운 방법은 nodejs 웹서버 컨테이너에 접속해서 localhost:8080으로 들어가보면 됩니다. 터미널로 들어갈 수 있으니까 아마 curl localhost:8080 이런거 쳐보면 알 수 있겠군요.

근데 그 작업을 자동화해줄 수도 있습니다.

  • 자동으로 니가 알아서 5초마다 curl localhost:8080 쳐보라고 할 수 있는데,
  • 그걸 멋있는 말로 healthcheck라고 합니다.

docker_10-15

▲ 그래서 여기에 터미널 명령어를 적으면 그걸 얘가 컨테이너 안에서 자동으로 X초마다 실행해줍니다. 일종의 컨테이너 모니터링 방법이라고 생각하면 되겠습니다.

1
CMD-SHELL, curl -f http://localhost:8080 || exit 1

그냥 기본적으로 이거 채우고 시작하면 되는데, CMD-SHELL 이건 bash같은 기본적인 쉘을 쓰라는 것이고

  • 그 오른쪽에 명령어 입력하면 되는데 대부분 curl 이런거 쓰면 됩니다.
  • 그리고 curl 요청이 실패하면 exit 1 하라고 코드짜면 되는데,
    • exit 1 이런게 헬스체크를 실패했다는 암구호같은 거라 써주면 됩니다.
  • 그리고 밑에 몇초마다 할건지 이런건 쭉 읽어보면서 알아서 적으면 됩니다.

2.5 curl 있나 확인하는 것도 좋음

근데 가끔 curl 이런 기본 프로그램이 설치 안되어있는 이미지나 OS가 있습니다.

  • e.g. node:20-slim 이런 것도 이미지에 curl이 설치안되어있을 수 있는데,
  • 그래서 이거 실행하기 전에 직접 컨테이너에 들어가서 curl 커맨드 잘 되나 확인해보는것도 좋습니다.

curl이 없으면

  • wget 그런거 찾아서 써도 되고
  • 이미지에 직접 curl 설치하라고 Dockerfile에 기재해도 되고
  • bash 정도는 있으면 bash 내장 기능중에 특정 페이지로 요청해주는 그런 비밀기능이 있어서 그거 써도 됩니다.
1
timeout 10s bash -c ': > /dev/tcp/localhost/8080' || exit 1

▲ bash에서 /dev/tcp/localhost/8080 이런식으로 적으면, 신기하게도 localhost:8080에 TCP 요청을 날려줍니다. TCP 요청은 그냥 접속해본다는 뜻이고, 이미지에 bash가 있으면 이걸 써서 헬스체크 하셔도 됩니다.

근데 그냥 /dev/tcp/localhost/8080 이렇게 입력만 하면 그 디렉터리 열라는 뜻이 될 수 있어서

  • 그걸 방지하려고 : > 이런 이상한 기호도 쓰면 됩니다.
  • : 이건 텅빈 값이라는 뜻이고
  • >이건 왼쪽 값을 오른쪽에 작성하라는 뜻입니다.

그래서 텅빈 값을 그 경로에 넣으라고 의미없는 명령어를 추가해준 것인데 그래야 잘동작합니다.


2.6 nginx 컨테이너도 띄우기

docker_10-16

▲ 웹서버 컨테이너 말고 nginx 컨테이너도 띄워야하니까 컨테이너 하나 추가해서 잘 입력해봅시다. 컨테이너 이름, URI, 포트는 80:80, CPU와 메모리 적절히, healthcheck는 기본명령어 이런거 설정하는 것 말고는 딱히 건드릴게 없으니 알아서 남자답게 채워봅시다.

아무튼 다 됐으면 태스크 정의 생성 눌러보면 되겠습니다. 이제 클러스터 들어가서 서비스 생성 누르고 태스크 골라서 띄우면 되는데 그건 다음에 해보도록 합시다.


3. 서비스 만들기

저번 시간에 태스크 정의를 만들어봤는데 태스크 정의는 docker compose 파일이라고 했습니다. 그래서 그 파일이 있으면 서비스와 태스크를 띄울 수 있습니다. 클러스터 안에 들어가서 서비스 생성을 눌러봅시다.


3.1 서비스 시작유형

서비스 생성을 누르면 우선 컴퓨팅 옵션을 정하라고 합니다. 이게 뭐냐면 어떤 컴퓨터에 태스크들을 띄울지 정하는 부분입니다.

docker_10-17

  • ‘용량공급자 전략’ 이런거 고르면 EC2, Fargate에 태스크를 분산해서 띄울 수 있습니다.
  • ‘시작 유형’ 고르면 대충 한 곳에서 태스크를 띄워줍니다.
  • 우리는 그냥 맨 처음에 Fargate하나만 쓴다고 해놨으니까 그냥 ‘시작 유형’ 이런거 골라서 Fargate 쓴다고 합시다.

💡 cf. 스팟 인스턴스 이런건 뭐냐면 이건 남들이 안쓰는 EC2또는 Fargate 컴퓨터를 잠깐 빌려쓰는겁니다.

  • 보통 70%더 저렴해서 좋은데 근데 원래 주인이 회수해가면 갑자기 컨테이너가 정지되고 그럴 위험성이 항상 있어서
  • 1회성 작업같은거 할 때나 고려해봅시다.

3.2 배포구성

docker_10-18

▲ 여기는 서비스에 어떤 태스크를 실행할지 태스크 정의 파일을 고르는 부분입니다. 만들어둔 태스크 정의 파일을 골라줍시다. ‘개정’은 태스크 정의 파일의 버전입니다.

docker_10-19

▲ 서비스 안에 태스크를 몇개 복제해둘건지 선택도 가능합니다.

  • 가용영역 리밸런싱은 태스크가 여러개 있는 경우
  • 태스크를 서울 뿐만 아니라 오사카, 도쿄 등 가까운 리전에 골고루 뿌려두는 짓입니다.
  • 그럼 하나가 다운되어도 안정적으로 서비스가 가능한데 우리는 필요없겠군요.

docker_10-20

▲ 배포옵션은 그냥 업데이트 옵션입니다.

  • 나중에 태스크 내용이 업데이트가 되어야하면 기존 태스크를 끄고 새로 띄워야하지 않겠습니까
  • 그래서 그 방법을 고르는 부분입니다.

docker_10-21

롤링업데이트는 업데이트된 태스크들을 추가로 더 띄우고, 그 다음에 기존 태스크를 차례로 종료시키는 방식입니다.

  • 최댓값 설정도 가능한데 최댓값을 200%으로 설정한 경우에는
  • 지금 3개 태스크가 실행중이면 3개를 또 띄워서 총 6개를 띄워둔 후에 옛날 컨테이너들을 하나씩 끄는 식으로 동작하라는 뜻입니다.
  • 간편한데 유저들이 이전 태스크와 새로운 태스크로 골고루 안내되는 상황이 발생할 수 있습니다.

docker_10-22

블루그린은 업데이트된 태스크들을 띄운 다음에 거기로 모든 트래픽을 갑자기 바꿔버리는 식으로 동작합니다. 그래서 한 번에 모든 트래픽을 새로운 컨테이너로 안내할 수 있는게 장점입니다. 저는 롤링 업데이트로 골랐습니다.

docker_10-23

▲ Service Connect라는 것도 설정도 할 수 있는데,

  • 서비스가 많아지면 서비스끼리 이름을 잘 지어놔야 서로 통신을 할 수 있어서 이름 지어주는 옵션입니다.
  • 다른 서비스에 연결만 할거면 “클라이언트” 고르고,
    • 다른 서비스가 나를 찾는 상황도 필요하면 “서버” 뭐시기 고르면 됩니다.
  • 나중에 필요하면 설정해봅시다.

3.3 VPC

AWS에서 서비스할 때 항상 VPC 이런걸 고르라고 하는데, 기본으로 선택되어있는거 일단 사용하면 됩니다. VPC가상 네트워크입니다.

docker_10-24

VPC(가상 네트워크) 안에 subnet이라는걸 마음대로 만들어서 내 서비스나 컴퓨터를 보관하고 그럴 수 있습니다.

  • subnet은 그냥 폴더같은 것인데 비유하자면, 도커에서 쓰던 네트워크랑 비슷한 개념입니다.
  • subnet 안에 있는 컴퓨터들은 서로 쉽게 통신이 가능합니다.

일반 사람들도 접속이 가능해야하면 public subnet을 만들어서 거기 넣어두고, 일반 사람들이 접속하면 안되는 그런 컨테이너들은 private subnet 만들어서 거기 넣어두면 되고, 나중에 어떤 subnet끼리 서로 통신할 수 있는지 제한도 해놓으면 안전하게 사용할 수 있는데, 그건 보안그룹이라는걸 만지면 설정할 수 있습니다.

그래서 우리가 만드는 서비스가 속할 보안그룹도 새로 만들어주면 좋은데, 이건 로드밸런서 만들고나서 조금 있다가 해봅시다.


3.4 public IP 할당

태스크마다 퍼블릭 IP주소를 부여할지 선택해야하는데, 퍼블릭 IP주소가 있으면 손쉽게 외부랑 통신이 가능합니다.

docker_10-25

▲ 그래서 퍼블릭 IP가 있어야 외부에 올려둔 이미지도 받아올 수 있어서 퍼블릭 IP를 할당해줍시다.

  • 이걸 안해두면 여러분이 직접 인터넷 게이트웨이 이런걸 귀찮게 설정해줘야 외부통신이 가능해지고,
  • 도커 이미지도 외부에서 받아올 수 있습니다.
  • 그래서 Fargate 쓰면 일단 체크하고 갑시다.

근데 이거 체크하면 태스크마다 월 4달러인가 요금이 나올 수 있는데,

  • 왜냐면 AWS가 최근에 퍼블릭 IPv4 주소를 사용하면, 하나 쓸 때마다 월 4달러인가 요금을 추가하기 시작했습니다.
  • 그래서 그 대안으로 IPv6 주소는 무료니까 그거 쓰라고 하는데,
    • AWS안에서 IPv6 주소는 쓸수 있는 곳이 거의 없습니다.
    • 쓰레기같은 정책입니다.

이걸 체크 안할거면 도커 이미지를 AWS ECR이라는 곳에다가 올려서, VPC 엔드포인트 링크인가를 써서 가져오면 됩니다. 나중에 한번 해봅시다.


3.5 load balancer 만들기

로드밸런서는 유저가 나에게 들어왔을 때, 내 뒤에 있는 서버들에 균등하게 안내해주는 역할을 하는 프로그램일 뿐입니다.

이걸 왜 만드냐면

  1. 일단 Fargate를 쓰면 컴퓨터 형체가 없습니다.
    • 그래서 외부 사람들이 그 태스크 돌아가는 컴퓨터로 접속을 하려면 로드밸런서가 강제로 필요
  2. 태스크 여러개에다가 고르게 트래픽을 분산시키려면 로드밸런서가 필요함
    • 그래서 지금처럼 외부인들이 접속해야되는 그런 서비스는 기본적으로 로드밸런서 하나 붙여주는게 낫습니다.

실은 컴퓨터 하나 빌려서 nginx로 직접 만들어도 되고,

  • 아니면 nginx대신 좀 더 클라우드환경에 적합한 Traefik같은 프로그램으로 만들어도 되고,
  • 근데 여기선 서비스 띄울 때 로드밸런서를 바로 만들고 장착할 수 있게 되어있어서 그렇게 만들어봅시다.
  • cf. 로드밸런서는 별도로 요금이 발생합니다.

docker_10-26

▲ Application load balancer 만들면 됩니다. 어떤 컨테이너가 로드밸런서에서 오는 트래픽을 수신할지 정할 수 있습니다.

docker_10-27

▲ 로드밸런서는 어떤 포트를 오픈할지도 정할 수 있습니다. 일단 80 넣어줍시다.

  • 대상 그룹이 중요한데 로드밸런서로 들어오는 트래픽의 목적지를 정해주는 부분입니다.
  • 그래서 “내가 지금 만드는 서비스”를 대상그룹으로 설정하면 되는데
  • 근데 여기서 만들면 자동으로 채워지기 때문에 신경안쓰고 넘어가도 됩니다.

3.6 보안 그룹 (security group)

AWS에서 컴퓨터를 빌리거나 서비스를 만들거나 그럴 때, 항상 보안그룹을 잘 설정해둬야 안전하게 운영이 가능합니다. 보안그룹은 누가 내 서비스나 컴퓨터에 접속할 수 있는지 정의해놓는 규칙입니다.

  • 로드밸런서는 “인터넷상의 일반인 아무나 내 80번 포트로 접속가능”
  • 서비스는 “로드밸런서만 접속가능” 이런 식으로 보안그룹을 각각 만들어두면 안전하겠죠?

근데 로드밸런서를 서비스랑 같이 만들어버리면 보안그룹을 따로 만들 수 없고 합쳐서 만들 수 밖에 없습니다. 그래서 안전하게 쓰려면 나중에 로드밸런서를 별도로 만들어와서 목적지를 서비스로 안내하고 그런 식으로 해보시고, 지금은 그냥 위에 있는 보안그룹이나 설정하러 가봅시다.

docker_10-28

▲ VPC 메뉴에서 보안그룹을 만지면 서비스 + 로드밸런서의 보안그룹을 동시에 설정할 수 있습니다.

  • 위 처럼 작성하면 80번 포트로 아무 아이피에서나 접속가능하다는 뜻입니다.
  • 0.0.0.0/0 이게 아무 아이피라는 뜻임
  • 그럼 앞으로 로드밸런서도메인주소:80 이걸 브라우저에 입력하면 개나소나 들어올 수 있게 됩니다.
  • 일반 유저들도 들어올 수 있겠군요.

그럼 아무튼 서비스 생성을 눌러봅시다. 로드밸런서 때문에 5분 넘게 소요될텐데 아무튼 기다리면 서비스가 하나 생성이 되어있을겁니다.

docker_10-29

▲ 서비스로 들어가보면 어떤 태스크가 돌아가고 있는지 볼 수 있는데, 태스크가 파란색으로 5분넘게 “대기중” 이라고 뜨면 뭔가 문제가 있다는 뜻입니다. 그럴 땐 로그, 태스크 이런 메뉴 들어가서 이상한 메세지는 없는지 확인해보면 됩니다.

내 서비스에 접속하려면 로드밸런서에 접속해보면 되는데, 로드밸런서 찾아서 로드밸런서 DNS 주소를 가져와서 브라우저 주소창에 http://로드밸런서DNS주소 입력하면 됩니다. 그럼 서비스에서 돌아가고 있는 nginx와 웹서버 컨테이너를 잘 만날 수 있겠군요. 이제 로드밸런서에다가 HTTPS 인증서 설치하고 도메인 사서 연결하고 그러면 실제 웹서비스처럼 운영할 수 있겠군요.


3.7 서비스가 안떠요

  • 5분동안 계속 대기중 상태를 못벗어나면 로그, 태스크 등 들어가서 에러메세지는 없는지 확인해봅시다.
    • 이미지를 잘못 만들었거나, 이미지 다운로드를 못해왔거나, 보안그룹 설정이 이상하거나 그런 경우가 대부분임
  • nginx에서 웹서버를 못찾는건 아닌가 nginx 설정파일을 확인해봅시다.
  • CannotPullContainerError는 이미지 다운로드를 못했다는 뜻이라,
    • 서비스 생성시 네트워크 부분 설정에서 public IP 주소 할당을 켜봅시다.
  • 초록불은 떠서 실행중이라고 뜨는데 http://로드밸런서DNS주소.com으로 접속시 아무것도 안뜨면,
    • 로드밸런서의 “보안그룹” 들어가서 모든 아이피에서 80번 포트로 접속이 가능하도록 설정했나 확인합시다.
    • 모든 아이피를 표현하고 싶으면 0.0.0.0입니다.

3.8 태스크 업데이트는

  1. 코드짠걸 새로 빌드해서 이미지를 어딘가에 올리고
  2. 기존에 있던 태스크 정의를 수정해서 어떤 이미지를 사용할건지 기재하고
  3. 그 태스크로 기존 서비스 업데이트하라고 명령내리면 끝임

3.9 삭제는

서비스가 잘돌아가는거 확인했으면 요금나오니까 끕시다.

  • 서비스 삭제하고
  • 클러스터는 Fargate쓰는 경우 냅둬도 요금은 안나올텐데 불안하면 클러스터도 삭제하고
  • 로드밸런서도 생성해놨을텐데 그것도 삭제하려면 상단에 EC2 검색해서 들어가서 로드밸런서 메뉴에서 삭제하면 됩니다.