gpgp密钥请求在dockerfile中失败,但不是bash

我有一个问题,当我build立我的docker集装箱时,尝试接收gpg密钥失败。 我正在提供的命令在命令行执行时正常工作。

  • 我在防火墙后面; 我有下面这个详细的代理设置。
  • 主持人:CentOS 7.4; Docker版本17.09.0-ce,编译afdb6d4
  • 对于正在使用的帐户,没有为代理设置环境variables。
  • Docker服务具有根据Docker设置的代理的环境variables:

/etc/systemd/system/docker.service.d/http-proxy.conf

 [Service] Environment="HTTP_PROXY=http://<corporate proxy>/" "HTTPS_PROXY="<corporate proxy>/" "NO_PROXY=localhost,127.0.0.1,.domain.local,.corp" 

我使用build.sh shell脚本来构build图像:

 #/bin/bash docker build -t hgk/test-container . 

shell脚本与我的Dockerfile位于相同的位置。 这是目录中唯一的两件事情。

 FROM openjdk:8 ARG KEYSERV=hkp://p80.pool.sks-keyservers.net:80 ARG THEPROXY=<my corporate proxy> # grab gosu for easy step-down from root # (see docker-sonarqube pull request #115) RUN set -x \ && wget -e https_proxy=$THEPROXY -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture)" \ && wget -e https_proxy=$THEPROXY-O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture).asc" \ && export GNUPGHOME="$(mktemp -d)" \ && gpg --version \ && gpg -vv --keyserver $KEYSERV --keyserver-options http-proxy=$THEPROXY --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ && gpg --list-keys \ && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ && rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc \ && chmod +x /usr/local/bin/gosu \ && gosu nobody true 

两个wget命令正常工作,他们检索文件。 第一个gpg命令最终超时:

 + mktemp -d + export GNUPGHOME=/tmp/tmp.LJ1EVFQmpO + gpg --version gpg (GnuPG) 2.1.18 libgcrypt 1.7.6-beta Copyright (C) 2017 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Home: /tmp/tmp.LJlEVFQmpO Supported algorithms: Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256 Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 Compression: Uncompressed, ZIP, ZLIB, BZIP2 + gpg -vv --keyserver hkp://p80.pool.sks-keyservers.net:80 --keyserver-options http-proxy=<corp proxy> --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 gpg: keybox '/tmp/tmp.LJlEVFQmpO/pubring.kbx' created gpg: no running Dirmngr - starting '/usr/bin/dirmngr' gpg: waiting for the dirmngr to come up ... (5s) gpg: connection to the dirmngr established [[I am hung here - It just waits for ... something? I'll update the question if anything prints after this]] 

我把gpg --list-keys命令放到了Dockerfile中,看看我们是否通过了。 但是,如果通过命令行运行它,它将成功检索密钥:

 [root@me foo]# printenv | grep proxy [root@me foo]# gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 -- keyserver-options http-proxy=<corp proxy> --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 gpg: keyring `/root/.gnupg/pubring.gpg' created gpg: requesting key BF357DD4 from hkp server p80.pool.sks-keyservers.net Version: SKS 1.1.6 gpg: armor header: Comment: Hostname: sks.okoyono.de gpg: armor header: gpg: pub 4096R/BF357DD4 2014-02-28 Tianon Gravi <tianon@debian.org> gpg: key BF357DD4: removed multiple subkey binding gpg: key BF357DD4: removed multiple subkey binding gpg: /tmp/tmp.DIX6yQQf25/trustdb.gpg: trustdb created gpg: using PGP trust model gpg: key BF357DD4: public key "Tianon Gravi <tianon@tianon.xyz>" imported gpg: 1 keys cached (126 signatures) gpg: 0 keys processed (0 validity counts cleared) gpg: no ultimately trusted keys found gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) [root@me foo]# gpg --list-keys /root/.gnupg/pubring.gpg ------------------------ pub 4096R/BF357DD4 2014-02-28 [expires: 2019-07-06] uid Tianon Gravi <tianon@tianon.xyz> uid Tianon Gravi <tianon@debian.org> uid Tianon Gravi <tianon@dockerproject.org> uid Andrew Page (tianon) <andrew@infosiftr.com> uid Andrew Page (tianon) <andrew@vitalroute.com> uid Andrew Page (Tianon Gravi) <admwiggin@gmail.com> uid Tianon Gravi (Andrew Page) <tianon@infosiftr.com> sub 4096R/769826E6 2014-02-28 [expires: 2019-07-06] 

我已经尝试了不同的sks-keyservers(ubuntu,MIT和其他sks)具有相同的行为 – 正确的bash,错误的来自Docker。

任何想法/提示/build议?

更新 :我的“openjdk:8”版本有一段时间没有更新(自8u121)。 我发现我正在运行gpg v1.4.18。 我做了一个docker image pull openjdk:8这使我达到8u151和gpg 2.1.18。 CentOS 7机器上的gpg版本是2.0.22。

我对这个问题的解决scheme(是否是正确的解决scheme是争论)是将http_proxyhttps_proxy环境variables添加到Dockerfile中。

 FROM openjdk:8 ARG KEYSERV=hkp://p80.pool.sks-keyservers.net:80 ARG THEPROXY=<my corporate proxy> ENV http_proxy $THEPROXY ENV https_proxy $THEPROXY # grab gosu for easy step-down from root # (see docker-sonarqube pull request #115) RUN set -x \ && wget -e https_proxy=$THEPROXY -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture)" \ && wget -e https_proxy=$THEPROXY-O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture).asc" \ && export GNUPGHOME="$(mktemp -d)" \ && gpg --version \ && gpg -vv --keyserver $KEYSERV --keyserver-options http-proxy=$THEPROXY --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ && gpg --list-keys \ && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ && rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc \ && chmod +x /usr/local/bin/gosu \ && gosu nobody true 

我对这个修补程序的解释是, gpg转动dirmngr 。 dirmngr “是用于pipe理和下载X.509证书的证书吊销列表(CRL)并自行下载证书的服务器。 这暗示了某种forms的networking连接是必要的。 阅读[dirmngr选项] [2]页面,有一个--http-proxy参数,似乎并不传递给dirmngr的启动参数。

不知何故,将http_proxy添加到环境允许dirmngr成功地完成它的工作。

我不确定这是否是一个错误(在gnupg源代码中有一个--honor-http-proxy选项默认设置为0,所以我不确定为什么它会selecthttp_proxy ,但我的解决scheme正在工作,并且满足了我的需求,本周末我会试着更详细地阅读源代码,但是对于我和我的团队来说,这不是一个高优先级的事情。

构buildDocker镜像时,您的systemd单元文件的环境variables不会传递到容器中。 相反,请使用--build-arg参数来传递代理值:

 docker build --build-arg=HTTP_PROXY=http://<corporate proxy>/ --build-arg=HTTPS_PROXY=http://<corporate proxy>/ -t hgk/test-container . 

您不应该像代理variables一样将运行时选项烧入Dockerfile中,而是始终通过环境variables(或此构build参数参数)传递configuration。

附加提示: 大多数应用程序依赖于http_proxyhttps_proxy – 虽然大多数环境variables确实是全大写,但代理variables的使用范围更广泛。