Skip to content

Instantly share code, notes, and snippets.

@serhiiluhovyi
Last active August 4, 2020 23:11
Show Gist options
  • Save serhiiluhovyi/4322769cb56d78b6210d16ab262ab5e3 to your computer and use it in GitHub Desktop.
Save serhiiluhovyi/4322769cb56d78b6210d16ab262ab5e3 to your computer and use it in GitHub Desktop.

Links:

https://kubernetes.io/docs/reference/kubectl/cheatsheet/
https://medium.com/faun/be-fast-with-kubectl-1-18-ckad-cka-31be00acc443
https://github.com/twajr/ckad-prep-notes#tasks-from-kubernetes-doc
https://github.com/saaguero/ckad-notes
https://github.com/dgkanatsios/CKAD-exercises
https://github.com/lucassha/CKAD-resources
https://eax.me/vim-commands/
https://discuss.kubernetes.io/t/kubectl-tips-and-tricks/

Clusters:

minikube start --memory 4096
minikube stop
minikube delete
https://cloud.google.com/sdk/docs
gcloud config set compute/zone us-central1-a
gcloud config set compute/region us-central1
gcloud container clusters create my-cluster --cluster-version=1.16.11-gke.5 --image-type=ubuntu --num-nodes=2
gcloud container clusters get-credentials my-cluster
gcloud container clusters delete my-cluster
gcloud container get-server-config
kubectl config use-context minikube

vi:

'dd' - delete current line
'd3d' - delete 3 line
'D' - Удаление текста до конца строки
'dG' - Deletes contents from cursor to end of file. This is very useful when editing YAML files.

'yy' - copy line
'y3y' - copy 3 lines
'p' - paste

'cc' - delete line and staert editing
'u' - undo
CTR-R - redo

v + hjkl
SHIFT + v 
CTR + v 
p 
y 
d 

'Shift + A' - go to the end of the current row (insert mode)
'Shift + C' - delete everything after the cursor (insert mode)
'Shift + I' - go to the first letter on the current row (insert mode)
'Shift + G' - go to the last row of data in the file

'/Pod' - find any instances of `Pod` in the file

'e' - jump to the end of the next word
'w' - jump to the start of the next word
':25' - go to the 25th row in the file

'ZZ' - Save and exit quickly.

Commands:

sudo -i
man lf_exam

# ubuntu
apt update
apt install 

nc -z -v -w 1 secure-service 80

# wget
wget -qO- <link> # quiet, output to - (stdout)
wget --spider <link> # just check the page is there 

source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

alias k=kubectl
alias ka='k get all'
alias kaa='k get all -A'
alias kaf='k apply -f'
complete -F __start_kubectl k

k version --short

k cluster-info
k get nodes

k config view
k config get-contexts
//todo - switch context
k config set-context --current --namespace=dev

k get events -A

k get pods -o wide 
k get pods --selector='app=my'
k get all -A

kubectl run busybox --rm --image=busybox -it --restart=Never -- sh

k exec --stdin --tty pod1 -- /bin/bash

k run nginx --image=nginx --restart=Never --port=80 --expose -o yaml --dry-run=client

cat > pod2.yaml
cmd+v
cmd+c

k create deploy deploy1 --image=nginx -o yaml --dry-run=client

k create deployment nginx --image=nginx
k expose deployment nginx --port=80 --target-port=8080

k run nginx --image=nginx --restart=Never
k create job nginx --image=nginx
k create cronjob nginx --image=nginx --schedule="* * * * *"  
k create cronjob time-limited-job --image=busybox --restart=Never --dry-run --schedule="* * * * *" -o yaml -- /bin/sh -c 'date; echo Hello from the Kubernetes cluster' > time-limited-job.yaml

k create configmap app-config --from-literal=key123=value123
k create secret generic my-secret --from-literal=foo=bar -o yaml --dry-run > my-secret.yaml
echo "YmFy" | base64 --decode

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: db-secret-xxdf
type: Opaque
data:
  DB_Host: $(echo -n "sql01" | base64 -w0)
  DB_User: $(echo -n "root" | base64 -w0)
EOF

kubectl run nginx --image=nginx --restart=Never --requests='cpu=100m,memory=256Mi' --limits='cpu=200m,memory=512Mi'

Pods

k get po pod1 -o wide
k label pods my-pod new-label=awesome
k annotate pods my-pod icon-url=http://goo.gl/XXBTWq 
kubectl logs my-pod
k logs my-pod -c my-container
k exec pod1 -- ls /
k exec --stdin --tty pod1 -- /bin/bash
apiVersion: v1
kind: Pod
metadata:
  name: pod1
  labels:
    app: my-app
    tier: frontend
spec:
  containers:
  - image: nginx
    name: pod1

Commands and Arguments

apiVersion: v1
kind: Pod
metadata:
  name: command-demo
spec:
  containers:
  - name: command-demo-container
    image: ubuntu
    command: ["sleep"]
    args: ["30"]
  restartPolicy: OnFailure

Environment Variables

apiVersion: v1
kind: Pod
metadata:
  name: pod1
  labels:
    app: my-app
    tier: frontend
spec:
  containers:
  - image: nginx
    name: pod1
    env:
    - name: DEMO_1
      value: "Hello"
    - name: DEMO_2
      value: "World"

Security Contexts

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  containers:
  - name: security-context-demo
    image: ubuntu
    command: ["sleep", "300"]
    securityContext:
      runAsUser: 1000
      capabilities:
        add: ["NET_ADMIN", "SYS_TIME"]

Service Account

k create sa test-sa
k get secret
apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-sa
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: test-sa
  containers:
  - name: nginx
    image: nginx
  

Resource Requirements

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: wp
    image: wordpress
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
spec:
  limits:
  - default:
      memory: 512Mi
    defaultRequest:
      memory: 256Mi
    type: Container
apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-limit-range
spec:
  limits:
  - default:
      cpu: 1
    defaultRequest:
      cpu: 0.5
    type: Container

Taints and Toleratio

kubectl taint nodes node1 app=blue:NoSchedule
kubectl taint nodes node1 app:NoSchedule-          # remove taint
k describe node node1 | grep Taint -A 3 -B 3 -i
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:
  - key: "app"
    operator: "Equal"
    value: "blue"
    effect: "NoSchedule"

Node Selectors

k label nodes node1 size=Large
k get nodes --show-labels
k describe node minikube | grep label -A 10 -B 3 -i
kubectl label node node1 size-

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    size: Large

Node Affinity

k label nodes node1 size=Large
k label nodes node2 size=Medium
k label nodes node3 size=Small
k get nodes --show-labels
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: size
            operator: In
            values:
            - Large
            - Medium
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent

Multi-Container PODs

k exec -it two-containers -c nginx-container -- /bin/bash
apiVersion: v1
kind: Pod
metadata:
  name: two-containers
spec:
  restartPolicy: Never
  volumes:
  - name: shared-data
    emptyDir: {}
  containers:
  - name: nginx-container
    image: nginx
    volumeMounts:
    - name: shared-data
      mountPath: /usr/share/nginx/html
  - name: debian-container
    image: debian
    volumeMounts:
    - name: shared-data
      mountPath: /pod-data
    command: ["/bin/sh"]
    args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]

Probes

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
      failureThreshold: 3
    livenessProbe:
      httpGet:
        path: /
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10
      failureThreshold: 3
readinessProbe: / livenessProbe:
  exec:
    command:
    - cat
    - /tmp/healthy
  initialDelaySeconds: 5
  periodSeconds: 5

Container Logging

k logs -f my-pod
k logs -f my-pod my-container

Monitoring

minikube addons enable metrics-server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.6/components.yaml
k top node
k top pod

ReplicaSets

k scale rs frontend --replicas=10
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: nginx
        image: nginx

Namespace

k create ns dev
k config set-context --current --namespace=dev
apiVersion: v1
kind: Namespace
metadata:
  name: dev

Resource Quotas

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-resources-dev
  namespace: dev
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi

ConfigMaps

kubectl create configmap my-cm --from-literal=DB_NAME=SQL3322 --from-literal=DB_HOST=sql322.mycompany.com 
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-demo
data:
  VAR_1: "1"
  VAR_2: "2"
apiVersion: v1
kind: Pod
metadata:
  name: pod1
  labels:
    app: my-app
    tier: frontend
spec:
  containers:
  - image: nginx
    name: pod1
    env:
    - name: VAR_1
      valueFrom:
        configMapKeyRef:
          name: cm-demo
          key: VAR_1
apiVersion: v1
kind: Pod
metadata:
  name: pod2
  labels:
    app: my-app
    tier: frontend
spec:
  containers:
  - image: nginx
    name: pod2
    envFrom:
    - configMapRef:
        name: cm-demo
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-demo-prop-file
data: 
  application.properties: |
    property.1=value-1
    property.2=value-2
apiVersion: v1
kind: Pod
metadata:
  name: pod3
  labels:
    app: my-app
    tier: frontend
spec:
  containers:
  - image: nginx
    name: pod3
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
     - name: config-volume
       configMap:
         name: cm-demo-prop-file    

Secrets

kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb='
k create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
echo -n 'admin' | base64
apiVersion: v1
kind: Secret
metadata:
  name: mysecret-1
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm
apiVersion: v1
kind: Secret
metadata:
  name: mysecret-2
type: Opaque
stringData:
  config.yaml: |-
    apiUrl: "https://my.api.com/api/v1"
    username: admin
    password: admin
apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: mycontainer
    image: redis
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret-1
            key: username
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret-2

Volumes

minikube ssh
cat /data/number.out
apiVersion: v1
kind: Pod
metadata:
  name: num-generator
spec:
  containers:
  - image: alpine
    name: alpine
    command: ["/bin/sh", "-c"]
    args: ["shuf -i 0-100 -n 1 >> /opt/number.out;"]
    volumeMounts:
    - mountPath: /opt
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /data
      type: DirectoryOrCreate

Persistent Volumes

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"

Persistent Volume Claims

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
apiVersion: v1
kind: Pod
metadata:
  name: num-generator-my
spec:
  containers:
  - image: alpine
    name: alpine
    command: ["/bin/sh", "-c"]
    args: ["shuf -i 0-100 -n 1 >> /opt/number.out;"]
    volumeMounts:
    - mountPath: /opt
      name: data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: my-pvc

Storage Classes

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  iopsPerGB: "10"
  fsType: ext4
---
pvc defenition with storageClassName: slow
---
pod defenition

StatefulSets

Headless Services

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

Deployments

k create deployment --image=nginx nginx
k create deployment --image=nginx nginx --dry-run=client -o yaml
k scale deploy nginx --replicas=10
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Services

k expose pod redis --port=6379 --name redis-service --dry-run=client -o yaml
k expose pod nginx --port=80 --name nginx-service --type=NodePort --dry-run=client -o yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: ClusterIP
  selector:
    app: mysql
  ports:
    - port: 3306
      targetPort: 3306
apiVersion: v1
kind: Service
metadata:
  name: example-service
spec:
  selector:
    app: example
  ports:
    - port: 8765
      targetPort: 9376
  type: LoadBalancer

Ingress

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-space
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-space
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ingress-serviceaccount
  namespace: ingress-space
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-controller
  namespace: ingress-space
spec:
  replicas: 1
  selector:
    matchLabels:
      name: nginx-ingress
  template:
    metadata:
      labels:
        name: nginx-ingress
    spec:
      serviceAccountName: ingress-serviceaccount
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.21.0
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --default-backend-service=app-space/default-http-backend
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
apiVersion: v1
kind: Service
metadata:
  name: ingress
  namespace: ingress-space
spec:
  type: NodePort
  selector:
    name: nginx-ingress
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080
      protocol: TCP
      name: http
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-wear-watch
  namespace: app-space
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - path: /wear
        backend:
          serviceName: wear-service
          servicePort: 8080
      - path: /watch
        backend:
          serviceName: video-service
          servicePort: 8080          

Network Policies

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

Jobs and CronJobs

apiVersion: batch/v1
kind: Job
metadata:
  name: math-add-job
spec:
  completions: 3
  parallelism: 3
  template:
    spec:
      containers:
      - name: math-add
        image: ubuntu
        command: ["expr", "10", "+", "20"]
      restartPolicy: Never
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

Labels, Selectors and Annotations

k get po --selector='my=test'
k get deploy --selector='tier=frontend'
k get po -l app=nginx -l my=test
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
    tier: frontend
  annotations:
    buildVersion: 1.99
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        my: test
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Rolling Updates & Rollbacks in Deployments

k apply -f deployment.yaml --record
k rollout status deployment nginx
k rollout history deployment nginx
k rollout undo deployment nginx --to-revision=1
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment