kubernetes on the cloud
- 1. Kubernetes on the GKE
- 1.1. How do master nodes communicate?
- 1.2. Where can we run Kubernetes?
- 1.3. Can K8s be used in a hybird, multi-cloud world?
- 1.4. Interacting with K8s
- 1.5. Names and UIDs
- 1.6. Namespaces
- 1.7. Labels
- 1.8. Volumes
- 1.9. Lab: Volumes and the exmptydir volume
- 1.10. Persistent Volumes
- 1.11. Lab: use of secrets pass information to pods
- 2. Debugging
Kubernetes on the GKE
use cloud shell
1 | #setup zone |
By default a pod is accessible to only other internal machines in the cluster
1 | #kubectl expose pod: Exposed the pod a a service so it can be accessed externally |
How Kubernetes Works
Kubernetes: Orchestration technology- convert isolated containers running on different hardware into a cluster
Pod: Atomic unit of deployment in Kubernetes.
- Consists of 1 or more tightly coupled containers.
- Pod runs on node, which is controlled by master.
- Kubernetes only knows about pods
- Cannot start container without a pod
- Pod => Sandbox for 1 or more cntainers
Kubernetes::Hadoop
- Docker Container Engine -> Java Runtime
- Docker containers -> Jars
- Kubernetes -> Hadoop
Kubernetes for Orchestration
- Fault-tolerance: Pod/Nod failures
- Auto-scaling: More clients? More demand
- Rollback: Advanced deployment options
- Auto-healing: Crashed containers restart
- Load-balancing: Distribute client requests
- Isolation: Sandboxes so that containers don’t interfere
kubectl
Telling k8s what the desire state is.
What does the k8s master do?
Kubernetes Master
- One or more nodes designated as master
- Several k8s processes run on master
- Multi-master for high-availability
kube-apiserver
- Communicates with user
- RESTful API end-points
- Manifest yaml files are accepted by apiserver
etcd
Cluster Store for Metadata
- Metadata about spec and status of cluster
- etcd is consistent and highly available key-value store
- source-of-truth for cluster state
kube-scheduler
- Handle pod creation and management
- Kube-scheduler match/assign nodes to pods
- Complex-affinities, taints, tolerations,…
controller-manager
- Different master processes
- Actual state <-> Desired State
- cloud-controller-manager
- kube-controller-manager
- Node controller
- Replication controller
- Route controller
- Volume controller
Control Plane
- Apiserver
- etc
- scheduler
- controller-manager
- cloud-controller-manager
- kube-controller-manager
What runs on each node of a cluster?
Kubernetes Node (Minion)
- Kubelet
- Agent running on this node
- Listen to k8s master
- Port 10255
- Kube-proxy
- Needed because pod IP addresses are ephemeral
- Networking- will make sense when we discuss Service objects
- Container engine
- Works with kubelet
- Pulling images
- Start/stop
- Could be Docker or rkt
What are Pods?
Multi-Container Pods
- Share access to memory space
- Connect to each other using localhost
- Share access to the same volumes (storage abstraction)
- Same parameters such as configMaps
- Tight coupling is dangerous
- Once crashes, all crash
Use cases for multi-container Pod
- Main container, “sidecar” supporting containers
- Proxies, Bridges, Adapters
Anti-Patterns for multi-container pods
- Avoid packing three-tier web app into 1 pod
- Do not pack multiple similar containers in the same pod for scaling
- Use Deployments or ReplicaSet instead
- Micro0services: Simple, independent components
Pods limitations
- No auto-healing or scaling
- Pod crashes? Must be handled at higher level
- ReplicaSet,Deployment,Service
- Ephemeral: Ip address are ephemeral
Higer level k8s objects
- ReplicaSet, ReplicationController: Scaling and healing
- Deployment: Versioning and rollback
- Service: Static (non-ephemeral) IP and networking
- Volume: Non-ephemeral storage
How do master nodes communicate?
Cluster to master
- All cluster -> master communication only with apiserver
- HTTPS (443)
- Relatively secure
Master to cluster
- apiserver->kubelet
- Certicate not verified by default
- Vulnerable to man-in-the-middle attacks
- Don’t run on public network
- To harden
- set -kubelet-certificate-authority
- use SSH tunelling
- apiserver->nodes/pods/services
- aws(kops)
- azure
- gcp(kubectl)
- GKE:Google Kubernetes Engine
- Infra on GCE Virtual machines
- GCE: Google Compute Engine (IaaS)
Bootstrap(kubeadm): On-prem, private cloud
Playgrounds:PWK(Browser-based,time-limited sessions), Minikube(Windows or Mac, Sets up VM on your machine)
Can K8s be used in a hybird, multi-cloud world?
Hybrid=On-prem+Public Cloud
- On-premise: vare metal or VMs
- Legacy infra, large on-prem datacenters
- Medium-term importance
Multi-Cloud
- More than 1 public cloud provider
- Strategic reasons, vendor lock-in (Amazon buying Whole Foods)
Interacting with K8s
How do we work with k8s
- kubectl
- Most common command line utility
- Make POST requests to apiserver of control plane
- kubeadm
- Bootstrap cluster when not on cloud Kubernetes service
- To create cluster out of individual infra nodes
- kubefed
- Administer federated clusters
- Federated cluster-> group of multiple clusters (multi-cloud,hybrid)
- kubelet
- kube-proxy
Objects
- K8s objects are persistent entities
- Everything is an object…
- Pod,ReplicaSet, Deployment, Node … all are objects
- Send object specification (usually in .yaml or .json)
Three object management methods
- Imperative commands
- No .yaml or config files
- kubectl run …
- kubectl expose …
- kubectl autosacle …No config file
1
2kubectl run ningx --image nginx
kubectl create deployment nginx --image nginx
Imperative: intent is in command
Pro:
- Simple
Cons: - No audit trail or review mechanism
- Can’t reuse or use in template
- Imperative object configuration
- kubectl + yaml or config files used
- kubectl create -f config.yaml
- kubectl replace -f config.yaml
- kubectl delete -f config.yaml
Config file required
Still Imperative: intent is in command
Pros:
- Still simple
- Robust - files checked into repo
- One file for multiple operations
- Declarative object configuration
- Only .yaml or config files used
- kubectl apply -f config.yamlConfig files(s) are all that is required
1
kubectl apply -f configs/
Declarative not imperative
Pros:
Most robust-review, repos, audit trails
K8S will automatically figure out intents
Can specify multiple files/directories recursively
Live object configuration: The live configuration values of an object, as observed by the Kubernetes cluster
Current object configuration files: The config file we are applying in the current command
List-applied object configuration file: The last config file what was applied to the object
Don’t mix and match!
Declarative is preferred
Merging Changes
- Primitive fields
- String, init, boolean, images or replicas
- Replace old state with Current object configuration file
- Map fields
- Merge old state with Current object configuration file
- List field
- Complex-varies by field
The Pros and Cons of Declarative and Imperative object management
Declarative
kubectl apply -f config.yaml
- Robust
- Track in repos, review
- Recursively apply to directories
Imperative
kubectl run …
kubectl expose…
kubectl autosacle…
- Simple, intention is very clear
- Preferred for deletion
Names and UIDs
How are objects named?
- Objects-persistent entities
- pods,replicasets,services,volumes,nodes,…
- information maintained in etcd
- Identified using
- Divide physical cluster into multiple virtual clusters
- Three pre-defined namespaces:
- default: if non specified
- kube-system: for internal k8s objects
- kub-public: auto-readable by all users
- Name scopes: names need to be unique only inside a namespace
- Future version: namespace-> common access control
- Don’t use namespaces for versioning
- Just use labels instead
Objects without namespaces
- Nodes
- PersistentVolumes
- Namespace themselves
Labels
- key/value pairs attached to objects
- metadata
- need not be unique (same label to mutiple objects)
- No sematics for k8s (meaningful only to humans)
- Loose coupling via selectors
- Can be added
- at creation time
- after creation
- Multiple objects can have same label
- Same label can’t repeat key though
Volumes
- Permanence: Storage that lasts longer than lifetime of a pod
- a container inside pod (true for all volumes)
- a pod (only true for persistent volumes)
- Shared State: multiple containers in a pod need to share state/files
- Volumes: address both these needs
- Volumes (in general): lifetime of abstraction=lifetime of pod
- Note that this is longer than lifetime of any container inside pod
- Persistent Volumes: lifetime of abstraction independent of pod lifetime
Types of Volumes
- awsElasticBlockStore
- azureDisk
- azureFile
- gcePersistentDisk
- Many non-cloud-specific volume types as well
Important type of volumes
- configMap
- emptyDir
- gitRepo
- secret
- hostPath
Lab: Volumes and the exmptydir volume
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31stancloud9@cloudshell:~ (scenic-torch-250909)$ cat pod-redis.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}
stancloud9@cloudshell:~ (scenic-torch-250909)$ k get pod redis --watch NAME READY STATUS RESTARTS AGE
redis 0/1 Pending 0 7m36s
redis 0/1 Pending 0 7m36s
redis 0/1 ContainerCreating 0 7m36s
redis 1/1 Running 0 7m40s
^Cstancloud9@cloudshell:~ (scenic-torch-250909)$ k exec -it redis -- /bin/bash
root@redis:/data# cd /data/redis
root@redis:/data/redis# echo Hello > test-file
root@redis:/data/redis# kill 1
root@redis:/data/redis# command terminated with exit code 137
stancloud9@cloudshell:~ (scenic-torch-250909)$ k get pod redis --watch
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 1 18m
^Cstancloud9@cloudshell:~ (scenic-torch-250909)$ k exec -it redis -- /bin/bash
root@redis:/data# ls /data/redis
test-filePersistent Volumes
- Low-level objects, like nodes
- Two types of provisioning:
- Static: administrator pre-creates the volumes
- Dynamic: containers need to file a PersistentVolumeClaim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83gcloud compute disks create my-disk-1 --zone australia-southeast1-a
gcloud compute disks list
stancloud9@cloudshell:~ (scenic-torch-250909)$ cat volum-sample.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
gcePersistentDisk:
pdName: my-disk-1
fsType: ext4
k create -f volum-sample.yaml --validate=false
pod/test-pd created
stancloud9@cloudshell:~ (scenic-torch-250909)$ k get pod test-pd --watch
NAME READY STATUS RESTARTS AGE
test-pd 0/1 ContainerCreating 0 23s
test-pd 1/1 Running 0 29s
^Cstancloud9@cloudshell:~ (scenic-torch-250909)$ k describe pod test-pd
Name: test-pd
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: gke-my-first-cluster-default-pool-8ca613e9-w13m/10.152.0.2
Start Time: Sat, 31 Aug 2019 11:39:22 +1000
Labels: <none>
Annotations: kubernetes.io/limit-ranger: LimitRanger plugin set: cpu request for container test-container
Status: Running
IP: 10.24.0.22
Containers:
test-container:
Container ID: docker://8b08b4cd144d256a078fe3c7b4031844e2c3355d854a711ec454611c0edea30b
Image: k8s.gcr.io/test-webserver
Image ID: docker-pullable://k8s.gcr.io/test-webserver@sha256:f63e365c13646f231ec4a16791c6133ddd7b80fcd1947f41ab193968e02b0745
Port: <none>
Host Port: <none>
State: Running
Started: Sat, 31 Aug 2019 11:39:50 +1000
Ready: True
Restart Count: 0
Requests:
cpu: 100m
Environment: <none>
Mounts:
/test-pd from test-volume (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-gw57h (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
test-volume:
Type: GCEPersistentDisk (a Persistent Disk resource in Google Compute Engine)
PDName: my-disk-1
FSType: ext4
Partition: 0
ReadOnly: false
default-token-gw57h:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-gw57h
Optional: false
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m15s default-scheduler Successfully assigned default/test-pd to gke-my-first-cluster-default-pool-8ca613e9-w13m
Normal SuccessfulAttachVolume 2m9s attachdetach-controller AttachVolume.Attach succeeded for volume "test-volume"
Normal Pulling 109s kubelet, gke-my-first-cluster-default-pool-8ca613e9-w13m pulling image "k8s.gcr.io/test-webserver"
Normal Pulled 107s kubelet, gke-my-first-cluster-default-pool-8ca613e9-w13m Successfully pulled image "k8s.gcr.io/test-webserver"
Normal Created 107s kubelet, gke-my-first-cluster-default-pool-8ca613e9-w13m Created container
Normal Started 107s kubelet, gke-my-first-cluster-default-pool-8ca613e9-w13m Started container
What are some important types of volumes?
emptyDir
- Not persistent
- Created when pod is created on node
- Initially empty
- Share space/state across containers in same pod
- Containers acan mount at different times
- When pod removed/crashes, data lost
- When container carshes data remains
- Usecases: Scratch space, checkpointing…
hostPath
- Mount file/directory from node filesystem into pod
- Uncommon- pods should be independent of nodes
- Makes pod-node coupling tight
- Usecases: Access docker internals, running cAdvisor
- Block devices or sockets on host
gitRepo
configMap
- configMap volume mounts data from ConfigMap object
- configMap objects define key-value pairs
- configMap objects inject paramters into pods
- Two main usecases:
- Providing config information for apps running inside pods
- Specifying config information for control plane (controllers)
secret
- Pass ensitive inforamtion to pods
- First create secret so it is stored in control plane
- kubectl create secret
- Mount that secret as a volume so that it is available inside pod
- Secret is stored in RAM storage (not written to persistent disk)
Lab: use of secrets pass information to pods
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33stancloud9@cloudshell:~ (scenic-torch-250909)$ cat secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYMxw
password: Mzk1MjqkdmRnN0pi
stancloud9@cloudshell:~ (scenic-torch-250909)$ cat secrets-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
# name must match the volume name below
- name: secret-volume
mountPath: /etc/secret-volume
# The secret data is exposed to Containers in the Pod through a Volume.
volumes:
- name: secret-volume
secret:
secretName: test-secret
stancloud9@cloudshell:~ (scenic-torch-250909)$ k get pod secret-test-pod
NAME READY STATUS RESTARTS AGE
secret-test-pod 1/1 Running 0 19m
stancloud9@cloudshell:~ (scenic-torch-250909)$ k exec -it secret-test-pod -- /bin/bash
root@secret-test-pod:/# cd /etc/secret-volume/
root@secret-test-pod:/etc/secret-volume# ls
password username
Debugging
Insufficient cpu
1 | stancloud9@cloudshell:~ (scenic-torch-250909)$ k get pod secret-test-pod |