-
Notifications
You must be signed in to change notification settings - Fork 17
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
Implement persistence with StatefulSets #201
Changes from 87 commits
8591882
b4d958d
2244992
3c7a657
36fea97
25b4684
64b642f
9b5d269
8ca2d45
ddcbb6d
b2ece1a
418837d
23e6b07
975696c
989af04
578b823
e6826ab
06d7daa
88c2bcb
16cf8f6
3361d92
08cac69
0b91640
9ecdcaf
833a720
255cca3
92b099b
6690c0b
ffe1f86
0e9765e
7449f74
7581d97
5cfff30
e8e70de
3d69f43
a3a5ca1
ee9f83b
a9c2c66
e7da267
feb2760
cf5efb8
1f9475a
8a576bf
538aaff
51a487d
bb0bcb8
4f3e1dc
5efcdc1
8914288
85e59be
768e8f1
c7f421c
4a8d061
93e7fa4
d534996
2943d14
28f4578
17597cf
1b4c0d5
a1de425
2b263c2
e0f0273
93f82dc
d002da3
2f3adef
fb9d9f8
b6be7bc
b6a8401
d9399c9
71e0638
9caf4c0
6041ff4
951f9fe
3aff775
6dfc118
89e4eea
0573853
78468bb
f4b9093
8d7720c
d17efa3
96d7aa1
8e9e0e2
5d16382
1ed628c
4a6f295
64e7f10
ca9e0c8
4f327c9
efe0e8f
f3af7cd
b8876df
49da9a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Persistent Storage example | ||
|
||
Habitat objects are translated by the operator into `StatefulSet` objects, which | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Maybe add a note that the user needs to know about basic understanding of persistent volumes in K8s and link to it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I'll add a link to this |
||
provide optional support for persistent storage. | ||
|
||
In order to enable persistent storage for your Habitat object, you need to: | ||
|
||
* create a | ||
[`StorageClass`](https://kubernetes.io/docs/concepts/storage/storage-classes/) object in your cluster | ||
* add the `spec.persistentStorage` key to the Habitat object's manifest | ||
* specify the `name` of the aforementioned `StorageClass` object under | ||
`spec.persistence.storageClassName` in the Habitat object's manifest | ||
|
||
## Workflow | ||
|
||
Before deploying the example, create a `StorageClass` object, specifying the | ||
type of volume your cluster is able to provision. | ||
|
||
**NOTE**: If you're deploying the example on GKE, a standard | ||
`StorageClass` for `GCEPersistentDisk` has already been defined, so you can skip | ||
the above step | ||
|
||
Once the `StorageClass` has been created, run the example: | ||
|
||
kubectl create -f examples/persisted/habitat.yml | ||
|
||
When you want to delete the Habitat, run: | ||
|
||
kubectl delete -f examples/persisted/habitat.yml | ||
|
||
**NOTE**: Any `PersistentVolume` created by the operator will **NOT** be | ||
automatically removed. This is the default behaviour of Kubernetes and is | ||
intended as a safeguard against accidental data deletion. | ||
|
||
If you want to explicitly delete the `PersistentVolume`, run: | ||
|
||
kubectl delete pvc -l habitat-name=example-persistent-habitat |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
apiVersion: habitat.sh/v1beta1 | ||
kind: Habitat | ||
metadata: | ||
name: example-persistent-habitat | ||
spec: | ||
# the core/redis habitat service packaged as a Docker image | ||
image: kinvolk/redis-hab | ||
count: 3 | ||
# the presence of this key activates persistent storage | ||
persistentStorage: | ||
# the size of the volume that will be mounted in each Pod | ||
size: 1Gi | ||
# a StorageClass object with name "standard" must be created beforehand by | ||
# the cluster administrator | ||
storageClassName: standard | ||
# the location under which the volume will be mounted | ||
mountPath: /tmp/foobar | ||
env: | ||
- name: HAB_REDIS | ||
# this is needed to make redis accept connections from other hosts | ||
# see https://redis.io/topics/security#protected-mode | ||
# NOTE: do not use this setting in a production environment | ||
value: '{ "protected-mode": "no" }' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a note of warning here. |
||
service: | ||
name: redis | ||
topology: leader | ||
# if not present, defaults to "default" | ||
group: foobar |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,7 +34,7 @@ rules: | |
- apiGroups: | ||
- apps | ||
resources: | ||
- deployments | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we not need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No I don't think so, as it's not the operator that's creating There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You were right btw, we did have to: the PV/PVC There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I am guessing as this is not needed anymore the above comment is not valid, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly. |
||
- statefulsets | ||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] | ||
- apiGroups: [""] | ||
resources: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,20 @@ type HabitatSpec struct { | |
// The EnvVar type is documented at https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#envvar-v1-core. | ||
// Optional. | ||
Env []corev1.EnvVar `json:"env,omitempty"` | ||
// Optional. | ||
PersistentStorage *PersistentStorage `json:"persistentStorage,omitempty"` | ||
} | ||
|
||
// PersistentStorage contains the details of the persistent storage that the | ||
// cluster should provision. | ||
type PersistentStorage struct { | ||
// Size is the volume's size. | ||
// It uses the same format as Kubernetes' size fields, e.g. 10Gi | ||
Size string `json:"size"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are missing the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean? Right now we only explicitly document that a field is optional, otherwise it's mandatory. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, just before in the docs.md file it was more clear at least to me, what is required. But if it makes sense to you 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAICT that's also how its' done in upstream. |
||
// MountPath is the path at which the PersistentVolume will be mounted. | ||
MountPath string `json:"mountPath"` | ||
// StorageClassName is the name of the StorageClass that the StatefulSet will request. | ||
StorageClassName string `json:"storageClassName"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Can we name this just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I gave it the same name it has in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool, that makes sense! |
||
} | ||
|
||
type HabitatStatus struct { | ||
|
@@ -102,6 +116,8 @@ const ( | |
|
||
TopologyStandalone Topology = "standalone" | ||
TopologyLeader Topology = "leader" | ||
|
||
HabitatKind = "Habitat" | ||
) | ||
|
||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the whole point of persistence is that you can mount already existing volumes, can you maybe write up some steps of how a user can do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I explicitly avoided to do that because it's a big topic and I would only make a poorer job at explaining it than the official docs do, which I linked. I anyway added some commits after your comment which should hopefully make things clearer.
BTW, it's not necessary that the PV has been created beforehand, if the cluster supports dynamic provisioning.
TL;DR: IMHO explaining how persistence works in Kubernetes is beside the scope of this README.