Кладовочка

О разном, чтобы было под рукой онлайн

Kubernetes: шпаргалка — pods, services, deployments, configmaps, helm, диагностика, RBAC

Kubernetes — стандарт оркестрации контейнеров. Шпаргалка покрывает kubectl, все объекты, Helm, диагностику и обслуживание кластера.

kubectl: основные команды

# Просмотр ресурсов
kubectl get pods                                          # список
kubectl get pods -o wide                                  # с IP и нодой
kubectl get pods -w                                       # watch
kubectl get pods --show-labels                            # с лейблами
kubectl get pods -l app=web                               # фильтр по лейблу
kubectl get all                                            # всё в namespace
kubectl api-resources                                     # все типы ресурсов в кластере

# Информация
kubectl describe pod pod-name                             # полная + события
kubectl describe node node-name                           # ресурсы, условия

# Логи
kubectl logs pod-name                                     # текущий контейнер
kubectl logs pod-name -c container                        # конкретный контейнер
kubectl logs pod-name --previous                          # ПРЕДЫДУЩИЙ экземпляр!
kubectl logs -f pod-name                                  # follow
kubectl logs --tail=100 pod-name                          # последние 100 строк

# Выполнение команд
kubectl exec -it pod-name -- /bin/sh                      # интерактивный shell
kubectl exec pod-name -- ls /app                          # одна команда

# Применение
kubectl apply -f deployment.yaml                          # создать/обновить
kubectl apply -f ./k8s/                                    # вся директория
kubectl diff -f deployment.yaml                            # посмотреть изменения ДО apply!
kubectl delete -f deployment.yaml                         # удалить
kubectl delete pod pod-name --grace-period=0 --force      # жёстко

# Редактирование
kubectl edit deployment deploy-name                       # YAML в редакторе
kubectl patch deployment deploy-name -p '{"spec":{"replicas":3}}'  # patch

kubectl output: jsonpath и форматирование

# jsonpath — извлечение конкретных полей (без jq!)
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.podIP}{"\n"}{end}'

# Кастомные колонки
kubectl get pods -o custom-columns=NAME:.metadata.name,IP:.status.podIP,NODE:.spec.nodeName

# go-template — сложные запросы
kubectl get pods -o go-template='{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'

# Secrets — декодировать одной командой!
kubectl get secret my-secret -o go-template='{{range $k,$v := .data}}{{printf "%s: %s\n" $k ($v|base64decode)}}{{end}}'

# Широкий вывод
kubectl get pods -o wide          # IP + NODE
kubectl get pods -o yaml          # полный манифест
kubectl get pods -o json | jq '.' # JSON + фильтрация

Deployment: полный цикл

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: app
        image: myapp:1.2.3
        ports:
        - containerPort: 3000
        resources:
          requests: { memory: "128Mi", cpu: "100m" }
          limits:   { memory: "256Mi", cpu: "500m" }
        livenessProbe:                    # жив ли?
          httpGet: { path: /health, port: 3000 }
          initialDelaySeconds: 15
          periodSeconds: 10
        readinessProbe:                   # готов принимать трафик?
          httpGet: { path: /ready, port: 3000 }
          initialDelaySeconds: 5
          periodSeconds: 5

Rollout management

kubectl rollout restart deployment/name       # перезапуск подов
kubectl rollout status deployment/name        # следить за статусом
kubectl rollout history deployment/name       # история версий
kubectl rollout undo deployment/name          # откатить на предыдущую
kubectl rollout undo deployment/name --to-revision=3  # на конкретную
kubectl scale deployment name --replicas=5    # масштабирование

Service / Ingress

# Service
apiVersion: v1
kind: Service
metadata: { name: web-service }
spec:
  type: ClusterIP      # ClusterIP | NodePort | LoadBalancer
  selector: { app: web }
  ports:
  - port: 80
    targetPort: 3000
    protocol: TCP

# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
  - hosts: [example.com]
    secretName: tls-secret
  rules:
  - host: example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service: { name: api-service, port: { number: 80 } }
Тип Service Доступ Когда
ClusterIP Внутри кластера БД, внутренние API
NodePort <NodeIP>:30000-32767 Отладка
LoadBalancer Внешний IP Продакшен

ConfigMap / Secret

# ConfigMap
apiVersion: v1
kind: ConfigMap
metadata: { name: app-config }
data:
  APP_ENV: production
  config.json: |
    { "timeout": 30, "retries": 3 }

# Secret
apiVersion: v1
kind: Secret
metadata: { name: db-secret }
type: Opaque
stringData:                  # plaintext (!), закодируется автоматически
  username: admin
  password: s3cret
# или data: (base64 вручную): username: YWRtaW4=

# Использование
spec:
  containers:
  - name: app
    envFrom:
    - configMapRef: { name: app-config }
    - secretRef: { name: db-secret }
    env:
    - name: SINGLE_KEY
      valueFrom:
        configMapKeyRef: { name: app-config, key: LOG_LEVEL }
    volumeMounts:                     # как файлы
    - name: config-vol
      mountPath: /etc/config
  volumes:
  - name: config-vol
    configMap: { name: app-config }

PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata: { name: data-pvc }
spec:
  accessModes: [ReadWriteOnce]
  resources: { requests: { storage: 10Gi } }
  storageClassName: standard

# В поде:
volumes:
- name: data
  persistentVolumeClaim: { claimName: data-pvc }

Helm

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install my-release bitnami/nginx
helm install my-release ./my-chart -f values-prod.yaml
helm upgrade my-release ./my-chart
helm rollback my-release 1
helm uninstall my-release
helm list && helm history my-release
helm template my-release ./my-chart -f values.yaml   # preview
helm get values my-release -a                        # все values

Сеть: диагностика

# DNS
kubectl run -it --rm debug --image=busybox -- nslookup my-service
kubectl exec pod -- nslookup kubernetes.default
kubectl get pods -n kube-system -l k8s-app=kube-dns   # CoreDNS

# Endpoints
kubectl get endpoints service-name                     # должны быть IP подов

# Port forward
kubectl port-forward pod/pod-name 8080:80
kubectl port-forward service/svc-name 8080:80

# Debug pod
kubectl run debug --rm -it --image=alpine -- /bin/sh
kubectl debug -it pod-name --image=busybox --target=app  # ephemeral container

Управление нодами

kubectl cordon node-name           # пометить как unschedulable (новые поды не размещаются)
kubectl drain node-name            # выселить все поды + cordon (перед обслуживанием)
kubectl drain node-name --ignore-daemonsets --delete-emptydir-data
kubectl uncordon node-name         # вернуть в работу

kubectl top nodes                  # потребление ресурсов
kubectl top pods --sort-by=memory
kubectl top pod pod-name --containers

kubectl describe nodes | grep -A5 "Allocated resources"  # загрузка нод

RBAC: краткий справочник

# ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata: { name: app-sa }

# Role (в рамках namespace)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: { name: pod-reader }
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]

# RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata: { name: read-pods }
subjects:
- kind: ServiceAccount
  name: app-sa
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

# ClusterRole + ClusterRoleBinding — глобально (все namespaces)

Диагностика: решение реальных проблем

CrashLoopBackOff

kubectl logs pod-name --previous          # логи ПРЕДЫДУЩЕГО экземпляра!
kubectl describe pod pod-name             # Exit Code: 1(ошибка), 137(OOM), 0(не найдена команда)
kubectl get pod pod-name -o jsonpath='{.spec.containers[*].command}'  # команда запуска

OOMKilled (Exit 137)

kubectl top pod pod-name                  # реальное потребление
kubectl describe pod | grep -A5 "State:"  # Exit Code: 137
# Решение: увеличить limits.memory

ImagePullBackOff

kubectl describe pod | grep -A5 "Events"  # опечатка в теге?
kubectl create secret docker-registry regcred \
  --docker-server=reg.example.com --docker-username=u --docker-password=p
# spec.imagePullSecrets: [{ name: regcred }]

Pending — не может запуститься

kubectl describe pod pod-name             # Events — причина
kubectl describe nodes | grep -A5 "Allocated resources"
kubectl get pvc && kubectl describe pvc    # если ждёт том

ConfigMap не обновляет поды

# env не обновляются — нужен restart
kubectl rollout restart deployment/name

# Монтирование томом — обновится через ~60 сек (kubelet)
# Авто-хеш для авто-рестарта при изменении ConfigMap (Helm):
# template.metadata.annotations:
#   checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}

Полезные однострочники

# Поды с IP и нодой
kubectl get pods -o wide

# Поды с ошибками
kubectl get pods --field-selector=status.phase!=Running

# Удалить все Evicted-поды
kubectl get pods --field-selector=status.phase=Failed -o name | xargs kubectl delete

# События за последний час
kubectl get events --sort-by='.lastTimestamp'

# Ресурсы по подам
kubectl top pods --sort-by=memory
kubectl top pods -A --sort-by=cpu | head -20

# Рестарты подов
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.containerStatuses[*].restartCount}{"\n"}{end}' | column -t

# Все образы в подах
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'

# Secret decode (jq)
kubectl get secret my-secret -o json | jq '.data | map_values(@base64d)'

Частые проблемы и их решения

Проблема Причина ✅ Решение
CrashLoopBackOff Приложение падает kubectl logs pod --previous
ImagePullBackOff Неверный тег / нет registry Проверить имя, создать imagePullSecrets
OOMKilled (137) Превышена память Увеличить limits.memory
Pending Нет ресурсов / PVC describe pod → Events
DNS не работает CoreDNS / NetworkPolicy kubectl get pods -n kube-system
Ingress 404 host / path неверный Проверить host: и pathType: Prefix
Service не находит поды Labels не совпадают kubectl get endpoints svc
ConfigMap не обновился env не автообновляемы kubectl rollout restart
PVC не создаётся Нет StorageClass kubectl describe pvc
Нет доступа к API RBAC / ServiceAccount Проверить Role + RoleBinding

Полезные ресурсы


Что дальше

Связанные шпаргалки: Docker, Linux Commands, Git Advanced, DevOps