Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addon Postgres-operator #615

Merged
merged 10 commits into from
Feb 5, 2023
66 changes: 66 additions & 0 deletions examples/postgres-operator/demo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: postgres-operator-sample
spec:
components:
# This component is provided by postgres-operator addon.
# In this example, 3 redis instances(replicas)
# will be created.
- type: "postgres-cluster"
name: "postgres"
properties:
# You can increase/decrease this later to add/remove instances.
replicas: 3 # By default it's set to 2
teamId: acid
image: "ghcr.io/zalando/spilo-15:2.1-p9"
volume:
size: 1Gi
databases:
foo: zalando
preparedDatabases:
bar:
defaultUsers: true
extensions:
pg_partman: public
pgcrypto: public
schemas:
data: {}
history:
defaultRoles: true
defaultUsers: false
users:
zalando: [superuser, createdb]
foo_user: []
patroni:
failsafe_mode: false
initdb:
encoding: UTF8
locale: en_US.UTF-8
data-checksums: "true"
enableShmVolume: true
enableMasterLoadBalancer: false
enableReplicaLoadBalancer: false
enableConnectionPooler: false
enableReplicaConnectionPooler: false
enableMasterPoolerLoadBalancer: false
enableReplicaPoolerLoadBalancer: false
ttl: 30
loopWait: 10
retryTimeout: 10
synchronousMode: false
synchronousModeStrict: false
synchronousNodeCount: 1
resources:
requests:
cpu: 10m
memory: 100Mi
limits:
cpu: 500m
memory: 500Mi
tls:
secretName: ""
certificateFile: tls.crt
privateKeyFile: tls.key
caFile: ""
caSecretName: ""
80 changes: 80 additions & 0 deletions experimental/addons/postgres-operator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# postgres-operator

This is an addon template. Check how to build your own addon: https://kubevela.net/docs/platform-engineers/addon/intro

## Install

Add experimental registry
```
vela addon registry add experimental --type=helm --endpoint=https://addons.kubevela.net/experimental/
```

Enable this addon
```
vela addon enable postgres-operator
```

```shell
$ vela ls -A | grep postgres
vela-system addon-postgres-operator ns-postgres-operator k8s-objects running healthy
vela-system └─ postgres-operator helm running
healthy Fetch repository successfully, Create helm release
```

Disable this addon
```
vela addon disable postgres-operator
```

## Use
## postgres-operator

After you enable this addon, create a namespace `prod`:

```shell
$ kubectl create namespace prod
```

Then apply this Application yaml to create a postgres cluster:

```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: postgres-operator-sample
spec:
components:
- type: "postgres-cluster"
namespace: prod
name: postgres
properties:
replicas: 3
```

```shell
$ kubectl get po -n prod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
postgres-0 1/1 Running 0 2m30s 10.244.1.73 minikube <none> <none>
postgres-1 1/1 Running 0 2m20s 10.244.1.74 minikube <none> <none>
postgres-2 1/1 Running 0 105s 10.244.1.75 minikube <none> <none>
```

### Connect to PostgreSQL via psql

With a port-forward on one of the database pods (e.g. the master) you can connect to the PostgreSQL database from your machine. Use labels to filter for the master pod of our test cluster.

```shell
# get name of master pod of acid-minimal-cluster
export PGMASTER=$(kubectl get pods -o jsonpath={.items..metadata.name} -l application=spilo,cluster-name=postgres,spilo-role=master -n prod)

# set up port forward
kubectl port-forward $PGMASTER 6432:5432 -n default
```

Open another CLI and connect to the database using e.g. the psql client. When connecting with a manifest role like foo_user user, read its password from the K8s secret which was generated when creating acid-minimal-cluster. As non-encrypted connections are rejected by default set SSL mode to require:

```shell
export PGPASSWORD=$(kubectl get secret postgres.postgres.credentials.postgresql.acid.zalan.do -o 'jsonpath={.data.password}' | base64 -d)
export PGSSLMODE=require
psql -U postgres -h localhost -p 6432
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
"postgres-cluster": {
alias: ""
annotations: {}
attributes: workload: type: "autodetects.core.oam.dev"
description: "postgres cluster component"
labels: {}
type: "component"
}

template: {
output: {
kind: "postgresql"
apiVersion: "acid.zalan.do/v1"
metadata: {
name: context.name
namespace: context.namespace
// default namespace will be "prod"
}
spec: {
dockerImage: parameter.image //ghcr.io/zalando/spilo-15:2.1-p9
numberOfInstances: parameter.replicas //By default it's 2
teamId: parameter.teamId
postgresql: parameter.postgresql
databases: parameter.databases
preparedDatabases: parameter.preparedDatabases
users: parameter.users
enableMasterLoadBalancer: parameter.enableMasterLoadBalancer
enableReplicaLoadBalancer: parameter.enableReplicaLoadBalancer
enableConnectionPooler: parameter.enableConnectionPooler
enableReplicaConnectionPooler: parameter.enableReplicaConnectionPooler
enableMasterPoolerLoadBalancer: parameter.enableReplicaConnectionPooler
enableReplicaPoolerLoadBalancer: parameter.enableReplicaPoolerLoadBalancer
allowedSourceRanges: [ // load balancers' source ranges for both master and replica services
"127.0.0.1/32"
]
volume: parameter.volume
additionalVolumes: [
{
name: "empty"
mountPath: "/opt/empty"
targetContainers: [
"all"
]
volumeSource: {
emptyDir: {}
}
}
]
enableShmVolume: parameter.enableShmVolume
resources: parameter.resources
patroni: parameter.patroni
ttl: parameter.ttl
loop_wait: parameter.loopWait
retry_timeout: parameter.retryTimeout
synchronous_mode: parameter.synchronousMode
synchronous_mode_strict: parameter.synchronousModeStrict
synchronous_node_count: parameter.synchronousNodeCount
maximum_lag_on_failover: 33554432
initContainers: [
{
name: "date"
image: "busybox"
command: [ "/bin/date" ]
}
]
// Custom TLS certificate. Disabled unless tls.secretName has a value.
tls: parameter.tls
}
}
parameter: {
//+usage=configure postgresql.
postgresql: {
//+usage=the version of the postgresql to be used.
version: *"15" | string
parameters: {
// Expert section
shared_buffers: *"32MB" | string
max_connections: *"10" | string
log_statement: *"all" | string
}
}
//+usage=the size of the postgres cluster.
replicas: *2 | int
//+usage=set team Id.
teamId: *"acid" | string
//+usage=the image of the spilo.
image: *"ghcr.io/zalando/spilo-15:2.1-p9" | string
//+usage=configure volume.
volume: {
//+usage=the size of the volume used of postgres.
size: *"1Gi" | string
}
//+usage=define databases to be used.
databases: *{
foo: "zalando" // dbname: owner
} | {...}
//+usage=configure created databases.
preparedDatabases: *{
bar: {
defaultUsers: true
extensions: {
pg_partman: "public"
pgcrypto: "public"
}
schemas: {
data: {}
history: {
defaultRoles: true
defaultUsers: false
}
}
}
} | {...}
//+usage=configure users for the databases.
users: *{
zalando: ["superuser", "createdb"]
foo_user: []
} | {...}
//+usage=configure patroni.
patroni: {
failsafe_mode: *false | bool
initdb: {
encoding: *"UTF8" | string
locale: *"en_US.UTF-8" | string
"data-checksums": *"true" | string
}
}
//+usage=enable SHM volume if set true.
enableShmVolume: *true | bool
//+usage=enable master as load balancer if set true.
enableMasterLoadBalancer: *false | bool
//+usage=enable replica as load balancer if set true.
enableReplicaLoadBalancer: *false | bool
//+usage=enable/disable connection pooler deployment.
enableConnectionPooler: *false | bool
//+usage=set to enable connection pooler for replica service.
enableReplicaConnectionPooler: *false | bool
//+usage=set to enable master pooler as load balancer.
enableMasterPoolerLoadBalancer: *false | bool
//+usage=set to enable replica pooler as load balancer.
enableReplicaPoolerLoadBalancer: *false | bool
//+usage=set ttl(Time to live) by dedault it's 30 days.
ttl: *30 | int
//+usage=set loop wait time by dedault it's 10.
loopWait: *10 | int
//+usage=set retry timeout by dedault it's 10.
retryTimeout: *10 | int
//+usage=set to enable synchronous mode.
synchronousMode: *false | bool
//+usage=set to enable synchronous mode strictly.
synchronousModeStrict: *false | bool
//+usage=set how many nodes to be synchronized.
synchronousNodeCount: *1 | int
//+usage=configure resources.
resources: {
requests: {
cpu: *"10m" | string
memory: *"100Mi" | string
}
limits: {
cpu: *"500m" | string
memory: *"500Mi" | string
}
}
//+usage=configure custom TLS.
tls: {
//+usage=sets custom TLS secret name, It should correspond to a Kubernetes Secret resource to load.
secretName: *"" | string
//+usage=sets custom TLS certificate file.
certificateFile: *"tls.crt" | string
//+usage=sets custom TLS private key file.
privateKeyFile: *"tls.key" | string
//+usage=optionally configure Postgres with a CA certificate.
caFile: *"" | string
//+usage=optionally the ca.crt can come from this secret instead.
caSecretName: *"" | string
}
}
}
13 changes: 13 additions & 0 deletions experimental/addons/postgres-operator/metadata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: postgres-operator
version: 1.0.0
description: This addon adds postgres-operator to the kubevela to be used by across the application installed in kubevela.
icon: ""
url: "https://www.postgresql.org/"

tags:
- postgres-operator

invisible: false

dependencies:
- name: fluxcd
11 changes: 11 additions & 0 deletions experimental/addons/postgres-operator/parameter.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// parameter.cue is used to store addon parameters.
//
// You can use these parameters in template.cue or in resources/ by 'parameter.myparam'
//
// For example, you can use parameters to allow the user to customize
// container images, ports, and etc.
parameter: {
// +usage=Custom parameter description
namespace: *"postgres-operator" | string
clusters?: [...string]
}
Loading