| local kube = import "../../kube/kube.libsonnet"; |
| local cm = import "../../cluster/kube/lib/cert-manager.libsonnet"; |
| |
| { |
| local app = self, |
| local cfg = app.cfg, |
| cfg:: { |
| namespace: "registry", |
| domain: "k0.hswaw.net", |
| }, |
| |
| metadata(component):: { |
| namespace: cfg.namespace, |
| labels: { |
| "app.kubernetes.io/name": "registry", |
| "app.kubernetes.io/managed-by": "kubecfg", |
| "app.kubernetes.io/component": component, |
| }, |
| }, |
| |
| namespace: kube.Namespace(cfg.namespace), |
| |
| registryIssuer: cm.Issuer("registry-issuer") { |
| metadata+: app.metadata("registry-issuer"), |
| spec: { |
| selfSigned: {}, |
| }, |
| }, |
| authCertificate: cm.Certificate("auth") { |
| metadata+: app.metadata("auth"), |
| spec: { |
| secretName: "auth-internal", |
| duration: "43800h0m0s", // 5 years |
| issuerRef: { |
| name: app.registryIssuer.metadata.name, |
| }, |
| commonName: "auth.registry", |
| }, |
| }, |
| registryCertificate: cm.Certificate("registry") { |
| metadata+: app.metadata("registry"), |
| spec: { |
| secretName: "registry-internal", |
| duration: "43800h0m0s", // 5 years |
| issuerRef: { |
| name: app.registryIssuer.metadata.name, |
| }, |
| commonName: "registry.registry", |
| }, |
| }, |
| |
| registryConfig: kube.ConfigMap("registry-config") { |
| metadata+: app.metadata("registry-config"), |
| data: { |
| "config.yml": std.manifestYamlDoc({ |
| version: "0.1", |
| log: { |
| fields: { |
| service: "registry", |
| }, |
| }, |
| storage: { |
| cache: { |
| blobdescriptor: "inmemory", |
| }, |
| filesystem: { |
| rootdirectory: "/var/lib/registry", |
| }, |
| }, |
| http: { |
| addr: ":5000", |
| headers: { |
| "X-Content-Type-Options": ["nosniff"], |
| }, |
| tls: { |
| certificate: "/certs/tls.crt", |
| key: "/certs/tls.key", |
| }, |
| }, |
| health: { |
| storagedriver: { |
| enabled: true, |
| interval: "10s", |
| threshold: 3, |
| }, |
| }, |
| auth: { |
| token: { |
| realm: "https://registry.%s/auth" % [cfg.domain], |
| service: "my.docker.registry", |
| issuer: "registry.%s auth server" % [cfg.domain], |
| rootcertbundle: "/authcerts/tls.crt", |
| }, |
| }, |
| }), |
| }, |
| }, |
| |
| authConfig: kube.ConfigMap("auth-config") { |
| metadata+: app.metadata("auth-config"), |
| data: { |
| "auth_config.yml": std.manifestYamlDoc({ |
| server: { |
| addr: ":5001", |
| certificate: "/certs/tls.crt", |
| key: "/certs/tls.key", |
| }, |
| token: { |
| issuer: "registry.%s auth server" % [cfg.domain], |
| expiration: 900, |
| }, |
| users: { |
| # Password is specified as a BCrypt hash. Use `htpasswd -nB USERNAME` to generate. |
| "admin": { |
| password: "$2y$05$LO.vzwpWC5LZGqThvEfznu8qhb5SGqvBSWY1J3yZ4AxtMRZ3kN5jC", # badmin |
| }, |
| "test": { |
| password: "$2y$05$WuwBasGDAgr.QCbGIjKJaep4dhxeai9gNZdmBnQXqpKly57oNutya", # 123 |
| }, |
| }, |
| acl: [ |
| { |
| match: {account: "admin"}, |
| actions: ["*"], |
| comment: "Admin has full access to everything.", |
| }, |
| { |
| match: {account: "user"}, |
| actions: ["pull"], |
| comment: "User \"user\" can pull stuff.", |
| }, |
| ], |
| }), |
| } |
| }, |
| |
| authDeployment: kube.Deployment("auth") { |
| metadata+: app.metadata("auth"), |
| spec+: { |
| replicas: 1, |
| template+: { |
| spec+: { |
| volumes_: { |
| config: kube.ConfigMapVolume(app.authConfig), |
| certs: { |
| secret: { secretName: app.authCertificate.spec.secretName }, |
| }, |
| }, |
| containers_: { |
| auth: kube.Container("auth") { |
| image: "cesanta/docker_auth:1", |
| volumeMounts_: { |
| config: { mountPath: "/config" }, |
| certs: { mountPath: "/certs" }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| authService: kube.Service("auth") { |
| metadata+: app.metadata("auth"), |
| target_pod:: app.authDeployment.spec.template, |
| spec+: { |
| type: "ClusterIP", |
| ports: [ |
| { name: "auth", port: 5001, targetPort: 5001, protocol: "TCP" }, |
| ], |
| } |
| }, |
| registryDeployment: kube.Deployment("docker-registry") { |
| metadata+: app.metadata("docker-registry"), |
| spec+: { |
| replicas: 1, |
| template+: { |
| spec+: { |
| volumes_: { |
| config: kube.ConfigMapVolume(app.registryConfig), |
| certs: { |
| secret: { secretName: app.registryCertificate.spec.secretName }, |
| }, |
| authcerts: { |
| secret: { secretName: app.authCertificate.spec.secretName }, |
| }, |
| }, |
| containers_: { |
| registry: kube.Container("docker-registry") { |
| image: "registry:2", |
| args: ["/config/config.yml"], |
| volumeMounts_: { |
| config: { mountPath: "/config" }, |
| certs: { mountPath: "/certs" }, |
| authcerts: { mountPath: "/authcerts" }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| registryService: kube.Service("docker-registry") { |
| metadata+: app.metadata("docker-registry"), |
| target_pod:: app.registryDeployment.spec.template, |
| spec+: { |
| type: "ClusterIP", |
| ports: [ |
| { name: "registry", port: 5000, targetPort: 5000, protocol: "TCP" }, |
| ], |
| } |
| }, |
| registryIngress: kube.Ingress("registry") { |
| metadata+: app.metadata("registry") { |
| annotations+: { |
| "kubernetes.io/tls-acme": "true", |
| "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod", |
| "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", |
| }, |
| }, |
| spec+: { |
| tls: [ |
| { |
| hosts: ["registry.%s" % [cfg.domain]], |
| secretName: "registry-tls", |
| }, |
| ], |
| rules: [ |
| { |
| host: "registry.%s" % [cfg.domain], |
| http: { |
| paths: [ |
| { path: "/auth", backend: app.authService.name_port }, |
| { path: "/", backend: app.registryService.name_port }, |
| ] |
| }, |
| } |
| ], |
| }, |
| }, |
| } |