LoginSignup
6
1

More than 5 years have passed since last update.

Cloud Functions(nodejs)から、Kubernetes APIを呼び出す

Last updated at Posted at 2019-04-23

はじめに

GCSの変更通知をCloud Functionsで受け取り、そこからKubernetes側にとある処理を実行したいな…と思ったときに結構ハマったのでメモです。

私は、社内用のbotを作るときしか、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
}

どうにも system:anonymous となっている事から認証されていないっぽいですね。

対応

通常は、下記のような定義だと思います。

kubeconfig
    "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が動作してしまうためです。

kubeconfig
    "users": [
      {
      }
    ]

さみしいですね。で、変わりに何で認証するか?という部分ですが、
config.ts#L294
に、下記の記述があります。

config.ts
        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
        }
      }
    ]

その他

golangはあきらめたお話

最初は、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で実装する事に変えました。

このやり方は正しいのかは分からない。

公式サイトや、stackoverflowなどでも探したのですが、Cloud Functionからの呼び出し方法は不明なままでした。
あくまで、これでやったら現時点では上手くいったよ。という内容となります。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1