Как запустить команды kubectl внутри контейнера?
В контейнере внутри контейнера, как я могу запустить команду с помощью kubectl? Например, если мне нужно сделать что-то вроде этого внутри контейнера:
kubectl get pods
Я пробовал это: в моем файле docker у меня есть следующие команды:
RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
RUN chmod +x ./kubectl
RUN sudo mv ./kubectl /usr/local/bin/kubectl
EDIT: я пытался использовать файл OSX, я исправил его в бинарном файле linux. (исправлено @svenwltr
При создании файла докеров это происходит успешно, но когда я запускаю кубтеклы, получаю контейнеры внутри контейнера,
kubectl get pods
Я получаю эту ошибку:
Соединение с сервером: было отказано - вы указали правильный хост или порт?
Когда я развертывал локально, я столкнулся с этой ошибкой, если моя докер-машина не была запущена, но внутри контейнера, как можно запустить докер-машину?
Локально, я обошел эту ошибку, выполнив следующие команды:
(dev является именем докер-машины)
docker-machine env dev
eval $(docker-machine env dev)
Может кто-нибудь, пожалуйста, скажите мне, что мне нужно делать?
Ответы
Ответ 1
Я бы использовал kubernetes api, вам просто нужно установить curl вместо kubectl
а остальное успокоить.
curl http://localhost:8080/api/v1/namespaces/default/pods
Я бегу над командой на одном из моих серверов. Измените localhost на IP-адрес apiserver/имя DNS.
В зависимости от вашей конфигурации вам может понадобиться использовать ssl или предоставить клиентский сертификат.
Чтобы найти конечные точки API, вы можете использовать --v=8
с kubectl
.
пример:
kubectl get pods --v=8
Ресурсы:
Документация по Kubernetes API
Обновление для RBAC:
Я предполагаю, что вы уже настроили rbac, создали служебную учетную запись для своего модуля и запустите ее. Эта учетная запись службы должна иметь права доступа к списку модулей в требуемом пространстве имен. Для этого необходимо создать роль и привязку роли для этой учетной записи службы.
Каждый контейнер в кластере заполнен токеном, который можно использовать для аутентификации на сервере API. Для проверки внутри контейнера выполните:
cat /var/run/secrets/kubernetes.io/serviceaccount/token
Чтобы сделать запрос к apiserver, внутри контейнера запустите:
curl -ik \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://kubernetes.default.svc.cluster.local/api/v1/namespaces/default/pods
Ответ 2
Немного опоздал на вечеринку здесь, но это мои два цента:
Я обнаружил, что использовать kubectl
внутри контейнера гораздо проще, чем вызывать API кластера.
(Почему? Авто аутентификация!)
Допустим, вы развертываете проект Node.js, который требует использования kubectl
.
- Скачать и построить
kubectl
внутри контейнера - Создайте свое приложение, скопировав
kubectl
в ваш контейнер - Вуаля!
kubectl
предоставляет богатый клиент для управления вашим кластером kubernetes
Полезная документация
--- РЕДАКТИРОВАТЬ ---
Поработав с kubectl
в моих кластерных kubectl
, я нашел более эффективный способ аутентификации модулей, чтобы можно было выполнять вызовы API k8s. Этот метод обеспечивает более строгую аутентификацию.
- Создайте учетную запись
ServiceAccount
для своего модуля и настройте его для использования указанной учетной записи. Документация по учетным записям службы k8s - Сконфигурируйте
RoleBinding
или ClusterRoleBinding
чтобы у служб была авторизация для взаимодействия с API k8s. k8s ролевая документация - Вызовите API напрямую или используйте клиент k8s для управления вызовами API для вас. Я НАСТОЯТЕЛЬНО рекомендую использовать клиент, он имеет автоматическую настройку для pods, которая удаляет шаг токена аутентификации, требуемый для обычных запросов.
Когда вы закончите, вы будете иметь следующее: ServiceAccount
, ClusterRoleBinding
, Deployment
(ваши стручки)
Не стесняйтесь комментировать, если вам нужно более четкое указание, я постараюсь помочь как можно больше :)
Все в одном примере
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: k8s-101
spec:
replicas: 3
template:
metadata:
labels:
app: k8s-101
spec:
serviceAccountName: k8s-101-role
containers:
- name: k8s-101
imagePullPolicy: Always
image: salathielgenese/k8s-101
ports:
- name: app
containerPort: 3000
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: k8s-101-role
subjects:
- kind: ServiceAccount
name: k8s-101-role
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: k8s-101-role
Изображение salathielgenese/k8s-101
содержит kubectl
. Поэтому можно просто войти в контейнер pod и выполнить kubectl
как если бы он выполнял его на хосте kubectl exec -it pod-container-id -- kubectl get pods
: kubectl exec -it pod-container-id -- kubectl get pods
Ответ 3
Первый вопрос
/usr/local/bin/kubectl: cannot execute binary file
Похоже, вы загрузили двоичный файл OSX для kubectl
. При работе в Docker вам, вероятно, нужен Linux:
https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
Второй вопрос
Если вы запустите kubectl
в правильно настроенном кластере Kubernetes, он сможет подключиться к серверу.
kubectl
основном использует этот код для поиска и проверки подлинности: github.com/kubernetes/client-go/rest.InClusterConfig
Это означает:
- Хост и порт сервера хранятся в переменных среды
KUBERNETES_SERVICE_HOST
и KUBERNETES_SERVICE_PORT
. - Токен доступа монтируется в
var/run/secrets/kubernetes.io/serviceaccount/token
. - Сертификат сервера монтируется в
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
.
Это все, kubectl
нужно знать kubectl
для подключения к серверу.
Некоторые мысли, почему это может не сработать:
- Контейнер не работает в Куберне.
- Недостаточно использовать один и тот же хост Docker; контейнер должен работать как часть определения модуля.
- Доступ ограничен с помощью плагина авторизации (который не используется по умолчанию).
-
spec.serviceAccountName
данные учетной записи службы перезаписываются определением модуля (spec.serviceAccountName
).