GAミント至上主義

Web Monomaniacal Developer.

2018/1/26 Google Kubernetes Engine & Stackdriverでログが見れない問題

いつもGKEでデプロイした後は、Cloud ConsoleからStackdriverのログを眺めているけど、一向に出てこない。

しばらくこちら側のログレベル設定を確認したり、kubectl logなどを見たけど正常。

Twitter検索したら同じ症状の人が見つかる。

公式の障害情報を見たら全部 Availableになってるけど、一番下にメッセージが出てた。

Google Cloud Status Dashboard

We are investigating delays with Google Stackdriver Logging Viewer and GCS Export. The issue with Monitoring API has been resolved as of 2018-01-25 16:27 US/Pacific. We will provide more information by 22:15 US/Pacific.

たまたまタイミングが悪かったようなので待つしかない。

GKE上の Django + ManifestStaticFilesStorage + Google Cloud Storage でValueError無限ループが起きてハマった話

Templyでは、Djangoのアプリが入ったDockerコンテナをGoogle Kubernetes Engine(GKE)で動かし、ファイルはGoogle Cloud Storage(GCS)で管理している。
temply.bizocean.jp

本番公開してからデプロイ時にcss、jsなどの静的ファイルが更新されず困ったので、よくあるファイル名にハッシュを付ける形にして解決しようとしたところ、下記のようなエラーが連発して、止まってしまうことがあった。

ValueError at /favicon.ico
The file 'send/img/favicon.png' could not be found with <mysite.storage.MyManifestStaticFilesStorage object at 0x7f5fbae7d320>.

問題と解決方法を3行まとめ。

  • staticファイルはGCS上に置くので.dockerignoreで/static/以下をDockerイメージに含めないようにしていた
  • staticfiles.jsonは、STATIC_URL上ではなく、ローカルファイルシステム上STATIC_ROOT直下から読み込もうとする
  • GCSを使う場合でもSTATIC_ROOT/staticfiles.jsonだけはイメージに含めるなどdjango側がローカルで読める必要がある

以下詳細。

ファイル名にハッシュをつけるのはDjangoの標準で入っているManifestStaticFilesStorageを使った。

The staticfiles app | Django documentation | Django

これはsettings.pyに下記のような設定を追加するだけでおk。

STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

あとはテンプレートでちゃんとstaticを使ってパスを書いていれば、自動的に変換してくれるので導入は簡単。

{% static 'app/css/style.css' %}

仕組みとしては、collectstaticコマンド実行時に元のファイル名と、ハッシュ付きのファイル名のペアが書かれたstaticfiles.jsonを書き出し、それを使ってパスを変換してくれる。

で、開発環境では問題なく動いているのに、本番環境ではエラーが連発しまくってValueErrorのメールがきまくる現象になった。

faviconでエラーが出る原因は、ブラウザが裏で勝手にアクセスし、まずfavicon.icoがないのでエラーを出そうとするんだけど、そのエラーページでもfavicon.icoを呼び出すのでさらにエラーの無限ループだった。

静的ファイルはGCS上に別途アップし配信しているので、staticfiles.jsonもそっちから取ってきてるだろうと思っていたのだが違った。

開発環境ではアプリのディレクトリをまるごとマウントし、開発しやすくしており、/static/以下も入っていたので問題にならなかった。

下記のようにSTATIC_ROOTに指定したパス+staticfiles.jsonを.dockerignoreに追加すればおk。
.dockerignore

!app/django/static/staticfiles.json

いくらDockerといえども、こういった外部ストレージ周りは本番と開発で差異が出てしまうので注意が必要そう。

vimのPython環境を再構築した

基本的にPythonの開発は社内のLinuxサーバー上でVimを使い行っている。

Pythonを使うからには、やっぱりPEP8を守り、見た目も統一されたソースコードにしたいので、Vimに下記のプラグインを入れ、
github.com

さらに.vimrcに下記を追加して保存時走るようにして文法などのチェックを行っている。

autocmd BufWritePost *.py call Flake8()

インストール時にはたしかNeoBundleなどのパッケージ管理を使ったが、いまだに理解できず、何とか動いている感じで、消していいかわからないゴミもたくさん残っていた。

そんな風に感じている中、下記記事に出会った。

プラグインはフォルダでgit cloneするだけでいいらしい。

すてき。

tyru.hatenablog.com

でもvim8が必要。サーバーはUbuntu16.10でまだvim7だったので、下記記事通りにVim8にアップデートする。

Vim 8.0 Released! How to install it in Ubuntu 16.04 - Tips on Ubuntu

あっけなく動いて、.vimrcや、.vimディレクトリがかなりすっきりした。

残る問題としては、まだ社内サーバーはUbuntu16.10のためPython3.5で、Dockerでは3.6を使っているのでtype hintingがエラーになってしまうなど。これはおそらくUbuntu17.10にすればpythonも3.6になるので解決しそう。

Vimテクニックバイブル ?作業効率をカイゼンする150の技

Vimテクニックバイブル ?作業効率をカイゼンする150の技