Инструменты пользователя

Инструменты сайта


how-to:kubernetes

Kubernetes

https://kubernetes.io/ru/docs/tasks/tools/install-kubectl/ - способы установки kubectl (curl,apt,snap)

Команды

Удалить namespace со статусом Terminating:

NAMESPACE=<namespace>
kubectl proxy &
kubectl get ns $NAMESPACE -o json | jq '.spec = {"finalizers":[]}' > /tmp/$NAMESPACE.json
curl -k -H "Content-Type: application/json" -X PUT --data-binary @/tmp/$NAMESPACE.json 127.0.0.1:8001/api/v1/namespaces/$NAMESPACE/finalize

https://stackoverflow.com/questions/52369247/namespace-stuck-as-terminating-how-do-i-remove-it
https://github.com/Azure/AKS/issues/733

Удалить pod со статусом Terminating:

kubectl -n ${NAMESPACE} delete pod ${POD} --grace-period=0 --force

Запустить pod в интерактивном режиме:

kubectl -n default run test -it --rm --image=alpine --restart=Never sh

Запустить nvidia-smi в pod с affinity и tolerations

Запустить nvidia-smi в pod с affinity и tolerations

kubectl -n dev run test -it --rm --image=nvidia/cuda:11.0.3-base --restart=Never --overrides='{"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"gpu","operator":"In","values":["T4"]}]}]}}},"tolerations":[{"effect":"NoSchedule","key":"sku","operator":"Equal","value":"gpu"}]}}' nvidia-smi

overrides:

{
  "spec": {
    "affinity": {
      "nodeAffinity": {
        "requiredDuringSchedulingIgnoredDuringExecution": {
          "nodeSelectorTerms": [
            {
              "matchExpressions": [
                {
                  "key": "gpu",
                  "operator": "In",
                  "values": [
                    "T4"
                  ]
                }
              ]
            }
          ]
        }
      }
    },
    "tolerations": [
      {
        "effect": "NoSchedule",
        "key": "sku",
        "operator": "Equal",
        "value": "gpu"
      }
    ]
  }
}


Запустить pod c использованием secret и configmap

Запустить pod c использованием secret и configmap

apiVersion: v1
kind: ConfigMap
metadata:
  name: cronjob-weekly
data:
  config.json: "
{
  "test":"configMap"
}
"
{
  "apiVersion": "v1",
  "kind": "Secret",
  "metadata": {
    "name": "secretname"
  },
  "type": "Opaque",
  "data": {
    "secretkey": "dGhpc3NlY3JldA=="
  }
}
kubectl -n dev run test -it --rm --image=alpine --restart=Never --overrides='{"spec":{"volumes":[{"name":"volumeconfig","configMap":{"name":"сonfig"}}],"containers":[{"image":"alpine","imagePullPolicy":"IfNotPresent","name":"test","env":[{"name":"VARIABLE_SECRET","valueFrom":{"secretKeyRef":{"name":"secretname","key":"secretkey"}}}],"volumeMounts":[{"name":"volumeconfig","mountPath":"/tmp/volumeconfig","readOnly":true}],"command":["/bin/sh","-c"],"args":["echo Variable=\"$(VARIABLE_SECRET)\"; cat /tmp/volumeconfig/config.json"]}]}}'


Удалить namespace:

kubectl delete ns dev1 --force --grace-period=0

Редактировать с редактором mcedit:

KUBE_EDITOR="mcedit" kubectl edit -n monitoring pods prometheus-cluster-monitoring-prometh-prometheus-0

Увеличить кол-во реплик:

kubectl scale --replicas=2 deployment $DEPLOYMENT -n $NAMESPACE

Мониторинг

CPU/Memory

Показать аргументы statefulsets prometheus-cluster-monitoring-prometh-prometheus контейнера prometheus:

kubectl get statefulsets prometheus-cluster-monitoring-prometh-prometheus -o=json | jq -r '.spec.template.spec.containers[] | select( ."name" == "prometheus" ).args'

Показать все поды и их образы:

kubectl get pods -o='custom-columns=PODS:.metadata.name,Images:.spec.containers[*].image'

http://itisgood.ru/2019/10/24/kubectl-shpargalka-vseh-neobhodimyh-komand-kubernetes-chast-1/
https://kubernetes.io/ru/docs/reference/kubectl/cheatsheet/

Показать все контейнеры в подах:

kubectl get pods -o=custom-columns=NameSpace:.metadata.namespace,NAME:.metadata.name,CONTAINERS:.spec.containers[*].name

Показать потребление ресурсов для каждой ноды (с сортировкой по памяти):

kubectl top node --sort-by='memory'

Показать потребление ресурсов подами на ноде:

kubectl top pod -A | grep -P "$(kubectl get pod -A -o wide | grep ${NODENAME} | awk '{print $1,"+",$2}'| paste -s -d '|')"
kubectl describe node ${NODENAME}

Images

Показать образы и их размер на нодах:

kubectl get nodes -o json | jq '.items[].status.images[] | .names[1], (.sizeBytes | tonumber/1024/1024)'

https://kubernetes.io/docs/tasks/access-application-cluster/list-all-running-container-images/

Storage

Недостоверно

Недостоверно

Информация о диске нод:

kubectl get nodes -o json | jq -r '.items[].status | .addresses[0].address, (.capacity,.allocatable | ."ephemeral-storage")'
kubectl get node ${NODENAME} -o json | jq -r '.status | .addresses[0].address, (.capacity,.allocatable | ."ephemeral-storage")'


port-foward

kubectl port-forward -n monitoring svc/cluster-monitoring-prometh-prometheus --address 0.0.0.0 9090:9090

Удалить

Пример удаления grafana:

kubectl delete deployment cluster-monitoring-grafana -n monitoring
kubectl delete svc cluster-monitoring-grafana -n monitoring

Удалить все поды со статусом Evicted:

kubectl get pods --all-namespaces -o json | jq '.items[] | select(.status.reason!=null) | select(.status.reason | contains("Evicted")) | "kubectl delete pods \(.metadata.name) -n \(.metadata.namespace)"' | xargs -n 1 sh -c
#или
kubectl delete pods --field-selector 'status.phase==Failed' --all-namespaces

Перегрузить

config

Показать все контексты:

kubectl config get-contexts

Изменить текущий контекст:

kubectl config use-context context_name

Показать текущий namespace:

kubectl config view --minify -o jsonpath='{..namespace}'

Изменить namespace по умолчанию для сессии:

kubectl config set-context $(kubectl config current-context) --namespace=monitoring

secret

Показать secret в декодированном виде:

kubectl get secret $SECRET -o go-template='{{range $k,$v := .data}}{{printf "%s: " $k}}{{if not $v}}{{$v}}{{else}}{{$v | base64decode}}{{end}}{{"\n"}}{{end}}'

или

kubectl get secret $SECRET -o json | jq '.data | map_values(@base64d)'
kubectl get secret $SECRET -o json | jq '.data | @base64d'

Показать сертификат tls.crt из секрета $SECRET в x509 формате:

kubectl get secret $SECRET -o json | jq -r '.data."tls.crt"' | base64 -d | openssl x509 -text -noout

Обновить tls секрет:

kubectl create secret tls $SECRET --dry-run=client --key=./tls.key --cert=./tls.crt -o yaml --dry-run=client | kubectl apply -f -

Обновить/добавить один из ключей секрета:

kubectl get secret $SECRET -o json | jq --arg VARIABLE "$(echo VALUE | base64 -w 0)" '.data["KEYNAME"]=$VARIABLE' | kubectl apply -f -
# или только с помощью jq
kubectl get secret $SECRET -o json | jq '.data["KEYNAME"]="VALUE" | .data["KEYNAME"] |= @base64' | kubectl apply -f -

Удалить один из ключей секрета:

kubectl get secret $SECRET -o json | jq 'del(.data["KEYNAME"]) | kubectl apply -f -

label

Показать все метки узлов:

kubectl get nodes --show-labels
kubectl get node ${NODENAME} --show-labels
#json
kubectl get nodes -o json  | jq ".items[].metadata.labels"
kubectl get node ${NODENAME} -o json  | jq ".metadata.labels"

Назначить метку узлу:

kubectl label nodes <nodename> <label-key>=<label-value>

Удалить метку namelabel у namespace ingress:

kubectl label namespace ingress namelabel-

https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/

taint

Показать все taint всех нод:

kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints --no-headers

Показать все taint одной ноды:

kubectl get nodes <nodename> -o json | jq '.spec.taints[]'

https://stackoverflow.com/questions/43379415/how-can-i-list-the-taints-on-kubernetes-nodes/59494876

ingress

nginx

tls certificate

Генерация сертификата через annotations cert-manager в ingress nginx:

kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"

https://stackoverflow.com/questions/59958837/cant-get-a-tls-certificate-in-cert-manager
https://www.fosstechnix.com/kubernetes-nginx-ingress-controller-letsencrypt-cert-managertls/

https://github.com/kubernetes/ingress-nginx/blob/master/internal/ingress/annotations/ipwhitelist/main_test.go

Nodes

Пометить ноду как unschedulable (SchedulingDisabled):

kubectl cordon $NODENAME

Пометить ноду как schedulable:

kubectl uncordon $NODENAME

Private Registry

https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account

Запустить в интерактивном режиме из приватного репозитория:

kubectl -n default run test -it --rm --restart=Never --image=privateregistry.domain.com/alpine --overrides='{ "apiVersion": "v1", "spec": {"imagePullSecrets": [{"name": "regcred"}]} }'

Запустить на определённой ноде через affinity:

--overrides='{ "spec": { "affinity": { "nodeAffinity": { "requiredDuringSchedulingIgnoredDuringExecution": { "nodeSelectorTerms": [{ "matchExpressions": [{ "key": "gpu", "operator": "In", "values": [ "T4" ]} ]} ]} } } } }'

Запустить на определённой ноде через affinity и tolerations:

--overrides='{ "spec": { "affinity": { "nodeAffinity": { "requiredDuringSchedulingIgnoredDuringExecution": { "nodeSelectorTerms": [{ "matchExpressions": [{ "key": "sku", "operator": "In", "values": [ "monitoring" ]} ]} ]} } }, "tolerations": [{ "effect": "NoSchedule", "key": "sku", "operator": "Equal", "value": "monitoring" }] }}'

Volume

Azure

Монитирование

Монтирование напрямую (azure disk и azure file)

Монтирование напрямую (azure disk и azure file)

azure-disks.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - image: alpine
    name: mypod
    command:
      - /bin/sh
      - "-c"
      - "sleep 60m"
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 250m
        memory: 256Mi
    volumeMounts:
      - name: adisk
        mountPath: /mnt/adisk
      - name: afile
        mountPath: /mnt/afile
  volumes:
      - name: adisk
        azureDisk:
          kind: Managed
          diskName: minio-backup
          diskURI: /subscriptions/<SUBSCRIPTIONID>/resourceGroups/<MCRESORCEGROUP>/providers/Microsoft.Compute/disks/<DISKNAME>
      - name: afile
        azureFile:
          secretName: azure-secret
          shareName: <SHARENAME>
          readOnly: false

Монтирование через pvc (azure file)

Монтирование через pvc (azure file)

azure-disks.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - image: alpine
    name: mypod
    command:
      - /bin/sh
      - "-c"
      - "sleep 60m"
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 250m
        memory: 256Mi
    volumeMounts:
      - name: afile
        mountPath: /mnt/afile
  volumes:
  - name: afile
    persistentVolumeClaim:
      claimName: azurefile

Создать PV и PVC
azure-pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: file.csi.azure.com
  name: azurefile
spec:
  capacity:
    storage: 64Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: azurefile-csi
  csi:
    driver: file.csi.azure.com
    readOnly: false
    volumeHandle: <idforcluster-afile>
    volumeAttributes:
      shareName: <SHARENAME>
    nodeStageSecretRef:
      name: azure-storage-account-dvsminio-secret
      namespace: <NAMESPACE>
  mountOptions:
    - dir_mode=0777
    - file_mode=0777
    - uid=0
    - gid=0
    - mfsymlinks
    - cache=strict
    - nosharesock
    - nobrl

azure-pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: azurefile
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: azurefile-csi
  volumeName: azurefile
  resources:
    requests:
      storage: 64Gi
kubectl apply -f azure-pv.yaml
kubectl apply -f azure-pvc.yaml


Перед запуском пода, для azure files создать секрет (Storage accounts → $STORAGEACCOUNT → Access keys):

kubectl create secret generic azure-secret --from-literal=azurestorageaccountname=$STORAGEACCOUNT --from-literal=azurestorageaccountkey=$STORAGE_KEY

Запустить pod с дисками:

kubectl apply -f azure-disks.yaml

https://docs.microsoft.com/en-us/azure/aks/azure-disk-volume
https://docs.microsoft.com/en-us/azure/aks/azure-files-volume
https://github.com/MicrosoftDocs/azure-docs/blob/main/articles/aks/azure-files-volume.md

Plugins

Krew

Установить

Установить

(
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)
echo ${PATH} | grep krew || export PATH="$PATH:${KREW_ROOT:-$HOME/.krew}/bin"
grep krew $HOME/.bashrc || echo "export PATH=\"$PATH\"" | tee -a $HOME/.bashrc
kubectl krew install ctr ctx ns resource-capacity


https://krew.sigs.k8s.io/plugins/

Примеры

Проблемы

Multi-Attach error for Volume "pvc-xx" Volume is already Used

Решения:
Уменьшить кол-во реплик до 0 и вернуть:

kubectl -n <namespace> scale deployment/<deployment_name> --replicas=0
#после уменьшения вернуть:
kubectl -n <namespace> scale deployment/<deployment_name> --replicas=<desired_replica>

Изменить стратегию обновления:

.spec.strategy.type==Recreate

пример в helm:

--set deploymentUpdate.type=Recreate

или использовать внешние тома, а также тома ReadWriteMany(RWX)
или использовать приложение как StatefulSet вместо Deployment

https://www.cyberithub.com/solved-multi-attach-error-for-volume-pvc-xx-volume-is-already/

Status: Terminating

Решение:

kubectl patch pv <PVNAME> -p '{"metadata":{"finalizers":null}}'
kubectl patch pvc <PVCNAME> -p '{"metadata":{"finalizers":null}}'
kubectl patch pod <PODNAME> -p '{"metadata":{"finalizers":null}}'
#для pod
kubectl exec <PODNAME> -- kill 1

Ссылки

https://kubernetes.io/ru/docs/reference/kubectl/cheatsheet/ - Шпаргалка по kubectl
https://prudnitskiy.pro/post/2021-01-15-k8s-pod-distribution/ - Распределяем pod-ы по машинам в kubernetes
https://k8slens.dev/ - The Kubernetes management tool

how-to/kubernetes.txt · Последнее изменение: lioncub