Skip to content

Commit 3720c57

Browse files
committedNov 2, 2021
Test: More tests
1 parent d0ff095 commit 3720c57

12 files changed

+379
-40
lines changed
 

‎Makefile

+20-12
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,28 @@ all:
55

66
.PHONY: test
77
test:
8-
helm -n com-linktohack-redmine template redmine . -f docker-compose-redmine.yaml -f docker-compose-redmine-override.yaml \
8+
# redmine kitchen sink
9+
helm -n com-linktohack-redmine template redmine . -f test/docker-compose-redmine.yaml -f test/docker-compose-redmine-override.yaml \
910
--set services.db.expose={3306:3306} \
1011
--set services.db.ports={3306:3306} \
1112
--set services.db.deploy.placement.constraints={node.role==manager} \
1213
--set services.redmine.deploy.placement.constraints={node.role==manager} \
13-
--set chdir=/stack | yq -sy 'sort_by(.kind, .metadata.name) | .[]' > stack2.yaml
14-
cmp stack1.yaml stack2.yaml
14+
--set chdir=/stack | yq -sy 'sort_by(.kind, .metadata.name) | .[]' > test/docker-compose-redmine.spec2.yaml
15+
diff -u test/docker-compose-redmine.spec.yaml test/docker-compose-redmine.spec2.yaml
1516

16-
.PHONY: diff
17-
diff:
18-
helm -n com-linktohack-redmine template redmine . -f docker-compose-redmine.yaml -f docker-compose-redmine-override.yaml \
19-
--set services.db.expose={3306:3306} \
20-
--set services.db.ports={3306:3306} \
21-
--set services.db.deploy.placement.constraints={node.role==manager} \
22-
--set services.redmine.deploy.placement.constraints={node.role==manager} \
23-
--set chdir=/stack | yq -sy 'sort_by(.kind, .metadata.name) | .[]' > stack2.yaml
24-
diff -u stack1.yaml stack2.yaml
17+
# dockersamples
18+
helm -n com-linktohack-dockersamples template dockersamples . -f test/docker-compose-dockersamples.yaml \
19+
| yq -sy 'sort_by(.kind, .metadata.name) | .[]' > test/docker-compose-dockersamples.spec2.yaml
20+
diff -u test/docker-compose-dockersamples.spec.yaml test/docker-compose-dockersamples.spec2.yaml
21+
22+
# kubernetes dashboard
23+
helm -n com-linktohack-kubernetes-dashboard template kubernetes-dashboard . -f test/docker-compose-kubernetes-dashboard.yaml \
24+
| yq -sy 'sort_by(.kind, .metadata.name) | .[]' > test/docker-compose-kubernetes-dashboard.spec2.yaml
25+
diff -u test/docker-compose-kubernetes-dashboard.spec.yaml test/docker-compose-kubernetes-dashboard.spec2.yaml
26+
27+
# traefik
28+
helm -n com-linktohack-traefik template traefik . \
29+
-f test/docker-compose-traefik.yaml \
30+
-f test/docker-compose-traefik-override.yaml \
31+
| yq -sy 'sort_by(.kind, .metadata.name) | .[]' > test/docker-compose-traefik.spec2.yaml
32+
diff -u test/docker-compose-traefik.spec.yaml test/docker-compose-traefik.spec2.yaml

‎README.md

+28-28
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ helm -n your-stack upgrade --install your-stack link/stack -f docker-compose.yam
1414
While the inter-container communication is enabled in `swarm` either by `network` or `link`, in `k8s` if you have more than one service and they need to communicate together, you will need to expose the ports explicitly by `--set services.XXX.expose={YYYY}`
1515

1616
# Features (complete)
17-
The chart is quite features complete and I was able to deploy complex stacks with it including `traefik` and `kubernetes-dashboard`. In all cases, there is a mechanism to override the generated manifests with full possibilities of `k8s` API (see below.)
17+
The chart is features complete and I was able to deploy complex stacks with it including `traefik` and `kubernetes-dashboard`. In all cases, there is a mechanism to override the generated manifests with full possibilities of `k8s` API (see below.)
1818

19-
Acceptable configurations can be found in the [test](./docker-compose-redmine.yaml):.
19+
Acceptable configurations can be found in the [test](./test/docker-compose-redmine.yaml):.
2020

2121
- [X] Deployment:
2222
- Default to `Deployment`
@@ -31,31 +31,30 @@ Acceptable configurations can be found in the [test](./docker-compose-redmine.ya
3131
- [X] Resources:
3232
- `deploy.resources.reservations` map to `request` and
3333
- `deploy.resources.limits` map to `limit` (accept both `cpus` and `cpu` keys)
34-
- [X] Toleration: via extra key `deploy.placement.tolerations` with `kubectl taint` syntax
35-
- [X] Resources: `deploy.resource.reservations` map to `request` and `deploy.resource.limits` map to `limit` (accept both `cpus` and `cpu`!)
34+
- [X] Toleration: via [extra key](#extra-keys) `deploy.placement.tolerations` with `kubectl taint` syntax
3635
- [X] Service:
3736
- `ports` expose `LoadBlancer` by default
3837
- `expose` exposes `ClusterIP` services
3938
- `nodePorts` expose `NodePort` services
4039
- [X] Ingress
41-
- Support `traefik` (1.7) labels (`deploy.labels`) as input with annotations including basic auth
42-
- Support `CertManager` `Issuer` and `ClusterIssuer` via extra labels `traefik.issuer` and `traefik.cluster-issuer`
40+
- Support `traefik` (1.7) labels (`deploy.labels`) as input with annotations support, including basic auth, `PathPrefixStrip`, `customRequestHeaders`, `customResponseHeaders`...
41+
- Support `CertManager`'s `Issuer` and `ClusterIssuer` via extra labels `traefik.issuer` and `traefik.cluster-issuer`
4342
- Support `Ingress` class via extra label `traefik.ingress-class`
4443
- Support `segment` labels for services that expose multiple ports `traefik.port`, `traefik.first.port`, `traefik.second.port`...
45-
- Advanced features (`PathPrefixStrip`, custom headers...) will set the Ingress class to `traefik`, but again it can be overwritten.
46-
- [X] Volume: Handle inline/top-level volumes/external volumes
44+
- [X] Volume: Support inline/top-level volumes/external volumes
45+
- Support both short and long syntax
4746
- Automatic switch to `volumeClaimTemplates` for `StatefulSet` (really useful if combine with cloud provider's dynamic provisioner).
48-
- Dynamic provisioner should work as expected `volumes.XXX.driver_opts.type` maps directly to `storageClassName` including treatments for
47+
- Dynamic provisioner should work as expected. `volumes.XXX.driver_opts.type` maps directly to `storageClassName` including treatments for:
4948
- `none` (default storage class)
5049
- `nfs`
5150
- `emptyDir`
52-
- Support `none` (map to `hostPath` if `volumes.XXX.driver_opts.device` presents) and `nfs` (support `addr` in `volumes.XXX.driver_opts.o`, `volumes.XXX.driver_opts.device`) static provisioner.
53-
- Support `readOnly` attribute (`volume:/path:ro`)
54-
- [X] Config: Handle top-level configs/external configs
51+
- Support `none` (map to `hostPath` if `volumes.XXX.driver_opts.device` presents) and `nfs` (if `addr` presents in `volumes.XXX.driver_opts.o` and `volumes.XXX.driver_opts.device` prensents) static provisioner.
52+
- Support `readOnly` attribute (`volume:/path:ro` style)
53+
- [X] Config: Support top-level configs/external configs
5554
- Support both short and long syntax
5655
- Data can be integrated directly via `data` external key
5756
- Support mouting as directory by setting `file` to null. See [Advance: full override](#advance-full-override) to see how to insert more than one files
58-
- [X] Secret: Handle top-level secrets/external secrets
57+
- [X] Secret: Support top-level secrets/external secrets
5958
- Support both short and long syntax
6059
- Data can be integrated directly via `data` and `stringData` external keys
6160
- Support mouting as directory by setting `file` to null. See [Advance: full override](#advance-full-override) to see how to insert more than one files
@@ -70,7 +69,7 @@ Acceptable configurations can be found in the [test](./docker-compose-redmine.ya
7069
Tested in a K3s cluster with `local-path` provisioner.
7170

7271
```sh
73-
❯ helm -n com-linktohack-docker-on-compose upgrade --install sample link/stack -f docker-compose-dockersamples.yaml
72+
❯ helm -n com-linktohack-docker-on-compose upgrade --install sample link/stack -f test/docker-compose-dockersamples.yaml
7473
Release "sample" does not exist. Installing it now.
7574
NAME: sample
7675
LAST DEPLOYED: Tue Jan 14 18:38:42 2020
@@ -158,18 +157,18 @@ services:
158157
tcp: {}
159158
upd: {}
160159
Ingress:
161-
default: {}
162-
seg: {}
160+
default: {} # default segement
161+
seg1: {} # segment seg1
163162
Auth:
164163
default: {}
165-
seg: {}
164+
seg: {} # segment seg1
166165
Deployment:
167166
spec:
168167
template:
169168
spec:
170169
containers:
171170
- name: override-name
172-
imagePullPolicy: Always
171+
imagePullPolicy: Always # supported as an extra key already
173172
DaemonSet:
174173
spec:
175174
StatefulSe:
@@ -178,26 +177,26 @@ services:
178177
spec:
179178
CronJob:
180179
spec:
181-
schedule: '*/1 * * * *'
180+
schedule: '*/1 * * * *' # mostly require
182181
volumes:
183182
db:
184183
PV:
185184
spec:
186185
capacity:
187-
storage: 10Gi
186+
storage: 10Gi # supported as an extra key already
188187
persistentVolumeReclaimPolicy: Retain
189188
PVC:
190189
spec:
191190
resources:
192191
requests:
193-
storage: 10Gi
192+
storage: 10Gi # supported as an extra key already
194193
configs:
195194
redmine_config:
196195
ConfigMap:
197196
data:
198197
hello.yaml: there
199198
secrets:
200-
tested:
199+
with_string_data:
201200
Secret:
202201
stringData: ""
203202
```
@@ -217,13 +216,14 @@ The same technique can be applied via a proper language instead of using a Helm
217216
# Contribution
218217
- More `traefik` headers
219218
- JSON schema of `docker-compose` and extra keys
219+
- More tests
220220

221221
# More examples
222222
## Redmine + MySQL
223223
This example contains almost all the possible configurations of this stack.
224224

225225
```sh
226-
helm -n com-linktohack-redmine upgrade --install redmine link/stack -f docker-compose-redmine.yaml -f docker-compose-redmine-override.yaml \
226+
helm -n com-linktohack-redmine upgrade --install redmine link/stack -f test/docker-compose-redmine.yaml -f test/docker-compose-redmine-override.yaml \
227227
--set services.db.expose={3306:3306} \
228228
--set services.db.ports={3306:3306} \
229229
--set services.db.deploy.placement.constraints={node.role==manager} \
@@ -236,26 +236,26 @@ helm -n com-linktohack-redmine upgrade --install redmine link/stack -f docker-co
236236

237237
## Traefik ingress
238238
```sh
239-
helm -n kube-system upgrade --install traefik link/stack -f docker-compose-traefik.yml -f docker-compose-traefik-override.yml
239+
helm -n kube-system upgrade --install traefik link/stack -f test/docker-compose-traefik.yml -f test/docker-compose-traefik-override.yml
240240
```
241241

242242
## Kubernetes dashboard (with basic auth and skip login)
243243
- Create `kubernetes-dashboard` service account
244244
- Bind it with `cluster-admin` role
245245

246246
```sh
247-
helm -n kubernetes-dashboard upgrade --install dashboard link/stack -f docker-compose-kubernetes-dashboard.yml
247+
helm -n kubernetes-dashboard upgrade --install dashboard link/stack -f test/docker-compose-kubernetes-dashboard.yml
248248
```
249249

250250
## Via template
251251
```sh
252-
helm -n com-linktohack-redmine template redmine link/stack -f docker-compose-redmine.yaml -f docker-compose-redmine-override.yaml \
252+
helm -n com-linktohack-redmine template redmine link/stack -f test/docker-compose-redmine.yaml -f test/docker-compose-redmine-override.yaml \
253253
--set services.db.expose={3306:3306} \
254254
--set services.db.ports={3306:3306} \
255255
--set services.db.deploy.placement.constraints={node.role==manager} \
256256
--set services.redmine.deploy.placement.constraints={node.role==manager} \
257-
--set chdir=/stack --debug > stack1.yaml
258-
kubectl -n com-linktohack-redmine apply -f stack1.yaml
257+
--set chdir=/stack --debug > test/docker-compose-redmine.manifest.yaml
258+
kubectl -n com-linktohack-redmine apply -f test/docker-compose-redmine.manifest.yaml
259259
```
260260

261261
# Changelog
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: db
5+
spec:
6+
selector:
7+
matchLabels:
8+
service: db
9+
template:
10+
metadata:
11+
labels:
12+
service: db
13+
spec:
14+
containers:
15+
- image: dockersamples/k8s-wordsmith-db
16+
name: db
17+
---
18+
apiVersion: apps/v1
19+
kind: Deployment
20+
metadata:
21+
name: web
22+
spec:
23+
selector:
24+
matchLabels:
25+
service: web
26+
template:
27+
metadata:
28+
labels:
29+
service: web
30+
spec:
31+
containers:
32+
- image: dockersamples/k8s-wordsmith-web
33+
name: web
34+
---
35+
apiVersion: apps/v1
36+
kind: Deployment
37+
metadata:
38+
name: words
39+
spec:
40+
replicas: 5
41+
selector:
42+
matchLabels:
43+
service: words
44+
template:
45+
metadata:
46+
labels:
47+
service: words
48+
spec:
49+
containers:
50+
- image: dockersamples/k8s-wordsmith-api
51+
name: words
52+
---
53+
apiVersion: v1
54+
kind: Service
55+
metadata:
56+
name: web-loadbalancer-tcp
57+
spec:
58+
ports:
59+
- name: tcp-33000
60+
port: 33000
61+
protocol: TCP
62+
targetPort: 80
63+
selector:
64+
service: web
65+
type: LoadBalancer
File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: kubernetes-dashboard-settings
5+
---
6+
apiVersion: apps/v1
7+
kind: Deployment
8+
metadata:
9+
name: dashboard-metrics-scraper
10+
spec:
11+
selector:
12+
matchLabels:
13+
service: dashboard-metrics-scraper
14+
template:
15+
metadata:
16+
labels:
17+
service: dashboard-metrics-scraper
18+
spec:
19+
containers:
20+
- image: kubernetesui/metrics-scraper:v1.0.1
21+
name: dashboard-metrics-scraper
22+
volumeMounts:
23+
- mountPath: /tmp
24+
name: tmp-volume2
25+
serviceAccountName: kubernetes-dashboard
26+
volumes:
27+
- emptyDir: {}
28+
name: tmp-volume2
29+
---
30+
apiVersion: apps/v1
31+
kind: Deployment
32+
metadata:
33+
name: kubernetes-dashboard
34+
spec:
35+
selector:
36+
matchLabels:
37+
service: kubernetes-dashboard
38+
template:
39+
metadata:
40+
labels:
41+
service: kubernetes-dashboard
42+
spec:
43+
containers:
44+
- args:
45+
- --auto-generate-certificates
46+
- --namespace=kubernetes-dashboard
47+
- --enable-skip-login
48+
image: kubernetesui/dashboard:v2.0.0-beta8
49+
imagePullPolicy: Always
50+
name: kubernetes-dashboard
51+
volumeMounts:
52+
- mountPath: /tmp
53+
name: tmp-volume1
54+
- mountPath: /certs
55+
name: kubernetes-dashboard-certs
56+
serviceAccountName: kubernetes-dashboard
57+
volumes:
58+
- name: kubernetes-dashboard-certs
59+
secret:
60+
secretName: kubernetes-dashboard-certs
61+
- emptyDir: {}
62+
name: tmp-volume1
63+
---
64+
apiVersion: extensions/v1beta1
65+
kind: Ingress
66+
metadata:
67+
annotations:
68+
ingress.kubernetes.io/auth-realm: traefik
69+
ingress.kubernetes.io/auth-remove-header: 'true'
70+
ingress.kubernetes.io/auth-secret: kubernetes-dashboard-default-basic-auth
71+
ingress.kubernetes.io/auth-type: basic
72+
ingress.kubernetes.io/protocol: https
73+
name: kubernetes-dashboard-default
74+
spec:
75+
rules:
76+
- host: REDACTED
77+
http:
78+
paths:
79+
- backend:
80+
serviceName: kubernetes-dashboard
81+
servicePort: tcp-8443
82+
path: /
83+
---
84+
apiVersion: v1
85+
kind: Secret
86+
metadata:
87+
name: kubernetes-dashboard-certs
88+
type: Opaque
89+
---
90+
apiVersion: v1
91+
kind: Secret
92+
metadata:
93+
name: kubernetes-dashboard-csrf
94+
type: Opaque
95+
---
96+
apiVersion: v1
97+
data:
98+
auth: UkVEQUNURUQ=
99+
kind: Secret
100+
metadata:
101+
name: kubernetes-dashboard-default-basic-auth
102+
type: Opaque
103+
---
104+
apiVersion: v1
105+
kind: Service
106+
metadata:
107+
name: dashboard-metrics-scraper
108+
spec:
109+
ports:
110+
- name: tcp-8000
111+
port: 8000
112+
protocol: TCP
113+
targetPort: 8000
114+
selector:
115+
service: dashboard-metrics-scraper
116+
type: ClusterIP
117+
---
118+
apiVersion: v1
119+
kind: Service
120+
metadata:
121+
name: kubernetes-dashboard
122+
spec:
123+
ports:
124+
- name: tcp-8443
125+
port: 8443
126+
protocol: TCP
127+
targetPort: 8443
128+
selector:
129+
service: kubernetes-dashboard
130+
type: ClusterIP
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

‎test/docker-compose-traefik.spec.yaml

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
apiVersion: v1
2+
data:
3+
rules.toml: ''
4+
kind: ConfigMap
5+
metadata:
6+
name: rules-toml
7+
---
8+
apiVersion: v1
9+
data:
10+
traefik.toml: "debug = true\nlogLevel = \"DEBUG\"\ninsecureSkipVerify = true\ndefaultEntryPoints\
11+
\ = [\"http\", \"https\"]\n\n[entryPoints]\n [entryPoints.http]\n address =\
12+
\ \":80\"\n [entryPoints.http.redirect]\n entryPoint = \"https\"\n [entryPoints.https]\n\
13+
\ address = \":443\"\n [entryPoints.https.tls]\n\n[web]\n[web.auth.basic]\n\
14+
users = [\"REDACTED.\"]\n\n[docker]\n endpoint = \"unix:///var/run/docker.sock\"\
15+
\n domain = \"docker.localhost\"\n watch = true\n exposedByDefault = true\n\
16+
\ swarmMode = true\n network = \"web\"\n\n[kubernetes]\n\n[file]\n filename\
17+
\ = \"rules.toml\"\n watch = true\n\n[acme]\n email = \"REDACTED\"\n storage\
18+
\ = \"acme.json\"\n entryPoint = \"https\"\n onHostRule = true\n [acme.httpChallenge]\n\
19+
\ entryPoint = \"http\""
20+
kind: ConfigMap
21+
metadata:
22+
name: traefik-toml
23+
---
24+
apiVersion: apps/v1
25+
kind: Deployment
26+
metadata:
27+
name: traefik
28+
spec:
29+
selector:
30+
matchLabels:
31+
service: traefik
32+
template:
33+
metadata:
34+
labels:
35+
service: traefik
36+
spec:
37+
affinity:
38+
nodeAffinity:
39+
requiredDuringSchedulingIgnoredDuringExecution:
40+
nodeSelectorTerms:
41+
- matchExpressions:
42+
- key: node-role.kubernetes.io/master
43+
operator: In
44+
values:
45+
- 'true'
46+
containers:
47+
- image: traefik:1.7
48+
name: traefik
49+
volumeMounts:
50+
- mountPath: /var/run/docker.sock
51+
name: volume-0
52+
- mountPath: /acme.json
53+
name: volume-1
54+
- mountPath: /traefik.toml
55+
name: traefik-toml
56+
subPath: traefik.toml
57+
- mountPath: /rules.toml
58+
name: rules-toml
59+
subPath: rules.toml
60+
serviceAccountName: admin-user
61+
terminationGracePeriodSeconds: 60
62+
volumes:
63+
- configMap:
64+
name: rules-toml
65+
name: rules-toml
66+
- configMap:
67+
name: traefik-toml
68+
name: traefik-toml
69+
- hostPath:
70+
path: /var/run/docker.sock
71+
name: volume-0
72+
- hostPath:
73+
path: /path/to/traefik/acme.json
74+
name: volume-1
75+
---
76+
apiVersion: extensions/v1beta1
77+
kind: Ingress
78+
metadata:
79+
annotations:
80+
ingress.kubernetes.io/auth-realm: traefik
81+
ingress.kubernetes.io/auth-secret: traefik-default-basic-auth
82+
ingress.kubernetes.io/auth-type: basic
83+
name: traefik-default
84+
spec:
85+
rules:
86+
- host: REDACTED
87+
http:
88+
paths:
89+
- backend:
90+
serviceName: traefik
91+
servicePort: tcp-8080
92+
path: /
93+
---
94+
apiVersion: v1
95+
data:
96+
auth: UkVEQUNURUQ=
97+
kind: Secret
98+
metadata:
99+
name: traefik-default-basic-auth
100+
type: Opaque
101+
---
102+
apiVersion: v1
103+
kind: Service
104+
metadata:
105+
name: traefik
106+
spec:
107+
ports:
108+
- name: tcp-8080
109+
port: 8080
110+
protocol: TCP
111+
targetPort: 8080
112+
selector:
113+
service: traefik
114+
type: ClusterIP
115+
---
116+
apiVersion: v1
117+
kind: Service
118+
metadata:
119+
name: traefik-loadbalancer-tcp
120+
spec:
121+
ports:
122+
- name: tcp-80
123+
port: 80
124+
protocol: TCP
125+
targetPort: 80
126+
- name: tcp-443
127+
port: 443
128+
protocol: TCP
129+
targetPort: 443
130+
- name: tcp-8080
131+
port: 8080
132+
protocol: TCP
133+
targetPort: 8080
134+
selector:
135+
service: traefik
136+
type: LoadBalancer
File renamed without changes.

0 commit comments

Comments
 (0)
Please sign in to comment.