Skip to content
This repository has been archived by the owner on Feb 22, 2022. It is now read-only.

Commit

Permalink
add helm v2 chart for patroni with petset (#57)
Browse files Browse the repository at this point in the history
* feat(patroni): add helm v2 chart for patroni with petset

* chore(patroni): vendor etcd chart

* feat(patroni): have patroni use vendored etcd by default

* fix(patroni): use console instead of bash

* fix(patroni): make termination commands more reliable

* docs(patroni): add documentation to the configurable values

* docs(patroni): describe how to access postgres

* docs(patroni): add some details about how patroni on k8s works

* fix(patroni): do not require GCS by default
  • Loading branch information
linki authored and Vic Iglesias committed Sep 26, 2016
1 parent 6d3f477 commit 7932838
Show file tree
Hide file tree
Showing 11 changed files with 717 additions and 0 deletions.
12 changes: 12 additions & 0 deletions incubator/patroni/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: patroni
description: "Highly available elephant herd: HA PostgreSQL cluster."
version: 0.1.0
home: https://github.com/zalando/patroni
sources:
- https://github.com/zalando/patroni
- https://github.com/zalando/spilo
maintainers:
- name: Team ACID @ Zalando SE
email: team-acid@zalando.de
- name: Team Teapot @ Zalando SE
email: team-teapot@zalando.de
117 changes: 117 additions & 0 deletions incubator/patroni/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Patroni Helm Chart

This directory contains a Kubernetes chart to deploy a five node patroni cluster using a petset.

## Prerequisites Details
* Kubernetes 1.3 with alpha APIs enable
* PV support on the underlying infrastructure

## PetSet Details
* http://kubernetes.io/docs/user-guide/petset/

## PetSet Caveats
* http://kubernetes.io/docs/user-guide/petset/#alpha-limitations

## Todo
* Make namespace configurable

## Chart Details
This chart will do the following:

* Implement a HA scalable PostgreSQL cluster using Kubernetes PetSets

## Get this chart

Download the latest release of the chart from the [releases](../../../releases) page.

Alternatively, clone the repo if you wish to use the development snapshot:

```console
$ git clone https://github.com/kubernetes/charts.git
```

## Installing the Chart

To install the chart with the release name `my-release`:

```console
$ helm install --name my-release patroni-x.x.x.tgz
```

## Connecting to Postgres

Your access point is a cluster IP. In order to access it spin up another pod:

```console
$ kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il
```

Then, from inside the pod, connect to postgres:

```console
$ apt-get update && apt-get install postgresql-client -y
$ psql -U admin -h my-release-patroni.default.svc.cluster.local postgres
<admin password from values.yaml>
postgres=>
```

## Configuration

The following tables lists the configurable parameters of the patroni chart and their default values.

| Parameter | Description | Default |
|-------------------------|-------------------------------------|-----------------------------------------------------|
| `Name` | Service name | `patroni` |
| `Namespace` | Service namespace | `default` |
| `Spilo.Image` | Container image name | `registry.opensource.zalan.do/acid/spilo-9.5` |
| `Spilo.Version` | Container image tag | `1.0-p5` |
| `ImagePullPolicy` | Container pull policy | `IfNotPresent` |
| `Replicas` | k8s petset replicas | `5` |
| `Component` | k8s selector key | `patroni` |
| `Resources.Cpu` | container requested cpu | `100m` |
| `Resources.Memory` | container requested memory | `512Mi` |
| `Resources.Storage` | Persistent volume size | `1Gi` |
| `Credentials.Superuser` | password for the superuser | `tea` |
| `Credentials.Admin` | password for the admin user | `cola` |
| `Credentials.Standby` | password for the replication user | `pinacolada` |
| `Etcd.Discovery` | domain name of etcd cluster | `<release-name>-etcd.<namespace>.svc.cluster.local` |

Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`.

Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,

```console
$ helm install --name my-release -f values.yaml patroni-x.x.x.tgz
```

> **Tip**: You can use the default [values.yaml](values.yaml)
## Cleanup

In order to remove everything you created a simple `helm delete <release-name>` isn't enough (as of now), but you can do the following:

```console
$ release=<release-name>
$ helm delete $release
$ grace=$(kubectl get po $release-patroni-0 --template '{{.spec.terminationGracePeriodSeconds}}')
$ kubectl delete petset,po -l release=$release
$ sleep $grace
$ kubectl delete pvc -l release=$release
```

## Internals

Patroni is responsible for electing a Postgres master pod by leveraging etcd.
It then exports this master via a Kubernetes service and a label query that filters for `spilo-role=master`.
This label is dynamically set on the pod that acts as the master and removed from all other pods.
Consequently, the service endpoint will point to the current master.

```console
$ kubectl get pods -l spilo-role -L spilo-role
NAME READY STATUS RESTARTS AGE SPILO-ROLE
my-release-patroni-0 1/1 Running 0 9m replica
my-release-patroni-1 1/1 Running 0 9m master
my-release-patroni-2 1/1 Running 0 8m replica
my-release-patroni-3 1/1 Running 0 8m replica
my-release-patroni-4 1/1 Running 0 8m replica
```
21 changes: 21 additions & 0 deletions incubator/patroni/charts/etcd/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
9 changes: 9 additions & 0 deletions incubator/patroni/charts/etcd/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: etcd
home: https://github.com/coreos/etcd
version: 0.1.0
description: Etcd Helm chart for Kubernetes.
sources:
- https://github.com/coreos/etcd
maintainers:
- name: Lachlan Evenson
email: lachlan@deis.com
178 changes: 178 additions & 0 deletions incubator/patroni/charts/etcd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Etcd Helm Chart

Credit to https://github.com/ingvagabund. This is an implementation of that work

* https://github.com/kubernetes/contrib/pull/1295

## Prerequisites Details
* Kubernetes 1.3 with alpha APIs enable
* PV support on the underlying infrastructure

## PetSet Details
* http://kubernetes.io/docs/user-guide/petset/

## PetSet Caveats
* http://kubernetes.io/docs/user-guide/petset/#alpha-limitations

## Todo
* Implement SSL

## Chart Details
This chart will do the following:

* Implemented a dynamically scalable etcd cluster using Kubernetes PetSets

## Get this chart

Download the latest release of the chart from the [releases](../../../releases) page.

Alternatively, clone the repo if you wish to use the development snapshot:

```bash
$ git clone https://github.com/kubernetes/charts.git
```

## Installing the Chart

To install the chart with the release name `my-release`:

```bash
$ helm install --name my-release etcd-x.x.x.tgz
```

## Configuration

The following tables lists the configurable parameters of the etcd chart and their default values.

| Parameter | Description | Default |
|-----------------------|----------------------------------|----------------------------------------------------------|
| `Name` | Spark master name | `etcd` |
| `Image` | Container image name | `gcr.io/google_containers/etcd-amd64` |
| `ImageTag` | Container image tag | `2.2.5` |
| `ImagePullPolicy` | Container pull policy | `Always` |
| `Replicas` | k8s petset replicas | `3` |
| `Component` | k8s selector key | `etcd` |
| `Cpu` | container requested cpu | `100m` |
| `Memory` |container requested memory | `512Mi` |
| `ClientPort` | k8s service port | `2379` |
| `PeerPorts`| Container listening port | `2380` |
| `Storage`| Persistent volume size | `1Gi` |

Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`.

Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,

```bash
$ helm install --name my-release -f values.yaml etcd-x.x.x.tgz
```

> **Tip**: You can use the default [values.yaml](values.yaml)
# Deep dive

## Cluster Health

```
$ for i in <0..n>; do kubectl exec <release-podname-$i> -- sh -c 'etcdctl cluster-health'; done
```
eg.
```
$ for i in {0..9}; do kubectl exec named-lynx-etcd-$i --namespace=etcd -- sh -c 'etcdctl cluster-health'; done
member 7878c44dabe58db is healthy: got healthy result from http://named-lynx-etcd-7.named-lynx-etcd:2379
member 19d2ab7b415341cc is healthy: got healthy result from http://named-lynx-etcd-4.named-lynx-etcd:2379
member 6b627d1b92282322 is healthy: got healthy result from http://named-lynx-etcd-3.named-lynx-etcd:2379
member 6bb377156d9e3fb3 is healthy: got healthy result from http://named-lynx-etcd-0.named-lynx-etcd:2379
member 8ebbb00c312213d6 is healthy: got healthy result from http://named-lynx-etcd-8.named-lynx-etcd:2379
member a32e3e8a520ff75f is healthy: got healthy result from http://named-lynx-etcd-5.named-lynx-etcd:2379
member dc83003f0a226816 is healthy: got healthy result from http://named-lynx-etcd-2.named-lynx-etcd:2379
member e3dc94686f60465d is healthy: got healthy result from http://named-lynx-etcd-6.named-lynx-etcd:2379
member f5ee1ca177a88a58 is healthy: got healthy result from http://named-lynx-etcd-1.named-lynx-etcd:2379
cluster is healthy
```

## Failover

If any etcd member fails it gets re-joined eventually.
You can test the scenario by killing process of one of the pets:

```shell
$ ps aux | grep etcd-1
$ kill -9 ETCD_1_PID
```

```shell
$ kubectl get pods -l "app=etcd"
NAME READY STATUS RESTARTS AGE
etcd-0 1/1 Running 0 54s
etcd-2 1/1 Running 0 51s
```

After a while:

```shell
$ kubectl get pods -l "app=etcd"
NAME READY STATUS RESTARTS AGE
etcd-0 1/1 Running 0 1m
etcd-1 1/1 Running 0 20s
etcd-2 1/1 Running 0 1m
```

You can check state of re-joining from ``etcd-1``'s logs:

```shell
$ kubectl logs etcd-1
Waiting for etcd-0.etcd to come up
Waiting for etcd-1.etcd to come up
ping: bad address 'etcd-1.etcd'
Waiting for etcd-1.etcd to come up
Waiting for etcd-2.etcd to come up
Re-joining etcd member
Updated member with ID 7fd61f3f79d97779 in cluster
2016-06-20 11:04:14.962169 I | etcdmain: etcd Version: 2.2.5
2016-06-20 11:04:14.962287 I | etcdmain: Git SHA: bc9ddf2
...
```

## Scaling using kubectl

This is for reference. Scaling should be managed by `helm upgrade`

The etcd cluster can be scale up by running ``kubectl patch`` or ``kubectl edit``. For instance,

```sh
$ kubectl get pods -l "app=etcd"
NAME READY STATUS RESTARTS AGE
etcd-0 1/1 Running 0 7m
etcd-1 1/1 Running 0 7m
etcd-2 1/1 Running 0 6m

$ kubectl patch petset/etcd -p '{"spec":{"replicas": 5}}'
"etcd" patched

$ kubectl get pods -l "app=etcd"
NAME READY STATUS RESTARTS AGE
etcd-0 1/1 Running 0 8m
etcd-1 1/1 Running 0 8m
etcd-2 1/1 Running 0 8m
etcd-3 1/1 Running 0 4s
etcd-4 1/1 Running 0 1s
```

Scaling-down is similar. For instance, changing the number of pets to ``4``:

```sh
$ kubectl edit petset/etcd
petset "etcd" edited

$ kubectl get pods -l "app=etcd"
NAME READY STATUS RESTARTS AGE
etcd-0 1/1 Running 0 8m
etcd-1 1/1 Running 0 8m
etcd-2 1/1 Running 0 8m
etcd-3 1/1 Running 0 4s
```

Once a pet is terminated (either by running ``kubectl delete pod etcd-ID`` or scaling down),
content of ``/var/run/etcd/`` directory is cleaned up.
If any of the etcd pets restarts (e.g. caused by etcd failure or any other),
the directory is kept untouched so the pet can recover from the failure.
Loading

0 comments on commit 7932838

Please sign in to comment.