使用Cloud Functions(Node.js)调用Kubernetes API

首先

由于在使用Cloud Functions接收GCS变更通知后,希望能执行一些特定的处理操作到Kubernetes这一侧,但遇到了一些困扰,所以写下了这个备忘录。

我是一位后端工程师,只有在开发公司内部使用的机器人时才会使用nodejs。希望能够得到大家善意的代码审查和严格的指正,这会让我很高兴。

成果

以下是结果:
https://github.com/h-r-k-matsumoto/cloud-function-gke

迷上了的要点

由于无法在Cloud Functions中使用gcloud命令,无法进行认证。

当试图使用`~/.kube/config`时,出现了以下错误。
即使是示例也无法运行。

{
    "kind": "Status",
    "apiVersion": "v1",
    "metadata": {},
    "status": "Failure",
    "message": "pods is forbidden: User \"system:anonymous\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
    "reason": "Forbidden",
    "details": {
        "kind": "pods"
    },
    "code": 403
}

看起来由于系统匿名,无法确认认证。

处理

我认为通常情况下,它的定义如下。

    "users": [
      {
        "authProvider": {
          config: {
            "cmd-args": "config config- helper--format = json",
            "cmd-path": "/usr/lib64/google-cloud-sdk/bin/gcloud",
            "expiry": "2019-04-23T07:05:48Z",
            "expiry-key": '{.credential.token_expiry}',
            "token-key": '{.credential.access_token}'
          },
          "name": "gcp"
        }
      }
    ]

我会将authProvider从代码中彻底删除。因为有这一部分代码,@kubernetes/client-node库中的cloud_auth.ts会被执行。

    "users": [
      {
      }
    ]

很寂寞呢。那么关于用什么进行身份验证的部分,你可以参考以下的描述,位于config.ts文件的第294行。

        if (user.token) {
            token = 'Bearer ' + user.token;
        }

是的。那就是您可以自己設定token。所以…就像下面這樣獲取token。

async function getToken() {
  let authResult = await auth.getClient({ scopes: 'https://www.googleapis.com/auth/cloud-platform' });
  let accessToken = await authResult.getAccessToken().catch((err) => {
    throw err;
  })
  return accessToken.token
}

然后,将获取的值设置如下。

    users: [
      {
        user: {
          token: token
        }
      }
    ]

其他

Go语言是一个放弃的故事。

起初,我尝试用golang进行实现。但是,在golang 1.11版本中,出现了以下问题。

..\..\..\..\..\pkg\mod\k8s.io\client-go@v11.0.0+incompatible\rest\request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
        have (*versioned.Decoder)
        want (watch.Decoder, watch.Reporter)

对于初学者来说,这种Golang的错误真是让人头疼…然后,一旦尝试使用master,就会遇到困难。

>go build main.goform\lake\notification>go build main.go
go: finding google.golang.org/api/support/bundler latest
go: finding google.golang.org/api/support latest..\..\..\..\..\pkg\mod\contrib.go.opencensus.io\exporter\ocagent@v0.4.12\ocagent.go:24:2: unknown import path "google.golang.org/api/support/bundler": cannot find moduleproviding package google.golang.org/api/support/bundler

由于与库相关的错误出现,我认为对于初学者来说更加困难,所以我决定改用nodejs进行实现。

我不知道这种方法是否正确。

我在官方网站和Stack Overflow上搜索了,但对于从Cloud Function中调用的方法仍然不清楚。
总之,我尝试了这个方法,目前看起来工作得很顺利。