AirflowでDAGが認識されなくてハマった
起こった事象
- 以下のようにDAGの生成を別のメソッドに切り出していたらAirflowからDAGが認識されなくなった
dag_factory = DAGFactory.get_default()
dag = dag_factory.create(
dag_id="example",
...,
)
原因
- DAG file は
airflow
とdag
という文字列を両方含んでいる必要があるらしい - option的には
dag_discovery_safe_mode
回避策
- やや強引だが以下のようにAirflowという文字列が含まれるようにすればよい
- または dag_discovery_safe_mode を
False
にしてもよい
dag_factory = AirflowDAGFactory.get_default()
dag = dag_factory.create(
dag_id="example",
...,
)
Telepresence で Kubernetes Client Library を使う
結論
Telepresenceの --mount
オプションと docker volume オプションを使う。
telepresence \ --swap-deployment <container name> \ --mount /tmp/known \ --docker-run --rm \ -v=/tmp/known/var/run/secrets:/var/run/secrets \ <local image>
背景
Kubebuilder (v2.3.1) で k8s の Operator を開発していたが、共用の GKE Cluster で動かしたくなった。
ローカルでの開発を避けたい理由は以下の通り。
課題
以下のようなエラーが出た。
ERROR controller-runtime.client.config unable to get kubeconfig {"error": "could not locate a kubeconfig"}
kubeconfigが読めないらしい。
解決策
https://godoc.org/sigs.k8s.io/controller-runtime/pkg/client/config によると以下の順に評価して、configを取得しているらしい。
- --kubeconfig flag pointing at a file
- KUBECONFIG environment variable pointing at a file
- In-cluster config if running in cluster
- $HOME/.kube/config if exists
今回はCluster内で動かそうとしているので In-cluster config を見に行かせたい。
https://github.com/kubernetes/client-go/tree/master/examples/in-cluster-client-configuration によると/var/run/secrets/kubernetes.io/serviceaccount
を見に行っている。
これは実際に kubectl describe pod ...
等実行するとvolume mountされていることが確認できる。
Telepresenceを使う場合は root dir が $TELEPRESENCE_ROOT
以下に設定されるためおかしなことになる。
冒頭のコマンドで $TELEPRESENCE_ROOT/var/run/secrets:/var/run/secrets
を読みに行かせることで解決。
なお、kubebuilder で webhookを有効化した場合は以下のようなエラーが出る。
ERROR setup problem running manager {"error": "open /tmp/k8s-webhook-server/serving-certs/tls.crt: no such file or directory"}
これも同様に tls.crt
のディレクトリのvolume設定を変えてあげればok。以下のオプションを追加すれば良い。
-v=/tmp/known/tmp/k8s-webhook-server/serving-certs:/tmp/k8s-webhook-server/serving-certs \
終わりに
最近は専らKubebuilder職人になっている。 Kubebuilder を用いた Custom Controller 実装には以下の書籍を参考にさせて頂いている。
参考
- config - GoDoc
- client-go/examples/in-cluster-client-configuration at master · kubernetes/client-go · GitHub
- Using a Kubernetes Client Library · Telepresence: Fast, realistic local development for Kubernetes and OpenShift Origin microservices
- Volume access · Telepresence: Fast, realistic local development for Kubernetes and OpenShift Origin microservices
GHRC: GitHub Repositoryの設定を宣言的に管理するツールを作った
機能としてはRepositoryのLabel, Protected branch, Merge options, etc. の設定をYAMLで宣言的に管理できる。
既存の設定を ghrc import
して .ghrc.yaml
というファイルに書き込み、YAMLをシュッと書き換えて ghrc apply
する、みたいな使い方ができる。
Terraformっぽくplanコマンドも実装したので ghrc plan
でdry-runも可能。
似たツールとしてはTerraformのGitHub Providerや github-labeler が近い。 しかし、Terraformだとややセットアップが面倒なのと、github-labeler は想定しているユースケースが違った。
ghrcではmerge時のオプション( mergeボタンの Squash and merge
とか選ぶやつ)や、Protected branchを管理できるようにした。
チーム開発時にcommitが汚い開発者(自分はこのタイプ)が適当にmaster mergeすると、masterブランチが大変なことになってしまう(許さない)。
そういった事態を避けるため、あるいは特殊なCI/CD上の都合で Squash and merge
を強制したい場合があり、これらをコード(といってもYAML)として管理したいと思った。
Repositoryの設定についてチームのルールとして合意を取るだけではなく、各リポジトリで管理し、Pull Request & CI/CDベースで変更できるようにすると開発ルールが良い感じに統一できて嬉しい。
また、Protected Branchについては設定を忘れていてmasterに誤爆pushするケースが極稀にあるので一緒に設定できるようにした。 こちらもコードレビューのルール等をコードで管理できるようになるので良いんじゃないかと思った。
というわけで気が向いたら使って下さい。
jemallocを利用したRubyのDocker Imageを作る
以下の記事で説明されているようにメモリアロケータをjemallocにすることで、Rubyのメモリ効率をよしなにできる場合があります。是非使いましょう!!!!!!
さて、時は2019年であり、世界はコンテナに包まれました。
RubyのDocker Imageもjemallocオプションを有効にしてビルドしたものが提供されてあろうこと期待していたのですが、公式イメージとしては提供されていません。
代わりに以下のIssueが見つかりました。要するにサポートされていません。
そのため、jemallocを有効化したImageは自分で作る必要があります。
幸いにも上記Issueのコメントに作り方が書いてありました。
正解は以下です。
FROM ruby:2.6.2 # Enable jemalloc RUN apt-get update && apt-get install libjemalloc1 && rm -rf /var/lib/apt/lists/* ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.1
ビルド時に指定する必要はないみたいですね。
FIN
ソフトウェアエンジニア4年目の作業環境(物理)
職業ソフトウェアエンジニアを始めて4年目の自分の現在の作業環境について語ります。 タイトルに「物理」と付けているのはソフトウェアとしての開発環境ではなく、椅子やキーボード等の実物質を伴った環境であることを表しています。
背景
ソフトウェアエンジニア、あるいはプログラマは性質上、長時間椅子に座りながらディスプレイを凝視しながら仕事をします。 生物学的には不自然な行いであるが故、身体に相応の負荷がかかることは想像に難くありません。
長期間の負荷の蓄積か、あるいは加齢による身体機能の低下か原因は不明ですが、同じスタイルでコードを書いていてもある日突然身体に異変が起こる事があります。 腰・肩・首を破壊するケースに大別されるかと思いますが、自分の場合は2年目くらいから肩の痛みを発症し、最近になって突発的に首の痛みも併発してしまいました。 次は腰かな?
現代医療(整形外科)の力で致命的な痛みは一時的に緩和できるものの、根本的な問題に向き合う必要があります。
そこで、本記事では身体の負荷を抑えるべく見直した自分の作業環境について簡単に紹介していきます。
PC
Mac Book Proを使っています。前提条件としての位置づけなので特に語ることはないです。
キーボード
外付けのキーボード(Magic Keyboard)を2台利用します。
人間工学界では有名なデュアルキーボードスタイルを採用し、右手と左手で別々のキーボードを操作します。 デュアルキーボードスタイルにすることによって人間工学的に肩が開いて良く、肩凝りが起きにくくなります。 自分は実際にデュアルキーボードを導入してから深刻な肩凝り問題からほぼ解放されました。
重要なポイントは2点あります。
一点目は外付けのキーボードを利用する点です。外付けのキーボードを利用しPC自体を遠くに配置することで自然と目線が上がります。 こうすることで首への負荷を小さくすることができます。 PC自体は適当なPCスタンド上に配置し、自分に合った高さに調節すると良い感じです。
自分の場合はPCスタンドを購入したのですが、冷静に考えると本棚の積読を引っ張り出してオライリータワーを建築してあげると土台としてそこそこ安定しますし、何よりオシャレなのでおすすめです。 本は読みましょう。
二点目はセパレートキーボードではなくデュアルキーボードを利用している点です。 セパレートキーボードはキーボードが真っ二つに別れ、キーがシャーディングされた構成のものです。 対してデュアルキーボードは通常のキーボードを水平にスケーリングしたスタイルを指します。
セパレートキーボードは左右のパーツ単体だけでは機能しない分断されたモノリスであり、柔軟性に欠けます。また、利用可能な種類も限られており、値段も高いものが多いです。 デュアルキーボード方式では左右それぞれが単体のキーボードとして動作するため冗長性が高く、キーボードの種類も自由に選ぶことができます。 万が一デュアルキーボードに飽きたら片方のキーボードはメルカリに出品可能な点も魅力的です。
椅子
また、会社ではオカムラのバロンを使っています。 他の選択肢としてはアーロンチェア等が有名ですが、10万円↑くらいの高機能オフィスチェアかつ自分の体格に合ったものであれば何でも良いと思います。
個人的に腰は無傷なので今の所ランバーサポートの恩恵はあまり感じていないのですが、アームレスト・ヘッドレストは必須度が高いです。 アームレストをデスクの高さと揃え、デュアルキーボードを組み合わせ、肩・肘・手首をほぼ直角の位置関係にすると肩への負荷が大きく減らせます。 ヘッドレストも同様に首へのダメージを大きく減らすことができます。 ヘッドレストは位置固定のものが多く難易度が高いため、ネックピローのようなクッションと併用して良いポジションを見つけると良いです。
会社の椅子のデフォルト設定だとヘッドレスト・アームレストがなかったのですが、首痛発症を機にヘッドレスト・アームレスト付きのものに交換してもらい、無事に人権を得ることができました。
机
あまり課金するポイントではないと思っているので適当にニトリで買って組み立てました。 個人的に気をつけるべき点は以下だと考えています。
- 幅: 利用する椅子が余裕で入ること。ディスプレイを複数台おくなら画面幅x枚数分。
- 奥行き: ディスプレイを置いても近すぎない程度に。
- 高さ: 適当(椅子やフットレストでチューニング可能)。
- 足元: 後方に板がないタイプ。板があると足が伸ばせないのでつらい。
フットレスト
上述の通り、机の高さのチューニングとして利用します。何でも良いと思います。
フロアマット
ないとフローリングが大変なことになります。
ディスプレイ
目は意外と丈夫なので適当なものを使っています。念の為作業中はブルーライトカットのメガネを装備しています。
終わりに
健康面には気をつけましょう。 作業環境の改善以外にも食生活・睡眠を改善したり、適度な運動を取り入れて体調を管理することが大切だと思います。
2018年に読んで良かった技術書・ビジネス書TOP3
今年は読んだ中で特に良かった本を3冊紹介します。
Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems
- 作者: Martin Kleppmann
- 出版社/メーカー: O'Reilly Media
- 発売日: 2017/03/16
- メディア: Kindle版
- この商品を含むブログを見る
今年読んだ中ではこれがダントツでした。通称DDIAと呼ばれている本です。 ACID・BASE・CAP・RDBMS・KVS・バッチ処理・ストリーム処理・分散システム...等、データ(フロー)設計周りについて体系的かつ詳細に学ぶことができます。 また、パフォーマンス・スケーラビリティ・整合性などのトレードオフについても多く語られているので、実際にデータを扱うシステム設計の意思決定に非常に役立ちます。
かなり物量があって読み通すのは非常に骨が折れますが、各章がある程度独立しているので辞書っぽく使うこともできます。
ビジネス書
エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング
エンジニアリング組織論への招待 ?不確実性に向き合う思考と組織のリファクタリング
- 作者: 広木大地
- 出版社/メーカー: 技術評論社
- 発売日: 2018/02/22
- メディア: Kindle版
- この商品を含むブログを見る
この本を読んでから「不確実性」というものを強く意識できるようになりました。 アジャイルで迷子になった時に読むと良いです。
起業の科学
- 作者: 田所 雅之
- 出版社/メーカー: 日経BP社
- 発売日: 2017/11/07
- メディア: Kindle版
- この商品を含むブログを見る
社内外でいくつか新規プロジェクトに関わることが増えたので読みました。 リーンスタートアップ系の本と合わせて読んでおくと新規事業で大きく道を踏み外すことはないと思います。
GatsbyJSをGAEにデプロイする
GatsbyJS をGoogle App Engine にデプロイする方法の備忘です。
app.yaml
と cloudbuild.yaml
を設定してCloud Buildのコマンドを叩くことでデプロイします。
Google App Engine の設定
まずは app.yaml の設定です。
基本は Hosting a static website on Google App Engine | App Engine standard environment for PHP | Google Cloud を参考にします。
ルーティングの都合上、拡張子を指定しない場合のリクエストは index.html
にマッピングさせます。
runtime: php55 api_version: 1 handlers: # file with extensions (e.g. .html) - url: /(.*\..*) static_files: public/\1 upload: public/(.*) - url: /(.*)/ static_files: public/\1/index.html upload: public/(.*)/index.html - url: / static_files: public/index.html upload: public/index.html - url: /(.*) static_files: public/\1/index.html upload: public/(.*)/index.html skip_files: - node_modules/ - src/ - \.cache/ - package\.json - yarn\.lock
Google Cloud Build の設定
cloudbuild.yaml
の設定です。
steps: - name: 'gcr.io/cloud-builders/yarn' args: ['install'] - name: 'gcr.io/cloud-builders/yarn' args: ['run', 'build'] - name: 'gcr.io/cloud-builders/gcloud' args: ['app', 'deploy']
権限の設定
Google Cloud Build はデフォルトではAppEngineにデプロイする権限を持たないのでいい感じに設定してあげる必要があります。
appengine.serviceAdmin
と appengine.deployer
のroleを <project_number>@cloudbuild.gserviceaccount.com
に設定してあげます。
Terraformを使った例では以下のようになります。
resource "google_project_iam_binding" "appengine-service-admin" { project = "${var.gcp_project}" role = "roles/appengine.serviceAdmin" members = [ "serviceAccount:${var.gcp_project_number}@cloudbuild.gserviceaccount.com", ] } resource "google_project_iam_binding" "appengine-deployer" { project = "${var.gcp_project}" role = "roles/appengine.deployer" members = [ "serviceAccount:${var.gcp_project_number}@cloudbuild.gserviceaccount.com", ] }
Deploy
gcloudコマンドを叩くことでデプロイが完了します。
$ gcloud builds submit . --config=cloudbuild.yaml
プログラマのためのGoogle Cloud Platform入門 サービスの全体像からクラウドネイティブアプリケーション構築まで
- 作者: 阿佐志保,中井悦司
- 出版社/メーカー: 翔泳社
- 発売日: 2017/06/02
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
WTFormsでPythonの予約語をFieldとして扱いたい場合の対処法
こういうことをしたかった。
class MyForm(FlaskForm): from = DateField(format='%Y%m%d') to = DateField(format='%Y%m%d')
が、これは syntax error
になる。理由は from
がPythonの予約語であるため。
from
を辞書のkeyのstringとして扱えれば回避できるのでここは type
を使ってclassをメタ的に生成する。
MyForm = type('MyForm', (FlaskForm,), { 'from': DateField(format='%Y%m%d'), 'to': DateField(format='%Y%m%d'), })
値を取り出す際も dot アクセスするとsyntax errorになるので辞書として取得する。
f['from']
面倒なのでそもそもの form に予約語になりそうなフィールドを含めないようにしましょう。
Dockerのコンテナ内部からコンテナidを取得する
cat /etc/hostname
すればいけた
# cat /etc/hostname
7b9fc2c0bc4f
Docker の multi-stage build で golang の 軽量 image を作る
Multi-Stage Build
Docker の 17.05 (ce) から multi-stage build 機能が追加されました。 multi-stage build とは、ベースイメージを複数利用し、多段階で build を行う機能です。
利用シーンはビルド環境とランタイム環境の分離が挙げられます。 ビルド環境とランタイム環境を分けるとランタイムがネイティブである Go のような言語では Docker image を劇的に小さくすることができます。
golang の ベースイメージは 数百 MB ありますが、alpine のような 軽量 Linux イメージ単体では 数 MB のため、効果としては 90 % 以上のダイエットに繋がります。
Docker image サイズを小さくするメリットや、一般的なプラクティスについてはページ下部のリンクが非常に参考になります。
Dockerfile の作成
multi-stage build を使って Go のコンテナアプリケーションを作成するテンプレートです。
Dockerfile の中身はこんな感じになります。
FROM golang:latest as builder ENV CGO_ENABLED=0 ENV GOOS=linux ENV GOARCH=amd64 WORKDIR /go/src/github.com/shotat/light-golang-container-template COPY . . RUN make # runtime image FROM alpine RUN apk add --no-cache ca-certificates COPY --from=builder /go/src/github.com/shotat/light-golang-container-template/app /app EXPOSE 8080 ENTRYPOINT ["/app"]
Multi-stage build なので FROM
が二回登場しています。
一行目の FROM では as xxx
としてビルド環境に名前をつけています。
as で指定した名前は COPY --from=builder /go/src/github.com/shotat/light-golang-container-template/app /app
で参照しています。
builder で GOOS
GOARCH
CGO_ENABLED
の環境変数を指定し、 alpine 用にビルドを行います。
amd64の場合 CGO_ENABLED=0
を指定しないとビルド環境依存が発生してしまうため指定は必須です。
RUN apk add --no-cache ca-certificates
は SSL/TLS 通信を行うために必要で、ほとんどアプリケーションで利用するはずです。
通信の必要がなければ alpine
ではなく busybox
や scratch
を使ってより小さなイメージが作れます。
Build する
ビルド自体は make
だけで簡潔するようにしています。
Makefile
の中身はこんな感じです。パッケージ管理には dep
を使います。
# 適当に設定を書く # NAME := hello # VERSION := v1 # ... all: setup build setup: go get -u github.com/golang/dep/cmd/dep dep ensure build: go build -o app
$ docker build . -t app:dev
アプリケーションの中身です。 適当に外部ライブラリを入れたかったので logger として logrus を使っています。
package main import ( log "github.com/sirupsen/logrus" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { log.Info("Hello") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) }
実際にビルドしてみます。
$ docker build . -t app:dev
Run !
動かします。
$ docker run --rm -p 8080:8080 app:dev $ curl localhost:8080 # container output time="2017-08-05T12:43:25Z" level=info msg=Hello
無事いい感じに動作しています。 デプロイサイクル短縮の鼓動を感じました。
参考書籍
プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化
- 作者: WINGSプロジェクト阿佐志保
- 出版社/メーカー: 翔泳社
- 発売日: 2015/11/19
- メディア: Kindle版
- この商品を含むブログ (3件) を見る
Docker 実践ガイド (impress top gear)
- 作者: 古賀政純
- 出版社/メーカー: インプレス
- 発売日: 2015/12/17
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
- 作者: ?橋健一,谷口禎英,井本大登,山崎勝平,大和田純,内村元樹,坂東昌哉,平田敏之,牧大輔,板敷康洋,大?浩崇,穴井宏幸,原口宗悟,久田真寛,ふしはらかん,のざきひろふみ,うらがみ,ひげぽん,池田拓司,はまちや2,竹原,片田雄樹,渋江一晃,WEB+DB PRESS編集部編
- 出版社/メーカー: 技術評論社
- 発売日: 2017/06/24
- メディア: 大型本
- この商品を含むブログを見る
- 作者: 松木雅幸,mattn,藤原俊一郎,中島大一,牧大輔,鈴木健太,稲葉貴洋
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/09
- メディア: 大型本
- この商品を含むブログ (4件) を見る