この記事はMIS.W カウントダウンカレンダー2019冬、5日目の記事です。 お久しぶりです。53代Tsuzuです。 やたら大層なタイトルをつけてしまいましたが、MIS.W内で利用しているシステムを管理するSysAd係についてお話させていただきたいと思います。
私は今年の3月頃からMIS.WのSysAd係に就任しました。
SysAd係とは
SysAd係はMIS.Wにおける様々なシステムを管理する係です。具体的には、
- サービス等: Kibela、Slack、サークル内オンラインストレージなど
- 契約: ドメイン、レンタルサーバ
- その他: 公式・イベントHP、部室のサーバ、ルータ、ネットワーク回線、問い合わせ用メールアドレス などです。
今年3月に就任したと言いましたが、私の前任はいません。今まではWeb班の班長や幹事長によってこれらの仕事は行われていました。ですが、班と違ってなくなっては困る役職であること、管理責任が伴うことなどからSysAd係として確立されました。(と言っても実際には私がWeb班長も兼任しています。MIS.WでWebバックエンド・インフラ系の人が増えて欲しいなぁ、と思っています。)
SysAd係の役割
私はSysAd係の役割は、MIS.Wで快適にデジタル創作活動をすることを支える
- 安定した(保守しやすい)
- セキュアで
- 使いやすい
システムを構築、保守していくことだと考えています。その中でも、なるべく楽しく学びのあるシステムにして行くのが私の目標です。
以前のシステム
SysAd係として取り組んできたことについてお話しする前に以前のシステムについて先にちょっと話します。 MIS.Wでは以前から公式HP、サークル内Wiki、オンラインストレージなど全てのサービスを部室のサーバにて運用していました。
- 公式HP: 魔改造されたWordPress
- 先代のサークル員が作ったほとんど使われていないWebサイト: PHPなど、Apache2で稼働
- オンラインストレージ: ownCloud
- サークル内Wiki: MediaWiki
という構成でした。 脆弱性があり攻撃が行われるなどのインシデントが発生したり、ownCloudとMediaWikiはどちらも共通パスワード方式などセキュリティ的にとても良くない状況でした。また、Infrastructure as Codeが実現できていないため誰も管理できておらず、保守していくのが困難でした。
以上より、これらのシステムの刷新を決断しました。
Release Notes
SysAd係設立前まで遡ります。その頃は51代の むさしん さんと しくがわ さんがメインで進められていました。
公式HP
公式HPのサーバが部室にあると部室のサーバの刷新が難しかったため、さくらのレンタルサーバ さんに一旦旧公式HPを移動しました。とはいえ、旧公式HPは上で述べたようにこれからも保守していくことが難しい状況であったため新しく作り直すという流れになりました。そして、現在の新公式HPが51代と53代のサークル員が中心となって作成されました🙏 これもレンタルサーバ上で引き続き稼働しています。 また、コミケや早稲田祭などのイベント時には特設サイトをWebデザイン班の方が作ってくれています。これもレンタルサーバにて運用しています。
Wiki
サークル内で情報共有をするツールとして当時MediaWikiが運用されていましたが、これも外部に切り出せないか、という話になりました。そこでKibelaというサービスを利用することにしました。Kibelaは本来有料サービスなのですが、ありがたいことに非営利団体では無料で使えるとのことだったので活用させていただいています。 今では引継ぎ資料などもKibelaで管理されています。
オンラインストレージ
上2つが切り出せたタイミングで、残るはオンラインストレージのみになりました。 そのためバックアップをとってサーバの中身を一度削除し、新しくOSから入れ直しました。 新しいサーバの管理方法は悩んだのですが、その時部室のサーバで動かすソフトウェアがオンラインストレージしかない事などからプロビショニングツールの採用は一旦見送り、一方でコンテナは利用した方が管理しやすいためDocker+docker-composeでNextCloudを導入し、yamlファイルをGitHubで管理するようにしました。 また、NextCloudの前段に設置してHTTPS化を行うためにTraefikを採用しました。Traefikについては以前一度記事を書いたのですが、設定を書くだけでLet's Encryptから証明書を取得したり細かくルーティングができる多機能なL7ロードバランサです。最近Traefik 2.0が出てよりKubernetesなどで利用しやすくなったそうです。
シングルサインオン
共通アカウント方式を廃止するにはサークル員それぞれにアカウントを用意する必要があります。Slack、Kibela、NextCloudそれぞれでアカウントを用意するのは管理が非常に大変となるためシングルサインオン(SSO)を実現したい、と考えました。Slackはサークル内で長年使われてきたおり、これを別のツールに移行するのは困難でした。ですが、SlackをSSOに対応させるのは有料プランにする必要があります。そのためにはサークル費の値上げも必要となるため、他の解決策を探しました。SlackをSSO対応させることが困難であれば、SlackでSSOすれば良い、ということでそのためのアプローチを探し、Auth0にたどり着きました。
Auth0
Auth0は非常に高機能なIDaaSです。 Auth0内部に直接アカウントを作成することももちろんできますが、外部のサービスを利用した認証が沢山提供されています。Twitter、Google、GitHubなどのSocial Loginを始めとしSAML、Active Directory等も利用できます。標準のSocial LoginにはSlackはないのですが、Custom Social ConnectionsにてSlackが提供されています。
Auth0を外部からIdPとして利用する際にはOpenID Connect、SAML 2等のプロトコルが利用できます。今回はSAML2を利用してNextCloudをSlackでログインできるようにしました。 以下のような感じです。
できた pic.twitter.com/0NC3LOpVpe
— Tsuzu (@Wp120_3238) 2019年3月27日
Kibelaは導入した時点ではSAML2非対応でしたが、今年の6月に対応した*1とのことだったのでSAMLでのSSOに完全移行しました。これによりサークル内サービスのSSO対応が完了しました。
また、Auth0ではRuleが設定でき、ログイン時に関数を実行させることができます。以下のようなRuleを設定することで、Kibelaのログイン時にroleを設定できるようになりました。*2
function(user, context, callback) { user.app_metadata = user.app_metadata || {}; user.app_metadata.kibela_role = user.app_metadata.kibela_role || "full_member"; context.samlConfiguration.mappings = context.samlConfiguration.mappings || {}; context.samlConfiguration.mappings["kibela.user.role"] = "app_metadata.kibela_role"; auth0.users.updateAppMetadata(user.user_id, user.app_metadata) .then(function(){ callback(null, user, context); }) .catch(function(err){ callback(err); }); }
後で述べるKubernetesもAuth0経由のOpenID Connectで認証するようにしたため、現在は以下のような構成になっています。
また、Auth0では複数の認証基盤を同時にバックエンドとして利用することができます。まだ新入生をSlackに招待できていないゴールデンウィークに開催されたゲームジャムでは、新入生にNextCloudを使ってもらうためにMySQLにログイン情報を入れておいてそれをバックエンドとして使いました。こういった柔軟さもAuth0の強みだと感じています。
Kubernetesクラスタ構築
Kubernetesとは何か、の説明に関しては省略させていただきます。
MIS.Wのサーバでは10月からKubernetesクラスタの稼働を始めました。 kubeadmとkubesprayのどちらを利用して構築するかは少し悩みました。 この機会にHDDのマウント、監視ツールのインストールまでGitで管理したい、という思いが強くなりAnsibleを導入したため、一緒にGit管理ができるkubesprayを採用しました。
Kubernetesを導入した時点ではdocker-compose上ですでにNextCloudが稼働しており、またNextCloudを即座にKubernetesの上に移動させるのはノウハウ的にも難しいと判断しました。ingress-nginx、cert-manager、sealed-secertsは最初期から稼働させていたので、nginxをdeploymentとして動かし、すでに動かしているコンテナに対してリバースプロキシすることでダウンタイムなしでingress-nginx経由に切り替えることができました。
ただ、移行してすぐは気付きませんでしたが、ボディの制限を緩和することを完全に忘れており、ファイルがアップロードできない、という報告が寄せられました・・・。ごめんなさい。
その後Persistent Volumeなども整え終わった状態でNextCloudは完全にKubernetesへ移行しました、つい先日のことですが。
— Tsuzu (@Wp120_3238) 2019年12月10日
導入の最初の目的は早稲田祭において複数のゲーム制作企画がバックエンドを動かす基盤としてMIS.Wのサーバを利用することでした。そのサーバを動かす基盤としてKubernetesを利用し、無事2日間を乗り切ることができました。 試験的にGitHub Actionsのself-hosted runnerをクラスタ上で実行したりもしています。
なぜKubernetes?
Kubernetesが必要となるのはスケールしたい、多くのサーバを効率よく利用したい、高可用性を実現したい、などが主要な目的だと思いますが、MIS.Wにおいてはそれらは求められていません。また、実現することも難しいです。いくら高可用性を頑張っても大学側の都合で勝手に電源やネットワークが落ちますし、ふとしたことでルータの電源が抜けています・・・。
Kubernetesが必要なのか?と問われれば、必要ないとも言えるでしょう。それでもMIS.WにおいてKubernetesを利用する意味は
- (少ないものの)複数台のサーバを効率的に利用できる、増やしやすい
- Kubernetes Nativeなモダンなツールが活用できる
- 流動性が上がる
- 新しいアプリケーションの導入障壁が下がる
といったところにあると感じています。また、冒頭でも挙げたように折角なら学びのあるものにしたい、というのも大きなところです。
TODO
2019年はSysAd係にとってインフラを刷新する年だったと感じています。早いもので来年の今頃には引退です。2020年、引退するまでの抱負をここで述べておきます。基盤が整ったのであればその上でアプリケーションをば、ということで以下のようなことを検討中です。
Kubernetes NativeなPaaSの開発
これは現在私個人としてmodoki-paas/modoki-k8s で開発を進めています。以前開発していたバージョンはDocker+Traefikだったのですが拡張性等を考えて作り直しているのが今のmodoki-k8sです。認証・認可をいい感じにする仕組みが思い付かず悩み中です・・・。
折角あるサーバのリソースを活用したいということに加え、サークル内でWebに興味のある人が少ないということもあり、なるべく気軽に使いやすいPaaSを用意することでhands-onなども開催しやすくしたいと考えています。
MIS.W内ポータルサイト
MIS.Wのアカウントは全てSlackで統一されています。しかし、Slack自体のアカウント管理が難しく課題となっています。このあたりの問題を、サークル内の登録処理などと合わせてまとめて技術的に解決できそうだな、ということを感じており年明けから進めたいと思っています。
監視基盤の構築
これは基盤の話です。 現在サーバの監視はMackerelを利用して行っていますが、Kubernetesを導入し、またこれから色々なアプリケーションを導入していくに当たって現状の監視では不十分だと感じています。Prometheusを導入したいと考えてはいるのですが私に知見がなくまだ進められていません。
また、SysAd係は人手不足が続きそうなため、来年は講座も積極的に行ってSysAd係の人材を増やしていけるようにしたいと考えています。
終わりに
ここまで、お読みいただきありがとうございました。これからもSysAd係としてより良い基盤の構築・保守に努めていきたいと思います。
来年から早稲田大学に来られる方でインフラに興味がある方がいればぜひMIS.Wへ!歓迎します。
明日の記事は52代CG研究会ドット絵班班長ΙΔΈΑさんによるドット絵に関しての記事です。お楽しみに!