More Related Content Similar to CAMPHOR- day 2020 - Docker 超入門
Similar to CAMPHOR- day 2020 - Docker 超入門 (20) CAMPHOR- day 2020 - Docker 超入門8. このトークで扱う範囲
• Linux 上の docker に限定 (Windows は今回は扱わない)
• Docker はランタイムとして runc を使用していると仮定
• これ以降に示すコマンドはすべて Ubuntu 18.04 において実行
11. Docker CLI
いわゆる docker コマンド
• docker run …
• docker build …
dockerd の REST API で通信
• TCP ソケット、 Unix ソケットなどを通じて通信
12. dockerd
• docker cli が使用する REST API を公開する daemon
• containerd と gRPC を通じて通信
Docker CLI
dockerd
containerd
RunC
Registry
REST API
gRPC
ランタイムとして使用
イメージの
Push/Pull
13. containerd
• gRPC Endpoint で待ち受ける daemon
• コンテナのライフサイクル管理
• イメージの push / pull
• runc などのランタイムのコマンドを実行する
Docker CLI
dockerd
containerd
RunC
Registry
REST API
gRPC
ランタイムとして使用
イメージの
Push/Pull
14. runc
• containerd が使用するランタイム
• 実際にコンテナを作成するのはココ!
• OCI (Open Container Initiative) の規格に準拠
Docker CLI
dockerd
containerd
RunC
Registry
REST API
gRPC
ランタイムとして使用
イメージの
Push/Pull
OCI とは
コンテナイメージやコンテナランタイムの
仕様を定めている団体
16. 名前空間
• PID などがコンテナ外から見えないようにするための仕掛け
• 基本的に名前空間の外は見えない
• 分離するもの
• PID (名前空間が違えば同じプロセス ID のプロセスが存在できる)
• MNT (ファイルシステムのツリーを完全に分離できる)
• NET (IP アドレス、ルーティングなどのネットワークスタックを分離)
• IPC (共有メモリ空間の分離)
• UTS (ホスト名、ドメインの分離)
• etc…
18. 名前空間の確認方法
• /proc/[pid] ディレクトリに、 各プロセスの情報が入っている
• /proc/self は特殊なリンクで、現在実行中のプロセスの情報にリ
ンクしている
• 例
• /proc/self/cwdはカレントディレクトリへのリンク
• /proc/self/exeは実行中のファイル
$ ls -la /proc/self/cwd /proc/self/exe
lrwxrwxrwx1root root 0 3月 28 11:41 /proc/self/cwd ->/root
lrwxrwxrwx1root root 0 3月 28 11:41 /proc/self/exe -> /bin/ls
19. 名前空間の確認方法
• /proc/self/ns ディレクトリにある!
$ls -l /proc/self/ns
total0
lrwxrwxrwx1rootroot0 3月 2811:48cgroup->'cgroup:[4026531835]'
lrwxrwxrwx1rootroot0 3月 2811:48ipc ->'ipc:[4026531839]'
lrwxrwxrwx1rootroot0 3月 2811:48mnt-> 'mnt:[4026531840]'
lrwxrwxrwx1rootroot0 3月 2811:48net-> 'net:[4026531992]'
lrwxrwxrwx1rootroot0 3月 2811:48pid-> 'pid:[4026531836]'
lrwxrwxrwx1rootroot0 3月 2811:48pid_for_children-> 'pid:[4026531836]'
lrwxrwxrwx1rootroot0 3月 2811:48user->'user:[4026531837]'
lrwxrwxrwx1rootroot0 3月 2811:48uts->'uts:[4026531838]'
20. 名前空間を見てみる
一番上はホスト側のシェル、下の 2 つはそれぞれ別のコンテナで
PID namespace を確認した結果
すべてバラバラ
$ls -l /proc/self/ns/pid
lrwxrwxrwx1rootroot0 3月 2812:07/proc/self/ns/pid-> 'pid:[4026531836]’
$ls -l /proc/self/ns/pid
lrwxrwxrwx1rootroot0Mar2803:10/proc/self/ns/pid-> 'pid:[4026532149]’
$ls -l /proc/self/ns/pid
lrwxrwxrwx1rootroot0Mar2803:11/proc/self/ns/pid-> 'pid:[4026532281]'
26. まとめ
• Docker は 1 つのアプリケーションではなくいくつかのモジュール
が連携して動いている
• runc ではコンテナ仮想化を実現するために名前空間をはじめと
する Linux カーネルの機能を使用している
• 他にも docker にまつわる Linux カーネルの機能はたくさんある
ので気になる人は以下の単語で調べてみてください
• Overlay File System
• Cgroup
• Etc…
Editor's Notes では、「Docker 超入門」というタイトルで話します 簡単に自己紹介
本名は巻田、 Twitter やってるんでフォローお願いします
今年の春から京大の大学院、情報学研究科の M1
普段はバイトで C# を書きつつ研究では Python で Deep Learning このトークでは主に 2 つのことに関して話します
モジュール間の関連性 (1 つのモノリシックなシステムではなく、複数のモジュールから構成されている)
ランタイム「runc」 がコンテナ間で環境を分離している仕組み
質問などあればこのライブのコメントに書くか、 Twitter のハッシュタグでつぶやいて Docker 使ってますか??
便利ですよね??? まず、 Docker とはそもそも何か???に関して話します
英単語としての docker は港とかで作業する人、の意味で、コンテナとかの積み下ろしなどをする人です
で、アプリケーションの docker はこれらの特徴
環境分離 コンテナに入れるとアプリケーション間の干渉が起こらない
同じ状況を再現 ライブラリ、ミドルウェアとかの環境がそっくりそのまま Docker は魔法ではなく、ちゃんとバックに動作の仕組みが存在する!
このトークの目標は
Docker が動いている仕組みをざっくりと理解する 今回は、 Linux 上の docker に関してのみ扱う。
Windows 上の docker も存在はするが、今回は扱わない
Docker ランタイム、 (これは後で説明) には runc を使用
ちなみに、今後に示すコマンドは ubuntu 18.04 で、 実行、 docker は snap で入れたもの、
あと、コマンドは基本的に root で実行してる まずは、 docker を構成するモジュールたちに関して解説 全体がこんな感じ、
今回jは左側の 4 つに関して解説。
ちなみに、右にある registry は docker image を格納しておくサービスで、 Docker Hub や GitHub Packages などが有名 まずは、 docker CLI に関して解説
いわゆる docker コマンドを叩いた時に最初に呼び出されるプログラム
このプログラムは dockerd が提供する REST API のクライアントになっている
REST API は TCP ソケットや Unix ソケットなどを通じて通信している Dockerd は cli が使用する REST API を公開している daemon
ちなみに、 linux 上のアプリケーションで d が最後に着くのは daemon と言ってバックグラウンドで動き続ける、 httpd とか sshd とか
REST API 内の動作は containerd と gRPC で通信して動いている Containerd は、 dockerd が使う gRPC インタフェースを提供
コンテナのライフサイクル管理、作成、起動、削除など
イメージの push と pull
コンテナ周りの具体的な機能はコンテナランタイムの runc に任せている Runc とは containerd が依存する、コンテナランタイムで、実際にコンテナを作ったりする
ただし、 runc は OCI が定めた企画に従って作成されている。
他にもランタイムは存在するので、代替可能
OCI はコンテナ周りの仕様を決めている団体で、コンテナランタイム以外にもイメージに関する企画も決めている 次は、 runc が環境の分離を実現している仕組みを解説 Runc では、ホスト OS とコンテナで同じ共有されたカーネルを使用している。
で、その中でものを分離するのに使われるのが namespace
これによって namespace 内から namespace 外のものが基本的に見えなくなるため環境が分離される
NS にはいくつかの種類があり、分離しているリソースが異なっている
一つずつ見ていくと、
PID name space は名前空間を分けることで同じプロセス ID のプロセスが存在できるようにする
MNT name space はファイルシステムのマウントポイントを他の name space から見えないようにしてファイルシステムのツリーを完全に分離する
network name space は IP アドレス、 NIC などの network stack を分離する
IPC name space はプロセス間通信で使用される共有メモリを、分離する
UTS name space は同じホストで複数の host name, domain の利用を可能にする
他にも色々ある。
詳しくはググってみてください
では、名前空間を実際に確認する方法を紹介
その前に、プロセスの情報を見る方法を紹介します
/proc ディレクトリの中を見ると、数字のディレクトリがいっぱい!
で、これの一部はプロセス ID に該当するもの
他に、 /proc/self は特別なリンクで、現在実行中のpid のディレクトリにリンクしている
つまり、 /proc/self ディレクトリに、現在実行中のプロセスに関する情報が入ってる。
中身はいろいろあるが、、、 cwd, exe はそれぞれカレントディレクトリ、実行中のプログラムへのリンクが張られている。 先ほどの /proc/self の中に、 /proc/self/ns というディレクトリがあり、その中に namespace に関する情報が入っている
ここを見ると nams space の一覧が見られる では、実際にホスト側のシェル、コンテナ内のシェルで実際に name space を見てみる、
ここでは PID name space を見てみる
一番上がホスト側、下 2 つがそれぞれ別のコンテナ内で PID を確認した結果
赤字の部分を見てわかるが、すべて別々の名前空間内で実行されていることがわかる では、名前空間があればそれで充分分離できているのか??????
そんなことはない!!!!
コンテナ内の処理は、基本的に外から見ると root 権付で実行されることが多いため、結構厄介
他にもいろいろと必要な機能があるが、ここでは
システムコールの制限、
ファイルアクセスの制限
を紹介。
システムコールとは、要するに OS カーネルの機能呼び出しみたいな感じ、
で、カーネルと話すので、カーネルの動作に影響する可能性があり、それは完全なコンテナ間の分離を妨げる。
例えばシステムの時刻を設定するシステムコールを考える。
システムの時刻設定は date コマンドで行える。
例えば、 OTP とかは時刻に従って生成されているシステムも多い。
つまり、システムの時計が狂うとこれはいろいろとヤバイ
デフォルトでコンテナ内からは実行できないが、 --cap-add すればコンテナ内から実行できる。 実際に動かしてみると、
コンテナ内から、このコマンドを実行したところ、ホスト OS の時計が変わる!
ちなみに、この日付は????
まあググってみてw 他にも、ファイルシステム上にはファイルのアクセス制限が必要な場合がある
例えば、 /proc/sysrq-trigger のファイルは以下のような性質がある
C を書き込むとクラッシュ、 B を書き込むと強制的な再起動
これでは困るので、読み取り専用にするとか非表示にするとかの対策。 まとめです。
まず、 Docker はものしりっくなものではない!
で、 ruunc ではいろいろと仮想化のために Linux カーネルの機能を利用している
他にも docker にまつわる linux kernel の機能は沢山あるので、興味あればこの辺の単語でググってみてください、