Created by gh-md-toc
Take notes of Docker stuffs
いまさらだけどDockerに入門したので分かりやすくまとめてみた updated at 2019-12-17
VirtualBox、VMWare Player。
DockerはLinuxカーネルのnamespaceの機能を使ってコンテナ毎の区画化を実現している。
namespace毎に下記を管理している。
PID:プロセスに関して
Network:IPアドレス、ポート番号、ルーティング、フィルタリングなどのネットワークに関して
UID/GID:ユーザIDとグループIDに関して
MOUNT:マウントに関して
UTS:ホスト名やドメイン名に関して
IPC:メッセージキューなどのプロセス間通信に関して
DockerはLinuxカーネルのcgroupの機能を使ってコンテナが利用する物理マシンリソース(CPUやメモリなど)の割り当ての管理を実現している。
プロセスをグループ化して、グループごとにリソース使用量制限をかけている。
コンテナにはそれぞれ仮想NIC(eth0)が割り当てられ、172.17.0.0/16のセグメントのIPがDHCPで割り当てられる。
コンテナの仮想NICはホストOS上の1つのブリッジ(docker0)に接続されているためコンテナ同士で通信することが可能。
(リンク機能)
ただし、複数物理サーバが存在するマルチホスト環境において、異なる物理サーバへのリンク機能を使った通信は不可。
コンテナ内で確認したインターフェース情報は以下。 コンテナ側から見るとまるで物理NIC(eth0)のように見える。
# ip a
(省略)
34: eth0@if35: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
しかし、ホストOS側から見ると実体はvethであることが以下から分かる。 vethは、L2の仮想NICであり、コンテナのNIC(eth0)とホストOSのブリッジ(docker0)間でトンネリングをしている。
# ip a
(省略)
35: vethd48920c@if34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 9e:bd:4d:63:ed:38 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::9cbd:4dff:fe63:ed38/64 scope link
valid_lft forever preferred_lft forever
また、ホストOS上で以下の通り、docker0ブリッジを確認できる。
# ip a
(省略)
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:bd:f7:d8:19 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
- pull:Dockerイメージをレジストリから取得
- ls:Dockerイメージの一覧を表示
- inspect:Dockerイメージの詳細を表示
- tag:Dockerイメージにタグをつける
- push:Dockerイメージをレジストリへアップロード
- rm:Dockerイメージの削除
- save:Dockerイメージをtarファイルに保存
- load:saveで固めたtarからDockerイメージを作成
- import:exportで固めたtarファイルからDockerイメージを作成
- ls:コンテナの一覧を表示
- run:Dockerイメージからコンテナを生成
- stats:コンテナのリソース使用状況を表示
- logs:コンテナ内の実行ログ確認
- create:Dockerイメージからコンテナの生成
- start:コンテナの起動
- stop:コンテナの停止
- restart:コンテナの再起動
- pause:コンテナの一時停止
- unpause:一時停止中コンテナの起動
- rm:停止中コンテナの削除
- attach:稼働中コンテナに接続
- exec:稼働中コンテナに接続
- top:稼働中コンテナ内のプロセス一覧表示
- port:コンテナの公開ポート番号表示
- rename:コンテナの名前変更
- cp:コンテナとホストOS間でファイルとディレクトリのコピー
- diff:Dockerイメージが生成されてからの変更情報を表示
- commit:変更があったコンテナからイメージを作成
- export:コンテナをtarファイルに保存
- version:Dockerのバージョンを表示
- info:Dockerの実行環境情報を表示
- search:Docekrイメージの検索
- login:Docker Hubへログイン
- logout:Docker Hubからログアウト
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
搞了好久, 才發現問題出現在 RUN rm -rf /var/lib/mysql/* 這行, 當我建立出一個container後, 進去裡面看, /var/lib/mysql/ 竟然還有殘留兩個空目錄. 以至於造成entrypoint.sh 執行失敗. 至於為何 rm 指令無法刪除, 我做了許多實驗, 包括 added delay, sync, mv then delete, delete twice…..etc 某些組合會成功,某些組合會失敗. 搞得我好亂啊!! 乾脆先去睡一覺. 隔天起床後去問google 大神.
找的可能的原因了如下:
Cannot (force) remove directory in Docker build
unexpected file permission error in container
根據上面的討論, 懷疑是AUFS filesystem, 或者是有可能是linux kernel 的bug (或許在 4.4.6 版已經解決). 但是我的linux kernel 還太舊, 而且又不是x86 系統. 根本無法更新啊.
突然想到, 既然懷疑是AUFS 在存取 lower layer 和 upper layer 所造成的問題. 那就把它做在同一個 layer 就好了啊. 於是改寫dockerfile 如下:
strongstrong
strongstrong
quote
quote
- checklist1
- checklist2
- 1
- 2
- 3
- 1
- 2
- 3