概要
proxy環境下でdockerを使うために設定をしていたとき、http_proxy
,https_proxy
がどうしても上手く読み込めてなかったので何をして何が原因で何をしたのかをここに残す。
設定時
DockerはLinuxシステムの環境変数にあるhttp_proxy
やhttps_proxy
とは別に、専用のproxy設定を施す必要がある。
なのでこのサイトを参考に設定をした。
そのときのconfファイルの設定内容はこんな感じ。(実際の接続先URLは載せるわけにはいかないので、例として架空のurlを用いる)
[Service]
Environment="HTTP_PROXY=http://aaaa:admin!@example.ad.jp:8080"
のように書き込んだ。
これでdocker pull イメージ名
を実行したところ以下のようなエラーが出力された。
Error response from daemon: Get https://registry-1.docker.io/v2/: proxyconnect tcp: dial tcp: lookup https on xxx.xxx.xxx.xxx:xx: no such host
解決策
http://aaaa:admin!@example.ad.jp:8080
の!
をURLエンコードしてやればよい。
どうやらLinuxにおいて!(エクスクラメーションマーク)
は特別な意味を持つ記号で、通常の'(シングルクォーテーション)
を用いたエスケープが効かないそうだ。
※¥(円マーク)
でエスケープはできたがURLにそのまま残ってしまう↓
http://aaaa:admin¥!@example.ad.jp:8080
↑この場合PWの一部として円マークが認識されてしまう
※参考ページ: bashに !' で event no found と怒られた理由を考えてみる - https://qiita.com/Qutjl/items/6e0056853c94011d245b
URLなので%21
のようにエンコードすればどうにかなるんじゃねと思い、やってみたところできてたっぽい
(この時上記に関係ないエラーが発生して、それを勘違いして最初はこの方法でもできてないと思った)
↓URLエンコードバージョン
[Service]
Environment="HTTP_PROXY=http://aaaa:admin%21@example.ad.jp:8080"
ちなみにdocker info
を実行することでDockerに関する情報が出力される。先ほどのProxy設定情報も出力される。
[root@hogehoge ~]# docker info
~中略~
HTTP Proxy: http://xxxxx:xxxxx@example.ad.jp:8080
HTTPS Proxy: https://xxxxx:xxxxx@example.ad.jp:8080
~中略~
エスケープしても上のようにusername@password
が伏字になってしまうことがある。
しかしsystemctl show docker --property Environment
でProxy設定情報を確認すると
Environment=HTTP_PROXY=http://aaaa:admin%21@example.ad.jp:8080 HTTPS_PROXY=https://aaaa:admin%21@example.ad.jp:8080
このようにエクスクラメーションマークがエスケープされて登録されていることがわかる。
なぜ伏字になるのかは不明。
余談
上にも書いたが、URLエンコードで対応してもエラーが発生した。このエラーは以下のようなものだった
Get https://registry-1.docker.io/v2/: proxyconnect tcp: tls: first record does not look like a TLS handshake
上手くTLSのコネクションがはれていないのかなと思いググってみた。
すると以下のページに答えが載っていた。
VagrantをProxy経由で利用する - https://qiita.com/daichannel/items/08e074a01e8ab41d52f7#docker
単純にHTTPS_PROXY
に設定するURLのスキームをhttp
にすれば良いだけだった。
(なぜhttpsではダメなのかは不明。これでいいのか感が否めない・・・)
[Service]
Environment="HTTPS_PROXY=http://aaaa:admin%21@example.ad.jp:8080"
余談2
今回は通常のURLエンコードでどうにかなったが、場合によっては%
を2回続けないと反映されないらしい。
上記のhttps-proxy.conf
を例にすると
[Service]
Environment="HTTPS_PROXY=http://aaaa:admin%%21@example.ad.jp:8080"
このようにエクスクラメーションマークを変換する際は%%21
と%を2回続けると上手くいくこともあるらしい。
どうやらsystemctlでは**%ダブル**で$
や%
などの特殊文字をエスケープしているらしい(?)
結論
systemctlのconfファイルに用いる!
はLinuxにおける通常のエスケープ方法が効かないことがわかった。
Linuxシステムにおいて!
は扱いが特殊なので、そもそもURLなどに混ぜるべきではないと思った。