KAEDE Hack blog

JavaScript 中心に ライブラリなどの使い方を解説する技術ブログ。

Docker で Ubuntu bash の特定のコンテナを使い続ける

why

  • docker-comopse が業務で必要になったが、Docker が Apache と混じるくらい理解が浅いので、基礎の勉強の必要性を感じた
  • ちょうど Twitter で米国データサイエンティストの かめさん がセールしてた 人気の udemy 講座を買っていたのでやった

twitter.com

  • この人

www.udemy.com

  • このコース

  • メニューにはdocker-compose まではない。

  • これを

結果

  • Docker コンテナ で Ubuntu Bash を動かす
  • テキストファイルを保存
  • Docker コンテナから exit
  • さっきのコンテナに入ってさっき保存したテキストファイルを見る

ここまでできるようになった

Ubuntu を使う

f:id:kei_s_lifehack:20200929042842p:plain

docker run hello-world
docker run -it ubuntu bash
  • hello-world イメージは別で扱ったので省略
  • 今回は ubuntu bash を動かす。

上記の2つの違いは

  • -it が bash を起動するのに必要な「おまじない」であり
  • bash がコンテナ起動時に必要なプログラムになるらしい
  • bash は Kernel という OS の核の囲い、ユーザーの入力を受け付けるところになる
  • -iは標準入力を開き続ける
  • -tは疑似ttyの割り当てで、
  • お手元の環境で、docker内入力ができるようにする呪文

だそう。 実際に試してみる。まずは docker login

id は このサービスでは kaedeio だった. kaede0902 に統一したい

docker run -it ubuntu bash
root@fbb35a34304c:/# 
  • Ubuntu OS / bash Shell が動いた!やった!

毎回違うコンテナを動かしているのでファイルが保存できない

  • ただ、毎回これで作成しているとUbuntu 内部のファイルは毎回消える
root@fbb35a34304c:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  
mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@fbb35a34304c:/# mkdir new_dir
root@fbb35a34304c:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  
mnt  new_dir  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@fbb35a34304c:/# exit
exit
docker run -it ubuntu bash
root@10075622af77:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  
mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

root@ の後の id からして 別の bash が開いているようだ。

この id はコンテナの id なので、コンテナが毎回別のものになってる

つまり 毎回 docker run -it ubuntu bashUbuntu Bash を開く方法では ファイルシステムの中にファイルを保存しておくことはできない!

hacknote.jp

このやり方だとイメージがスナップショット、一時的なもの?になっているから exit した時に消えてしまうらしい。

ワーキングスペースと4つのレイヤーについて

どうやら Docker を使う場合、この二種類のワーキングスペースがある。

  • Host (MBP/bash) にいる場合
  • Container (Ubuntu/bash) にいる場合

今回の講座での Ubuntu は4つの Layer Images を pull して作られるが、

その 4つのレイヤーの 一番上に新しい 保存可能な Layer が作成される。

これがコンテナ id になるようだ。

ここがファイルをおくところと解釈する。

1 つの Dockerfile から コンテナは複数作ることができるが、4 つのレイヤのうち、異なるのは一番上の一つだけ ( id 部分? ) で残りの 3 つの部分は共通となる

この仕組みの利点としては、新しくコンテナB を、同じ Docker イメージから作成した時、下 3 つのイメージレイヤーを再利用できるので、ストレージを圧迫しないで済むらしい

Docker イメージを再起動する

Docker コンテナ id 10075622af77 に aaa.txt を作成して exit

root@10075622af77:/# touch aaa.txt
root@10075622af77:/# exit
exit
  • id 10075622af77 の Ubuntu コンテナに aaa.txt を touch で作成した

コンテナ 10075622af77 から exit してホストである MBP のシェルに戻る exit した コンテナをプロセス履歴から確認

docker ps -a                                                                                                      
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS                          PORTS
                      NAMES                                                                                                            
10075622af77        ubuntu                           "bash"                   23 hours ago        Exited (0) About a minute ago        
                      elegant_euler 

docker ps -a で 終了したプロセスをリストアップする さっき終了したこれが確認できた

  • id 10075622af77
  • image ubuntu
  • command bash
  • exited about a min ago

exit したコンテナを id 指定で再起動

docker restart 10075622af77
10075622af77
docker restart elegant_euler
elegant_euler

しない

docker ps
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                    NAMES
10075622af77        ubuntu                           "bash"                   23 hours ago        Up 16 seconds                                elegant_euler
99529632c371        kaede0902/docker-nextjs:latest   "docker-entrypoint.s…"   4 days ago          Up 4 days           0.0.0.0:3333->3000/tcp   inspiring_gagarin

アクティブなプロセスを出してみると、status が up 16s になっている これはすでに動いてるから入れないってことだろうか?

プロセスを殺す

docker kill 10075622af77
10075622af77
docker ps
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                    NAMES
99529632c371        kaede0902/docker-nextjs:latest   "docker-entrypoint.s…"   4 days ago          Up 4 days           0.0.0.0:3333->3000/tcp   inspiring_gagarin
  • id を指定してプロセスを殺した

再び再起動

無事居なくなっている ここで docker restart 10075622af77 で...

docker restart 10075622af77
10075622af77
  • これだけでは入れなかった
docker exec -it 10075622af77 bash
root@10075622af77:/# ls
aaa.txt  bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
  • restart した上で exec する必要があった

違うプロセスが走っています docker start -a で attache MySQLDなどでは attache と exec では結果が違います

  • しかし、正確には同じコンテナを動かせていても 違うプロセスが動いているらしい。これは後で調べる

まとめ

docker run -it ubuntu bash
root@fbb35a34304c:/# 
  • これで ubuntu bash のコンテナを作成して
  • 同時に起動して
root@fbb35a34304c:/# exit
exit
  • これで exit して
docker ps -a
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS                          PORTS
                      NAMES
10075622af77        ubuntu                           "bash"                   23 hours ago        Exited (0) About a minute ago
                      elegant_euler 
  • プロセスを確認して
docker kill 10075622af77
10075622af77
  • 殺したくなったら殺して
docker restart 10075622af77
10075622af77
docker exec -it 10075622af77 bash
root@10075622af77:/# ls
aaa.txt  bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
  • restart してコンテナを動かして、 exec して 入って作業する

  • これで Docker で Ubuntu を立ち上げて作業できるようになった!