Docker 环境:Nexus3.x 的私有仓库
Nexus3.x 的私有仓库使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。在企业中把内部的一些工具包放入 Nexus 中是比较常见的做法,最新版本Nexus3.x全面支持 Docker 的私有镜像。所以使用Nexus3.x一个软件来管理Docker,Maven...
Nexus3.x 的私有仓库
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。
使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。在企业中把内部的一些工具包放入 Nexus 中是比较常见的做法,最新版本 Nexus3.x
全面支持 Docker 的私有镜像。所以使用 Nexus3.x
一个软件来管理 Docker
, Maven
, Yum
, PyPI
等是一个明智的选择。
启动 Nexus 容器
$ docker run -d --name nexus3 --restart=always \
-p 8081:8081 \
--mount src=nexus-data,target=/nexus-data \
sonatype/nexus3
等待 3-5 分钟,如果 nexus3
容器没有异常退出,那么你可以使用浏览器打开 http://YourIP:8081
访问 Nexus 了。
第一次启动 Nexus 的默认帐号是 admin
密码是 admin123
登录以后点击页面上方的齿轮按钮进行设置。
(PS:我执行到这 nexus3 容器显示是启动状态,但浏览器一直访问不成功,端口已开,查看日志才发现报错了:
2018-07-02 01:34:34,175+0000 ERROR [FelixStartLevel] *SYSTEM org.sonatype.nexus.internal.orient.OrientBootstrap - Failed transition: NEW -> STARTED
java.lang.reflect.InvocationTargetException: null
at org.sonatype.nexus.common.stateguard.MethodInvocationAction.run(MethodInvocationAction.java:45)
at org.sonatype.nexus.common.stateguard.StateGuard$TransitionImpl.run(StateGuard.java:191)
at org.sonatype.nexus.common.stateguard.TransitionsInterceptor.invoke(TransitionsInterceptor.java:56)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:77)
at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:55)
at org.sonatype.nexus.internal.orient.OrientBootstrap$$EnhancerByGuice$$221620cd.start(<generated>)
at org.sonatype.nexus.extender.NexusLifecycleManager.startComponent(NexusLifecycleManager.java:155)
at org.sonatype.nexus.extender.NexusLifecycleManager.to(NexusLifecycleManager.java:95)
at org.sonatype.nexus.extender.NexusContextListener.frameworkEvent(NexusContextListener.java:189)
at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1429)
at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:308)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.OutOfMemoryError: null
at sun.misc.Unsafe.allocateMemory(Native Method)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:127)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
at com.orientechnologies.common.directmemory.OByteBufferPool.allocateBuffer(OByteBufferPool.java:410)
at com.orientechnologies.common.directmemory.OByteBufferPool.acquireDirect(OByteBufferPool.java:361)
at com.orientechnologies.orient.core.storage.cache.local.OWOWCache.load(OWOWCache.java:841)
at com.orientechnologies.orient.core.storage.cache.local.twoq.O2QCache.updateCache(O2QCache.java:1167)
at com.orientechnologies.orient.core.storage.cache.local.twoq.O2QCache.doLoad(O2QCache.java:361)
at com.orientechnologies.orient.core.storage.cache.local.twoq.O2QCache.allocateNewPage(O2QCache.java:412)
at com.orientechnologies.orient.core.storage.impl.local.paginated.atomicoperations.OAtomicOperation.commitChanges(OAtomicOperation.java:434)
at com.orientechnologies.orient.core.storage.impl.local.paginated.atomicoperations.OAtomicOperationsManager.endAtomicOperation(OAtomicOperationsManager.java:468)
at com.orientechnologies.orient.core.storage.impl.local.paginated.atomicoperations.OAtomicOperationsManager.endAtomicOperation(OAtomicOperationsManager.java:412)
at com.orientechnologies.orient.core.storage.impl.local.paginated.base.ODurableComponent.endAtomicOperation(ODurableComponent.java:113)
at com.orientechnologies.orient.core.storage.impl.local.paginated.OPaginatedCluster.create(OPaginatedCluster.java:192)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.addClusterInternal(OAbstractPaginatedStorage.java:4365)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.doAddCluster(OAbstractPaginatedStorage.java:4346)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.create(OAbstractPaginatedStorage.java:487)
at com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage.create(OLocalPaginatedStorage.java:129)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.create(ODatabaseDocumentTx.java:438)
at com.orientechnologies.orient.server.OSystemDatabase.init(OSystemDatabase.java:160)
at com.orientechnologies.orient.server.OSystemDatabase.<init>(OSystemDatabase.java:44)
at com.orientechnologies.orient.server.OServer.initSystemDatabase(OServer.java:1309)
at com.orientechnologies.orient.server.OServer.activate(OServer.java:367)
at org.sonatype.nexus.internal.orient.DatabaseServerImpl.doStart(DatabaseServerImpl.java:186)
at org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport.start(StateGuardLifecycleSupport.java:67)
at org.sonatype.nexus.common.stateguard.MethodInvocationAction.run(MethodInvocationAction.java:39)
at org.sonatype.nexus.common.stateguard.StateGuard$TransitionImpl.run(StateGuard.java:191)
at org.sonatype.nexus.common.stateguard.TransitionsInterceptor.invoke(TransitionsInterceptor.java:56)
at org.sonatype.nexus.internal.orient.OrientBootstrap.doStart(OrientBootstrap.java:73)
at org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport.start(StateGuardLifecycleSupport.java:67)
at org.sonatype.nexus.common.stateguard.MethodInvocationAction.run(MethodInvocationAction.java:39)
at org.sonatype.nexus.common.stateguard.StateGuard$TransitionImpl.run(StateGuard.java:191)
at org.sonatype.nexus.common.stateguard.TransitionsInterceptor.invoke(TransitionsInterceptor.java:56)
... 6 common frames omitted
原因不明,如果你解决了请给我讲解一下。)
创建仓库
创建一个私有仓库的方法: Repository->Repositories
点击右边菜单 Create repository
选择 docker (hosted)
- Name: 仓库的名称
- HTTP: 仓库单独的访问端口
- Enable Docker V1 API: 如果需要同时支持 V1 版本请勾选此项(不建议勾选)。
- Hosted -> Deployment pollcy: 请选择 Allow redeploy 否则无法上传 Docker 镜像。
其它的仓库创建方法请各位自己摸索,还可以创建一个 docker (proxy) 类型的仓库链接到 DockerHub 上。再创建一个 docker (group) 类型的仓库把刚才的 hosted 与 proxy 添加在一起。主机在访问的时候默认下载私有仓库中的镜像,如果没有将链接到 DockerHub 中下载并缓存到 Nexus 中。
添加访问权限
菜单 Security->Realms
把 Docker Bearer Token Realm 移到右边的框中保存。
添加用户规则:菜单 Security->Roles
->Create role
在 Privlleges
选项搜索 docker 把相应的规则移动到右边的框中然后保存。
添加用户:菜单 Security->Users
->Create local user
在 Roles
选项中选中刚才创建的规则移动到右边的窗口保存。
NGINX 加密代理
证书的生成请参见 私有仓库高级配置
里面证书生成一节。
NGINX 示例配置如下
upstream register
{
server "YourHostName OR IP":5001; #端口为上面添加的私有镜像仓库是设置的 HTTP 选项的端口号
check interval=3000 rise=2 fall=10 timeout=1000 type=http;
check_http_send "HEAD / HTTP/1.0\r\n\r\n";
check_http_expect_alive http_4xx;
}
server {
server_name YourDomainName;#如果没有 DNS 服务器做解析,请删除此选项使用本机 IP 地址访问
listen 443 ssl;
ssl_certificate key/example.crt;
ssl_certificate_key key/example.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
large_client_header_buffers 4 32k;
client_max_body_size 300m;
client_body_buffer_size 512k;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_buffer_size 128k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 512k;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://register;
proxy_read_timeout 900s;
}
error_page 500 502 503 504 /50x.html;
}
Docker 主机访问镜像仓库
如果不启用 SSL 加密可以通过前面章节的方法添加信任地址到 Docker 的配置文件中然后重启 Docker
使用 SSL 加密以后程序需要访问就不能采用修改配置的访问了。具体方法如下:
$ openssl s_client -showcerts -connect YourDomainName OR HostIP:443 </dev/null 2>/dev/null|openssl x509 -outform PEM >ca.crt
$ cat ca.crt | sudo tee -a /etc/ssl/certs/ca-certificates.crt
$ systemctl restart docker
使用 docker login YourDomainName OR HostIP
进行测试,用户名密码填写上面 Nexus 中生成的。
转自:https://yeasy.gitbooks.io/docker_practice/repository/nexus3_registry.html
更多推荐
所有评论(0)