Nexus3.x 说明
功能介绍
Nexus3, 是一款支持仓库种类繁多的私服仓库管理工具,支持目前大众所知晓的仓库类型如:go、pypi、docker、maven、yum、git、helm、npm、apt …,且功能强大。为此解决了不同类型的仓库 统一管理
问题。
仓库类型
目前Nexus3 仓库类型,可以分为三种,即 hosted
、proxy
、group
类型参考。
-
group: 即是多个仓库的集合,group中可 包涵多个
hosted, proxy, group 类型的仓库
注意,在 group 中还存在优先级的关系,即示例图中,如 custom
和 aliyun
的docker仓库中多包涵了 centos:7
的镜像,那么在客户端使用 docker pull 拉取的是 custom
中的 centos7,原因为: “在nexus3 group仓库中使用为 自上而下
的匹配方式,当匹配后将 不再继续
向下匹配”,所以说我们在使用 “group"类型参考时还需要考虑一下,各个仓库的 优先级
。
-
proxy: 即是代理仓库,也叫缓存仓库, 示例原理: 。
客户端请求 proxy 类型私服 如仓库中依赖存在即返回给客户端,如未存在就从proxy配置的远程仓库中拉取依赖返回给客户端,同时在 proxy 私服中进行缓存一份,当第二次访问时,即命中直接从本地 proxy 仓库返回
环境说明
- 操作系统: Centos 7.7 (
vm
)
- Docker 版本: 18.09.9
- 代理工具: Nginx
- Helm 版本: 3.x
- Nginx: 1.16.1
使用 Docker 部署
建议部署 nexus3 的机器,应配置使用 lvm 逻辑卷
管理,方便在磁盘空间不足时可以添加磁盘进行 动态扩展
。
省略 docker 安装步骤和 os 初始化
,这部分参考 链接
1
2
3
4
5
6
7
8
9
10
|
mkdir -p /application/nexus3/data \
&& chmod 777 -R /application/nexus3 # 这里权限,出于安全考虑不应该设置这么大,我这里是开发环境使用就无所谓,生产环境应该酌情考虑。
docker run -dti \
--net=host --name=nexus3 \
--privileged=true --restart=always \
-e INSTALL4J_ADD_VM_PARAMS="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=6g" \
-v /etc/localtime:/etc/localtime:ro \
-v /application/nexus3/data:/nexus-data \
sonatype/nexus3:3.27.0
|
检查是否正常启动
1
2
3
|
sleep 5 && docker logs --tail 100 nexus3
netstat -lntp |grep 8081 # 端口是否监听
|
初始安装账号为 admin
,初始密码在这个文件里面 /application/nexus3/data/admin.password
(按照我的步骤来的话),剩下的就是会有一个初始化的过程 也就是让你重置 admin 的密码 和 是否开启匿名
功能 。
配置 nginx 反向代理
此步骤包涵配置nginx 反向代理,及初始化nexus docker私服
。
nginx 安装及 配置文件调优
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
yum install -y nginx # 安装
useradd -M -s /sbin/nologin www # 添加 http 服务专属用户
mv /etc/nginx/nginx.conf{,.bak} # 修改默认配置
cat > /etc/nginx/nginx.conf << EOF
user www www;
worker_processes auto;
error_log /var/log/error_nginx.log crit;
pid /var/run/nginx.pid;
worker_rlimit_nofile 51200;
events {
use epoll;
worker_connections 51200;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 0;
client_body_buffer_size 4096m;
sendfile on;
tcp_nopush on;
keepalive_timeout 600;
# server_tokens off;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_intercept_errors on;
#Gzip Compression
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
log_format access_log_json '{ "@timestamp": "$time_local", '
'"remote_addr": "$remote_addr", '
'"referer": "$http_referer", '
'"request": "$request", '
'"status": $status, '
'"bytes": $body_bytes_sent, '
'"agent": "$http_user_agent", '
'"x_forwarded": "$http_x_forwarded_for", '
'"up_addr": "$upstream_addr",'
'"up_host": "$upstream_http_host",'
'"up_resp_time": "$upstream_response_time",'
'"request_time": "$request_time"'
' }';
log_format json '{ "@timestamp": "$time_iso8601", '
'"time": "$time_iso8601", '
'"remote_addr": "$remote_addr", '
'"remote_user": "$remote_user", '
'"body_bytes_sent": "$body_bytes_sent", '
'"request_time": "$request_time", '
'"status": "$status", '
'"host": "$host", '
'"request": "$request", '
'"request_method": "$request_method", '
'"uri": "$uri", '
'"http_referrer": "$http_referer", '
'"body_bytes_sent":"$body_bytes_sent", '
'"http_x_forwarded_for": "$http_x_forwarded_for", '
'"http_user_agent": "$http_user_agent" '
'}';
include conf.d/*.conf;
}
EOF
nginx -t # 测试配置文件,有无错误.
|
配置 Docker 私服 & 配置 nginx 反向代理
创建 docker 专属 blob 存储卷
创建 docker hosted
类型仓库
添加 docker proxy
类型仓库
图中使用代理仓库地址为: https://7bezldxe.mirror.aliyuncs.com
创建 docker group
类型仓库
检查配置完成后,端口是否有监听,是否正常
1
2
3
4
|
netstat -lntp|egrep "8081|8082|8083" # 如有以下三个端口存在即表示正常
tcp 0 0 0.0.0.0:8083 0.0.0.0:* LISTEN 1393/java
tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN 1393/java
tcp 0 0 0.0.0.0:8082 0.0.0.0:* LISTEN 1393/java
|
开启 Docker认证功能
此功能不开启将导致 docker私服
, 无法正常使用。
配置 nginx 反向代理
注意下列命令中带有 转义符号
,应直接复制到终端执行即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
cat > /etc/nginx/conf.d/nexus3.conf << EOF
upstream nexus_web {
server 127.0.0.1:8081;
}
upstream nexus_docker_get {
server 127.0.0.1:8082;
}
upstream nexus_docker_put {
server 127.0.0.1:8083;
}
server {
listen 80;
server_name idocker.io;
access_log /var/log/idocker.io.log json;
client_max_body_size 0;
client_body_buffer_size 4096m;
chunked_transfer_encoding on;
set \$upstream "nexus_docker_put";
if ( \$request_method ~* 'GET') {
set \$upstream "nexus_docker_get";
}
if (\$request_uri ~ '/search') {
set \$upstream "nexus_docker_put";
}
index index.html index.htm index.php;
location / {
proxy_pass http://\$upstream;
proxy_set_header Host \$host;
proxy_connect_timeout 3600;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_set_header X-Real-IP \$remote_addr;
proxy_buffering off;
proxy_request_buffering off;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
}
}
server {
listen 80;
server_name repo.demo.com;
client_max_body_size 0;
proxy_max_temp_file_size 0;
access_log /var/log/repo.demo.com.log access_log_json;
location /download {
root /application/download;
}
location / {
proxy_pass http://nexus_web;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
}
EOF
|
测试配置文件是否正常,进行配置的重载。
1
2
3
4
5
|
nginx -t
service nginx restart \
&& service nginx status \
&& systemctl enable nginx # 启动并设置开机自启
|
最终所有仓库展示
docker 私服客户端测试使用
在客户端 docker 容器的配置文件中添加 insecure-registries": ["idocker.io"]
, 并配置对应 hosts记录, 示例中即 idocker.io
。
配置文件完整展示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
cat /etc/docker/daemon.json
{
"oom-score-adjust": -1000,
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 10,
"registry-mirrors": ["https://7bezldxe.mirror.aliyuncs.com"],
"storage-driver": "overlay2",
"insecure-registries": ["idocker.io"],
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
|
配置文件配好了后,进行重启一下 docker 服务进行测试。
1
2
3
4
5
6
|
service docker restart \
&& service docker status # 重启服务
ping -c 3 idocker.io # 检查对应host 是否有添加
docker login idocker.io -u admin -p 123456 # 登录私服,密码为你重置后的密码
|
测试 镜像的上传
1
2
3
|
docker tag sonatype/nexus3:3.27.0 idocker.io/sonatype/nexus3:3.27.0
docker push idocker.io/sonatype/nexus3:3.27.0
|
Docker 部署,如何进行版本升级。
示例将 nexus3 版本升级至 3.29.2
。笔者在使用 nexus3 一年多以来,老是发现xx版本有xxx漏洞,提示你尽快更新版本进行修复,所有这个升级版本的操作还是比较常用的,官方提供的最佳实践里面也说了,让你经常的更新 nexus3 的版本。
原容器启动命令
1
2
3
4
5
6
7
8
|
docker run -dti \
--net=host \
--name=nexus3 \
--privileged=true \
--restart=always \
-e INSTALL4J_ADD_VM_PARAMS="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=6g" \
-v /etc/localtime:/etc/localtime \
-v /application/nexus3:/nexus-data sonatype/nexus3:3.28.1
|
升级步骤
升级使用的镜像版本应使用具体版本号的镜像,建议不要使用 latest
镜像,这样在维护的时候不好区分。
更新步骤具体如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
docker stop nexus3
docker rename nexus3 nexus3_old
docker pull sonatype/nexus3:3.29.2 # 减少启动容器的时间,可先将镜像 download下来 。
docker run -dti \
--net=host \
--name=nexus3 \
--privileged=true \
--restart=always \
-e INSTALL4J_ADD_VM_PARAMS="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=6g" \
-v /etc/localtime:/etc/localtime \
-v /application/nexus3:/nexus-data sonatype/nexus3:3.29.2
docker logs -f --tail 100 nexus3 # 查看启动有无报错
|
新容器启动没有问题后,记得删除老容器即
。
1
|
docker rm -f nexus3_old
|
其他类型私服的配置
配置部署 Yum 私服
Nexus 具体配置项
创建 blob stores
创建 hosted
yum 仓库
⚠️ 注意这里的 文件深度
,会影响后期的 rpm 包依赖上传
, 下面图片中为截取官方文档的说明。
RPM 依赖的上传配置
接下来我们来进行 测试上传 前的准备
示例使用 CentOS-7-x86_64-Everything-2003.iso
镜像中所有 rpm包,配置到 yum 私服中
1
2
3
4
5
|
mount -t auto CentOS-7-x86_64-Everything-2003.iso /mnt/ # 挂载镜像
mkdir -p /data/centos7/rpm-lists/ # 文件夹深度对应私服上的深度
\cp -a /mnt/Packages/*.rpm /data/centos7/rpm-lists/ # 将文件 copy 至上传文件夹下,因挂载的镜像为只读。此时我们也可以在上传文件夹下放置一些我们想上传到私服rpm依赖。
|
上传依赖至私服中
为防止账号密码泄露,可暂时关闭命令记录。
1
2
3
|
export HISTSIZE=0 # 关闭当前终端 命令记录。
for i in `ls`;do curl -v --user 'admin:123456' --upload-file /data/centos7/rpm-lists/"$i" http://192.168.1.9:8081/repository/yum-hosted/7/os/x86_64/"$i";done
|
执行完成上传后 等待 60秒或手动完成索引重建
Yum 私服 客户端使用
定义 yum 私服文件
注意下列命令中携带了 转义符
,如配置了反向代理,可将主机地址指向 反向代理地址
。
1
2
3
4
5
6
7
8
9
10
11
12
|
mv /etc/yum.repos.d{,.bak}
mkdir -p /etc/yum.repos.d
cat > /etc/yum.repos.d/nexus.repo << EOF
[nexusrepo]
name=Nexus Repository
baseurl=http://192.168.1.9:8081/repository/yum-hub/\$releasever/os/\$basearch/
enabled=1
gpgcheck=0
EOF # 注意 baseurl 地址
yum clean all
yum makecache # 缓存索引
|
测试一下安装一个包
此包为我在上传前,放到 “上传文件夹"下的,所有在我的环境会有,也可以测试安装包替换为 vim
1
|
yum install -y kubectl # or vim
|
配置部署 Helm 私服
Nexus 配置项记录
创建 helm 专属 blob stores
创建 helm hosted
类型仓库
此处helm,未演示配置 proxy
类型的仓库了,其实现原理就是当客户端访问 nexus proxy 仓库时,如仓库中依赖存在即返回给客户端,如未存在就从proxy配置的远程仓库中拉取依赖返回给客户端,同时在 proxy 私服中进行缓存一份,当第二次访问时,即命中直接从本地 proxy 仓库返回。 nexus3 中proxy 仓库原理多是使用这个机制
。
Helm 上传依赖包配置
dashboard 界面上传
curl 命令上传
1
|
curl -u "USER_NAME":"USER_PASSWD" http://repo.demo.com/repository/helm-demo/ --upload-file ./"$UPLOADFILE" -v
|
客户端使用
1
2
|
helm repo add demo http://repo.demo.com/repository/helm-demo # helm 3.x
helm repo update
|
配置部署 pypi 私服
Nexus 配置项记录
创建 pypi 专属 blob stores
创建 pypi hosted
类型仓库
创建 pypi group
类型仓库,并将上面
创建的 hosted 仓库加入至组中
配合完成后,即使用 group
地址
Pypi 依赖上传配置
省略 dashboard 上传,同上 helm 一致,区别于选择仓库
命令上传
命令上传,依赖使用 twine
工具。目前 pypi 私服上传且支持 .tar.gz
& .whl
两种类型的包
具体 文档参考
1
2
3
4
5
|
python3 setup.py sdist # python 打包
pip install twine # 安装上传工具
twine upload --repository-url http://repo.demo.com/repository/pypi-demo/ dist/* -u ${USERKEY_USR} -p ${USERKEY_PSW}
|
pending。。