Commit d56cbe7f by Guangbo Chen

added docker registry chart

parent 071261b7
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
apiVersion: v1
description: A Helm chart for Docker Registry
name: docker-registry
version: 1.4.3
appVersion: 2.6.2
home: https://hub.docker.com/_/registry/
icon: https://camo.githubusercontent.com/1e11d429705bf6695b79d24966cb1267c00b7df6/68747470733a2f2f7777772e646f636b65722e636f6d2f73697465732f64656661756c742f66696c65732f6f79737465722d72656769737472792d332e706e67
sources:
- https://github.com/docker/distribution-library-image
maintainers:
- name: jpds
email: jpds@protonmail.com
- name: rendhalver
email: pete.brown@powerhrg.com
approvers:
- jpds
- rendhalver
reviewers:
- jpds
- rendhalver
# Docker Registry Helm Chart
This directory contains a Kubernetes chart to deploy a private Docker Registry.
## Prerequisites Details
* PV support on underlying infrastructure (if persistence is required)
## Chart Details
This chart will do the following:
* Implement a Docker registry deployment
## Configuration
The following table lists the configurable parameters of the docker-registry chart and
their default values.
| Parameter | Description | Default |
|:----------------------------|:-------------------------------------------------------------------------------------------|:----------------|
| `image.pullPolicy` | Container pull policy | `IfNotPresent` |
| `image.repository` | Container image to use | `registry` |
| `image.tag` | Container image tag to deploy | `2.6.2` |
| `imagePullSecrets` | Specify image pull secrets | `nil` (does not add image pull secrets to deployed pods) |
| `persistence.accessMode` | Access mode to use for PVC | `ReadWriteOnce` |
| `persistence.enabled` | Whether to use a PVC for the Docker storage | `false` |
| `persistence.size` | Amount of space to claim for PVC | `10Gi` |
| `persistence.storageClass` | Storage Class to use for PVC | `-` |
| `persistence.existingClaim` | Name of an existing PVC to use for config | `nil` |
| `service.port` | TCP port on which the service is exposed | `5000` |
| `service.type` | service type | `ClusterIP` |
| `service.clusterIP` | if `service.type` is `ClusterIP` and this is non-empty, sets the cluster IP of the service | `nil` |
| `service.nodePort` | if `service.type` is `NodePort` and this is non-empty, sets the node port of the service | `nil` |
| `replicaCount` | k8s replicas | `1` |
| `updateStrategy` | update strategy for deployment | `{}` |
| `podAnnotations` | Annotations for pod | `{}` |
| `resources.limits.cpu` | Container requested CPU | `nil` |
| `resources.limits.memory` | Container requested memory | `nil` |
| `storage` | Storage system to use | `filesystem` |
| `tlsSecretName` | Name of secret for TLS certs | `nil` |
| `secrets.htpasswd` | Htpasswd authentication | `nil` |
| `secrets.s3.accessKey` | Access Key for S3 configuration | `nil` |
| `secrets.s3.secretKey` | Secret Key for S3 configuration | `nil` |
| `secrets.swift.username` | Username for Swift configuration | `nil` |
| `secrets.swift.password` | Password for Swift configuration | `nil` |
| `haSharedSecret` | Shared secret for Registry | `nil` |
| `configData` | Configuration hash for docker | `nil` |
| `s3.region` | S3 region | `nil` |
| `s3.bucket` | S3 bucket name | `nil` |
| `s3.encrypt` | Store images in encrypted format | `nil` |
| `s3.secure` | Use HTTPS | `nil` |
| `swift.authurl` | Swift authurl | `nil` |
| `swift.container` | Swift container | `nil` |
To generate htpasswd file, run this docker command:
`docker run --entrypoint htpasswd registry:2 -Bbn user password > ./htpasswd`.
questions:
- variable: persistence.enabled
default: false
description: "Enable persistent volume for Docker registry"
type: boolean
label: Docker Registry Persistent Volume Enabled
show_subquestion_if: true
group: "Settings"
subquestions:
- variable: persistence.size
default: "10Gi"
description: "Docker registry Registry Persistent Volume Size"
type: string
label: Docker Registry Volume Size
- variable: persistence.storageClass
default: ""
description: "If undefined or null, uses the default StorageClass. Default to null"
type: storageclass
label: Default StorageClass for Docker Registry
- variable: ingress.enabled
default: true
description: "Expose app using Layer 7 Load Balancer - ingress"
type: boolean
label: Expose app using Layer 7 Load Balancer
show_subquestion_if: true
group: "Services and Load Balancing"
subquestions:
- variable: ingress.hosts[0]
default: "xip.io"
description: "Hostname to your Docker Registry installation"
type: hostname
required: true
label: Hostname
- variable: service.type
default: "NodePort"
description: "Docker Registry Service type"
type: enum
options:
- "ClusterIP"
- "NodePort"
required: true
label: Docker Registry Service Type
show_subquestion_if: "NodePort"
group: "Services and Load Balancing"
subquestions:
- variable: service.nodePort
default: ""
description: "NodePort http port(to set explicitly, choose port between 30000-32767)"
type: int
min: 30000
max: 32767
label: NodePort Http Port
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range .Values.ingress.hosts }}
http://{{ . }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "docker-registry.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc -w {{ template "docker-registry.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "docker-registry.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:{{ .Values.service.externalPort }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "docker-registry.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:{{ .Values.service.port }}
{{- end }}
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "docker-registry.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "docker-registry.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s" .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: "{{ .Release.Name }}-crt"
spec:
secretName: "{{ .Release.Name }}-crt"
acme:
config:
- http01:
ingress: {{ template "docker-registry.fullname" . }}
domains:
- xip.io
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "docker-registry.fullname" . }}-config
labels:
app: {{ template "docker-registry.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
data:
config.yml: |-
{{ toYaml .Values.configData | indent 4 }}
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: {{ template "docker-registry.fullname" . }}
labels:
app: {{ template "docker-registry.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
replicas: {{ .Values.replicaCount }}
{{- if .Values.updateStrategy }}
strategy:
{{ toYaml .Values.updateStrategy | indent 4 }}
{{- end }}
minReadySeconds: 5
template:
metadata:
labels:
app: {{ template "docker-registry.name" . }}
release: {{ .Release.Name }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
{{- if $.Values.podAnnotations }}
{{ toYaml $.Values.podAnnotations | indent 8 }}
{{- end }}
spec:
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{ toYaml .Values.imagePullSecrets | indent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command:
- /bin/registry
- serve
- /etc/docker/registry/config.yml
ports:
- containerPort: {{ .Values.service.port }}
livenessProbe:
httpGet:
{{- if .Values.tlsSecretName }}
scheme: HTTPS
{{- end }}
path: /
port: {{ .Values.service.port }}
readinessProbe:
httpGet:
{{- if .Values.tlsSecretName }}
scheme: HTTPS
{{- end }}
path: /
port: {{ .Values.service.port }}
resources:
{{ toYaml .Values.resources | indent 12 }}
env:
{{- if .Values.secrets.htpasswd }}
- name: REGISTRY_AUTH
value: "htpasswd"
- name: REGISTRY_AUTH_HTPASSWD_REALM
value: "Registry Realm"
- name: REGISTRY_AUTH_HTPASSWD_PATH
value: "/auth/htpasswd"
{{- end }}
- name: REGISTRY_HTTP_SECRET
valueFrom:
secretKeyRef:
name: {{ template "docker-registry.fullname" . }}-secret
key: haSharedSecret
{{- if .Values.tlsSecretName }}
- name: REGISTRY_HTTP_TLS_CERTIFICATE
value: /etc/ssl/docker/tls.crt
- name: REGISTRY_HTTP_TLS_KEY
value: /etc/ssl/docker/tls.key
{{- end }}
{{- if eq .Values.storage "filesystem" }}
- name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
value: "/var/lib/registry"
{{- else if eq .Values.storage "s3" }}
- name: REGISTRY_STORAGE_S3_ACCESSKEY
valueFrom:
secretKeyRef:
name: {{ template "docker-registry.fullname" . }}-secret
key: s3AccessKey
- name: REGISTRY_STORAGE_S3_SECRETKEY
valueFrom:
secretKeyRef:
name: {{ template "docker-registry.fullname" . }}-secret
key: s3SecretKey
- name: REGISTRY_STORAGE_S3_REGION
value: {{ required ".Values.s3.region is required" .Values.s3.region }}
- name: REGISTRY_STORAGE_S3_BUCKET
value: {{ required ".Values.s3.bucket is required" .Values.s3.bucket }}
{{- if .Values.s3.encrypt }}
- name: REGISTRY_STORAGE_S3_ENCRYPT
value: {{ .Values.s3.encrypt | quote }}
{{- end }}
{{- if .Values.s3.secure }}
- name: REGISTRY_STORAGE_S3_SECURE
value: {{ .Values.s3.secure | quote }}
{{- end }}
{{- else if eq .Values.storage "swift" }}
- name: REGISTRY_STORAGE_SWIFT_AUTHURL
value: {{ required ".Values.swift.authurl is required" .Values.swift.authurl }}
- name: REGISTRY_STORAGE_SWIFT_USERNAME
valueFrom:
secretKeyRef:
name: {{ template "docker-registry.fullname" . }}-secret
key: swiftUsername
- name: REGISTRY_STORAGE_SWIFT_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "docker-registry.fullname" . }}-secret
key: swiftPassword
- name: REGISTRY_STORAGE_SWIFT_CONTAINER
value: {{ required ".Values.swift.container is required" .Values.swift.container }}
{{- end }}
volumeMounts:
{{- if .Values.secrets.htpasswd }}
- name: auth
mountPath: /auth
readOnly: true
{{- end }}
{{- if eq .Values.storage "filesystem" }}
- name: data
mountPath: /var/lib/registry/
{{- end }}
- name: "{{ template "docker-registry.fullname" . }}-config"
mountPath: "/etc/docker/registry"
{{- if .Values.tlsSecretName }}
- mountPath: /etc/ssl/docker
name: tls-cert
readOnly: true
{{- end }}
{{- if .Values.nodeSelector }}
nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
{{- end }}
volumes:
{{- if .Values.secrets.htpasswd }}
- name: auth
secret:
secretName: {{ template "docker-registry.fullname" . }}-secret
items:
- key: htpasswd
path: htpasswd
{{- end }}
{{- if eq .Values.storage "filesystem" }}
- name: data
{{- if .Values.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "docker-registry.fullname" . }}{{- end }}
{{- else }}
emptyDir: {}
{{- end -}}
{{- end }}
- name: {{ template "docker-registry.fullname" . }}-config
configMap:
name: {{ template "docker-registry.fullname" . }}-config
{{- if .Values.tlsSecretName }}
- name: tls-cert
secret:
secretName: {{ .Values.tlsSecretName }}
{{- end }}
{{- if .Values.ingress.enabled -}}
{{- $serviceName := .Release.Name -}}
{{- $servicePort := .Values.service.port -}}
{{- $path := .Values.ingress.path -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ template "docker-registry.fullname" . }}
labels:
app: {{ template "docker-registry.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
annotations:
{{- range $key, $value := .Values.ingress.annotations }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
rules:
{{- range $host := .Values.ingress.hosts }}
- host: {{ $host }}
http:
paths:
- path: {{ $path }}
backend:
serviceName: {{ $serviceName }}
servicePort: {{ $servicePort }}
{{- end }}
tls:
- hosts:
{{- range $host := .Values.ingress.hosts }}
- {{ $host }}
{{- end }}
secretName: {{ .Release.Name }}-crt
{{- if .Values.ingress.tls }}
{{ toYaml .Values.ingress.tls | indent 4 }}
{{- end }}
{{- end }}
{{- if .Values.persistence.enabled }}
{{- if not .Values.persistence.existingClaim -}}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "docker-registry.fullname" . }}
labels:
app: {{ template "docker-registry.fullname" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
spec:
accessModes:
- {{ .Values.persistence.accessMode | quote }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- if .Values.persistence.storageClass }}
{{- if (eq "-" .Values.persistence.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.persistence.storageClass }}"
{{- end }}
{{- end }}
{{- end }}
{{- end -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "docker-registry.fullname" . }}-secret
labels:
app: {{ template "docker-registry.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
type: Opaque
data:
{{- if .Values.secrets.htpasswd }}
htpasswd: {{ .Values.secrets.htpasswd | b64enc }}
{{- end }}
{{- if .Values.secrets.haSharedSecret }}
haSharedSecret: {{ .Values.secrets.haSharedSecret | b64enc | quote }}
{{- else }}
haSharedSecret: {{ randAlphaNum 16 | b64enc | quote }}
{{- end }}
{{- if eq .Values.storage "s3" }}
{{- if and .Values.secrets.s3.secretKey .Values.secrets.s3.accessKey }}
s3AccessKey: {{ .Values.secrets.s3.accessKey | b64enc | quote }}
s3SecretKey: {{ .Values.secrets.s3.secretKey | b64enc | quote }}
{{- end }}
{{- else if eq .Values.storage "swift" }}
{{- if and .Values.secrets.swift.username .Values.secrets.swift.password }}
swiftUsername: {{ .Values.secrets.swift.username | b64enc | quote }}
swiftPassword: {{ .Values.secrets.swift.password | b64enc | quote }}
{{- end }}
{{- end }}
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
labels:
app: {{ template "docker-registry.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- if .Values.service.annotations }}
annotations:
{{ toYaml .Values.service.annotations | indent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
{{- if (and (eq .Values.service.type "ClusterIP") (not (empty .Values.service.clusterIP))) }}
clusterIP: {{ .Values.service.clusterIP }}
{{- end }}
ports:
- port: {{ .Values.service.port }}
protocol: TCP
name: {{ .Values.service.name }}
targetPort: {{ .Values.service.port }}
{{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }}
nodePort: {{ .Values.service.nodePort }}
{{- end }}
selector:
app: {{ template "docker-registry.name" . }}
release: {{ .Release.Name }}
# Default values for docker-registry.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
updateStrategy:
# type: RollingUpdate
# rollingUpdate:
# maxSurge: 1
# maxUnavailable: 0
podAnnotations: {}
image:
repository: registry
tag: 2.6.2
pullPolicy: IfNotPresent
# imagePullSecrets:
# - name: docker
service:
name: registry
type: ClusterIP
# clusterIP:
port: 5000
# nodePort:
annotations: {}
# foo.io/bar: "true"
ingress:
enabled: false
path: ""
# Used to create an Ingress record.
hosts:
- chart-example.local
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
tls:
# Secrets must be manually created in the namespace.
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
persistence:
accessMode: 'ReadWriteOnce'
enabled: false
size: 10Gi
# storageClass: '-'
# set the type of filesystem to use: filesystem, s3
storage: filesystem
# Set this to name of secret for tls certs
# tlsSecretName: registry.docker.example.com
secrets:
haSharedSecret: ""
htpasswd: ""
# Secrets for S3 access and secret keys
# s3:
# accessKey: ""
# secretKey: ""
# Secrets for Swift username and password
# swift:
# username: ""
# password: ""
# Options for s3 storage type:
# s3:
# region: us-east-1
# bucket: my-bucket
# encrypt: false
# secure: true
# Options for swift storage type:
# swift:
# authurl: http://swift.example.com/
# container: my-container
configData:
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment