WESEEK Tech Blog

WESEEK のエンジニアブログです

社内 Kubernetes 実験環境を Rancher 1.6 から 2.0 にアップデートして復活させた話

こちらは 「社内 Kubernetes 実験環境をRancher 1.6から 2.0にアップデートして復活させた話」からの転載です。

当記事は 2018 年に発生した事例の紹介記事です。現在は Rancher 2.0 で快適に動作しております。



「SEROKU フリーランス(以下、SEROKU)」の中の人をやっている kouki です。 SEROKUを支える技術〜社内 Kubernetes 編〜 でも言及しましたが、社内では自分たちでサーバマシンを用意し、Kubernetes 環境を構築しています。

今回、その実験環境が壊れてしまったので、Rancher 2.0 にアップデートして復活させたお話をさせていただこうと思います。

Rancher とは

まず、社内 Kubernetes 実験環境は Rancher というソフトウェアを用いて構築しています。

rancher.com

OSS で公開されており、比較的簡単に Kubernetes クラスタを構築できるソフトウェアです。 オンプレミスで構築できるだけでなく、 GCE や AWS ESK、Azure Container Service など、様々なクラウドプロバイダにも対応しています。

また、Rancher 1.6 の段階では、Kubernetes 以外にも Cattle, Mesos, docker swarm などの様々なコンテナ分散システムに対応していました。ですが、2017年9月頃、 Rancher 2.0 が発表され、Kubernetes 前提のシステムに舵を切っています。

弊社では、2017年12月頃から利用を始めたため、安定版である Rancher 1.6 を採用しました。

Rancher OS とは

Rancher OS とは、Rancher を開発している同社が公開している Rancher に特化した Operating System です。 動作速度と軽量さが特徴ですが、一番の特徴としては、すべてのコマンドやシステムがコンテナで動作する前提で組まれているところだと思います。

OS の機能を担当する system-docker と、それ以外の用途で利用される docker といった形でコンテナの実行環境が分離されており、ポータビリティに優れた設計になっています。

f:id:weseek:20190919161548p:plain
※Overview of RancherOS から引用

社内 Kubernetes 実験環境では Rancher OS と Rancher を組み合わせて、Kubernetes クラスタを構築しています。

なぜ壊れたのか

半年ほど安定して運用していたのですが、今年の6月末あたりにミスで大量にコンテナ(数百程度)を作成してしまい、 Node(Kubernetes クラスタに属しているサーバ)に負荷がかかり、Rancher システム自体の動作が不安定になる事象が発生しました。

最初は大量に作成されたコンテナを削除していくことで収束していくだろう、と目論んでいたのですが、負荷も相まって Kubernetes の設定などを保持している etcd のデータに不整合が発生し、クラスタの状態を正しく復元することができなくなっていました。

リカバリをするために etcd が持っている内部データのバイナリを見てみると、設定が保存されているようでしたが、そのデータから頑張って復元処理をするよりも、Rancher 2.0 GA がアナウンスされていたため、社内ノウハウの刷新も含め、そちらを採用する選択をしました。

幸いにも Kubernetes にデプロイしている各種設定は別のレポジトリにバックアップを取っていて、コンテナのボリュームは NFS ストレージ上に残っていたため、新しいクラスタ上にも復元することは可能でした。

2.0 にアップデートして嬉しかったこと

Kubernetes クラスタ前提のシステムになったため、Rancher 独自の用語が少なくなっており、Kubernetes への理解があればシンプルに扱えるようになりました。

また、以下のような点にメリットを感じました。

  1. Cattle が排除され、対応するクラスタKubernetes 前提になったため、動作するコンテナがシンプルになった
    • 1.6 ではクラスタを組むためのシステム用途的なコンテナが多く動作していました。それが 2.0 からは比較的少ないコンテナでクラスタが組めるようになったため、本来サービスに割り当てたいリソースを使えるようになりました。
  2. Node 同士のネットワークを組む際に Flannel, Canal, Calico が選択可能になった
    • Calico を利用することでセキュリティポリシーも設定できるようになるため、柔軟なアクセスコントロールを書けることができるようになったのは非常に便利でした
  3. Kubernetes 前提の WebUI になっている Kubernetes に対応を絞ったことにより、 Kubernetes の namespace 一覧や Volume 一覧などを手軽に WebUI から確認できるようになりました

Rancher 2.0 の不満点

不満というほどではないのですが、下記のような点が 1.6 と比較して気になりました

  1. 1.6 ではサポートされていた LDAP 認証が v2.0.4 段階ではまだリリースされていない
    • 間もなくリリースされるようです
    • Add openLDAP as a auth provider in 2.0*1
  2. 1.6 ではあった Infrastructure という Pod 一覧が見ることができる管理画面が 2.0 にはない
    • f:id:weseek:20190919161925p:plain
    • 上記の画像のように Node 毎の Pod が見られる画面があり、Pod の開始、停止などをリアルタイムに確認できる画面が 1.6 にはありましたが、2.0 では今のところ採用されていません。
    • kubectl コマンドなどを利用して、Pod の状態は確認できますが、個人的には格好良い画面だと思っていたので少々残念でした

2.0 で行ったトラブルシューティング

構築する際にスムーズに行かなかった点があり、数件トラブルシューティングを行いました。

  1. グローバル IP とプライベート IP 2つの足(NIC)を持つサーバを Kubernetes クラスタのネットワークに所属させることができない (Calico ネットワークが確立されない)
  2. 一度クラスタに所属させた Node をクラスタから外し、再度クラスタに所属させようとすると、etcd のデータ同期が上手く同期されない

こちらは解決方法とトラブルシューティングの過程も含めて、また別の記事として公開したいと思います。

最後に

Kubernetes クラスタが壊れるという経験はあまりできないことで、今回は貴重な経験ができたと思います。トラブルが発生しても、「ただでは起きない精神」というのは大切にしていきたいです。

また、再度最初から Kubernetes クラスタを構築し直したことで、古い設定を刷新していくこともできましたし、Kubernetesyaml 設定が残っていれば復元可能である、という Kubernetes 自体の強力さも痛感しました。

Rancher 2.0 もバージョンが v2.0.4 とリリースされてから間もないですが、開発が活発にされているため、今後も期待できるソフトウェアだと思います。

*1:2019/09/19 現在、リリースされています

イマドキの JavaScript 開発で使える、リモートデバッグとロガーの Tips

こちらは 「イマドキの JavaScript 開発で使える、リモートデバッグとロガーの Tips (2018年版-前編)」からの転載です。

SEROKU の開発を例に、弊社で使っているリモートデバッグとロガーの Tips をご紹介します。 当記事は 2018 年、と過去の記事ですが、現在でも応用可能な Tips になっています。



案件としても OSS 成果物としても、JavaScript を利用するシチュエーションは増え続けています。まだまだ枯れた言語とは言い難い状況で、使われるバージョンも ES5 から ES7 まで進化を続け、新しい文字列リテラルや async/awaitのような「イマドキの JavaScript の書き方」を紹介する記事は多い中、デバッグはこうあるべきという情報は比較的少ないように思います。

本記事では JavaScript による開発、特に node.js を使ったサーバーサイド開発環境および babel を使ったクライアントサイド開発環境で便利なロガーの Tips、そして Microsoft 提供の Visual Studio Code とのリモートデバッグの Tips を紹介します。

動機

デバッガ、ロガーの存在意義とは

開発を行う上で、print デバッグを卒業してデバッガを利用し、ブレークポイントを仕掛けてなにがどうなっているのかを見るのが脱初心者の証。どうしてうまく動かないのか、流れるコードを途中で止めて状況を把握するのは、生産性向上に直結します。

他方でロガーは、開発時・運用時両方で重要な要素です。正常時・異常時両方を把握するのに便利な一方で、いざ本番環境で理解不能な状況に陥った場合に一時的にログレベルを上げることで問題解決に必要な情報を手に入れることができます。

Java の世界を見てみよう

筆者は Java 歴が長いのですが、あちらのエコシステムではその両方をすぐ使える状況になっています。

デバッガに関して言えば、Java 開発の文化では EclipseIntelliJ のような重量級 IDE を利用するのが一般的です。それらにはボタン1つクリックするだけでデバッガが立ち上がるようになっているため、Java 開発者は初心者のうちからデバッガの利用を教えられ、活用していくことが多いと思います。

ロガーに関しては、Java ではインターフェース・実装共に選択肢が非常に多いのが特徴的です。Commons Logging の登場を皮切りに多種多様なロギングライブラリが登場し、何を採用したらいいのかわからない暗黒時代を経て、現状は SLF4j というインターフェースを中心に、プロダクト開発者やフレームワーク開発者が自由にライブラリを組み合わせて、好みのロギング方法、ログ出力方法を選べるようになっています。

参考: Javaのロギングライブラリの歴史と現状をふんわり把握する(初学者向け)

言語仕様が枯れていること、そもそも静的型付けの言語であること、歴史が長いことも、Java コミュニティがこれらの資産を産み出すことができた一因と言えるでしょう。

翻って JavaScript 開発

JavaScript 界隈の変化のスピードは Java の比ではありません。そのため、アーキテクチャとして何を組み合わせるのか、ビルド環境をどうするのかなど、様々な要素で「これがデファクト」というものが事実上存在していない状況です。

デバッガ

IDE を利用するチームは少数派で、多くはコーディングはエディタで行い、開発環境でのビルド・実行は直接ターミナルから npm を叩く構成が主流です。そのため、デバッガの整備には一工夫必要で、エディタと連携してリモートデバッグ可能な環境で開発を行っている開発者は少ないのではないでしょうか(もっとも、ライトウェイト言語による開発全般でその傾向はあると思われます)。

ロガー

先にフレームワークの話から入りますが、「デファクトフレームワークが標準搭載しているロガーが便利」な状況があるからこそ、JavaRuby でそのあたりをがんばらなくていい、というのはあります。Spring Boot と log4j, logback の関係であり、Ruby on RailsRails.logger の関係です。

Express は Spring Boot や Rails と比べて守備範囲が狭く、オールインワンで使えるロガーを準備してくれているわけではありません。クライアントサイドに於いても webpack/babel は地位を固めましたが、これらはビルドツールであり、React もまたそのあたりは守備範囲外です。

また、多くの開発者に使われている debug というライブラリは明らかに機能不足です。ログレベルがないのが致命的で、できることと言えばログが属するネームスペースごとに出すか出さないかを決められるだけ、そしてその設定方法も環境変数 DEBUG にネームスペースを羅列するだけと、非常にシンプルなだけに手が届かないところは多いと言えます。

理想の世界

では、今の世界がどうなると JavaScript 開発者の生産性が上がるでしょうか。理想を挙げておきましょう。

対象システム

以下の3つのシナリオをカバーすることにします。

  • シナリオA
    • node.js (Express)
  • シナリオB
    • node.js (Express) + webpack/babel によるクライアントビルド
  • シナリオC
    • next.js on Express

シナリオCなどは大変「イマドキ」ですね

デバッガ

  • SourceMap の利用
    • ブラウザの開発者ツールでエラーを追う場合、トランスパイル前のソースの行数が分かる
  • リモートデバッグ

ロガー

  • 記述側
    • サーバーサイド、クライアントサイド両方で同じログモジュールを利用できる
    • ログレベルを指定したログ出力行の記述ができる
  • 出力側
    • サーバーサイド、クライアントサイド両方で同じログモジュールを利用できる
    • development, production 等の環境用の設定ファイルでデフォルトの挙動を設定できる
      • 環境変数設定により、上記を一時的に変更できる
    • プロダクト全体でのデフォルトログ出力レベルを設定できる
    • ログのネームスペースごとにログ出力レベルを設定できる
    • development, production 等の環境に応じて出力フォーマットを変更できる
      • development 環境ではフォーマットされたログ出力
      • production 環境下では JSON フォーマット出力による高速なログ出力
  • 過去の資産の有効利用
    • 今まで記述された debug ライブラリによる記述を変更することなく、新しいロギングライブラリによる出力を可能にする

今回見送ること

ロガーに関しては、他言語のフレームワークでできているようなファイルへのログ出力 および ログローテートを可能にしたい、という需要もあるかもしれません。今回利用するロギングライブラリでも設定によってはそれも可能なのですが、コンテナディプロイ全盛の「イマドキ」では優先度は低いと考え、見送ることにします。

まとめ

前編ではデバッガ、ロガーの大切さと、他の言語・フレームワークと比べた際の JavaScript 開発環境に於けるビハインドについてまとめました。次回、中編・後編で「理想の世界」を実現する具体的なコードを紹介していきます。

WESEEK がプロジェクトを始めるときに準備していること

こちらは 「SEROKUを支える技術 〜開発準備編〜」からの転載です。(多少編集をしています)

SEROKU の開発スタートを例に、弊社で行っているプロジェクト開始時の準備項目を紹介しています。



こんにちは。haruhikonyan です。 今回は前回のプロジェクト管理編に引き続き、この「SEROKUフリーランス」開発プロジェクトを開始するにあたっての準備にはどういったものが必要だったかを紹介したいと思います。

このSEROKUだけに限らず、何を開発するにも開発準備は必要だと思うので、参考になれば幸いです。

Wiki等情報共有ツールの用意

個人での開発では必須ではないかもしれませんが、チーム開発を行う上ではwikiなどの情報共有のためのツールは不可欠であると思います。

プロジェクト管理編でも紹介しましたが、WESEEKでは wiki には GROWI、チャットには Slack、ITS には YouTrack を使用しています。

プロジェクトの大筋には関係ありませんが、個人でも会社でもメンバーが一番使い慣れていたり、使いたい機能があるものを選定し、何かを始める際にはそのセットをすぐに立ち上げられるように準備しておくことが良いでしょう。

大まかな要件の確認

開発を行う上で要件を確認せずにいきなり開始するプロジェクトはそうありませんよね。とはいえ SEROKU ではウォーターフォール型開発を採用していないので長い長い要件定義フェーズというものがあるわけではありません。

そこで行うのが大まかな要件の確認です。コアとなるサービスの機能や、必要なことが確実にわかっている最低限の要件というものを洗い出していきます。

SEROKU の場合は

  1. フリーランスユーザと企業ユーザの2種類がいてユーザ登録とログインができる
  2. フリーランスユーザはオークション形式で自分のスキルの出品ができる
  3. 企業ユーザは出品されてるオークションに対して入札ができる

といったような具合にシステムの大まかな要件を洗い出していきます。そのほかの要件については、アジャイル開発を進めていくうえで都度優先度を決めて追加していきます。

アーキテクチャ選定

あらかたシステムの基礎となる要件の確認ができたら、実際に開発で使うアーキテクチャの選定を行います。

選定するうえで大事なのは下記のようなものを気にするとよいと思います。

  • 挙がっている要件を実現できるか
  • 流行っているか、コミュニティが成熟しているか
  • 扱える人材がチームにいるか
  • チームメンバーの宗教上扱うことが可能か

挙がっている要件を実現できるか

これは当たり前ですね。作ろうとしているものが技術上の制約で実現できなければ意味がありません。また、言語やフレームワークが作ろうとしているものに対しての向き・不向きも、もちろん考える必要があります。

流行っているか、コミュニティが成熟しているか

流行っているかどうかも技術の選定上では重要なファクターであると思います。

廃れているような技術やもう開発が終了していてコミュニティが盛んでないような技術は、問題が発生した際に対応することが難しかったり、そもそも情報がどこにも無いということがあります。その際に自分達だけで解決しようとすると余計な工数がかかってしまうという危険性があります。

扱える人材がチームにいるか

当たり前のようですが「流行っているから」とか「よさそうな記事を見つけたから」という理由で採用し、学習コストばかりかかってしまっても最終的にハッピーとは言い難かったりします。

とはいえ「最新技術を積極的に取り入れていきたい」という気持ちももちろんあると思います。その場合 WESEEK では技術選定のフェーズで試しに誰かが最新技術を使ってみて、その人がチーム内での先駆者となり主導していくということを行ったりします。

新規プロダクトのシステム開発合宿を試した、その結果・・・ では初めて使う技術を先駆者の導きにより、見事チーム全員が翌日には難なく扱えるようになっていました。

ソースコード管理

使うアーキテクチャの選定が終わったらソースコードの管理についても考える必要があります。これを含めてアーキテクチャ選定と言ってもいいかもしれません。

分散型 vs 集中型

ソースコードの管理にはバージョン管理システムを使っているチームがほとんどだと思いますが、バージョン管理システムには大きく分けて2種類あります。

ほとんどの方はこちらを採用していると思いますが Git や Mercurial などの分散型と、一方で一昔前までは主流であった Subversion (SVN) などの集中型があります。

WESEEK では基本的にはテキストファイル(ソースコードなど)の管理には分散型を用い、バイナリファイル(画像など)は集中型を使う、といったように併用しています。*1

オンプレ vs クラウドサービス

管理するための技術の選定が出来たら、ソースコードのバージョン管理を行うサーバが必要です。

Git でクラウドサービスを選択するのであれば、かの有名な GitHub をはじめとしたホスティングサービスが使えます。しかし大体のサービスはプライベートリポジトリを作成しようとするとお金がかかります。*2

一方オンプレで管理をするのであればサーバの電気代などの諸経費を考えなければ外部にお金を払う必要ありません。しかし万が一問題が起きた場合や構築するための人件費などを考えると必ずしも安上がりではないことに注意したいです。

開発スタートアップ執筆

ここまで割と一般的なことを述べてきましたが、おそらく開発スタートアップというものはどこの開発チームでもやっているものではないと思います。

SEROKU 及び WESEEK で行うプロジェクトにおいては必ず開発スタートアップというドキュメントを用意しています。
このドキュメントを書くことで、個人特有の環境の差異で出てしまうバグなどを未然に防ぐことであったり、新しくチームにジョインしてきた人もスムーズに開発へと参加できます。

ドキュメントを作成するためどうしても最初にコストはかかってしまうのですが、十分にペイできていると思います。

CD/CI 準備

現代においてプロダクトの開発を行う上では CD/CI は必須と言っても過言ではないと言われてきています。もちろん SEROKU でも CD/CI 環境の構築は施されています。

詳しい利用技術や概要については SEROKU を支える技術 ~CI/CD編~ を参照ください。

まとめ

これら上記に挙げたものはすべて必須と言うものではありませんが、 WESEEK がこれまでに「開発をする際に開発者が気持ち良く開発をできるようにするにはどういう準備、どういう仕組みが必要なのか」を吟味した結果です。

もちろんこれらの構成が決定版ということではなく、これからも技術の進歩とともに変化していくものだと思っていますので一例としての参考になればうれしいです。

関連記事

tech.weseek.co.jp

*1:Git ではバイナリファイルを取り扱うとリポジトリが肥大化しがちなので、 asset などの素材管理は Subversion で行っています。最近ではバイナリの扱いを Git LFS に逃がすという手法も一般的になってきています。皆さんは Git でのバイナリファイルの取り扱いはどうされていますか?

*2:2019/09/13 現在、無償化されたことは把握しています

Kubernetes + Let’s Encrypt でワイルドカード証明書を自動発行できる基盤を作ってみよう

こちらは 「Kubernetes + Let’s Encrypt でワイルドカード証明書を自動発行できる基盤を作ってみよう」からの転載です。


「SEROKU フリーランス(以下、SEROKU)」の中の人をやっている syunsuke です。SEROKU では主にインフラ面の担当をしています。

はじめに

SEROKU の開発フローでは、開発用のリポジトリMercurial を用い、各機能実装ごとにブランチを用意した上で開発を行っています。

その上でさらに、社内に Kubernetes クラスタを用意して、ブランチごとにデモ環境を立ち上げられるような仕組みを整備しています。

(詳しい内容については、SEROKU ジャーナルの別記事でご紹介している SEROKUを支える技術〜CI/CD編〜 をご覧ください)

当初は、各ブランチごとにドメインを作成し、Let’s Encrypt による SSL 証明書を発行していたのですが、並行で開発するブランチ数が多くなってくるとやがて rate-limit に当たるようになりました。 (参考: Rate Limits – Let’s Encrypt – Free SSL/TLS Certificates)

今回は、それを回避するために必要となった、Kubernetes クラスタ上で Let’s Encrypt を用いたワイルドカード証明書を自動発行・更新できる基盤の作り方についてご紹介します。

弊社では AWS Route 53 でドメインを管理しているため、本記事では Route 53 を利用したドメインを対象とします。

必要となる前提知識

本記事では、以下の技術用語については説明いたしませんので、まだご存知ないという方は参考サイトをご覧になってから本記事をご覧になると、より理解が進むと思います。

基盤構築にあたって必要となるスタート条件

本記事では、以下の条件が揃った状態をスタートに必要な条件とします。

  1. kubectl コマンドを利用して、Kubernetes クラスタにログイン・操作できること
  2. helm コマンドを利用して、Kubernetes クラスタに任意の Chart をインストールできること
  3. 証明書を発行する予定のドメインを保持していること
    • 本記事では、証明書を発行する対象ドメインexample.com とします
  4. AWS Route 53 で上記ドメインが管理できていること
    • ドメインの NS レコードが Route 53 に向いていることを前提とします

本記事のゴール

Kubernetes クラスタ上で以下ができるようになることをゴールとします。

本記事でご紹介するミドルウェア(cert-manager)について

本記事では、Kubernetes クラスタ上で証明書の自動発行・更新を担ってくれるミドルウェアとして cert-manager v0.3.0(執筆時最新) を利用します。

このミドルウェアは、Let’s Encrypt で証明書を発行・更新する上で必要となる以下の作業を自動化してくれます。

構築手順

1. AWS IAM role の用意

まず、cert-manager が Route 53 を操作するために必要なユーザを追加します。

  1. AWS IAM の Management Console へアクセスします
  2. 左側のサイドバーより「ユーザー」をクリックします
  3. 上部にある「ユーザーを追加」ボタンをクリックします
  4. 「ユーザー名」に適当な文字列を入れます
    • 自分が後で見て分かりやすい文字列を入力しておきましょう
    • 例: k8s-cert-manager など
  5. 「アクセスの種類」は「プログラムによるアクセス」にチェックを入れます
  6. 「次のステップ: アクセス権限」ボタンをクリックします
  7. 「xxx のアクセス権限を設定」の箇所で、「既存のポリシーを直接アタッチ」をクリックします
  8. 「ポリシーの作成」ボタンをクリックします
  9. 開いたタブ/ウィンドウの中で「JSON」タブをクリックします
  10. 出てきたテキストエリアに以下のテキストをコピーします

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "route53:GetChange",
                "Resource": "arn:aws:route53:::change/*"
            },
            {
                "Effect": "Allow",
                "Action": "route53:ChangeResourceRecordSets",
                "Resource": "arn:aws:route53:::hostedzone/*"
            },
            {
                "Effect": "Allow",
                "Action": "route53:ListHostedZonesByName",
                "Resource": "*"
            }
        ]
    }
    
    • 公式ドキュメント に IAM に設定すべきポリシーが記載されていますが、その内容だと cert-manager がうまく Route 53 にアクセスできないため、こちらの Issue に挙がっているポリシーを使います*1
  11. 画面下部にある「Review Policy」ボタンをクリックします
  12. 「名前」に適当な文字列を入力します
    • 例: route53-access-for-cert-manager
  13. 「Create Policy」ボタンをクリックします
  14. 「xxx が作成されました」という表示が確認出来たら、そのウィンドウ/タブは閉じてください
  15. 元のユーザ追加画面で「更新」ボタンを押してから、作成したポリシーを検索し、画面左端のチェックボックスをオンにします
  16. 「次のステップ: 確認」ボタンをクリックします
  17. 内容に問題がないようであれば、そのまま「ユーザーの作成」ボタンをクリックします
  18. 作成に完了すると、アクセスキーID/シークレットアクセスキーが表示されますので、忘れずにメモしましょう
    • ここで表示されるアクセスキーID/シークレットアクセスキーをこの後の手順で利用します
    • ちなみにメモし忘れたとしても、今回作成したユーザについて別のアクセスキーを発行することが可能です

2. Kubernetes クラスタ上に cert-manager のインストール

公式ドキュメント通り、helm を用いて cert-manager を Kubernetes クラスタへインストールします。

$ helm install \
    --name cert-manager \
    --namespace kube-system \
    stable/cert-manager

インストールが完了すると、以下の様に kube-system namespace に cert-manager の Pod が動き始めます。

$ kubectl -n kube-system get pod
NAME                                           READY     STATUS    RESTARTS   AGE
cert-manager-cert-manager-56fcf79bc8-dx85q     1/1       Running   0          39m

3. 証明書を発行するための設定を行う

cert-manager では、証明書を発行するための ACME プロパイダ(Let’s Encrypt)や DNS プロパイダなどの設定を Issuer/ClusterIssuer というリソースで管理します。

Issuer/ClusterIssuer は namespace 毎に利用可能とするか、クラスタ全体で利用可能とするかの違いで、本記事ではクラスタ全体で利用できるように ClusterIssuer として登録します。

  1. まず、IAM ユーザー作成時に発行したシークレットアクセスキーを Secret として登録します

     $ kubectl -n kube-system create secret generic prod-route53-credentials-secret --from-literal=secret-access-key=<シークレットアクセスキー>
    
  2. 登録できたか確認します

     $ kubectl -n kube-system get secret prod-route53-credentials-secret
     NAME                              TYPE      DATA      AGE
     prod-route53-credentials-secret   Opaque    1         59d
    
  3. DNS-01 でドメインを検証できるようにする ClusterIssuer を作成し、Kubernetes クラスタ上に登録します

     $ cat <<'EOF'> clusterissuer-letsencrypt.yaml
     apiVersion: certmanager.k8s.io
     kind: ClusterIssuer
     metadata:
       name: letsencrypt
     spec:
       acme:
         email: <任意のメールアドレス>
         server: https://acme-staging-v02.api.letsencrypt.org/directory
         privateKeySecretRef:
           name: letsencrypt-private-key
         dns01:
           providers:
           - name: route53
             route53:
               accessKeyID: <アクセスキーID>
               region: us-east-1
               secretAccessKeySecretRef:
                 key: secret-access-key
                 name: prod-route53-credentials-secret
     EOF
     $ kubectl apply -f clusterissuer-letsencrypt.yaml
    
    • <任意のメールアドレス> の部分は、ご自身で受信できるメールアドレスを記載してください
      • 発行した証明書の期限が近づくと、メールで通知が来るようになります
    • <アクセスキーID> の部分は、IAM ユーザー作成時に発行したアクセスキーIDを記載してください
  4. Let’s Encrypt のアカウント発行状況を確認します

     $ kubectl describe clusterissuer letsencrypt
     ...(snip)...
     Status:
       Acme:
         Uri:  https://acme-v02.api.letsencrypt.org/acme/acct/XXXXXXXX
       Conditions:
         Last Transition Time:  2018-05-18T15:20:48Z
         Message:               The ACME account was registered with the ACME server
         Reason:                ACMEAccountRegistered
         Status:                True
         Type:                  Ready
     Events:                    <none>
    
    • 上記のように、Message が The ACME account was registered with the ACME server となっていれば、Let’s Encrypt アカウントを正常に作成できています

4. 証明書の発行

ここまで準備できたら、いよいよ証明書を発行してみます。

cert-manager では、発行する証明書の中身を定義する設定を Certificate というリソースで管理します。

本記事では、*.example.com に関するワイルドカード証明書を発行する、という想定で設定を記載していきます。

  1. Certificate を作成し、Kubernetes クラスタ上に登録します

     $ cat <<'EOF'> cert-wildcard-example.yaml
     apiVersion: certmanager.k8s.io/v1alpha1
     kind: Certificate
     metadata:
       name: wildcard-example
     spec:
       acme:
         config:
         - dns01:
             provider: route53
           domains:
           - '*.example.com'
       commonName: '*.example.com
       issuerRef:
         kind: ClusterIssuer
         name: letsencrypt
       secretName: cert-wildcard-example
     EOF
     $ kubectl apply -f cert-wildcard-example.yaml
    
    • kubectl apply によるリソースの登録が完了すると、cert-manager によってすぐに証明書発行作業が開始されます
    • 証明書発行が完了すると、 spec.secretName に設定された Secret に取得した証明書の内容が出力されます
  2. 証明書の発行状況を確認します

     $ kubectl describe cert wildcard-example
     ...(snip)...
     Status:
       Acme:
         Order:
           URL:  https://acme-v02.api.letsencrypt.org/acme/order/XXXXXXXX/XXXXXXXX
       Conditions:
         Last Transition Time:  2018-06-18T03:26:11Z
         Message:               Certificate renewed successfully
         Reason:                CertRenewed
         Status:                True
         Type:                  Ready
         Last Transition Time:  <nil>
         Message:               Order validated
         Reason:                OrderValidated
         Status:                False
         Type:                  ValidateFailed
    
    • DNS-01 によるドメイン検証は DNS 伝搬に時間がかかるため、証明書発行が完了するまで少し待つ必要があります
      • DNS 伝搬が完了するまで待機する作業も cert-manager ではやってくれています!
    • 証明書発行が完了すると、上記のように Certificate renewed successfully というメッセージが確認できます
  3. 証明書が出力されたことを確認します

     $ kubectl get secret cert-wildcard-example
     NAME                    TYPE                DATA      AGE
     cert-wildcard-example   kubernetes.io/tls   2         25d
    
    • 上記のように kubernetes.io/tls タイプの Secret の存在が確認できれば、証明書は発行できています!

5. Kubernetes クラスタ上に立てた Web サービスの公開

本記事では、サンプルのための nginx Pod を Kubernetes クラスタ上に立てて、それを外部に公開するための Service/Ingress を登録してみます。 Ingress で指定する証明書に、今回発行した証明書を指定しています。

  1. サンプルアプリを立ち上げます

     $ cat <<'EOF' > example-nginx.yaml
     apiVersion: extensions/v1beta1
     kind: Deployment
     metadata:
       name: nginx-example-deployment
       labels:
         app: example-nginx
     spec:
       replicas: 1
       template:
         metadata:
           labels:
             app: example-nginx
         spec:
           containers:
           - name: nginx
             image: nginx
             ports:
             - containerPort: 80
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: example-nginx
       labels:
         app: example-nginx
     spec:
       ports:
       - name: http
         port: 80
         protocol: TCP
         targetPort: 80
       selector:
         app: example-nginx
       type: NodePort
     ---
     apiVersion: extensions/v1beta1
     kind: Ingress
     metadata:
       name: example-nginx
       labels:
         app: example-nginx
     spec:
       rules:
       - host: nginx.example.com
         http:
           paths:
           - backend:
               serviceName: example-nginx
               servicePort: 80
       tls:
       - hosts:
         - nginx.example.com
         secretName: cert-wildcard-example
     EOF
     $ kubectl apply -f example-nginx.yaml
    
  2. Ingress で取得できたアドレスを確認します(以下の「ADDRESS」の箇所)

     $ kubectl get ing
     NAME            HOSTS               ADDRESS                  PORTS     AGE
     example-nginx   nginx.example.com   XXX.XXX.XXX.XXX          80, 443   3m
    
    • このアドレスに対して名前が引けるように DNS を設定します

6. AWS Route 53 の設定

AWS Route53 へアクセスし、上記のアドレスに対して nginx.example.com でアクセスできるように A レコードを追加します。

7. Let’s アクセス!!

https://nginx.example.com へアクセスして、以下の様に発行された証明書がブラウザ上で確認できれば、証明書発行基盤の構築は完了です!

f:id:weseek:20190912125006p:plain

サンプルで利用したサービスの設定は以下で全部削除できます。

$ kubectl delete deploy,svc,ing -l 'app=example-nginx'

その他のドメイン検証方法

本記事では、ワイルドカード証明書を発行するために必要な DNS-01 方式のドメイン検証をする設定を作成しましたが、cert-manager では DNS-01 方式以外にも HTTP-01 方式でのドメイン検証にも対応しています。

詳しくは、cert-manager の公式ドキュメントもご覧ください。

まとめ

いかがでしたでしょうか。本記事で紹介した基盤を Kubernetes クラスタ上に用意しておくことで、デモ環境をよりたくさん、安全に用意することが可能になります。

是非、CI/CD と併せて皆さんの開発環境に取り入れていただき、本記事が開発・リリース速度を向上させる上で参考になれば幸いです。

*1:2019/09/12 現在修正されている可能性があります

新規プロダクトのシステム開発合宿を試した、その結果・・・

こちらは 「新規プロダクトのシステム開発合宿を試した、その結果・・・」からの転載です。

2018/06/16 に掲載されているので、情報は若干古めではありますが、先日 OpenBeta としてリリースした GROWI.cloud の開発合宿を行った様子を紹介しています。




株式会社 WESEEK の佐藤です。

先日、弊社では一つのプロダクトを社員全員で開発する合宿を初めて開催しました。 (普段はリモートワークをしているメンバーも合流しました)

今回はプロダクトの詳細は説明することができませんが、開発合宿を振り返り、当時の様子と良かった点・悪かった点を紹介したいと思います。

開発合宿について

開発合宿は自社オフィスから離れた某所で行いました。

f:id:weseek:20190911130456p:plain

午前中に健康診断を済ませた後に社員全員で移動し、
到着後、各自持参したラップトップ PC を使って開発を行いました。

尚、事前に準備したことがいくつかあります。

  • インフラ、フロントエンド、バックエンド選定 (チャレンジ指向)
    • next.js, express, sequelize, Jest, MariaDB, k8s(オンプレ) + Docker, BRIGADE を利用することとした
  • 選定した技術を用いた Hello World となるコード
    • サンプルのモデルを使って CRUD 操作までできる Hello World を作成した
    • reactstrap, bootstrap 4 も導入した
  • 開発スタートアップ、開発ルールなどのドキュメント
    • 開発環境を整えるためのマニュアルを作成した
    • 開発ルールは社内で通例となっているものをドキュメント化した
  • CI/CD 環境
    • RhodeCode + Git, Jenkins, k8s + Docker を用意した
    • ブランチ毎に demo 環境にデプロイできる環境を用意した
      • Topic ブランチ(Fix / Feat / Imprv / Support) に push すると k8s 上に https://demo-${ブランチ名(加工済)}/ としてアクセス出来る環境がデプロイされる
    • master ブランチが更新されると k8s 上に demo 環境がデプロイされる
  • Agile 開発用カンバン
    • ストーリーを作成、ポイント付けを実施、Sprintを用意した
  • 開発環境
    • 全員が PC 上で開発スタートアップを実施した
    • 大半が温泉の交互浴により体を整えた*1 (合宿ですし f:id:weseek:20190911131316p:plain )

開発の進め方

  • 合宿参加者は一つのプロダクトの開発を行う (普段は各人マルチプロジェクトで対応している)
  • 基本的に開発ルールに則るが1点特別ルールを設けた
    • 実装後の第3者による動作確認は割愛して自己責任とする (動作しなかったら直す)
  • 開発方針を決めたい・確認したいときは、その場でプチ議論を行って解消させる
  • 各々自由な姿勢・恰好で開発を行い休憩も適宜取る
  • チェックアウトまでは部屋で開発を進め、チェックアウト後も会議室を借りて開発を進める

f:id:weseek:20190911130626p:plain

合宿場所とオフィスでは場所以外に開発環境の違いはあまりなく、

  • ラップトップPCを使う点
  • Wifi でインターネットに接続する点
  • オフィス机と椅子がない点

くらいだったので、割と普段どおりに開発を進められました。

また、幸いにも Wifi 接続は 802.11ac/11n が利用でき、実測でも 30 – 50Mbps 程度出ていて快適でした。

合宿の成果

合宿の成果としては以下のとおりです。

f:id:weseek:20190911130708p:plain
GROWI.cloud TOP画面

  • 稼働時間 16時間
    • 1日目 16時~19時、20時~28時
    • 2日目 10時~15時
  • 12 ストーリー(何かしらの進捗あり)
  • 51 タスク(6 Open, 4 Progress, 18 To Verify, 21 Done, 2 Reject)
  • 185 コミット
    • 参考) 5月,6月のコミット数

f:id:weseek:20190911130759p:plain

実装が開始できるまでは実装期間と比べて長い時間を使って技術スタックの選定に時間を費やすものの、コミット数でみると合宿の効果は見られました。

インフラ/バックエンドの成果

  • k8s
    • Pod/Service をデプロイする Helm Chart を作成した
    • Appが共有で利用するリソースをデプロイした
  • BRIGADE
    • k8s クラスタに Pod/Service をデプロイする event を作成した
    • 下記検証も行った
      • REST を使って event が発火できるか調査した (返答がブロックなのかノンブロックなのかを含む)
      • 試しに BRIGADE の Getting Start を動かした
  • k8s & Jenkins のトラブルシュートやチューニングを適宜実施した
    • topic ブランチごとにデプロイすると k8s クラスタが高負荷となった
    • CI/CD が 4 分では終了しないことがしばしばあった
    • k8s に Service がデプロイされていると k8s によって自動で設定される環境変数が、アプリで利用する環境変数と競合して予期せぬ動作をした
      • Service 名に DB など短すぎる名前を採用するのは避けましょう…
    • 謎の inode 枯渇現象が度々発生した
    • ・・・etc

フロントエンドの成果

  • next.js + sequelize
    • プロダクトで利用するデータモデルを一通り作成した (5種類)
    • ユーザに紐づくモデル(各ユーザが任意に作成できるリソースを示すモデル)
      • 一覧が表示できる
      • 新規作成するボタンが表示できてウィザード画面に遷移できる
      • ウィザード画面を一通り遷移できる
    • Order モデル(ユーザに紐づくモデルの Order 処理を示すモデル)
      • BRIGADE に対してリソースを新規追加する event を発火できる
    • ユーザログイン画面が表示できる
      • スタイリッシュなテーマを適用した
    • ユーザのログイン状態に応じてページの表示・非表示を制御できる (未完)
    • GitHub アカウントを使って OAuth によるログイン機能ができる (未完)

合宿を振り返ってみて

ざっくりとした感想としては、オフィスを離れて温泉で休養もしつつ、ちゃんと仕事を進められたため成功だったと思います。

振り返ってみて次の点がよかった点・悪かった点だと思います。

  • 一つのプロダクトに対して実装を進めるため、マルチプロジェクトに比べて頭の切り替えが少なくて済んだ
  • タスクのブロックが発生しやすいため常に実装を進めないとチーム開発が止まる緊張感が生まれた
  • 全員が同じ時間帯・場所で仕事をするため連携がしやすかった
  • 結果的にコミット量やタスク解決速度が高まった
  • いつでも温泉に入れて体が休まった
  • とは言え深夜まで実装して早起きすると疲れは残った
  • オフィスデスク/チェア・デュアルディスプレイがないと腰と目が辛かった
  • 合宿明けに通常業務への復帰に一瞬戸惑った (普段はタスクの確認を前営業日に行うが合宿時は割愛したため)

皆様もオフィスから離れて合宿をしてみると普段とは一風変わった結果を得られて、今後の開発に役立つかもしれません。

スペシャルサンクス

実装合宿の企画と各種手配を進めてくれたのは普段はリモートワークをしている Tatsuya さんでした。

この場をお借りしてお礼をさせて頂きます。

どうもありがとうございました。

f:id:weseek:20190911131033p:plain

WESEEK で採用している CI/CD 実現手法

こちらは 「SEROKUを支える技術〜CI/CD編〜」からの転載です。

本記事では SEROKU の開発を例に社内で採用している CI/CD の実現手法を紹介しています。




「SEROKUフリーランス」を支える技術シリーズ。今回は SEROKU フリーランスで行っているCI/CDについてご紹介します。

CI/CD とは?

CI/CD とは、 Continuous Integration/Continuous Delivery (継続的インテグレーション/継続的デリバリー)を示す言葉で、ソフトウェア開発におけるプラクティスの一種です。

比較的わかりやすい説明が AWS の DevOps サイトに掲載されていましたので、詳しい説明はそちらに譲ろうと思います。

aws.amazon.com aws.amazon.com

SEROKU フリーランスはどのようなCI/CDを行っているか

SEROKU フリーランスでは CI/CD ツールに Jenkins を使用しています。他の CI ツールも検討しましたが、社内の多くの他のプロダクトでも CI/CD ツールに Jenkins を採用しており、社内でも扱いに慣れているエンジニアが多数いることから、今回も Jenkins を採用しました。

従来のプロダクトでの CI/CD の一例

SEROKU フリーランス以前のプロダクト群では、Jenkins で以下のような CI/CD を行っていました。

  • git などの repository の default branch に code がマージされたら下記の CI/CD を実施
    1. code の build 実施
      • 開発したcodeを実環境で動かすために compile, transpile, bundle, ライブラリのインストールなどを行う
    2. Test 実施
      • 開発した code が意図した動作を行うか、自動化された unit test, e2e test を行う
    3. 上記に問題が無ければ、default branch の code を検証環境に deploy
      • Web ブラウザで検証環境にアクセスして未リリースのプロダクトを先行利用することで、本番環境にリリースする前にプロダクトの動作を確認することができる

SEROKU フリーランスでの CI/CD

しかし SEROKU フリーランスでは上記をより発展させ、次のような CI/CD を行っています。

  • git などの repository の あらゆる branch に code が commit されたら、その branch ごとに下記の CI/CD を実施
    1. code の build 実施
    2. Test 実施
    3. 上記に問題がなければ、docker image を build して docker registory に登録
    4. default branch であれば build した docker image を検証環境に deploy

従来のプロダクトでの CI/CD と SEROKU フリーランスでの CI/CD では大きく2点の変更があります。

一つは従来では default branch のみ CI/CD 対象にしていたのを SEROKU フリーランスでは全 branch を CI/CD 対象にするようになった点です。これには Jenkins2 系から導入された multibranch pipline*1 という機能を使用しています。

もう一つは docker image の build と docker registory が増えている点です。これは本番のプロダクト環境で Kubernetes を採用しているため、リリースを行うには開発した code は docker image 化されている必要があるからです。

また、「SEROKUフリーランス」を支える技術〜社内 Kubernetes 編〜 で触れた、「トピックブランチのデモを簡単に作れるといいなぁ」という要望をかなえるために構築した環境も Kubernetes を採用しているため、やはり docker image 化する必要があります。そのため、全ての branch で docker image を build しています。

改善された CI/CD の効果

上記の通り、SEROKU フリーランスでの CI/CD を従来型に比べて発展させた結果、以下のような恩恵を受けられています。

default branch にマージする前に test, lint 結果が正常か確実に確認できるようになった

以前は default branch のみ CI 対象にしていたため、default branch へ merge する前にコードレビューを行う際に、レビュアーは事前にテスト結果を知るために自身の開発環境で test を走らせるか、コード実装者に test 結果を共有してもらう必要がありました。一応、社内ルールでは実装者は test に通過することを確認した後にコードレビューを依頼するという決まりがあります。

しかし、希にルール通りの手順を踏まずにレビューを依頼してしまうことがあり、レビュアーも test を走らせたか素早く確認する術がなかったため、いざ default branch に merge したら実は test に失敗してしまう状態だった、ということが発生していました。

しかし multibranch pipeline により全ての branch で CI できるようになったので、実装者、レビュアーともに CI のステータスを素早く認識することができるようになり、前述のようなトラブルが減少しました。

CI/CD の動作が code 化されて管理できるようになった

multibranch pipeline 化以前の CI/CD では、CI/CD を行うためのコマンドやその実行順番は Jenkins 側で管理していました。そのためコマンドの実行順序変更などの履歴は Jenkins 側に記録される様になっており、開発コードとの管理の分離が発生していました。

これにより、例えば開発コード側の仕様変更に伴い CI のコマンドが変更されたとしても、開発コードの変更と CI コマンドの変更は別々システムで履歴管理がされるため、しばらく経過した後に当時の経緯を追跡しようとすると開発コードと Jenkins の CI コマンド変更履歴を両方確認し、突合させる必要があったりと難しい対応をする必要がありました。

multibranch pipelineでは、Jenkins での CI/CD のコマンドや手順は Jenkinsfile という file に記述し、開発コードの repository に内包する形を取ります。従って CI/CD のコマンドも開発コードと同一 repository で管理できるようになり、以前より管理が楽になりました。

リリース頻度の増加

multibranch pipeline による全 branch に対する CI/CD と 「SEROKUフリーランス」を支える技術〜社内 Kubernetes 編〜 で触れた、トピックブランチのデモでの動作確認が実現できたことにより、CD の目的である「どのようなタイミングでも default branch のコードはリリースできる状態である」が達成できるようになりました。

そのため、リリースがどのようなタイミングでも実施できるようになり、以前のプロダクトよりリリースを頻繁に行えるようになりました。SEROKU フリーランスでは週に1回以上のリリースを定常的に行っている実績があります。

今後の展望

現状では、トピックブランチごとのデモ環境に関しては、docker image を自動で立ち上げるところまで実施していません。なのでトピックブランチデモを立ち上げたい人が手動で社内 Kubernetes に環境を立ち上げる必要があります。(ただし manifest のテンプレートはあるので、文字列置換をすればすぐ立ち上がる状況です)

今後は、トピックブランチデモ環境も自動で立ち上がるようにしていきたいと考えています。すでに社内で新しく立ち上げた別の新プロジェクトでは実現済みですので、それを SEROKU フリーランスの CI/CD 環境にも導入するすることになるでしょう。

まとめ

いかがでしたか?CI/CD を適切に整備することで、開発環境や品質の向上が期待できるだけでなく、素早くリリースすることで最終的にユーザーの利益にもつながります。今回紹介した内容が、皆さんのプロジェクトの改善などに参考になれば幸いです。

Rancher を利用した社内 Kubernetes 構築

こちらは 「SEROKUを支える技術〜社内 Kubernetes 編〜」からの転載です。

本記事では SEROKU の開発を例に社内 Kubernetes の紹介をしています。




WESEEK の kouki です。SEROKU では主にインフラ担当をしています。

今回は社内で展開しつつ、SEROKU の開発でも利用している社内 Kubernetes 環境についてご紹介します。具体的な構築ログはこちらに記載しています。

Qiita: 快適な kubernetes オンプレミス環境を構築する(1. 設計編)

上記の記事は淡々と記載していますが、今回は社内 Kubernetes での利用例や実は苦労した点をつらつらと書かせていただきます。

はじめに、SEROKU の開発は Jenkins などを利用して CI/CD 環境を構築しています。マルチブランチパイプラインによる各トピックブランチのテスト実施など、昨今では「当たり前」になっている環境を提供しています。

SEROKU での社内 Kubenetes 利用例

そういった開発を行っているうちに、「トピックブランチのデモを簡単に作れるといいなぁ」という要望が社内から上がりました。

本番環境は GKE(Google Kubernetes Engine) を利用していますが、社内サーバの活用と Kubenetes ノウハウ蓄積のために Kubernetes クラスタを社内に構築することに至りました。

具体的には以下のような流れでトピックブランチのデモ環境を活用しています。

  1. 開発者が開発用にトピックブランチ切る
  2. 開発者が手元で開発を行い、適宜完成したらレポジトリに commit
  3. 開発者が実装が終わったら、レビュー担当者にレビュー依頼
  4. 開発者が社内 Kubernetes 環境にトピックブランチをデプロイ & 別の開発者に動作確認を依頼
  5. 動作確認者が社内 Kubernetes 環境に構築されたデモ環境を使って動作確認
  6. レビュー担当者が動作確認まで完了をしていることを確認して、リリース用ブランチにマージ

Kubernetes にデモをデプロイする手順は、社内 wiki に記載して開発者に周知しています。各開発者の方たちはスムーズにデモ環境の構築ができているようです。

構築するときに苦労した点

GKE と同様の環境を構築するにあたって苦労した点を紹介します。

Kubernetes クラスタ自体を構築するのは rancher を使ったため、とても容易に構築できました。しかし、実利用という観点から考えると様々な懸念点が浮上してきました。

  1. インターネット上にデモを公開するとして、グローバル IP アドレスはどの Node が受け持つのか?
    • グローバル IP アドレスとプライベート IP アドレスを 2つ持つ Node に Ingress 相当を担当させることができるか?
  2. GKE 環境にデプロイするときには Google Container Registry を利用すればいいが、社内に閉じるためにはプライベートなレジストリが必要
  3. GKE は PersistentVolume を意識しなくてもよいが、社内 Kubernetes の PersistentVolume は何を使う?

構築した時期が 2017年の末あたりだったので、ネットに情報も少なく海外のサイトを渡り歩いたり、公式ドキュメントを読み込んだりしていました。調査をしているうちに、いくつかシンプルに実装できる方法が分かってきました。

  1. の問題に対する解決方法
    • グローバル IP アドレスを持つ Node に対して、 nginx-ingress-controller を DaemonSet として動作させることによって意図した動作ができるようになりました。
  2. の問題に対する解決方法
    • docker-registry と Portus をコンテナとしてクラスタにデプロイすることによって、プライベートなレジストリを利用することができました。また、Portus には LDAP 認証機能が付いているので、社内の LDAP と連携することができました。
  3. の問題に対する解決方法
    • 社内に NFS サーバを構築して、 nfs-client-provisioner を利用することで解決しました。他にも Rook などの選択肢もありましたが、分散ストレージ運用よりもインフラ環境のシンプルさを選択しました。

まとめ

私は開発も担当していますが、調査などを含めて1ヵ月程度で構築することができました。トピックブランチのデモができるようになったことで、SEROKU の新機能実装や画面イメージなどが共有しやすくなりました。

また、社内 Kubernetes 環境が構築されたことで、社内のアプリをコンテナ化する気概が高まったという点が一番のメリットだと感じています。

SEROKU 以外にも、Prometheus や Jenkins X など様々なインフラツールを試す土壌ができているため、興味があるメンバーは社内 Kubernetes にお手軽に環境を構築していたりもします。最近はアプリ側も helm package にして、煩雑になりがちな Kubernetesyaml を隠蔽していこうという流れになっていたりもします。

今回を機に今後も SEROKU と共にインフラ環境の整備を進化させ続けようと思います。