Docker(도커) 컨테이너의 헬스체크와 자동 재시작, AutoHeal(오토힐) 적용 방법

Docker(도커) 컨테이너의 헬스체크와 자동 재시작, AutoHeal(오토힐) 적용 방법

안전한 토렌트 사용을 위해 NordVPN을 사용중으로 이쪽 계통에서는 사실상 올인원에 가까운 transmission-openvpn 컨테이너를 사용하고 있습니다.

transmission-openvpn 의 경우 단순히 VPN 제공자의 아이디와 비밀번호만 환경변수로 넘겨주면 되기 때문에 복잡한 설정이 필요하지 않고 여러 컨테이너를 거칠 필요 없이 하나로 모든 설정이 가능하다는 장점이 있습니다.

Transmission-OpenVPN 도커 트랜스미션을 VPN 설정으로 안전하게 사용하는 방법!
대표적인 Torrent(토렌트) 다운로드 클라이언트인 Transmission(트랜스미션)에 외부로부터 좀 더 안전한 환경인 VPN을 적용해보도록 하겠습니다.

위처럼 VPN용 컨테이너를 관리하게 되면 해당 컨테이너를 대표 네트워크로 선언해서 다른 컨테이너들을 추가로 엮어서 운용하는 설정이 몹시 간단한 반면 아쉬운 점도 있습니다.

문제는 컨테이너의 네트워크 연결이 끊어졌을때 각각 알아서 컨테이너를 재시작한다면 편리할텐데 이를 기본으로 지원하지 않고 있어 꽤나 골치아픈 문제입니다.

만약 VPN의 연결이 끊어지면 재연결을 시도하도록 설정은 가능하나, 그럼에도 연동된 컨테이너들의 네트워크가 별도로 자동으로 갱신되는 것은 아니기 때문입니다.

지금까지는 네트워크 문제 발생 시 전체 Stack(스택)을 재실행하는 식으로 간간히 해결해왔지만 이번엔 직접 조치할 상황조차 없도록 완전히 자동화 해보도록 하겠습니다.

일단 제 경우 NordVPN을 연동한 haugene/transmission-openvpn 컨테이너의 경우 기본 설정이 다음과 같습니다.

- OPENVPN_OPTS=--inactive 3600 --ping 10 --ping-exit 60 # VPN 연결이 끊어지면 컨테이너 강제 종료(킬 스위치)

위처럼 별도의 환경 변수로 핑을 날려 VPN 연결에 문제시 아예 컨테이너를 종료해버립니다.

이처럼 완전히 컨테이너를 죽여야하기 때문에 restart: unless-stopped 옵션을 사용하고 있었습니다.

그러나 이런식으로 동작하게 되면 뭔가 안된다 싶을때 관리자가 직접 도커 컨테이너를 재기동 해야하며, 심지어 단순히 transmission-openvpn 컨테이너만 재기동해서는 다른 컨테이너들의 네트워크 문제가 해결되지 않습니다.

따라서 헬스체크를 사용해 각 컨테이너들의 Status(상태)를 별도로 체크하고 만약 네트워크에 문제가 생기는 경우 Unhealthy로 변경 되도록 설정을 추가하겠습니다.

상태만 변경하면 되기 때문에 도커 컨테이너에 문제가 발생하더라도 일단 항상 동작하도록 restart: unless-stopped 옵션을 restart: always 로 변경하겠습니다.

healthcheck:
  test: ["CMD", "curl", "-f", "https://www.google.com"]
  interval: 1m30s
  timeout: 15s
  retries: 3

다음은 위처럼 추가로 VPN 컨테이너 설정 사이에 healthcheck 블록을 추가합니다.

기본적인 형태는 interval(반복실행 시간)1분 30초마다 시도해서 3번의 재시도를 하는동안 작업에 실패하는 경우 컨테이너의 상태를 Healthy 에서 Unhealthy 로 바꾸어주는 역할을 합니다.

그렇다면 이제 VPN 컨테이너는 Unhealthy 상태로 변경이 가능하게 되었으니 AutoHeal을 적용하기 위해 별도의 라벨을 추가해야겠습니다.

labels:
  - autoheal=true

포테이너의 Stack(YAML 형식) 내용 사이에 위처럼 labels 항목을 추가하도록 하겠습니다.

추가로 오토힐을 적용하기 위한 플래그 값인 autoheal=true 를 지정해줍니다.

  autoheal:
    container_name: openvpn-autoheal
    image: willfarrell/autoheal:latest
    restart: always
    environment:
      - AUTOHEAL_CONTAINER_LABEL=all
      - TZ=Asia/Seoul # 국내 타임존으로 설정
      - AUTOHEAL_CONTAINER_LABEL=autoheal # 오토힐 적용할 라
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    logging:
      driver: json-file
      options:
        max-size: 10m # log 파일의 용량을 10m로 제한

다음은 컨테이너를 감시하고 Unhealthy 상태인 컨테이너를 재기동 시켜 줄 오토힐 컨테이너를 하단에 추가해주시면 되겠습니다.

반드시 동일한 Stack 안에서 실행하실 필요는 없지만 제 경우 편의상 같은 YAML 안에 추가했습니다.

docker-compose.yml

version: "3.3"
services:
  transmission-openvpn:
    cap_add:
      - NET_ADMIN
    volumes:
      - "[직접입력]/data:/data"
      - "[직접입력]/config:/config"
      - "[직접입력]/download:/data/completed"
      - "[직접입력]/incomplete:/data/incomplete"
      - "[직접입력]/watch:/data/watch"
    environment:
      - OPENVPN_PROVIDER=NORDVPN
      - OPENVPN_CONFIG=us.socks.nordhold.net
      - NORDVPN_COUNTRY=US
      - NORDVPN_CATEGORY=legacy_p2p
      - NORDVPN_PROTOCOL=tcp
      - NORDVPN_SERVER=sg460.nordvpn.com
      - OPENVPN_USERNAME=[직접입력]
      - OPENVPN_PASSWORD=[직접입력]
      - OPENVPN_OPTS=--inactive 3600 --ping 10 --ping-exit 60
      - TRANSMISSION_SCRAPE_PAUSED_TORRENTS_ENABLED=false
      - LOCAL_NETWORK=192.168.0.0/16
      - TRANSMISSION_RPC_AUTHENTICATION_REQUIRED=true
      - TRANSMISSION_RPC_USERNAME=[직접입력]
      - TRANSMISSION_RPC_PASSWORD=[직접입력]
      - PUID=1000
      - PGID=100
      - TZ=Asia/Seoul
      - OVERRIDE_DNS_1=8.8.8.8
      - OVERRIDE_DNS_2=8.8.4.4
    logging:
      driver: json-file
      options:
        max-size: 10m
    ports:
      - 39091:9091
    image: haugene/transmission-openvpn:5.1.0
    restart: always
    healthcheck:
      test:
        - CMD
        - curl
        - -f
        - https://www.google.com
      interval: 1m30s
      timeout: 15s
      retries: 3
    labels:
      - autoheal=true
  autoheal:
    container_name: openvpn-autoheal
    image: willfarrell/autoheal:latest
    restart: always
    environment:
      - AUTOHEAL_CONTAINER_LABEL=all
      - TZ=Asia/Seoul
      - AUTOHEAL_CONTAINER_LABEL=autoheal
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    logging:
      driver: json-file
      options:
        max-size: 10m

따라서 전체적인 예시로 표현하자면 위처럼 transmission-openvpn오토힐 컨테이너를 적용한 위와 같은 YAML 형태가 될 것입니다.

물론 여전히 이 헬스체크 설정이 모든 문제를 해결해주진 못했습니다.

Curl을 이용해 구글 접속을 체크하는 방식이기 때문에 만약 CMD에서 Curl을 기본으로 지원하지 않는 컨테이너라면 헬스체크를 적용할 수가 없었습니다.

대표적으로 틴포일 웹서버 컨테이너의 경우 Curl이 동작하질 않아 다른 방법을 찾아보아야 할 것 같습니다.

다만 트랜스 미션이나 Sonarr, Radarr, Bazarr, TSharp 등의 컨테이너에는 적용하기 너무나 간단하기 때문에 주요 컨테이너들에게는 쉽게 자동 재시작 설정이 가능하다는 장점이 있었습니다.

현재 헬스체크가 적용되었는지를 확인하기 위해서는 컨테이너의 Status(상태)를 확인하는 것으로 쉽게 체크가 가능합니다.

만약 healthy 상태라면 헬스체크가 제대로 적용 된 것이고 일반적인 running 상태라면 헬스체크를 적용하고 있지 않은 상황이 되겠습니다.

아직까진 모든 상황에 적용 가능한 최고의 해결 방법을 찾진 못했으나 이 또한 해결이 된다면 따로 포스팅 해보도록 하겠습니다.

도움이 되시길 바랍니다.

감삽합니다.

비정기로 발행되는 추천 포스트를 이메일로 받아 보실 수 있습니다.

특별한 추천 포스트를 바로 이메일로 받아보세요. 물론 무료입니다!
좋아요! 받은 편지함을 확인하고 구독을 확인하려면 링크를 클릭하십시오.
오류! 유효한 이메일 주소를 입력하십시오!