├── .gitignore
├── README.md
├── rbac
├── rolebinding.yml
├── README.md
├── role.yml
└── init.sh
├── persistent-volume
├── minikube
│ ├── pv-claim.yaml
│ ├── pv.yaml
│ ├── statefulset-restore.yaml
│ ├── statefulset.yaml
│ └── demo.sh
├── aws
│ ├── pv-claim.yaml
│ ├── pv.yaml
│ ├── statefulset-restore.yaml
│ ├── statefulset.yaml
│ └── demo.sh
└── util.sh
├── apps
├── busybox.yml
├── nginx.yaml
└── joatmon08-hello.yaml
├── LICENSE.md
└── logging
└── fluentd_daemonset.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | *.crt
2 | *.csr
3 | *.key
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # kubernetes-reference
2 | References outlining some key Kubernetes deployments/constructs.
3 |
--------------------------------------------------------------------------------
/rbac/rolebinding.yml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: RoleBinding
3 | apiVersion: rbac.authorization.k8s.io/v1beta1
4 | metadata:
5 | name: deployment-manager-binding
6 | namespace: test
7 | subjects:
8 | - kind: User
9 | name: joatmon08
10 | apiGroup: ""
11 | roleRef:
12 | kind: Role
13 | name: deployment-manager
14 | apiGroup: ""
15 |
--------------------------------------------------------------------------------
/persistent-volume/minikube/pv-claim.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: PersistentVolumeClaim
3 | apiVersion: v1
4 | metadata:
5 | name: www-claim
6 | spec:
7 | storageClassName: standard
8 | accessModes:
9 | - ReadWriteOnce
10 | resources:
11 | requests:
12 | storage: 1Gi
13 | volumeName: pvc-f2617ebf-3e0b-11e8-b2b3-080027732cee
--------------------------------------------------------------------------------
/persistent-volume/aws/pv-claim.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: PersistentVolumeClaim
4 | metadata:
5 | labels:
6 | app: hello-stateful
7 | name: joatmon08-pvc
8 | spec:
9 | accessModes:
10 | - ReadWriteOnce
11 | resources:
12 | requests:
13 | storage: 1Gi
14 | storageClassName: gp2
15 | volumeName: joatmon08-pv
16 |
--------------------------------------------------------------------------------
/persistent-volume/aws/pv.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: PersistentVolume
4 | metadata:
5 | name: joatmon08-pv
6 | spec:
7 | storageClassName: gp2
8 | accessModes:
9 | - ReadWriteOnce
10 | capacity:
11 | storage: 1Gi
12 | persistentVolumeReclaimPolicy: Delete
13 | awsElasticBlockStore:
14 | fsType: ext4
15 | volumeID: aws://{{ AWS region }}/{{ volume ID }}
16 |
--------------------------------------------------------------------------------
/persistent-volume/minikube/pv.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: PersistentVolume
3 | apiVersion: v1
4 | metadata:
5 | name: pvc-f2617ebf-3e0b-11e8-b2b3-080027732cee
6 | spec:
7 | storageClassName: standard
8 | accessModes:
9 | - ReadWriteOnce
10 | capacity:
11 | storage: 1Gi
12 | persistentVolumeReclaimPolicy: Delete
13 | hostPath:
14 | path: "/tmp/hostpath-provisioner/pvc-f2617ebf-3e0b-11e8-b2b3-080027732cee"
--------------------------------------------------------------------------------
/apps/busybox.yml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: apps/v1
3 | kind: Deployment
4 | metadata:
5 | name: busybox
6 | labels:
7 | app: busybox
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: busybox
13 | template:
14 | metadata:
15 | labels:
16 | app: busybox
17 | spec:
18 | containers:
19 | - name: busybox
20 | image: busybox
21 | command:
22 | - "sleep"
23 | - "3600"
24 |
--------------------------------------------------------------------------------
/rbac/README.md:
--------------------------------------------------------------------------------
1 | # k8s-rbac
2 | This is a reference for implementing RBAC for a user, limited to a
3 | specific namespace.
4 |
5 | ## Usage
6 | * Run `./init.sh $CERT_PATH $CLUSTER $NAMESPACE $USERNAME`
7 | * Update role.yml and rolebinding.yml with the correct namespace
8 | and users.
9 | * Apply to the cluster.
10 | ```
11 | kubectl apply -f role.yml
12 | kubectl delete -f rolebinding.yml
13 | ```
14 | * To use the context, add the `--context` option.
15 | ```
16 | kubectl --context=$USERNAME-context get pods
17 | ```
18 |
--------------------------------------------------------------------------------
/rbac/role.yml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: Role
3 | apiVersion: rbac.authorization.k8s.io/v1beta1
4 | metadata:
5 | namespace: test
6 | name: deployment-manager
7 | rules:
8 | - apiGroups: ["", "extensions", "apps"]
9 | resources: ["deployments", "replicasets"]
10 | verbs: ["get", "list", "create", "delete", "update"]
11 | - apiGroups: [""]
12 | resources: ["services", "secrets", "configmaps"]
13 | verbs: ["get", "list", "create", "delete"]
14 | - apiGroups: [""]
15 | resources: ["pods"]
16 | verbs: ["get", "list"]
17 |
--------------------------------------------------------------------------------
/apps/nginx.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: apps/v1beta2
3 | kind: Deployment
4 | metadata:
5 | name: nginx
6 | spec:
7 | selector:
8 | matchLabels:
9 | run: nginx
10 | replicas: 1
11 | template:
12 | metadata:
13 | labels:
14 | run: nginx
15 | spec:
16 | containers:
17 | - name: nginx
18 | image: nginx
19 | ports:
20 | - containerPort: 80
21 | ---
22 | apiVersion: v1
23 | kind: Service
24 | metadata:
25 | name: nginx
26 | labels:
27 | run: nginx
28 | spec:
29 | ports:
30 | - port: 80
31 | selector:
32 | run: nginx
--------------------------------------------------------------------------------
/rbac/init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ $# -ne 4 ]; then
4 | echo "Got ${#} arguments"
5 | exit 1
6 | fi
7 |
8 | CERT_PATH=$1
9 | CLUSTER=$2
10 | NAMESPACE=$3
11 | USERNAME=$4
12 |
13 | client_cert=$1/$2/ca.crt
14 | client_key=$1/$2/ca.key
15 |
16 | kubectl create namespace $NAMESPACE
17 | openssl genrsa -out user.key 4096
18 | openssl req -new -key user.key -out user.csr -subj "/CN=$USERNAME/O=developer"
19 | openssl x509 -req -in user.csr -CA $client_cert -CAkey $client_key -CAcreateserial -out user.crt -days 10
20 | kubectl config set-credentials $USERNAME --client-certificate=user.crt --client-key=user.key
21 | kubectl config set-context $USERNAME-context --cluster=$CLUSTER --namespace=$NAMESPACE --user=$USERNAME
22 |
--------------------------------------------------------------------------------
/apps/joatmon08-hello.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1beta2
2 | kind: Deployment
3 | metadata:
4 | name: joatmon08-hello
5 | spec:
6 | selector:
7 | matchLabels:
8 | run: joatmon08-hello
9 | replicas: 1
10 | template:
11 | metadata:
12 | labels:
13 | run: joatmon08-hello
14 | spec:
15 | containers:
16 | - name: joatmon08-hello
17 | image: joatmon08/hello
18 | ports:
19 | - containerPort: 8001
20 | protocol: TCP
21 | name: http
22 | - containerPort: 8002
23 | protocol: TCP
24 | name: metric
25 | ---
26 | apiVersion: v1
27 | kind: Service
28 | metadata:
29 | name: joatmon08-hello
30 | labels:
31 | run: joatmon08-hello
32 | spec:
33 | ports:
34 | - port: 8001
35 | protocol: TCP
36 | name: http
37 | - port: 8002
38 | protocol: TCP
39 | name: metric
40 | selector:
41 | run: joatmon08-hello
--------------------------------------------------------------------------------
/persistent-volume/aws/statefulset-restore.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: Service
4 | metadata:
5 | name: hello-stateful
6 | labels:
7 | app: hello-stateful
8 | spec:
9 | clusterIP: None
10 | selector:
11 | app: hello-stateful
12 | ---
13 | apiVersion: apps/v1
14 | kind: StatefulSet
15 | metadata:
16 | name: hello-stateful
17 | spec:
18 | selector:
19 | matchLabels:
20 | app: hello-stateful
21 | serviceName: hello-stateful
22 | replicas: 1
23 | template:
24 | metadata:
25 | labels:
26 | app: hello-stateful
27 | spec:
28 | terminationGracePeriodSeconds: 10
29 | containers:
30 | - name: hello-stateful
31 | image: joatmon08/hello-stateful:1.0
32 | volumeMounts:
33 | - name: log
34 | mountPath: /usr/share/hello
35 | volumes:
36 | - name: log
37 | persistentVolumeClaim:
38 | claimName: joatmon08-pvc
--------------------------------------------------------------------------------
/persistent-volume/minikube/statefulset-restore.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: Service
4 | metadata:
5 | name: nginx
6 | labels:
7 | app: nginx
8 | spec:
9 | ports:
10 | - port: 80
11 | name: web
12 | clusterIP: None
13 | selector:
14 | app: nginx
15 | ---
16 | apiVersion: apps/v1
17 | kind: StatefulSet
18 | metadata:
19 | name: web
20 | spec:
21 | selector:
22 | matchLabels:
23 | app: nginx
24 | serviceName: "nginx"
25 | replicas: 1
26 | template:
27 | metadata:
28 | labels:
29 | app: nginx
30 | spec:
31 | terminationGracePeriodSeconds: 10
32 | containers:
33 | - name: nginx
34 | image: k8s.gcr.io/nginx-slim:0.8
35 | ports:
36 | - containerPort: 80
37 | name: web
38 | volumeMounts:
39 | - name: www
40 | mountPath: /usr/share/nginx/html
41 | volumes:
42 | - name: www
43 | persistentVolumeClaim:
44 | claimName: www-claim
--------------------------------------------------------------------------------
/persistent-volume/aws/statefulset.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: Service
4 | metadata:
5 | name: hello-stateful
6 | labels:
7 | app: hello-stateful
8 | spec:
9 | clusterIP: None
10 | selector:
11 | app: hello-stateful
12 | ---
13 | apiVersion: apps/v1
14 | kind: StatefulSet
15 | metadata:
16 | name: hello-stateful
17 | spec:
18 | selector:
19 | matchLabels:
20 | app: hello-stateful
21 | serviceName: hello-stateful
22 | replicas: 1
23 | template:
24 | metadata:
25 | labels:
26 | app: hello-stateful
27 | spec:
28 | terminationGracePeriodSeconds: 10
29 | containers:
30 | - name: hello-stateful
31 | image: joatmon08/hello-stateful:1.0
32 | volumeMounts:
33 | - name: log
34 | mountPath: /usr/share/hello
35 | volumeClaimTemplates:
36 | - metadata:
37 | name: log
38 | spec:
39 | accessModes: [ "ReadWriteOnce" ]
40 | storageClassName: gp2
41 | resources:
42 | requests:
43 | storage: 1Gi
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2018 Rosemary Wang
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/persistent-volume/minikube/statefulset.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: Service
4 | metadata:
5 | name: nginx
6 | labels:
7 | app: nginx
8 | spec:
9 | ports:
10 | - port: 80
11 | name: web
12 | clusterIP: None
13 | selector:
14 | app: nginx
15 | ---
16 | apiVersion: apps/v1
17 | kind: StatefulSet
18 | metadata:
19 | name: web
20 | spec:
21 | selector:
22 | matchLabels:
23 | app: nginx
24 | serviceName: "nginx"
25 | replicas: 1
26 | template:
27 | metadata:
28 | labels:
29 | app: nginx
30 | spec:
31 | terminationGracePeriodSeconds: 10
32 | containers:
33 | - name: nginx
34 | image: k8s.gcr.io/nginx-slim:0.8
35 | ports:
36 | - containerPort: 80
37 | name: web
38 | volumeMounts:
39 | - name: www
40 | mountPath: /usr/share/nginx/html
41 | volumeClaimTemplates:
42 | - metadata:
43 | name: www
44 | spec:
45 | accessModes: [ "ReadWriteOnce" ]
46 | storageClassName: standard
47 | resources:
48 | requests:
49 | storage: 1Gi
--------------------------------------------------------------------------------
/logging/fluentd_daemonset.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: ConfigMap
4 | metadata:
5 | name: fluentdconf
6 | namespace: kube-system
7 | data:
8 | fluent.conf: |
9 |
10 | @type null
11 |
12 |
13 |
14 | @type tail
15 | path /var/log/containers/*.log
16 | pos_file /var/log/fluentd-containers.log.pos
17 | time_format %Y-%m-%dT%H:%M:%S.%NZ
18 | tag kubernetes.*
19 | format json
20 | read_from_head true
21 |
22 |
23 |
24 | @type kubernetes_metadata
25 |
26 |
27 |
28 | @type null
29 |
30 |
31 |
32 | @type null
33 |
34 |
35 |
36 | @type stdout
37 |
38 | ---
39 | apiVersion: extensions/v1beta1
40 | kind: DaemonSet
41 | metadata:
42 | name: fluentd
43 | namespace: kube-system
44 | labels:
45 | k8s-app: fluentd-logging
46 | version: v1
47 | kubernetes.io/cluster-service: "true"
48 | spec:
49 | template:
50 | metadata:
51 | labels:
52 | k8s-app: fluentd-logging
53 | version: v1
54 | kubernetes.io/cluster-service: "true"
55 | spec:
56 | tolerations:
57 | - key: node-role.kubernetes.io/master
58 | effect: NoSchedule
59 | containers:
60 | - name: fluentd
61 | image: fluent/fluentd-kubernetes-daemonset:v0.12-alpine-elasticsearch
62 | resources:
63 | limits:
64 | memory: 200Mi
65 | requests:
66 | cpu: 100m
67 | memory: 200Mi
68 | volumeMounts:
69 | - name: fluentconfig
70 | mountPath: /fluentd/etc/
71 | - name: varlog
72 | mountPath: /var/log
73 | - name: varlibdockercontainers
74 | mountPath: /var/lib/docker/containers
75 | readOnly: true
76 | terminationGracePeriodSeconds: 30
77 | volumes:
78 | - name: fluentconfig
79 | configMap:
80 | name: fluentdconf
81 | - name: varlog
82 | hostPath:
83 | path: /var/log
84 | - name: varlibdockercontainers
85 | hostPath:
86 | path: /var/lib/docker/containers
87 |
--------------------------------------------------------------------------------
/persistent-volume/util.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2016 The Kubernetes Authors All rights reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | readonly reset=$(tput sgr0)
17 | readonly green=$(tput bold; tput setaf 2)
18 | readonly yellow=$(tput bold; tput setaf 3)
19 | readonly blue=$(tput bold; tput setaf 6)
20 | readonly timeout=$(if [ "$(uname)" == "Darwin" ]; then echo "1"; else echo "0.1"; fi)
21 | readonly ipv6regex='(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))'
22 |
23 | function desc() {
24 | maybe_first_prompt
25 | echo "$blue# $@$reset"
26 | prompt
27 | }
28 |
29 | function desc_rate() {
30 | maybe_first_prompt
31 | rate=30
32 | if [ -n "$DEMO_RUN_FAST" ]; then
33 | rate=1000
34 | fi
35 | echo "$blue# $@$reset" | pv -qL $rate
36 | prompt
37 | }
38 |
39 | function prompt() {
40 | echo -n "$yellow\$ $reset"
41 | }
42 |
43 | started=""
44 | function maybe_first_prompt() {
45 | if [ -z "$started" ]; then
46 | prompt
47 | started=true
48 | fi
49 | }
50 |
51 | # After a `run` this variable will hold the stdout of the command that was run.
52 | # If the command was interactive, this will likely be garbage.
53 | DEMO_RUN_STDOUT=""
54 |
55 | function run() {
56 | maybe_first_prompt
57 | rate=50
58 | if [ -n "$DEMO_RUN_FAST" ]; then
59 | rate=1000
60 | fi
61 | echo "$green$1$reset" | pv -qL $rate
62 | if [ -n "$DEMO_RUN_FAST" ]; then
63 | sleep 0.5
64 | fi
65 | OFILE="$(mktemp -t $(basename $0).XXXXXX)"
66 | script -q "$OFILE" /bin/bash -c "$1"
67 | r=$?
68 | read -d '' -t "${timeout}" -n 10000 # clear stdin
69 | prompt
70 | if [ -z "$DEMO_AUTO_RUN" ]; then
71 | read -s
72 | fi
73 | DEMO_RUN_STDOUT="$(tail -n +2 $OFILE | sed 's/\r//g')"
74 | return $r
75 | }
76 |
77 | function relative() {
78 | for arg; do
79 | echo "$(realpath $(dirname $(which $0)))/$arg" | sed "s|$(realpath $(pwd))|.|"
80 | done
81 | }
82 |
83 | trap "echo" EXIT
84 |
--------------------------------------------------------------------------------
/persistent-volume/aws/demo.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | . ../util.sh
3 |
4 | desc "Create the StatefulSet."
5 | run "kubectl apply -f statefulset.yaml"
6 |
7 | volume=$(kubectl get pvc | grep hello | tail -n 1 | cut -d' ' -f9)
8 | pvc=$(kubectl get pvc | grep hello | tail -n 1 | cut -d' ' -f1)
9 | pod=$(kubectl get pods | grep hello | cut -d' ' -f1)
10 |
11 | desc "Get the output of the stateful.log file."
12 | run "kubectl exec ${pod} -- cat /usr/share/hello/stateful.log"
13 |
14 | desc "Delete the StatefulSet."
15 | run "kubectl delete -f statefulset.yaml --ignore-not-found"
16 |
17 | desc "Does the volume and claim still exist?"
18 | run "kubectl get pv"
19 | run "kubectl get pvc"
20 | run "kubectl get statefulsets"
21 | desc "Yes, the volume and claim still exist!"
22 |
23 | desc "Let's bring the StatefulSet back up."
24 | run "kubectl apply -f statefulset.yaml"
25 |
26 | desc "Does the volume get reattached?"
27 | desc "Let's check the statefulset.log for previous log messages."
28 | run "kubectl exec ${pod} -- cat /usr/share/hello/stateful.log"
29 | desc "Yes, the volume is reattached."
30 |
31 | desc "We'll back up the volume with an AWS snapshot."
32 | volumeID=$(kubectl get pv ${volume} -o jsonpath='{.spec.awsElasticBlockStore.volumeID}' | cut -d'/' -f4)
33 | run "aws ec2 create-snapshot --volume-id ${volumeID} --region=${REGION}"
34 |
35 | desc "Let's capture the last known written log file line."
36 | lastline=$(kubectl exec ${pod} -- cat /usr/share/hello/stateful.log | tail -n 1)
37 |
38 | desc "Let's delete the statefulset, but keep the pvc & pv."
39 | run "kubectl delete -f statefulset.yaml"
40 | desc "And let's delete the backend volume, as if something went wrong."
41 | run "aws ec2 delete-volume --volume-id ${volumeID} --region=${REGION}"
42 |
43 | desc "What happens when I access my stateful logs?"
44 | run "kubectl exec ${pod} -- cat /usr/share/hello/stateful.log"
45 |
46 | desc "Oh no!"
47 | run "kubectl get pvc"
48 | run "kubectl get pv"
49 |
50 | desc "But yet the pvc and pv are still there..."
51 |
52 | desc "There's a possibility that we can create a new statefulset and reattach the volume."
53 | desc "Let's restore the volume with our snapshot."
54 | run "aws ec2 create-volume --availability-zone=${REGION}a --snapshot-id ${snapshotID} --region=${REGION} --volume-type gp2 --tag-specifications 'ResourceType=volume,Tags=[{Key=KubernetesCluster,Value=joatmon08.k8s.local}]'"
55 |
56 | desc "Let's add the new volume ID to the pv.yaml and create it."
57 | desc "!!!! BE SURE TO ADD THE AWS REGION AND VOLUME ID TO THE pv.yaml FILE !!!!"
58 | run "kubectl apply -f pv.yaml"
59 |
60 | desc "Let's apply the pv claim."
61 | run "kubectl apply -f pv-claim.yaml"
62 |
63 | desc "We'll delete the old pvc and pv."
64 | run "kubectl delete pvc ${pvc}"
65 | run "kubectl delete pv ${volume}"
66 |
67 | desc "Let's create the StatefulSet."
68 | run "kubectl apply -f statefulset-restore.yaml"
69 |
70 | desc "Does it show the original state?"
71 | run "kubectl exec ${pod} -- cat /usr/share/hello/stateful.log"
72 | desc "YES!"
73 |
74 | desc "Let's delete everything now."
75 | run "kubectl delete -f statefulset.yaml --ignore-not-found"
76 | run "kubectl delete -f statefulset-restore.yaml --ignore-not-found"
77 | run "kubectl delete -f pv.yaml --ignore-not-found"
78 | run "kubectl delete -f pv-claim.yaml --ignore-not-found"
79 |
--------------------------------------------------------------------------------
/persistent-volume/minikube/demo.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | . ../util.sh
3 |
4 | desc "Create the StatefulSet."
5 | run "kubectl apply -f statefulset.yaml"
6 |
7 | volume=$(kubectl get pvc | grep www | tail -n 1 | cut -d' ' -f9)
8 | minikube_ip=$(minikube ip)
9 | token=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | xargs)
10 |
11 | desc "Put some text for nginx to serve."
12 | run "ssh -i ~/.minikube/machines/minikube/id_rsa docker@${minikube_ip} sudo 'echo Hello! > /tmp/hostpath-provisioner/"${volume}"/index.html'"
13 |
14 | desc "Let's make a call to the nginx web server."
15 | run "curl -k -H 'Authorization:Bearer ${token}' https://${minikube_ip}:8443/api/v1/namespaces/default/services/nginx:web/proxy/"
16 |
17 | desc "Delete the StatefulSet."
18 | run "kubectl delete -f statefulset.yaml --ignore-not-found"
19 |
20 | desc "Does the volume and claim still exist?"
21 | run "kubectl get pv"
22 | run "kubectl get pvc"
23 | run "kubectl get statefulsets"
24 | run "ssh -i ~/.minikube/machines/minikube/id_rsa docker@${minikube_ip} cat /tmp/hostpath-provisioner/${volume}/index.html"
25 | desc "Yes, the volume and claim still exist!"
26 |
27 | desc "Let's bring the StatefulSet back up."
28 | run "kubectl apply -f statefulset.yaml"
29 |
30 | desc "Does the volume get reattached?"
31 | desc "Let's make a call to the nginx web server."
32 | run "curl -k -H 'Authorization:Bearer ${token}' https://${minikube_ip}:8443/api/v1/namespaces/default/services/nginx:web/proxy/"
33 | desc "Yes, the volume is reattached."
34 |
35 | desc "We'll back up the volume."
36 | run "ssh -i ~/.minikube/machines/minikube/id_rsa docker@${minikube_ip} sudo cp -r /tmp/hostpath-provisioner/${volume} /tmp/${volume}-backup"
37 |
38 | desc "Let's delete the backend volume, as if something went wrong."
39 | run "ssh -i ~/.minikube/machines/minikube/id_rsa docker@${minikube_ip} sudo rm -rf /tmp/hostpath-provisioner/${volume}"
40 |
41 | desc "Let's make a call to the nginx web server."
42 | run "curl -k -H 'Authorization:Bearer ${token}' https://${minikube_ip}:8443/api/v1/namespaces/default/services/nginx:web/proxy/"
43 |
44 | desc "Oh no!"
45 | run "kubectl get pvc"
46 | run "kubectl get pv"
47 |
48 | desc "But yet the pvc and pv are still there..."
49 | desc "Let's get more details on the actual persistent volume."
50 | desc "Notice the HostPath that is specified."
51 | run "kubectl describe pv ${volume}"
52 |
53 | desc "There's a possibility that we can still fix the volume."
54 | desc "Let's restore the volume, with our original index.html."
55 | run "ssh -i ~/.minikube/machines/minikube/id_rsa docker@${minikube_ip} sudo cp -r /tmp/${volume}-backup /tmp/hostpath-provisioner/${volume}"
56 |
57 | desc "The permissions need to be read/write/execute."
58 | run "ssh -i ~/.minikube/machines/minikube/id_rsa docker@${minikube_ip} sudo chmod 777 /tmp/hostpath-provisioner/${volume}"
59 |
60 | desc "Just in case, we'll check the claim and the volume."
61 | run "kubectl get pvc"
62 | run "kubectl get pv"
63 |
64 | desc "Let's make a call to the nginx web server."
65 | run "curl -k -H 'Authorization:Bearer ${token}' https://${minikube_ip}:8443/api/v1/namespaces/default/services/nginx:web/proxy/"
66 |
67 | desc "Interesting, it didn't work. Maybe the pod needs to be restarted?"
68 | run "kubectl delete pod web-0"
69 |
70 | desc "Let's check if the pod came back up."
71 | run "kubectl get pods"
72 |
73 | desc "Let's make a call to the nginx web server."
74 | run "curl -k -H 'Authorization:Bearer ${token}' https://${minikube_ip}:8443/api/v1/namespaces/default/services/nginx:web/proxy/"
75 |
76 | desc "Let's delete everything now."
77 | run "kubectl delete -f statefulset.yaml --ignore-not-found"
78 | run "kubectl delete pv ${volume}"
79 | run "kubectl delete pvc $(kubectl get pvc | grep web | cut -d' ' -f1)"
--------------------------------------------------------------------------------