【问题标题】:GCP cloud function - Could not find kubectl on the pathGCP 云功能 - 在路径上找不到 kubectl
【发布时间】:2020-06-27 18:45:51
【问题描述】:

我正在编写这个 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 文件。未找到配置。

请帮我解决一下

【问题讨论】:

  • 您是否尝试在云函数中运行此代码?
  • @JohnHanley 是的,这是云功能代码的一部分
  • @JohnHanley 这两行不必要的只是试图以某种方式解决问题 os.system("./google-cloud-sdk/install.sh") os.system("gcloud init")它没有帮助
  • @KrisDEV,请记住您处于无服务器环境中。你不知道底层服务器上安装了什么,因为它不是你的服务器,它是无服务器的!就算今天能用,明天也不能用!你只能依赖你的代码,而不是服务器环境!总之,永远不要在无服务器环境(Cloud Function 和 AppEngine 标准)中使用 os 调用!
  • @guillaumeblaquiere 我今天明白了,但我不知道如何处理它,我必须部署一个 yaml 文件来创建 pod 和服务,我必须为此创建一个云功能,并且我找不到任何可以帮助我的东西

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


【解决方案1】:

您必须以编程方式访问 K8S API。你有API in the documentation的描述

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

首先,获取 GKE 主 IP

然后您就可以轻松访问集群了。在这里阅读部署

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

注意:镜像cloud-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()
    .......

【讨论】:

  • 您好,非常感谢您的回答,我很高兴获得更多帮助:我在一个文件夹中有不同的文件,其中一些是部署,其中一些是有状态集,其中一些是服务,我想部署文件,不选择类型,像这样namespaces/default/deployments有没有办法做到这一点
  • okey - 所以在尝试按照您的建议部署 yaml 文件后,我遇到了下一个问题:apiVersion: extensions/v1beta1 kind: Deployment metadata: name: zookeeper namespace: zookeeper 这是我的 yaml 文件的一部分,所以我写道:response = session.post ('3.1.1.1/apis/extensions/v1beta1/namespaces/zookeeper/…', data=data, headers={'content-type': 'application/yaml'}, verify=False) 而不是你的建议,我得到了下一个错误:409客户端错误:url 冲突:34.94.20.3/apis/extensions/v1beta1/namespaces/zookeeper/… 我该如何解决?
  • 没有秘密。我看了kubectl code 并解析了文件,有一种以正确顺序应用定义的策略,但每个 API 都是单独调用的。正如我在回答中所说的“这并不容易和简单”。关于您的错误,请注意 GKE 集群版本、yaml apiVersion 定义和您调用的端点。
  • [github.com/kubernetes/kubectl/] 我该如何使用它?我真的不明白
  • kubectl是与K8S高手对话的最佳工具。您只需执行 kubectl apply -f file 并将所有文件应用到您的集群,调用正确的 API 并以正确的顺序。它是开源的,你可以看看它是如何构建的。您不能在 Python 和 Cloud Function 中使用它。在 Go 中,脏东西是可能的,但不推荐。
【解决方案2】:

您应该使用 google-cloud-container 客户端库直接进行相同的 API 调用,而不是在 Cloud Function 中使用 gcloud(并尝试在每个请求上安装它,这将显着增加函数的运行时间)来自 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)

【讨论】:

  • 我想部署(kubectl apply -f)一些 yaml 文件到集群 - 如果我使用你建议的解决方案,你知道什么命令可以帮助我吗?
  • 取决于你想要做什么,也许update_cluster()?
  • 我有一个节点很少的集群 - 每个节点都有很少的工作负载 - 使用 yaml 配置。一天结束时,我从节点中删除了所有部署和服务,早上我想再次“打开”系统 - 在本地我只写“kubectl apply -f %path”。我想通过云功能做同样的事情
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-25
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 2020-11-13
相关资源
最近更新 更多