EKS에 self-hosted runners(Github Actions)를 시작하여 안전하게 digdag push

소개



현재 운영되고 있는 서비스에서는 워크플로우의 실행에 Digdag를 채용하고 있어 워크플로우의 파일은 Github에서 관리되고 있습니다. 이 구성에서 Github Actions를 사용하여 워크플로 배포를 자동화할 때 발생한 보안 문제와 해결 방법을 요약했습니다.

전제


  • Digdag 워크 플로우를 Github에서 관리합니다.
  • Github Actions나 CircleCI 등의 외부에서 Digdag에 PUSH를 하고 싶다.

  • [구성도]
    이번 구성에서는 Digdag를 EKS상에서 움직이고 있습니다.


    하고 싶은 일


  • Ditdag 워크 플로우를 Github Actions에 자동 배포하여 즐기고 싶습니다

  • 도전


  • 보안 관점에서 Digdag 엔드 포인트는 외부에 공개하지 않지만 GithubActions IP에서 Digdag 엔드 포인트에 연결하고 싶습니다.

    해결책



    Digdag의 엔드포인트에 접속하는 방안으로서는 2개 검토했습니다.

    제안 1: Runner의 IP를 SecurityGroup에서 허용



    CircleCI는 작업 라운드로서 일시적으로 CircleCI가 사용하는 IP를 허용하는 방법을 소개합니다.

    Github도 IP 주소 목록을 얻는 방법을 소개하고 있지만 IP 주소에 의한 권한은 권장하지 않는다고 쓰여 있습니다.

    개인적으로도 공유되는 IP를 허용하는 것은 추천하고 싶지 않을까, , , 라고 하는 인상입니다.

    제안 2: self-hosted runners 사용



    이번에는 이쪽의 방법을 채용했습니다. 다음과 같은 구성도가 됩니다.


    self-hosted runners를 사용하는 이점은 다음과 같은 곳이라고 생각합니다.
  • 정기적으로 Github Actions로 폴링하는 사양이므로 외부에서 self-hosted runners에 액세스 할 필요가 없다 (보안적으로 유리하다)
  • EKS상에 Pod로 기동해 두면, 외부에 접속할 때의 IP 주소(NatGatewayIP)를 고정할 수 있다.
  • Digdag 엔드포인트의 ALB SecurityGroup에 NatGatewayIP를 등록해 두면 self-hosted runners로부터 액세스할 수 있다.

  • 해보자



    다음 단계는 생략합니다.
  • Parsonal Access Token 얻기
  • Personal Access Token을 Secrets에 등록 (External Secrets를 이용하고 있습니다)
  • NatGateway의 IP를 ALB의 SecurityGroup에 추가

  • Dockerfile 준비



    이 사이트를 참고로 해, 일부 재작성하고 있습니다.
    htps : // 씨로 rk인ぺ. 코 m / 2020 / 03 / 세루 lf - ss-d-gi-b-b-c-chi-on-s-r-r-be-r-s /

    변경점
  • stg 환경과 prd 환경의 runner를 label로 판정하기 위해 환경 변수를 추가
  • digdag가 움직이도록 베이스 이미지를 변경(azul/zulu-openjdk:8)
  • digdag 설치

  • Dockerfile
    FROM azul/zulu-openjdk:8
    
    ARG GITHUB_RUNNER_VERSION="2.277.1"
    
    ENV RUNNER_NAME "runner"
    ENV GITHUB_PAT ""
    ENV GITHUB_OWNER ""
    ENV GITHUB_REPOSITORY ""
    ENV RUNNER_WORKDIR "_work"
    ENV GLOBAL_ENVIRONMENT ""
    
    RUN apt-get update \
        && apt-get install -y \
            curl \
            sudo \
            git \
            jq \
        && apt-get clean \
        && rm -rf /var/lib/apt/lists/* \
        && useradd -m github \
        && usermod -aG sudo github \
        && echo "%sudo ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
    
    RUN curl -o /usr/local/bin/digdag --create-dirs -L 'https://dl.digdag.io/digdag-0.10.0' \
        && chmod +x /usr/local/bin/digdag
    
    USER github
    WORKDIR /home/github
    
    RUN curl -Ls https://github.com/actions/runner/releases/download/v${GITHUB_RUNNER_VERSION}/actions-runner-linux-x64-${GITHUB_RUNNER_VERSION}.tar.gz | tar xz \
        && sudo ./bin/installdependencies.sh
    
    COPY --chown=github:github entrypoint.sh ./entrypoint.sh
    RUN sudo chmod u+x ./entrypoint.sh
    
    ENTRYPOINT ["/home/github/entrypoint.sh"]
    

    entrypoint.sh
    #!/bin/sh
    registration_url="https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPOSITORY}/actions/runners/registration-token"
    echo "Requesting registration URL at '${registration_url}'"
    
    payload=$(curl -sX POST -H "Authorization: token ${GITHUB_PAT}" ${registration_url})
    export RUNNER_TOKEN=$(echo $payload | jq .token --raw-output)
    
    ./config.sh \
        --labels ${GLOBAL_ENVIRONMENT} \
        --name $(hostname) \
        --token ${RUNNER_TOKEN} \
        --url https://github.com/${GITHUB_OWNER}/${GITHUB_REPOSITORY} \
        --work ${RUNNER_WORKDIR} \
        --unattended \
        --replace
    
    remove() {
        ./config.sh remove --unattended --token "${RUNNER_TOKEN}"
    }
    
    trap 'remove; exit 130' INT
    trap 'remove; exit 143' TERM
    
    ./run.sh "$*" &
    
    wait $!
    

    [주의 사항]
    Parsonal Access Token을 이용하여 runner용의 토큰을 취득하고 있습니다만, 「Parsonal Access Token」은 1년 붙지 않으면 삭제되므로, 1년 이상 Deploy하고 있지 않으면 토큰이 만료되어 릴리스에 실패할 수 있습니다.
    htps : // / cs. 기주 b. 코 m / 쟈 / 기테 b

    ECR로 이미지 PUSH



    이번에는 AmazonECR을 이용하기 위해 사전에 ECR 리소스를 생성해 둡니다.

    명령 예
    docker build -t github-runner .
    docker tag github-runner:latest xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/github-runner:latest
    docker push xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/github-runner:latest
    

    배포



    Parsonal Access Token은 Secret에 등록합니다.

    github-runner.yml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: github-runner
      labels:
        app: github-runner
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: github-runner
      template:
        metadata:
          labels:
            app: github-runner
        spec:
          containers:
          - name: github-runner
            image: xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/github-runner:latest
            env:
            - name: GITHUB_OWNER
              value: 'xxxxxx' #組織名
            - name: GITHUB_REPOSITORY
              value: 'xxxxxxx' #GHAを動かすrepository
            - name: GLOBAL_ENVIRONMENT
              value: 'xxx' #stg/prdなど
            - name: GITHUB_PAT
              valueFrom:
                secretKeyRef:
                  name: github-secret
                  key: pat
    

    kubernetes에 배포
    kubectl apply -f github-runner.yml
    

    확인



    Github의 Settings > Actions에 Runner가 등록되어 있으면 정상적으로 가동하고 있습니다.

    좋은 웹페이지 즐겨찾기