Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 7ec9635

Browse files
authored
Merge pull request #3 from rojanjose/master
Lab 1 instructions
2 parents 4eca5d5 + 01a98bc commit 7ec9635

File tree

8 files changed

+644
-21
lines changed

8 files changed

+644
-21
lines changed

workshop/Lab0/README.md

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,40 @@
1-
# Pre-work
2-
1+
# Lab 0: Pre-work
32

43
## 1. Setup Kubernetes environment
54

65
Run through the instructions listed [here](https://github.com/IBM/kube101/tree/master/workshop/Lab0)
76

8-
## 2. Download or clone the repo
7+
## 2. Cloud shell login.
8+
9+
## 3. Docker hub account.
10+
11+
Create a [dockerhub](https://hub.docker.com/) user and set the environment variable.
12+
```
13+
DOCKERUSER=<dockerhub useid>
14+
```
15+
16+
## 4. Set the cluster name
17+
18+
```
19+
ibmcloud ks clusters
20+
21+
OK
22+
Name ID State Created Workers Location Version Resource Group Name Provider
23+
user001-workshop bseqlkkd0o1gdqg4jc10 normal 3 months ago 5 Dallas 4.3.38_1544_openshift default classic
24+
25+
26+
CLUSTERNAME=use001-workshop
27+
```
28+
or
29+
30+
```
31+
CLUSTERNAME=`ibmcloud ks clusters | grep Name -A 1 | awk '{print $1}' | grep -v Name`
32+
33+
echo $CLUSTERNAME
34+
user001-workshop
35+
```
36+
37+
38+
39+
940

workshop/Lab1/README.md

Lines changed: 300 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,306 @@
1-
# Lab 1. Container storage and Kubernetes
1+
# Lab 1: Non-persistent storage with Kubernetes
22

3-
Expolore how local storage works on the pods.
4-
Mount it on Docker.
3+
Storing data in containers or worker nodes are considered as the [non-persistent](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#local-ephemeral-storage) forms of data storage.
4+
In this lab, we will explore storage options on the IBM Kubernetes worker nodes. Follow this [lab](https://github.com/remkohdev/docker101/tree/master/workshop/lab-3) is you are interested in learning more about container-based storage.
55

6-
The application is the [Guestbook App](https://github.com/IBM/guestbook), which is a sample multi-tier web application.
6+
The lab covers the following topics:
7+
- Create and claim IBM Kubernetes [non-persistent](https://cloud.ibm.com/docs/containers?topic=containers-storage_planning#non_persistent_overview) storage based on the primary and secondary storage available on the worker nodes.
8+
- Make the volumes available in the `Guestbook` application.
9+
- Use the volumes to store application cache and debug information.
10+
- Access the data from the guestbook container using the Kubernetes CLI.
11+
- Assess the impact of losing a pod on data retention.
12+
- Claim back the storage resources and clean up.
713

8-
## Scenario 1: Deploy the application using `kubectl`
14+
15+
The primary storage maps to the volume type `hostPath` and the secondary storage maps to `emptyDir`. Learn more about Kubernetes volume types [here](https://Kubernetes.io/docs/concepts/storage/volumes/).
16+
17+
## Reserve Persistent Volumes
18+
19+
From the cloud shell prompt, run the following commands to get the guestbook application and the kubernetes configuration needed for the storage labs.
920

1021
```bash
11-
git clone https://github.com/IBM/workshop-template
12-
cd workshop-template
22+
cd $HOME
23+
git clone --branch fs https://github.com/IBM/guestbook-nodejs.git
24+
git clone --branch storage https://github.com/rojanjose/guestbook-config.git
25+
cd $HOME/guestbook-config/storage
26+
```
27+
28+
Let's start with reserving the Persistent volume from the primary storage.
29+
Review the yaml file `pv-hostpath.yaml`. Note the values set for `type`, `storageClassName` and `hostPath`.
30+
31+
```console
32+
apiVersion: v1
33+
kind: PersistentVolume
34+
metadata:
35+
name: guestbook-primary-pv
36+
labels:
37+
type: local
38+
spec:
39+
storageClassName: manual
40+
capacity:
41+
storage: 10Gi
42+
accessModes:
43+
- ReadWriteOnce
44+
hostPath:
45+
path: "/mnt/data"
46+
```
47+
48+
Create the persistent volume as shown in the command below:
49+
```
50+
kubectl create -f pv-hostpath.yaml
51+
persistentvolume/guestbook-primary-pv created
52+
53+
kubectl get pv
54+
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
55+
guestbook-primary-pv 10Gi RWO Retain Available manual 13s
56+
```
57+
58+
Next
59+
PVC yaml:
60+
```
61+
apiVersion: v1
62+
kind: PersistentVolumeClaim
63+
metadata:
64+
name: guestbook-local-pvc
65+
spec:
66+
storageClassName: manual
67+
accessModes:
68+
- ReadWriteMany
69+
resources:
70+
requests:
71+
storage: 3Gi
72+
```
73+
74+
Create PVC:
75+
76+
```
77+
kubectl create -f guestbook-local-pvc.yaml
78+
persistentvolumeclaim/guestbook-local-pvc created
79+
❯ kubectl get pvc
80+
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
81+
guestbook-local-pvc Bound guestbook-local-pv 10Gi RWX manual 6s
82+
```
83+
84+
85+
## Guestbook application using storage
86+
87+
The application is the [Guestbook App](https://github.com/IBM/guestbook-nodejs), which is a simple multi-tier web application built using the loopback framework.
88+
89+
Change to the guestbook application source directory:
90+
91+
```
92+
cd $HOME/guestbook-nodejs/src
93+
```
94+
Review the source `common/models/entry.js`. The application uses storage allocated using `hostPath` to store data cache in the file `data/cache.txt`. The file `logs/debug.txt` records debug messages provisioned using the `emptyDir` storage type.
95+
96+
```source
97+
module.exports = function(Entry) {
98+
99+
Entry.greet = function(msg, cb) {
100+
101+
// console.log("testing " + msg);
102+
fs.appendFile('logs/debug.txt', "Received message: "+ msg +"\n", function (err) {
103+
if (err) throw err;
104+
console.log('Debug stagement printed');
105+
});
106+
107+
fs.appendFile('data/cache.txt', msg+"\n", function (err) {
108+
if (err) throw err;
109+
console.log('Saved in cache!');
110+
});
111+
112+
...
113+
```
114+
115+
Run the commands listed below to build the guestbook image and copy into the docker hub registry:
116+
117+
```
118+
cd $HOME/guestbook-nodejs/src
119+
docker build -t $DOCKERUSER/guestbook-nodejs:storage .
120+
docker login -u $DOCKERUSER
121+
docker push $DOCKERUSER/guestbook-nodejs:storage
122+
```
123+
124+
Review the deployment yaml file `guestbook-deplopyment.yaml` prior to deploying the application into the cluster.
125+
126+
```
127+
cd $HOME/guestbook-config/storage/lab1
128+
cat guestbook-deployment.yaml
129+
```
130+
131+
Replace the first part of `image` name with your docker hub user id.
132+
The section `spec.volumes` lists `hostPath` and `emptyDir` volumes. The section `spec.containers.volumeMounts` lists the mount paths that the application uses to write in the volumes.
133+
134+
```
135+
apiVersion: apps/v1
136+
kind: Deployment
137+
metadata:
138+
name: guestbook-v1
139+
labels:
140+
app: guestbook
141+
...
142+
spec:
143+
containers:
144+
- name: guestbook
145+
image: rojanjose/guestbook-nodejs:storage
146+
imagePullPolicy: Always
147+
ports:
148+
- name: http-server
149+
containerPort: 3000
150+
volumeMounts:
151+
- name: guestbook-primary-volume
152+
mountPath: /home/node/app/data
153+
- name: guestbook-secondary-volume
154+
mountPath: /home/node/app/logs
155+
volumes:
156+
- name: guestbook-primary-volume
157+
persistentVolumeClaim:
158+
claimName: guestbook-primary-pvc
159+
- name: guestbook-secondary-volume
160+
emptyDir: {}
161+
162+
163+
...
164+
```
165+
166+
Deploy the Guestbook application:
167+
168+
```
169+
kubectl create -f guestbook-deployment.yaml
170+
deployment.apps/guestbook-v1 created
171+
172+
kubectl get pods
173+
NAME READY STATUS RESTARTS AGE
174+
guestbook-v1-6f55cb54c5-jb89d 1/1 Running 0 14s
175+
176+
kubectl create -f guestbook-service.yaml
177+
service/guestbook created
178+
```
179+
180+
Find the URL for the guestbook application by joining the worker node external IP and service node port.
181+
182+
```
183+
HOSTNAME=`ibmcloud ks workers --cluster $CLUSTERNAME | grep Ready | head -n 1 | awk '{print $2}'`
184+
SERVICEPORT=`kubectl get svc guestbook -o=jsonpath='{.spec.ports[0].nodePort}'`
185+
echo "http://$HOSTNAME:$SERVICEPORT"
186+
```
187+
188+
Open the URL in a browser and create guest book entries.
189+
190+
![Guestbook entries](images/lab1-guestbook-entries.png)
191+
192+
Log into the pod:
193+
194+
```
195+
kubectl exec -it guestbook-v1-6f55cb54c5-jb89d bash
196+
197+
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
198+
199+
root@guestbook-v1-6f55cb54c5-jb89d:/home/node/app# ls -al
200+
total 256
201+
drwxr-xr-x 1 root root 4096 Nov 11 23:40 .
202+
drwxr-xr-x 1 node node 4096 Nov 11 23:20 ..
203+
-rw-r--r-- 1 root root 12 Oct 29 21:00 .dockerignore
204+
-rw-r--r-- 1 root root 288 Oct 29 21:00 .editorconfig
205+
-rw-r--r-- 1 root root 8 Oct 29 21:00 .eslintignore
206+
-rw-r--r-- 1 root root 27 Oct 29 21:00 .eslintrc
207+
-rw-r--r-- 1 root root 151 Oct 29 21:00 .gitignore
208+
-rw-r--r-- 1 root root 30 Oct 29 21:00 .yo-rc.json
209+
-rw-r--r-- 1 root root 105 Oct 29 21:00 Dockerfile
210+
drwxr-xr-x 2 root root 4096 Nov 11 03:40 client
211+
drwxr-xr-x 3 root root 4096 Nov 10 23:04 common
212+
drwxr-xr-x 2 root root 4096 Nov 11 23:16 data
213+
drwxrwxrwx 2 root root 4096 Nov 11 23:44 logs
214+
drwxr-xr-x 439 root root 16384 Nov 11 23:20 node_modules
215+
-rw-r--r-- 1 root root 176643 Nov 11 23:20 package-lock.json
216+
-rw-r--r-- 1 root root 830 Nov 11 23:20 package.json
217+
drwxr-xr-x 3 root root 4096 Nov 10 23:04 server
218+
219+
root@guestbook-v1-6f55cb54c5-jb89d:/home/node/app# cat data/cache.txt
220+
Hello Kubernetes!
221+
Hola Kubernetes!
222+
Zdravstvuyte Kubernetes!
223+
Nǐn hǎo Kubernetes!
224+
Goedendag Kubernetes!
225+
226+
root@guestbook-v1-6f55cb54c5-jb89d:/home/node/app# cat logs/debug.txt
227+
Received message: Hello Kubernetes!
228+
Received message: Hola Kubernetes!
229+
Received message: Zdravstvuyte Kubernetes!
230+
Received message: Nǐn hǎo Kubernetes!
231+
Received message: Goedendag Kubernetes!
232+
233+
234+
root@guestbook-v1-6f55cb54c5-jb89d:/home/node/app# df -h
235+
Filesystem Size Used Avail Use% Mounted on
236+
overlay 98G 3.5G 90G 4% /
237+
tmpfs 64M 0 64M 0% /dev
238+
tmpfs 7.9G 0 7.9G 0% /sys/fs/cgroup
239+
/dev/mapper/docker_data 98G 3.5G 90G 4% /etc/hosts
240+
shm 64M 0 64M 0% /dev/shm
241+
/dev/xvda2 25G 3.6G 20G 16% /home/node/app/data
242+
tmpfs 7.9G 16K 7.9G 1% /run/secrets/kubernetes.io/serviceaccount
243+
tmpfs 7.9G 0 7.9G 0% /proc/acpi
244+
tmpfs 7.9G 0 7.9G 0% /proc/scsi
245+
tmpfs 7.9G 0 7.9G 0% /sys/firmware
246+
247+
```
248+
249+
Kill the pod to see the impact of deleting the pod on data.
250+
251+
```
252+
kubectl get pods
253+
NAME READY STATUS RESTARTS AGE
254+
guestbook-v1-6f55cb54c5-jb89d 1/1 Running 0 12m
255+
256+
kubectl delete pod guestbook-v1-6f55cb54c5-jb89d
257+
pod "guestbook-v1-6f55cb54c5-jb89d" deleted
258+
259+
kubectl get pods
260+
NAME READY STATUS RESTARTS AGE
261+
guestbook-v1-5cbc445dc9-sx58j 1/1 Running 0 86s
262+
```
263+
264+
![Guestbook delete data](images/lab1-guestbook-data-deleted.png)
265+
266+
Enter new data:
267+
![Guestbook reload](images/lab1-guestbook-data-reload.png)
268+
269+
Log into the pod to view the state of the data.
270+
271+
```
272+
kubectl get pods
273+
NAME READY STATUS RESTARTS AGE
274+
guestbook-v1-5cbc445dc9-sx58j 1/1 Running 0 86s
275+
276+
kubectl exec -it guestbook-v1-5cbc445dc9-sx58j bash
277+
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
278+
279+
root@guestbook-v1-5cbc445dc9-sx58j:/home/node/app# cat data/cache.txt
280+
Hello Kubernetes!
281+
Hola Kubernetes!
282+
Zdravstvuyte Kubernetes!
283+
Nǐn hǎo Kubernetes!
284+
Goedendag Kubernetes!
285+
Bye Kubernetes!
286+
Aloha Kubernetes!
287+
Ciao Kubernetes!
288+
Sayonara Kubernetes!
289+
290+
root@guestbook-v1-5cbc445dc9-sx58j:/home/node/app# cat logs/debug.txt
291+
Received message: Bye Kubernetes!
292+
Received message: Aloha Kubernetes!
293+
Received message: Ciao Kubernetes!
294+
Received message: Sayonara Kubernetes!
295+
root@guestbook-v1-5cbc445dc9-sx58j:/home/node/app#
296+
```
297+
298+
This shows that the storage type `emptyDir` loose data on a pod restart whereas `hostPath` data lives until the worker node or cluster is deleted.
299+
300+
301+
## Clean up
302+
13303
```
304+
cd $HOME/guestbook-config/storage/lab1
305+
kubectl delete -f .
306+
```
107 KB
Loading
182 KB
Loading
198 KB
Loading

0 commit comments

Comments
 (0)