げっとシステムログ

WEB開発メモ

dockle と trivy で CI してみる

前回の「dockle で docker build のベストプラクティスをチェックしてみる」で、 dockle 試してみるところまでやってみた。

今回は CI で定期的にチェックするようにする。 また、trivy で脆弱性のテストができるので、これも組み込んでみる。

2019/08/23 追記 : 買収に伴ってリポジトリが aquasecurity/trivy に移動した模様。

CONTENTS
  1. できあがったもの
  2. dockle でテストする
  3. trivy でテストする
  4. merge-request でテストする
  5. 定期的にテストする
  6. まとめ
  7. 参考資料
ENVIRONMENTS
  • GitLab
  • dockle : v0.1.14
  • trivy : 0.1.4

できあがったもの

.gitlab-ci.yml

test:
  only:
    - merge_requests

  image: docker:stable

  variables:
    DOCKER_HOST: tcp://docker:2375/
    DOCKER_DRIVER: overlay2
    DOCKER_CONTENT_TRUST: 1
  services:
    - docker:dind

  cache:
    paths:
      - .cache

  before_script:
    - ./bin/install_ci_tools.sh
  script:
    - ./bin/test.sh

bin/install_ci_tools.sh

#!/bin/sh

apk -Uuv add bash git curl tar sed grep && \
./bin/install_dockle.sh && \
./bin/install_trivy.sh && \
:

bin/install_dockle.sh

#!/bin/bash

VERSION=$(
  curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \
  grep '"tag_name":' | \
  sed -E 's/.*"v([^"]+)".*/\1/' \
) && \
curl -L -o dockle.tar.gz https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.tar.gz && \
tar zxvf dockle.tar.gz && \
mv dockle /usr/bin && \
:

bin/install_trivy.sh

#!/bin/bash

VERSION=$(
  curl --silent "https://api.github.com/repos/knqyf263/trivy/releases/latest" | \
  grep '"tag_name":' | \
  sed -E 's/.*"v([^"]+)".*/\1/' \
) && \
curl -L -o trivy.tar.gz https://github.com/knqyf263/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz && \
tar zxvf trivy.tar.gz && \
mv trivy /usr/bin && \
:

bin/test.sh

#!/bin/bash

set -x

export HOME=$(pwd)

image=ci/build

docker build -t $image:${CI_COMMIT_SHORT_SHA} . && \
dockle --exit-code 1 $image:${CI_COMMIT_SHORT_SHA} && \
trivy --exit-code 1 --quiet --auto-refresh $image:${CI_COMMIT_SHORT_SHA} && \
:

TOP

dockle でテストする

dockle は docker サービスを必要とするので、そのための設定を .gitlab-ci.yml に追加する。

test:
  only:
    - merge_requests

  image: docker:stable

  variables:
    DOCKER_HOST: tcp://docker:2375/
    DOCKER_DRIVER: overlay2
    DOCKER_CONTENT_TRUST: 1
  services:
    - docker:dind

  before_script:
    - ./bin/install_ci_tools.sh
  script:
    - ./bin/test.sh

before_script で必要なツールをインストールする。 ここでは dockle に必要なパッケージの追加と dockle のダウンロードを行う。

bin/install_ci_tools.sh

#!/bin/sh

apk -Uuv add bash git curl tar sed grep && \
./bin/install_dockle.sh && \
:

bin/install_ci_tools.sh の起動時には bash が存在しない。 このため、#!/bin/bash と書くと「bin/install_ci_tools.sh が見つからない」というエラーが出るので注意。

bin/install_dockle.sh

#!/bin/bash

VERSION=$(
  curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \
  grep '"tag_name":' | \
  sed -E 's/.*"v([^"]+)".*/\1/' \
) && \
curl -L -o dockle.tar.gz https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.tar.gz && \
tar zxvf dockle.tar.gz && \
mv dockle /usr/bin && \
:

script で docker イメージのビルドと dockle でのチェックを行う。

bin/test.sh

#!/bin/bash

set -x

image=ci/build

docker build -t $image:${CI_COMMIT_SHORT_SHA} . && \
dockle --exit-code 1 $image:${CI_COMMIT_SHORT_SHA} && \
:

ここで指定する $image は単に dockle でビルドしたイメージを参照するためのものなので、どんな名前でも良い。

TOP

trivy でテストする

trivy の設定は dockle のものとほとんど同じ。 trivy は $HOME/.cache にキャッシュを作成するので、そのための cache 設定を追加する。

test:
  only:
    - merge_requests

  image: docker:stable

  variables:
    DOCKER_HOST: tcp://docker:2375/
    DOCKER_DRIVER: overlay2
    DOCKER_CONTENT_TRUST: 1
  services:
    - docker:dind

  cache:
    paths:
      - .cache

  before_script:
    - ./bin/install_ci_tools.sh
  script:
    - ./bin/test.sh

before_script で必要なツールをインストールする。

bin/install_ci_tools.sh

#!/bin/sh

apk -Uuv add bash git curl tar sed grep && \
./bin/install_trivy.sh && \
:

bin/install_trivy.sh

#!/bin/bash

VERSION=$(
  curl --silent "https://api.github.com/repos/knqyf263/trivy/releases/latest" | \
  grep '"tag_name":' | \
  sed -E 's/.*"v([^"]+)".*/\1/' \
) && \
curl -L -o trivy.tar.gz https://github.com/knqyf263/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz && \
tar zxvf trivy.tar.gz && \
mv trivy /usr/bin && \
:

script で docker イメージのビルドと trivy でのチェックを行う。

bin/test.sh

#!/bin/bash

set -x

export HOME=$(pwd)

image=ci/build

docker build -t $image:${CI_COMMIT_SHORT_SHA} . && \
trivy --exit-code 1 --quiet --auto-refresh $image:${CI_COMMIT_SHORT_SHA} && \
:

trivy の --quiet はインジケータの表示を抑制するもので、--auto-refresh は脆弱性データベースの更新を行うもの。

trivy は $HOME/.cache にキャッシュを作成する。 GitLab は cache を設定することで指定したパスに生成されたものを job をまたいで再利用できる。 しかし、これはプロジェクトの中のディレクトリのみが対象となっている。 具体的にはビルド開始時のディレクトリ以下のファイルだ。

たとえば、cache:paths/root/.cache を設定しても GitLab は保存してくれない。 そこで、HOME を再設定することで ./.cache がキャッシュとして使用されるようにしている。

TOP

merge-request でテストする

以下の例のように設定することで merge-request でテストが走るようになる。

.gitlab-ci.yml

test:
  only:
    - merge_requests

  image: docker:stable

  variables:
    DOCKER_HOST: tcp://docker:2375/
    DOCKER_DRIVER: overlay2
    DOCKER_CONTENT_TRUST: 1
  services:
    - docker:dind

  cache:
    paths:
      - .cache

  before_script:
    - ./bin/install_ci_tools.sh
  script:
    - ./bin/test.sh

TOP

定期的にテストする

dockle にベストプラクティスのチェックが追加されたり、新たな脆弱性が trivy で検出されるようになったりするはず。 なので、定期的にこのテストを行いたい。

schedule_test:
  only:
    - schedules

  image: docker:stable

  variables:
    DOCKER_HOST: tcp://docker:2375/
    DOCKER_DRIVER: overlay2
    DOCKER_CONTENT_TRUST: 1
  services:
    - docker:dind

  cache:
    paths:
      - .cache

  before_script:
    - ./bin/install_ci_tools.sh
  script:
    - ./bin/test.sh

onlyschedules を指定して、スケジュールからの起動でのみ pipeline が走るようにする。 先の test の例と異なるのは only: - schedules の部分のみだ。 あとは、GitLab の設定画面からスケジュールを追加すれば OK。

TOP

まとめ

dockle と trivy を CI に組み込んでみた。 これで定期的に dockle と trivy によるチェックができるようになった。

TOP

参考資料

TOP