ぐるなび×GitLab×Rancher ~Deep Dive~

はじめまして。ぐるなびでサーバインフラエンジニアを担当している遠藤です。かれこれ8年以上在籍しています。 この記事では「GitLabとRancherで何ができるか」「ぐるなびではどう使っているか」 について書こうと思います。

ひっくるめて「ぐるなび×GitLab×Rancher」とタイトルを付けました。実は「Rancher Meetup Tokyo #13 (GitLab x Rancher特集)」というイベントで、全く同じタイトルで登壇させていただいたことがあります(そのときの資料はこちらで公開しています)が、今回の内容はこのブログのタイトルの通り、その内容を深堀りしたものになっています。

GitLabやRancherについてある程度ご存知の方は「GitLabとRancherの連携」からお読みいただいても問題ありません。内容は以下になります。

それではまずGitLabから紹介したいと思います。

GitLabについて

GitLabとは

かつては「GitHubクローン」と呼ばれていたようにソースコードのバージョン管理システムとして知られたOSSの「GitLab」ですが、現在ではその範疇に留まらず「Complete DevOps」を実現するための幅広い機能を提供するOSSに進化しています。

具体的には、CI/CDを実現する「GitLab Runner」、Docker HubのようにDocker ImageをPush/Pullすることができる「GitLab Container Registry」、Kubernetesと連携してビルドからテスト、レビュー、デプロイ、モニタリングにいたるまでの一連の作業を展開する「Auto DevOps」など、アプリケーション開発に便利となる多くの機能が提供されています。

ぐるなびとGitLab

ぐるなびでは2014年頃からGitLab Community Editionを利用し始めました。

GitLab導入までの経緯については「リポジトリホスティング導入の歩み」(「ぐるなび×GitLab×Rancher」より)に簡単にまとめています。

2014年当時はGitLabがここまでの進化を遂げると予想できなかったので、今となっては「先に知見を得ることができてよかった」と思っています。Rancher導入に伴いコンテナを利用し始めたからです。

前述した「GitLab Runner」「GitLab Container Registry」「Auto DevOps」などの機能は「コンテナのためにあり、コンテナと共にあるもの」です。GitLabはコンテナを利用するために必要な機能を備え、コンテナを活用することで更なる価値を得ることができます。 このようにコンテナとの親和性が非常に高いGitLabを活用するためにぐるなびが選択した製品が、KubernetesでありRancher 2.0 です。

次に、そのRancher について紹介します。

Rancherについて

ぐるなびとRancher

ぐるなびでは2017年11月に、弊社サービスでは初となったコンテナによる本番リリースを実現しました。そのときに採用したのが「Rancher」です。

当時の導入の経緯やリリースの流れなどについては、弊社湯原が書いた記事「RancherとDockerでぐるなびの本番サービスをリリースした話」をご覧ください。

Kubernetes対応したRancher 2.0の魅力

そのRancherも2018年5月に 1.6 から 2.0 となり、メジャーバージョンが上がり、かつてはCattleがメインだったコンテナオーケストレーションプラットフォームが「Kubernetes」に変更、一本化されました。

Kubernetesというのは、2018年3月、ホストされている「Cloud Native Computing Foundation」(CNCF)からGraduation認定された最初のプロジェクトであり、コンテナオーケストレーションプラットフォームのデファクトとして知られています。コンテナのデプロイやスケーリング、管理を自動化する仕組みが用意されており、さらにカスタムリソースやプラグインなどによる柔軟な拡張ができます。

まさに何でもできてしまいそうなKubernetesですが、その構築や運用は簡単ではありません。「本気で運用するなら専用チームを用意するべき」との意見も出るほどに、高度な専門知識を要します。

Rancherは、その大変なKubernetesの環境構築や運用作業を大幅にオフロードしてくれます。具体的にはdockerコマンドとUI操作で簡単にKubernetesクラスタを構築できます。最新のRancher 2.0 では、Kubernetesの最新バージョン「1.11.x」をセットアップすることができます(※バージョンは執筆時点2018年9月現在のものです)。

さらにRancherのカタログ機能を利用するとUI操作だけで簡単にアプリケーションをデプロイできるので、アプリケーション開発者はそのデプロイ環境の準備に時間を割くことなく直ちに開発に専念することができます。

Kubernetesを利用するエンジニアにとって、Rancherは「手軽に早く最新のバージョンで構築したい」という要望を満たしてくれる素晴らしいOSSだと思います。

それではGitLabとRancher 2.0 を使って、ぐるなびでは具体的に何をし始めたのか、これから何をやろうと考えているのかをご紹介したいと思います。

GitLabとRancherの連携

GitLab Runner/GitLab Container Registry × Rancher

CI/CDを実現する「GitLab Runner」、Docker HubのようにDocker ImageをPush/Pullすることができる「GitLab Container Registry」、それらとRancherを組み合わせることで、Docker ImageをベースとしたCI/CDをRancher上で実行することができます

以下はそれらを組み合わせた実行イメージです。

f:id:gnavi_developers:20180905095420p:plain (「ぐるなび×GitLab×Rancher」より抜粋)

上図の流れについて説明します。(※全てのフローがこの限りではありません)

1. コードを修正/Imageのbuild/push
2. .gitlab-ci.ymlファイルの内容に従いジョブ(GitLab Runner)を開始
3. GitLab RunnerはexecutorであるRancherにジョブを実行するよう依頼
4. RancherはDocker ImageをGitLab Container Registryから取得
5. 起動したPod(Rancher上のコンテナ)でジョブを実行
6. ジョブの実行が完了するとPodを終了し、GitLab側にステータスを返却

このように、CI/CDをコンテナで実行すると以下のようなメリットを得ることができます

  • ソフトウェアの追加やバージョンアップなど構成変更が容易
  • 常時CI/CDインスタンスを起動しておく必要がない
  • 前回のジョブ実行時のゴミファイルが残らない

上図ではGitLab Runnerが独立していますが、Rancher上に乗せてしまうことも可能です。その構成の方がよりスッキリしますね。

ぐるなびでは、上図の仕組みを開発環境で取り入れている最中です。アプリケーション開発者がGitLab上でコードを編集するだけで自動的にDocker Imageがビルドされ、Rancherにデプロイされる仕組みです。

さらに、Rancher上にデフォルトでデプロイされているIngressを利用して、ブランチ毎に外部からアクセス可能な多面環境を提供する機能も検討しています。インフラ管理者が介入することなく払い出し~デプロイまで行えるので、これらの仕組みが波に乗ってきたら、インフラ管理者、アプリケーション開発者双方の負担が軽減されて開発が捗ることを期待しています。

Auto DevOps × Rancher

次に、Kubernetesと連携してビルドからテスト、レビュー、デプロイ、モニタリングにいたるまでの一連の作業を展開する「Auto DevOps」とRancherの連携について紹介します。

先にお断りしておくと、ぐるなびではまだAuto DevOpsを導入しておらず、検証段階です。Auto DevOpsはGitLab v11.0 で正式にGA(Generally Available)となったので検証を開始しました。Proxy環境下の場合は実に様々な問題に遭遇します。ここではその問題内容と私が行った対処法について説明します。

工夫ポイント  
1. RoleBindingを設定する  
2. Kubernetesの代わりにRancherを用いる場合はRancherがラップしているAPIサーバの情報を取得する  
3. Rancher/GitLabがProxy環境下にある場合は2つの工夫をする  


1)まず、そもそもAuto DevOpsは2018年9月現在v11.2、RBACを有効にしたKubernetesクラスタとの連携は未サポートと公式に記載があります。

Currently, integrating GitLab with a Kubernetes cluster with RBAC enabled is not supported. You will need to enable and use the legacy ABAC mechanism (see the documentation here). RBAC will be supported in a future release. This affects GitLab.com and all self-hosted versions of GitLab.

(※GitLabのエンジニアブログ「What you need to know about Kubernetes RBAC」より抜粋)

将来的には対応される予定(現時点でのマイルストーンでは v11.3 を予定)なので、それまでは別途RoleBindingを設定してあげる必要があります。

2)次に、Kubernetesの代わりにRancherを用いる場合の連携にも工夫が必要です。 GitLabから接続可能なRancherのAPI URLおよびCA証明書ファイルを取得するには、Rancherサーバのコンテナに格納されているSecretから情報を得る必要があります。

このGitLabとRancherの連携方法は作業を簡単にするためのシェルスクリプトがRancherのエンジニアブログで公開されています。

3)これでRancherとGitLabの連携はうまくいきそうに思えますが、Rancher/GitLabがProxy環境下にある場合だと、2つの工夫が必要です。

3-a) Auto DevOpsセットアップ時に起動するPodが外部接続を必要とするため、そのPodにProxy設定をいれなければなりません。そのため、api-serverのadmission-controllにPodPresetを追加する必要がありました。Rancherでこのオプションを有効にするには、RancherのUIからCluster Optionを開き、「Edit as YAML」から編集します。kube-apiのextra_argsで以下のように記述します。

kube-api: 
    extra_args: 
      admission-control: "ServiceAccount,NamespaceLifecycle,LimitRanger,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds,PodPreset"

(※GitLab 11.1, Rancher 2.0.6(kubernetes 1.10.3)で検証した当時の情報です)

あとはHelmをインストールする前に「gitlab-managed-apps」ネームスペースに対してProxy設定情報を記述したマニフェストを適用すれば、Helm Tillerのインストールは無事に完了すると思います。

3-b) これでもうまくいかない場合、GitLabの設定(gitlab.rb)の「gitlab_rails['env'] http(s)_proxy」が原因の場合があります。Proxy環境下の場合、外部(Slackなど)との連携のためにGitLabにProxy設定していると思います。ですが、そのProxy設定が入っていると、Auto DevOpsでHelm Tillerインストール時に Rancher APIへの接続がProxy経由となってしまい、連携がうまくいかない問題に遭遇しました。GitLabの設定でRancher APIをno_proxyに設定すれば解決するかと思いましたが、それでもProxyサーバ経由になってしまいます。

この問題は、GitLabがKubernetesを扱う際に利用しているライブラリ「kubeclient」が no_proxy対応されていないことに起因していると思われます(参考「$no_proxy support? #277」)。こういったProxy接続問題はkubeclientに限らず、GitLabが利用するライブラリ周りで過去にもよく発生し、徐々に対応されていったので、この問題もGitLabのバージョンアップに伴い解決する日がくるかもしれません。

現状でこの問題を回避するには、
1. 一時的にGitLabのProxy設定をオフにする
2. Proxyサーバ側でRancher API URLに対するアクセス制御をいれる (Rancher APIに折り返してあげる)
などが考えられますが、これらが容易にできる環境は多くないと思います

こうしたProxy環境下での煩わしさが理由で、Auto DevOpsについては弊社ではまだ導入していません。GitLabのバージョンが上がり上記問題の回避方法が確立されるまで様子を見つつ、GitLab Meetupなどで機能詳細や運用上の知見を得てから、またいずれトライしたいと思います。

その他、注目していること

その他、こんなところにも注目しています。

GitLab Helm Chartは何となくわかる方は多いかと思います。

ぐるなびではGitLabをオンプレミス上のCentOSにyumインストールして構築していますが、最近GAとなったGitLabのHelm Chartに置き換える検証もそのうちやりたいと考えています。

Fluxについては最近知ったばかりで理解が浅いのですが、Kubernetesクラスタにデプロイする際にkubectlやDashboardなどから変更するといったアプローチではなく、Gitリポジトリ上に管理されたマニフェストを更新すると自動的にデプロイされる「GitOps」という考えを実現するもの、と捉えています。

確かにkubectlやDashboardから更新したマニフェストのGit管理って漏れそうですよね。GitOpsを導入するとそうした漏れを防ぐことができるのでは?という点で注目しています。オンプレミス上のGitLabとも連携はできるみたいです。

How do I use a private git host (or one that's not github.com, gitlab.com, or bitbucket.org)?


As part of using git+ssh securely from the Flux daemon, we make sure StrictHostKeyChecking is on in the SSH config. This mitigates against man-in-the-middle attacks.


We bake host keys for github.com, gitlab.com, and bitbucket.org into the image to cover some common cases. If you're using another service, or running your own git host, you need to supply your own host key(s).


How to do this is documented in setup.md.

(※weaveworks/flux「General questions」より抜粋)

いつかFlux×GitLab×Rancherを試してみたいです。

あとは、最近はCloud NativeやMicroservice、ChaosEngineering、NoOpsといった分野に関心が強く、勉強会にもよく参加しています。このブログを読んでいただき、ご質問や「これって実はこうだよ」などがありましたら、懇親会の場などでお話ができると嬉しいです。

まとめ

長くなってしまいましたが、Rancher 2.0 とGitLabを使ってぐるなびで何をしているか、どう使っていきたいかを紹介しました。

Rancher 2.0 に果敢に挑戦したおかげで、Kubernetesも少しずつ理解できました。またGitLabと連携することで「新しいCI/CDの形」や「開発環境管理の負担減」といった恩恵も受けることができそうです。

一方でこうした挑戦は行き過ぎてしまうと、同じ社内のインフラメンバーにさえも「得体の知れない何かをやっている人」に映ってしまうかもしれません。この先まだ見えていない苦労や落とし穴が待っているかもしれません。そのときに誰にも共有していなかったり、ドキュメントが全くなかったり、一部のメンバーしか理解できていない(あるいは当時構築したメンバーが既にいない)と、それらはメンテナンスされなくなり負の遺産となってしまう恐れがあります。

そういった事態を回避してぐるなびのインフラをより高くより強く維持していくために、レビュー、ドキュメント、社内勉強会によるメンバーへの技術共有でフォローするなど模索しながら「挑戦と運用のよりよいサイクル」を築いていけたらと思います。


お知らせ
ぐるなびでは一緒に働く仲間を募集しています。


遠藤
2010年ぐるなびに入社、サイト全体のサーバ構築および運用を担当してます。去年10kg痩せて今年10kg太りました。お酒と甘いものが大好きです。