Предисловие переводчика: Эта статья — комбинация из перевода двух материалов от проекта CoreOS (см. ссылки в конце публикации), посвящённых работе с консольным инструментом для выполнения команд на кластерах Kubernetes — kubectl. Листинг, приведённый автором оригинала для Mac OS X, был адаптирован под Linux, в других листингах было исправлено форматирование YAML, а для удобства чтения всего материала в него были добавлены подзаголовки.

Kubectl — инструмент, который знаком пользователям Kubernetes и обладает широкими функциональными возможностями. Овладение ими занимает время, но позволяет увидеть, что это более мощный инструмент, чем многие предполагали. Представляю набор советов, позволяющих улучшить ваши возможности при работе с
В

Слияние конфигов с контекстами через
Слияние конфигураций Kubernetes — популярный паттерн, если вы взаимодействуете со множеством кластеров Kubernetes. При работе с разными конфигами используется концепция контекста (
Например, у вас есть два конфига Kubernetes для разных кластеров, и требуется провести их слияние.
Конфиг первого кластера:
Конфиг второго кластера:
Их слияние можно выполнить с помощью
У каждого конфигурационного файла есть единственный контекст, так что они не конфликтуют между собой. Слияние двух файлов через
Список файлов, экспортируемых с
Остаётся только поддерживать правильное значение
Новый контекст можно использовать так:
Чтобы узнать больше о возможностях, предоставляемых Kubernetes API, запросите файл
Можно также зайти на
Поскольку
Просмотр
А вот следующая команда описывает API, доступные в кластере Kubernetes и к которым у вас есть доступ. Команда в примере ниже выполнена под пользователем-администратором. Если у вас включён контроль доступа по RBAC, вывод может отличаться:
Команда
Попробуйте выполнить
Операции с подами через
Все последующие примеры используют Kubernetes API, чтобы узнать что-либо о подах. Одним из способов получения нужных данных — построить запрос и понять, какое его выражение потребуется в терминах
Если у вас нет запущенного приложения, для знакомства с примерами можно создать поды с лейблом run=shop и запустить их как сервис на порту 80:
Теперь можно посмотреть, что мы будем делать с
Укажите пространство имён (
Укажите пространство имён (
Операции с узлами (нодами) через
Комбинация
Зачастую высокоуровневая статистика помогает в отладке. Эта команда подсчитает количество всех подов на каждом из узлов:
Запросы с лейблами можно использовать и для узлов. Такой подход часто применяется при конфигурации deployments, нуждающихся в определённых ограничениях. Для получения подробной информации о селекторах смотрите вывод
Вывести все лейблы можно с помощью аргумента
Генерируется JSON-документ с названием узла Kubernetes и список всех названий подов, запущенных на этом узле. Очень полезная команда при отладке:
Примечание: Читайте в нашем блоге перевод другой статьи от CoreOS про работу с Kubernetes из консоли: «Автоматизация SSH-доступа к нодам Kubernetes с помощью Fabric и интеграции от CoreOS», а также заметку «Полезные утилиты при работе с Kubernetes» (в ней представлены преимущественно консольные инструменты).

Kubectl — инструмент, который знаком пользователям Kubernetes и обладает широкими функциональными возможностями. Овладение ими занимает время, но позволяет увидеть, что это более мощный инструмент, чем многие предполагали. Представляю набор советов, позволяющих улучшить ваши возможности при работе с
kubectl. Не забудьте также посмотреть на cheat sheet в секции официальной документации Kubernetes!Автоматическое дополнение в shell
В
kubectl есть отличное встроенное автодополнение для bash и zsh, что значительно упрощает работу с командами, флагами и объектами вроде пространств имён и названий подов. В документации есть готовые инструкции по его включению. А GIF-анимация ниже показывает, как автодополнение работает:
# Подключить код автодополнения для текущего сеанса в Bash
source <(kubectl completion bash)
# … или добавить код автодополнения в файл и подключить его к .bashrc
mkdir ~/.kube
kubectl completion bash > ~/.kube/completion.bash.inc
printf "\n# Kubectl shell completion\nsource '$HOME/.kube/completion.bash.inc'\n" >> $HOME/.bashrc
source $HOME/.bashrc
# Альтернатива — подключить код автодополнения для текущего сеанса в Zsh
source <(kubectl completion zsh)Слияние конфигов с контекстами через KUBECONFIG
Слияние конфигураций Kubernetes — популярный паттерн, если вы взаимодействуете со множеством кластеров Kubernetes. При работе с разными конфигами используется концепция контекста (
context), указывающего на параметры, которые kubectl будет использовать для поиска конкретного, целевого кластера. Но добиться нужного результата с контекстами бывает сложно. Чтобы упростить себе жизнь, воспользуйтесь переменной окружения KUBECONFIG — она позволяет указать на конфигурационные файлы, которые используются при слиянии. Подробнее о KUBECONFIG можно прочитать в официальной документации.Например, у вас есть два конфига Kubernetes для разных кластеров, и требуется провести их слияние.
Конфиг первого кластера:
$ kubectl config view --minify > cluster1-configapiVersion: v1
clusters:
- cluster:
certificate-authority: cluster1_ca.crt
server: https://cluster1
name: cluster1
contexts:
- context:
cluster: cluster1
user: cluster1
name: cluster1
current-context: cluster1
kind: Config
preferences: {}
users:
- name: cluster1
user:
client-certificate: cluster1_apiserver.crt
client-key: cluster1_apiserver.keyКонфиг второго кластера:
$ cat cluster2-configapiVersion: v1
clusters:
- cluster:
certificate-authority: cluster2_ca.crt
server: https://cluster2
name: cluster2
contexts:
- context:
cluster: cluster2
user: cluster2
name: cluster2
current-context: cluster2
kind: Config
preferences: {}
users:
- name: cluster2
user:
client-certificate: cluster2_apiserver.crt
client-key: cluster2_apiserver.keyИх слияние можно выполнить с помощью
KUBECONFIG. Преимуществом такого слияния станет возможность динамически переключаться между контекстами. Контекст — это «сопоставление» (map), включающее в себя описания кластера и пользователя, а также название, с помощью которого на конфигурацию можно ссылаться для аутентификации кластера и взаимодействия с ним. Флаг --kubeconfig позволяет посмотреть на контекст для каждого файла:$ kubectl --kubeconfig=cluster1-config config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* cluster1 cluster1 cluster1
$ kubectl --kubeconfig=cluster2-config config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* cluster2 cluster2 cluster2У каждого конфигурационного файла есть единственный контекст, так что они не конфликтуют между собой. Слияние двух файлов через
KUBECONFIG показывает оба контекста. Для сохранения текущего контекста создайте новый пустой файл с названием cluster-merge:$ export KUBECONFIG=cluster-merge:cluster-config:cluster2-config
dcooley@lynx ~
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* cluster1 cluster1 cluster1
cluster2 cluster2 cluster2Список файлов, экспортируемых с
KUBECONFIG, загружается в строгом порядке. Поэтому контекст, который выбирается, соответствует указанному как current-context в первом конфиге. Изменение контекста на cluster2 смещает знак текущего (*) к этому контексту в списке, и команды kubectl начинают применяться к этому (второму) контексту:$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* cluster1 cluster1 cluster1
cluster2 cluster2 cluster2
$ kubectl config use-context cluster2
Switched to context "cluster2".
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
cluster1 cluster1 cluster1
* cluster2 cluster2 cluster2
$ cat cluster-mergeapiVersion: v1
clusters: []
contexts: []
current-context: cluster2
kind: Config
preferences: {}
users: []Остаётся только поддерживать правильное значение
current-context. Использовать контексты Kubernetes и осуществлять их слияние можно разными способами. Например, вы можете создать контекст (cluster1_kube-system), который будет определять пространство имён (kube-system) для всех исполняемых команд kubectl:$ kubectl config set-context cluster1_kube-system --cluster=cluster1 --namespace=kube-system --user=cluster1
Context "cluster1_kube-system" set.
$ cat cluster-mergeapiVersion: v1
clusters: []
contexts:
- context:
cluster: cluster1
namespace: kube-system
user: cluster1
name: cluster1_kube-system
current-context: cluster2
kind: Config
preferences: {}
users: []Новый контекст можно использовать так:
$ kubectl config use-context cluster1_kube-system
Switched to context "cluster1_kube-system".
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
default-http-backend-fwx3g 1/1 Running 0 28m
kube-addon-manager-cluster 1/1 Running 0 28m
kube-dns-268032401-snq3h 3/3 Running 0 28m
kubernetes-dashboard-b0thj 1/1 Running 0 28m
nginx-ingress-controller-b15xz 1/1 Running 0 28mИзучение Kubernetes API
Чтобы узнать больше о возможностях, предоставляемых Kubernetes API, запросите файл
swagger.json:$ kubectl proxy
$ curl -O 127.0.0.1:8001/swagger.jsonМожно также зайти на
http://localhost:8001/api/ и посмотреть на имеющиеся в Kubernetes API пути.Поскольку
swagger.json — это документ в формате JSON, можно его просмотреть с помощью jq. Утилита jq — лёгкий обработчик JSON-файлов, позволяющий выполнять сравнения и другие операции. Подробнее читайте здесь.Просмотр
swagger.json поможет понять Kubernetes API. Это сложный API, функции в котором разбиты на группы, что затрудняет его восприятие:$ cat swagger.json | jq '.paths | keys[]'
"/api/"
"/api/v1/"
"/api/v1/configmaps"
"/api/v1/endpoints"
"/api/v1/events"
"/api/v1/namespaces"
"/api/v1/nodes"
"/api/v1/persistentvolumeclaims"
"/api/v1/persistentvolumes"
"/api/v1/pods"
"/api/v1/podtemplates"
"/api/v1/replicationcontrollers"
"/api/v1/resourcequotas"
"/api/v1/secrets"
"/api/v1/serviceaccounts"
"/api/v1/services"
"/apis/"
"/apis/apps/"
"/apis/apps/v1beta1/"
"/apis/apps/v1beta1/statefulsets"
"/apis/autoscaling/"
"/apis/batch/"
"/apis/certificates.k8s.io/"
"/apis/extensions/"
"/apis/extensions/v1beta1/"
"/apis/extensions/v1beta1/daemonsets"
"/apis/extensions/v1beta1/deployments"
"/apis/extensions/v1beta1/horizontalpodautoscalers"
"/apis/extensions/v1beta1/ingresses"
"/apis/extensions/v1beta1/jobs"
"/apis/extensions/v1beta1/networkpolicies"
"/apis/extensions/v1beta1/replicasets"
"/apis/extensions/v1beta1/thirdpartyresources"
"/apis/policy/"
"/apis/policy/v1beta1/poddisruptionbudgets"
"/apis/rbac.authorization.k8s.io/"
"/apis/storage.k8s.io/"
"/logs/"
"/version/"А вот следующая команда описывает API, доступные в кластере Kubernetes и к которым у вас есть доступ. Команда в примере ниже выполнена под пользователем-администратором. Если у вас включён контроль доступа по RBAC, вывод может отличаться:
$ kubectl api-versions
apps/v1beta1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1beta1
autoscaling/v1
batch/v1
batch/v2alpha1
certificates.k8s.io/v1alpha1
coreos.com/v1
etcd.coreos.com/v1beta1
extensions/v1beta1
oidc.coreos.com/v1
policy/v1beta1
rbac.authorization.k8s.io/v1alpha1
storage.k8s.io/v1beta1
v1Команда
kubectl explain помогает лучше понять, что делают разные компоненты API:$ kubectl explain
You must specify the type of resource to explain. Valid resource types include:
* all
* certificatesigningrequests (aka 'csr')
* clusters (valid only for federation apiservers)
* clusterrolebindings
* clusterroles
* componentstatuses (aka 'cs')
* configmaps (aka 'cm')
* daemonsets (aka 'ds')
* deployments (aka 'deploy')
* endpoints (aka 'ep')
* events (aka 'ev')
* horizontalpodautoscalers (aka 'hpa')
* ingresses (aka 'ing')
* jobs
* limitranges (aka 'limits')
* namespaces (aka 'ns')
* networkpolicies
* nodes (aka 'no')
* persistentvolumeclaims (aka 'pvc')
* persistentvolumes (aka 'pv')
* pods (aka 'po')
* poddisruptionbudgets (aka 'pdb')
* podsecuritypolicies (aka 'psp')
* podtemplates
* replicasets (aka 'rs')
* replicationcontrollers (aka 'rc')
* resourcequotas (aka 'quota')
* rolebindings
* roles
* secrets
* serviceaccounts (aka 'sa')
* services (aka 'svc')
* statefulsets
* storageclasses
* thirdpartyresources
error: Required resource not specified.
See 'kubectl explain -h' for help and examples.Попробуйте выполнить
kubectl explain deploy. Команда explain работает с разными уровнями вложенности, что позволяет вам также ссылаться на зависимые объекты:$ kubectl explain deploy.spec.template.spec.containers.livenessProbe.exec
RESOURCE: exec <Object>
DESCRIPTION:
One and only one of the following should be specified. Exec specifies the
action to take.
ExecAction describes a "run in container" action.
FIELDS:
command <[]string>
Command is the command line to execute inside the container, the working
directory for the command is root ('/') in the container's filesystem. The
command is simply exec'd, it is not run inside a shell, so traditional shell
instructions ('|', etc) won't work. To use a shell, you need to explicitly
call out to that shell. Exit status of 0 is treated as live/healthy and
non-zero is unhealthy.Операции с подами через kubectl
Все последующие примеры используют Kubernetes API, чтобы узнать что-либо о подах. Одним из способов получения нужных данных — построить запрос и понять, какое его выражение потребуется в терминах
jsonpath. Например, можно выполнить kubectl get pods --all-namespaces -o json, чтобы увидеть весь вывод, из которого мы можем потом отфильтровать нужные данные для примера с сортировкой подов по времени (см. ниже).Если у вас нет запущенного приложения, для знакомства с примерами можно создать поды с лейблом run=shop и запустить их как сервис на порту 80:
$ kubectl run shop --replicas=2 --image quay.io/coreos/example-app:v1.0 --port 80 --exposeТеперь можно посмотреть, что мы будем делать с
jsonpath. Более подробную информацию по нему можно получить из официальной документации.Фильтрация подов Kubernetes по времени их создания
$ kubectl get pods --all-namespaces --sort-by='.metadata.creationTimestamp' -o jsonpath='{range .items[*]}{.metadata.name}, {.metadata.creationTimestamp}{"\n"}{end}'Поиск пода Kubernetes по селектору лейбла и просмотр его логов
Укажите пространство имён (
your-namespace) и свой запрос на наличие лейбла, который поможет найти нужные поды, и получите логи этих подов. Если под не единственный, логи будут получены из всех подов параллельно:$ ns='<your-namespace>' label='<yourkey>=<yourvalue>' kubectl get pods -n $ns -l $label -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | xargs -I {} kubectl -n $ns logs {}Поиск пода Kubernetes по селектору лейбла и подключение к нему
Укажите пространство имён (
your-namespace) и свой запрос на наличие лейбла, который поможет найти нужные поды, и подключитесь к нему по имени (к первому из найденных подов). Замените 8080 на нужный порт пода:$ ns='<your-namespace>' label='<yourkey>=<yourvalue>' kubectl -n $ns get pod -l $label -o jsonpath='{.items[1].metadata.name}' | xargs -I{} kubectl -n $ns port-forward {} 8080:80Операции с узлами (нодами) через kubectl
Комбинация
jq и JSON-вывода kubectl позволяет делать сложные запросы, такие как фильтрация всех ресурсов по времени их создания.Подсчёт количества подов в узле Kubernetes
Зачастую высокоуровневая статистика помогает в отладке. Эта команда подсчитает количество всех подов на каждом из узлов:
$ kubectl get pods --all-namespaces -o json | jq '.items[] | .spec.nodeName' -r | sort | uniq -cФильтрация узлов по лейблу
Запросы с лейблами можно использовать и для узлов. Такой подход часто применяется при конфигурации deployments, нуждающихся в определённых ограничениях. Для получения подробной информации о селекторах смотрите вывод
kubectl explain deployment.spec.selector.$ kubectl get nodes -l 'master' or kubectl get nodes -l '!master'Вывести все лейблы можно с помощью аргумента
--show-labels для любого объекта Kubernetes:$ kubectl get nodes --all-namespaces --show-labelsСписок всех подов для каждого узла
Генерируется JSON-документ с названием узла Kubernetes и список всех названий подов, запущенных на этом узле. Очень полезная команда при отладке:
$ kubectl get pods --all-namespaces -o json | jq '.items | map({podName: .metadata.name, nodeName: .spec.nodeName}) | group_by(.nodeName) | map({nodeName: .[0].nodeName, pods: map(.podName)})'Получение внешних IP для узлов Kubernetes
$ kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name} {.status.addresses[?(@.type=="ExternalIP")].address}{"\n"}{end}'Примечание: Читайте в нашем блоге перевод другой статьи от CoreOS про работу с Kubernetes из консоли: «Автоматизация SSH-доступа к нодам Kubernetes с помощью Fabric и интеграции от CoreOS», а также заметку «Полезные утилиты при работе с Kubernetes» (в ней представлены преимущественно консольные инструменты).
Источники
- «Kubernetes kubectl Tips and Tricks» (Duffie Cooley из CoreOS, 15 мая 2017 г.)
- «Kubectl Unix Pipes: Manage Multiple Clusters With Ease» (Duffie Cooley из CoreOS, 8 июня 2017 г.)
Поделиться с друзьями
badc0de
Мы еще используем
ReplicaSetsдля понимания того, какие Docker образы используются (или могут быть использованы) в рамках конкретного кластера.Делаем мы это не через bash/jq, но можно и через bash:
При использовании
Private Registry— эта информация может быть полезна для удаления старых образов. Указывая глубину возможных откатов через revisionHistoryLimit, мы по каждому деплою приблизительно (из-за слоев докера и частотой запуска garbage collector) ограничиваем количество образов сохраненных в Registry.Однако, тут есть ньюанс: в Registry несколько тэгов (tags) могут указывать на один образ (image), и поэтому очень важно выполнять дополнительные проверки перед удалением.