t.marcusの外部記憶装置

忘備録とかちょっとした考えとかをつらつらと...

GKEからPubsubへの接続でタイムアウトが発生する件

このアプリをビルド&AlpineのDockerイメージ化したものをGKEで動かして、Topicを取得するときに(内部的にはPubSubに接続する時)タイムアウトエラーで落ちてしまう現象が発生した

$ cat Dockerfile
FROM alpine:3.8

RUN apk add bash tree pstree

ENTRYPOINT [ "/opt/pubsub" ]


$ cat pubsub.go
package main

import (
	"cloud.google.com/go/pubsub"
	"context"
	"fmt"
	"os"
	"time"
)

func main() {
	projectName := os.Getenv("PROJECT")
	topicName := os.Getenv("TOPIC")
	subscriptionName := os.Getenv("SUBSCRIPTION")
	ctx := context.Background()
	ctx, _ = context.WithTimeout(ctx, 5*time.Second)
	client, err := pubsub.NewClient(ctx, projectName)
	if err != nil {
		panic(err)
	}
	topicExists, err := client.Topic(topicName).Exists(ctx)
	if err != nil {
		panic(err)
	}
	fmt.Println(topicName, topicExists)

	subscription := client.Subscription(subscriptionName)
	subscriptionExists, err := subscription.Exists(ctx)
	if err != nil {
		panic(err)
	}
	fmt.Println(subscriptionName, subscriptionExists)

	go func() {
		err = subscription.Receive(ctx, func(rcvCtx context.Context, message *pubsub.Message) {
			fmt.Println("RCV", message.ID, string(message.Data), message.Attributes)
		})
	}()

	time.Sleep(500 * time.Millisecond)

	if err != nil {
		panic(err)
	}

	fmt.Println("Wait for signal...")
	sigCh := make(chan os.Signal, 1)
	signal.Notify(
		sigCh,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT)
	fmt.Println("SignalRcv ->", <-sigCh)
}

結論結論としては、Alpineに ca-certificates がなかったため、Pubsubのエンドポイント ( https://pubsub.googleapis.com )に接続しようとして接続できなかった模様。

なので apk add ca-certificates してパッケージをインストールすることでタイムアウト(に見えるhttps接続エラー)は出なくなった。