Аутентификация мастера GKE в Python - PullRequest
0 голосов
/ 29 января 2019

Мне нужно пройти аутентификацию в кластере Kubernetes, предоставленном в GKE , с использованием клиента Python Kubernetes и клиента Python Google Cloud.Я бы предпочел не выкладывать на gcloud по нескольким причинам:

  • полагаться на системную оболочку gcloud в скрипте Python, когда у меня есть нативная библиотека Google Cloud, не элегантная
  • требуется, чтобы система имела gcloud
  • Я должен был бы переключить пользователей на соответствующий ServiceAccount и переключиться обратно
  • Это влечет за собой стоимость запуска / присоединения к другому процессу

Таким образом, рабочего процесса gcloud container clusters get-credentials (который делегирует gcloud config config-helper) будет недостаточно для получения мне необходимого API-ключа.Как получить эквивалентный вывод с помощью Google Cloud Python API?

Вот что у меня есть:

import kubernetes.client
import googleapiclient.discovery
import base64

# get the cluster object from GKE
gke = googleapiclient.discovery.build('container', 'v1', credentials=config['credentials'])
name = f'projects/{config["project_id"]}/locations/{config["location"]}/{parent}/clusters/{config["name"]}'
gke_clusters = gke.projects().locations().clusters()
gke_cluster = gke_clusters.get(name=name).execute()

# set up Kubernetes Config
kube_config = kubernetes.client.Configuration()
kube_config.host = 'https://{0}/'.format(gke_cluster['endpoint'])
kube_config.verify_ssl = True
#kube_config.api_key['authenticate'] = "don't know what goes here"

# regretably, the Kubernetes client requires `ssl_ca_cert` to be a path, not the literal cert, so I will write it here.
kube_config.ssl_ca_cert = 'ssl_ca_cert'
with open(kube_config.ssl_ca_cert, 'wb') as f:
    f.write(base64.decodestring(gke_cluster['masterAuth']['clusterCaCertificate'].encode()))

# use Kubernetes client to do something
kube_client = kubernetes.client.ApiClient(configuration=kube_config)
kube_v1 = kubernetes.client.CoreV1Api(kube_client)
kube_v1.list_pod_for_all_namespaces(watch=False)

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Ниже приведено решение, которое извлекает токен доступа из googleapiclient, а не копирует объекты вручную.

import googleapiclient.discovery
from tempfile import NamedTemporaryFile
import kubernetes
import base64

def token(*scopes):
    credentials = googleapiclient._auth.default_credentials()
    scopes = [f'https://www.googleapis.com/auth/{s}' for s in scopes]
    scoped = googleapiclient._auth.with_scopes(credentials, scopes)
    googleapiclient._auth.refresh_credentials(scoped)
    return scoped.token

def kubernetes_api(cluster):
    config = kubernetes.client.Configuration()
    config.host = f'https://{cluster["endpoint"]}'

    config.api_key_prefix['authorization'] = 'Bearer'
    config.api_key['authorization'] = token('cloud-platform')

    with NamedTemporaryFile(delete=False) as cert:
        cert.write(base64.decodebytes(cluster['masterAuth']['clusterCaCertificate'].encode()))
        config.ssl_ca_cert = cert.name

    client = kubernetes.client.ApiClient(configuration=config)
    api = kubernetes.client.CoreV1Api(client)

    return api

def run(cluster):
    """You'll need to give whichever account `googleapiclient` is using the 
    'Kubernetes Engine Developer' role so that it can access the Kubernetes API.

    `cluster` should be the dict you get back from `projects.zones.clusters.get`
    and the like"""

    api = kubernetes_api(cluster)
    print(api.list_pod_for_all_namespaces())

Чтобы понять это, потребовалось больше времени, чем мне хотелось бы признать.@ Пост Ивана очень помог.

0 голосов
/ 05 февраля 2019

Для аутентификации в кластере GKE вы можете использовать учетную запись службы для подключения к проекту, а затем сгенерированный секретный ключ из GKE для аутентификации в кластере.Вот шаги:

  1. Создайте учетную запись службы в GCP.Перейдите в IAM> Учетные записи служб> создайте учетную запись службы.Дайте ему роль владельца проекта.После создания SA создайте ключ и загрузите его как json.
  2. Загрузите файл key.json в папку, в которой находится скрипт .py
  3. Получить API_TOKEN.Это ваш главный вопрос, вы можете получить его, прочитав файл токена:
    • Первый запуск kubectl get secrets
    • Вы получите 'default-token-xxxxx'
    • runkubectl describe secrets default-token-xxxxx (замените xxxxx на ваше имя токена).
    • Отображаемый параметр токена - это ваш «API-ключ».Скопируйте его в свой скрипт.
  4. Создание скрипта.Он немного отличается от вашего по нескольким причинам: вам нужно сначала пройти аутентификацию в проекте с учетной записью службы, затем вам нужно передать api_token, но также вам нужно получить сертификат SSL при аутентификации в GKE master.
import base64, pprint
import kubernetes.client
from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file("key.json")
gke = googleapiclient.discovery.build('container', 'v1', credentials=credentials)
name = 'projects/your_project/locations/your_zone/clusters/your_gke_cluster'
gke_clusters = gke.projects().locations().clusters()
gke_cluster = gke_clusters.get(name=name).execute()

kube_config = kubernetes.client.Configuration()
kube_config.host = 'https://{}'.format(gke_cluster['endpoint'])
kube_config.verify_ssl = True

kube_config.api_key['authorization'] = 'your_api_token'
kube_config.api_key_prefix['authorization'] = 'Bearer'

kube_config.ssl_ca_cert = 'ssl_ca_cert'

with open(kube_config.ssl_ca_cert, 'wb') as f:
    f.write(base64.decodestring(gke_cluster['masterAuth']['clusterCaCertificate'].encode()))

kube_client = kubernetes.client.ApiClient(configuration=kube_config)
kube_v1 = kubernetes.client.CoreV1Api(kube_client)
pprint.pprint(kube_v1.list_pod_for_all_namespaces())

Специальные поля:

  • ваш_проект - из GCP
  • ваша _зона - где создан кластер gke
  • ваш _gke_cluster- Имя кластера GKE
  • your_api_key - что вы получаете на шаге 3.

Этого должно быть достаточно для аутентификации вас в кластере GKE.

...