본문 바로가기
docker

traefik 리버스 프록시 로드밸런서

by misankim 2023. 3. 6.
traefik 리버스 프록시 로드밸런서



공식 문서

 

도커 이미지



haproxy와 유사하지만 웹 대시보드를 제공하고 컨테이너 레이블을 통해 로드밸런싱 대상 컨테이너를 자동으로 검색하는 기능이 있음
kubernetes 의 ingress 로도 사용 가능(ingress-nginx 와 같은 역할)



# traefik 컨테이너 실행
-> 정적 설정 파일 생성하여 컨테이너 실행

 

샘플 설정 파일 참고

 

mkdir -p /etc/traefik/dynamic_conf/
mkdir -p /etc/traefik/certs/

vim /etc/traefik/traefik.yml

 

entryPoints:
  web:
    address: :80

  websecure:
    address: :443

providers:
  docker:
    exposedByDefault: false
    defaultRule: "Host(`{{ trimPrefix `/` .Name }}.docker.localhost`)"
  file:
    directory: /etc/traefik/dynamic_conf
    watch: true

api:
  insecure: true

accessLog: true
 
traefik 컨테이너 실행
docker run -d -p 80:80 -p 443:443 -p 8080:8080 --name traefik \
-v /etc/traefik/:/etc/traefik/ \
-v /var/run/docker.sock:/var/run/docker.sock traefik:v2.5

 

대시보드 접속
http://docker_서버_아이피_주소:8080/

 

(참고) 보유하고 있는 ssl 인증서를 적용하고 싶은 경우
-> 동적 설정 파일에 tls 관련 설정 추가
-> 동적 설정 파일의 경우 traefik 컨테이너 재시작 없이도 바로 적용됨

 

vim /etc/traefik/dynamic_conf/dynamic.yml

 

tls:
  certificates:
    - certFile: /etc/traefik/certs/test.example.com.crt
      keyFile: /etc/traefik/certs/test.example.com.key

 

사설 인증서 생성
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/traefik/certs/test.example.com.key -out /etc/traefik/certs/test.example.com.crt -subj "/CN=test.example.com/O=test.example.com"

 

(참고) 사용 가능한 정적/동적 옵션 확인

 

정적 설정 옵션

 

동적 설정 옵션



(참고) docker-compose 파일

 

mkdir -p ~/compose/traefik/ && cd ~/compose/traefik/

vim docker-compose.yaml

 

version: '3'
services:
  traefik:
    image: traefik:v2.5
    container_name: traefik
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /etc/traefik/:/etc/traefik/
      - /var/run/docker.sock:/var/run/docker.sock



# 백엔드 컨테이너 실행 및 접속 테스트
-> 로드밸런싱 대상 컨테이너 생성 시 "traefik.enable=true" 레이블 추가 필수
-> defaultRule 설정 시 백엔드 컨테이너 생성 시 자동으로 "컨테이너_이름.docker.localhost" 호스트를 통해 접속 가능하도록 라우팅 구성됨
-> kubernetes 에서 자동으로 설정되는 dns 네임스페이스와 유사한 방식

 

## whoami 컨테이너

 

백엔드 컨테이너 실행
docker run -d -l "traefik.enable=true" --name test containous/whoami

 

접속 테스트
curl --header 'Host:test.docker.localhost' 'http://localhost:80/'

 

(참고) 접속 테스트 시 출력
[root@centos7 ~]# curl --header 'Host:test.docker.localhost' 'http://localhost:80/'
Hostname: d162bcc7d2fb
IP: 127.0.0.1
IP: 172.17.0.3
RemoteAddr: 172.17.0.2:36292
GET / HTTP/1.1
Host: test.docker.localhost
User-Agent: curl/7.29.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.17.0.1
X-Forwarded-Host: test.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 67f8996de91c
X-Real-Ip: 172.17.0.1

 

## apache 컨테이너
-> 로드밸런싱 대상 컨테이너가 다른 docker 네트워크에 속하는 경우 반드시 traefik 컨테이너에 해당 네트워크를 연결해줘야함

 

백엔드 컨테이너 실행
docker network create web
docker network connect web traefik
docker run -d --network web -l "traefik.enable=true" --name apache httpd

 

접속 테스트
curl --header 'Host:apache.docker.localhost' 'http://localhost:80/'

 

(참고) docker swarm 사용 시 traefik 서비스는 반드시 매니저 노드에 배포해야함(docker api 액세스가 필요하기 때문에)

 

## bootcamp 컨테이너
-> defaultRule 없이 labels를 통해 동일 호스트로 여러 컨테이너 간 로드밸런싱
-> docker-compose로 생성되는 다수 컨테이너가 동일 라우터에 연결되고, 같은 이름의 서비스가 생성되어 연결

 

mkdir -p ~/compose/bootcamp && cd ~/compose/bootcamp

vim docker-compose.yaml

 

version: '3.7'
services:
    bootcamp:
        network_mode: bootcamp
        image: gcr.io/google-samples/kubernetes-bootcamp:v1
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.bootcamp.rule=Host(`bootcamp.docker.localhost`)"
        deploy:
            mode: replicated
            replicas: 4



docker network create bootcamp
docker network connect bootcamp traefik


docker-compose up -d

 

접속 테스트
curl --header 'Host:bootcamp.docker.localhost' 'http://localhost:80/'



# 개별 컨테이너를 동일 라우터, 서비스에 할당
-> 별도의 서비스 포트를 설정하는 경우 개별 컨테이너가 해당 서비스에 연결되고 레이블에 지정한 서비스가 해당 라우터에 연결됨
[root@centos7 test]# cat docker-compose.yaml
version: '3.7'
services:
    test1:
        network_mode: bootcamp
        image: gcr.io/google-samples/kubernetes-bootcamp:v1
        container_name: test1
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.bootcamp.rule=Host(`bootcamp.docker.localhost`)"
            - "traefik.http.services.bootcamp.loadbalancer.server.port=8080"
    test2:
        network_mode: bootcamp
        image: gcr.io/google-samples/kubernetes-bootcamp:v1
        container_name: test2
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.bootcamp.rule=Host(`bootcamp.docker.localhost`)"
            - "traefik.http.services.bootcamp.loadbalancer.server.port=8080"

 

혹은 docker run 커맨드로

 

docker run -d --network bootcamp --name test1 -l "traefik.enable=true" -l "traefik.http.routers.bootcamp.rule=Host(\`bootcamp.docker.localhost\`)" -l "traefik.http.services.bootcamp.loadbalancer.server.port=8080" gcr.io/google-samples/kubernetes-bootcamp:v1

docker run -d --network bootcamp --name test2 -l "traefik.enable=true" -l "traefik.http.routers.bootcamp.rule=Host(\`bootcamp.docker.localhost\`)" -l "traefik.http.services.bootcamp.loadbalancer.server.port=8080" gcr.io/google-samples/kubernetes-bootcamp:v1
 
# sticky session, cookie, 헬스 체크 등 로드밸런싱 관련 옵션

 

 

아래는 docker-compose.yaml 파일 예시

 

version: '3.3'
services:
    web:
        network_mode: gnu
        image: 'my-gnu:latest'
        deploy:
            replicas: 2
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.gnu.rule=Host(`test.example.com`)"
            - "traefik.http.services.gnu.loadbalancer.sticky.cookie=true"

 

 
쿠키의 기본 값은 sha1 으로 해싱됨(쿠키 값 예시 - _02dc0(키)=6b567c1384106610(값))
별도로 원하는 쿠키 이름(traefik_lb)이 있는 경우 아래와 같이 지정

 

            - "traefik.http.services.gnu.loadbalancer.sticky.cookie.name=traefik_lb"

 

기본적으로 컨테이너가 다운되면 로드밸런싱 대상에서 제외되지만 별도로 헬스 체크 관련 레이블을 부여하여 200 응답이 아닌 경우 대상에서 제외하도록 설정 가능(헬스체크 간격 기본값 30초)

 

version: '3.3'
services:
    web:
        network_mode: gnu
        image: 'my-gnu:latest'
        deploy:
            replicas: 2
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.gnu.rule=Host(`test.example.com`)"
            - "traefik.http.services.gnu.loadbalancer.healthcheck.path=/health_check.html"
            - "traefik.http.services.gnu.loadbalancer.healthcheck.interval=10s"

 

# https 설정
-> http 라우터와 별도로 https 전용 라우터를 생성함
-> 동적 설정 파일을 통해 별도 인증서를 설정하지 않으면 traefik 기본 인증서가 적용됨

 

version: '3.3'
services:
    web:
        network_mode: gnu
        image: 'my-gnu:latest'
        deploy:
            replicas: 2
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.gnu.rule=Host(`test.example.com`)"
            - "traefik.http.routers.gnu_https.rule=Host(`test.example.com`)"
            - "traefik.http.routers.gnu_https.tls=true"




'docker' 카테고리의 다른 글

Alpine Linux로 Docker 이미지 빌드  (0) 2023.03.13
Docker buildx를 통한 멀티 플랫폼 이미지 빌드  (0) 2023.03.11
docker swarm  (0) 2023.03.06
docker buildx  (0) 2023.03.06