DinDでIs the docker daemon running?が出たときの解決策

# 背景

GitLabCIの勉強を「GitLab実践ガイド(著：北山 晋吾さん)」を使って行っていました。 
せっかくだからDockerをDocker Executer上で使用するためにGitLabが推奨するDocker-in-docker（以下dind)を使ってみようと思い試していたところタイトルにあるエラーに遭遇しました。 

```
 $ docker build . -t ${APP_NAME}
 Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
 ERROR: Job failed: exit code 1
```

対処法を調べましたが、日本語の情報はなかったので書き置きします。

> GitLab実践ガイド(著：北山 晋吾さん)はこちら。
> Kindle Unlimitedの専門書ラインナップが充実してきて嬉しいです。
> https://www.amazon.co.jp/dp/B079DL362C/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1


# 環境

* GitLab動作環境 : GitLab.com
* Runner動作環境 : Ubuntu16.04(parallels Desktop15)

GitLab.com上にテスト用プロジェクトを作成し、Specific Runnerを仮想デスクトップ環境のUbuntu上に作成しています。
dindを使用するため、Docker Executerを設定します。

> dindについてはこちらの記事がわかりやすかったです。
> [Dockerコンテナ内からDockerを使うことについて](https://qiita.com/esaka/items/37e5d60d66c6061c19d0)

なお、GitLab.comのShared Runnersを使用したところエラーは発生しませんでした。
おそらく適切に対処されているのでShared Runnersを使用するのも解決策となります。
そのため本記事は自前でRunnerを構築する人向けのものになります。

# エラー時の設定

dindを利用するために、gitlab-ci.ymlファイルに以下の設定を行います。 
> DOCKER_DRIVERにoverlayFSを選択しているのはおすすめ設定だから入れておこうの精神です。
> docker infoを使用して、Strage Driverを確認したところ明示的に宣言しなくてもデフォルトでoverlay2になっていたため不要かもしれません。 
> この機会に以下の記事で勉強したのでご紹介だけしておきます。
> [Dockerのストレージドライバを理解する](https://qiita.com/NaotoHanaue/items/b9f395a63f7aae2a41b7)

```yml:.gitlab-ci.yml
# docker image
image: docker:latest

# Docker DriverをoverlayFSに変更する(おすすめ設定)。
variables:
  DOCKER_DRIVER: overlay2
# dindを設定
services:
  - docker:dind
```
この設定でdockerのbuildを行おうとすると"Is the docker daemon running?"が発生するようです。


# 原因
docker 19.03からdindが自動的にTLS証明書を作成し通信に使用するようになったことが原因のようです。
詳しくは以下の公式ドキュメントに書いています。
対処法も書いていますが後述で私が試した対処法を書いていきます。 
> https://about.gitlab.com/releases/2019/07/31/docker-in-docker-with-docker-19-dot-03/
>
> 飛び元はこちら
>https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-ocker-workflow-with-docker-executor
>
> 元のissueはこちら
> https://gitlab.com/gitlab-org/gitlab-runner/issues/1986


# 対処法
## 対処法1: TLSを構築する
こちらも公式にある方法(Configure TLS)です。
サービスとジョブコンテナ間で証明書を共有するため、volumesにマウントを追加します。
他の対処法はTLSを使用しないようにしているため、一番正当な対処法のように思います。
ちなみにconfig.tomlはubuntuだと'sudo vi /etc/gitlab-runner/config.toml'で編集できます。

```toml:config.toml
[[runners]]
  name = "My Docker Runner"
  url = "http://gitlab.com"
  token = ""
  executor = "docker"
  [runners.custom_build_dir]
  [runners.docker]
    privileged = true
    volumes = ["/certs/client", "/cache"]
    shm_size = 0
```

```yml:.gitlab-ci.yml

image: docker:19.03.0

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: "/certs"

services:
  - docker:19.03.0-dind
```


## 対処法2: dindのバージョン変更
dind 19.03からの不具合のため、単にバージョンを下げることで解決します。

```yml:.gitlab-ci.yml
image: docker:18.09.7

# Docker DriverをoverlayFSに変更する(おすすめ設定)。
variables:
  DOCKER_DRIVER: overlay2
# dindを設定
services:
  - docker:18.09.7-dind
```

## 対処法3: TLSを使用しない
こちらも公式にある方法(Disable TLS)です。
TLS証明書を明示的に使用しないように設定すれば回避することができます。

```yml:.gitlab-ci.yml
image: docker:19.03.0

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ""

services:
  - docker:19.03.0-dind
```

# まとめ
'Is the docker deamon running？'の対処法をまとめました。
基本的に社内利用の場合はどの方法でも良いかなと思いますが、一番おすすめされている方法は対処法1のTLS構築です。

専門外な上に、記事初投稿なので至らぬ点があったらご指摘願います。