Learning Platform
Глоссарий Troubleshooting
Урок 04.01 · 18 мин
Средний
kubectlkubeconfigEKSGKEAKSauthversion skew

Установка и конфигурация kubectl

Прежде чем разбирать команды, договоримся об одной вещи, которая снимает половину магии вокруг Kubernetes. kubectl — это обычный HTTP-клиент. Он не знает про Pod-ы, Deployments и Services больше, чем знает curl про эти ресурсы. Внутри kubectl читает файл ~/.kube/config, формирует TLS-соединение с kube-apiserver (обычно на порту 6443), отправляет JSON-запросы, парсит ответы и форматирует их в таблицу для вашего терминала. Всё, что вы будете делать в курсе, — это HTTP GET/POST/PATCH/DELETE на REST endpoints /api/v1/... и /apis/<group>/<version>/.... Когда вы это окончательно усвоите, фраза «kubectl не работает» перестанет существовать — будет «TLS handshake failed», «401 Unauthorized», «context указывает на мёртвый кластер». Каждое из этих сообщений лечится одним конкретным способом.


SSH в глубину: ключи, config, tunneling, multiplexing

Установка под все ОС

Бинарь kubectl поставляется отдельно от cluster. Это критично понимать: вы можете иметь один kubectl и десяток разных кластеров (production EKS, staging GKE, локальный kind), и переключаться между ними сменой контекста — не переустанавливая бинарь.

Варианты установки kubectl v1.35
macOSHomebrew — стандарт. brew install kubectl. Альтернатива: прямой скачать бинарь с dl.k8s.io.
Linux (Debian/Ubuntu)Официальный apt-репозиторий pkgs.k8s.io. Добавить ключ, добавить source, apt update, apt install -y kubectl.
Linux (RHEL/CentOS)dnf-репозиторий pkgs.k8s.io. Аналогично apt, только yum/dnf install kubectl.
WindowsChocolatey: choco install kubernetes-cli. Альтернатива: scoop install kubectl, либо прямой бинарь kubectl.exe.
Прямой бинарьdl.k8s.io/release/v1.35.0/bin/{linux,darwin,windows}/{amd64,arm64}/kubectl. Скачать → chmod +x → mv /usr/local/bin/. Самый портабельный способ, подходит для CI и контейнеров.

Универсальный способ — прямое скачивание с dl.k8s.io:

# Linux amd64
curl -LO "https://dl.k8s.io/release/v1.35.0/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# macOS Apple Silicon
curl -LO "https://dl.k8s.io/release/v1.35.0/bin/darwin/arm64/kubectl"
chmod +x kubectl && sudo mv kubectl /usr/local/bin/

# Windows (PowerShell)
curl.exe -LO "https://dl.k8s.io/release/v1.35.0/bin/windows/amd64/kubectl.exe"

После установки убедитесь, что версия — та, которую ожидаете:

kubectl version --client
# Client Version: v1.35.0
# Kustomize Version: v5.x.x

Skew policy: версия kubectl и cluster

Kubernetes даёт официальную гарантию совместимости между версиями. kubectl поддерживается в пределах +/-1 minor от cluster version. То есть кластер v1.35 совместим с kubectl v1.34, v1.35, v1.36. С kubectl v1.32 — undefined behaviour: часть команд может работать, часть — нет, поля могут не сериализоваться.

WARNING

В команде, где кто-то держит cluster v1.30, а на лаптопе уже v1.35 — kubectl apply для новых полей будет молча отбрасывать их, потому что apiserver их не знает. Версия kubectl должна следовать за версией production cluster, не опережая её слишком сильно.

ClusterПоддерживаемые kubectl
v1.35v1.34, v1.35, v1.36
v1.34v1.33, v1.34, v1.35
v1.33v1.32, v1.33, v1.34

На CKAD-экзамене это редко становится проблемой — там фиксированная версия kubectl и cluster, оба соответствуют экзаменационному релизу. Но в реальной работе вы будете держать несколько kubectl рядом (через asdf, mise или симлинки kubectl-1.33, kubectl-1.35) и переключаться под кластер.


kubeconfig: где хранятся credentials

Когда вы запускаете kubectl get pods, он должен ответить на три вопроса:

  1. На какой apiserver слать запрос (URL и его CA-сертификат)?
  2. Под каким пользователем (cert+key, bearer token, exec plugin)?
  3. В каком namespace искать ресурсы?

Все три ответа лежат в файле ~/.kube/config — это kubeconfig. Обычный YAML, который вы можете открыть и прочитать.

# Путь по умолчанию
ls -la ~/.kube/config

# Альтернативный путь через флаг
kubectl --kubeconfig=/path/to/other.yaml get pods

# Несколько файлов через env (Linux/macOS: ":", Windows: ";")
export KUBECONFIG="$HOME/.kube/config:$HOME/.kube/work-config:$HOME/.kube/eks-prod"
kubectl config view  # merged view всех файлов

Когда KUBECONFIG содержит несколько путей, kubectl мерджит их в один логический view: clusters, users, contexts со всех файлов объединяются. Если есть конфликт имён — приоритет у первого файла в списке. Это удобно: храните каждый кластер в отдельном файле, не редактируя один большой ~/.kube/config.


Структура kubeconfig

Файл состоит из трёх списков (clusters, users, contexts) и одного указателя (current-context). Минимальный пример:

apiVersion: v1
kind: Config
current-context: dev-cluster

clusters:
- name: dev-cluster
  cluster:
    server: https://192.168.1.10:6443
    certificate-authority-data: LS0tLS1CRUdJTi...  # base64(CA cert)

users:
- name: dev-admin
  user:
    client-certificate-data: LS0tLS1CRUdJTi...    # base64(cert)
    client-key-data: LS0tLS1CRUdJTi...            # base64(private key)

contexts:
- name: dev-cluster
  context:
    cluster: dev-cluster
    user: dev-admin
    namespace: dev
Три сущности kubeconfig
clusterОПИСАНИЕ КЛАСТЕРА. server: URL apiserver (обычно https://host:6443). certificate-authority(-data): CA, которым подписан TLS apiserver — kubectl его использует для верификации. Альтернатива — insecure-skip-tls-verify: true (НЕ для prod).
userУЧЁТНЫЕ ДАННЫЕ. Варианты: (1) client-certificate + client-key — mTLS, (2) token — bearer JWT (для ServiceAccount), (3) username/password — Basic auth (deprecated), (4) exec — внешний плагин (aws-iam-authenticator, gcloud), (5) auth-provider — OIDC.
связываются через context
contextПАРА cluster+user плюс default namespace. Имя контекста — произвольная строка. current-context на верхнем уровне kubeconfig указывает, какой контекст активен сейчас. Все kubectl команды используют его, пока не передан --context другой.

Ключевая идея: cluster и user независимы. Один кластер можно использовать под разными user (admin, viewer, ci-bot) — это разные context, ссылающиеся на один cluster. Один user может работать с несколькими кластерами (dev и staging) — это разные context с одним user.


Варианты аутентификации в user-entry

Это самая запутанная часть kubeconfig — поэтому разберём по типам:

1. Client cert + key (статическая mTLS):

users:
- name: admin
  user:
    client-certificate-data: <base64>
    client-key-data: <base64>

Так выглядит kubeconfig, который генерирует kubeadm для админа cluster. Сертификат подписан CA, который apiserver принимает. CN в сертификате становится username, O — группами (для RBAC).

2. Bearer token (для ServiceAccount или OIDC):

users:
- name: ci-bot
  user:
    token: eyJhbGciOiJSUzI1NiIs...

ServiceAccount token, JWT от OIDC-провайдера, static token из --token-auth-file apiserver. kubectl добавит заголовок Authorization: Bearer <token> к каждому запросу.

3. Exec plugin (динамический token):

users:
- name: eks-user
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1
      command: aws
      args: ["eks", "get-token", "--cluster-name", "my-cluster"]

kubectl запускает внешнюю команду (aws, gcloud, az), получает свежий token, использует его. Так работают managed clusters — token живёт 10-15 минут, exec plugin обновляет его прозрачно.

4. OIDC через auth-provider (устаревает в v1.35):

users:
- name: dex-user
  user:
    auth-provider:
      name: oidc
      config:
        idp-issuer-url: https://dex.company.com
        client-id: kubernetes
        refresh-token: <token>

Этот формат deprecated в пользу exec plugins (kubelogin).


Managed K8s: автоматическая генерация kubeconfig

В production вы редко руками редактируете kubeconfig для облачных кластеров. У каждого provider есть команда, которая аппендит нужный context в ваш ~/.kube/config:

# AWS EKS
aws eks update-kubeconfig --region us-east-1 --name prod-cluster
# Создаёт context arn:aws:eks:us-east-1:123456:cluster/prod-cluster
# user — exec aws eks get-token

# Google GKE
gcloud container clusters get-credentials prod-cluster \
  --region us-central1 --project my-project
# Создаёт context gke_my-project_us-central1_prod-cluster
# user — exec gke-gcloud-auth-plugin

# Azure AKS
az aks get-credentials --resource-group prod --name prod-cluster
# Создаёт context prod-cluster
# user — exec kubelogin (или legacy token)

# Yandex Cloud Managed K8s
yc managed-kubernetes cluster get-credentials prod-cluster --external

После любой из этих команд kubectl config get-contexts покажет новый context. Дальше — kubectl config use-context <name> и работаете.

TIP

Команды update-kubeconfig / get-credentials — идемпотентны. Запускайте сколько угодно раз — они только обновят запись, не сломают ничего другого. На новом ноутбуке после git clone infrastructure-as-code обычно достаточно прогнать список всех нужных команд — и весь набор кластеров готов.


Безопасность: kubeconfig — это secret

То, что в ~/.kube/config лежит plaintext YAML, может ввести в заблуждение. Это файл, дающий полный доступ к кластеру для того user, на который он указывает. Если у вас admin-context — получивший этот файл получает кластер.

DANGER

Никогда не коммитьте ~/.kube/config в git. Никогда не передавайте через Slack/email. Если случайно опубликовали — немедленно: (1) сделайте kubectl config view --raw -o yaml чтобы понять, какой user скомпрометирован, (2) revoke его в IAM/IdP, (3) сгенерируйте новые credentials. Просто удалить файл из git history недостаточно — он уже в копиях, кэшах и forks.

Хорошие практики:

  • Права файла: chmod 600 ~/.kube/config — читать только owner.
  • Никаких long-lived static tokens. Только exec plugins или OIDC с коротким TTL.
  • Один user — одни RBAC permissions (виду нужен viewer, ci-bot — отдельный SA с deploy-правами).
  • Для prod кластеров — отдельный KUBECONFIG=~/.kube/prod.yaml, который вы экспортируете в shell только когда действительно работаете с prod.
  • Включить --token-ttl минимальным где можно. exec plugin AWS возвращает токен на 14 минут — это нормально, ничего удлинять не нужно.

Быстрая проверка после установки

После любых манипуляций с kubectl и kubeconfig прогоните три команды. Если все три работают — окружение готово:

kubectl version            # client + server version, проверка skew
kubectl config current-context   # какой context активен
kubectl get nodes          # реальный запрос к apiserver

Если version показывает server version: <unknown> или nodes падает с connection refused — apiserver недостижим (firewall, VPN, кластер выключен). Если Unauthorized — credentials битые (cert истёк, token revoked). Если forbidden — auth прошёл, но RBAC запрещает действие. Каждое из этих сообщений локализует проблему до одного уровня.


Что дальше

В следующем уроке — два паттерна работы с API: imperative и declarative. На CKAD вы будете чередовать оба — imperative для генерации заготовок, declarative для финальных манифестов. И поймём, какие fields kubectl на самом деле отправляет в apiserver — потому что между YAML на диске и состоянием в etcd есть пара трансформаций, которые иногда удивляют.


Проверка знанийKnowledge check
Объясните, почему kubectl и kube-apiserver должны быть совместимы по версиям, и какой допускается skew. Что произойдёт, если запустить kubectl v1.32 против cluster v1.35?
ОтветAnswer
kubectl и apiserver общаются через REST API, схема которого эволюционирует от версии к версии: новые поля добавляются, старые могут deprecate. Официальный skew — +/-1 minor: cluster v1.35 поддерживает kubectl v1.34, v1.35, v1.36. Это даёт окно для обновления одного раньше другого. При запуске kubectl v1.32 против cluster v1.35: (1) часть команд может работать, потому что REST endpoints сохраняют backward compatibility, (2) команды для новых ресурсов (введённых после v1.32) — например, ValidatingAdmissionPolicy в v1.30 — могут не работать, kubectl не знает таких kinds, (3) при `apply` новые spec-поля будут молча отброшены, потому что kubectl сериализует только известные ему поля. Результат — частично работающее окружение с тихими багами. Поэтому в проде версия kubectl должна следовать за версией cluster, обновляясь синхронно.

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 5. У вас kubectl v1.32 на лаптопе, в production cluster v1.35. Что произойдёт при попытке `kubectl apply -f deployment.yaml` с новым полем, появившимся в v1.34?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5