GCP云功能-在路径上找不到kubectl

时间:2020-03-16 16:23:34

标签: python kubernetes google-cloud-platform google-cloud-functions

我正在编写此Google Cloud Function(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**')

当我运行代码时,它给了我错误 “无效的kube-config文件。 'kubernetes.config.config_exception.ConfigException:无效的kube-config文件。找不到配置。

请帮助我解决它

2 个答案:

答案 0 :(得分:0)

与其在Cloud Function中使用gcloud(并尝试在每个请求上安装它,这将显着增加函数的运行时间),不如使用google-cloud-container客户端库来创建直接从Python调用相同的API,例如:

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)

答案 1 :(得分:0)

您必须以编程方式访问K8S API。您具有API in the documentation

的描述

但是执行起来并不容易。但是,这里有一些输入可以实现您想要的。

首先,获取GKE主IP 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端点。我不知道一种仅在一个API调用中应用带有多个定义的整个yaml的方法。

最后,请务必向云功能服务帐户提供correct GKE roles

更新

另一个解决方案是使用Cloud Run。确实,有了Cloud Run并借助Container功能,您就能够安装和调用系统进程(它是完全开放的,因为your container runs into a GVisor sandbox,但允许大多数常用用法)

想法如下:使用gcloud SDK基本映像并在其上部署应用程序。然后,对您的应用进行编码以执行系统调用。

在Go中有一个可行的示例

Docker文件

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"]

注意:图像云SDK图像很重:700Mb

内容示例(仅是一条快乐的路。我删除了错误管理,以及用于简化代码的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()
    .......