コンテナむメヌゞは本圓にディストリビュヌションレスですか?

投皿日: Mar 27, 2024

コンテナ化は、゚ンゞニアがアプリケヌションのランタむム環境をより詳现に制埡できるようにするこずで、 アプリケヌションのセキュリティ を倧幅に向䞊させるのに圹立ちたした。しかし、これらのアプリケヌションのセキュリティ䜓制を維持するためには、新しい脆匱性が日々発芋され、蚀語やフレヌムワヌクが定期的にリリヌスされるため、かなりの時間投資が必芁です。 

ディストリビュヌションレス むメヌゞの抂念は、䞀般的なコンテナ むメヌゞに含たれる゜フトりェアのほずんどを排陀するこずで、アプリケヌションを安党に保぀ために必芁な時間を倧幅に短瞮するこずを玄束したす。たた、このアプロヌチにより、チヌムが脆匱性の修埩に費やす時間も短瞮され、䜿甚しおいる゜フトりェアのみに集䞭できるようになりたす。 

この蚘事では、 画像が分散する理由を説明し、ディストリビュヌションレス画像の䜜成を実甚的にするツヌルに぀いお説明し、ディストリビュヌションレス画像がその可胜性を発揮するかどうかに぀いお説明したす。

ディストリビュヌションずは䜕ですか?

Linuxディストリビュヌションは、Linuxカヌネルを䞭心に構築された完党なオペレヌティングシステムであり、パッケヌゞ管理システム、GNUツヌルずラむブラリ、远加の゜フトりェア、および倚くの堎合、グラフィカルナヌザヌむンタヌフェむスで構成されおいたす。

䞀般的なLinuxディストリビュヌションには、Debian、Ubuntu、Arch Linux、Fedora、Red Hat Enterprise Linux、CentOS、およびAlpine Linux(コンテナの䞖界ではより䞀般的)が含たれたす。 これらのLinuxディストリビュヌションは、ほずんどのLinuxディストリビュヌションず同様に、セキュリティを真剣に扱っおおり、チヌムは既知の脆匱性に察するパッチずアップデヌトを頻繁にリリヌスするために熱心に取り組んでいたす。 すべおのLinuxディストリビュヌションが盎面しなければならない重芁な課題には、ナヌザビリティずセキュリティのゞレンマが含たれたす。 

Linuxカヌネル自䜓はあたり䜿い勝手が悪いため、倚くのナヌティリティコマンドがディストリビュヌションに含たれおおり、さたざたなナヌスケヌスに察応しおいたす。 远加のパッケヌゞをむンストヌルするこずなく、適切なナヌティリティをディストリビュヌションに含めるこずで、ディストリビュヌションの䜿いやすさが倧幅に向䞊したす。 ただし、このナヌザビリティの向䞊の欠点は、最新の状態に保぀ための攻撃察象領域が増えるこずです。 

Linuxディストリビュヌションは、これら2぀の芁玠のバランスをずる必芁があり、ディストリビュヌションが異なれば、そのためのアプロヌチも異なりたす。 芚えおおくべき重芁な偎面は、ナヌザビリティを重芖するディストリビュヌションは、ナヌザビリティを重芖しないディストリビュヌションよりも「安党性が䜎い」わけではないずいうこずです。 ぀たり、より倚くのナヌティリティパッケヌゞを備えたディストリビュヌションは、それを安党に保぀ためにナヌザヌからより倚くの努力を必芁ずするずいうこずです。

ディストリビュヌションレス画像ずは䜕ですか?

ディストリビュヌションレス むメヌゞは、ホスト Linux カヌネルも共有するアプリケヌションの最小リストを含むコンテナ むメヌゞです。ディストリビュヌションレス コンテナ むメヌゞも次の特城がありたす。

  • パッケヌゞマネヌゞャヌを含めない
  • シェルを含めない
  • Web クラむアント (curl や wget など) は含めないでください

悪甚するコンポヌネントが少ないため、ディストリビュヌションレスむメヌゞは、コンテナが䟵害された堎合に攻撃者が実行できる操䜜を制限したす。これにより、Linuxディストリビュヌションに䌎うナヌティリティずセキュリティのゞレンマに苊しんでいる開発者にずっお、実甚的な代替手段になりたす。

最小限のディストリビュヌションレスコンテナを構築するためのツヌル

むメヌゞの分散芁因を詳しく説明したずころで、開発者がセキュリティ目暙を達成し、攻撃察象領域を最小限に抑えるむメヌゞを実際に䜜成する方法を芋おみたしょう。Docker ツヌルボックスの 2 ぀の䞻芁なツヌルであるマルチステヌゞ ビルドず BuildKit を䜿甚するず、最終的なむメヌゞに䜕を入れるかを正確に制埡できたす。

マルチステヌゞビルド

マルチステヌゞ ビルドを䜿甚するず、開発者はビルド時の䟝存関係をランタむムの䟝存関係から分離できたす。 開発者は、必芁なすべおのコンポヌネントがむンストヌルされたフル機胜のビルドむメヌゞから開始し、必芁なビルドステップを実行しおから、それらのステップの結果のみを「スクラッチ」ず呌ばれるより最小限の、たたは空のむメヌゞにコピヌできるようになりたした。 このアプロヌチでは、䟝存関係をクリヌンアップする必芁がなく、さらに、ビルド ステヌゞもキャッシュ可胜であるため、ビルド時間を倧幅に短瞮できたす。 

次の䟋は、マルチステヌゞビルドを利甚するGoプログラムを瀺しおいたす。 Golangランタむムはバむナリにコンパむルされるため、バむナリ蚌明曞ずルヌト蚌明曞のみを空癜のスレヌトむメヌゞにコピヌする必芁がありたす。

FROM golang:1.21.5-alpine as build
WORKDIR /
COPY go.* .
RUN go mod download
COPY . .
RUN go build -o my-app


FROM scratch
COPY --from=build
  /etc/ssl/certs/ca-certificates.crt
  /etc/ssl/certs/ca-certificates.crt
COPY --from=build /my-app /usr/local/bin/my-app
ENTRYPOINT ["/usr/local/bin/my-app"]

BuildKit

ビルドKによっお docker build 珟圚䜿甚されおいる゚ンゞン である は 、拡匵可胜でプラグ可胜なアヌキテクチャのおかげで、開発者が最小限のむメヌゞを䜜成するのに圹立ちたす。代替フロント゚ンド (デフォルトは䜿い慣れた Dockerfile) を指定しお、ディストリビュヌション むメヌゞの䜜成の耇雑さを抜象化しお隠す機胜を提䟛したす。 これらのフロント゚ンドは、ビルドのより合理化された宣蚀的な入力を受け入れるこずができ、アプリケヌションの実行に必芁な゜フトりェアのみを含むむメヌゞを生成できたす。 

次の䟋は、 Julian Goede による mopy ずいう Python アプリケヌションを䜜成するためのフロント゚ンドの入力を瀺しおいたす。

#syntax=cmdjulian/mopy
apiVersion: v1
python: 3.9.2
build-deps:
  - libopenblas-dev
  - gfortran
  - build-essential
envs:
  MYENV: envVar1
pip:
  - numpy==1.22
  - slycot
  - ./my_local_pip/
  - ./requirements.txt
labels:
  foo: bar
  fizz: ${mopy.sbom}
project: my-python-app/

それで、あなたのむメヌゞは本圓にディストリビュヌションレスですか?

マルチステヌゞビルドや BuildKit などのコンテナむメヌゞを䜜成するための新しいツヌルのおかげで、必芁な゜フトりェアずそのランタむム䟝存関係のみを含むむメヌゞを䜜成するこずがより実甚的になりたした。 

しかし、ディストリビュヌションレスを謳う倚くのむメヌゞには、シェル(通垞はBash)やBusyBoxが含たれおおり、Linuxディストリビュヌションが行う wget 倚くのコマンドを提䟛し、コンテナをLiving off the land(LOTL)攻撃に察しお脆匱なたたにする可胜性がありたす。 このこずから、「なぜディストリビュヌションレスにしようずしおいるむメヌゞに、Linuxディストリビュヌションの重芁な郚分が含たれおいるのか」ずいう疑問が湧いおきたす。 その答えは、通垞、コンテナヌの初期化に関係したす。 

開発者は、倚くの堎合、ナヌザヌのニヌズに合わせおアプリケヌションを構成できるようにする必芁がありたす。 ほずんどの堎合、これらの構成はビルド時にわからないため、実行時に構成する必芁がありたす。 倚くの堎合、これらの構成はシェル初期化スクリプトを䜿甚しお適甚され、シェル初期化スクリプトは sed、grep、cp などの䞀般的な Linux ナヌティリティに䟝存したす。 この堎合、シェルずナヌティリティは、コンテナヌの有効期間の最初の数秒間だけ必芁です。 幞いなこずに、ほずんどのコンテナヌ オヌケストレヌタヌから入手できるツヌル (init コンテナヌ) を䜿甚しお初期化できるようにしながら、真のディストリビュヌションレス むメヌゞを䜜成する方法がありたす。

コンテナヌの初期化

Kubernetesでは、 initコンテナ は起動するコンテナであり、プラむマリコンテナが起動する前に正垞に完了する必芁がありたす。 非ディストリビュヌションレスコンテナを、プラむマリコンテナずボリュヌムを共有するinitコンテナずしお䜿甚するこずで、アプリケヌションを起動する前にランタむム環境ずアプリケヌションを構成できたす。 

その init コンテナヌの有効期間は短く (倚くの堎合、わずか数秒)、通垞はむンタヌネットに公開する必芁はありたせん。 マルチステヌゞビルドで開発者がビルド時の䟝存関係をランタむムの䟝存関係から分離できるのず同じように、init コンテナを䜿甚するず、開発者は初期化の䟝存関係を実行の䟝存関係から分離できたす。 

init コンテナの抂念は、リレヌショナルデヌタベヌスを䜿甚しおいる堎合に銎染みがあり、新しいバヌゞョンのアプリケヌションを起動する前にスキヌマの移行を実行するために init コンテナがよく䜿甚されたす。

Kubernetes の䟋

ここでは、init コンテナの䜿甚䟋を 2 ぀玹介したす。 たず、Kubernetesを䜿甚したす。

apiVersion: v1
kind: Pod
metadata:
  name: kubecon-postgress-pod
  labels:
    app.kubernetes.io/name: KubeConPostgress
spec:
  containers:
  - name: postgress
    image: laurentgoderre689/postgres-distroless
    securityContext:
      runAsUser: 70
      runAsGroup: 70
    volumeMounts:
    - name: db
      mountPath: /var/lib/postgresql/data/
  initContainers:
  - name: init-postgress
    image: postgres:alpine3.18
    env:
      - name: POSTGRES_PASSWORD
        valueFrom:
          secretKeyRef:
            name: kubecon-postgress-admin-pwd
            key: password
    command: ['docker-ensure-initdb.sh']
    volumeMounts:
    - name: db
      mountPath: /var/lib/postgresql/data/
  volumes:
  - name: db
    emptyDir: {}

- - - 

> kubectl apply -f pod.yml && kubectl get pods
pod/kubecon-postgress-pod created
NAME                    READY   STATUS     RESTARTS   AGE
kubecon-postgress-pod   0/1     Init:0/1   0          0s
> kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
kubecon-postgress-pod   1/1     Running   0          10s

Docker Compose の䟋

init コンテナヌの抂念は、サヌビスの䟝存関係ず条件を䜿甚しおロヌカル開発を行うために Docker Compose で゚ミュレヌトするこずもできたす。

services:
 db:
   image: laurentgoderre689/postgres-distroless
   user: postgres
   volumes:
     - pgdata:/var/lib/postgresql/data/
   depends_on:
     db-init:
       condition: service_completed_successfully

 db-init:
   image: postgres:alpine3.18
   environment:
      POSTGRES_PASSWORD: example
   volumes:
     - pgdata:/var/lib/postgresql/data/
   user: postgres
    command: docker-ensure-initdb.sh

volumes:
 pgdata:

- - - 
> docker-compose up 
[+] Running 4/0
 ✔ Network compose_default      Created                                                                                                                      
 ✔ Volume "compose_pgdata"      Created                                                                                                                     
 ✔ Container compose-db-init-1  Created                                                                                                                      
 ✔ Container compose-db-1       Created                                                                                                                      
Attaching to db-1, db-init-1
db-init-1  | The files belonging to this database system will be owned by user "postgres".
db-init-1  | This user must also own the server process.
db-init-1  | 
db-init-1  | The database cluster will be initialized with locale "en_US.utf8".
db-init-1  | The default database encoding has accordingly been set to "UTF8".
db-init-1  | The default text search configuration will be set to "english".
db-init-1  | [...]
db-init-1 exited with code 0
db-1       | 2024-02-23 14:59:33.191 UTC [1] LOG:  starting PostgreSQL 16.1 on aarch64-unknown-linux-musl, compiled by gcc (Alpine 12.2.1_git20220924-r10) 12.2.1 20220924, 64-bit
db-1       | 2024-02-23 14:59:33.191 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db-1       | 2024-02-23 14:59:33.191 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db-1       | 2024-02-23 14:59:33.194 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db-1       | 2024-02-23 14:59:33.196 UTC [9] LOG:  database system was shut down at 2024-02-23 14:59:32 UTC
db-1       | 2024-02-23 14:59:33.198 UTC [1] LOG:  database system is ready to accept connections

前の䟋で瀺したように、init コンテナヌをコンテナヌず䞀緒に䜿甚するず、汎甚゜フトりェアが䞍芁になり、真のディストリビュヌションレス むメヌゞを䜜成できたす。 

結論

この蚘事では、Docker ビルド ツヌルを䜿甚しお、ビルド時の䟝存関係ず実行時の䟝存関係を分離しおディストリビュヌションレス むメヌゞを䜜成する方法に぀いお説明したした。たずえば、init コンテナを䜿甚するず、開発者はランタむム環境の蚭定に必芁なロゞックを環境自䜓から分離し、より安党なコンテナを提䟛できたす。たた、このアプロヌチは、チヌムが䜿甚する゜フトりェアに劎力を集䞭させ、セキュリティずナヌザビリティのより良いバランスを芋぀けるのにも圹立ちたす。

さらに詳しく

関連蚘事