@bluedynamics/cdk8s-plone 0.1.43 → 0.1.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +25 -24
- package/API.md +6 -2
- package/README.md +3 -3
- package/documentation/sources/conf.py +55 -29
- package/documentation/sources/explanation/architecture.md +14 -16
- package/documentation/sources/explanation/cdk8s-workflow.md +66 -0
- package/documentation/sources/explanation/index.md +1 -27
- package/documentation/sources/how-to/backup-and-restore.md +107 -0
- package/documentation/sources/how-to/configure-env-and-secrets.md +184 -0
- package/documentation/sources/how-to/configure-ingress-tls.md +108 -0
- package/documentation/sources/how-to/configure-security-context.md +0 -5
- package/documentation/sources/how-to/deploy-blicca.md +8 -8
- package/documentation/sources/how-to/{deploy-production-volto.md → deploy-volto.md} +20 -25
- package/documentation/sources/how-to/deploy-with-httpcache.md +224 -0
- package/documentation/sources/how-to/deploy-with-vinyl-cache.md +0 -5
- package/documentation/sources/how-to/enable-prometheus-monitoring.md +4 -5
- package/documentation/sources/how-to/index.md +15 -8
- package/documentation/sources/how-to/scale-and-high-availability.md +122 -0
- package/documentation/sources/how-to/schedule-pods.md +0 -5
- package/documentation/sources/how-to/troubleshooting.md +113 -0
- package/documentation/sources/how-to/upgrade-and-rollout.md +89 -0
- package/documentation/sources/index.md +3 -11
- package/documentation/sources/reference/api/index.md +6 -4
- package/documentation/sources/reference/configuration-options.md +85 -516
- package/documentation/sources/reference/index.md +16 -43
- package/documentation/sources/tutorials/01-quick-start.md +1 -1
- package/documentation/sources/tutorials/index.md +7 -11
- package/examples/blicca/.env.example +3 -2
- package/examples/blicca/README.md +21 -24
- package/examples/blicca/__snapshots__/main.test.ts.snap +138 -345
- package/examples/blicca/main.test.ts +7 -0
- package/examples/blicca/main.ts +8 -7
- package/examples/blicca/postgres.plain.ts +115 -0
- package/examples/blicca/tsconfig.json +33 -0
- package/examples/{production-volto → volto}/.env.example +3 -2
- package/examples/{production-volto → volto}/README.md +20 -23
- package/examples/{production-volto → volto}/__snapshots__/main.test.ts.snap +139 -345
- package/examples/{production-volto → volto}/main.test.ts +7 -0
- package/examples/{production-volto → volto}/main.ts +8 -7
- package/examples/{production-volto → volto}/package.json +1 -1
- package/examples/volto/postgres.plain.ts +115 -0
- package/examples/volto/tsconfig.json +33 -0
- package/lib/httpcache.js +1 -1
- package/lib/imports/vinyl.bluedynamics.eu.d.ts +4011 -53
- package/lib/imports/vinyl.bluedynamics.eu.js +1786 -157
- package/lib/plone.js +1 -1
- package/lib/vinylcache.d.ts +3 -1
- package/lib/vinylcache.js +3 -2
- package/package.json +6 -6
- package/documentation/sources/_static/brand-theme.css +0 -685
- package/documentation/sources/_static/custom-icons.css +0 -123
- package/documentation/sources/_static/fonts/hack/Hack-Regular.woff2 +0 -0
- package/documentation/sources/_static/fonts/orbitron/Orbitron-Black.woff2 +0 -11
- package/documentation/sources/_static/fonts/orbitron/Orbitron-Bold.woff2 +0 -11
- package/documentation/sources/_static/fonts/orbitron/Orbitron-Regular.woff2 +0 -0
- package/documentation/sources/_static/fonts/rajdhani/Rajdhani-Bold.woff2 +0 -11
- package/documentation/sources/_static/fonts/rajdhani/Rajdhani-Medium.woff2 +0 -11
- package/documentation/sources/_static/fonts/rajdhani/Rajdhani-Regular.woff2 +0 -11
- package/documentation/sources/_static/fonts/rajdhani/Rajdhani-SemiBold.woff2 +0 -11
- package/documentation/sources/_static/kup6s-icon-explanation.svg +0 -32
- package/documentation/sources/_static/kup6s-icon-howto.svg +0 -34
- package/documentation/sources/_static/kup6s-icon-reference.svg +0 -34
- package/documentation/sources/_static/kup6s-icon-tutorials.svg +0 -30
- package/documentation/sources/_static/logo-fix.js +0 -12
- package/documentation/sources/reference/api/.gitkeep +0 -1
- package/examples/blicca/postgres.bitnami.ts +0 -49
- package/examples/production-volto/postgres.bitnami.ts +0 -49
- /package/documentation/sources/_static/{kup6s-icon-plone.svg → logo.svg} +0 -0
- /package/examples/{production-volto → volto}/cdk8s.yaml +0 -0
- /package/examples/{production-volto → volto}/config/varnish.tpl.vcl +0 -0
- /package/examples/{production-volto → volto}/ingress.ts +0 -0
- /package/examples/{production-volto → volto}/jest.config.js +0 -0
- /package/examples/{production-volto → volto}/postgres.cloudnativepg.ts +0 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
---
|
|
2
|
+
myst:
|
|
3
|
+
html_meta:
|
|
4
|
+
"description": "Deploy the PloneHttpcache Varnish cache via the mittwald kube-httpcache Helm chart and attach it to a Plone deployment."
|
|
5
|
+
"property=og:description": "Deploy the PloneHttpcache Varnish cache via the mittwald kube-httpcache Helm chart and attach it to a Plone deployment."
|
|
6
|
+
"property=og:title": "Deploy with PloneHttpcache"
|
|
7
|
+
"keywords": "Plone, cdk8s, Kubernetes, Varnish, kube-httpcache, mittwald, PloneHttpcache, caching, VCL"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Deploy with PloneHttpcache
|
|
11
|
+
|
|
12
|
+
This guide shows you how to deploy the `PloneHttpcache` Varnish cache and attach it to an existing Plone instance.
|
|
13
|
+
|
|
14
|
+
`PloneHttpcache` deploys Varnish through the [mittwald kube-httpcache](https://github.com/mittwald/kube-httpcache) Helm chart.
|
|
15
|
+
The construct renders that chart at synth time, so the cache is part of your own manifests.
|
|
16
|
+
For an operator-managed alternative, see {doc}`/how-to/deploy-with-vinyl-cache`.
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- A running Plone deployment created with `cdk8s-plone` (see {doc}`/tutorials/01-quick-start`).
|
|
21
|
+
- The `helm` CLI available wherever you run `cdk8s synth`.
|
|
22
|
+
- A Kubernetes `Secret` holding the Varnish admin credentials, referenced through `existingSecret`.
|
|
23
|
+
- amd64 worker nodes.
|
|
24
|
+
|
|
25
|
+
The construct renders the kube-httpcache Helm chart locally, so you do not pre-install a controller in the cluster.
|
|
26
|
+
The pod `nodeSelector` is hard-coded to `kubernetes.io/arch=amd64` (a kube-httpcache workaround), so `PloneHttpcache` pods only schedule on amd64 nodes.
|
|
27
|
+
There is no `nodeSelector` option on this construct.
|
|
28
|
+
|
|
29
|
+
Create the admin credentials Secret before you deploy:
|
|
30
|
+
|
|
31
|
+
```shell
|
|
32
|
+
kubectl create secret generic varnish-admin \
|
|
33
|
+
--namespace <namespace> \
|
|
34
|
+
--from-literal=secret="$(head -c32 /dev/urandom | base64)"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Attach a basic PloneHttpcache
|
|
38
|
+
|
|
39
|
+
Construct `PloneHttpcache` with a `plone` reference, the `existingSecret`, and a `replicas` count.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { Plone, PloneHttpcache } from '@bluedynamics/cdk8s-plone';
|
|
43
|
+
|
|
44
|
+
const plone = new Plone(chart, 'plone', {
|
|
45
|
+
backend: { image: 'plone/plone-backend:6.1.3' },
|
|
46
|
+
frontend: { image: 'plone/plone-frontend:16.0.0' },
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
new PloneHttpcache(chart, 'cache', {
|
|
50
|
+
plone: plone,
|
|
51
|
+
existingSecret: 'varnish-admin',
|
|
52
|
+
replicas: 2,
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
RBAC for the rendered controller is always enabled; there is nothing to configure.
|
|
57
|
+
|
|
58
|
+
## Set resources
|
|
59
|
+
|
|
60
|
+
Tune the CPU and memory requests and limits to match your workload.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
new PloneHttpcache(chart, 'cache', {
|
|
64
|
+
plone: plone,
|
|
65
|
+
existingSecret: 'varnish-admin',
|
|
66
|
+
requestCpu: '200m',
|
|
67
|
+
limitCpu: '1',
|
|
68
|
+
requestMemory: '256Mi',
|
|
69
|
+
limitMemory: '1Gi',
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The defaults are `requestCpu: '100m'`, `limitCpu: '500m'`, `requestMemory: '100Mi'`, and `limitMemory: '500Mi'`.
|
|
74
|
+
|
|
75
|
+
## Customize the VCL
|
|
76
|
+
|
|
77
|
+
Provide an inline VCL through `varnishVcl`, which takes precedence over `varnishVclFile`.
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
new PloneHttpcache(chart, 'cache', {
|
|
81
|
+
plone: plone,
|
|
82
|
+
existingSecret: 'varnish-admin',
|
|
83
|
+
varnishVcl: `
|
|
84
|
+
vcl 4.1;
|
|
85
|
+
backend default {
|
|
86
|
+
.host = "{{ .Env.BACKEND_SERVICE_NAME }}";
|
|
87
|
+
.port = "{{ .Env.BACKEND_SERVICE_PORT }}";
|
|
88
|
+
}
|
|
89
|
+
`,
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Alternatively, point `varnishVclFile` at a VCL template file on disk; the construct reads it at synth time.
|
|
94
|
+
When you set neither option, the construct uses the built-in `config/varnish.tpl.vcl`.
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
new PloneHttpcache(chart, 'cache', {
|
|
98
|
+
plone: plone,
|
|
99
|
+
existingSecret: 'varnish-admin',
|
|
100
|
+
varnishVclFile: './config/varnish.tpl.vcl',
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
VCL templates use Go template syntax.
|
|
105
|
+
The construct supplies these environment variables: `BACKEND_SERVICE_NAME`, `BACKEND_SERVICE_PORT`, `BACKEND_SITE_ID`, `FRONTEND_SERVICE_NAME`, and `FRONTEND_SERVICE_PORT`.
|
|
106
|
+
Reference them as `{{ .Env.NAME }}`.
|
|
107
|
+
|
|
108
|
+
Add your own variables through `extraEnvVars`, which are appended to the built-in set.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
new PloneHttpcache(chart, 'cache', {
|
|
112
|
+
plone: plone,
|
|
113
|
+
existingSecret: 'varnish-admin',
|
|
114
|
+
extraEnvVars: [
|
|
115
|
+
{ name: 'THUMBOR_SERVICE_NAME', value: 'my-thumbor' },
|
|
116
|
+
],
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Reference an extra variable in your VCL template as `{{ .Env.THUMBOR_SERVICE_NAME }}`.
|
|
121
|
+
|
|
122
|
+
## Schedule the cache pods
|
|
123
|
+
|
|
124
|
+
Add `tolerations` so the cache pods can run on tainted nodes.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
new PloneHttpcache(chart, 'cache', {
|
|
128
|
+
plone: plone,
|
|
129
|
+
existingSecret: 'varnish-admin',
|
|
130
|
+
tolerations: [
|
|
131
|
+
{ key: 'dedicated', operator: 'Equal', value: 'cache', effect: 'NoSchedule' },
|
|
132
|
+
],
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Omit `effect` to tolerate every taint for the given key.
|
|
137
|
+
`operator` defaults to `'Equal'`.
|
|
138
|
+
|
|
139
|
+
## Enable monitoring
|
|
140
|
+
|
|
141
|
+
Set `servicemonitor` to emit a Prometheus `ServiceMonitor`, and keep `exporterEnabled` so the Varnish exporter sidecar is present for it to scrape.
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
new PloneHttpcache(chart, 'cache', {
|
|
145
|
+
plone: plone,
|
|
146
|
+
existingSecret: 'varnish-admin',
|
|
147
|
+
servicemonitor: true,
|
|
148
|
+
exporterEnabled: true,
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`exporterEnabled` defaults to `true`, and `servicemonitor` defaults to `false`.
|
|
153
|
+
Use `servicemonitor` here; there is no `monitoring` option on this construct.
|
|
154
|
+
For the full monitoring setup, see {doc}`/how-to/enable-prometheus-monitoring`.
|
|
155
|
+
|
|
156
|
+
## Pin the chart and image versions
|
|
157
|
+
|
|
158
|
+
Set `chartVersion` to pin the kube-httpcache Helm chart, and `appVersion` to pin the image tag.
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
new PloneHttpcache(chart, 'cache', {
|
|
162
|
+
plone: plone,
|
|
163
|
+
existingSecret: 'varnish-admin',
|
|
164
|
+
chartVersion: '0.13.1',
|
|
165
|
+
appVersion: '0.13.1',
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`chartVersion` defaults to the latest chart, and `appVersion` defaults to `chartVersion`.
|
|
170
|
+
|
|
171
|
+
## Point your ingress at the cache
|
|
172
|
+
|
|
173
|
+
Route external traffic through the cache by using the read-only `httpcacheServiceName` output as your Ingress or IngressRoute upstream instead of the Plone frontend service.
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
const cache = new PloneHttpcache(chart, 'cache', {
|
|
177
|
+
plone: plone,
|
|
178
|
+
existingSecret: 'varnish-admin',
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const upstream = cache.httpcacheServiceName;
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
For the routing and TLS details, see {doc}`/how-to/configure-ingress-tls`.
|
|
185
|
+
|
|
186
|
+
## Verify the cache
|
|
187
|
+
|
|
188
|
+
Generate the manifests and confirm the cache resources are present.
|
|
189
|
+
|
|
190
|
+
```shell
|
|
191
|
+
cdk8s synth
|
|
192
|
+
grep -l 'kube-httpcache' dist/*.yaml
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Apply the manifests and inspect the rollout on the cluster.
|
|
196
|
+
|
|
197
|
+
```shell
|
|
198
|
+
kubectl apply -f dist/
|
|
199
|
+
kubectl get pods -n <namespace>
|
|
200
|
+
kubectl get service -n <namespace>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Send a request through the cache service and check the Varnish response headers.
|
|
204
|
+
|
|
205
|
+
```shell
|
|
206
|
+
kubectl run -it --rm curl --image=curlimages/curl --restart=Never -- \
|
|
207
|
+
curl -sI http://<httpcacheServiceName>.<namespace>:80/
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
A cached response carries an `X-Varnish` header, and an `Age` header greater than zero confirms a cache hit.
|
|
211
|
+
|
|
212
|
+
## PloneHttpcache compared with PloneVinylCache
|
|
213
|
+
|
|
214
|
+
`PloneHttpcache` runs Varnish from the mittwald kube-httpcache chart with a Secret and a VCL template that you supply.
|
|
215
|
+
`PloneVinylCache` runs Varnish through the cloud-vinyl operator, which generates VCL from structured configuration and manages credentials for you.
|
|
216
|
+
For the trade-offs between the two, see {doc}`/explanation/architecture` and {doc}`/how-to/deploy-with-vinyl-cache`.
|
|
217
|
+
|
|
218
|
+
## See also
|
|
219
|
+
|
|
220
|
+
- {doc}`/reference/api/index` — authoritative `PloneHttpcache` and `PloneHttpcacheOptions` reference.
|
|
221
|
+
- {doc}`/reference/configuration-options` — guide to `varnishVcl`, `existingSecret`, `extraEnvVars`, and `servicemonitor`.
|
|
222
|
+
- {doc}`/how-to/enable-prometheus-monitoring` — scrape the Varnish cache with Prometheus.
|
|
223
|
+
- {doc}`/how-to/deploy-with-vinyl-cache` — operator-managed Varnish caching alternative.
|
|
224
|
+
- [mittwald kube-httpcache](https://github.com/mittwald/kube-httpcache) — upstream controller and Helm chart.
|
|
@@ -7,11 +7,6 @@ myst:
|
|
|
7
7
|
"keywords": "Plone, cdk8s, Kubernetes, Varnish, cloud-vinyl, VinylCache, operator, caching"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
```{image} ../_static/kup6s-icon-howto.svg
|
|
11
|
-
:align: center
|
|
12
|
-
:class: section-icon-large
|
|
13
|
-
```
|
|
14
|
-
|
|
15
10
|
# Deploy with cloud-vinyl cache
|
|
16
11
|
|
|
17
12
|
<div class="page-metadata">
|
|
@@ -7,11 +7,6 @@ myst:
|
|
|
7
7
|
"keywords": "Plone, cdk8s, Kubernetes, Prometheus, ServiceMonitor, monitoring, metrics"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
```{image} ../_static/kup6s-icon-howto.svg
|
|
11
|
-
:align: center
|
|
12
|
-
:class: section-icon-large
|
|
13
|
-
```
|
|
14
|
-
|
|
15
10
|
# Enable Prometheus monitoring
|
|
16
11
|
|
|
17
12
|
<div class="page-metadata">
|
|
@@ -93,6 +88,10 @@ new PloneVinylCache(chart, 'cache', {
|
|
|
93
88
|
});
|
|
94
89
|
```
|
|
95
90
|
|
|
91
|
+
```{note}
|
|
92
|
+
The option name differs by construct: backend, frontend, and `PloneHttpcache` use `servicemonitor`, while `PloneVinylCache` uses `monitoring`. Both create a Prometheus `ServiceMonitor`.
|
|
93
|
+
```
|
|
94
|
+
|
|
96
95
|
## Verify the rollout
|
|
97
96
|
|
|
98
97
|
```shell
|
|
@@ -7,11 +7,6 @@ myst:
|
|
|
7
7
|
"keywords": "Plone, cdk8s, Kubernetes, how-to, deployment, configuration"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
```{image} ../_static/kup6s-icon-howto.svg
|
|
11
|
-
:align: center
|
|
12
|
-
:class: section-icon-large
|
|
13
|
-
```
|
|
14
|
-
|
|
15
10
|
# How-to guides
|
|
16
11
|
|
|
17
12
|
**Goal-oriented guides showing you how to solve specific problems with cdk8s-plone.**
|
|
@@ -39,8 +34,9 @@ setup-prerequisites
|
|
|
39
34
|
maxdepth: 1
|
|
40
35
|
titlesonly: true
|
|
41
36
|
---
|
|
42
|
-
deploy-
|
|
37
|
+
deploy-volto
|
|
43
38
|
deploy-blicca
|
|
39
|
+
deploy-with-httpcache
|
|
44
40
|
deploy-with-vinyl-cache
|
|
45
41
|
```
|
|
46
42
|
|
|
@@ -51,11 +47,13 @@ deploy-with-vinyl-cache
|
|
|
51
47
|
maxdepth: 1
|
|
52
48
|
titlesonly: true
|
|
53
49
|
---
|
|
50
|
+
configure-env-and-secrets
|
|
54
51
|
configure-security-context
|
|
55
52
|
schedule-pods
|
|
53
|
+
configure-ingress-tls
|
|
56
54
|
```
|
|
57
55
|
|
|
58
|
-
## Operations
|
|
56
|
+
## Operations and maintenance
|
|
59
57
|
|
|
60
58
|
```{toctree}
|
|
61
59
|
---
|
|
@@ -63,11 +61,20 @@ maxdepth: 1
|
|
|
63
61
|
titlesonly: true
|
|
64
62
|
---
|
|
65
63
|
enable-prometheus-monitoring
|
|
64
|
+
scale-and-high-availability
|
|
65
|
+
upgrade-and-rollout
|
|
66
|
+
backup-and-restore
|
|
66
67
|
```
|
|
67
68
|
|
|
68
69
|
## Troubleshooting
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
```{toctree}
|
|
72
|
+
---
|
|
73
|
+
maxdepth: 1
|
|
74
|
+
titlesonly: true
|
|
75
|
+
---
|
|
76
|
+
troubleshooting
|
|
77
|
+
```
|
|
71
78
|
|
|
72
79
|
---
|
|
73
80
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
myst:
|
|
3
|
+
html_meta:
|
|
4
|
+
"description": "Scale the Plone backend and frontend with cdk8s-plone, configure a PodDisruptionBudget, and add a HorizontalPodAutoscaler."
|
|
5
|
+
"property=og:description": "Scale the Plone backend and frontend with cdk8s-plone, configure a PodDisruptionBudget, and add a HorizontalPodAutoscaler."
|
|
6
|
+
"property=og:title": "Scale and run highly available"
|
|
7
|
+
"keywords": "Plone, cdk8s, Kubernetes, scaling, replicas, PodDisruptionBudget, HPA, high availability"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Scale and run highly available
|
|
11
|
+
|
|
12
|
+
This guide shows you how to run more than one replica of the Plone backend and frontend, protect them with a PodDisruptionBudget, and add a HorizontalPodAutoscaler.
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
- A working Plone deployment created with `cdk8s-plone`.
|
|
17
|
+
- A PostgreSQL backend reachable by every backend replica.
|
|
18
|
+
|
|
19
|
+
The backend uses RelStorage on PostgreSQL, so several backend replicas share one database and scale horizontally.
|
|
20
|
+
The Volto frontend is stateless and scales horizontally as well.
|
|
21
|
+
|
|
22
|
+
## Set the replica count
|
|
23
|
+
|
|
24
|
+
Set `replicas` on `backend` and `frontend` independently.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { Plone, PloneVariant } from '@bluedynamics/cdk8s-plone';
|
|
28
|
+
|
|
29
|
+
new Plone(chart, 'plone', {
|
|
30
|
+
variant: PloneVariant.VOLTO,
|
|
31
|
+
backend: {
|
|
32
|
+
image: 'plone/plone-backend:6.1.3',
|
|
33
|
+
replicas: 3,
|
|
34
|
+
},
|
|
35
|
+
frontend: {
|
|
36
|
+
image: 'plone/plone-frontend:16.0.0',
|
|
37
|
+
replicas: 2,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Both default to `2` replicas when you omit the option.
|
|
43
|
+
|
|
44
|
+
## Protect availability with a PodDisruptionBudget
|
|
45
|
+
|
|
46
|
+
A PodDisruptionBudget keeps a minimum number of pods running during voluntary disruptions such as node drains.
|
|
47
|
+
|
|
48
|
+
Set `minAvailable` or `maxUnavailable` on the component.
|
|
49
|
+
Each accepts an absolute number or a percentage string such as `"50%"`.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
backend: {
|
|
53
|
+
image: 'plone/plone-backend:6.1.3',
|
|
54
|
+
replicas: 5,
|
|
55
|
+
minAvailable: 3,
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`cdk8s-plone` creates the PodDisruptionBudget automatically when `replicas` is `2` or more, or when you set `minAvailable` or `maxUnavailable` explicitly.
|
|
60
|
+
A single replica with no explicit setting gets no PodDisruptionBudget.
|
|
61
|
+
The generated PodDisruptionBudget always sets `unhealthyPodEvictionPolicy: AlwaysAllow`, so unhealthy pods never block a node drain.
|
|
62
|
+
|
|
63
|
+
## Add a HorizontalPodAutoscaler
|
|
64
|
+
|
|
65
|
+
`cdk8s-plone` emits plain Deployments and does not configure autoscaling.
|
|
66
|
+
To scale on load, add your own HorizontalPodAutoscaler that targets the generated backend Deployment.
|
|
67
|
+
|
|
68
|
+
Find the Deployment name from the synthesized manifests:
|
|
69
|
+
|
|
70
|
+
```shell
|
|
71
|
+
cdk8s synth
|
|
72
|
+
grep -A2 'kind: Deployment' dist/*.yaml | grep 'name:'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Add the autoscaler as a Kubernetes manifest and apply it alongside your deployment:
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
apiVersion: autoscaling/v2
|
|
79
|
+
kind: HorizontalPodAutoscaler
|
|
80
|
+
metadata:
|
|
81
|
+
name: plone-backend
|
|
82
|
+
spec:
|
|
83
|
+
scaleTargetRef:
|
|
84
|
+
apiVersion: apps/v1
|
|
85
|
+
kind: Deployment
|
|
86
|
+
name: <backend-deployment-name>
|
|
87
|
+
minReplicas: 2
|
|
88
|
+
maxReplicas: 8
|
|
89
|
+
metrics:
|
|
90
|
+
- type: Resource
|
|
91
|
+
resource:
|
|
92
|
+
name: cpu
|
|
93
|
+
target:
|
|
94
|
+
type: Utilization
|
|
95
|
+
averageUtilization: 70
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The HorizontalPodAutoscaler needs [metrics-server](https://github.com/kubernetes-sigs/metrics-server) in the cluster.
|
|
99
|
+
Keep `minReplicas` at `2` or more so the PodDisruptionBudget stays effective.
|
|
100
|
+
|
|
101
|
+
## Verify
|
|
102
|
+
|
|
103
|
+
Confirm the PodDisruptionBudget is present in the synthesized manifests:
|
|
104
|
+
|
|
105
|
+
```shell
|
|
106
|
+
cdk8s synth
|
|
107
|
+
grep -l 'kind: PodDisruptionBudget' dist/*.yaml
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Inspect the running objects on the cluster:
|
|
111
|
+
|
|
112
|
+
```shell
|
|
113
|
+
kubectl get deploy -n <namespace>
|
|
114
|
+
kubectl get pdb -n <namespace>
|
|
115
|
+
kubectl get hpa -n <namespace>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## See also
|
|
119
|
+
|
|
120
|
+
- {doc}`/reference/api/index` — authoritative `replicas`, `minAvailable`, and `maxUnavailable` reference.
|
|
121
|
+
- {doc}`/how-to/schedule-pods` — place the extra replicas on specific nodes.
|
|
122
|
+
- {doc}`/explanation/architecture` — how the backend, frontend, and database fit together.
|
|
@@ -7,11 +7,6 @@ myst:
|
|
|
7
7
|
"keywords": "Plone, cdk8s, Kubernetes, nodeSelector, tolerations, scheduling, taints"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
```{image} ../_static/kup6s-icon-howto.svg
|
|
11
|
-
:align: center
|
|
12
|
-
:class: section-icon-large
|
|
13
|
-
```
|
|
14
|
-
|
|
15
10
|
# Schedule pods to specific nodes
|
|
16
11
|
|
|
17
12
|
<div class="page-metadata">
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
myst:
|
|
3
|
+
html_meta:
|
|
4
|
+
"description": "Diagnose and fix common cdk8s-plone problems: pods not scheduling, crashes, failing probes, database connection errors, and synth failures."
|
|
5
|
+
"property=og:description": "Diagnose and fix common cdk8s-plone problems: pods not scheduling, crashes, failing probes, database connection errors, and synth failures."
|
|
6
|
+
"property=og:title": "Troubleshoot a deployment"
|
|
7
|
+
"keywords": "Plone, cdk8s, Kubernetes, troubleshooting, CrashLoopBackOff, probes, scheduling, synth"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Troubleshoot a deployment
|
|
11
|
+
|
|
12
|
+
This guide shows you how to diagnose and fix the problems you are most likely to hit when you deploy Plone with `cdk8s-plone`.
|
|
13
|
+
|
|
14
|
+
Start by looking at the overall state, then drill into the failing object.
|
|
15
|
+
|
|
16
|
+
```shell
|
|
17
|
+
kubectl get pods -n <namespace>
|
|
18
|
+
kubectl describe pod <pod> -n <namespace>
|
|
19
|
+
kubectl logs <pod> -n <namespace>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## `cdk8s synth` fails
|
|
23
|
+
|
|
24
|
+
If `synth` fails while rendering `PloneHttpcache`, confirm the `helm` CLI is installed and on your `PATH`.
|
|
25
|
+
`PloneHttpcache` renders the kube-httpcache Helm chart at synth time and shells out to `helm`.
|
|
26
|
+
|
|
27
|
+
If `synth` fails on a missing custom resource type, run the example's import step (`npm run import`) to regenerate the CRD bindings.
|
|
28
|
+
|
|
29
|
+
## Pods stay `Pending`
|
|
30
|
+
|
|
31
|
+
Describe the pod and read the `Events` section for the scheduler's reason.
|
|
32
|
+
|
|
33
|
+
```shell
|
|
34
|
+
kubectl describe pod <pod> -n <namespace>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Common causes:
|
|
38
|
+
|
|
39
|
+
- Insufficient CPU or memory on the nodes. Lower `requestCpu` or `requestMemory`, or add capacity.
|
|
40
|
+
- A `nodeSelector` or `tolerations` setting that no node satisfies. See {doc}`/how-to/schedule-pods`.
|
|
41
|
+
- `PloneHttpcache` pods only schedule on amd64 nodes, because the construct hard-codes `kubernetes.io/arch=amd64`. Provide an amd64 node or use {doc}`/how-to/deploy-with-vinyl-cache` instead.
|
|
42
|
+
|
|
43
|
+
## A pod is in `CrashLoopBackOff`
|
|
44
|
+
|
|
45
|
+
Read the logs of the current and previous container starts.
|
|
46
|
+
|
|
47
|
+
```shell
|
|
48
|
+
kubectl logs <pod> -n <namespace>
|
|
49
|
+
kubectl logs <pod> -n <namespace> --previous
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
A backend that exits immediately almost always cannot reach its database.
|
|
53
|
+
See {ref}`backend-db-connection`.
|
|
54
|
+
|
|
55
|
+
(backend-db-connection)=
|
|
56
|
+
|
|
57
|
+
## The backend cannot reach the database
|
|
58
|
+
|
|
59
|
+
The backend uses RelStorage on PostgreSQL, so it needs a correct connection string and credentials.
|
|
60
|
+
|
|
61
|
+
- Confirm the database is running and reachable from the backend namespace.
|
|
62
|
+
- Confirm the environment variable that carries the DSN resolves from its Secret. See {doc}`/how-to/configure-env-and-secrets`.
|
|
63
|
+
|
|
64
|
+
```shell
|
|
65
|
+
kubectl get secret -n <namespace>
|
|
66
|
+
kubectl exec -n <namespace> deployment/<backend-deployment> -- env | grep -i storage
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Pods never become ready
|
|
70
|
+
|
|
71
|
+
A pod that stays `Running` but never `Ready` is failing its readiness probe.
|
|
72
|
+
|
|
73
|
+
- Increase `readinessInitialDelaySeconds` if the backend needs longer to start.
|
|
74
|
+
- Increase `readinessTimeoutSeconds` or `readinessFailureThreshold` for a slow first request.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
backend: {
|
|
78
|
+
image: 'plone/plone-backend:6.1.3',
|
|
79
|
+
readinessInitialDelaySeconds: 30,
|
|
80
|
+
readinessTimeoutSeconds: 15,
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Liveness probes are disabled by default (`livenessEnabled` defaults to `false`).
|
|
85
|
+
If pods restart in a loop after you enable liveness, raise `livenessInitialDelaySeconds` so the probe does not fire during startup.
|
|
86
|
+
|
|
87
|
+
## The cache does not cache
|
|
88
|
+
|
|
89
|
+
Check the cache pod logs, then confirm requests reach the cache service rather than the backend or frontend directly.
|
|
90
|
+
|
|
91
|
+
```shell
|
|
92
|
+
kubectl logs -n <namespace> -l app.kubernetes.io/part-of=plone
|
|
93
|
+
kubectl run -it --rm curl --image=curlimages/curl --restart=Never -- \
|
|
94
|
+
curl -sI http://<cache-service>.<namespace>:80/
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
A missing `X-Varnish` header means traffic bypasses the cache; point your ingress at the cache service. See {doc}`/how-to/configure-ingress-tls`.
|
|
98
|
+
For VCL behavior, see {doc}`/how-to/deploy-with-httpcache` and {doc}`/how-to/deploy-with-vinyl-cache`.
|
|
99
|
+
|
|
100
|
+
## Prometheus does not scrape the metrics
|
|
101
|
+
|
|
102
|
+
If a `ServiceMonitor` exists but no target appears in Prometheus, the selectors do not match.
|
|
103
|
+
|
|
104
|
+
- Confirm the `ServiceMonitor` namespace matches the `Prometheus` resource's `serviceMonitorNamespaceSelector`.
|
|
105
|
+
- Confirm its labels match the `Prometheus` resource's `serviceMonitorSelector`.
|
|
106
|
+
|
|
107
|
+
See {doc}`/how-to/enable-prometheus-monitoring` for the full setup.
|
|
108
|
+
|
|
109
|
+
## See also
|
|
110
|
+
|
|
111
|
+
- {doc}`/how-to/deploy-volto` — a complete deployment to compare against.
|
|
112
|
+
- {doc}`/reference/api/index` — authoritative option and default reference.
|
|
113
|
+
- {doc}`/explanation/architecture` — how the components depend on each other.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
myst:
|
|
3
|
+
html_meta:
|
|
4
|
+
"description": "Upgrade the Plone image and the cdk8s-plone library, roll out changes safely, and roll back a failed update."
|
|
5
|
+
"property=og:description": "Upgrade the Plone image and the cdk8s-plone library, roll out changes safely, and roll back a failed update."
|
|
6
|
+
"property=og:title": "Upgrade and roll out"
|
|
7
|
+
"keywords": "Plone, cdk8s, Kubernetes, upgrade, rollout, rolling update, rollback, migration"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Upgrade and roll out
|
|
11
|
+
|
|
12
|
+
This guide shows you how to upgrade the Plone images and the `cdk8s-plone` library, roll the change out safely, and roll it back if it fails.
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
- A working Plone deployment created with `cdk8s-plone`.
|
|
17
|
+
- Two or more replicas if you need a zero-downtime rollout. See {doc}`/how-to/scale-and-high-availability`.
|
|
18
|
+
|
|
19
|
+
## Upgrade the Plone image
|
|
20
|
+
|
|
21
|
+
Change the `image` tag on `backend` and `frontend` to the new version.
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
backend: {
|
|
25
|
+
image: 'plone/plone-backend:6.1.4',
|
|
26
|
+
},
|
|
27
|
+
frontend: {
|
|
28
|
+
image: 'plone/plone-frontend:16.1.0',
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Pin a specific tag rather than `latest`, so the rollout is reproducible and you can roll back to a known version.
|
|
33
|
+
|
|
34
|
+
Regenerate the manifests and apply them:
|
|
35
|
+
|
|
36
|
+
```shell
|
|
37
|
+
cdk8s synth
|
|
38
|
+
kubectl apply -f dist/
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Kubernetes replaces the pods with the default RollingUpdate strategy.
|
|
42
|
+
With two or more replicas and a PodDisruptionBudget, the old pods drain only as new pods become ready.
|
|
43
|
+
|
|
44
|
+
```{important}
|
|
45
|
+
Upgrading to a new Plone major or minor version may require a Plone site upgrade step that `cdk8s-plone` does not perform.
|
|
46
|
+
After the new backend pods are ready, run the upgrade from the Plone control panel (`@@plone-upgrade`) on the maintenance or uncached route.
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Watch the rollout
|
|
50
|
+
|
|
51
|
+
Follow the rollout and confirm it completes.
|
|
52
|
+
|
|
53
|
+
```shell
|
|
54
|
+
kubectl rollout status deployment/<backend-deployment> -n <namespace>
|
|
55
|
+
kubectl get pods -n <namespace> -w
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Roll back a failed upgrade
|
|
59
|
+
|
|
60
|
+
If the new version misbehaves, undo the rollout to the previous ReplicaSet:
|
|
61
|
+
|
|
62
|
+
```shell
|
|
63
|
+
kubectl rollout undo deployment/<backend-deployment> -n <namespace>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
To return to a known-good definition instead, restore the previous image tag in your code, then `cdk8s synth` and `kubectl apply -f dist/` again.
|
|
67
|
+
|
|
68
|
+
```{warning}
|
|
69
|
+
A rollback reverts the container image, not your data.
|
|
70
|
+
If the upgrade ran an irreversible Plone site migration, restore the database from a backup. See {doc}`/how-to/backup-and-restore`.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Upgrade the cdk8s-plone library
|
|
74
|
+
|
|
75
|
+
Bump the dependency, regenerate, and review the manifest diff before applying.
|
|
76
|
+
|
|
77
|
+
```shell
|
|
78
|
+
npm install @bluedynamics/cdk8s-plone@latest
|
|
79
|
+
cdk8s synth
|
|
80
|
+
git diff dist/
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Read the [changelog](https://github.com/bluedynamics/cdk8s-plone/releases) for renamed or deprecated options, then apply the reviewed manifests.
|
|
84
|
+
|
|
85
|
+
## See also
|
|
86
|
+
|
|
87
|
+
- {doc}`/how-to/scale-and-high-availability` — replicas and PodDisruptionBudget for zero-downtime rollouts.
|
|
88
|
+
- {doc}`/how-to/backup-and-restore` — back up before a risky upgrade.
|
|
89
|
+
- {doc}`/reference/api/index` — authoritative option reference for each release.
|