Drone Extension のリスク

    Drone v1 では Extension という仕組みが導入されました。 これは文字通り Drone を拡張する仕組みで、仕様に従って作れば自由に Drone を拡張できます。 https://docs.drone.io/extensions/overview/ 全てを本体でやるのではなく、拡張する仕組みを提供し、あとはコミュニティに委ねるというのが Drone の一つの方針とも言えると思います。 Extension は非常に面白い仕組みだと思いますが、 Drone を運用する立場からすると中々頭が痛い仕組みな気がしてて、 自分は導入に対し慎重な立場です。 単なる杞憂で済めば良いのですが、その懸念について書きたいと思います。 根本は Drone Extension 固有の問題と言うより、一般的な拡張機構全般に言えることだと思います。 ただし、 Drone Extension は全てのビルドに影響を及ぼす、 CI/CDシステムが動かなくなるとサービスのリリースに影響を及ぼしかねないということからよりリスクの高いものになっています。 本体の drone/drone と比べ、開発は活発ではなく、サードパーティの extension はいつ開発が止まってもおかしくない 本体の drone/drone と比べ、ドキュメントやサポート体制が貧弱だと思われる(drone に関しては https://discourse.drone.io でサポートされているが、サードパーティの extension では難しい) ユーザーからの extension に関する要望を受け付けるようになると、管理者の負担になる extension のクォリティはマチマチであり、例外処理が甘かったり、ちゃんとエラーを吐かないものもあるだろう トラブルシューティングが難しいと思われる extension の仕組み上、extension を必要としないビルドにも影響を及ぼしうる 一度追加し、依存しだすと消すのが難しくなる extension が落ちると全 build に影響するので、耐障害性(冗長化)、モニタリングが必要 etc 勿論、上記の懸念点は Extension によって提供される機能とトレードオフであり、 Extension の導入方針は Drone が運用される環境によって大きく依存すると思います。 例えば全員が顔見知りのような小さな組織で特定のサービス専用に Drone を使っていてかつ Drone の運用体制(人員)に十分余裕があるなら 積極的に Extension を導入しても問題ないかもしれません。

    Drone v1 で gRPC が使われなくなった

    v0.8 では server - agent 間の通信に gPRC が使われていましたが、 v1 では使われなくなりました。 理由 https://discourse.drone.io/t/curious-about-decision-to-drop-grpc/3987 gRPC関連のトラブルの問い合わせが多すぎてサポートしきれないので止めた v1 での通信方法 https://discourse.drone.io/t/drone-agents-keep-closing-connections-with-499-code/5197/2 agent がロングポーリングしている 30秒後、なんのビルドもなければコネクションを切って、再接続する(張りっぱなしにしてると、LBやファイアウォールにコネクション切られるため) 自分も v0.8 から Drone を運用していて最近 v1 に upgrade しましたが、 v0.8 では gRPC 関連のトラブルが頻発していました。 server のログでは絶えず gRPC 関連のエラーを吐いていましたし、 server - agent 間の TCP connection が切れっぱなしになって戻らくなって agent 数がどんどん減っていったり ビルドが pending のままになったり、色々ありました。 関連する issue はあり、幾つか対策を打ってみたりしましたが、結局解決しませんでした。 https://github.com/drone/drone/issues/2090 https://github.com/drone/drone/issues/2246 https://github.com/drone/drone/pull/2294 https://www.reddit.com/r/droneci/comments/8opifu/drone_stops_working_after_some_little_time/e06d1gn/ それが v1 にアップグレードして gRPC が使われなくなってから解消し、個人的にはとても助かりました。 管理者的にはアップグレードして一番嬉しい点ですね。

    Drone v1 では Jsonnet が extension なしで使える

    Drone では v1 から冗長な YAML を DRY にする一つの手として、 Jsonnet の利用が推奨されています。 これについては過去のブログでも触れています。 https://techblog.szksh.cloud/drone-jsonnet-generator/ しかし、 v1 の rc の時点では Jsonnet の活用には Jsonnet Extension が必要でした。 https://engineering.linecorp.com/ja/blog/go-oss-ci-cd-platform-drone-1-0-0-rc-1/#title7-1 しかし、 v1 の正式版では Jsonnet Extension がなくても Jsonnet が利用できるようになっています。 まず Drone の管理者側で Drone server に環境変数 DRONE_JSONNET_ENABLED=true を設定する必要があります。 そうしたら、ユーザー側は次のようにすることで jsonnet が使えます。 .drone.yml の代わりに .drone.jsonnet をコミットする (.drone.yml は不要) 各リポジトリの settings の Main > Configuration で設定ファイルのパスを変更する こうすることでビルド実行時に自動で Jsonnet が YAML に変換され処理されるようです。 いつから Jsonnet Extension は不要になったのか https://github.com/drone/drone/compare/v1.0.0-rc.6...v1.0.0 https://github.com/drone/drone/commit/5013cfa993fa455fc56f10e45b9f36cf1d6dff57 v1 の rc ではサポートされてませんでしたが、正式版をリリースするタイミングで Jsonnet Extension が不要になっていたようです。

    Drone で「ビルド実行時にパラメータを渡す」っぽいことをする

    Jenkins では parameterized build という機能で、ビルド実行時に Web UI からパラメータを指定することができます。 Drone では基本的に Git のイベントをフックして動くので「ビルドを実行時に手動でパラメータを設定する」ということは出来ません。 自分は基本的にできなくても構わないと思っていますが、 こういった機能がないから Drone を使わないという人も中にはいるので、 Drone でもちょっとした工夫でそれっぽいことは出来るんじゃないかと思い、簡単なサンプルを書いてみました。 一応言っておくと、 Jenkins の parameterized build を完全に代替するようなものではありません。 https://github.com/suzuki-shunsuke/example-drone-build-parameter 以下のファイルが必要です。 build_params/params.sh.tpl: ビルドパラメータを記述するファイルのテンプレート scripts/deploy.sh: デプロイ時に実行するスクリプト .drone.yml: Drone の設定ファイル スクリプトを実行してデプロイします。 $ bash scripts/deploy.sh するとパラメータを記述するファイルがテンプレートから作成され、エディタで開きます。 https://github.com/suzuki-shunsuke/example-drone-build-parameter/blob/master/scripts/deploy.sh#L12-L17 パラメータを記述し、エディタを閉じます。 するとそのファイルがコミットされ、新しいタグが作成され、コミットとタグがリモートにプッシュされます。 https://github.com/suzuki-shunsuke/example-drone-build-parameter/blob/master/scripts/deploy.sh#L27-L35 Drone でタグをプッシュするイベントをフックしてビルドが実行されます。 https://github.com/suzuki-shunsuke/example-drone-build-parameter/blob/master/.drone.yml#L13-L17 ビルドではコミットされたパラメータの設定ファイルを読み込むことでビルドにパラメータを渡せます。 https://github.com/suzuki-shunsuke/example-drone-build-parameter/blob/master/.drone.yml#L10 こうすることでビルドにパラメータを渡すことができます。 パラメータの設定ファイルはコミットされるので Git で管理できるというのも特徴です。 https://github.com/suzuki-shunsuke/example-drone-build-parameter/blob/master/build_params/2019-07-07T10-04-02JST/params.sh 上記のスクリプトではパラメータの設定ファイルとしてシェルスクリプトで環境変数を定義していますが、 シェルスクリプトである必要性はなく、例えば JSON ファイルを記述してビルドで JSON ファイルを読み込んでもよいし、 パラメータを選択させるようなことがしたければ fzf のようなものを使ってもよいし、 いくらでも改善できます。 以上、簡単な tips でした。

    Drone v0.8 の .drone.yml を v1 の .drone.jsonnet に変換するツールを作った

    Drone v0.8 の .drone.yml を v1 の .drone.jsonnet に変換するツールを作ったので紹介します。 https://github.com/suzuki-shunsuke/drone-jsonnet-generator 背景 https://docs.drone.io/user-guide/pipeline/migrating/ Drone は v0.8 から v1 で .drone.yml のフォーマットが大きく変わっています。 Drone v1 ではビルド実行時に自動で変換しているため、v0.8 の .drone.yml でもそのまま動きます(matrix builds も動きます)。 そのため、Drone v0.8 から v1 に移行する際、すぐに .drone.yml を修正しなくても問題ないのですが、 v1 独自の機能が出てきた場合 v0.8 のフォーマットの場合利用できないかもしれませんし、 いつまでも古いままだと気持ち悪いので出来るならフォーマットを変換したいです。 drone-cli ではフォーマットを変換する drone convert というコマンドが提供されています。 ただし、 drone convert は matrix build を multiple pipeline に変換するのですが、 非常に冗長になります。 そのため、jsonnet を利用することが推奨されています。 https://docs.drone.io/user-guide/pipeline/migrating/ The above syntax can be quite verbose if you are testing a large number of variations.

    .drone.jsonnet と .drone.yml を比較する Drone plugin を作った

    久しぶりに Drone plugin を作ったので紹介します。 https://www.github.com/suzuki-shunsuke/drone-plugin-jsonnet-check .drone.jsonnet から .drone.yml を生成していて、両方を Git で管理している場合に、 .drone.jsonnet と .drone.yml の状態が一致しているかテストするための plugin です。 Drone v1 では matrix builds が廃止され、multiple pipeline が導入されました。 matrix builds を drone convert コマンドで multiple pipeline に変換すると、pipeline の数が多いほど冗長でメンテナンス性が悪くなります。 そこで公式では jsonnet で記述して .drone.yml に変換する方法が推奨されています。 https://docs.drone.io/user-guide/pipeline/migrating/ To simplify your configuration we recommend using jsonnet. $ drone jsonnet --format --stream jsonnet から yaml への変換は Jsonnet extension を使うと Drone がビルド実行時に自動で変換してくれるので .drone.yml を管理する必要はなくなりますが、 使っていない場合、 .drone.jsonnet と .

    metabase を使って drone の利用状況を可視化する

    drone OSS 0.8.5 で検証しています。 https://drone.io/ と https://www.metabase.com/ の話です。 drone の利用状況を可視化したかったので、 drone の DB(MySQL) のデータを metabase で可視化しました。 どんなグラフを作ったのか いざグラフを作成するとなると、何を作ったらいいのか迷いましたが、以下のようなものをとりあえず作ってみました。 ユーザー数 有効化されたリポジトリ数 buildの多いリポジトリ buildをよく実行しているユーザー ビルド時間の分布 build event の割合(push, tag, pull request, deployment) リポジトリのsecretsの数の分布

    drone の管理のために portainer を導入した

    drone OSS 0.8.5 で検証しています。 https://drone.io/ と https://portainer.io/ の話です。 drone はかなり安定したシステムだと思いますが、 ユーザーが好きなイメージで好きなコマンドを実行できる以上、トラブルが起こることはあります。 その結果、 特定の build がタイムアウトにならずに延々と実行され続けるなんてことがあります。 その場合、 どのノードのどのコンテナでトラブルが起きているのか そのコンテナで何が起こっているのか というのを知りたいのですが、 drone にはそういった管理機能はありません。 そこで 複数のサーバで実行されている Docker コンテナを管理できるツールはないかと探したところ、 portainer が良さそうだったので導入しました。 portainer を使うと複数のサーバのコンテナを一覧で見ることが出来、 コンテナを操作(削除、停止、再起動etc)出来ます。 コンテナのログや簡単なメトリックス(CPU, memory, network usage) が見れます。 コンテナだけでなく、network や volume, image といったリソースも管理できます。 portainer の導入 公式ドキュメントに書いてありますが、 swarm cluster を構築してそこにデプロイすればよいです。 https://docs.docker.com/engine/swarm/swarm-tutorial/ https://portainer.readthedocs.io/en/stable/deployment.html#inside-a-swarm-cluster 困っていること 毎回検索で絞り込みしないといけない 検索で絞り込んだ後に特定のコンテナの詳細画面飛んだ後一覧に戻ると 検索がクリアされているのでもう一度検索しないといけないのが面倒です。 もう少し高度な検索がしたい 自由入力の検索ボックスが1つあるだけで、特にクエリが書けるわけでもなさそうなので、 もう少し高度な検索がしたいです。 例えば Created At で 1時間以上前に特定のノードで作られたコンテナの一覧とか。 docker API でエラーが出て、コンテナを操作できない これは多分不具合とかではなく自分の設定が良くないのだと思います。 この辺の issue が関係してそうですが、まだ解消できていません。

    drone の step を実行するか否かをタグ名で判定する方法

    drone 0.8.5 で検証しています。 tag 名による判定方法はドキュメントには書いてないので書いておきます。 when: ref: refs/tags/foo-* # タグ名が foo-* ならステップを実行 グロブ * には / は含まれないことには注意してください。 上記の例だと、 tag foo/bar/0.1.0 はマッチしません。 これは Go の filepath.Match を使っているからです。 https://github.com/cncd/pipeline/blob/f8c48fc9fb9fd113c6e7dd941d63bb9f86a623cb/pipeline/frontend/yaml/constraint.go#L70 https://github.com/cncd/pipeline/blob/f8c48fc9fb9fd113c6e7dd941d63bb9f86a623cb/pipeline/frontend/yaml/constraint.go#L80

    drone の project visibility とは

    恐らく公式ドキュメントに説明がない気がするので書いておきます。 と言っても、以下のissueに全部書いてありますが。 https://github.com/drone/drone/issues/2042 droneの web ui からリポジトリごとに設定できます。 そのリポジトリが誰に見えるかの設定です。 public: ログインしていなくても誰でも見れる(publicリポジトリのデフォルト) private: リポジトリにアクセスできる人しか見れない(privateリポジトリのデフォルト) internal: ログインしていれば誰でも見れる