nouhau
nouhau copied to clipboard
App Engine Standard Go 1.9 migration to Go 1.11 の知見
WHAT
App Engine Standard Go 1.9 migration to Go 1.11の知見を集約していく このissueにそのまま書いてもよいし、やった時に書いたBlogなどへのLinkでもよい
- 移行時にやったこと
- 移行時にはまったことや解決策, ワークアラウンド
WHY
App Engine Standardにはたくさんの機能が存在していて、開発環境なども絡むと結構ややこしいので、色んな人のケースを集めてみよう。
Refs
https://speakerdeck.com/emahiro/go-conference-2019-spring-go1-dot-9-to-go1-dot-11
https://techblog.ap-com.co.jp/entry/2019/04/19/174903
ドキュメント読んでて気づかなかったのでシェアします。
Go1.11ランタイムではAppEngineTokenSource
をつかっていると怒られました。
2019/07/01 10:45:54 google: AppEngineTokenSource is deprecated on App Engine standard second generation runtimes (>= Go 1.11) and App Engine flexible. Please use DefaultTokenSource or ComputeTokenSource.
そうしないとGCP APIが叩けません。
oauth2/google: can't get a token from the metadata service; not running on GCE
AppEngineTokenSource
が deprecated なのは事実として、 ComputeTokenSource
に delegate しているはずなので動かないとしたら golang.org/x/oauth2
のバグのような気もしますね。
https://godoc.org/golang.org/x/oauth2/google#AppEngineTokenSource
Second generation App Engine runtimes (>= Go 1.11) and App Engine flexible: AppEngineTokenSource is DEPRECATED on second generation runtimes and on the flexible environment. It delegates to ComputeTokenSource, and the provided context and scopes are not used. Please use DefaultTokenSource (or ComputeTokenSource, which DefaultTokenSource will use in this case) instead.
https://github.com/golang/oauth2/blob/master/google/appengine_gen2_flex.go#L21
2018年11月時点で動くようには書かれているはずなので、動かなかった条件が少し知りたいところですね。 aetest
とか dev_appserver.py
で動かないのは間違いないと思います。
https://github.com/golang/oauth2/pull/341
oauth2/google: can't get a token from the metadata service; not running on GCE
これはAppEngineTokenSource
にしていたときにエラーが出たもので、DefaultTokenSource
にするとすんなり解決したためComputeTokenSource
は試していません。
2019/07/01 10:45:54 google: AppEngineTokenSource is deprecated on App Engine standard second generation runtimes (>= Go 1.11)
ここはGo1.11はsecond generation runtimes
扱いなんだとびっくりしましたw
試しに google.AppEngineTokenSource
を使ったものを App Engine Go 1.11 にデプロイしてみたところAppEngineTokenSource is deprecated
のログは出力されたものの動いたので、動かないというのはやはり何か前提条件がおかしい気がしますね。
oauth2/google: can't get a token from the metadata service; not running on GCE
が出ているということは、デプロイ先がおかしい OR デプロイしないローカル環境での結果ではないでしょうか。 下は実際に動かしてみたもの。
package main
import (
"fmt"
"io"
"net/http"
"os"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/appengine"
)
func main() {
http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
tokenSource := google.AppEngineTokenSource(r.Context())
client := oauth2.NewClient(r.Context(), tokenSource)
resp, err := client.Get(fmt.Sprintf(`https://appengine.googleapis.com/v1/apps/%s/services`, os.Getenv("GOOGLE_CLOUD_PROJECT")))
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
defer resp.Body.Close()
io.Copy(rw, resp.Body)
})
appengine.Main()
}
runtime: go111
service: go111-tokensource
移行時にはまったことや解決策, ワークアラウンド
- ソースコードはGitHubのprivate repoで管理している
- デプロイするアプリケーションは社内で開発しているprivate repoにあるライブラリに依存している
- Go1.11ランタイムを使用し、ローカルではGo Moduleによる依存関係解決をしている
ような場合、そのままgcloud app deploy
してしまうとGAEのapp_builderさんがCloudBuildマシンから認証が必要なGitHubリポジトリにアクセスしようとしてビルド出来ないので、デプロイ前に小細工が必要でした
具体的には
go mod vendor
mv ./go.mod ./go.mod.temp
mv ./go.sum ./go.sum.temp
gcloud app deploy
のように、vendorフォルダを作った後、go.modファイルをリネームするなり何なりしてやる必要があります
go111ランタイムの初期の頃はgcloud app deploy
する際に環境変数GO111MODULE
が参照されているような挙動だったのですが、いつからかgo.modファイルがあるかどうかでGo Moduleを使うかどうかが変わるようになりました
実は go mod vendor
については Cloud Functions のドキュメントの方が詳しくて、 go.mod
を無視するために .gcloudignore
が使えることも書いてあったりしますね。こちらに挙動が合わせられている様子。
https://cloud.google.com/functions/docs/writing/specifying-dependencies-go?hl=en#using_a_vendor_directory
https://github.com/gcpug/nouhau/tree/master/app-engine/note/gaego111-private-repo-deploy も合わせてどうぞ!
誘導ありがとうございます
今は.gcloudignore
でちゃんと間引けるようになってるんですね :)
dev_appserver.pyにbug。
handlers:
- url: /hello
script: auto
- url: /(.+)
static_files: static/\1
upload: static/.*
上記の様に scriptハンドラを上書きするURLパターンのstatic_filesハンドラがあると、scriptハンドラが処理されず404エラーとなる。 (dev_appserverはgo1.11の場合にscriptハンドラを全て無視してデフォルトハンドラで処理している為)
プロダクションでは問題なし。
↓issue https://issuetracker.google.com/issues/128170900