Kubernetes - Docker DLH Short Course
Kubernetes - Docker DLH Short Course
Kubernetes training
1
Introduction
The training: Main Reference and contents
1. Introduction
2. Key concepts
3. Architecture overview
a. Control Plane components
b. Node components
c. Other components
4. Network
5. Concept and resources
6. Kubernetes Apis
a. Core Objects
b. Workloads
c. Batch API (optional)
7. Storage (optional)
8. ConfigMap and secrets (optional)
Introduction
What Does “Kubernetes” Mean?
Image Source
What is Kubernetes?
07/2019
A couple of Key concepts
Pods
They are
also
Ephemeral!
Services
● Unified method of
accessing the exposed
workloads of Pods.
● Durable resource
○ static cluster IP
○ static namespaced DNS
name
Services
● Unified method of
accessing the exposed
workloads of Pods.
● Durable resource
○ static cluster IP
○ static namespaced DNS
name
NOT Ephemeral!
Architecture Overview
Architecture Overview
Control planes components
Control Plane Components
● kube-apiserver
● etcd
● kube-controller-manager
● kube-scheduler
kube-apiserver
Image Source
kube-controller-manager
● kubelet
● kube-proxy
● Container Runtime Engine
kubelet
● Pod Network
○ Cluster-wide network used for pod-to-pod
communication managed by a CNI (Container Network
Interface) plugin.
● Service Network
○ Cluster-wide range of Virtual IPs managed by
kube-proxy for service discovery.
Container Network Interface (CNI)
● Container-to-Container
○ Containers within a pod exist within the same network
namespace and share an IP.
○ Enables intrapod communication over localhosĞ.
● Pod-to-Pod
○ Allocated cluster unique IP for the duration of its life
cycle.
○ Pods themselves are fundamentally ephemeral.
Fundamentals Applied
● Pod-to-Service
○ managed by kube-proxy and given a persistent cluster
unique IP
○ exists beyond a Pod’s lifecycle.
● External-to-Service
○ Handled by kube-proxy.
○ Works in cooperation with a cloud provider or other
external entity (load balancer).
Exercise 1
Installation
bit.ly/dlh-kube-exo1
Concept and resources
Concept and resources
The API and object model
API Overview
Image Source
API Groups
Format:
● Designed to make it
/apis/<group>/<version>/<resource>
extremely simple to
both understand and Examples:
extend. /apis/apps/v1/deployments
/apis/batch/v1beta1/cronjobs
● An API Group is a REST
compatible path that acts as the type descriptor for a
Kubernetes object.
● Referenced within an object as the apiVersion and
kind.
API Versioning
Format:
● Three tiers of API maturity
/apis/<group>/<version>/<resource>
levels.
● Also referenced within the
Examples:
object apiVersion. /apis/apps/v1/deployments
/apis/batch/v1beta1/cronjobs
apiVersion: v1
kind: Pod
metadata:
name: yaml
spec:
containers:
- name: container1
image: nginx
- name: container2
image: alpine
Object Expression - YAML
apiVersion: v1
kind: Pod Scalar
Mapping metadata:
Hash name: yaml
Dictionary spec:
containers:
- name: container1
image: nginx
- name: container2 Sequence
Array
image: alpine List
YAML vs JSON
apiVersion: v1 {
"apiVersion": "v1",
kind: Pod
"kind": "Pod",
metadata: "metadata": {
name: pod-example "name": "pod-example"
spec: },
containers: "spec": {
"containers": [
- name: nginx
{
image: nginx:stable-alpine "name": "nginx",
ports: "image": "nginx:stable-alpine",
- containerPort: 80 "ports": [ { "containerPort": 80 } ]
}
]
}
}
Object Model - Workloads
apiVersion: v1 conditions:
lastTransitionTime: 2018-02-14T14:15:52Z
metadata:
status: "True"
name: pod-example type: Ready
spec: - lastProbeTime: null
- lastProbeTime: null
ports:
lastTransitionTime: 2018-02-14T14:15:49Z
- containerPort: 80 status: "True"
type: PodScheduled
Exercise 2
Dashboard Installation
bit.ly/dlh-kube-exo2
Kubernetes APIs
Kubernetes APIs
Core Objects
Core Concepts
Namespaces
Pods Services
Labels Selectors
Namespaces
Example Object Example Status Snippet
status:
apiVersion: v1 conditions:
lastTransitionTime: 2018-02-14T14:15:52Z
metadata:
status: "True"
name: pod-example type: Ready
spec: - lastProbeTime: null
- lastProbeTime: null
ports:
lastTransitionTime: 2018-02-14T14:15:49Z
- containerPort: 80 status: "True"
type: PodScheduled
Namespaces
* https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set
Labels Example
apiVersion: v1
kind: Pod
metadata:
name: pod-label-example
labels:
app: nginx
env: prod
spec:
containers:
- name: nginx
image: nginx:stable-alpine
ports:
- containerPort: 80
Selectors
apiVersion: v1
Selectors use labels to filter kind: Pod
or select objects, and are metadata:
name: pod-label-example
used throughout labels:
Kubernetes. app: nginx
env: prod
spec:
containers:
- name: nginx
image: nginx:stable-alpine
ports:
- containerPort: 80
nodeSelector:
gpu: nvidia
Selector Example
apiVersion: v1
kind: Pod
metadata:
name: pod-label-example
labels:
app: nginx
env: prod
spec:
containers:
- name: nginx
image: nginx:stable-alpine
ports:
- containerPort: 80
nodeSelector:
gpu: nvidia
Selector Types
Equality based selectors allow for Set-based selectors are supported
simple filtering (=,==, or !=). on a limited subset of objects.
However, they provide a method of
filtering on a set of values, and
supports multiple operators
including: in, notin, and exist.
selector: selector:
matchLabels: matchExpressions:
gpu: nvidia - key: gpu
operator: in
values: [“nvidia”]
Quizz
Selectors in actions
Labels
Labels
Labels
Labels
Labels
Services
● Unified method of accessing the exposed workloads of
Pods.
● Durable resource (unlike Pods)
○ static cluster-unique IP
○ static namespaced DNS name
<service name>.<namespace>.svc.cluster.local
Services
apiVersion: v1
ClusterIP services exposes a kind: Service
service on a strictly cluster metadata:
name: example-prod
internal virtual IP. spec:
selector:
app: nginx
env: prod
ports:
- protocol: TCP
port: 80
targetPort: 80
Cluster IP Service
Name: example-prod
Selector: app=nginx,env=prod
Type: ClusterIP
IP: 10.96.28.176
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.255.16.3:80,
10.255.16.4:80
/ # nslookup example-prod.default.svc.cluster.local
Name: example-prod.default.svc.cluster.local
Address 1: 10.96.28.176 example-prod.default.svc.cluster.local
NodePort Service
apiVersion: v1
● NodePort services extend kind: Service
the ClusterIP service. metadata:
name: example-prod
● Exposes a port on every spec:
type: NodePort
node’s IP. selector:
app: nginx
● Port can either be statically env: prod
30000-32767. port: 80
targetPort: 80
NodePort Service
Name: example-prod
Selector: app=nginx,env=prod
Type: NodePort
IP: 10.96.28.176
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 32410/TCP
Endpoints: 10.255.16.3:80,
10.255.16.4:80
LoadBalancer Service
apiVersion: v1
● LoadBalancer services kind: Service
extend NodePort. metadata:
name: example-prod
● Works in conjunction with spec:
an external system to map a type: LoadBalancer
selector:
cluster external IP to the app: nginx
exposed service. env: prod
ports:
protocol: TCP
port: 80
targetPort: 80
LoadBalancer Service
Name: example-prod
Selector: app=nginx,env=prod
Type: LoadBalancer
IP: 10.96.28.176
LoadBalancer
Ingress: 172.17.18.43
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 32410/TCP
Endpoints: 10.255.16.3:80,
10.255.16.4:80
ExternalName Service
apiVersion: v1
● ExternalName is used to kind: Service
reference endpoints metadata:
OUTSIDE the cluster. name: example-prod
spec:
● Creates an internal type: ExternalName
spec:
CNAME DNS entry that externalName: example.com
aliases another.
Exercise 3
apiVersion: apps/v1
● replicas: The desired
kind: ReplicaSet
number of instances of the metadata:
Pod. name: rs-example
spec:
● selector:The label selector
replicas: 3
for the ReplicaSet will manage selector:
ALL Pod instances that it matchLabels:
targets; whether it’s desired or app: nginx
not. env: prod
template:
<pod template>
ReplicaSet
$ kubectl get pods
apiVersion: apps/v1 NAME READY STATUS RESTARTS AGE
kind: ReplicaSet rs-example-9l4dt 1/1 Running 0 1h
metadata: rs-example-b7bcg 1/1 Running 0 1h
name: rs-example rs-example-mkll2 1/1 Running 0 1h
spec:
$ kubectl describe rs rs-example
replicas: 3 Name: rs-example
selector: Namespace: default
Selector: app=nginx,env=prod
matchLabels: Labels: app=nginx
app: nginx env=prod
Annotations: <none>
env: prod Replicas: 3 current / 3 desired
template: Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
metadata: Labels: app=nginx
env=prod
labels:
Containers:
app: nginx nginx:
Image: nginx:stable-alpine
env: prod Port: 80/TCP
spec: Environment: <none>
Mounts: <none>
containers: Volumes: <none>
- name: nginx Events:
Type Reason Age From Message
image: nginx:stable-alpine
ports: Normal SuccessfulCreate 16s replicaset-controller Created pod: rs-example-mkll2
Normal SuccessfulCreate 16s replicaset-controller Created pod: rs-example-b7bcg
- containerPort: 80 Normal SuccessfulCreate 16s replicaset-controller Created pod: rs-example-9l4dt
Deployment
R1 pod-template-hash:
676677fff
R2 pod-template-hash:
54f7ff7d6d
R1 pod-template-hash:
676677fff
R2 pod-template-hash:
54f7ff7d6d
R1 pod-template-hash:
676677fff
R2 pod-template-hash:
54f7ff7d6d
R1 pod-template-hash:
676677fff
R2 pod-template-hash:
54f7ff7d6d
R1 pod-template-hash:
676677fff
R2 pod-template-hash:
54f7ff7d6d
R1 pod-template-hash:
676677fff
R2 pod-template-hash:
54f7ff7d6d
apiVersion: apps/v1
● revisionHistoryLimit: The kind: StatefulSet
number of previous iterations of the metadata:
name: sts-example
StatefulSet to retain. spec:
replicas: 2
● serviceName: The name of the
revisionHistoryLimit: 3
associated headless service; or a selector:
service without a ClusterIP. matchLabels:
app: stateful
serviceName: app
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0
template:
<pod template>
StatefulSet
apiVersion: apps/v1
● updateStrategy: Describes the method kind: StatefulSet
of updating the Pods based on the type. metadata:
name: sts-example
Valid options are OnDelete or spec:
RollingUpdate. replicas: 2
revisionHistoryLimit: 3
○ OnDelete: The new instance of the selector:
Pod is deployed ONLY after the matchLabels:
app: stateful
current instance is deleted. serviceName: app
updateStrategy:
○ RollingUpdate: Pods with an type: RollingUpdate
ordinal greater than the partition rollingUpdate:
value will be updated in one-by-one partition: 0
template:
in reverse order. <pod template>
Exercise 4
apiVersion: batch/v1
● backoffLimit: The number of failures
kind: Job
before the job itself is considered failed. metadata:
name: job-example
● completions: The total number of
spec:
successful completions desired. backoffLimit: 4
completions: 4
● parallelism: How many instances of
parallelism: 2
the pod can be run concurrently. template:
spec:
● spec.template.spec.restartPolicy: restartPolicy: Never
Jobs only support a restartPolicy of <pod-template>
type Never or OnFailure.
Job
apiVersion: batch/v1 $ kubectl describe job job-example
kind: Job Name: job-example
Namespace: default
metadata: Selector: controller-uid=19d122f4-1576-11e8-a4e2-080027a3682b
name: job-example Labels: controller-uid=19d122f4-1576-11e8-a4e2-080027a3682b
job-name=job-example
spec: Annotations: <none>
Parallelism: 2
backoffLimit: 4 Completions: 4
completions: 4 Start Time: Mon, 19 Feb 2018 08:09:21 -0500
Pods Statuses: 0 Running / 4 Succeeded / 0 Failed
parallelism: 2 Pod Template:
Labels: controller-uid=19d122f4-1576-11e8-a4e2-080027a3682b
template: job-name=job-example
spec: Containers:
hello:
containers: Image: alpine:latest
Port: <none>
- name: hello Command:
image: alpine:latest /bin/sh
-c
command: ["/bin/sh", "-c"] Args:
args: ["echo hello from $HOSTNAME!"] echo hello from $HOSTNAME!
Environment: <none>
restartPolicy: Never Mounts: <none>
Volumes: <none>
Events:
$ kubectl get pods --show-all Type Reason Age From Message
NAME READY STATUS RESTARTS AGE ---- ------ ---- ---- -------
Normal SuccessfulCreate 52m job-controller Created pod: job-example-v5fvq
job-example-dvxd2 0/1 Completed 0 51m job-example- Normal SuccessfulCreate 52m job-controller Created pod: job-example-hknns
hknns 0/1 Completed 0 52m job-example-tphkm 0/1 Normal SuccessfulCreate 51m job-controller Created pod: job-example-tphkm
Completed 0 51m job-example-v5fvq 0/1 Normal SuccessfulCreate 51m job-controller Created pod: job-example-dvxd2
Completed 0 52m
CronJob
Cluster Cluster
Users Admins
PersistentVolume
● capacity.storage: The total apiVersion: v1
kind: PersistentVolume
amount of available storage. metadata:
name: nfsserver
● volumeMode: The type of volume, spec:
capacity:
this can be either Filesystem or storage: 50Gi
Block. volumeMode: Filesystem
accessModes:
2. StorageClass provisions
request through API with
1. PVC makes a request of external storage system.
the StorageClass.
uid: 9df65c6e-1a69-11e8-ae10-080027a3682b
4. provisioned PV is bound
to requesting PVC.
3. External storage system
creates a PV strictly satisfying
pv: pvc-9df65c6e-1a69-11e8-ae10-080027a3682b
the PVC request.
StorageClass
● AWSElasticBlockStore ● iSCSI
● AzureFile ● Quobyte
● AzureDisk ● NFS
● CephFS ● RBD
● Cinder ● VsphereVolume
● FC ● PortworxVolume
● Flocker ● ScaleIO
● GCEPersistentDisk ● StorageOS
● Glusterfs ● Local
Internal Provisioner
Exercise 6
Use storage
bit.ly/dlh-kube-exo6
Configmap and Secret
Configuration
$ cat info/city
Ann Arbor
$ cat info/state
Michigan
$ kubectl create configmap file-example --from-file=cm/city --from-file=cm/state
configmap "file-example" created
ConfigMap Example
$ cat info/city
Ann Arbor
$ cat info/state
Michigan
$ kubectl create configmap file-example --from-file=cm/city --from-file=cm/state
configmap "file-example" created
ConfigMap Example
$ cat info/city
Ann Arbor
$ cat info/state
Michigan
$ kubectl create configmap file-example --from-file=cm/city --from-file=cm/state
configmap "file-example" created
ConfigMap Example
$ cat info/city
Ann Arbor
$ cat info/state
Michigan
$ kubectl create configmap file-example --from-file=cm/city --from-file=cm/state
configmap "file-example" created
Secret
apiVersion: v1
● type: There are three different
kind: Secret
types of secrets within Kubernetes: metadata:
name: manifest-secret
○ docker-registry - credentials
type: Opaque
used to authenticate to a data:
container registry username: ZXhhbXBsZQ==
○ generic/Opaque - literal values password: bXlwYXNzd29yZA==
name: manifest-example
$ cat info/username
type: Opaque example
data: $ cat info/password
mypassword
username: ZXhhbXBsZQ== $ kubectl create secret generic dir-secret --from-file=secret/
password: bXlwYXNzd29yZA== Secret "file-secret" created
$ cat secret/username
example
$ cat secret/password
mypassword
$ kubectl create secret generic file-secret --from-file=secret/username --from-file=secret/password
Secret "file-secret" created
Secret Example
name: manifest-example
$ cat info/username
type: Opaque example
data: $ cat info/password
mypassword
username: ZXhhbXBsZQ== $ kubectl create secret generic dir-secret --from-file=secret/
password: bXlwYXNzd29yZA== Secret "file-secret" created
$ cat secret/username
example
$ cat secret/password
mypassword
$ kubectl create secret generic file-secret --from-file=secret/username --from-file=secret/password
Secret "file-secret" created
Secret Example
name: manifest-example
$ cat info/username
type: Opaque example
data: $ cat info/password
mypassword
username: ZXhhbXBsZQ== $ kubectl create secret generic dir-secret --from-file=secret/
password: bXlwYXNzd29yZA== Secret "file-secret" created
$ cat secret/username
example
$ cat secret/password
mypassword
$ kubectl create secret generic file-secret --from-file=secret/username --from-file=secret/password
Secret "file-secret" created
Secret Example
name: manifest-example
$ cat info/username
type: Opaque example
data: $ cat info/password
mypassword
username: ZXhhbXBsZQ== $ kubectl create secret generic dir-secret --from-file=secret/
password: bXlwYXNzd29yZA== Secret "file-secret" created
$ cat secret/username
example
$ cat secret/password
mypassword
$ kubectl create secret generic file-secret --from-file=secret/username --from-file=secret/password
Secret "file-secret" created
Injecting as Environment Variable
apiVersion: batch/v1 apiVersion: batch/v1
kind: Job kind: Job
metadata: metadata:
name: cm-env-example name: secret-env-example
spec: spec:
template: template:
spec: spec:
containers: containers:
- name: mypod - name: mypod
image: alpine:latest image: alpine:latest
command: [“/bin/sh”, “-c”] command: [“/bin/sh”, “-c”]
args: [“printenv CITY”] args: [“printenv USERNAME”]
env: env:
- name: CITY - name: USERNAME
valueFrom: valueFrom:
configMapKeyRef: secretKeyRef:
name: manifest-example name: manifest-example
key: city key: username
restartPolicy: Never restartPolicy: Never
Exercise 7
ConfigMap
bit.ly/dlh-kube-exo7