お題
以前、GKE上で動くアプリを公開し、Stackdriver Logging(以降、SDL)でアプリが出力したログを確認するところまでやったが、SDL上のログには保持期間というものがあり、放っておくと消える。
当然、ログの退避方法というのがあるので、試してみる。
環境
# OS
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="17.10 (Artful Aardvark)"
# gcloud
$ gcloud version
Google Cloud SDK 217.0.0
app-engine-go
app-engine-java 1.9.65
app-engine-python 1.9.75
beta 2018.07.16
bigtable
bq 2.0.34
cbt
cloud-build-local
cloud-datastore-emulator 2.0.2
cloud_sql_proxy
container-builder-local
core 2018.09.17
docker-credential-gcr
gsutil 4.34
kubectl 2018.09.17
pubsub-emulator 2018.02.02
# kubectl
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.7", GitCommit:"0c38c362511b20a098d7cd855f1314dad92c2780", GitTreeState:"clean", BuildDate:"2018-08-20T10:09:03Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"9+", GitVersion:"v1.9.7-gke.6", GitCommit:"9b635efce81582e1da13b35a7aa539c0ccb32987", GitTreeState:"clean", BuildDate:"2018-08-16T21:33:47Z", GoVersion:"go1.9.3b4", Compiler:"gc", Platform:"linux/amd64"}
実践
■以前の投稿のおさらい
1)クラスタ作成
$ gcloud container clusters create my-cluster-1-min --zone asia-northeast1-a --preemptible --machine-type=f1-micro --disk-size=10 --num-nodes=3
〜省略〜
Creating cluster my-cluster-1-min...done.
Created [https://container.googleapis.com/v1/projects/【プロジェクトID】/zones/asia-northeast1-a/clusters/my-cluster-1-min].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/asia-northeast1-a/my-cluster-1-min?project=【プロジェクトID】
kubeconfig entry generated for my-cluster-1-min.
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
my-cluster-1-min asia-northeast1-a 1.9.7-gke.6 【IPアドレス】 f1-micro 1.9.7-gke.6 3 RUNNING
2)WebAPIアプリを内包するコンテナをデプロイ(※前提:GCRに対象イメージ格納済み)
$ kubectl run go-webapi-for-gke-study-server --image gcr.io/【プロジェクトID】/go-webapi-for-gke-study@sha256:e38c30b2dae0364ba91ab66f7b7247a392dac952f317143c475efe11a98dcf40 --port 80
deployment.apps "go-webapi-for-gke-study-server" created
3)サービス公開
kubectl expose deployment go-webapi-for-gke-study-server --type "LoadBalancer"
service "go-webapi-for-gke-study-server" exposed
4)ログはStackdriver Loggingに溜まる?
GKEの設定(指定なしならデフォルトでStackdriver Logging利用となる)
公開されたサービスにブラウザでアクセスすると?
まず、Podのログを見ると、ちゃんとアクセスされたログ(INFO, WARN, ERRORそれぞれ)が出ている。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
go-webapi-for-gke-study-server-56bb9576f5-ljsm7 1/1 Running 0 1m
$
$ kubectl logs go-webapi-for-gke-study-server-56bb9576f5-ljsm7
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v3.3.6
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:80
{"level":"info","ts":1537626936.8119755,"caller":"go-webapi-for-gke-study/main.go:21","msg":"INFO LEVEL with severity","severity":"INFO"}
{"level":"warn","ts":1537626936.8120918,"caller":"go-webapi-for-gke-study/main.go:22","msg":"WARN LEVEL with severity","severity":"WARN"}
{"level":"error","ts":1537626936.8121026,"caller":"go-webapi-for-gke-study/main.go:23","msg":"ERROR LEVEL with severity","severity":"ERROR","stacktrace":"main.main.func1\n\t/go/src/github.com/sky0621/go-webapi-for-gke-study/main.go:23\ngithub.com/sky0621/go-webapi-for-gke-study/vendor/github.com/labstack/echo.(*Echo).Add.func1\n\t/go/src/github.com/sky0621/go-webapi-for-gke-study/vendor/github.com/labstack/echo/echo.go:480\ngithub.com/sky0621/go-webapi-for-gke-study/vendor/github.com/labstack/echo.(*Echo).ServeHTTP\n\t/go/src/github.com/sky0621/go-webapi-for-gke-study/vendor/github.com/labstack/echo/echo.go:583\nnet/http.serverHandler.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2619\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:1801"}
Stackdriver Logging上でもログ出力を確認
■ログのエクスポート
[参考]
https://cloud.google.com/logging/docs/export/
https://cloud.google.com/logging/docs/export/configure_export_v2
ログのエクスポートをするためには、「シンク」というものを作成する必要がある。
「シンク」によって、Stackdriver Loggingに流れてくるログのうち、”どのようなログ”を”どこ”にエクスポートするかが決められる。
1)「シンク」によるエクスポート先としてGCSのバケットを作っておく
2)ログビューアによる「シンク」の作成
もろもろ埋める。
ログレベルとして「ERROR」のものをGCSの先ほど作成したバケットにエクスポートする指定でシンク作成
3)ログがGCSに溜まるか確認
実際に溜まっていることを確認しようとしたが、GCSの場合は1時間単位でまとめて送信される(なんなら初回は2〜3時間かかることもあるとのこと)そうなので、いったん送信まで待つ。
ちなみに、ログのエクスポート先としてはGCSの他にBigQueryとCloud Pub/Subがある。
こちらであれば、GCSと違って即時送信であるらしい。
ということで、GCSへの送信を待っている間に、Cloud Pub/Subへのエクスポートを試してみよう。
4)Cloud Pub/Subにトピックとサブスクリプションを作成
トピックを作成
サブスクリプションを作成
5)Cloud Pub/Subへエクスポートする「シンク」を作成
6)ログがCloud Pub/Subに溜まるか確認
$ gcloud pubsub subscriptions list
---
ackDeadlineSeconds: 10
messageRetentionDuration: 604800s
name: projects/【プロジェクトID】/subscriptions/my-ss-sink
pushConfig: {}
topic: projects/【プロジェクトID】/topics/my-tpc-sink
$ gcloud pubsub subscriptions pull projects/fs-work-1978/subscriptions/my-ss-sink --auto-ack
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────────┬───────────────────────────────────────────────────────┐
│ DATA │ MESSAGE_ID │ ATTRIBUTES │
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────────┼───────────────────────────────────────────────────────┤
│ {"insertId":"ftl347f6mk9e0","jsonPayload":{"caller":"go-webapi-for-gke-study/main.go:22","level":"warn","msg":"WARN LEVEL with severity","ts":1537631639.4484},"labels":{"compute.googleapis.com/resource_name":"fluentd-gcp-v2.0.17-j26ns","container.googleapis.com/namespace_name":"default","container.googleapis.com/pod_name":"go-webapi-for-gke-study-server-56bb9576f5-ljsm7","container.googleapis.com/stream":"stderr"},"logName":"projects/fs-work-1978/logs/go-webapi-for-gke-study-server","receiveTimestamp":"2018-09-22T15:54:04.187127526Z","resource":{"labels":{"cluster_name":"my-cluster-1-min","container_name":"go-webapi-for-gke-study-server","instance_id":"2599213054701599462","namespace_id":"default","pod_id":"go-webapi-for-gke-study-server-56bb9576f5-ljsm7","project_id":"fs-work-1978","zone":"asia-northeast1-a"},"type":"container"},"severity":"WARNING","timestamp":"2018-09-22T15:53:59Z"} │ 211335298657122 │ logging.googleapis.com/timestamp=2018-09-22T15:53:59Z │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴─────────────────┴───────────────────────────────────────────────────────┘
想定通り、WARNレベルのログだけが溜まってた。
まとめ
お遊びや勉強用にGCP使っている分には不要だけど、プロダクションとしてはログの退避は必須なので、ここは覚えておくべき事柄。
ちなみに gcloudコマンド
使う場合は下記参照。
https://cloud.google.com/logging/docs/reference/tools/gcloud-logging#exporting_logs
GCSの方は、まだ送信されないので、送信されたらこの記事は更新することにして、いったん公開しよう。