20220111のdockerに関する記事は3件です。

DockerでSFTPサーバ立ててGoでアクセスしてみる

最初に GoのSFTPパッケージ触りたかったけど、サーバ立てるのも面倒だったのでコンテナでサクッとやっちゃおうと思ったメモ SFTPサーバ立てるメモ atmoz/sftpを使って docker-compose.yml version: '3' services: sftp: image: atmoz/sftp container_name: sftp-server volumes: - ./sftp-server/upload:/home/foo/upload ports: - "2222:22" command: foo:pass:::upload な感じでyaml用意して mkdir sftp-server mkdir sftp-server/upload docker-compose up -d --build sftp -oPort="2222" foo@localhost な感じでコマンド叩いて、パスワードにpassって入れたら接続できる。 sftp> cd upload sftp> put test sftp> exit な感じでupload以下にファイル配置OK Go SFTPが用意できたので、github.com/pkg/sftpとgolang.org/x/crypto/sshのサンプル参考に main.go package main import ( "fmt" "log" "os" "github.com/pkg/sftp" "golang.org/x/crypto/ssh" ) func main() { if err := Main(); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } func Main() error { host := "localhost" port := "2222" user := "foo" pass := "pass" fmt.Println("Create sshClientConfig") sshConfig := &ssh.ClientConfig{ User: user, Auth: []ssh.AuthMethod{ ssh.Password(pass), }, HostKeyCallback: ssh.InsecureIgnoreHostKey(), } fmt.Println("SSH connect") addr := fmt.Sprintf("%s:%s", host, port) fmt.Println(addr) conn, err := ssh.Dial("tcp", addr, sshConfig) if err != nil { return err } fmt.Println("open an SFTP session over an existing ssh connection") client, err := sftp.NewClient(conn) if err != nil { return err } defer client.Close() fmt.Println("walk a directory") w := client.Walk("./") for w.Step() { if w.Err() != nil { continue } log.Println(w.Path()) } fmt.Println("leave your mark") f, err := client.Create("./upload/hello.txt") if err != nil { return err } if _, err := f.Write([]byte("Hello world!")); err != nil { return err } f.Close() fmt.Println("check it's there") fi, err := client.Lstat("./upload/hello.txt") if err != nil { return err } log.Println(fi) return nil } な感じで接続OK kotaoue/go-sftpにコードおいておく ?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンテナのレイヤ構造を調べた時の備忘録

を読んで、レイヤ構造の実現方法について興味がわいたので少し詳しく調べてみた。 こちらの本は、Dockerの内部で使われている技術について簡潔に説明されていておすすめ。 コンテナのイメージはコンテナ実行時のrootfsとその設定ファイル。 イメージのrootfs部はレイヤ構造で管理されている イメージにはポータビリティがあり、イメージのフォーマットはOCI Image Specificationで定義されている フォーマットは特定のファイルシステム(overlayやbtrfsなど)には依存しない形で定義されている レイヤごとにそのディレクトリ構造がtarで固められているような感じ docker saveで出力されるフォーマットと似ているけれどちょっと違う イメージを配布するときの仕様としてOCI Image Distribution Specificationがある。Docker HubなどのコンテナイメージレジストリのAPIを定義したもの。 コンテナを起動するときには、イメージがファイルシステムに展開されてコンテナが使うrootfsになる。どうやって展開するかはコンテナランタイムがイメージ展開に使うファイルシステム(ストレージドライバ)次第。 イメージはレイヤごとにデータが別れている(tarになっている)ので、それを重ね合わせて一つのrootfsにする必要がある。そのため、レイヤ構造に対応したoverlay2やbtrfsなどのファイルシステムの仕組みが使われる。 overlay2がデフォルト。overlay2は複数のディレクトリを重ね合わせて一つのディレクトリに見せることができる。重ね合わせるディレクトリがイメージのレイヤに1対1で対応する形となり、直感的でわかりやすい。最上位のReadWrite可能なCoWな層が来る。 btrfsがつかわれることも増えている? overlayは最上位にCoWの層を被せる形だが、btrfsはファイルシステム全体でCoWな動作をする。サブボリュームとそのスナップショットという概念があり、スナップショットがイメージのレイヤに対応する。 ファイルシステムに展開したrootfsを使って、コンテナ(=プロセスが実行できる閉鎖環境)が作成されて、その中でプロセスが実行される コンテナの実行環境、すなわちコンテナランタイムは高レベルと低レベルの2層に分かれている。 イメージの作成や展開、配布は高レベルランタイムの役割 高レベルランタイムから渡される展開済みのrootfsや実行時設定を用いて、プロセスの実行環境を作って実行開始するのが低レベルランタイムの役割 高レベルランタイムで有名なのはdocker、containerd。 低レベルランタイムではrunc。 高レベルランタイムから低レベルランタイムへrootfsを渡すときの仕様は、OCI Runtime Filesystem bundleに定義されている 以下では、ストレージドライバとしてoverlayとbtrfsを使ったときの、イメージの作成と展開の内部動作(レイヤデータがどのように管理されるか)を比較してみてみる。 環境 M1 iMac multipassでubuntu20.04をインストール overlay2の動作 overlay2単体の動作を確認しておく。 マウントする際にlowerdirとuppderdirを指定する。 lowerdirはreadonlyな層。複数のディレクトリを設定することができる。 upperdirはCoWな層。 マウント先のディレクトリは、lowerdirとuppderdirが重ね合わされた状態にみえるようになる マウント先のディレクトリに書き込みを行うとupperdirに実体が書き込まれる lowerdirにあるファイルを変更すると、uppderdirにコピーされて変更した実体が書き込まれる(CoW = Copy on Write) このときlowerdirのファイルは変更されずそのままの状態が維持される レイヤとして重ね合わさせるディレクトリを二つ用意する。 $ mkdir 1st_layer $ mkdir 2nd_layer $ echo hello > ./1st_layer/hello.txt $ echo bye > ./2nd_layer/bye.txt CoW層にするディレクトリ(upper)と、作業ディレクトリ(work)、重ね合わせ先のディレクトリ(merged)を用意する。 $ mkdir upper work merged overlay fsでマウントする $ mount -t overlay overlay -olowerdir=1st_layer:2nd_layer,upperdir=upper,workdir=work merged マウントしたディレクトリをみると1stと2ndのディレクトリが重ね合わせられていることがわかる。 $ ls merged/ bye.txt hello.txt マウントしたディレクトリに新しいファイルを書き込む。 $ echo goodmorning > ./merge/goodmorning.txt $ ls ./merged/ bye.txt goodmorning.txt hello.txt 実体がupperディレクトリに保存されたことがわかる。 $ ls ./upper/ goodmorning.txt マウントしたディレクトリに1st_layerにあるファイルの内容を変更して保存する。 $ echo 'hello,world!' > ./merge/hello.txt upperディレクトリには新しいhello.txtが書き込まれ、1st_layerには古いhello.extが維持されることがわかる。 $ cat ./upper/hello.txt hello,world! $ cat ./1st_layer/hello.txt hello アンマウントするとmergedディレクトリの内容は見えなくなるが、upperディレクトリの内容を維持され、再度マウントすればmergedディレクトリの内容は復元される。 $ sudo umount merged $ ls merged/ $ ls upper/ goodmorning.txt hello.txt $ sudo mount -t overlay overlay -olowerdir=1st_layer:2nd_layer,upperdir=upper,workdir=work merged $ ls ./merged/ bye.txt goodmorning.txt hello.txt btrfsの動作 btrfsの単体動作を確認しておく。 マウントするためのループバックデバイスファイルを作る。 $ dd if=/dev/zero of=btrfs.img count=2097152 btrfsでフォーマットしてマウントする。 $ mkfs.btrfs btrfs.img $ mkdir btrfs $ mount -t btrfs -o loop btrfs.img ./btrfs サブボリュームを作成する。 $ cd ./btrfs $ btrfs subvolume create vol サブボリュームにファイルを書き込んでスナップショットを撮る。 $ echo hello > ./vol/hello.txt $ btrfs subvolume snapshot vol 1st_layer Create a snapshot of 'vol' in './1st_layer' $ ls ./1st_layer hello.txt さらにファイルを書き込んでスナップショットを撮る。 $ echo bye > ./vol/bye.txt $ btrfs subvolume snapshot vol 2nd_layer Create a snapshot of 'vol' in './2nd_layer' さらにファイルを書き込む。 $ echo goodmorning > ./vol/goodmorning.txt $ ls ./vol bye.txt goodmorning.txt hello.txt 1st_layerとして撮ったスナップショットに含まれるファイルを変更して上書き保存する。 $ echo 'hello,world!' > ./vol/hello.txt $ cat ./vol/hello.txt hello,world! 1st_layerと2nd_layerはスナップショットの時のまま。 $ ls ./1st_layer/ hello.txt $ cat ./1st_layer/hello.txt hello $ ls ./2nd_layer/ bye.txt hello.txt $ cat ./2nd_layer/hello.txt hello Dockerのストレージドライバーにoverlay2を利用した時の動作 alphineをベースに、ファイルを2つ足したイメージを作成する。 FROM alpine:latest ADD hello.sh /hello.sh ADD bye.sh /bye.sh ENTRYPOINT [ "/hello.sh" ] /var/libldocker/overlay2の初期状態 $ sudo tree /var/lib/docker/overlay2 /var/lib/docker/overlay2 └── l 1 directory, 0 files イメージをビルドした後の/var/lib/docker/overlay2。 alpineのレイヤと、ADD hello.txtしたレイヤと、ADD bye.txtをしたレイヤの3つのレイヤが存在する。 $ sudo tree -L 3 /var/lib/docker/overlay2 /var/lib/docker/overlay2 ├── 0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02 │   ├── committed │   ├── diff │   │   └── hello.sh │   ├── link │   ├── lower │   └── work ├── 0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb │   ├── committed │   ├── diff │   │   └── bye.sh │   ├── link │   ├── lower │   └── work ├── a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63 │   ├── committed │   ├── diff │   │   ├── bin │   │   ├── dev │   │   ├── etc │   │   ├── home │   │   ├── lib │   │   ├── media │   │   ├── mnt │   │   ├── opt │   │   ├── proc │   │   ├── root │   │   ├── run │   │   ├── sbin │   │   ├── srv │   │   ├── sys │   │   ├── tmp │   │   ├── usr │   │   └── var │   └── link └── l ├── AG7NYAURZHT73HZEZSGJ3XGQ5B -> ../0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb/diff ├── PDTAA47PQXCBIZBATEN6E4PKP3 -> ../0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02/diff └── WGD67YG7S35SU3FMVJCQUNUZIO -> ../a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63/diff イメージをdocker saveで書き出してみる。 alpineとADD hello.shとADD bye.shの3つのレイヤに対応するディレクトリが存在する。 $ docker save myimage:v1 | tar -xC ./myimage_v1.save/ $ tree ./myimage_v1.save/ ./myimage_v1.save/ ├── 27fd369832323dc013779a181a41732ad0b7d66c97c04af0c32025607263dec9.json ├── 387e5af651d6cd8c93ab10a7ad0a8fcc3e8d35b667a435e04e9a4606e209e571 │   ├── VERSION │   ├── json │   └── layer.tar ├── 4f6401c78ad9c5468f2a129c43be7f15d2293b3c11a9aec190120cf7411e14a1 │   ├── VERSION │   ├── json │   └── layer.tar ├── 60a4e2ecf7404dad03beac1f1e2110e045541774463678407f3e62c7664a5653 │   ├── VERSION │   ├── json │   └── layer.tar ├── manifest.json └── repositories 3 directories, 12 files tarファイルの中を見ると、各レイヤのファイルが入っていることが確認できる $ tar -tf ./myimage_v1.save/387e5af651d6cd8c93ab10a7ad0a8fcc3e8d35b667a435e04e9a4606e209e571/layer.tar bye.sh $ tar -tf ./myimage_v1.save/4f6401c78ad9c5468f2a129c43be7f15d2293b3c11a9aec190120cf7411e14a1/layer.tar hello.sh docker runしてみる。 /var/lib/docker/overlay2は下記のようになる。 b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3にmergedディレクトリがあり、これがコンテナ実行時に参照するrootfsディレクトリと思われる。 $ sudo tree -L 3 /var/lib/docker/overlay2 /var/lib/docker/overlay2 ├── 0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02 │   ├── committed │   ├── diff │   │   └── hello.sh │   ├── link │   ├── lower │   └── work ├── 0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb │   ├── committed │   ├── diff │   │   └── bye.sh │   ├── link │   ├── lower │   └── work ├── a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63 │   ├── committed │   ├── diff │   │   ├── bin │   │   ├── dev │   │   ├── etc │   │   ├── home │   │   ├── lib │   │   ├── media │   │   ├── mnt │   │   ├── opt │   │   ├── proc │   │   ├── root │   │   ├── run │   │   ├── sbin │   │   ├── srv │   │   ├── sys │   │   ├── tmp │   │   ├── usr │   │   └── var │   └── link ├── b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3 │   ├── diff │   ├── link │   ├── lower │   ├── merged │   │   ├── bin │   │   ├── bye.sh │   │   ├── dev │   │   ├── etc │   │   ├── hello.sh │   │   ├── home │   │   ├── lib │   │   ├── media │   │   ├── mnt │   │   ├── opt │   │   ├── proc │   │   ├── root │   │   ├── run │   │   ├── sbin │   │   ├── srv │   │   ├── sys │   │   ├── tmp │   │   ├── usr │   │   └── var │   └── work │   └── work ├── b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3-init │   ├── committed │   ├── diff │   │   ├── dev │   │   └── etc │   ├── link │   ├── lower │   └── work │   └── work └── l ├── 5BPXIBWUPBY4RMSRNRB6CUNVOU -> ../b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3/diff ├── AG7NYAURZHT73HZEZSGJ3XGQ5B -> ../0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb/diff ├── PDTAA47PQXCBIZBATEN6E4PKP3 -> ../0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02/diff ├── WGD67YG7S35SU3FMVJCQUNUZIO -> ../a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63/diff └── ZEXDBFNALOHVMEXO27IWF2RQNA -> ../b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3-init/diff 59 directories, 17 files mount状態を確認してみる。 mount | grep overlay overlay on /var/lib/docker/overlay2/b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/ZEXDBFNALOHVMEXO27IWF2RQNA:/var/lib/docker/overlay2/l/AG7NYAURZHT73HZEZSGJ3XGQ5B:/var/lib/docker/overlay2/l/PDTAA47PQXCBIZBATEN6E4PKP3:/var/lib/docker/overlay2/l/WGD67YG7S35SU3FMVJCQUNUZIO,upperdir=/var/lib/docker/overlay2/b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3/diff,workdir=/var/lib/docker/overlay2/b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3/work,xino=off) 下記のようになっている。b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3にコンテナ実行時にupperdir, workdir, マウントポイント(merged)が含まれている。 マウントポイント:b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3/merged lowerdir: ZEXDBFNALOHVMEXO27IWF2RQNA (/devと/etc) AG7NYAURZHT73HZEZSGJ3XGQ5B(bye.sh) PDTAA47PQXCBIZBATEN6E4PKP3 (hello.sh) WGD67YG7S35SU3FMVJCQUNUZIO (alpine) upperdir: b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3/diff workdir: b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3/work コンテナを停止してみる。 overlayでのマウントは解除されている。 /var/lib/docker/overlay2のディレクトリはそのまま残っている(umountされたのでmergedディレクトリは空) $ mount | grep overlay $ sudo tree -L 3 /var/lib/docker/overlay2 /var/lib/docker/overlay2 ├── 0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02 ... ├── 0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb ... ├── a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63 ... ├── b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3 │   ├── diff │   ├── link │   ├── lower │   └── work │   └── work ├── b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3-init │   ├── committed │   ├── diff │   │   ├── dev │   │   └── etc │   ├── link │   ├── lower │   └── work │   └── work └── l ├── 5BPXIBWUPBY4RMSRNRB6CUNVOU -> ../b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3/diff ├── AG7NYAURZHT73HZEZSGJ3XGQ5B -> ../0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb/diff ├── PDTAA47PQXCBIZBATEN6E4PKP3 -> ../0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02/diff ├── WGD67YG7S35SU3FMVJCQUNUZIO -> ../a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63/diff └── ZEXDBFNALOHVMEXO27IWF2RQNA -> ../b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3-init/diff 41 directories, 15 files コンテナを削除してみる。 コンテナ起動時に作成されたディレクトリ(b7009e00bf2ce43b3d377a368c0a096939d05861c9e0db9b91959520a3327bc3)が削除された。 $ sudo tree -L 3 /var/lib/docker/overlay2 /var/lib/docker/overlay2 ├── 0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02 ... ├── 0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb ... ├── a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63 ... └── l ├── AG7NYAURZHT73HZEZSGJ3XGQ5B -> ../0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb/diff ├── PDTAA47PQXCBIZBATEN6E4PKP3 -> ../0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02/diff └── WGD67YG7S35SU3FMVJCQUNUZIO -> ../a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63/diff 29 directories, 10 files もう一度コンテナを起動し、ファイル(goodmorning.txt)を追加してみる。 goodmorning.txtがmerged(mountポイント)とdiff(upperdir)のディレクトリに追加されている /var/lib/docker/overlay2 ... ├── c4b29c99de3813c94ab2054dfa840e2cbe116f9f90dd2ea530f322e5bd4ec326 │   ├── diff │   │   ├── goodmorning.txt │   │   └── root │   ├── link │   ├── lower │   ├── merged │   │   ├── bin │   │   ├── bye.sh │   │   ├── dev │   │   ├── etc │   │   ├── goodmorning.txt │   │   ├── hello.sh │   │   ├── home │   │   ├── lib │   │   ├── media │   │   ├── mnt │   │   ├── opt │   │   ├── proc │   │   ├── root │   │   ├── run │   │   ├── sbin │   │   ├── srv │   │   ├── sys │   │   ├── tmp │   │   ├── usr │   │   └── var │   └── work │   └── work ... コンテナを止めて ├── c4b29c99de3813c94ab2054dfa840e2cbe116f9f90dd2ea530f322e5bd4ec326 │   ├── diff │   │   ├── goodmorning.txt │   │   └── root │   ├── link │   ├── lower │   └── work │   └── work commitしてみる。 fde1c170aea126638e876aa80ffd33d746d7a12f70c82ee1042c5fea7111ed96が増えている。イメージとcommit時のコンテナ状態の差分ファイル(goodmorning.txt)が入っている $ sudo tree -L 3 /var/lib/docker/overlay2 /var/lib/docker/overlay2 ├── 0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02 ... ├── 0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb ... ├── a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63 ... ├── c4b29c99de3813c94ab2054dfa840e2cbe116f9f90dd2ea530f322e5bd4ec326 │   ├── diff │   │   ├── goodmorning.txt │   │   └── root │   ├── link │   ├── lower │   └── work │   └── work ├── c4b29c99de3813c94ab2054dfa840e2cbe116f9f90dd2ea530f322e5bd4ec326-init │   ├── committed │   ├── diff │   │   ├── dev │   │   └── etc │   ├── link │   ├── lower │   └── work │   └── work ├── fde1c170aea126638e876aa80ffd33d746d7a12f70c82ee1042c5fea7111ed96 │   ├── diff │   │   ├── goodmorning.txt │   │   └── root │   ├── link │   ├── lower │   └── work └── l ├── 7FDDE7YVUJGP4B2HAKI4GOD6E3 -> ../fde1c170aea126638e876aa80ffd33d746d7a12f70c82ee1042c5fea7111ed96/diff ├── AG7NYAURZHT73HZEZSGJ3XGQ5B -> ../0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb/diff ├── EHOQLPR52IOX6LHJ22RY3AK2U4 -> ../c4b29c99de3813c94ab2054dfa840e2cbe116f9f90dd2ea530f322e5bd4ec326/diff ├── PDTAA47PQXCBIZBATEN6E4PKP3 -> ../0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02/diff ├── WGD67YG7S35SU3FMVJCQUNUZIO -> ../a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63/diff └── WIAJFBDXFEMTIV7GACBMAJ5AOK -> ../c4b29c99de3813c94ab2054dfa840e2cbe116f9f90dd2ea530f322e5bd4ec326-init/diff コンテナを削除する。 コンテナ実行時に作成されたc4b29c99de3813c94ab2054dfa840e2cbe116f9f90dd2ea530f322e5bd4ec326は削除されている commit時に新たに作成されたfde1c170aea126638e876aa80ffd33d746d7a12f70c82ee1042c5fea7111ed96は残っている $ sudo tree -L 3 /var/lib/docker/overlay2 /var/lib/docker/overlay2 ├── 0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02 ... ├── 0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb ... ├── a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63 ... ├── fde1c170aea126638e876aa80ffd33d746d7a12f70c82ee1042c5fea7111ed96 │   ├── diff │   │   ├── goodmorning.txt │   │   └── root │   ├── link │   ├── lower │   └── work └── l ├── 7FDDE7YVUJGP4B2HAKI4GOD6E3 -> ../fde1c170aea126638e876aa80ffd33d746d7a12f70c82ee1042c5fea7111ed96/diff ├── AG7NYAURZHT73HZEZSGJ3XGQ5B -> ../0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb/diff ├── PDTAA47PQXCBIZBATEN6E4PKP3 -> ../0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02/diff └── WGD67YG7S35SU3FMVJCQUNUZIO -> ../a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63/diff 34 directories, 13 files まとめると、 /var/lib/docker/overlay2に各レイヤに対応するディレクトリが保存される レイヤで管理しているファイルはdiffサブディレクトリに保存される イメージからコンテナを起動すると、/var/lib/docker/overlay2にコンテナ用のディレクトリが増える overlayのupperdir, workdir, マウントポイント(merged)に対応するサブディレクトリがある lowerdirには、イメージを構成するレイヤのディレクトリのリストが設定される コンテナにはmergedサブディレクトリがrootfsとして渡される コンテナ実行中に追加、変更されたファイルはupperdirに保存される コンテナを削除するとこのディレクトリは削除される コンテナからイメージを作成すると、uppderdirの内容があらたなレイヤが作成されて、/var/lib/docker/overlay2に追加される イメージをdocker saveでエクスポートすると、各レイヤがtarファイルになって出力される(これはどんなストレージドライバでも同じ) Dockerのストレージドライバーにbtrfsを利用した時の動作 ストーレジドライバーをbtrfsに切り替える $ sudo systemctl stop docker $ sudo systemctl stop docker.socket $ sudo cp -au /var/lib/docker /var/lib/docker.bk $ sudo rm -rf /var/lib/docker/* $ dd if=/dev/zero of=btrfs.img count=2097152 $ mkfs.btrfs btrfs.img $ sudo mount -t btrfs -o loop btrfs.img /var/lib/docker $ sudo cp -au /var/lib/docker.bk/* /var/lib/docker/ $ sudo systemctl start docker $ sudo systemctl start docker.socket /var/lib/docker/btrfsの初期状態 /var/lib/docker/btrfsフォルダが作成されている /var/lib/docker/btrtfフォルダの中身は空 overlay2を検証した時のoverkay2フォルダは残っているが、おそらく参照されていない $ sudo tree -L 2 /var/lib/docker/ /var/lib/docker/ ├── btrfs ├── buildkit │ ├── cache.db │ ├── containerdmeta.db │ ├── content │ ├── executor │ ├── metadata_v2.db │ └── snapshots.db ├── containers ├── image │ ├── btrfs │ └── overlay2 ├── network │ └── files ├── overlay2 │ ├── 0e6729eab769f9cc6d5c2a551a7f8fe0b46776cf156e1f9340c28a71b8a83b02 │ ├── 0fa76ee07bcf4f15be0480d4d656c7e1a859b2867f9878ab3c2d884ecfe7f7fb │ ├── a52ae8547e061a5ba99f94c7be162210fd37e3f7384e1aa6052cb67a020cba63 │ ├── fde1c170aea126638e876aa80ffd33d746d7a12f70c82ee1042c5fea7111ed96 │ └── l ├── plugins │ ├── storage │ └── tmp ├── runtimes ├── swarm ├── tmp ├── trust └── volumes ├── backingFsBlockDev └── metadata.db 24 directories, 6 files 念の為、dockerdに認識されているイメージはないことを確認する。 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE イメージをビルドする。 btrfsにsubvolumesフォルダが作成されている alpine, ADD hello.sh, ADD bye.shの3つのレイヤに対応するサブボリュームがある $ sudo tree -L 3 /var/lib/docker/btrfs /var/lib/docker/btrfs └── subvolumes ├── 1e2fe26e24b54bddd9de09e8794d0c5db5dfdd2dee6c54ba13c39984822ca54e │ ├── bin │ ├── bye.sh │ ├── dev │ ├── etc │ ├── hello.sh │ ├── home │ ├── lib │ ├── media │ ├── mnt │ ├── opt │ ├── proc │ ├── root │ ├── run │ ├── sbin │ ├── srv │ ├── sys │ ├── tmp │ ├── usr │ └── var ├── 39a89c087e417a1aba16c3c400b36fa4247b351226417f7c193bcdaa37287319 │ ├── bin │ ├── dev │ ├── etc │ ├── hello.sh │ ├── home │ ├── lib │ ├── media │ ├── mnt │ ├── opt │ ├── proc │ ├── root │ ├── run │ ├── sbin │ ├── srv │ ├── sys │ ├── tmp │ ├── usr │ └── var └── 74cbac2e8c61e866ac8c07d849ea81383099c1dcf2ab092de7265569bb41375e ├── bin ├── dev ├── etc ├── home ├── lib ├── media ├── mnt ├── opt ├── proc ├── root ├── run ├── sbin ├── srv ├── sys ├── tmp ├── usr └── var 55 directories, 3 files docker saveでイメージをエクスポートしてみる。 overlay2の時と同じように、3つのレイヤがそれぞれtarファイルになっている エクスポートするとストレージドライバーに依存した情報はなくなる $ tree myimage_v1.btrfs.save/ myimage_v1.btrfs.save/ ├── 0c371df2ed57d0f8d21cd25798912caada2b111800f4fca2c82d1a02942d393c │ ├── VERSION │ ├── json │ └── layer.tar ├── 4f6401c78ad9c5468f2a129c43be7f15d2293b3c11a9aec190120cf7411e14a1 │ ├── VERSION │ ├── json │ └── layer.tar ├── 60a4e2ecf7404dad03beac1f1e2110e045541774463678407f3e62c7664a5653 │ ├── VERSION │ ├── json │ └── layer.tar ├── 89beb19f75feed20696df179293902464a54f736fa55d4728ea953bc6596dc90.json ├── manifest.json └── repositories 3 directories, 12 files $ tar -tf myimage_v1.btrfs.save/0c371df2ed57d0f8d21cd25798912caada2b111800f4fca2c82d1a02942d393c/layer.tar bye.sh ubuntu@ubuntu:~/getstarted/docker$ tar -tf myimage_v1.btrfs.save/4f6401c78ad9c5468f2a129c43be7f15d2293b3c11a9aec190120cf7411e14a1/layer.tar hello.sh btrfsのサブボリュームのリストを確認する btrfs上でたしかに3つのサブボリュームが認識されていることがわかる $ sudo btrfs subvolume list /var/lib/docker ID 256 gen 35 top level 5 path btrfs/subvolumes/74cbac2e8c61e866ac8c07d849ea81383099c1dcf2ab092de7265569bb41375e ID 259 gen 35 top level 5 path btrfs/subvolumes/39a89c087e417a1aba16c3c400b36fa4247b351226417f7c193bcdaa37287319 ID 261 gen 35 top level 5 path btrfs/subvolumes/1e2fe26e24b54bddd9de09e8794d0c5db5dfdd2dee6c54ba13c39984822ca54e コンテナを起動する。 サブボリュームが二つ増えている。末尾に-initがついているものと、ついていないもの initがついていない方がコンテナのrootfsとして使われるボリュームと思われる $ sudo ls /var/lib/docker/btrfs/subvolumes 1e2fe26e24b54bddd9de09e8794d0c5db5dfdd2dee6c54ba13c39984822ca54e 39a89c087e417a1aba16c3c400b36fa4247b351226417f7c193bcdaa37287319 3f31c3567b855de1a60d23ea0967ca8f3d18ea402c1168d5463ab78f54da0e8c 3f31c3567b855de1a60d23ea0967ca8f3d18ea402c1168d5463ab78f54da0e8c-init 74cbac2e8c61e866ac8c07d849ea81383099c1dcf2ab092de7265569bb41375e $ sudo tree -L 2 /var/lib/docker/btrfs/subvolumes /var/lib/docker/btrfs/subvolumes ├── 1e2fe26e24b54bddd9de09e8794d0c5db5dfdd2dee6c54ba13c39984822ca54e │ ├── bin │ ├── bye.sh │ ├── dev │ ├── etc │ ├── hello.sh │ ├── home │ ├── lib │ ├── media │ ├── mnt │ ├── opt │ ├── proc │ ├── root │ ├── run │ ├── sbin │ ├── srv │ ├── sys │ ├── tmp │ ├── usr │ └── var ├── 39a89c087e417a1aba16c3c400b36fa4247b351226417f7c193bcdaa37287319 │ ├── bin │ ├── dev │ ├── etc │ ├── hello.sh │ ├── home │ ├── lib │ ├── media │ ├── mnt │ ├── opt │ ├── proc │ ├── root │ ├── run │ ├── sbin │ ├── srv │ ├── sys │ ├── tmp │ ├── usr │ └── var ├── 3f31c3567b855de1a60d23ea0967ca8f3d18ea402c1168d5463ab78f54da0e8c │ ├── bin │ ├── bye.sh │ ├── dev │ ├── etc │ ├── hello.sh │ ├── home │ ├── lib │ ├── media │ ├── mnt │ ├── opt │ ├── proc │ ├── root │ ├── run │ ├── sbin │ ├── srv │ ├── sys │ ├── tmp │ ├── usr │ └── var ├── 3f31c3567b855de1a60d23ea0967ca8f3d18ea402c1168d5463ab78f54da0e8c-init │ ├── bin │ ├── bye.sh │ ├── dev │ ├── etc │ ├── hello.sh │ ├── home │ ├── lib │ ├── media │ ├── mnt │ ├── opt │ ├── proc │ ├── root │ ├── run │ ├── sbin │ ├── srv │ ├── sys │ ├── tmp │ ├── usr │ └── var └── 74cbac2e8c61e866ac8c07d849ea81383099c1dcf2ab092de7265569bb41375e ├── bin ├── dev ├── etc ├── home ├── lib ├── media ├── mnt ├── opt ├── proc ├── root ├── run ├── sbin ├── srv ├── sys ├── tmp ├── usr └── var 90 directories, 7 files コンテナを停止する ボリュームはそのまま $ sudo ls /var/lib/docker/btrfs/subvolumes 1e2fe26e24b54bddd9de09e8794d0c5db5dfdd2dee6c54ba13c39984822ca54e 39a89c087e417a1aba16c3c400b36fa4247b351226417f7c193bcdaa37287319 3f31c3567b855de1a60d23ea0967ca8f3d18ea402c1168d5463ab78f54da0e8c 3f31c3567b855de1a60d23ea0967ca8f3d18ea402c1168d5463ab78f54da0e8c-init 74cbac2e8c61e866ac8c07d849ea81383099c1dcf2ab092de7265569bb41375e コンテナを削除 コンテナを起動した時に作られた2つのボリュームが削除されている $ sudo ls /var/lib/docker/btrfs/subvolumes 1e2fe26e24b54bddd9de09e8794d0c5db5dfdd2dee6c54ba13c39984822ca54e 39a89c087e417a1aba16c3c400b36fa4247b351226417f7c193bcdaa37287319 74cbac2e8c61e866ac8c07d849ea81383099c1dcf2ab092de7265569bb41375e もう一度コンテナを起動して、今度はファイルを追加してみる。 7febがコンテナのrootfsと思われる $ sudo ls /var/lib/docker/btrfs/subvolumes 1e2fe26e24b54bddd9de09e8794d0c5db5dfdd2dee6c54ba13c39984822ca54e 39a89c087e417a1aba16c3c400b36fa4247b351226417f7c193bcdaa37287319 74cbac2e8c61e866ac8c07d849ea81383099c1dcf2ab092de7265569bb41375e 7feb15948d4cec72eb67541739fc8e3281b041f2ad4de9737de781e88a413fa7 7feb15948d4cec72eb67541739fc8e3281b041f2ad4de9737de781e88a413fa7-init goodmorning.txtを追加する たしかに7febにgoodmorning.txtに追加されている $ sudo tree -L 1 /var/lib/docker/btrfs/subvolumes/7feb15948d4cec72eb67541739fc8e3281b041f2ad4de9737de781e88a413fa7 /var/lib/docker/btrfs/subvolumes/7feb15948d4cec72eb67541739fc8e3281b041f2ad4de9737de781e88a413fa7 ├── bin ├── bye.sh ├── dev ├── etc ├── goodmorning.txt ├── hello.sh ├── home ├── lib ├── media ├── mnt ├── opt ├── proc ├── root ├── run ├── sbin ├── srv ├── sys ├── tmp ├── usr └── var 17 directories, 3 files コンテナを停止するして、docker commitして新たなイメージを作る。 新しいサブモジュール(6f5a)が一つ増えている $ sudo ls /var/lib/docker/btrfs/subvolumes 1e2fe26e24b54bddd9de09e8794d0c5db5dfdd2dee6c54ba13c39984822ca54e 39a89c087e417a1aba16c3c400b36fa4247b351226417f7c193bcdaa37287319 6f5a4d262345aa7825136834fc851ba001de00ebb5ba1bb0c40fc53ccb2cff9a 74cbac2e8c61e866ac8c07d849ea81383099c1dcf2ab092de7265569bb41375e 7feb15948d4cec72eb67541739fc8e3281b041f2ad4de9737de781e88a413fa7 7feb15948d4cec72eb67541739fc8e3281b041f2ad4de9737de781e88a413fa7-init $ sudo tree -L 1 /var/lib/docker/btrfs/subvolumes/6f5a4d262345aa7825136834fc851ba001de00ebb5ba1bb0c40fc53ccb2cff9a /var/lib/docker/btrfs/subvolumes/6f5a4d262345aa7825136834fc851ba001de00ebb5ba1bb0c40fc53ccb2cff9a ├── bin ├── bye.sh ├── dev ├── etc ├── goodmorning.txt ├── hello.sh ├── home ├── lib ├── media ├── mnt ├── opt ├── proc ├── root ├── run ├── sbin ├── srv ├── sys ├── tmp ├── usr └── var 17 directories, 3 files コンテナを削除する。 コンテナ用のrootfsと使われていたボリューム(7feb)は削除されている docker commitして追加されたボリューム(6f5a)は残っている $ sudo ls /var/lib/docker/btrfs/subvolumes 1e2fe26e24b54bddd9de09e8794d0c5db5dfdd2dee6c54ba13c39984822ca54e 39a89c087e417a1aba16c3c400b36fa4247b351226417f7c193bcdaa37287319 6f5a4d262345aa7825136834fc851ba001de00ebb5ba1bb0c40fc53ccb2cff9a 74cbac2e8c61e866ac8c07d849ea81383099c1dcf2ab092de7265569bb41375e コンテナ起動時にrootfsとして使われているのは、コンテナ起動時に作成されて、コンテナ削除時に削除されるボリュームだと思われるが、本当にそうか、コンテナ内のプロセスのmountinfoを見て確かめる。 コンテナを再度起動する。 おそらくrootfsはcf4d $ sudo ls /var/lib/docker/btrfs/subvolumes 1e2fe26e24b54bddd9de09e8794d0c5db5dfdd2dee6c54ba13c39984822ca54e 39a89c087e417a1aba16c3c400b36fa4247b351226417f7c193bcdaa37287319 6f5a4d262345aa7825136834fc851ba001de00ebb5ba1bb0c40fc53ccb2cff9a 74cbac2e8c61e866ac8c07d849ea81383099c1dcf2ab092de7265569bb41375e cf4d6cec6764c68058b216099115f1485e146272a44ea69aa2d22c848e805307 cf4d6cec6764c68058b216099115f1485e146272a44ea69aa2d22c848e805307-init lsnsでnamespaceの一覧を表示する。 $ sudo lsns NS TYPE NPROCS PID USER COMMAND 4026531835 cgroup 136 1 root /sbin/init splash 4026531836 pid 135 1 root /sbin/init splash 4026531837 user 136 1 root /sbin/init splash 4026531838 uts 132 1 root /sbin/init splash 4026531839 ipc 135 1 root /sbin/init splash 4026531840 mnt 128 1 root /sbin/init splash 4026531860 mnt 1 21 root kdevtmpfs 4026531888 net 135 1 root /sbin/init splash 4026532140 mnt 1 410 root /lib/systemd/systemd-udevd 4026532141 uts 1 410 root /lib/systemd/systemd-udevd 4026532142 mnt 1 540 systemd-timesync /lib/systemd/systemd-timesyncd 4026532143 uts 1 540 systemd-timesync /lib/systemd/systemd-timesyncd 4026532144 mnt 1 589 systemd-network /lib/systemd/systemd-networkd 4026532145 mnt 1 591 systemd-resolve /lib/systemd/systemd-resolved 4026532148 mnt 1 7950 root sleep infinity 4026532149 uts 1 7950 root sleep infinity 4026532150 ipc 1 7950 root sleep infinity 4026532151 pid 1 7950 root sleep infinity 4026532153 net 1 7950 root sleep infinity 4026532202 mnt 1 638 root /usr/sbin/irqbalance --foreground 4026532203 mnt 1 646 root /lib/systemd/systemd-logind 4026532204 uts 1 646 root /lib/systemd/systemd-logind sleep infinityなプロセスがコンテナ内プロセスなので、このプロセスのマウント情報を/procで確認する。 たしかにマウントポイント "/"に、cf4dのボリュームがマウントされている $ cat /proc/7950/mountinfo | grep btrfs 754 709 0:55 /btrfs/subvolumes/cf4d6cec6764c68058b216099115f1485e146272a44ea69aa2d22c848e805307 / rw,relatime master:245 - btrfs /dev/loop3 rw,space_cache,subvolid=271,subvol=/btrfs/subvolumes/cf4d6cec6764c68058b216099115f1485e146272a44ea69aa2d22c848e805307 まとめると、 /var/lib/docker/btrfs/subvolumesに各レイヤに対応するサブボリュームが保存される イメージからコンテナを起動すると、/var/lib/docker/btrfs/subvolumesにコンテナ用のサブボリュームが増える コンテナ実行中に追加、変更されたファイルはこのサブモジュールに保存される このサブモジュールはコンテナを削除すると消える コンテナからイメージを作成すると、このサブモジュールからスナップショットが撮られて、新たなサブモジュールが追加される イメージをdocker saveでエクスポートすると、各レイヤがtarファイルになって出力される(これはどんなストレージドライバでも同じ)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerで仮想環境構築

新しくMac miniを導入したところ、HomebrewからVirtualBoxのインストールでこけるので、Dockerに移行しました。N予備校での講座を参考にしています。以下備忘録。 インストール Docker Desktopのインストール Windowsの場合 WSL2 Linux カーネル更新プログラムのインストール Dockerイメージの作成 Dockerfile FROM --platform=linux/x86_64 ubuntu:18.04 RUN yes | unminimize RUN apt-get update RUN apt-get install -y vim curl tmux tcpdump RUN locale-gen ja_JP.UTF-8 ENV LANG ja_JP.UTF-8 ENV TZ Asia/Tokyo WORKDIR /linux-study FROM : 構築する Docker イメージの元となる Docker イメージの指定 RUN : Docker イメージの構築で実行するコマンド ENV : Docker イメージの構築で環境変数の値を設定する WORKDIR : 作業ディレクトリの指定 docker-compose.yml version: '3' services: app: build: . tty: true volumes: - .:/linux-study version : DockerCompose ツールのバージョン services : 全体を構成する要素(サービス)をこれより下の階層で記述 app : サービスの名前。 build : 指定したディレクトリにあるDockerfileからDockerイメージを構築する tty : コンテナを起動させ続ける volumes : ファイル共有の設定 コマンド 起動 docker-compose up -d Dockerfile編集後の起動 docker-compose up -d --build 稼働中のコンテナ確認 docker-compose ps -a コンテナの中に入る docker-compose exec サービス名 bash 終了・破棄 docker-compose down
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む