GNU/Linux >> Linux の 問題 >  >> Panels >> Docker

Dockerイメージを変更する方法

あなたはDockerに少し精通しており、Dockerコンテナの実行などの基本を知っていると思います。

以前の記事では、Dockerコンテナの更新とDockerファイルの作成について説明しました。

Dockerイメージを変更するのは正確には何ですか?

コンテナイメージはレイヤーに組み込まれ(またはレイヤーのコレクションです)、各Dockerfile命令はイメージのレイヤーを作成します。たとえば、次のDockerfileについて考えてみます。

FROM alpine:latest

RUN apk add --no-cache python3

ENTRYPOINT ["python3", "-c", "print('Hello World')"]

合計3つのDockerfileコマンドがあるため、このDockerfileから構築されたイメージには、合計3つのレイヤーが含まれます。

イメージを作成することで確認できます:

docker image built -t dummy:0.1 .

次に、コマンドdocker image historyを使用します 構築されたイメージ上。

articles/Modify a Docker Image on  modify-docker-images [?] took 12s 
❯ docker image history dummy:0.1 
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
b997f897c2db   10 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["python3" "-c…   0B        
ee217b9fe4f7   10 seconds ago   /bin/sh -c apk add --no-cache python3           43.6MB    
28f6e2705743   35 hours ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      35 hours ago     /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB

最後の「」レイヤーを無視します。

これらの各レイヤーは読み取り専用です。これらのレイヤーは読み取り専用であるため、このイメージの実行中のインスタンスに関連付けられたプロセスはこのイメージのコンテンツを変更できません。したがって、これらのレイヤーは、保持しなくても多くのコンテナーで共有できます。インスタンスごとにコピーします。ただし、コンテナのプロセスでr / wを実行できるようにするには、コンテナの作成時に既存のROレイヤーの上に別のレイヤーが追加されます。これは書き込み可能であり、他のコンテナと共有されません。

このr/wレイヤーの欠点は、このレイヤーで行われた変更が永続的ではないことです。ただし、ボリュームを使用して一部のデータを永続化することはできますが、既存のレイヤーの前にレイヤーを追加したり、レイヤーを削除したりする必要がある場合があります。画像または単にレイヤーを置き換えます。これらが、既存のdockerを変更したい理由です。 画像。

この記事では、さまざまな方法を使用して、上記のすべてのケースについて説明します。

Dockerイメージを変更する方法

Dockerイメージを変更する方法は2つあります。

  1. Dockerfilesを介して。
  2. コマンドdocker container commitの使用 。

両方の方法について説明し、最後に、コンテキスト内の方法にどちらのユースケースが適しているかを追加します。

方法1:Dockerfileを介してDockerイメージを変更する

Dockerイメージを変更することは、基本的にイメージのレイヤーを変更することを意味します。これで、各Dockerfileコマンドはイメージの1つのレイヤーを表すため、Dockerfileの各行を変更すると、それぞれのイメージも変更されます。

したがって、画像にレイヤーを追加する場合は、別のDockerfile命令を追加するだけで、1つを削除するには行を削除し、レイヤーを変更するには、それに応じて行を変更します。

Dockerfileを使用してイメージを変更する方法は2つあります。

  1. 変更するイメージをベースイメージとして使用し、子イメージを作成します。
  2. 変更するイメージの実際のDockerfileを変更します。

どの方法をいつ、どのように使用すべきかを説明しましょう。

1。画像をベース画像として使用する

これは、変更する画像を取得し、それにレイヤーを追加して新しい子画像を作成する場合です。イメージが最初から作成されない限り、すべてのイメージは同じ親ベースイメージへの変更です。

以前のDockerfileについて考えてみます。その画像から構築された画像の名前がdummy:0.1であるとします。 。ここで、「Hello World」を印刷するためにPython3の代わりにPerlを使用する必要があると思ったが、Python3も削除したくない場合は、dummy:0.1を使用できます。 ベースイメージとしてのイメージ(Python3はすでに存在するため)、次のようにそれからビルドします

FROM dummy:0.1

RUN apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

ここでは、dummy:0.1の上に構築しています 、適切と思われるレイヤーを追加します。

この方法は、既存のレイヤーを変更または削除する場合にはあまり役に立ちません。そのためには、次の方法に従う必要があります。

2。イメージのDockerfileを変更する

イメージの既存のレイヤーは読み取り専用であるため、新しいDockerfileを使用してそれらを直接変更することはできません。 FROMを使用 Dockerfileでコマンドを実行すると、ベースとしてイメージを取得し、上にビルドします。 それ、またはそれにレイヤーを追加します。

一部のタスクでは、既存のレイヤーを変更する必要がある場合がありますが、以前の方法を使用して、矛盾するRUNの束を使用して変更することができます。 手順(ファイルの削除、前のレイヤーで追加されたパッケージの削除/置換など)は、理想的なソリューションではなく、私がお勧めするものでもありません。レイヤーが追加され、画像サイズが大幅に増加するためです。

より良い方法は、イメージをベースイメージとして使用せずに、そのイメージの実際のDockerfileを変更することです。以前のDockerfileをもう一度考えてみてください。そのイメージにPython3を保持する必要がなく、Python3パッケージとコマンドをPerlのものに置き換える必要がなかった場合はどうなりますか?

前の方法に従うと、次のような新しいDockerfileを作成する必要がありました-

FROM dummy:0.1

RUN apk del python3 && apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

構築された場合、この画像には合計5つのレイヤーが含まれます。

articles/Modify a Docker Image on  modify-docker-images [?] took 3s 
❯ docker image history dummy:0.2
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
2792036ddc91   10 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["perl" "-e" "…   0B        
b1b2ec1cf869   11 seconds ago   /bin/sh -c apk del python3 && apk add --no-c…   34.6MB    
ecb8694b5294   3 hours ago      /bin/sh -c #(nop)  ENTRYPOINT ["python3" "-c…   0B        
8017025d71f9   3 hours ago      /bin/sh -c apk add --no-cache python3 &&    …   43.6MB    
28f6e2705743   38 hours ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      38 hours ago     /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB

また、画像のサイズは83.8MBです。

articles/Modify a Docker Image on  modify-docker-images [?] 
❯ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
dummy        0.2       2792036ddc91   19 seconds ago   83.8MB

これを行う代わりに、最初のDockerfileを取得し、Python3のものをPerlに変更します

FROM alpine:latest

RUN apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

レイヤーの数が3に減り、サイズは40.2MBになりました。

articles/Modify a Docker Image on  modify-docker-images [?] took 3s 
❯ docker image history dummy:0.3
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
f35cd94c92bd   9 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["perl" "-e" "…   0B        
053a6a6ba221   9 seconds ago   /bin/sh -c apk add --no-cache perl              34.6MB    
28f6e2705743   38 hours ago    /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      38 hours ago    /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB    

articles/Modify a Docker Image on  modify-docker-images [?] 
❯ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
dummy        0.3       f35cd94c92bd   29 seconds ago   40.2MB

画像が正常に変更されました。

前の方法は、既存のレイヤーの上にレイヤーを追加する場合に便利ですが、既存のレイヤーを削除、置換、並べ替え、すぐ。そこで、この方法が光ります。

方法2:dockercommitを使用して画像を変更する

実行中のコンテナのスナップショットを取り、それを独自のイメージに変換できる別の方法があります。

dummy:0.1を作成しましょう 同一のイメージですが、今回はDockerfileを使用していません。 alpine:latestを使用したので dummy:0.1として のベース、その画像のコンテナをスピンアップします。

docker run --rm --name alpine -ti alpine ash

コンテナ内に、Python3パッケージを追加します。apk add --no-cache python3 。完了したら、新しいターミナルウィンドウを開き、次のコマンド(または同様のコマンド)を実行します

docker container commit --change='ENTRYPOINT ["python3", "-c", "print(\"Hello World\")"]' alpine dummy:0.4

--changeを使用 フラグ新しいdummy:04にDockerfile命令を追加しています 画像(この場合、ENTRYPOINT 指示)。

docker container commitを使用 コマンドでは、基本的に最も外側のr/wレイヤーをr/oレイヤーに変換し、それを既存の画像のレイヤーに追加して、新しい画像を作成します。この方法はより直感的でインタラクティブなので、Dockerfilesの代わりにこれを使用することをお勧めしますが、これはあまり再現性がないことを理解してください。また、既存のレイヤーの削除または変更にも同じルールが適用されます。少なくともほとんどの場合、何かを削除したり、前のレイヤーで行った何かを変更したりするためだけにレイヤーを追加することは最善の方法ではありません。

これでこの記事は終わりです。これがお役に立てば幸いです。ご不明な点がございましたら、下にコメントしてください。


Docker
  1. ホスト間でDockerイメージを移動する方法

  2. Dockerイメージサイズを縮小する方法:6つの最適化方法

  3. Dockerイメージをあるサーバーから別のサーバーにパッケージ化して転送する方法

  1. Dockerfileを使用してDockerイメージを構築する方法

  2. Dockerイメージを他の人と共有する方法

  3. Dockerイメージに変更をコミットする方法

  1. Docker:実用的な方法でそれを使用する方法-パート3

  2. ビルド済みのDockerイメージ入門

  3. Dockerイメージのコンテンツを分析および調査する方法