Kubernetes Basics - Part III
Info
This workshop segment expect you to be inside a cloned repository of k8s-specs
.
| git clone https://github.com/vfarcic/k8s-specs.git
cd k8s-specs
|
Points to cover
- Persisting State
- Deploying Stateful Applications At Scale
Persisting State
Without state preservation
| kubectl create -f pv/jenkins-no-pv.yml --record --save-config
|
| kubectl -n jenkins get events
|
| kubectl -n jenkins create secret generic jenkins-creds \
--from-literal=jenkins-user=jdoe \
--from-literal=jenkins-pass=incognito
|
| kubectl -n jenkins rollout status deployment jenkins
|
Retrieve Jenkins Address
Log into Jenkins
Warning
If you're on windows, open
probably doesn't work.
Copy paste the url printed and open that in a browser.
| echo $JENKINS_ADDR
open "http://$JENKINS_ADDR/jenkins"
|
- use
jdoe
as username and incognito
as password
- create a job, doesn't matter what
Kill the pod
| kubectl -n jenkins get pods --selector=app=jenkins -o json
|
| POD_NAME=$(kubectl -n jenkins get pods --selector=app=jenkins \
-o jsonpath="{.items[*].metadata.name}")
|
| kubectl -n jenkins exec -it $POD_NAME pkill java
|
| echo "http://$JENKINS_ADDR/jenkins"
open "http://$JENKINS_ADDR/jenkins"
|
Create Volume
GKE
| gcloud compute instances list --filter="name:('${CLUSTER_NAME}')" \
--format 'csv[no-heading](zone)' | tee zones
|
| AZ_1=$(cat zones | head -n 1)
|
| AZ_2=$(cat zones | tail -n 2 | head -n 1)
|
| AZ_3=$(cat zones | tail -n 1)
|
Replace ???
with your name to make sure the disk name is unique.
| gcloud compute disks create ${PREFIX}-disk1 --zone $AZ_1
|
| gcloud compute disks create ${PREFIX}-disk2 --zone $AZ_2
|
| gcloud compute disks create ${PREFIX}-disk3 --zone $AZ_3
|
Warning
Later commands will depend on these variables.
So stay in the same console session or make sure you recreate these!
| VOLUME_ID_1=${PREFIX}-disk1
VOLUME_ID_2=${PREFIX}-disk2
VOLUME_ID_3=${PREFIX}-disk3
|
| gcloud compute disks describe VOLUME_ID_1
|
EKS
...
Create Persistent Volume
GKE
| YAML=pv/pv-gke.yml
cat $YAML
|
| cat $YAML \
| sed -e "s@REPLACE_ME_1@$VOLUME_ID_1@g" \
| sed -e "s@REPLACE_ME_2@$VOLUME_ID_2@g" \
| sed -e "s@REPLACE_ME_3@$VOLUME_ID_3@g" \
| kubectl create -f - --save-config --record
|
Claim Persistent Volume
| kubectl create -f pv/pvc.yml --save-config --record
|
| kubectl -n jenkins get pvc
|
Attach PVC
| kubectl apply -f pv/jenkins-pv.yml --record
|
| kubectl -n jenkins rollout status deployment jenkins
|
Demonstrate the persistent part
- open Jenkins
open "http://$JENKINS_ADDR/jenkins"
- create a job
| POD_NAME=$(kubectl -n jenkins get pod --selector=app=jenkins \
-o jsonpath="{.items[*].metadata.name}")
|
| kubectl -n jenkins exec -it $POD_NAME pkill java
|
Let's delete Jenkins' deployment.
| kubectl -n jenkins delete deploy jenkins
|
Confirm it is gone.
| kubectl get all -n jenkins
|
Now, let's recreate Jenkins.
| kubectl apply -f pv/jenkins-pv.yml --record
|
| kubectl -n jenkins rollout status deployment jenkins
|
- confirm job is still there
- open Jenkins
open "http://$JENKINS_ADDR/jenkins"
| kubectl -n jenkins get pvc
|
Cleanup
Storage Classes
View
Create
Use
Use 2
Use Default
| cat pv/jenkins-default.yml
|
| diff pv/jenkins-dynamic.yml pv/jenkins-default.yml
|
| kubectl apply -f pv/jenkins-default.yml --record
|
Prepare alternative SC
Create alternative SC
| kubectl create -f pv/$YAML
|
Use alternative SC
Cleanup
| kubectl delete ns jenkins
|
StatefulSet
Create StatefulSwet
| kubectl apply -f sts/jenkins.yml --record
|
| kubectl -n jenkins rollout status sts jenkins
|
| kubectl -n jenkins get pvc
|
| kubectl -n jenkins get pv
|
Get Jenkins Address
Use Jenkins
| open "http://$JENKINS_ADDR/jenkins"
|
| kubectl delete ns jenkins
|
Use DB without STS
| cat sts/go-demo-3-deploy.yml
|
| kubectl apply -f sts/go-demo-3-deploy.yml --record
|
| kubectl -n go-demo-3 rollout status deployment api
|
| kubectl -n go-demo-3 get pods
|
| DB_1=$(kubectl -n go-demo-3 get pods -l app=db \
-o jsonpath="{.items[0].metadata.name}")
|
| DB_2=$(kubectl -n go-demo-3 get pods -l app=db \
-o jsonpath="{.items[1].metadata.name}")
|
Investigate problems
| kubectl -n go-demo-3 logs $DB_1
|
| kubectl -n go-demo-3 logs $DB_2
|
| kubectl delete ns go-demo-3
|
Use DB with STS
| cat sts/go-demo-3-sts.yml
|
| kubectl apply -f sts/go-demo-3-sts.yml --record
|
| kubectl -n go-demo-3 get pods
|
If we want MongoDB to use the three instances as single dataplane, we have to tell it the dataplane members.
First, we shell into one of the db containers via exec
.
| kubectl -n go-demo-3 exec -it db-0 -- sh
|
Then, make sure we're talking with MongoDB, via its REPL, with mongo
.
And finally we explain MongoDB what we want to do.
| rs.initiate( {
_id : "rs0",
members: [
{_id: 0, host: "db-0.db:27017"},
{_id: 1, host: "db-1.db:27017"},
{_id: 2, host: "db-2.db:27017"}
]
})
|
Let's confirm with MongoDB before we exit the container.
And now you're free to exit the MongoDB REPL and the container via ctrl+d
(so twice).
| kubectl -n go-demo-3 get pods
|
Observe update process
| diff sts/go-demo-3-sts.yml sts/go-demo-3-sts-upd.yml
|
| kubectl apply -f sts/go-demo-3-sts-upd.yml --record
|
| kubectl -n go-demo-3 get pods
|
Cleanup
| kubectl delete ns go-demo-3
|