Dockerデーモンに関するもう少し詳しい説明

Docker
Docker公式ロゴ1a
©2020 Docker Inc. All rights reserved

 Hyper-vやvmwareなど様々な仮想化製品がありますが、どの仮想環境でも全体を制御する管理機能的な役割を果たすコンポーネントがあると思います。

 Dockerの場合は、dockerデーモンがその役割を担ってます。

 通常は、Dockerデーモンは普段は大々的に前面には登場しませんが、なにか少し複雑なことをしてみたいとか、トラブルが発生したときなどには、ほぼ関わってきます。

 そんな時に役に立つ情報になればと思い、dockerデーモンの基本的なことから、更にもう少し突っ込んだ内容について書いてみました。

 知っておいて損はしないと思います。

Dockerデーモンとは

 Dockerデーモンは、Docker環境の中では最も重要なコンポーネントなのですが、縁の下の力持ち的な存在であるため、あまり目立たないと思います。

 Docker環境の中では、Dockerイメージ、Dockerコンテナ、Dockerネットワーク、DockerボリュームなどDockerの構成要素の管理者的な仕事をしています。

 Dockerイメージ、Dockerコンテナなどの制御する場合は、Dockerクライアントであるdockerコマンドを使ってDockerデーモンとやり取りを行います。

 Dockerコンテナを1つのOSと見た場合、DockerデーモンはそのOSのカーネル部分に相当すると考えて良いでしょう。

 Dockerは、コンテナ型仮想環境を提供するために、Linuxカーネルが元々持っている複数の機能を利用してます。

 言い換えれば、Dockerは、Linuxカーネルが元々持つ便利で複雑な仮想化機能を組み合わせて、利用者に扱いやすい仮想環境を提供してくれているのです。

 参考までに、Dockerが利用しているLinuxカーネルの機能の主なものを以下に挙げます。

名称説明
namespacesプロセスに対する各種リソース割り当てを分離
させる技術
cgroupシステムリソースの割り当て、制御を行う
Union FileSystem複数のマウントポイントを1つに束ねる技術

 では、実際にDockerデーモンを見てみましょう。

 ホストOSはUbuntu 18.04を使用してます。

 ご利用のディストリビューションによって手順が異なることがありますので、適宜読み替えてください。

 まずは「systemctl status」にてdockerサービスのステータスを確認します。

# systemctl status docker

 以下のような内容が出力されました。

● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: e
Active: active (running) since Fri 2020-06-12 22:28:43 JST; 3 months 5 days a
Docs: https://docs.docker.com
Main PID: 1159 (dockerd)
Tasks: 90
CGroup: /system.slice/docker.service
tq 1159 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/contai
tq 2029 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port
tq 2071 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port

(以下略)

 Ubuntuでは、Dockerはsystemd配下で動いています。よって、Dockerデーモンはsystemctlコマンドにて操作します。

 Dockerデーモンのバイナリは、「/usr/bin/dockerd」になります。

 psコマンドで見てみましょう。

# ps -ef | grep dockerd

 以下のような内容が出力されたと思います。

root 27097 1 0 8月25 ? 00:00:38 /usr/bin/dockerd

dockerdのオプションの設定方法

 dockerdのオプションについてみてみましょう。

 オプション一覧は以下のコマンドで確認できます。

# /usr/bin/dockerd --help

 内容はバージョンごとに異なると思いますので、省略します。

 詳細は、Docker公式サイトでご確認ください。

 とりあえず、単独のDockerホストで外部から接続可能なDockerコンテナを作るのでしたら、デフォルトの状態で問題ないと思います。

 オプションを指定する場合は、以下のディレクトリに定義ファイルを置くことで、dockerデーモンの起動時に、その内容を自動で反映してくれます。

/etc/systemd/system/docker.service.d/

 存在しない場合は作成してください。

 一例としまして「--insecure-registry」オプションを指定する方法を説明します。

 通常はDockerレジストリとの通信はhttpsで行いますが、特定のネットワーク内のDockerレジストリだけはhttpで行うようにするためには、dockerdに「--insecure-registry」オプションを使用します。

 「192.168.0.0/24」のネットワーク内のDockerレジストリとの通信はhttpで行えるように設定してみます。

 まず、現時点でdockerdに設定されているオプションを調べてみましょう。

 現在の設定内容を確認するために、定義ファイルの場所を確認します。

# systemctl status docker

 以下のように出力されました。

● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) 
(以下略)

 出力内容の上部に「Loaded: loaded (/lib/systemd/system/docker.service;」と書かれた部分があります。このファイルにデフォルト設定が記載されています。

 catコマンドで/lib/systemd/system/docker.serviceファイルを表示して、ExecStartオプションの設定内容を確認します。

 私の環境では以下のように記載されていました。

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

 上の定義に、「--insecure-registry」オプションの設定を追加したものが、今回の定義内容になります。

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry=192.168.0.0/24

 実際の定義ファイルの内容は以下のとおりです。

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry=192.168.0.0/24

 上の内容を定義ファイル「docker.conf」に保存して、/etc/systemd/system/docker.service.d/ディレクトリに格納してください。

※設定内容が無い「ExecStart=」の行は必要です

 設定ファイル「docker.conf」の内容を反映させるためにdockerdの再起動を行います。

 まずは、systemd関連のファイルを更新したので、以下のコマンドを実行します。

# systemctl daemon-reload

 その後、以下のコマンドでdockerdの再起動を行います。

# systemctl restart docker

 再起動後、定義が反映されていることを確認します。

# systemctl status docker

 以下のような内容が出力されました。

● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
  Drop-In: /etc/systemd/system/docker.service.d
           |-docker.conf
   Active: active (running) since Thu 2020-09-17 15:23:40 JST; 30min ago
     Docs: https://docs.docker.com
 Main PID: 13609 (dockerd)
    Tasks: 86
   CGroup: /system.slice/docker.service
           |-13609 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/contai
nerd/containerd.sock --insecure-registry=192.168.0.0/24
           |-13945 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 33305 -container-ip 172.23.0.2 -container-port 3306
 (以下省略)

※ターミナルに表示された右側の部分が切れている場合は、カーソルキー右を押して表示します

 下のオプションが設定されていることが確認できます。

--insecure-registry=192.168.0.0/24

 あと、出力内容の3~4行目に、先ほど作成したファイルが読み込まれていることも分かります。

Drop-In: /etc/systemd/system/docker.service.d
 |-docker.conf

 今後、Dockerに色々なカスタマイズを行うことになると思いますが、その際はこの方法でオプションの追加を行う必要が出てくるかもしれませんので、覚えておいた方が良いでしょう。

Dockerデーモンとの通信(コミュニケーション)方法

 Dockerデーモンとの通信は、Dockerクライアントである「docker」コマンドを使用して行いますが、その通信には、デフォルトでは「unixドメインソケット」という技術を使用しています。

 unixドメインソケットは、ファイルシステムを介して行う通信方式で、Dockerは「/var/run/docker.sock」というファイルを使用してます。

 「ls」コマンドで確認してみてください。

$ ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0 8月 26 14:19 /var/run/docker.sock

 このファイルを使用して、プロセス間通信を行っています。

 ファイルの所有権は、ユーザはroot、グループはdockerになっています。

 以前の記事で、Docker管理者を追加する方法について書かせていただきましたが、その際に行ったdockerグループへの追加作業は、ここと関連しているのです。

 このファイルへの読み書きができませんと、dockerデーモンと通信が出来ないことになります。

 試しにテスト環境で、「/var/run/docker.sock」のグループをrootにしたら、今まで使えていたdocker管理ユーザで「docker ps」コマンドを実行しても、Dockerデーモンと通信が出来なくなり、以下の内容が出力されるようになってしまいました。

Cannot connect to the Docker daemon. Is the docker daemon running on this host?

 所有権を元に戻したら、当然元に戻りました。

 危険なので、あえてコマンドは書きませんが、お試しになる場合は自己責任でお願いします。

 Dockerデーモンとの通信方法は、unixドメインソケット以外に、TCPソケットもあります。しかし、この方法を安易に行ってしまいますと、Dockerホストのroot権限を晒すこととイコールになってしまいますので、十分ご注意ください。

おわりに

 本記事の内容は、普通にDockerを動かしている分には必要ないことが多いですが、よりセキュリティを強化したり、より細かくDockerの各種管理を行ったりする場合には、dockerデーモンの設定を行うことになるかもしれません。

 本記事の内容を頭の片隅に置いていただければ、調査の足掛かりとして使えるかもしれません。

 最後までお読みいただきありがとうございました。

コメント

タイトルとURLをコピーしました