1. 概要

Docker は、アプリケーションとそのすべての依存関係をコンテナーと呼ばれる軽量のエンティティにパッケージ化するのに役立ちます。 Dockerコンテナーは、任意の物理マシン、仮想マシン、さらにはクラウドにデプロイできます。

さまざまな環境でDockerサービスを使用しているときに、さまざまな問題が発生する可能性があります。 このチュートリアルでは、Dockerデーモンの接続の問題について学習します。 これは、初心者が遭遇する非常に一般的なエラーです。 また、この問題の原因とトラブルシューティングの方法についても説明します。

2. 問題を理解する

マシンにまだ存在していないLinuxでコマンドを実行しようとする状況を考えてみます。 「コマンドが見つかりません」というエラーメッセージが返されます。 この問題の理由は、コマンドが実際にマシンにインストールされていないか、インストールされているが正しく構成されていないことが原因である可能性があります。

まず、Dockerデーモン( dockerd )について理解しましょう。 これは、イメージ、コンテナー、ボリュームなど、すべてのDockerオブジェクトを管理するプログラムです。

別のエンティティであるDockerクライアントは、Dockerデーモンを介してユーザーからDockerサービスにコマンドを渡すのに役立ちます。 特定の状況下では、DockerクライアントはDockerデーモンへの接続に失敗します。 このような場合、Dockerは「Dockerデーモンに接続できません」というエラーをスローします。

DockerクライアントがDockerデーモンに接続できない理由はさまざまです。 ここで、この問題を解決するための根本的な原因とさまざまな解決策について詳しく見ていきましょう。

3. 非アクティブなDockerサービスが原因

このエラーの最も一般的な理由は、Dockerサービスにアクセスしようとしたが、開始されていない場合です。

$ docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock.
  Is the docker daemon running?

まず、Dockerサービスが実行されているかどうかに関係なく、Dockerサービスのステータスを確認します。

$ systemctl status docker
 docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
   Docs: https://docs.docker.com

ここで、出力はDockerサービスが非アクティブであることを明確に示しています。 次に、Dockerサービスを開始します。 これにより、ほとんどの場合、問題が解決します。

3.1. サービスを使用してDockerを起動する

通常、パッケージマネージャーを使用してDockerをインストールすると、Dockerサービスが作成されます。 これにより、Dockerの管理が容易になります。 systemctlサービスコマンドを使用してDockerを起動しましょう。

$ systemctl start docker

次のコマンドを使用して、Dockerのステータスを確認できます。

$ systemctl status docker
 docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2022-02-17 19:14:51 UTC; 1min 38s ago
     Docs: https://docs.docker.com
 Main PID: 1831 (dockerd)
    Tasks: 8
   Memory: 126.5M
   CGroup: /system.slice/docker.service
           └─1831 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

このコマンドは、現在のステータスのDockerサービスをアクティブ(実行中)として表示します。

3.2. Dockerデーモンを手動で起動します

または、サービスなしでDockerを起動することもできます。 dockerdコマンドをバックグラウンドで実行するだけです。

$ sudo dockerd
INFO[2022-02-18T05:19:50.048886666Z] Starting up                                  
INFO[2022-02-18T05:19:50.050883459Z] libcontainerd: started new containerd process  pid=2331
INFO[2022-02-18T05:19:50.050943756Z] parsed scheme: "unix"                         module=grpc

dockerdをSudo権限で実行していることを確認する必要があります。

4. 特権が不十分なため

パッケージマネージャーを使用してDockerをインストールすると、デフォルトでdockerユーザーとグループが作成されます。 Dockerにアクセスするには、現在のユーザーをdockerグループに追加する必要があります。

docker グループ外のユーザーからDockerサービスにアクセスしようとすると、次のエラーが発生します。

$ docker ps
Got permission denied while trying to connect to the Docker daemon socket
  at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/json:
  dial unix /var/run/docker.sock: connect: permission denied

この問題を解決するために、2つのことができます。 ユーザーをdockerグループに追加するか、Dockerソケットファイルの権限を更新することができます。 ここで、サンプルの例とともに、両方のソリューションについて詳しく見ていきましょう。

4.1. ユーザー権限の更新

Linuxでは、ユーザー権限は重要な概念です。 さまざまなユーザーのリソースへのアクセス可能性を決定します。

LinuxにDockerをインストールすると、新しい docker グループが作成され、Dockerサービスに関連するすべてのパッケージがこのdockerグループにリンクされます。 マシンにデフォルトのdockerグループが見つからない場合は、手動で作成できます。

$ sudo groupadd docker

上記のコマンドは、dockerグループを作成します。 次に、dockerグループ内に現在のユーザーを追加します。

$ sudo usermod -aG docker docker-test

ここで、 -a オプションは、ユーザーdocker-testdockerグループに追加します。 -G オプションは、グループ名を示すために使用されます。

最後に、Dockerサービスを再起動して、変更を有効にします。

$ sudo service docker restart

4.2. Dockerソケットファイル権限の更新

/var/run/docker.sockファイルの所有者を変更することで問題を修正することもできます。

$ sudo chown docker-test /var/run/docker.sock

このコマンドをsudo権限で実行していることに注意してください。 そうしないと、ファイルの権限が更新されません。

5. 結論

このチュートリアルでは、頻繁に発生するDockerデーモンの接続の問題について学習しました。

最後に、この問題は、Dockerサービスが正しく開始されていない場合、またはDockerサービスにアクセスするための適切なユーザー権限がない場合に発生します。

ユーザーをdockerグループに追加し、 sock ファイルの権限を変更することで、この問題を解決するさまざまな方法を検討しました。