使用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中调用的方法仍然不清楚。
总之,我尝试了这个方法,目前看起来工作得很顺利。