この記事は はてなエンジニア Advent Calendar 2021 11日目の記事です。
コンテナのベースイメージとしてdistrolessを選択肢にするということがここ最近増えてきました。
そんなdistrolessを非rootユーザで使おうとしたらとても簡単だったのでその紹介です。
どのくらい簡単かというと、Goのアプリケーションであれば以下のように変えるだけで対応できます。(コメントアウト部分は元々のrootユーザで動かしていた場合のもの)
FROM golang:1.17 as builder WORKDIR /go/src COPY go.mod go.sum . RUN go mod download COPY . . RUN go build -o /out/myapp . # FROM gcr.io/distroless/static:latest FROM gcr.io/distroless/static:nonroot # COPY --from=builder /out/myapp /usr/local/bin/ COPY --from=builder --chown=nonroot:nonroot /out/myapp /usr/local/bin/
distrolessでは2019年にマージされた以下のプルリクエストで非rootユーザである nonroot
ユーザ及びそれを利用するための :nonroot
というイメージタグが導入されました。
:nonroot
のタグはstaticに限らずdistrolessの全イメージで使うことができ、簡単には :latest
はrootユーザで :nonroot
はnonrootユーザという区別がされています。
なので非rootユーザ対応は基本的には :nonroot
にするだけで良いですが、マルチステージビルドの場合はbuilderステージで作成されたものはユーザを指定していない限りrootで作成されて実行できなくなってしまうのでCOPY時にchownオプション*1で nonroot:nonroot
を指定してあげる必要があります。
ちなみにnonrootというユーザは :nonroot
イメージに限らずどのイメージでも作成されているのでDockerfileに USER nonroot
と書くという方法でも冗長だけど一応実現は可能です。
cohalz@co ~ % docker run -it --rm gcr.io/distroless/static:debug / # cat /etc/passwd root:x:0:0:root:/root:/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/sbin/nologin nonroot:x:65532:65532:nonroot:/home/nonroot:/sbin/nologin
ちなみにdistrolessはnonroot以外にもbusybox入りのdebugイメージやアーキテクチャも指定することができますが、全部使いたい場合は順番としてはdebug-nonroot-arm64
といった順番で指定するという感じになっています。
この :nonroot
イメージは少しずつ利用が広がっており、google/koも2020年10月に出たv0.6.0からデフォルトではこのnonrootイメージを使うようになっています。
セキュリティ対策をちゃんとしようという流れがある中、コンテナイメージの非root化をまだ全然やれてない人は数行変えるだけで試せるdistrolessからやってみてはどうでしょうかという記事でした。
明日のアドベントカレンダーの担当は id:papix さんです。
*1:Docker 17.09から利用できる https://docs.docker.com/engine/release-notes/17.09/#17090-ce