DevOps

GitLabの導入(Backlog + GitHub からの移行)


いま、社内に GitLab を導入中です。数ヶ月かけて、これまで利用していた Backlog と GitHub を、GitLab に置きかえていく予定です。

Backlog は課金額がユーザ数に依存しません。そこで、いろいろな人が関わる課題管理には Backlog を利用しています。過去の履歴を見ると、2013年から 5年以上もお世話になっています。現在のアクティブユーザー数は120名ほど。

一方 Backlog の Gitリポジトリ機能はそれほど魅力的ではないため、コード管理には GitHub を利用しています。しかし GitHub はユーザ毎にお金がかかるため、コードを書く人に限定して使っています。現在のアクティブユーザー数は50名ほど。

開発の流れ

当社の開発の流れは、だいたい次のようになっています。

  1. 誰かが「○○をやりたい」と提案する。誰が何を提案してもいい。要点をまとめて Backlog に proposal(提案)として登録する。
  2. やるか、やらないか、優先度はどうするか、を毎朝のミーティングで決める。
  3. やることになった案件は planning(企画)フェーズに移行し、ディレクター、デザイナー、エンジニアなど案件毎に適切な人が仕様を決める。
  4. planningフェーズの仕様をレビューして問題がなければ、dev フェーズに移行させる。課題の優先度は毎朝の会議で決める。
  5. 優先度高の課題の中から好きなものを、手が空いたエンジニアが自分で取っていく。
  6. 開発が終わったら、提案者やディレクターがテストする。問題がなければリリース待ちとなる。
  7. リリースする。「街コンジャパン」の場合、少ない日で 1件、多い日で 10件くらいのリリースをする。ただし、売上が一番多いのが土日祝であるため、休みの前日のリリースはなるべく避ける。

提案から仕様を作るフェーズまでが Backlog で、開発が GitHub で、開発が終わるとまた Backlog に戻ってくる。これで仕事は充分に回っているのですが、開発の全ライフサイクルにまたがった、全プロダクト横断での進捗状況の見通しが悪い状態でした。

課題

  1. 全プロダクトを横断した状況の把握がしにくい
    Backlog でも FindIssueAllOver という全プロダクト(プロジェクト)横断の検索機能がありますが、おまけ程度の存在で、あまり実用的ではありません。エンジニアやディレクターが豊富にいるわけではないので、プロダクトにかかわらず、少しでも優先度の高い案件を先にやりたいという時の機動性はあまり提供してくれません。

  2. 開発の全ライフサイクルを横断して状況が把握しにくい
    Backlog と GitHub に情報がわかれていて、相互に簡単に行き来できないため、提案、企画、開発、テスト、リリースと、ライフサイクル全体を一望しにくいという欠点がありました。それぞれの開発担当者は、同時に数個程度の案件を頭にいれておけば良いので問題になりませんが、リーダーやマネージャが数十個、数百個単位で管理する場合、ライフサイクル横断性の悪さは非効率につながります。

  3. 工数のトラッキング手法が確立されていない
    これは Backlog や GitHub の問題ではありませんが、GitLab の工数トラッキング機能は魅力的に見えました。毎月月初に、経理に工数を報告しているのですが、過去3年近くにわたって、Excelファイルを各メンバーが作成して提出しています。正確性に欠ける上に、開発者にはあまり評判がよくありません。

  4. GitHub はユーザ数とコストが比例する
    たいした出費ではないものの、ユーザ数とコストが比例するので、本当に必要なユーザのみに限定しがちになります。

導入

GitLab の EC2 へのインストール

インストール先は AWS にしました。インフラチームが用意してくれました。当社のインフラチームは、AWS が大好きです。というか、基本的に特に理由がなければ AWS を使うようにしています。

GitHubリポジトリのインポート

影響の少なそうなリポジトリから、手作業で一つずつ、インポートしていきました。現時点で 82リポジトリなので、なんとかなります。Gitのリポジトリも Issue も、全自動でインポートしてくれます。

インポート時に GitLab側にユーザが存在すると、GitHub のユーザと GitLab のユーザを紐付けてくれます。そこで、50ユーザほどを手作業で作りました。これで移行した後も快適に使えるはずです。しかしここにワナが潜んでいました。

Google Account で OAuth

当社はメールやスケジュールは G Suite を利用しているので、Googleアカウントでログインできるものは、可能な限り Googleアカウントにしています。GitLab も、当然 Googleログインしたくなります。

ところが、OAuth でログインしようとすると、既に登録済みの既存のアカウントと衝突してエラーになります。これは GitLab のバグや機能不足ではなく、「メアドが同じだからといって同じユーザであるとみなしてはいけない」というセキュリティポリシーから来ているようです。

仕方が無いので、PostgreSQL に直接アクセスして、usersテーブルのメアドを一時的に .example.com 付きに変えて待避し、利用者に OAuth でログインしてもらい、identitiesテーブルの user_id を付け替えるという方法で、既存アカウントと Googleアカウントを紐付けました。

Kubernetes で CI

リポジトリが無事に移行できたので、次は CI です。当初は、GitHub で利用していた CircleCI をそのまま使うつもりでした。しかし、CircleCI は GitLab に対応していなかったのでした。

残念に思ったものの、調べてみると GitLab の CI は、かなり強力であることがわかりました。Circle CI よりも良い感じです。しかも Kubernetes(以下 k8s)に対応している。もう、心は決まりました。使ったことのない GKE で動かそう、と。これでソース、課題管理が AWS で CI が GCP になりました。(なお、当社のプロダクトの一つは、一年くらい前から GKE で動いています)

GitLab の CI は、Runner と呼ばれるサーバ上で実行されます。GitLabサーバが、Runnerと通信して、Runner が Dockerコンテナを立ち上げて CI します。この Runner は、ローカルの PC を登録してもいいし、EC2インスタンスを登録してもいいし、k8sクラスタを登録してもいい。k8sで動かすのが、一番難易度が高くて格好良さそうです。

しかし k8s上の Runner には、バグや制約がいくつかあったのです。そしてそれはドキュメントのどこにも書かれておらず、GitLab社の issue tracker を漁って初めてわかることでした。

その1. コンテナ間の通信がホスト名でできない

以下のように書いておけば、アプリケーションからは mysql という名前のホスト名で通信できる、というのが GitLab CI の仕様です。

services:
  - mysql:5.7

しかし k8s Runner では、ホスト名に 127.0.0.1 を指定しないと通信できませんでした。
https://gitlab.com/gitlab-org/gitlab-runner/issues/2229

その2. ファイルがキャッシュできない

以下のように書いておけば、ダウンロードしたライブラリがキャッシュされて、ビルドが短縮されるはずでした。

cache:
  paths:
    - vendor/bundle
    - node_modules

しかし k8s runner では動的にノード数が変わるため、キャッシュがサポートされていません。代わりに、S3 にファイルを待避するなどの仕掛けを自分で組み込む必要があります。

今回は、Dockerイメージに gem もインストールして container registry に置いておくことで、とりあえず回避しました。gem のバージョンアップ毎に少しずつ CI が遅くなりますが、数ヶ月は耐えることでしょう。。。

CI の時間

実は GitLab CI に移行してから、CI の時間が長くなりました。k8sのノードの vCPU数を増やしても、効果は無いようでした。CI の時間は開発効率に直接の影響を与えるので、ここは何とかしたいところですが、まだ試行錯誤中です。Circle CI って、優秀だったのですね。

GitHub + Circle CI: 8分
GitLab + k8s: 12分
GitLab + k8s with CircleCI MySQL image: 10分

創業7年を経過したリンクバルは、毎期増収増益中です。リンクバルでは、会社と共に成長していきたいエンジニアを大募集中です。あなたも一緒に、リンクバルの DevOps環境を進化させてみませんか?

リンクバル 採用情報
https://hrmos.co/pages/linkbal


AWS re:Invent 2018 参加レポート : 海外カンファレンスについて


リンクバル技術部の川畑です。AWS re:Invent 2018の全日程が終了しました。。
せっかく海外カンファレンスに参加したので、企業がエンジニアを海外カンファレンスに参加させる目的とその効果ついて考えてみましたので、こちらに纏めさせて頂きます。
ちなみに私は海外カンファレンスはAWS re:Inventしか参加したことないので、AWS re:Invent寄りの内容になることをご了承ください。

続きを読む


AWS re:Invent 2018 参加レポート : 4日目


リンクバル技術部の川畑です。AWS re:Invent 2018に参加するためラスベガスに来ています。本日もKeynoteでLambdaでのRubyサポート、そしてCOBOLも使えるようになるなど衝撃的な新サービスの発表がありました。
特にサーバーレスについては、Lambdaの前にALBを配置することが可能なので、WAFを設定できるようになり、DBはDynamoDBがトランザクションをサポート開始し、オンデマンドの従量課金体系に変わったので、これからはセキュリティやデータベースの制約でLambdaにできなかったシステム開発が可能となり、Lambdaを使ったサーバーレス化が加速するのではないかと思われます。
本日はそのLambdaのセキュリティ観点を学ぶために「Securing Serverless Applications and AWS Lambda」というワークショップを受けてきたので、その内容を簡単に共有させて頂きます。

続きを読む


AWS re:Invent 2018 参加レポート : 3日目


リンクバル技術部の川畑です。「AWS re:Invent 2018」に参加するためラスベガスに来ています。Amazon Web ServicesのCEO Andy Jassy氏による Keynote に参加してきました。毎年新たなサービスが発表されるのが恒例となっているようです。朝8時に開始にもかかわらず、朝7時に到着した時点ではすでに300メートルの10列ぐらいの行列ができていました。それでも何とか中にはスムーズに入ることができました。この辺りの誘導は手慣れたものだなと思いました。

会場の様子はこんな感じです。

本日のKeynoteでは以下のサービスが発表されました。

続きを読む


AWS re:Invent 2018 参加レポート : 2日目


リンクバル技術部の川畑です。「AWS re:Invent 2018」に参加するためラスベガスに来ています。
渡米するのは今回が初めてで、すべての食事はデカくて肉ばかり、という印象を持っていましたが、AWS re:Invent で提供される食事はベジタリアンの方を考慮してか、野菜が多く提供されている印象です。ライスは食べてませんが、日本にいるより野菜と果物を多く摂取している感じです。
2日目の今日は以下の Session に参加してきました。

  • SEC322-R – [REPEAT] Using AWS Lambda as a Security Team
  • DEV315-S – Building SRE from Scratch at Coinbase during Hypergrowth
  • CON301-R1 – [REPEAT 1] Mastering Kubernetes on AWS
  • DAT401 – Amazon DynamoDB Deep Dive: Advanced Design Patterns for DynamoDB

本日はこの中の、Uging AWS Lambda as a Secutiry Team のセッションの内容についてご紹介させて頂きます。

続きを読む


AWS re:Invent 2018 参加レポート : 1日目


リンクバル技術部の川畑です。「AWS re:Invent 2018」に参加するためラスベガスに来ています。本日は以下の Session に参加してきました。

  • Scaling Push Messaging for Millions of Netflix Devices
  • Unleash Team Productivity with Real-Time Operations
  • [REPEAT] Creating and Tuning Models with Amazon SageMaker
  • Keep Your IoT Devices Secure
  • Monday Night Live

Netflixのプッシュメッセージのアーキテクチャ、PagerDutyのDevSecOpsの事例などが聞けていろいろと参考になりました。本日は Key Note の1つである Monday Night Live について書かせて頂きます。

続きを読む


AWS re:Invent 2018 参加レポート : 事前準備


リンクバル技術部の川畑です。AWS re:Invent 2018に参加するためラスベガスに来ました。個人的には基調講演でEKSの東京リージョンやECSのリザーブドインスタンスやスポットインスタンスなどの発表などがあればいいなと楽しみにしています。本日はAWS re:Invent・ジャパン・ツアー・参加登録について書かせて頂きます。

AWS re:Inventとは

今回で7回目を迎えるAWSが主催する世界規模の大イベントで、全体で約45,000人、日本からは約1,200人が参加しており、以下のような特徴があります。
– AWSサービスの多様なセッション・最新テクノロジー・サービスの使い方・お客様事例などを学ぶ学習型イベント
– 基調講演による新サービスの発表
– Have Fun という 勉強したらリフレッシュするイベントも用意

続きを読む


AWS Lambda+Python3で複数のRDSを起動停止

aws python rds

リンクバル技術部の川畑です。9月も残すところあと3日。今年の台風は勢力が強く、今週末には台風24号が上陸するとの予報なので、皆様お気をつけてお過ごしください。
今回は、少しでもサーバー費用を削減すべく、特定のタグを設定して指定したタグ全てのRDSを起動停止するスクリプトを作成しましたので、ご紹介させていただきます。
(以前こちらの記事で似たようなスクリプトを紹介させて頂いたのですが、1つのRDSしか起動停止できないものでした)

スクリプト説明

  • boto3でRDSを操作するために高レベルAPIのResourcesを使いたかったけど、RDSは提供されていないようなので低レベルAPIのClientsを使用
  • AWSアカウントの指定リージョン全てのRDS情報を取得
  • RDS情報より指定したタグとRDSのステータスによりフィルタリング(すでに停止されているRDSを停止しようとすると、スクリプトでエラーとなるため)
  • フィルタリングされたRDSを起動停止

使用言語

  • python3.6
  • boto3

続きを読む