Kubernetes Basics - Parts II

Info

This workshop segment expect you to be inside a cloned repository of k8s-specs.

1
2
git clone https://github.com/vfarcic/k8s-specs.git
cd k8s-specs

Points to cover

  • Using ConfigMaps To Inject Configuration Files
  • Using Secrets To Hide Confidential Information
  • Dividing A Cluster Into Namespaces
  • Securing Kubernetes Clusters
  • Managing Resources

ConfigMap

Create from files

1
2
kubectl create cm my-config --from-file=cm/prometheus-conf.yml \
    --from-file=cm/prometheus.yml
1
cat cm/alpine.yml
1
kubectl create -f cm/alpine.yml
1
kubectl exec -it alpine -- ls /etc/config
1
kubectl exec -it alpine -- cat /etc/config/prometheus-conf.yml
1
kubectl delete -f cm/alpine.yml
1
kubectl delete cm my-config

Create from literals

1
2
kubectl create cm my-config \
    --from-literal=something=else --from-literal=weather=sunny
1
kubectl create -f cm/alpine.yml
1
kubectl exec -it alpine -- ls /etc/config
1
kubectl exec -it alpine -- cat /etc/config/something
1
kubectl delete -f cm/alpine.yml
1
kubectl delete cm my-config

Create from environment files

1
cat cm/my-env-file.yml
1
kubectl create cm my-config --from-env-file=cm/my-env-file.yml
1
kubectl get cm my-config -o yaml

Secrets

Generic secrets

1
2
kubectl create secret generic my-creds \
    --from-literal=username=jdoe --from-literal=password=incognito
1
kubectl get secrets
1
kubectl get secret my-creds -o json
1
2
kubectl get secret my-creds -o jsonpath="{.data.username}" \
    | base64 --decode
1
2
kubectl get secret my-creds -o jsonpath="{.data.password}" \
    | base64 --decode
1
cat secret/jenkins.yml
1
kubectl apply -f secret/jenkins.yml
1
kubectl rollout status deploy jenkins
1
2
POD_NAME=$(kubectl get pods -l service=jenkins,type=master \
    -o jsonpath="{.items[*].metadata.name}")
1
kubectl exec -it $POD_NAME -- ls /etc/secrets
1
kubectl exec -it $POD_NAME -- cat /etc/secrets/jenkins-user
1
IP=$(minikube ip) # If minikube
1
open "http://$IP/jenkins"

Cleanup

1
2
3
kubectl delete -f secret/jenkins.yml

kubectl delete secret my-creds

Namespaces

Create initial release

1
cat ns/go-demo-2.yml
1
2
IMG=vfarcic/go-demo-2
TAG=1.0
1
2
cat ns/go-demo-2.yml | sed -e "s@image: $IMG@image: $IMG:$TAG@g" \
    | kubectl create -f -
1
kubectl rollout status deploy go-demo-2-api

Retrieve existing Namespaces

1
kubectl get ns
1
kubectl get namespaces

Explore existing namespaces

1
kubectl -n kube-public get all
1
kubectl -n kube-system get all
1
kubectl -n default get all
1
kubectl get all

Create new namespace

1
2
3
kubectl create ns testing

kubectl get ns

Change default namespace

1
jx ns testing
1
kubens testing
1
2
3
DEFAULT_CONTEXT=$(kubectl config current-context)
kubectl config set-context testing --namespace testing \
    --cluster $DEFAULT_CONTEXT --user $DEFAULT_CONTEXT
1
2
3
kubectl config set-context testing --namespace testing \
    --cluster devops24.$AWS_DEFAULT_REGION.eksctl.io \
    --user iam-root-account@devops24.$AWS_DEFAULT_REGION.eksctl.io
1
2
kubectl config set-context testing --namespace testing \
    --cluster minikube --user minikube

Deploy to a new namespace

1
kubectl config view
1
kubectl config use-context testing
1
kubectl get all
1
2
TAG=2.0
DOM=go-demo-2.com
1
2
3
cat ns/go-demo-2.yml | sed -e "s@image: $IMG@image: $IMG:$TAG@g" \
    | sed -e "s@host: $DOM@host: $TAG\.$DOM@g" \
    | kubectl create -f -
1
kubectl rollout status deploy go-demo-2-api
1
curl -H "Host: go-demo-2.com" "http://$IP/demo/hello"
1
curl -H "Host: 2.0.go-demo-2.com" "http://$IP/demo/hello"

Communicate accross namespaces

Make sure we use the default namespace again.

1
jx ns default
1
kubens default
1
kubectl config use-context $DEFAULT_CONTEXT
1
kubectl config use-context iam-root-account@devops24.$AWS_DEFAULT_REGION.eksctl.io
1
kubectl config use-context minikube

Now we run a new container, and make sure it has curl.

1
kubectl run test --image=alpine --restart=Never sleep 10000
1
2
3
kubectl get pod test

kubectl exec -it test -- apk add -U curl

Now, lets exec into the container (kubectl exec) and use curl to test the services' DNS.

1
kubectl exec -it test -- curl "http://go-demo-2-api:8080/demo/hello"
1
2
kubectl exec -it test \
    -- curl "http://go-demo-2-api.testing:8080/demo/hello"

Delete a Namespace

1
kubectl delete ns testing
1
kubectl -n testing get all
1
kubectl get all
1
curl -H "Host: go-demo-2.com" "http://$IP/demo/hello"
1
2
kubectl set image deployment/go-demo-2-api \
    api=vfarcic/go-demo-2:2.0 --record
1
curl -H "Host: go-demo-2.com" "http://$IP/demo/hello"

Cleanup

1
2
kubectl delete -f ns/go-demo-2.yml
kubectl delete pod test

Resource limits & requests - SHORT

View resources

1
cat res/go-demo-2-random.yml
1
kubectl create -f res/go-demo-2-random.yml --record --save-config
1
kubectl rollout status deployment go-demo-2-api
1
kubectl describe deploy go-demo-2-api
1
kubectl describe nodes

Too little memory

1
cat res/go-demo-2-insuf-mem.yml
1
kubectl apply -f res/go-demo-2-insuf-mem.yml --record
1
kubectl get pods
1
kubectl describe pod go-demo-2-db

Too much memory

1
cat res/go-demo-2-insuf-node.yml
1
kubectl apply -f res/go-demo-2-insuf-node.yml --record
1
kubectl get pods
1
kubectl describe pod go-demo-2-db

Cleanup

1
kubectl delete -f res/go-demo-2-insuf-node.yml

Securing Kubernetes

GKE

Resource limits & requests

Enable Heapster

Heapster enables Container Cluster Monitoring and Performance Analysis for Kubernetes (versions v1.0.6 and higher), and platforms which include it.

Info

GKE has heapster installed and enabled by default.

1
minikube addons enable heapster
1
2
3
kubectl apply -f https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/heapster.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/influxdb.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/rbac/heapster-rbac.yaml

Warning

Heapster is now EOL, but still serves a purpose for this demo. Please do NOT use this in production systems.

View resources

1
cat res/go-demo-2-random.yml
1
kubectl create -f res/go-demo-2-random.yml --record --save-config
1
kubectl rollout status deployment go-demo-2-api
1
kubectl describe deploy go-demo-2-api
1
kubectl describe nodes

Expose heapster api endpoint

Info

The version of heapster might be different. Please confirm the actual name with the command below.

1
kubectl get deployment -n kube-system

1
2
kubectl -n kube-system expose deployment heapster-v1.6.0-beta.1 \
    --name heapster-api --port 8082 --type LoadBalancer
1
2
kubectl -n kube-system expose deployment heapster \
    --name heapster-api --port 8082 --type LoadBalancer
1
2
kubectl -n kube-system expose rc heapster \
    --name heapster-api --port 8082 --type NodePort

Measure consumption

Info

You can also use a tool such as Kube Capacity for easier access to these metrics.

1
kubectl -n kube-system get pods
1
kubectl -n kube-system get svc heapster-api -o json

Measure consumption 2

1
2
3
PORT=$(kubectl -n kube-system get svc heapster-api \
    -o jsonpath="{.spec.ports[0].nodePort}")
PORT=8082
1
2
ADDR=$(kubectl -n kube-system get svc heapster-api \
    -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
1
2
ADDR=$(kubectl -n kube-system get svc heapster-api \
    -o jsonpath="{.status.loadBalancer.ingress[0].hostname}")
1
ADDR=$(minikube ip)

Measure consumption 3

1
2
3
BASE_URL="http://$ADDR:$PORT/api/v1/model/namespaces/default/pods"

curl "$BASE_URL"
1
2
DB_POD_NAME=$(kubectl get pods -l service=go-demo-2 -l type=db \
    -o jsonpath="{.items[0].metadata.name}")
1
curl "$BASE_URL/$DB_POD_NAME/containers/db/metrics"
1
curl "$BASE_URL/$DB_POD_NAME/containers/db/metrics/memory/usage"
1
curl "$BASE_URL/$DB_POD_NAME/containers/db/metrics/cpu/usage_rate"

Resource discrepancies

1
cat res/go-demo-2-insuf-mem.yml
1
kubectl apply -f res/go-demo-2-insuf-mem.yml --record
1
kubectl get pods
1
kubectl describe pod go-demo-2-db
1
cat res/go-demo-2-insuf-node.yml
1
kubectl apply -f res/go-demo-2-insuf-node.yml --record
1
kubectl get pods
1
kubectl describe pod go-demo-2-db

Resource discrepancies 2

1
kubectl apply -f res/go-demo-2-random.yml --record
1
kubectl rollout status deployment go-demo-2-db
1
kubectl rollout status deployment go-demo-2-api

Adjusting resources

1
2
DB_POD_NAME=$(kubectl get pods -l service=go-demo-2 \
    -l type=db -o jsonpath="{.items[0].metadata.name}")
1
curl "$BASE_URL/$DB_POD_NAME/containers/db/metrics/memory/usage"
1
curl "$BASE_URL/$DB_POD_NAME/containers/db/metrics/cpu/usage_rate"
1
2
API_POD_NAME=$(kubectl get pods -l service=go-demo-2 \
    -l type=api -o jsonpath="{.items[0].metadata.name}")
1
curl "$BASE_URL/$API_POD_NAME/containers/api/metrics/memory/usage"
1
curl "$BASE_URL/$API_POD_NAME/containers/api/metrics/cpu/usage_rate"

Adjusting resources 2

1
cat res/go-demo-2.yml
1
kubectl apply -f res/go-demo-2.yml --record
1
kubectl rollout status deployment go-demo-2-api

QOS

1
kubectl describe pod go-demo-2-db
1
cat res/go-demo-2-qos.yml
1
kubectl apply -f res/go-demo-2-qos.yml --record
1
kubectl rollout status deployment go-demo-2-db
1
kubectl describe pod go-demo-2-db
1
kubectl describe pod go-demo-2-api
1
kubectl delete -f res/go-demo-2-qos.yml

Defaults & Limitations

1
kubectl create namespace test
1
cat res/limit-range.yml
1
2
kubectl -n test create -f res/limit-range.yml \
    --save-config --record
1
kubectl describe namespace test
1
cat res/go-demo-2-no-res.yml
1
2
kubectl -n test create -f res/go-demo-2-no-res.yml \
    --save-config --record
1
kubectl -n test rollout status deployment go-demo-2-api

Defaults & Limitations 2

1
kubectl -n test describe pod go-demo-2-db
1
cat res/go-demo-2.yml
1
kubectl -n test apply -f res/go-demo-2.yml --record
1
kubectl -n test get events -w
1
2
kubectl -n test run test --image alpine --requests memory=100Mi \
    --restart Never sleep 10000
1
2
kubectl -n test run test --image alpine --requests memory=1Mi \
    --restart Never sleep 10000
1
kubectl delete namespace test

Resource Quotas

1
cat res/dev.yml
1
kubectl create -f res/dev.yml --record --save-config
1
kubectl -n dev describe quota dev
1
kubectl -n dev create -f res/go-demo-2.yml --save-config --record
1
kubectl -n dev rollout status deployment go-demo-2-api
1
kubectl -n dev describe quota dev

Resource Quotas 2

1
cat res/go-demo-2-scaled.yml
1
kubectl -n dev apply -f res/go-demo-2-scaled.yml --record
1
kubectl -n dev get events
1
kubectl describe namespace dev
1
kubectl get pods -n dev
1
kubectl -n dev apply -f res/go-demo-2.yml --record
1
kubectl -n dev rollout status deployment go-demo-2-api

Resource Quotas 3

1
cat res/go-demo-2-mem.yml
1
kubectl -n dev apply -f res/go-demo-2-mem.yml --record
1
kubectl -n dev get events | grep mem
1
kubectl describe namespace dev
1
kubectl -n dev apply -f res/go-demo-2.yml --record
1
kubectl -n dev rollout status deployment go-demo-2-api
1
2
kubectl expose deployment go-demo-2-api -n dev \
    --name go-demo-2-api --port 8080 --type NodePort

Cleanup

1
kubectl delete ns dev