blob: 0b7fea569f5653b2245aaacc7cc2ad23fde9d5b1 [file] [log] [blame]
Piotr Dobrowolski6dc48392019-04-02 18:07:21 +02001local kube = import "../../kube/kube.libsonnet";
2local cm = import "../../cluster/kube/lib/cert-manager.libsonnet";
3
4{
5 local app = self,
6 local cfg = app.cfg,
7 cfg:: {
8 namespace: "registry",
9 domain: "k0.hswaw.net",
10 },
11
12 metadata(component):: {
13 namespace: cfg.namespace,
14 labels: {
15 "app.kubernetes.io/name": "registry",
16 "app.kubernetes.io/managed-by": "kubecfg",
17 "app.kubernetes.io/component": component,
18 },
19 },
20
21 namespace: kube.Namespace(cfg.namespace),
22
23 registryIssuer: cm.Issuer("registry-issuer") {
24 metadata+: app.metadata("registry-issuer"),
25 spec: {
26 selfSigned: {},
27 },
28 },
29 authCertificate: cm.Certificate("auth") {
30 metadata+: app.metadata("auth"),
31 spec: {
32 secretName: "auth-internal",
33 duration: "43800h0m0s", // 5 years
34 issuerRef: {
35 name: app.registryIssuer.metadata.name,
36 },
37 commonName: "auth.registry",
38 },
39 },
40 registryCertificate: cm.Certificate("registry") {
41 metadata+: app.metadata("registry"),
42 spec: {
43 secretName: "registry-internal",
44 duration: "43800h0m0s", // 5 years
45 issuerRef: {
46 name: app.registryIssuer.metadata.name,
47 },
48 commonName: "registry.registry",
49 },
50 },
51
52 registryConfig: kube.ConfigMap("registry-config") {
53 metadata+: app.metadata("registry-config"),
54 data: {
55 "config.yml": std.manifestYamlDoc({
56 version: "0.1",
57 log: {
58 fields: {
59 service: "registry",
60 },
61 },
62 storage: {
63 cache: {
64 blobdescriptor: "inmemory",
65 },
66 filesystem: {
67 rootdirectory: "/var/lib/registry",
68 },
69 },
70 http: {
71 addr: ":5000",
72 headers: {
73 "X-Content-Type-Options": ["nosniff"],
74 },
75 tls: {
76 certificate: "/certs/tls.crt",
77 key: "/certs/tls.key",
78 },
79 },
80 health: {
81 storagedriver: {
82 enabled: true,
83 interval: "10s",
84 threshold: 3,
85 },
86 },
87 auth: {
88 token: {
89 realm: "https://registry.%s/auth" % [cfg.domain],
90 service: "my.docker.registry",
91 issuer: "registry.%s auth server" % [cfg.domain],
92 rootcertbundle: "/authcerts/tls.crt",
93 },
94 },
95 }),
96 },
97 },
98
99 authConfig: kube.ConfigMap("auth-config") {
100 metadata+: app.metadata("auth-config"),
101 data: {
102 "auth_config.yml": std.manifestYamlDoc({
103 server: {
104 addr: ":5001",
105 certificate: "/certs/tls.crt",
106 key: "/certs/tls.key",
107 },
108 token: {
109 issuer: "registry.%s auth server" % [cfg.domain],
110 expiration: 900,
111 },
112 users: {
113 # Password is specified as a BCrypt hash. Use `htpasswd -nB USERNAME` to generate.
114 "admin": {
115 password: "$2y$05$LO.vzwpWC5LZGqThvEfznu8qhb5SGqvBSWY1J3yZ4AxtMRZ3kN5jC", # badmin
116 },
117 "test": {
118 password: "$2y$05$WuwBasGDAgr.QCbGIjKJaep4dhxeai9gNZdmBnQXqpKly57oNutya", # 123
119 },
120 },
121 acl: [
122 {
123 match: {account: "admin"},
124 actions: ["*"],
125 comment: "Admin has full access to everything.",
126 },
127 {
128 match: {account: "user"},
129 actions: ["pull"],
130 comment: "User \"user\" can pull stuff.",
131 },
132 ],
133 }),
134 }
135 },
136
137 authDeployment: kube.Deployment("auth") {
138 metadata+: app.metadata("auth"),
139 spec+: {
140 replicas: 1,
141 template+: {
142 spec+: {
143 volumes_: {
144 config: kube.ConfigMapVolume(app.authConfig),
145 certs: {
146 secret: { secretName: app.authCertificate.spec.secretName },
147 },
148 },
149 containers_: {
150 auth: kube.Container("auth") {
151 image: "cesanta/docker_auth:1",
152 volumeMounts_: {
153 config: { mountPath: "/config" },
154 certs: { mountPath: "/certs" },
155 },
156 },
157 },
158 },
159 },
160 },
161 },
162 authService: kube.Service("auth") {
163 metadata+: app.metadata("auth"),
164 target_pod:: app.authDeployment.spec.template,
165 spec+: {
166 type: "ClusterIP",
167 ports: [
168 { name: "auth", port: 5001, targetPort: 5001, protocol: "TCP" },
169 ],
170 }
171 },
172 registryDeployment: kube.Deployment("docker-registry") {
173 metadata+: app.metadata("docker-registry"),
174 spec+: {
175 replicas: 1,
176 template+: {
177 spec+: {
178 volumes_: {
179 config: kube.ConfigMapVolume(app.registryConfig),
180 certs: {
181 secret: { secretName: app.registryCertificate.spec.secretName },
182 },
183 authcerts: {
184 secret: { secretName: app.authCertificate.spec.secretName },
185 },
186 },
187 containers_: {
188 registry: kube.Container("docker-registry") {
189 image: "registry:2",
190 args: ["/config/config.yml"],
191 volumeMounts_: {
192 config: { mountPath: "/config" },
193 certs: { mountPath: "/certs" },
194 authcerts: { mountPath: "/authcerts" },
195 },
196 },
197 },
198 },
199 },
200 },
201 },
202 registryService: kube.Service("docker-registry") {
203 metadata+: app.metadata("docker-registry"),
204 target_pod:: app.registryDeployment.spec.template,
205 spec+: {
206 type: "ClusterIP",
207 ports: [
208 { name: "registry", port: 5000, targetPort: 5000, protocol: "TCP" },
209 ],
210 }
211 },
212 registryIngress: kube.Ingress("registry") {
213 metadata+: app.metadata("registry") {
214 annotations+: {
215 "kubernetes.io/tls-acme": "true",
216 "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
217 "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS",
218 },
219 },
220 spec+: {
221 tls: [
222 {
223 hosts: ["registry.%s" % [cfg.domain]],
224 secretName: "registry-tls",
225 },
226 ],
227 rules: [
228 {
229 host: "registry.%s" % [cfg.domain],
230 http: {
231 paths: [
232 { path: "/auth", backend: app.authService.name_port },
233 { path: "/", backend: app.registryService.name_port },
234 ]
235 },
236 }
237 ],
238 },
239 },
240}