JFrog Container Registry 支持 Subdomain 模式,主要用于优化多仓库场景下的镜像拉取和推送操作。
在 Subdomain 模式下,每个仓库(repository)都通过不同的子域名来访问,而不是通过传统路径访问。例如:
Repositpry Path 模式(传统路径):
1
| docker pull artifactory-jcr.warnerchen.com/docker-service-broker-tmp-local/library/nginx:mainline
|
Subdomain 模式:
1
| docker pull docker-service-broker-tmp-local.artifactory-jcr.warnerchen.com/library/nginx:mainline
|
也就是说,仓库名变成了主机名的一部分。
Subdomain 支持 Apache、Nginx、Tomcat,此处测试 Apache 和 Nginx。
部署 JFrog Container Registry
1 2 3
| helm repo add jfrog https://charts.jfrog.io helm repo update helm upgrade --install jfrog-container-registry --set artifactory.postgresql.postgresqlPassword=<postgres_password> jfrog/artifactory-jcr --namespace artifactory-jcr --create-namespace
|
获取 Service 信息,后续会用到:
1 2 3 4 5 6 7
| root@rke2-cilium-01:~# kubectl -n artifactory-jcr get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE artifactory-jcr ClusterIP 10.43.83.174 <none> 8082/TCP,8085/TCP,8081/TCP 21d artifactory-jcr-artifactory-nginx NodePort 10.43.252.158 <none> 80:31152/TCP,443:31837/TCP 21d artifactory-jcr-nodeport NodePort 10.43.229.183 <none> 8082:32636/TCP,8085:32222/TCP,8081:32098/TCP 21d artifactory-jcr-postgresql ClusterIP 10.43.222.157 <none> 5432/TCP 21d artifactory-jcr-postgresql-headless ClusterIP None <none> 5432/TCP 21d
|
准备自签证书
准备一个 VM 作为 Proxy,安装 Docker/Podman。
然后参考链接创建证书:https://docs.rancher.cn/docs/rancher2/installation/resources/advanced/self-signed-ssl/_index/#4-%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90%E8%87%AA%E7%AD%BE%E5%90%8D%E8%AF%81%E4%B9%A6
将证书存放到指定目录下:
1
| mkdir -pv ~/artifactory-jcr/tls
|
1 2
| root@test-0:~# ls ~/artifactory-jcr/tls/ tls.crt tls.key
|
Apache
默认情况下模式为 Repositpry Path,部署完成后,先通过 Ingress/NodePort 访问 JFrog Container Registry,将模式设置为 Subdomain:


在安装了 Proxy VM 中,创建目录:
1
| mkdir -pv ~/artifactory-jcr/apache_subdomain/conf.d
|
在生成的配置文件中,将 x.x.x.x:8081
和 x.x.x.x:8082
修改成对应的 NodePort,然后保存到上面的目录中:
1 2 3 4 5 6 7 8 9
| root@test-0:~/artifactory-jcr/apache_subdomain/conf.d# grep 172.16.16.120 default.conf ProxyPass "/artifactory/" http://172.16.16.120:32098/artifactory/ ProxyPassReverse "/artifactory/" http://172.16.16.120:32098/artifactory/ ProxyPass "/" http://172.16.16.120:32636/ nocanon ProxyPassReverse "/" http://172.16.16.120:32636/ ProxyPass "/artifactory/" http://172.16.16.120:32098/artifactory/ ProxyPassReverse "/artifactory/" http://172.16.16.120:32098/artifactory/ ProxyPass "/" http://172.16.16.120:32636/ nocanon ProxyPassReverse "/" http://172.16.16.120:32636/
|
创建 Apache 全局配置:
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
| cat <<EOF > ~/artifactory-jcr/apache_subdomain/httpd.conf ServerRoot "/usr/local/apache2" Listen 80 Listen 443 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule ssl_module modules/mod_ssl.so LoadModule unixd_module modules/mod_unixd.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so <IfModule !mpm_prefork_module> </IfModule> <IfModule mpm_prefork_module> </IfModule> LoadModule dir_module modules/mod_dir.so LoadModule alias_module modules/mod_alias.so LoadModule rewrite_module modules/mod_rewrite.so <IfModule unixd_module> User www-data Group www-data </IfModule> ServerAdmin you@example.com <Directory /> AllowOverride none Require all denied </Directory> DocumentRoot "/usr/local/apache2/htdocs" <Directory "/usr/local/apache2/htdocs"> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory> <IfModule dir_module> DirectoryIndex index.html </IfModule> <Files ".ht*"> Require all denied </Files> ErrorLog /proc/self/fd/2 LogLevel warn <IfModule log_config_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common <IfModule logio_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio </IfModule> CustomLog /proc/self/fd/1 common </IfModule> <IfModule alias_module> ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/" </IfModule> <IfModule cgid_module> </IfModule> <Directory "/usr/local/apache2/cgi-bin"> AllowOverride None Options None Require all granted </Directory> <IfModule headers_module> RequestHeader unset Proxy early </IfModule> <IfModule mime_module> TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz </IfModule> <IfModule proxy_html_module> Include conf/extra/proxy-html.conf </IfModule> <IfModule ssl_module> SSLRandomSeed startup builtin SSLRandomSeed connect builtin </IfModule> Include conf/conf.d/*.conf EOF
|
获取 mime.type
文件:
1
| podman run --rm harbor.warnerchen.com/library/httpd:2.4 cat /usr/local/apache2/conf/mime.types > ~/artifactory-jcr/apache_subdomain/mime.types
|
目录结构如下:
1 2 3 4 5 6 7 8
| root@test-0:~# tree ~/artifactory-jcr/apache_subdomain /root/artifactory-jcr/apache_subdomain ├── conf.d │ └── default.conf ├── httpd.conf └── mime.types
1 directory, 3 files
|
启动 Apache:
1
| podman run -d --name apache-subdomain -p 80:80 -p 443:443 -v /root/artifactory-jcr/apache_subdomain:/usr/local/apache2/conf -v /root/artifactory-jcr/tls:/etc/ssl harbor.warnerchen.com/library/httpd:2.4
|
将 JFrog Container Registry 的域名映射调整为 Proxy 的 IP,检查是否能够正常访问:

尝试 Push 镜像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| root@test-0:~# podman login docker-service-broker-tmp-local.artifactory-jcr.warnerchen.com --tls-verify=false -u xxx -p xxx Login Succeeded! root@test-0:~# podman push docker-service-broker-tmp-local.artifactory-jcr.warnerchen.com/devop/test/warner/nginx:mainline-podman --tls-verify=false Getting image source signatures Copying blob 7dca41ff1486 skipped: already exists Copying blob a0c145a29c8d skipped: already exists Copying blob ffe4285e2906 skipped: already exists Copying blob 19b722697f76 skipped: already exists Copying blob c3548211b826 skipped: already exists Copying blob a1fe8b721bb1 skipped: already exists Copying blob 61ef4e878aac skipped: already exists Copying blob 88a3676c9d4f skipped: already exists Copying config cefb6db338 done Writing manifest to image destination Storing signatures
|
Nginx
在 JFrog Container Registry 中,将 Apache 修改为 Nginx:

在安装了 Proxy VM 中,创建目录:
1
| mkdir -pv ~/artifactory-jcr/nginx_subdomain
|
在生成的配置文件中,将 x.x.x.x:8081
和 x.x.x.x:8082
修改成对应的 NodePort,然后保存到上面的目录中:
1 2 3
| root@test-0:~/artifactory-jcr/nginx_subdomain# grep "172.16.16.120" default.conf proxy_pass http://172.16.16.120:32636; proxy_pass http://172.16.16.120:32098;
|
Nginx 相比 Apache 较为方便,准备好配置文件即可启动 Nginx:
1
| podman run -d --name nginx-subdomain -p 80:80 -p 443:443 -v /root/artifactory-jcr/nginx-subdomain/default.conf:/etc/nginx/conf.d/default.conf -v /root/artifactory-jcr/tls:/etc/ssl harbor.warnerchen.com/library/nginx:mainline
|