running goharbor behind a reverse proxy

4/16/2020

Hello i have harbor running perfectly under http://harbor.domain using nginx ingress , i install using the harbor-helm chart.

On the terminal i can push helmcharts to http://harbor.domain/chartrepo/,

i am able to login

docker login harbor.domain:80

and push to the registry.

My challenge is i would like to have harbor be accessed via an apache proxy e.g.

I reinstalled using harbor-helm chart by changing values.yaml

externalURL: https://example.com

So i have then on /etc/apache2/sites-available/example-le-ssl.conf i have added the following

    # helmcharts 
    <Location "/chartrepo/"> 
          ProxyPass "http://harbor.domain/chartrepo/"
          ProxyPassReverse "http://harbor.domain/chartrepo/"
    </Location>

    # harbor 
    <Location "/harbor"> 
          ProxyPass "http://harbor.domain/harbor"
          ProxyPassReverse "http://harbor.domain/harbor"
    </Location>

    # registry 
    <Location "/v2"> 
          ProxyPass "http://harbor.domain/v2"
          ProxyPassReverse "http://harbor.domain/v2"
    </Location>

Unfortunetly if i do docker login example.com docker login returns

Error response from daemon: login attempt to https://example.com/v2/ failed with status: 503 Service Unavailable

i get the following error on the registry logs

error authorizing context: authorization token required

Any ideas of what is i am missing?

Trying to push a chart also fails.

helm push --username='username' --password='password' demo-chart.tgz https://example.com/chartrepo/

The error being

Error: 404: could not properly parse response JSON: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
<hr>
<address>Apache/2.4.41 (Ubuntu) Server at example.com Port 443</address>
</body></html>
-- Eddilbert Macharia
apache
docker-registry
harbor
kubernetes

2 Answers

4/16/2020

It looks like you are not able to authorize to the docker registry. Either you can add the variable to default service account or we can create docker registry secret and add that to deployment as imagepullsecret.

If you want to do that from imagepullsecret, you can create a template helper, something like

/* image pull secret */
{{- define "imagePullSecret" }}
{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.imageCredentials.registry (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }}
{{- end }}

Then you can use that in deployment file like

imagePullSecrets:
      - name: {{.Values.imageCredentials.secretName}}

Entire file may look like

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.appName }}
  namespace: {{ .Values.namespace }}
spec:
  selector:
    matchLabels:
      app: {{ .Values.appName }}
  replicas: {{ .Values.replicaCount }}
  template:
    metadata:
      labels:
        app: {{ .Values.appName }}
    spec:
      containers:
      - name: {{ .Values.appName }}
        image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        {{- if .Values.hasSecretVolume }}
        volumeMounts:
        - name: {{ .Values.appName }}-volume-sec
          mountPath: {{ .Values.secretVolumeMountPath }}
        {{- end}}
        {{- if or .Values.env.configMap .Values.env.secrets }}
        envFrom:
        {{- if .Values.env.configMap }}
        - configMapRef:
            name: {{ .Values.appName }}-env-configmap
        {{- end }}
        {{- if .Values.env.secrets }}
        - secretRef:
            name: {{ .Values.appName }}-env-secret
        {{- end }}
        {{- end }}
        ports:
        - containerPort: {{ .Values.containerPort }}
          protocol: TCP
{{- if .Values.springContainerHealthChecks}}
{{ toYaml .Values.springContainerHealthChecks | indent 8 }}
{{- end}}
      {{- if .Values.hasSecretVolume }}
      volumes:
      - name: {{ .Values.appName }}-volume-sec
        secret:
          secretName: {{ .Values.appName }}-volume-sec
      {{- end}}
      {{- if .Values.imageCredentials}}
      imagePullSecrets:
      - name: {{.Values.imageCredentials.secretName}}
      {{- end}}
-- Shubham Singh
Source: StackOverflow

4/18/2020

my first issue was how apache handles proxying to https backend explained here how to configure apache server to talk to HTTPS backend server?.

I added to my virtualhost /etc/apache2/sites-available/example-le-ssl.conf

    SSLProxyEngine on
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off
    <Location "/v2"> 
          ProxyPass "http://harbor.domain/v2"
          ProxyPassReverse "http://harbor.domain/v2"
    </Location>
    <Location "/service/">
          # RequestHeader set X-Forwarded-Proto "https"
          ProxyPass "http://harbor.domain/service/"
          ProxyPassReverse "http://harbor.domain/service/"
    </Location>
-- Eddilbert Macharia
Source: StackOverflow