Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploytest
  namespace: dev
spec:
  replica: 3
  selector:
    matchLabels:
      name: test-pod
  template:
    metadata:
      labels:
        name: test-pod
    spec:
      containers:
      - name: test-pod-container
        image: nginx

Commands

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: test-pod-container
    image: nginx
    command:
    - sleep
    - "2000"

or

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: test-pod-container
    image: nginx
    command: ["sleep"]
    args: ["--time", "1000"]

Config Map

Define ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config-map
data:
  MY_MAP_KEY_1: VALUE_1
  MY_MAP_KEY_2: VALUE_2

Environment Variable define Directly

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-pod-container
    image: nginx
    env:
    - name: MY_KEY_1
      value: VALUE_1

Use ConfigMap

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-pod-container
    image: nginx
    envFrom:
      - configMapRef:
          name: my-config-map

Use ConfigMap and search by key

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-pod-container
    image: nginx
    env:
    - name: MY_KEY_1
      valueFrom:
        configMapKeyRef:
          name: my-config-map
          key: MY_MAP_KEY_1

Mount ConfigMap as Volume

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  volumes:
  - name: my-configmap-volume
    configMap:
      name: my-config-map
  containers:
  - name: my-pod-container
    image: nginx
    volumeMounts:
    - name: my-volume
      mountPath: "/etc/config"

Secret

Define Secret

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
data: 
  SECRET_1: base64(VALUE_1)

Use command for base64 encode

Encode
$ echo -n 'xxxx' | base64
Decode
$ echo -n 'eHh4eAo=' | base64 --decode

Use in Pod as whole env variable

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-pod-container
    image: nginx
    envFrom:
    - secretRef:
        name: my-secret

Use in Pod as value reference of env variable

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-pod-container
    image: nginx
    env:
    - name: MY_ENV_1
      valueFrom:
        secretKeyRef:
          name: my-secret
          key: SECRET_1

Mount Secret as Volume

apVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  volumes:
  - name: secret-volume
    secret:
      secretName: my-secret
  containers:
  - name: my-pod-container
    image: nginx
    volumeMounts:
    - name: mounted-secret
      mountPath: "/etc/foo"
      readOnly: false

Security Context

Let Pod run as specific level of User
Pod can set user and container can overwrite it
use capabilities to add permission
only container can use capabilities

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  securityContext:
    runAsUser: 1000
  containers:
  - name: my-pod-container
    image: nginx
    securityContext:
      runAsUser: 1001
      capabilities:
        add: ["SYS_TIME"]

Service Account

Create sevice account

$ kubectl create serviceaccount [NAME]

Check tokens

$ kubectl describe serviceaccount [NAME]


above commands can find "Tokens" attribute with a name, here we called it [TOKENS_NAME] and

$ kubectl describe secrets [TOKENS_NAME]


You can find real token

Use service account in Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replica: 1
  selector:
    matchLabels: 
      name=my-deployment
  template:
    serviceAccount: [NAME]
    metadata:
      labels:
        name=my-deployment
    spec:
      containers:
      - name: my-deployment-container
        image: nginx

Resource

default is 0.5 CPU and 256 Mi

Define Resource in Pod

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-pod-container
    image: nginx
    ports:
    - containerPort: 8080
    resources:
      request:
        memory: "1Gi"
        cpu: 2
      limit:
        memory: "2Gi"
        cpu: 4

Taints and Tolerations

  • Taint on Node
  • Tolerant on Pod

Add taint to node

$ kubectl taint node [node name] [taint name]:[effect] 
  • [taint name]: could be a [traint key]=[traint value] or a name like node-role.kubernetes.io/master
  • [effect]: NoSchedule / NoExecute / PreferNoSchedule

Remove taint from node

$ kubectl taint node [node name] [taint name]-

Remember! add minus(-) at last...

Add tolerations to Pod

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  tolerations:
  - key: "[taint key]"
    value: "[taint value]"
    operator: "Equal"
    effect: "[taint effect]"
  containers:
  - name: my-pod-container
    image: nginx

Taint only can prevent pod executed on specific Node, but it can NOT let Pod executed on specific Node!

Node Selector, Node Affinity

Why we need affinity?

Node Selector not support OR or NOT options

Add Label to Node

$ kubectl label node <NODE name> [key]=[value]

e.g.

$ kubectl label node node01 size=Large

Create Node Selector on Pod

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-pod-container
    image: nginx
  nodeSelector:
    [key]: [value] 

Use Node Affinity

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-pod-container
    image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - key: [key]
          operator: In
          values:
          - [value1]
          - [value2] 

operator got In, NotIn, Exists ...

If you want make sure pod executed in specific node, and other pod can not execute in

  1. taint node
  2. set Tolerations on Pod
  3. set label to node
  4. set node affinity on Pod

Multicontainer Pod

Empty...

Readiness & Liveness

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-pod-container
    image: nginx
    ports:
    - containerPort: 8080
    readinessProbe:
      httpGet:
        path: /api/ready
        port: 8080
      initialDelaySeconds: 10
      periodSeconds: 1
      failureThreshold: 10

    livenessProbe:
      httpGet:
        path: /
        port:
      initialDelaySeconds: 10
      periodSeconds: 1
      failureThreshold: 10

Logs

$ kubectl logs -f [pod name]


if more than one container in Pod

$ kubectl logs -f [pod name] [container name] 

Selector

$ kubectl get [resource] \
--selector label_key=label_value \
--selector label_key=label_value

Rolling Update & Rollback

Strategy - Recreate

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replica: 4
  selector:
    matchLabels:
      name: frontend
  
    strategy:
      type: Recreate

Strategy - RollingUpdate (Default)


  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 20%
      maxunavailable: 10%
  template:
    metadat:
      name: my-pod
      labels: 
        name: frontend
    spec:
      containers:
      - name: my-pod-container
        image: nginx
        ports:
        - containerPort: 8080

Begin Rollout

$ kubectl create -f myapp-deployment.yml

Check Rollout status

$ kubectl rollout status deployment/myapp-deployment

Check Rollout history

$ kubectl rollout history deployment/myapp-deployment

Rollout new version

$ kubectl apply -f myapp-deployment-new.yml

or

$ kubectl set image deployment/myapp-deployment [container name]=[image name]

Rollback

$ kubectl rollout undo deployment/myapp-deployment

Jobs & CronJob

Jobs

apiVersion: batch/v1
kind: Job
metadata:
  name: my-job
spec:
  completions: 3
  parallelism: 3
  template:
    spec:
      container:
      - name: my-job-container
        image: nginx
      restartPolicy: Never

CronJob

CronJob is Cron schedule define and include job spec
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: my-cron-job
spec:
  schedule: "* * * * *"
  jobTemplate:
    ... Job define ....
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: my-cron-job
spce:
  schedule: "0 12 * * *"
  jobTemplate:
    spec:
      completions: 3
      parallelism: 3
      template:
        spec:
          containers:
          - name: my-cronjob-container
            image: nginx
          restartPolicy: Never

Service

NodePort

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  ports:
  - targetPort: 8080
    port: 80
    nodePort: 30008
  selector:
    app: my-app
    type: frontend

ClusterIP (Default)

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: my-app
    type: frontend

Network Policy

$ kubectl get networkpolicy
K8S default not support Network Policy

Ingress

The network traffic to a Pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-ingress-policy
spec:
  podSelector:
    matchLabels:
      name: my-pod
  policyTypes:
  - Ingress

  ingress:
  - from:
    - podSelector:
        matchLabels:
          name: other-pod-in
    ports:
    - protocol: TCP
      port: 8080

Egress

Network traffic from Pod to somewhere
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-egress-policy
spec:
  podSelector:
    matchLabels:
      name: my-pod
  policyTypes:
  - Egress

  egress:
  - to:
    - podSelector:
        matchLabels:
          name: to-other-pod
    ports:
    - port: 3306
      protocol: TCP

Volume & PersistentVolume & PersistentVolumeClaim

$ kubectl get pv
$ kubectl get pvc

Define a Volume

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  volumes:
  - name: my-volume
    hostPath:
      path: [Host Path]
      type: Directory
  containers:
  - name: my-pod-container
    image: nginx
    volumeMounts:
    - mountPath: [container path]
      name: my-volume

Define a PersistentVolume

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  accessModes:
  - ReadWriteMany
  capacity:
    storage: 1Gi
  hostPath:
    path: [Host path]
  peristentVolumeReclaimPolicy: Retain

Define a PersistentVolume

on host

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  accessModes:
  - ReadWriteMany
  capacity:
    storage: 1Gi
  hostPath:
    path: [Host path]
  peristentVolumeReclaimPolicy: Retain

on NFS

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  accessModes:
  - ReadWriteMany
  capacity:
    storage: 1Gi
  nfs:
    path: [NFS path]
    server: [NFS server]
  peristentVolumeReclaimPolicy: Retain

Use in Pod

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  volumes:
  - name: my-volume-name
    hostPath:
      path: [Host path]
      type: Directory
  - name: my-pvc-name
    persistentVolumeClaim:
      claimName: my-claim-name

  containers:
  - name: my-pod-container
    image: nginx
    volumeMounts:
    - mountPath: [containers path]
      name: my-volume-name
    - mountPath: [containers path]
      name: my-pvc-name

Kubectl Commands

Nodes

$ kubectl get nodes
$ kubectl get node [NAME] -o wide (or yaml or json)
$ kubectl get nodes --show-labels

Label

set Label to a node

$ kubectl label node [NAME] key=value

remove Label from a node

$ kubectl label node [NAME] key-

Role

set Role to a node

$ kubectl label node [NAME] \ 
node-role.kubernetes.io/[role]=\
node-role.kubernetes.io/master=

Context

get all Contexts

$ kubectl config get-contexts

change Context

$ kubectl config set current-context [context name]
$ kubectl config use-context [context name]

delete Context

$ kubectl config delete-context [NAME]

Pod

get Pods

$ kubectl get pods (--all-namespaces) (--namespace=[space name])
$ kubectl get po

execute command in Pod

$ kubectl exec [pod name] -it sh (or other command)

execute command in container of Pod

$ kubectl exec [pod name] -c [container name] -it sh (or other command)

delete a Pod

$ kubectl delete pod [NAME]
$ kubectl delete po [NAME]

Namespace

get all Namespaces

$ kubectl get namespace
$ kubectl get ns

create a Namespace

$ kubectl create namespace [NAME]
$ kubectl create ns [NAME]

delete a Namespace

$ kubectl delete namespace [NAME]
$ kubectl delete ns [NAME]

Deployment

get all Deployments

$ kubectl get deployment
$ kubectl get deploy

delete a Deployment

$ kubectl delete deployment [NAME]
$ kubectl delete deploy [NAME]

scale a Deployment

$ kubectl scale --current-replicas=[num] --replicas=[num] deployment/[NAME]

rollout

rollout a Deployment
$ kubectl set image deployment/[NAME] [container name]=[image name]:[new version]
rollout status
$ kubectl rollout status deployment/[NAME]
rollout history
$ kubectl rollout history deployment/[NAME]
check difference between rollout history
$ kubectl rollout history deployment/[NAME] --revision=[num]
undo rollout
$ kubectl rollout undo deployment/[NAME]
undo rollout to specific version
$ kubectl rollout undo deployment/[NAME] --to-revision=[num]

ReplicaSet

get all ReplicaSet

$ kubectl get replicaset
$ kubectl get rs

Create Pod YAML Tips

Create an NGINX Pod

$ kubectl run --generator=run-pod/v1 nginx --image=nginx

Generate POD Manifest YAML file (-o yaml). Don't create it(--dry-run)

$ kubectl run --generator=run-pod/v1 nginx --image=nginx --dry-run -o yaml

Create a deployment

$ kubectl run --generator=deployment/v1beta1 nginx --image=nginx

Generate Deployment YAML file (-o yaml). Don't create it(--dry-run)

$ kubectl run --generator=deployment/v1beta1 nginx --image=nginx --dry-run -o yaml
with 4 replicas
$ kubectl run --generator=deployment/v1beta1 nginx --image=nginx --dry-run --replicas=4 -o yaml

Save it to a file

$ kubectl run --generator=deployment/v1beta1 nginx --image=nginx --dry-run --replicas=4 -o yaml > nginx-deployment.yaml

Output Yaml from running Pod

$ kubectl get po <name> -o yaml --export > file.yml