From 8d9cfb82925f8c009e6e03fccb478749d5df078d Mon Sep 17 00:00:00 2001 From: David Landry Date: Wed, 16 Oct 2024 15:13:35 -0400 Subject: [PATCH] feat(docker-registry): add registry --- README.md | 1 + apps/docker-registry/base/config.yml | 24 +++++ apps/docker-registry/base/cronjob.yaml | 85 +++++++++++++++ apps/docker-registry/base/deployment.yaml | 102 ++++++++++++++++++ apps/docker-registry/base/ingress.yaml | 33 ++++++ apps/docker-registry/base/kustomization.yaml | 15 +++ apps/docker-registry/base/pdb.yaml | 19 ++++ apps/docker-registry/base/pvc.yaml | 19 ++++ apps/docker-registry/base/service.yaml | 23 ++++ .../overlays/system/config.json | 11 ++ .../overlays/system/deployment.patch.yaml | 10 ++ .../overlays/system/kustomization.yaml | 10 ++ .../overlays/system/secret-generator.yaml | 15 +++ .../overlays/system/secret.enc.yaml | 39 +++++++ 14 files changed, 406 insertions(+) create mode 100644 apps/docker-registry/base/config.yml create mode 100644 apps/docker-registry/base/cronjob.yaml create mode 100644 apps/docker-registry/base/deployment.yaml create mode 100644 apps/docker-registry/base/ingress.yaml create mode 100644 apps/docker-registry/base/kustomization.yaml create mode 100644 apps/docker-registry/base/pdb.yaml create mode 100644 apps/docker-registry/base/pvc.yaml create mode 100644 apps/docker-registry/base/service.yaml create mode 100644 apps/docker-registry/overlays/system/config.json create mode 100644 apps/docker-registry/overlays/system/deployment.patch.yaml create mode 100644 apps/docker-registry/overlays/system/kustomization.yaml create mode 100644 apps/docker-registry/overlays/system/secret-generator.yaml create mode 100644 apps/docker-registry/overlays/system/secret.enc.yaml diff --git a/README.md b/README.md index dcf2808..0bf30f4 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ The private keys are: - K8s cluster as a secret - MacOS - `$HOME/Library/Application Support/sops/age/keys.txt` +- Linux - `$HOME/.config/sops/age/keys.txt` ## 1. Create the resource diff --git a/apps/docker-registry/base/config.yml b/apps/docker-registry/base/config.yml new file mode 100644 index 0000000..13d795a --- /dev/null +++ b/apps/docker-registry/base/config.yml @@ -0,0 +1,24 @@ +health: + storagedriver: + enabled: true + interval: 10s + threshold: 3 +http: + addr: :5000 + debug: + addr: :5001 + prometheus: + enabled: false + path: /metrics + headers: + X-Content-Type-Options: + - nosniff +log: + fields: + service: registry +storage: + cache: + blobdescriptor: inmemory +version: 0.1 + + diff --git a/apps/docker-registry/base/cronjob.yaml b/apps/docker-registry/base/cronjob.yaml new file mode 100644 index 0000000..e2ad559 --- /dev/null +++ b/apps/docker-registry/base/cronjob.yaml @@ -0,0 +1,85 @@ +--- +# Source: docker-registry/templates/cronjob.yaml +apiVersion: batch/v1 +kind: CronJob +metadata: + name: docker-registry-garbage-collector + namespace: gitops + labels: + app: docker-registry + chart: docker-registry-2.2.3 + release: docker-registry + heritage: Helm +spec: + schedule: "0 1 * * *" + jobTemplate: + metadata: + labels: + app: docker-registry + release: docker-registry + annotations: + checksum/config: 7768037b11264d8a85079c7389faa0b2846b55771ae7ea102d41f7ea868676fb + checksum/secret: cf8de4fbecd435bc3788328888b074e895540fd0a0681fa391ee2d3f42e1e599 + spec: + template: + spec: + securityContext: + fsGroup: 1000 + runAsUser: 1000 + containers: + - name: docker-registry + image: "registry:2.8.1" + imagePullPolicy: IfNotPresent + command: + - /bin/registry + - garbage-collect + - --delete-untagged=true + - /etc/docker/registry/config.yml + env: + - name: REGISTRY_HTTP_SECRET + valueFrom: + secretKeyRef: + name: docker-registry-secret + key: haSharedSecret + - name: REGISTRY_AUTH + value: "htpasswd" + - name: REGISTRY_AUTH_HTPASSWD_REALM + value: "Registry Realm" + - name: REGISTRY_AUTH_HTPASSWD_PATH + value: "/auth/htpasswd" + - name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY + value: "/var/lib/registry" + - name: REGISTRY_PROXY_REMOTEURL + value: https://registry-1.docker.io + - name: REGISTRY_PROXY_USERNAME + valueFrom: + secretKeyRef: + name: docker-registry-secret + key: proxyUsername + - name: REGISTRY_PROXY_PASSWORD + valueFrom: + secretKeyRef: + name: docker-registry-secret + key: proxyPassword + volumeMounts: + - name: "docker-registry-config" + mountPath: "/etc/docker/registry" + - name: auth + mountPath: /auth + readOnly: true + - name: data + mountPath: /var/lib/registry/ + restartPolicy: OnFailure + volumes: + - name: docker-registry-config + configMap: + name: docker-registry-config + - name: auth + secret: + secretName: docker-registry-secret + items: + - key: htpasswd + path: htpasswd + - name: data + emptyDir: {} + diff --git a/apps/docker-registry/base/deployment.yaml b/apps/docker-registry/base/deployment.yaml new file mode 100644 index 0000000..c748fd4 --- /dev/null +++ b/apps/docker-registry/base/deployment.yaml @@ -0,0 +1,102 @@ +--- +# Source: docker-registry/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: docker-registry + namespace: gitops + labels: + app: docker-registry + chart: docker-registry-2.2.3 + release: docker-registry + heritage: Helm +spec: + selector: + matchLabels: + app: docker-registry + release: docker-registry + replicas: 1 + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + minReadySeconds: 5 + template: + metadata: + labels: + app: docker-registry + release: docker-registry + annotations: + updated-at/secret: 2024-10-16T14:38:25-04:00 + spec: + securityContext: + fsGroup: 1000 + runAsUser: 1000 + containers: + - name: docker-registry + image: "registry:2.8.1" + imagePullPolicy: IfNotPresent + command: + - /bin/registry + - serve + - /etc/docker/registry/config.yml + ports: + - containerPort: 5000 + livenessProbe: + httpGet: + path: / + port: 5000 + readinessProbe: + httpGet: + path: / + port: 5000 + resources: + {} + env: + - name: REGISTRY_HTTP_SECRET + valueFrom: + secretKeyRef: + name: docker-registry-secret + key: haSharedSecret + - name: REGISTRY_AUTH + value: "htpasswd" + - name: REGISTRY_AUTH_HTPASSWD_REALM + value: "Registry Realm" + - name: REGISTRY_AUTH_HTPASSWD_PATH + value: "/auth/htpasswd" + - name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY + value: "/var/lib/registry" + - name: REGISTRY_PROXY_REMOTEURL + value: https://registry-1.docker.io + - name: REGISTRY_PROXY_USERNAME + valueFrom: + secretKeyRef: + name: docker-registry-secret + key: proxyUsername + - name: REGISTRY_PROXY_PASSWORD + valueFrom: + secretKeyRef: + name: docker-registry-secret + key: proxyPassword + volumeMounts: + - name: "docker-registry-config" + mountPath: "/etc/docker/registry" + - name: auth + mountPath: /auth + readOnly: true + - name: data + mountPath: /var/lib/registry/ + volumes: + - name: docker-registry-config + configMap: + name: docker-registry-config + - name: auth + secret: + secretName: docker-registry-secret + items: + - key: htpasswd + path: htpasswd + - name: data + persistentVolumeClaim: + claimName: docker-registry diff --git a/apps/docker-registry/base/ingress.yaml b/apps/docker-registry/base/ingress.yaml new file mode 100644 index 0000000..c49da51 --- /dev/null +++ b/apps/docker-registry/base/ingress.yaml @@ -0,0 +1,33 @@ +--- +# Source: docker-registry/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: docker-registry + namespace: gitops + labels: + app: docker-registry + chart: docker-registry-2.2.3 + release: docker-registry + heritage: Helm + annotations: + cert-manager.io/cluster-issuer: letsencrypt-issuer + nginx.ingress.kubernetes.io/whitelist-source-range: 192.168.1.1/16 +spec: + ingressClassName: nginx + rules: + - host: registry.int.nc.landry.land + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: docker-registry + port: + name: http + tls: + - hosts: + - registry.int.nc.landry.land + secretName: registry-tls + diff --git a/apps/docker-registry/base/kustomization.yaml b/apps/docker-registry/base/kustomization.yaml new file mode 100644 index 0000000..154990e --- /dev/null +++ b/apps/docker-registry/base/kustomization.yaml @@ -0,0 +1,15 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - deployment.yaml + - ingress.yaml + - pvc.yaml + - service.yaml + - pdb.yaml + - cronjob.yaml + +configMapGenerator: + - name: docker-registry-config + files: + - config.yml diff --git a/apps/docker-registry/base/pdb.yaml b/apps/docker-registry/base/pdb.yaml new file mode 100644 index 0000000..8a72286 --- /dev/null +++ b/apps/docker-registry/base/pdb.yaml @@ -0,0 +1,19 @@ +--- +# Source: docker-registry/templates/poddisruptionbudget.yaml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: docker-registry + namespace: gitops + labels: + app: docker-registry + chart: docker-registry-2.2.3 + release: docker-registry + heritage: Helm +spec: + selector: + matchLabels: + app: docker-registry + release: docker-registry + maxUnavailable: 1 + diff --git a/apps/docker-registry/base/pvc.yaml b/apps/docker-registry/base/pvc.yaml new file mode 100644 index 0000000..8ca3e6d --- /dev/null +++ b/apps/docker-registry/base/pvc.yaml @@ -0,0 +1,19 @@ +--- +# Source: docker-registry/templates/pvc.yaml +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: docker-registry + namespace: gitops + labels: + app: docker-registry + chart: "docker-registry-2.2.3" + release: "docker-registry" + heritage: "Helm" +spec: + accessModes: + - "ReadWriteOnce" + resources: + requests: + storage: "10Gi" + diff --git a/apps/docker-registry/base/service.yaml b/apps/docker-registry/base/service.yaml new file mode 100644 index 0000000..2aaf845 --- /dev/null +++ b/apps/docker-registry/base/service.yaml @@ -0,0 +1,23 @@ +--- +# Source: docker-registry/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: docker-registry + namespace: gitops + labels: + app: docker-registry + chart: docker-registry-2.2.3 + release: docker-registry + heritage: Helm +spec: + type: ClusterIP + ports: + - port: 5000 + protocol: TCP + name: http + targetPort: 5000 + selector: + app: docker-registry + release: docker-registry + diff --git a/apps/docker-registry/overlays/system/config.json b/apps/docker-registry/overlays/system/config.json new file mode 100644 index 0000000..2572eef --- /dev/null +++ b/apps/docker-registry/overlays/system/config.json @@ -0,0 +1,11 @@ +{ + "appName": "docker-registry", + "userGivenName": "docker-registry", + "destNamespace": "gitops", + "destServer": "https://kubernetes.default.svc", + "srcPath": "apps/docker-registry/overlays/system", + "srcRepoURL": "ssh://git@gitea-ssh.gitops.svc.cluster.local:2222/davad/argo.git", + "srcTargetRevision": "", + "labels": null, + "annotations": null +} diff --git a/apps/docker-registry/overlays/system/deployment.patch.yaml b/apps/docker-registry/overlays/system/deployment.patch.yaml new file mode 100644 index 0000000..58d94e9 --- /dev/null +++ b/apps/docker-registry/overlays/system/deployment.patch.yaml @@ -0,0 +1,10 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: docker-registry +spec: + template: + metadata: + annotations: + updated-at/secret: 2024-10-16T15:23-04:00 + diff --git a/apps/docker-registry/overlays/system/kustomization.yaml b/apps/docker-registry/overlays/system/kustomization.yaml new file mode 100644 index 0000000..1d9bcf6 --- /dev/null +++ b/apps/docker-registry/overlays/system/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ../../base + +generators: + - ./secret-generator.yaml + +patches: + - path: ./deployment.patch.yaml diff --git a/apps/docker-registry/overlays/system/secret-generator.yaml b/apps/docker-registry/overlays/system/secret-generator.yaml new file mode 100644 index 0000000..17231ea --- /dev/null +++ b/apps/docker-registry/overlays/system/secret-generator.yaml @@ -0,0 +1,15 @@ +apiVersion: viaduct.ai/v1 +kind: ksops +metadata: + # Specify a name + name: example-secret-generator + annotations: + config.kubernetes.io/function: | + exec: + # if the binary is in your PATH, you can do + path: ksops + # otherwise, path should be relative to manifest files, like + # path: ../../../ksops +files: + - ./secret.enc.yaml + diff --git a/apps/docker-registry/overlays/system/secret.enc.yaml b/apps/docker-registry/overlays/system/secret.enc.yaml new file mode 100644 index 0000000..f8dc4b2 --- /dev/null +++ b/apps/docker-registry/overlays/system/secret.enc.yaml @@ -0,0 +1,39 @@ +# htpasswd is what our docker client uses to authenticate +# haSharedSecret, I _think_ is used internally by the registry +# proxyUsername and proxyPassword are used to pull from the upstream registry +apiVersion: v1 +kind: Secret +metadata: + name: docker-registry-secret + namespace: gitops + labels: + app: docker-registry + chart: docker-registry-2.2.3 + heritage: Helm + release: docker-registry +type: Opaque +data: + htpasswd: ENC[AES256_GCM,data:5h7uURIfPb0rhgFkVtyAPaxvWdQme+XO658zokdFo/MW63ums/ZPfM1ZGNstxX9Vu9u+0xaEUShl3Nx40ZC1R0zIrxZiBkUVqP4wHn1cWMuENGAyuXx4ZA==,iv:gahLRzdg00DjgA1TjPWsP7Gl2L4pROdoUojS6FW0P7M=,tag:0fG1LgSXpslaU9Hpq65Zxw==,type:str] + haSharedSecret: ENC[AES256_GCM,data:7T1G6Mn6ZDl+zPWcgUHyWtu0YLQ7xTu0,iv:ppzjJfrkjQ6HqoODQzalkhHYCkBJWrjpu9h6GAl8T3I=,tag:3QEuf5MkTsvF7gMHfnby9A==,type:str] + proxyUsername: "" + proxyPassword: "" +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1y26vr5qt6th3wu92rnsgkqcpxxah3pqkqa4khcjjycm3kg40aqyqjgfzx9 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaWkxRSmtSQjhMdFJsUVVQ + ck5PTW5rUnNPZEZMZWRDWlFBdjhqOTRmbVZJClJqSkVudWpuUFUyT3VEMXhwTVIv + WFM5RUxMSXVkdGlKdG9MSEtTVkZHalUKLS0tIE5UWWIzamMrQ004cktwL01TYU5j + R0d6SEpsWmMvOW4yWEVpZ1JWZWNaMEEKkZQF0LdmNb7gLPHpcNO69JmvgM9eOsE7 + /j3vwbU4GcYzyl9BDW9g7JldKxHSiFAH4CUHye9dQo2cKV2pQy00DQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-10-16T19:27:14Z" + mac: ENC[AES256_GCM,data:Wsiav/1E4LxZEDFJ4J4P0q4IIcaXb/dzTfLVqi5hbIak8mIWWi6dcmB9jCJ6uKwHlQtQ35FtnZyugdcOGrnC/qgAc6Y0cU/wq942rZgQmNuNmeQb+1npE1j7pAWu8Ws57ge/hepDuWRhQgb/+1mqBJRAWPoAl2RpoopTFFyW1U8=,iv:7VeiEu7ovC0I8Te7aZrFt+t4mgsaEOJXhH5rFYG+RDw=,tag:7SdU45JfGirXW+/k65s5vg==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.1