Docker のインストールの意味を完全に理解してみる

昨日は、Docker Swarm 関連でひどい目にあった。もう何回目だろうこの手のインストールで時間を使うのは。もういい加減嫌になった。

どうやったらもっと確実にいけるだろう？なぜ、毎回時間がかかるんだろう。今回、Docker Swarm のインストールがうまくいかない原因をしらべたかった。事実としては

* Docker for Azure なら動く
* acs-engine をバージョンアップしたら動かない（同じバージョンで）
* ログは出ているが、それがダメなのかわからない（syslog  で出ている）
* マスターはちゃんと動作していない。ブートのログを見ても、エラーは見つからない。

結局のところ何かと考えると、Docker for Azure のスクリプトと、acs-engine のスクリプトを比較したら問題がわかりそうなのだが、なぜそうしないか？というと、わかりそうにないから。
多分理由は「理解」していないからだ。なんとなく、インストール手順にしたがっていても、理解していないから、自分の中で確信をモテないからだろう。よっしゃ。一発、docker のインストール手順から一コマンド残らず全部意味を理解してみよう。そしたら、次回からはもっと早いだろう。
自分のメモなので、全部英語だけど、たまに日本語での意味を書いてみる。

# Install Docker 

[Get Docker CE for Ubuntu](https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#os-requirements)

I installed VMScale Set. I can configure Several VM's with VNet. However, it will take some time. I focus on installing/configurting Swarm.

今回は、Vnetを作るのめんどくさいので、Portalから、VMSS をデプロイして、試した。今回はスクリプトの理解が目的

# 1. Understand Architecture

You can read [32-bit vs 64-bit vs ARM in regards to programs and OSes]
In this case, x86-64 a.k.a. x64, amd64 (Not IA64)
(https://unix.stackexchange.com/questions/125295/32-bit-vs-64-bit-vs-arm-in-regards-to-programs-and-oses)

いつもなんとなくわかった気になっている「アーキテクチャ」ってなんだろうって調べて見た。アーキテクチャの種類ごとにバイナリが違うのは当然だけど、いろんな用語が出てくる。でも、`x86-64` `x64` `amd64` はみんな同じ意味か、、、なんと無くそう思っていたけど、調べると確信がもてる。

I checked the Inbound NAT rules. 

```
ssh azureuser@13.93.236.169 -p 50001 -A
```

# apt 関連

apt もなんとなく意味わかるけど、言われるがままにインストールしているパッケージはどんなものだろう？下に英語だけどメモしておいた。

```
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
```
* Enable APT to use https: [Package: apt-transport-https (1.5~rc4)](https://packages.debian.org/sid/apt-transport-https)
* Certificate to allow SSL-based application: [Package: ca-certificates](https://packages.debian.org/sid/ca-certificates)
* Provides an abstraction of the used apt repositories: [Package: software-properties-common](https://packages.debian.org/sid/admin/software-properties-common)

# GPG Keyって？

なんとなくやっているオペレーションやけど、これは、GPG(GNU Privacy Gard) というツール（暗号化、復号化のツール）のキーをダウンロードしている。docker のパッケージを復号化するためだ。それを、`apt-key` コマンドでキーに追加している。

```
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```
`apt-key` enable us to manage API key for apt package authentication. GPG key
is used for the key management. You can make sure if a key is installed. 

だから、`apt-key list` をすると、キーが追加されたのが確認される。

```
$ apt-key list
/etc/apt/trusted.gpg
--------------------
pub   1024D/437D05B5 2004-09-12
uid                  Ubuntu Archive Automatic Signing Key <ftpmaster@ubuntu.com>
sub   2048g/79164387 2004-09-12

pub   4096R/C0B21F32 2012-05-11
uid                  Ubuntu Archive Automatic Signing Key (2012) <ftpmaster@ubuntu.com>

pub   4096R/EFE21092 2012-05-11
uid                  Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com>

pub   1024D/FBB75451 2004-12-30
uid                  Ubuntu CD Image Automatic Signing Key <cdimage@ubuntu.com>

pub   4096R/0EBFCD88 2017-02-22
uid                  Docker Release (CE deb) <docker@docker.com>
sub   4096R/F273FCD8 2017-02-22

```

Also you can try for docker by fingerprint

# finger print ってなんだ？

指紋という意味だけど、いつもやっているフィンガープリントはなんのためだろう。これは、public key が、目的のものであるか確認するために、本来はpublic key は長いけど、短く、それが該当するキーか調べている。下記のコマンドは、ちゃんと、該当のキー(ここでは docker) が入ったか確認している。

```
$ sudo apt-key fingerprint 0EBFCD88
pub   4096R/0EBFCD88 2017-02-22
      Key fingerprint = 9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid                  Docker Release (CE deb) <docker@docker.com>
sub   4096R/F273FCD8 2017-02-22
```


* GNU Privacy Guard (GPG, also GnuPG) is free encryption software : [What is GPG, and how do I use it to encrypt files on IU's research computing systems?](https://kb.iu.edu/d/awio)

* [APT-KEY](http://jnug.net/po4a/apt-key.ja.8.html)

* [Public key fingerprint]
(https://en.wikipedia.org/wiki/Public_key_fingerprint)

In public-key cryptography, a public key fingerprint is a short sequence of bytes used to identify a longer public key. Fingerprints are created by applying a cryptographic hash function to a public key. Since fingerprints are shorter than the keys they refer to, they can be used to simplify certain key management tasks. In Microsoft software, "thumbprint" is used instead of "fingerprint".

# add-apt repository は何をしているか？

これは、`apt-get` で取得する先のリポジトリを登録している。ふわっとわかるけど、何しているのだろう。ちなみに`deb` はバイナリのリポジトリを示している。

```
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```

* [What does “sudo add-apt-repository” do?](https://askubuntu.com/questions/885903/what-does-sudo-add-apt-repository-do)

* [SourcesList](https://wiki.debian.org/SourcesList)

`lsb-release -cs` コマンドは、どのバージョンの、Ubuntu かを見ている。`16.04` は、`xential`。そして、`stable` のバージョンを指定している。他にも、`edge` とかあるらしい。

```
$ lsb_release -cs
xenial
```
xenial == Ubuntu 16.04

You can make sure if the new repo is installed. `deb` means binary repo. `deb src` is also there. 

# /etc/apt/sources.list で確認する

ちゃんと、リポジトリが登録されたか確認している。

```
$ cat /etc/apt/sources.list
  :
  deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable
  :
```

# docker-ce インストール

最終的についにインストールを実行。

```
sudo apt-get update
sudo apt-get install docker-ce
```

I can see the docker-ce 17.06 installed.

# apt-get でインストールされたパッケージはどこに行くの？

`dpkg` コマンドで調べると一覧が見れる。

BTW, where the app is installed? 

* [apt-getでインストールしたパッケージはどこに入ったのか。](http://d.hatena.ne.jp/hiro_nemu/20090327/1238168139)

* [apt-getの仕組み](https://matome.naver.jp/odai/2139540287718538401)


* [What is dpkg for?](https://askubuntu.com/questions/173465/what-is-dpkg-for)
As has been said, dpkg is a low-level system tool to extract, analyse, unpack and install or remove .deb files. 

```
$ dpkg -L docker-ce
/.
/etc
/etc/init.d
/etc/init.d/docker
/etc/default
/etc/default/docker
/etc/init
/etc/init/docker.conf
/lib
/lib/udev
/lib/udev/rules.d
/lib/udev/rules.d/80-docker-ce.rules
/lib/systemd
/lib/systemd/system
/lib/systemd/system/docker.socket
/lib/systemd/system/docker.service
/usr
/usr/share
/usr/share/zsh
/usr/share/zsh/vendor-completions
/usr/share/zsh/vendor-completions/_docker
/usr/share/docker-ce
/usr/share/docker-ce/contrib
/usr/share/docker-ce/contrib/mkimage
/usr/share/docker-ce/contrib/mkimage/debootstrap
/usr/share/docker-ce/contrib/mkimage/rinse
/usr/share/docker-ce/contrib/mkimage/solaris
/usr/share/docker-ce/contrib/mkimage/mageia-urpmi
/usr/share/docker-ce/contrib/mkimage/.febootstrap-minimize
/usr/share/docker-ce/contrib/mkimage/busybox-static
/usr/share/docker-ce/contrib/mkimage-arch-pacman.conf
/usr/share/docker-ce/contrib/mkimage-debootstrap.sh
/usr/share/docker-ce/contrib/mkimage.sh
/usr/share/docker-ce/contrib/nuke-graph-directory.sh
/usr/share/docker-ce/contrib/mkimage-yum.sh
/usr/share/docker-ce/contrib/mkimage-alpine.sh
/usr/share/docker-ce/contrib/mkimage-pld.sh
/usr/share/docker-ce/contrib/desktop-integration
/usr/share/docker-ce/contrib/desktop-integration/README.md
/usr/share/docker-ce/contrib/desktop-integration/gparted
/usr/share/docker-ce/contrib/desktop-integration/gparted/Dockerfile
/usr/share/docker-ce/contrib/desktop-integration/chromium
/usr/share/docker-ce/contrib/desktop-integration/chromium/Dockerfile
/usr/share/docker-ce/contrib/mkimage-crux.sh
/usr/share/docker-ce/contrib/mkimage-busybox.sh
/usr/share/docker-ce/contrib/check-config.sh
/usr/share/docker-ce/contrib/mkimage-rinse.sh
/usr/share/docker-ce/contrib/mkimage-arch.sh
/usr/share/docker-ce/contrib/mkimage-archarm-pacman.conf
/usr/share/man
/usr/share/man/man8
/usr/share/man/man8/dockerd.8.gz
/usr/share/man/man1
/usr/share/man/man1/docker-container-top.1.gz
/usr/share/man/man1/docker-load.1.gz
/usr/share/man/man1/docker-container-commit.1.gz
/usr/share/man/man1/docker-restart.1.gz
/usr/share/man/man1/docker-container-create.1.gz
/usr/share/man/man1/docker-save.1.gz
/usr/share/man/man1/docker-events.1.gz
/usr/share/man/man1/docker-start.1.gz
/usr/share/man/man1/docker-config-create.1.gz
/usr/share/man/man1/docker-inspect.1.gz
/usr/share/man/man1/docker-stack-ps.1.gz
/usr/share/man/man1/docker-container-update.1.gz
/usr/share/man/man1/docker-service-create.1.gz
/usr/share/man/man1/docker-kill.1.gz
/usr/share/man/man1/docker-secret-inspect.1.gz
/usr/share/man/man1/docker-swarm-join.1.gz
/usr/share/man/man1/docker-stats.1.gz
/usr/share/man/man1/docker-build.1.gz
/usr/share/man/man1/docker-logout.1.gz
/usr/share/man/man1/docker-checkpoint-rm.1.gz
/usr/share/man/man1/docker-run.1.gz
/usr/share/man/man1/docker-network-connect.1.gz
/usr/share/man/man1/docker-network-prune.1.gz
/usr/share/man/man1/docker-image-build.1.gz
/usr/share/man/man1/docker-image-pull.1.gz
/usr/share/man/man1/docker-checkpoint-create.1.gz
/usr/share/man/man1/docker-volume-prune.1.gz
/usr/share/man/man1/docker-system.1.gz
/usr/share/man/man1/docker-container-exec.1.gz
/usr/share/man/man1/docker-network-ls.1.gz
/usr/share/man/man1/docker-swarm.1.gz
/usr/share/man/man1/docker-stack-services.1.gz
/usr/share/man/man1/docker-config-inspect.1.gz
/usr/share/man/man1/docker-stack-ls.1.gz
/usr/share/man/man1/docker-image-save.1.gz
/usr/share/man/man1/docker-checkpoint-ls.1.gz
/usr/share/man/man1/docker-update.1.gz
/usr/share/man/man1/docker-history.1.gz
/usr/share/man/man1/docker-rename.1.gz
/usr/share/man/man1/docker-config-rm.1.gz
/usr/share/man/man1/docker-container-wait.1.gz
/usr/share/man/man1/docker-attach.1.gz
/usr/share/man/man1/docker-system-df.1.gz
/usr/share/man/man1/docker-plugin-push.1.gz
/usr/share/man/man1/docker-diff.1.gz
/usr/share/man/man1/docker-network-create.1.gz
/usr/share/man/man1/docker-container-attach.1.gz
/usr/share/man/man1/docker-node-demote.1.gz
/usr/share/man/man1/docker-image-history.1.gz
/usr/share/man/man1/docker-service.1.gz
/usr/share/man/man1/docker-port.1.gz
/usr/share/man/man1/docker-image-load.1.gz
/usr/share/man/man1/docker-node.1.gz
/usr/share/man/man1/docker-system-events.1.gz
/usr/share/man/man1/docker-plugin-upgrade.1.gz
/usr/share/man/man1/docker-container-rename.1.gz
/usr/share/man/man1/docker-import.1.gz
/usr/share/man/man1/docker-service-scale.1.gz
/usr/share/man/man1/docker-container-port.1.gz
/usr/share/man/man1/docker-network-disconnect.1.gz
/usr/share/man/man1/docker-service-ps.1.gz
/usr/share/man/man1/docker-plugin.1.gz
/usr/share/man/man1/docker-node-ls.1.gz
/usr/share/man/man1/docker-image.1.gz
/usr/share/man/man1/docker-container-restart.1.gz
/usr/share/man/man1/docker-secret-ls.1.gz
/usr/share/man/man1/docker-container-logs.1.gz
/usr/share/man/man1/docker-pause.1.gz
/usr/share/man/man1/docker-plugin-create.1.gz
/usr/share/man/man1/docker-plugin-install.1.gz
/usr/share/man/man1/docker-container-run.1.gz
/usr/share/man/man1/docker-version.1.gz
/usr/share/man/man1/docker-swarm-leave.1.gz
/usr/share/man/man1/docker-plugin-enable.1.gz
/usr/share/man/man1/docker-unpause.1.gz
/usr/share/man/man1/docker-swarm-unlock-key.1.gz
/usr/share/man/man1/docker-volume-rm.1.gz
/usr/share/man/man1/docker-network.1.gz
/usr/share/man/man1/docker-logs.1.gz
/usr/share/man/man1/docker-swarm-update.1.gz
/usr/share/man/man1/docker-image-inspect.1.gz
/usr/share/man/man1/docker-stop.1.gz
/usr/share/man/man1/docker-wait.1.gz
/usr/share/man/man1/docker-node-promote.1.gz
/usr/share/man/man1/docker-node-rm.1.gz
/usr/share/man/man1/docker-container-stats.1.gz
/usr/share/man/man1/docker-container-diff.1.gz
/usr/share/man/man1/docker-service-inspect.1.gz
/usr/share/man/man1/docker-volume-inspect.1.gz
/usr/share/man/man1/docker-export.1.gz
/usr/share/man/man1/docker-swarm-unlock.1.gz
/usr/share/man/man1/docker-container-cp.1.gz
/usr/share/man/man1/docker-service-update.1.gz
/usr/share/man/man1/docker-container-rm.1.gz
/usr/share/man/man1/docker-network-inspect.1.gz
/usr/share/man/man1/docker-search.1.gz
/usr/share/man/man1/docker-image-push.1.gz
/usr/share/man/man1/docker-volume-ls.1.gz
/usr/share/man/man1/docker-config-ls.1.gz
/usr/share/man/man1/docker-network-rm.1.gz
/usr/share/man/man1/docker-container-start.1.gz
/usr/share/man/man1/docker-service-rm.1.gz
/usr/share/man/man1/docker-container-stop.1.gz
/usr/share/man/man1/docker-image-tag.1.gz
/usr/share/man/man1/docker-tag.1.gz
/usr/share/man/man1/docker-image-ls.1.gz
/usr/share/man/man1/docker-container.1.gz
/usr/share/man/man1/docker-deploy.1.gz
/usr/share/man/man1/docker-login.1.gz
/usr/share/man/man1/docker-commit.1.gz
/usr/share/man/man1/docker-service-logs.1.gz
/usr/share/man/man1/docker-secret.1.gz
/usr/share/man/man1/docker-secret-rm.1.gz
/usr/share/man/man1/docker-container-prune.1.gz
/usr/share/man/man1/docker-swarm-init.1.gz
/usr/share/man/man1/docker-plugin-ls.1.gz
/usr/share/man/man1/docker-image-import.1.gz
/usr/share/man/man1/docker-service-ls.1.gz
/usr/share/man/man1/docker-swarm-join-token.1.gz
/usr/share/man/man1/docker-node-update.1.gz
/usr/share/man/man1/docker-push.1.gz
/usr/share/man/man1/docker-images.1.gz
/usr/share/man/man1/docker-swarm-ca.1.gz
/usr/share/man/man1/docker-container-inspect.1.gz
/usr/share/man/man1/docker-plugin-inspect.1.gz
/usr/share/man/man1/docker-stack-rm.1.gz
/usr/share/man/man1/docker-create.1.gz
/usr/share/man/man1/docker-volume-create.1.gz
/usr/share/man/man1/docker-image-rm.1.gz
/usr/share/man/man1/docker-config.1.gz
/usr/share/man/man1/docker-pull.1.gz
/usr/share/man/man1/docker-system-prune.1.gz
/usr/share/man/man1/docker-volume.1.gz
/usr/share/man/man1/docker-ps.1.gz
/usr/share/man/man1/docker.1.gz
/usr/share/man/man1/docker-cp.1.gz
/usr/share/man/man1/docker-secret-create.1.gz
/usr/share/man/man1/docker-container-unpause.1.gz
/usr/share/man/man1/docker-info.1.gz
/usr/share/man/man1/docker-checkpoint.1.gz
/usr/share/man/man1/docker-container-export.1.gz
/usr/share/man/man1/docker-plugin-set.1.gz
/usr/share/man/man1/docker-rmi.1.gz
/usr/share/man/man1/docker-node-ps.1.gz
/usr/share/man/man1/docker-node-inspect.1.gz
/usr/share/man/man1/docker-plugin-disable.1.gz
/usr/share/man/man1/docker-top.1.gz
/usr/share/man/man1/docker-system-info.1.gz
/usr/share/man/man1/docker-container-ls.1.gz
/usr/share/man/man1/docker-rm.1.gz
/usr/share/man/man1/docker-plugin-rm.1.gz
/usr/share/man/man1/docker-exec.1.gz
/usr/share/man/man1/docker-container-pause.1.gz
/usr/share/man/man1/docker-container-kill.1.gz
/usr/share/man/man1/docker-stack-deploy.1.gz
/usr/share/man/man1/docker-stack.1.gz
/usr/share/man/man1/docker-image-prune.1.gz
/usr/share/man/man5
/usr/share/man/man5/docker-config-json.5.gz
/usr/share/man/man5/Dockerfile.5.gz
/usr/share/fish
/usr/share/fish/vendor_completions.d
/usr/share/fish/vendor_completions.d/docker.fish
/usr/share/bash-completion
/usr/share/bash-completion/completions
/usr/share/bash-completion/completions/docker
/usr/share/doc
/usr/share/doc/docker-ce
/usr/share/doc/docker-ce/README.md.gz
/usr/share/doc/docker-ce/changelog.Debian.gz
/usr/share/nano
/usr/share/nano/Dockerfile.nanorc
/usr/bin
/usr/bin/docker-containerd-shim
/usr/bin/docker-containerd
/usr/bin/docker-runc
/usr/bin/docker
/usr/bin/docker-init
/usr/bin/docker-containerd-ctr
/usr/bin/docker-proxy
/usr/bin/dockerd
/usr/lib
/usr/lib/docker
```

You can refer available version 

ちなみに、本番環境では、適当なバージョンを入れずに、ちゃんとした狙い通りのを入れたい。`apt-cache madison` コマンドで使えるバージョンを確認。

```
$ apt-cache madison docker-ce
 docker-ce | 17.06.2~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
 docker-ce | 17.06.1~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
 docker-ce | 17.06.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
 docker-ce | 17.03.2~ce-0~ubuntu-xenial | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
 docker-ce | 17.03.1~ce-0~ubuntu-xenial | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
 docker-ce | 17.03.0~ce-0~ubuntu-xenial | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
 ```

 ```
 $ sudo docker version
Client:
 Version:      17.06.2-ce
 API version:  1.30
 Go version:   go1.8.3
 Git commit:   cec0b72
 Built:        Tue Sep  5 20:00:17 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.06.2-ce
 API version:  1.30 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   cec0b72
 Built:        Tue Sep  5 19:59:11 2017
 OS/Arch:      linux/amd64
 Experimental: false
```

* [Why apt madison?](https://unix.stackexchange.com/questions/276037/why-apt-madison/276040)
* [How can I see all versions of a package that are available in the archive?](https://askubuntu.com/questions/447/how-can-i-see-all-versions-of-a-package-that-are-available-in-the-archive)

# apt-get バージョン指定

明確にバージョンは本来指定した方が良い。明日には変わるかもしれないから。

You can specify the exact version 

```
$ sudo apt-get install docker-ce=<VERSION>
```

Verify the installation

動作確認。

```
$ sudo docker run hello-world
```

# sudo をやめる

現在のユーザを、docker groupにa参加させれば良い。docker は`/var/run/docker.sock`でソケット通信しているので、その権限設定がグループには読み書きを許可している。

```
sudo groupadd docker
sudo gpasswd -a $USER docker
-- logout / login again
docker run hello-world
```

* [How can I use docker without sudo?](https://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo)

# まとめ

完全理解をやって見たけど、かなり頭がスッキリする。時間がかかっても、最初の１回目はこれをやるべきだなぁ。次はSwarm に突入。