Облачная функция GCP - Не удалось найти kubectl на пути - PullRequest
1 голос
/ 16 марта 2020

Я пишу эту функцию Google Cloud (Python)

def create_kubeconfig(request):
    subprocess.check_output("curl https://sdk.cloud.google.com | bash | echo "" ",stdin=subprocess.PIPE, shell=True )
    os.system("./google-cloud-sdk/install.sh")
    os.system("gcloud init")
    os.system("curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.17.0/bin/linux/amd64/kubectl")

    os.system("gcloud container clusters get-credentials **cluster name** --zone us-west2-a --project **project name**")
    os.system("gcloud container clusters get-credentials **cluster name** --zone us-west2-a --project **project name**")
    conf = KubeConfig()
    conf.use_context('**cluster name**')

, когда я запускаю код, он выдает ошибку 'Недопустимый файл конфигурации куба. 'kubernetes.config.config_exception.ConfigException: неверный файл kube-config. Конфигурация не найдена.

помогите решить ее, пожалуйста

Ответы [ 2 ]

0 голосов
/ 17 марта 2020

Вы должны программно получить доступ к API K8S. У вас есть описание API в документации

Но это не легко и просто выполнить. Однако здесь приведены некоторые входные данные для достижения того, чего вы хотите.

Сначала получите IP-адрес мастера GKE enter image description here

Затем вы сможете легко получить доступ к кластеру. Здесь для чтения развертывания

    import google.auth
    from google.auth.transport import requests
    credentials, project_id = google.auth.default()
    session = requests.AuthorizedSession(credentials)
    response = session.get('https://34.76.28.194/apis/apps/v1/namespaces/default/deployments', verify=False)
    response.raise_for_status()
    print(response.json())

Для его создания вы можете сделать это

    import google.auth
    from google.auth.transport import requests
    credentials, project_id = google.auth.default()
    session = requests.AuthorizedSession(credentials)
    with open("deployment.yaml", "r") as f:
        data = f.read()
    response = session.post('https://34.76.28.194/apis/apps/v1/namespaces/default/deployments', data=data,
                            headers={'content-type': 'application/yaml'}, verify=False)
    response.raise_for_status()
    print(response.json())

В соответствии с объектом, который вы хотите построить, вы должны использовать правильное определение файла и правильная конечная точка API. Я не знаю способа применения целого yaml с несколькими определениями только в одном вызове API.

В заключение, обязательно предоставьте правильные роли GKE для функции облака Учетная запись службы

ОБНОВЛЕНИЕ

Другим решением является использование Cloud Run. Действительно, с Cloud Run и благодаря возможности Container у вас есть возможность установить и вызвать системный процесс (он полностью открыт, потому что ваш контейнер запускается в изолированную программную среду GVisor , но в большинстве случаев разрешено использование)

Идея заключается в следующем: используйте базовый образ gcloud SDK и разверните на нем свое приложение. Затем закодируйте свое приложение для выполнения системных вызовов.

Вот рабочий пример в Go

Docker file

FROM golang:1.13 as builder

# Copy local code to the container image.
WORKDIR /app/
COPY go.mod .
ENV GO111MODULE=on
RUN go mod download

COPY . .

# Perform test for building a clean package
RUN go test -v ./...
RUN CGO_ENABLED=0 GOOS=linux go build -v -o server

# Gcloud capable image
FROM google/cloud-sdk

COPY --from=builder /app/server /server
CMD ["/server"]

Примечание: изображение cloud-sdk изображение имеет большой размер: 700 МБ

Пример содержимого (только счастливый путь. Я удаляю управление ошибками и обратную связь stderr / stdout для упрощения кода)

    .......
// Example here: recover the yaml file into a bucket
    client,_ := storage.NewClient(ctx)
    reader,_ := client.Bucket("my_bucket").Object("deployment.yaml").NewReader(ctx)
    content,_:= ioutil.ReadAll(reader)
// You can store locally the file into /tmp directory. It's an in-memory file system. Don't forget to purge it to avoid any out of memory crash
    ioutil.WriteFile("/tmp/file.yaml",content, 0644)
// Execute external command
// 1st Recover the kube authentication
    exec.Command("gcloud","container","clusters","get-credentials","cluster-1","--zone=us-central1-c").Run()
// Then interact with the cluster with kubectl tools and simply apply your description file
    exec.Command("kubectl","apply", "-f","/tmp/file.yaml").Run()
    .......
0 голосов
/ 16 марта 2020

Вместо использования gcloud внутри облачной функции (и попытки устанавливать ее при каждом запросе, что значительно увеличит время выполнения вашей функции), вы должны использовать клиентскую библиотеку google-cloud-container для делать те же самые вызовы API непосредственно из Python, например:

from google.cloud import container_v1

client = container_v1.ClusterManagerClient()

project_id = 'YOUR_PROJECT_ID'
zone = 'YOUR_PROJECT_ZONE'

response = client.list_clusters(project_id, zone)
...