ubuntu 20.04.1 上でプロキシ環境でdocker を利用する

# ubuntu 20.04.1 上でプロキシ環境でdocker を利用する

## docker をインストールする。

docker をインストールしていない場合は以下の記事の手順で docker をインストールする
https://qiita.com/m-tmatma/items/06eb40514306e09142c4

## プロキシを用意する

以下の記事のようにしてプロキシを用意しておく。
https://qiita.com/m-tmatma/items/7b5ce812c85f30546209

この記事ではプロキシの IP が `192.168.11.61` で、ポート番号が `3128` という前提で記載する。


## プロキシ経由でしかアクセスできない環境をエミュレートする

プロキシ経由でしかアクセスできない環境をエミュレートする。
これにより、設定が誤っていた場合に検出できる。

### HTTP, HTTPS を禁止

```
sudo iptables -A OUTPUT -j REJECT -p tcp --dport 80
sudo iptables -A OUTPUT -j REJECT -p tcp --dport 443
```
### Git, SSHを禁止 (これは必須じゃないけど念のため)

```
sudo iptables -A OUTPUT -j REJECT -p tcp --dport 9418
sudo iptables -A OUTPUT -j REJECT -p tcp --dport 22
```

## apt

### apt のプロキシ設定をする

docker のコンテナ内で apt を使えるようにと思ったが、 `~/.docker/config.json` で設定した環境設定が有効になるため、コンテナ内で使う分には設定は不要。
ホスト環境でも環境変数で `http_proxy` `https_proxy` の設定を行っていれば不要。

```
sudo nano /etc/apt/apt.conf
```

以下の内容で保存する。

```
Acquire::http::Proxy "http://192.168.11.61:3128";
Acquire::https::Proxy "http://192.168.11.61:3128";
```

以下のようにプロキシの変数を設定する。

```
test@test-vmware:~$ cat /etc/apt/apt.conf
Acquire::http::Proxy "http://192.168.11.61:3128";
Acquire::https::Proxy "http://192.168.11.61:3128";
```

### apt の update をする

```
sudo apt update -y
sudo apt upgrade -y
```

## docker のインストール

### インストール

https://qiita.com/m-tmatma/items/06eb40514306e09142c4 を参考に docker をインストールする。

```
sudo apt install -y docker.io docker-compose
```

### カレントユーザーを docker グループに追加 (docker を起動するときに毎回 sudo する場合は省略可)

この手順は docker コマンドを sudo なしで実行したい場合のみ必要です。

docker を sudo なしで実行すると便利なので、カレントユーザーを docker グループに追加する。
反映するために再起動する。

```
sudo usermod -aG docker $USER
sudo reboot
```

なお、ここで再起動した場合は、[iptables の手順](#プロキシ経由でしかアクセスできない環境をエミュレートする)は再度実行すること。

## dockerd に環境変数でプロキシを設定する。

### プロキシ設定

以下コマンドを実行する。

```
sudo systemctl edit docker
```

#### 除外 IP を指定しない場合

`sudo systemctl edit docker` で起動するエディタで 以下の内容を入力して保存して終了する。

```
[Service]
Environment="HTTP_PROXY=http://192.168.11.61:3128"
Environment="HTTPS_PROXY=http://192.168.11.61:3128"
```

#### 除外 IP を指定する場合

`sudo systemctl edit docker` で起動するエディタで`NO_PROXY` も追加で指定する。
以下の内容を入力して保存して終了する。

```
[Service]
Environment="HTTP_PROXY=http://192.168.11.61:3128"
Environment="HTTPS_PROXY=http://192.168.11.61:3128"
Environment="NO_PROXY=localhost,127.0.0.1"
```

### 設定の確認

`/etc/systemd/system/docker.service.d/override.conf` に保存される。
以下は 除外 IP を指定しない場合の例

```
$ cat /etc/systemd/system/docker.service.d/override.conf 
[Service]
Environment="HTTP_PROXY=http://192.168.11.61:3128" "HTTPS_PROXY=http://192.168.11.61:3128"
```

### プロキシ設定を反映

設定を反映する。

```
sudo systemctl daemon-reload
```

### プロキシ設定を確認


設定を確認する。

```
sudo systemctl show docker --property Environment
```

### docker を再起動


docker を再起動する。

```
sudo systemctl restart docker
```

以下を実行して、`HTTP Proxy` と `HTTPS Proxy` に反映されているのを確認する。

```
docker info
```

参考
http://docs.docker.jp/engine/articles/systemd.html#http
https://docs.docker.com/config/daemon/systemd/

## ユーザーごとの docker の設定

設定ファイルを保存するフォルダを作る。

```
mkdir -p ~/.docker
```

`~/.docker/config.json` を編集する。

```
nano  ~/.docker/config.json
```
#### 除外 IP を指定しない場合

`~/.docker/config.json` で以下のような内容を入力して保存する。

```
{
  "proxies": {
    "default": {
      "httpProxy": "http://192.168.11.61:3128",
      "httpsProxy": "http://192.168.11.61:3128"
    }
  }
}
```

#### 除外 IP を指定する場合

プロキシに除外条件を指定する場合は`~/.docker/config.json` で `noProxy` で指定する。


```
{
  "proxies": {
    "default": {
      "httpProxy": "http://192.168.11.61:3128",
      "httpsProxy": "http://192.168.11.61:3128",
      "noProxy": "localhost,127.0.0.1"
    }
  }
}
```


参考
https://docs.docker.com/network/proxy/
https://docs.docker.com/network/proxy/#configure-the-docker-client

## docker pull の確認

以下のように docker pull できる。

```
$ docker pull alpine
Using default tag: latest
latest: Pulling from library/alpine
df20fa9351a1: Pull complete 
Digest: sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest
```

念のため iptables で確認しても http と https は直アクセスは禁止されている。

```
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-USER  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
REJECT     tcp  --  anywhere             anywhere             tcp dpt:https reject-with icmp-port-unreachable
REJECT     tcp  --  anywhere             anywhere             tcp dpt:http reject-with icmp-port-unreachable
REJECT     tcp  --  anywhere             anywhere             tcp dpt:git reject-with icmp-port-unreachable
REJECT     tcp  --  anywhere             anywhere             tcp dpt:ssh reject-with icmp-port-unreachable

Chain DOCKER (1 references)
target     prot opt source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-USER (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            
```