由于Docker Hub主动退出市场,导致国内不能方便的拉取docker镜像,故计划在内网使用Nexus Repository架设私有仓库,行pull through cache之职能,将下载的镜像/包缓存下来以便多次部署供内网的多设备使用,降低对国内高校镜像站的流量使用;同时考虑到PyPI也可能发起制裁导致不能使用,也计划建立PyPI的内网仓库。
目标
- 架设Nexus Repository OSS
- 通过高校镜像站提供的HTTP代理缓存Docker Hub
- 同上,缓存PyPI仓库
Nexus Repository OSS部署
Nexus Repository对Java 8以上的支持并不是特别好,有挺多坑需要留意。根据官网文档部署的情况下还需要注意以下几点:
Java版本选择
目前个人建议使用Java 11,因为当前LTS版本中Java 8太老而Java 17暂不支持OrientDb。我懒得专门部署一个外部数据库所以选择了Java 11,需要进行的改动最小。
# 使用Java 11以上版本的报错
java.lang.IllegalStateException: The maximum Java version for OrientDb is Java 11. Please check current Java version meets this requirement.
JVM选项修改
根据文档,使用Java 9以上版本时需要注释和取消注释掉{NEXUS_HOME}\bin\nexus.vmoptions
中的部分内容,理论上来说根据配置文件中的说明进行修改即可。但上述部分在随安装包附带的版本中存在缺失若干等号=
和路径不正确的问题,即使按照配置文件中的说明也无法直接使用。修改后的JVM配置文件如下,主要是缺少等号导致选项不能正确解析,再次说明对Java 8以上版本何等不上心,几年前的问题在最新版本中仍未修正。
-Xms2703m
-Xmx2703m
-XX:MaxDirectMemorySize=2703m
-XX:+UnlockDiagnosticVMOptions
-XX:+LogVMOutput
-XX:LogFile=../sonatype-work/nexus3/log/jvm.log
-XX:-OmitStackTraceInFastThrow
-Djava.net.preferIPv4Stack=true
-Dkaraf.home=.
-Dkaraf.base=.
-Dkaraf.etc=etc/karaf
-Djava.util.logging.config.file=etc/karaf/java.util.logging.properties
-Dkaraf.data=../sonatype-work/nexus3
-Dkaraf.log=../sonatype-work/nexus3/log
-Djava.io.tmpdir=../sonatype-work/nexus3/tmp
-Dkaraf.startLocalConsole=false
-Djdk.tls.ephemeralDHKeySize=2048
#
# additional vmoptions needed for Java9+
#
--add-reads=java.xml=java.logging
--add-exports=java.base/org.apache.karaf.specs.locator=java.xml,ALL-UNNAMED
--patch-module=java.base=./lib/endorsed/org.apache.karaf.specs.locator-4.3.9.jar
--patch-module=java.xml=./lib/endorsed/org.apache.karaf.specs.java.xml-4.3.9.jar
--add-opens=java.base/java.security=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.naming/javax.naming.spi=ALL-UNNAMED
--add-opens=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED
--add-exports=java.base/sun.net.www.protocol.http=ALL-UNNAMED
--add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED
--add-exports=java.base/sun.net.www.protocol.jar=ALL-UNNAMED
--add-exports=jdk.xml.dom/org.w3c.dom.html=ALL-UNNAMED
--add-exports=jdk.naming.rmi/com.sun.jndi.url.rmi=ALL-UNNAMED
--add-exports=java.security.sasl/com.sun.security.sasl=ALL-UNNAMED
#
# comment out this vmoption when using Java9+
#
# -Djava.endorsed.dirs=lib/endorsed
配置HTTP代理
部署完成后在System > HTTP > Proxy Settings
中填写对应的代理即可,拉到最下方可以添加排除列表,不需要通过高校HTTP代理拉取的站点被排除后则会直连。
配置Docker Hub仓库
创建仓库
- 新建仓库,选择类型为
docker (proxy)
- 填写仓库名称
- 在
HTTP
选项下填写一个端口;由于Nexus Repo的某些限制,通过port connector连接是最简单的方法(参见官方论坛讨论及这个issue) - 我勾选了
Allow anonymous docker pull
,看个人情况 Enable Docker V1 API
我没勾选,考虑到V1 API已经deprecate了Remote storage
填写Docker Hub的registry:https://registry-1.docker.io
Docker Index
勾选Use Docker Hub
- 其它均默认,如果有Docker Hub账号的话可以将创建的Token填写到最下方
Authentication
里,避免匿名帐号每6小时拉取100镜像的限制
配置匿名访问
在Security > Realms
中将Docker Bearer Token Realm
加入Active,参考这个问答。
修改使用Docker的终端
在终端上添加/修改配置文件/etc/docker/daemon.json
,添加Nexus Repo到非安全registry(因为我没有配置HTTPS)。
{
"insecure-registries" : [ "mirrors.example.net:5000" ]
}
然后重启Docker服务,随后在用到Docker的地方(我的话主要用Portainer)配置新的registry为mirrors.example.net:5000
即可。
配置PyPI仓库
创建仓库
- 新建仓库,选择类型为
pypi (proxy)
Remote storage
填写https://pypi.org
- 理论上其它留默认就行了
修改终端pip配置
从Nexus Repo复制出来的PyPI仓库URL可能形如http://mirrors.example.net:4000/repository/pypi/
,在填写到pip.ini
时注意稍作修改:
[global]
index-url = http://mirrors.example.net:4000/repository/pypi/simple
[install]
trusted-host = mirrors.example.net:4000
此时再通过pip安装包时便会通过Nexus Repo拉取,Nexus Repo也会缓存下这部分包。
缓存效果测试
在红色和绿色两个框内先后拉取了同一个镜像,可以看到第二次拉取时Nexus Repo并未再次下载镜像,而是使用本地缓存向Docker终端提供下载。