Skip to content

Commit d5660f6

Browse files
authored
[UI] add tab for monthly costs per cluster (#796)
* add tab for monthly costs per cluster * sync run_local and update version number * lowering resources * some Makefile polishing and updated admin docs on UI * extend admin docs on UI * add api-service manifest for operator * set min limits in UI to default min limits of operator * reflect new UI helm charts in docs * make cluster name label configurable
1 parent aea9e9b commit d5660f6

17 files changed

+257
-86
lines changed

charts/postgres-operator-ui/Chart.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
apiVersion: v1
22
name: postgres-operator-ui
33
version: 0.1.0
4-
appVersion: 1.2.0
4+
appVersion: 1.3.0
55
home: https://github.com/zalando/postgres-operator
66
description: Postgres Operator UI provides a graphical interface for a convenient database-as-a-service user experience
77
keywords:
@@ -12,6 +12,8 @@ keywords:
1212
- patroni
1313
- spilo
1414
maintainers:
15+
- name: Zalando
16+
1517
- name: siku4
1618
1719
sources:

charts/postgres-operator/templates/service.yaml

+1-4
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,11 @@ metadata:
88
app.kubernetes.io/instance: {{ .Release.Name }}
99
name: {{ template "postgres-operator.fullname" . }}
1010
spec:
11+
type: ClusterIP
1112
ports:
1213
- port: 8080
1314
protocol: TCP
1415
targetPort: 8080
1516
selector:
1617
app.kubernetes.io/instance: {{ .Release.Name }}
1718
app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
18-
sessionAffinity: None
19-
type: ClusterIP
20-
status:
21-
loadBalancer: {}

docs/administrator.md

+53-19
Original file line numberDiff line numberDiff line change
@@ -480,37 +480,71 @@ A secret can be pre-provisioned in different ways:
480480

481481
## Setting up the Postgres Operator UI
482482

483-
With the v1.2 release the Postgres Operator is shipped with a browser-based
483+
Since the v1.2 release the Postgres Operator is shipped with a browser-based
484484
configuration user interface (UI) that simplifies managing Postgres clusters
485-
with the operator. The UI runs with Node.js and comes with it's own Docker
486-
image.
485+
with the operator.
487486

488-
Run NPM to continuously compile `tags/js` code. Basically, it creates an
489-
`app.js` file in: `static/build/app.js`
487+
### Building the UI image
490488

491-
```
492-
(cd ui/app && npm start)
493-
```
494-
495-
To build the Docker image open a shell and change to the `ui` folder. Then run:
489+
The UI runs with Node.js and comes with it's own Docker
490+
image. However, installing Node.js to build the operator UI is not required. It
491+
is handled via Docker containers when running:
496492

497493
```bash
498-
docker build -t registry.opensource.zalan.do/acid/postgres-operator-ui:v1.2.0 .
494+
make docker
499495
```
500496

501-
Apply all manifests for the `ui/manifests` folder to deploy the Postgres
502-
Operator UI on K8s. For local tests you don't need the Ingress resource.
497+
### Configure endpoints and options
498+
499+
The UI talks to the K8s API server as well as the Postgres Operator [REST API](developer.md#debugging-the-operator).
500+
K8s API server URLs are loaded from the machine's kubeconfig environment by
501+
default. Alternatively, a list can also be passed when starting the Python
502+
application with the `--cluster` option.
503+
504+
The Operator API endpoint can be configured via the `OPERATOR_API_URL`
505+
environment variables in the [deployment manifest](../ui/manifests/deployment.yaml#L40).
506+
You can also expose the operator API through a [service](../manifests/api-service.yaml).
507+
Some displayed options can be disabled from UI using simple flags under the
508+
`OPERATOR_UI_CONFIG` field in the deployment.
509+
510+
### Deploy the UI on K8s
511+
512+
Now, apply all manifests from the `ui/manifests` folder to deploy the Postgres
513+
Operator UI on K8s. Replace the image tag in the deployment manifest if you
514+
want to test the image you've built with `make docker`. Make sure the pods for
515+
the operator and the UI are both running.
503516

504517
```bash
505-
kubectl apply -f ui/manifests
518+
sed -e "s/\(image\:.*\:\).*$/\1$TAG/" manifests/deployment.yaml | kubectl apply -f manifests/
519+
kubectl get all -l application=postgres-operator-ui
506520
```
507521

508-
Make sure the pods for the operator and the UI are both running. For local
509-
testing you need to apply proxying and port forwarding so that the UI can talk
510-
to the K8s and Postgres Operator REST API. You can use the provided
511-
`run_local.sh` script for this. Make sure it uses the correct URL to your K8s
512-
API server, e.g. for minikube it would be `https://192.168.99.100:8443`.
522+
### Local testing
523+
524+
For local testing you need to apply K8s proxying and operator pod port
525+
forwarding so that the UI can talk to the K8s and Postgres Operator REST API.
526+
The Ingress resource is not needed. You can use the provided `run_local.sh`
527+
script for this. Make sure that:
528+
529+
* Python dependencies are installed on your machine
530+
* the K8s API server URL is set for kubectl commands, e.g. for minikube it would usually be `https://192.168.99.100:8443`.
531+
* the pod label selectors for port forwarding are correct
532+
533+
When testing with minikube you have to build the image in its docker environment
534+
(running `make docker` doesn't do it for you). From the `ui` directory execute:
513535

514536
```bash
537+
# compile and build operator UI
538+
make docker
539+
540+
# build in image in minikube docker env
541+
eval $(minikube docker-env)
542+
docker build -t registry.opensource.zalan.do/acid/postgres-operator-ui:v1.3.0 .
543+
544+
# apply UI manifests next to a running Postgres Operator
545+
kubectl apply -f manifests/
546+
547+
# install python dependencies to run UI locally
548+
pip3 install -r requirements
515549
./run_local.sh
516550
```

docs/operator-ui.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,13 @@ status page.
3131
![pgui-waiting-for-master](diagrams/pgui-waiting-for-master.png "Waiting for master pod")
3232

3333
Usually, the startup should only take up to 1 minute. If you feel the process
34-
got stuck click on the "Logs" button to inspect the operator logs. From the
35-
"Status" field in the top menu you can also retrieve the logs and queue of each
36-
worker the operator is using. The number of concurrent workers can be
34+
got stuck click on the "Logs" button to inspect the operator logs. If the logs
35+
look fine, but the UI seems to got stuck, check if you are have configured the
36+
same [cluster name label](../ui/manifests/deployment.yaml#L45) like for the
37+
[operator](../manifests/configmap.yaml#L13).
38+
39+
From the "Status" field in the top menu you can also retrieve the logs and queue
40+
of each worker the operator is using. The number of concurrent workers can be
3741
[configured](reference/operator_parameters.md#general).
3842

3943
![pgui-operator-logs](diagrams/pgui-operator-logs.png "Checking operator logs")

docs/quickstart.md

+56-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ cd postgres-operator
5252
kubectl create -f manifests/configmap.yaml # configuration
5353
kubectl create -f manifests/operator-service-account-rbac.yaml # identity and permissions
5454
kubectl create -f manifests/postgres-operator.yaml # deployment
55+
kubectl create -f manifests/api-service.yaml # operator API to be used by UI
5556
```
5657

5758
There is a [Kustomization](https://github.com/kubernetes-sigs/kustomize)
@@ -104,7 +105,7 @@ kubectl create -f https://operatorhub.io/install/postgres-operator.yaml
104105
This installs the operator in the `operators` namespace. More information can be
105106
found on [operatorhub.io](https://operatorhub.io/operator/postgres-operator).
106107

107-
## Create a Postgres cluster
108+
## Check if Postgres Operator is running
108109

109110
Starting the operator may take a few seconds. Check if the operator pod is
110111
running before applying a Postgres cluster manifest.
@@ -115,7 +116,61 @@ kubectl get pod -l name=postgres-operator
115116

116117
# if you've created the operator using helm chart
117118
kubectl get pod -l app.kubernetes.io/name=postgres-operator
119+
```
120+
121+
If the operator doesn't get into `Running` state, either check the latest K8s
122+
events of the deployment or pod with `kubectl describe` or inspect the operator
123+
logs:
124+
125+
```bash
126+
kubectl logs "$(kubectl get pod -l name=postgres-operator --output='name')"
127+
```
128+
129+
## Deploy the operator UI
130+
131+
In the following paragraphs we describe how to access and manage PostgreSQL
132+
clusters from the command line with kubectl. But it can also be done from the
133+
browser-based [Postgres Operator UI](operator-ui.md). Before deploying the UI
134+
make sure the operator is running and its REST API is reachable through a
135+
[K8s service](../manifests/api-service.yaml). The URL to this API must be
136+
configured in the [deployment manifest](../ui/manifests/deployment.yaml#L43)
137+
of the UI.
118138

139+
To deploy the UI simply apply all its manifests files or use the UI helm chart:
140+
141+
```bash
142+
# manual deployment
143+
kubectl apply -f ui/manifests/
144+
145+
# or helm chart
146+
helm install postgres-operator-ui ./charts/postgres-operator-ui
147+
```
148+
149+
Like with the operator, check if the UI pod gets into `Running` state:
150+
151+
```bash
152+
# if you've created the operator using yaml manifests
153+
kubectl get pod -l name=postgres-operator-ui
154+
155+
# if you've created the operator using helm chart
156+
kubectl get pod -l app.kubernetes.io/name=postgres-operator-ui
157+
```
158+
159+
You can now access the web interface by port forwarding the UI pod (mind the
160+
label selector) and enter `localhost:8081` in your browser:
161+
162+
```bash
163+
kubectl port-forward "$(kubectl get pod -l name=postgres-operator-ui --output='name')" 8081
164+
```
165+
166+
Available option are explained in detail in the [UI docs](operator-ui.md).
167+
168+
## Create a Postgres cluster
169+
170+
If the operator pod is running it listens to new events regarding `postgresql`
171+
resources. Now, it's time to submit your first Postgres cluster manifest.
172+
173+
```bash
119174
# create a Postgres cluster
120175
kubectl create -f manifests/minimal-postgres-manifest.yaml
121176
```

manifests/api-service.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: postgres-operator
5+
spec:
6+
type: ClusterIP
7+
ports:
8+
- port: 8080
9+
protocol: TCP
10+
targetPort: 8080
11+
selector:
12+
name: postgres-operator

manifests/kustomization.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ resources:
44
- configmap.yaml
55
- operator-service-account-rbac.yaml
66
- postgres-operator.yaml
7+
- api-service.yaml

ui/Makefile

+6-14
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
.PHONY: clean test appjs docker push mock
22

3-
BINARY ?= postgres-operator-ui
4-
BUILD_FLAGS ?= -v
5-
CGO_ENABLED ?= 0
6-
ifeq ($(RACE),1)
7-
BUILD_FLAGS += -race -a
8-
CGO_ENABLED=1
9-
endif
10-
11-
LOCAL_BUILD_FLAGS ?= $(BUILD_FLAGS)
12-
LDFLAGS ?= -X=main.version=$(VERSION)
13-
14-
IMAGE ?= registry.opensource.zalan.do/acid/$(BINARY)
3+
IMAGE ?= registry.opensource.zalan.do/acid/postgres-operator-ui
154
VERSION ?= $(shell git describe --tags --always --dirty)
165
TAG ?= $(VERSION)
176
GITHEAD = $(shell git rev-parse --short HEAD)
@@ -32,8 +21,11 @@ appjs:
3221
docker run $(TTYFLAGS) -u $$(id -u) -v $$(pwd):/workdir -w /workdir/app node:10.1.0-alpine npm run build
3322

3423
docker: appjs
35-
docker build --build-arg "VERSION=$(VERSION)" -t "$(IMAGE):$(TAG)" .
36-
@echo 'Docker image $(IMAGE):$(TAG) can now be used.'
24+
echo `(env)`
25+
echo "Tag ${TAG}"
26+
echo "Version ${VERSION}"
27+
echo "git describe $(shell git describe --tags --always --dirty)"
28+
docker build --rm -t "$(IMAGE):$(TAG)" -f Dockerfile .
3729

3830
push: docker
3931
docker push "$(IMAGE):$(TAG)"

ui/app/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "postgres-operator-ui",
3-
"version": "1.0.0",
3+
"version": "1.3.0",
44
"description": "PostgreSQL Operator UI",
55
"main": "src/app.js",
66
"config": {

ui/app/src/new.tag.pug

+8-8
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ new
408408
ref='cpuLimit'
409409
type='number'
410410
placeholder='{ cpu.state.limit.initialValue }'
411-
min='1'
411+
min='250'
412412
required
413413
value='{ cpu.state.limit.state }'
414414
onchange='{ cpu.state.limit.edit }'
@@ -434,22 +434,22 @@ new
434434
onkeyup='{ memory.state.request.edit }'
435435
)
436436
.input-group-addon
437-
.input-units Gi
437+
.input-units Mi
438438

439439
.input-group
440440
.input-group-addon.resource-type Limit
441441
input.form-control(
442442
ref='memoryLimit'
443443
type='number'
444444
placeholder='{ memory.state.limit.initialValue }'
445-
min='1'
445+
min='250'
446446
required
447447
value='{ memory.state.limit.state }'
448448
onchange='{ memory.state.limit.edit }'
449449
onkeyup='{ memory.state.limit.edit }'
450450
)
451451
.input-group-addon
452-
.input-units Gi
452+
.input-units Mi
453453

454454
.col-lg-3
455455
help-general(config='{ opts.config }')
@@ -519,10 +519,10 @@ new
519519
resources:
520520
requests:
521521
cpu: {{ cpu.state.request.state }}m
522-
memory: {{ memory.state.request.state }}Gi
522+
memory: {{ memory.state.request.state }}Mi
523523
limits:
524524
cpu: {{ cpu.state.limit.state }}m
525-
memory: {{ memory.state.limit.state }}Gi{{#if restoring}}
525+
memory: {{ memory.state.limit.state }}Mi{{#if restoring}}
526526
527527
clone:
528528
cluster: "{{ backup.state.name.state }}"
@@ -786,8 +786,8 @@ new
786786
return instance
787787
}
788788

789-
this.cpu = DynamicResource({ request: 100, limit: 1000 })
790-
this.memory = DynamicResource({ request: 1, limit: 1 })
789+
this.cpu = DynamicResource({ request: 100, limit: 500 })
790+
this.memory = DynamicResource({ request: 100, limit: 500 })
791791

792792
this.backup = DynamicSet({
793793
type: () => 'empty',

ui/app/src/postgresql.tag.pug

+3
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ postgresql
7676
.alert.alert-danger(if='{ progress.requestStatus !== "OK" }') Create request failed
7777
.alert.alert-success(if='{ progress.requestStatus === "OK" }') Create request successful ({ new Date(progress.createdTimestamp).toLocaleString() })
7878

79+
.alert.alert-info(if='{ !progress.postgresql }') PostgreSQL cluster manifest pending
80+
.alert.alert-success(if='{ progress.postgresql }') PostgreSQL cluster manifest created
81+
7982
.alert.alert-info(if='{ !progress.statefulSet }') StatefulSet pending
8083
.alert.alert-success(if='{ progress.statefulSet }') StatefulSet created
8184

0 commit comments

Comments
 (0)