Artifactory Docker Push报405 Method Not Allowed问题求助
问题描述
我们使用Artifactory Pro许可证,通过Helm在Kubernetes上部署了Artifactory。创建Repository Path模式的Docker本地仓库并推送镜像时,出现405 Method Not Allowed错误,但Docker登录、拉取功能正常。
错误信息
docker push art2.bee0dev.lge.com/docker-local/hello-world e07ee1baac5f: Pushing [==================================================>] 14.85kB unknown: Method Not Allowed
环境架构
在Nginx Ingress Controller前端部署了负责TLS的HAProxy负载均衡器(Nginx Ingress的HTTP NodePort为31071)。
配置文件
Artifactory Helm values.yaml
global: joinKeySecretName: "artbee-stg-joinkey-secret" masterKeySecretName: "artbee-stg-masterkey-secret" storageClass: "sa-stg-netapp8300-bee-blk-nonretain" ingress: enabled: true defaultBackend: enabled: false hosts: ["art2.bee0dev.lge.com"] routerPath: / artifactoryPath: /artifactory/ className: "" annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/proxy-read-timeout: "600" nginx.ingress.kubernetes.io/proxy-send-timeout: "600" nginx.ingress.kubernetes.io/configuration-snippet: | proxy_pass_header Server; proxy_set_header X-JFrog-Override-Base-Url https://art2.bee0dev.lge.com; labels: {} tls: [] additionalRules: [] ## Artifactory license. artifactory: name: artifactory replicaCount: 1 image: registry: releases-docker.jfrog.io repository: jfrog/artifactory-pro # tag: pullPolicy: IfNotPresent labels: {} updateStrategy: type: RollingUpdate migration: enabled: false customInitContainersBegin: | - name: "init-mount-permission-setup" image: "{{ .Values.initContainerImage }}" imagePullPolicy: "{{ .Values.artifactory.image.pullPolicy }}" securityContext: runAsUser: 0 runAsGroup: 0 allowPrivilegeEscalation: false capabilities: drop: - NET_RAW command: - 'bash' - '-c' - if [ $(ls -la /var/opt/jfrog | grep artifactory | awk -F' ' '{print $3$4}') == 'rootroot' ]; then echo "mount permission=> root:root"; echo "change mount permission to 1030:1030 " {{ .Values.artifactory.persistence.mountPath }}; chown -R 1030:1030 {{ .Values.artifactory.persistence.mountPath }}; else echo "already set. No change required."; ls -la {{ .Values.artifactory.persistence.mountPath }}; fi volumeMounts: - mountPath: "{{ .Values.artifactory.persistence.mountPath }}" name: artifactory-volume database: maxOpenConnections: 80 tomcat: maintenanceConnector: port: 8091 connector: maxThreads: 200 sendReasonPhrase: false extraConfig: 'acceptCount="100"' customPersistentVolumeClaim: {} license: ## licenseKey is the license key in plain text. Use either this or the license.secret setting licenseKey: "???" secret: dataKey: resources: requests: memory: "2Gi" cpu: "1" limits: memory: "20Gi" cpu: "8" javaOpts: xms: "1g" xmx: "12g" admin: ip: "127.0.0.1" username: "admin" password: "!swiit123" secret: dataKey: service: name: artifactory type: ClusterIP loadBalancerSourceRanges: [] annotations: {} persistence: mountPath: "/var/opt/jfrog/artifactory" enabled: true accessMode: ReadWriteOnce size: 100Gi type: file-system storageClassName: "sa-stg-netapp8300-bee-blk-nonretain" nginx: enabled: false
HAProxy配置
frontend cto-stage-http-frontend bind 10.185.60.75:80 bind 10.185.60.76:80 bind 10.185.60.201:80 bind 10.185.60.75:443 ssl crt /etc/haproxy/ssl/bee0dev.lge.com.pem ssl-min-ver TLSv1.2 ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 bind 10.185.60.76:443 ssl crt /etc/haproxy/ssl/bee0dev.lge.com.pem ssl-min-ver TLSv1.2 ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 bind 10.185.60.201:443 ssl crt /etc/haproxy/ssl/bee0dev.lge.com.pem ssl-min-ver TLSv1.2 ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 mode http option forwardfor option accept-invalid-http-request acl k8s-cto-stage hdr_end(host) -i -f /etc/haproxy/web-ide/cto-stage use_backend k8s-cto-stage-http if k8s-cto-stage backend k8s-cto-stage-http mode http redirect scheme https if !{ ssl_fc } option tcp-check balance roundrobin server lgestgbee04v 10.185.60.78:31071 check fall 3 rise 2
解决方案
针对该405错误,排查和修复步骤如下:
1. 修正Ingress路径映射
当前Ingress的routerPath: /与artifactoryPath: /artifactory/组合会导致Docker推送请求的路径转发异常。Docker推送的请求路径为/docker-local/v2/...,需添加专门的转发规则:
修改Ingress配置中的additionalRules:
ingress: # 其他配置保持不变 additionalRules: - host: art2.bee0dev.lge.com http: paths: - path: /v2 pathType: Prefix backend: service: name: {{ .Values.artifactory.service.name }} port: number: 8081 - path: /docker-local pathType: Prefix backend: service: name: {{ .Values.artifactory.service.name }} port: number: 8081
或直接调整artifactoryPath为/,确保所有请求都能正确转发:
ingress: artifactoryPath: / # 其他配置保持不变
2. 调整HAProxy重定向规则
HAProxy后端的redirect scheme https if !{ ssl_fc }会将HTTP请求强制重定向到HTTPS,但默认重定向会丢失请求方法(如POST/PUT),导致405错误。修改为保留请求方法的307重定向:
backend k8s-cto-stage-http mode http redirect scheme https code 307 if !{ ssl_fc } option tcp-check balance roundrobin server lgestgbee04v 10.185.60.78:31071 check fall 3 rise 2
3. 验证Artifactory仓库配置
确保Docker本地仓库的Repository Path模式配置正确:
- 仓库Key为
docker-local - 已勾选
Enable Docker V2 API - 路径模式设置为
Repository Path
4. 测试推送
更新配置后重新部署Artifactory和Ingress,执行推送测试:
docker push art2.bee0dev.lge.com/docker-local/hello-world:latest
内容的提问来源于stack exchange,提问作者cheoro
相关产品推荐
相关产品推荐

