前回の「dockle で docker build のベストプラクティスをチェックしてみる」で、 dockle 試してみるところまでやってみた。
今回は CI で定期的にチェックするようにする。 また、trivy で脆弱性のテストができるので、これも組み込んでみる。
2019/08/23 追記 : 買収に伴ってリポジトリが aquasecurity/trivy に移動した模様。
CONTENTS
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} && \ :
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 でビルドしたイメージを参照するためのものなので、どんな名前でも良い。
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
がキャッシュとして使用されるようにしている。
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
定期的にテストする
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
only
に schedules
を指定して、スケジュールからの起動でのみ pipeline が走るようにする。
先の test
の例と異なるのは only: - schedules
の部分のみだ。
あとは、GitLab の設定画面からスケジュールを追加すれば OK。
まとめ
dockle と trivy を CI に組み込んでみた。 これで定期的に dockle と trivy によるチェックができるようになった。