Как запустить команды 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.

  1. Скачать и построить kubectl внутри контейнера
  2. Создайте свое приложение, скопировав kubectl в ваш контейнер
  3. Вуаля! kubectl предоставляет богатый клиент для управления вашим кластером kubernetes

Полезная документация

--- РЕДАКТИРОВАТЬ ---

Поработав с kubectl в моих кластерных kubectl, я нашел более эффективный способ аутентификации модулей, чтобы можно было выполнять вызовы API k8s. Этот метод обеспечивает более строгую аутентификацию.

  1. Создайте учетную запись ServiceAccount для своего модуля и настройте его для использования указанной учетной записи. Документация по учетным записям службы k8s
  2. Сконфигурируйте RoleBinding или ClusterRoleBinding чтобы у служб была авторизация для взаимодействия с API k8s. k8s ролевая документация
  3. Вызовите 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).