
楽天クラウドではじめるCICD(GitLab)
柳 松 クラウドプラットフォーム技術部 クラウド技術グループ
ビジネスの変化に、迅速かつ柔軟に対応できるITインフラの構築が求められる今、クラウド環境でスケーラブルなアプリケーションを構築・実行する能力をもたらす“クラウドネイティブ”に対する注目は、ますます高まっています。そして、そのクラウドネイティブを実現するための手法には、マイクロサービス・DevOps・コンテナ・分散アプリケーションの応用があり、これらの技術のおかげで、ワークロードの俊敏性・伸縮性・パフォーマンスを向上することができます。
「楽天クラウドRed Hat®OpenStack Platform」は、企業のデジタルトランスフォーメーションを支えるクラウドインフラストラクチャとして、クラウドネイティブにまつわる技術サポートに尽力しています。そこで、この記事では、CI/CDの概要とともに、Docker ComposeでGitLabを構築して行うCIについて紹介します。
1. CI/CDとは?
CI/CDとは、「CI(Continuous Integration:継続的インテグレーション)」と、「CD(Continuous Delivery:継続的デリバリー、あるいは、Continuous Deployment:継続的デプロイメント)」を意味しており、ソフトウェアの構築における統合、および、テストフェーズからのデリバリーやデプロイメントまで、ソフトウェアのライフサイクル全体を通じて、継続的な自動化と監視を導入するものです。
<CI/CDのメリット>
・停止してリリースを待つ必要がないため、リリース頻度を高めることができます。コミットごとに自動的にテストやビルドが実施されます。
・顧客は、継続的な改善を日々確認することができます。
・小さなバッチでリリースされると、リスクが軽減されるため、問題が見つかった場合は簡単に修正できます。
一方、開発担当者と運用担当者が緊密に協力・連携し、開発を迅速に進めることを目指すDevOps(Development and Operations)は、ソフトウェアの開発・テスト・運用・保守の統合に重点を置いた“考え方と文化”です。DevOpsを導入することで、様々な部門間の通信コストを削減して、迅速に高品質なソフトウェアのリリースを実現することができます。
そのDevOpsを支えるのが、CI/CDです。CI/CDツールを使用してプロセス全体を自動化することで、DevOpsの効率性が高められるのです。
DevOps・CI・CDの関係は、次の図を参照ください。
2. Dockerとは?
Dockerとは、Docker Inc.によって開発された、コンテナ型の仮想環境を作成・配布・実行するためのソフトウェアです。最小限のリソースでアプリケーションを利用できるほか、OSを起動せずにアプリケーションを動かすことができることなどから、昨今、技術者の間で大きな注目を集めています。
コンテナとは、DockerのドライバによってOSの内部で分離されたアプリケーションの実行環境のことです。アプリケーションの実行に必要なOSのライブラリやランタイムがアプリケーションと共にパッケージ化されているため、各コンテナは名前空間やシステムリソースに関する固有の設定を持つことができます。
次に、仮想マシンとDockerを比較してみましょう。
(コンテナと仮想マシンの違い)
参照元:https://www.docker.com/resources/what-container
Dockerデーモンはメインオペレーティングシステムと直接通信し、各Dockerコンテナにリソースを割り当てることができます。また、コンテナをメインオペレーティングシステムから分離して、各コンテナを互いに分離することも可能です。
仮想マシンの起動には数分かかりますが、Dockerコンテナはわずか数ミリ秒で起動することができます。セカンダリオペレーティングシステムのように肥大化することがないため、多くのディスク領域やそのほかのシステムリソースを節約できるのもDockerの特長です。
このようにDockerには数多くのメリットがありますが、すべてのシーンにおいて仮想マシンテクノロジーよりもDockerのほうが優れているというわけではありません。
オペレーティング環境全体を完全に分離する際には、仮想マシンのほうが適しています。例えば、クラウドサービスプロバイダーは仮想マシンテクノロジーを駆使して、ユーザーの利用環境を分離しています。
他方、Dockerは、フロントエンド、バックエンド、データベースなどの様々なアプリケーションを分離するために使用されています。
したがって、アプリケーションの利用シーンやニーズに応じて、Dockerテクノロジーとサーバー仮想化テクノロジーのいずれを使用するか、最適なほうを選択する必要があります。
今後、楽天クラウドRed Hat OpenStack Platformではコンテナのオーケストレーションサービスを提供する予定です。ご期待ください。
3. Docker環境を準備する
「楽天クラウドRed Hat OpenStack Platform」で、Docker環境を準備する手順を紹介します。
「楽天クラウドRed Hat OpenStack Platform」でgitlab-vmという名前のインスタンスを作成して、FloatingIPを振り分けます。
ここでは、実験に必要なDockerはまだ入っていませんので、まずはDockerをインストールしていきましょう。
yum-config-managerで、yumリポジトリを追加して有効にします。Root権限が必要なので、sudoで実行します。
[r-user@gitlab-vm ~]$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror, langpacks
adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
grabbing file https://download.docker.com/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
リポジトリから、Dockerバージョンを確認することができます。
[r-user@gitlab-vm ~]$ yum list docker-ce --showduplicates | sort -r
* updates: ty1.mirror.newmediaexpress.com
Loading mirror speeds from cached hostfile
Loaded plugins: fastestmirror, langpacks
* extras: ty1.mirror.newmediaexpress.com
docker-ce.x86_64 3:19.03.9-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.8-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.7-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.6-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.5-3.el7 docker-ce-stable
===中略===
docker-ce.x86_64 17.03.2.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.03.1.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.03.0.ce-1.el7.centos docker-ce-stable
* base: ty1.mirror.newmediaexpress.com
Available Packages
最新版をインストールする場合は、下のコマンドを実行します。
sudo yum -y install docker-ce
バージョンを指定することもできます。
sudo yum -y install docker-ce-<VERSION>
Dockerサービスを起動します。
sudo systemctl start docker
インストールが成功したか確認します。
[r-user@gitlab-vm ~]$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
Dockerコマンドを実行するときに、sudoを使わないとpermission deniedエラーが起きます。
sudoなしでDockerコマンドを実行する場合には、使っているユーザーをdockerグループに追加します。
sudo gpasswd -a r-user docker
sudo service docker restart
exit
再度ログインすることで、エラーが起きずにDockerコマンドを実行することができました。
次はDockerで、アプリのコンテナを起動しましょう。起動する方法は2つあります。Dockerコマンドを使用する方法と、Composeツールを使用する方法です。複数のコンテナを定義・実行する場合には、Composeツールを使用することを推奨します。
アプリケーションを構成する各サービスを docker-compose.yml ファイルで定義します。こうすることで、独立した環境を一斉に実行できるようにします。docker-compose up を実行したら、Compose はアプリケーション全体を起動・実行します。
LinuxのCompose最新版は、 GitHub 上にある Compose リポジトリのリリースページ を確認してください。次のコマンドを実行して、 Docker Compose 最新版(現時点)をダウンロードします。
sudo curl -L https://github.com/docker/compose/releases/download/1.26.0-rc5/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
バイナリに対して実行権限を付与します。
sudo chmod +x /usr/local/bin/docker-compose
インストールを確認します。
[r-user@gitlab-vm ~]$ docker-compose --version
docker-compose version 1.26.0-rc5, build 3d94f442
4. GitLabを導入する
まず、Git、GitLab、GitHubについて簡単に紹介します。
Gitとは、プログラムソースの変更履歴を記録する、バージョン管理システムです。コマンドでの操作が可能で、GUIはありません。
GitLabは、Gitに基づくオンラインコード管理ソフトウェアで、Web GUIを提供し、企業や学校などチーム間でプログラムソースを共同開発する際に使用されます。バージョン8.0から、GitLab CIがGitLabに統合され、CI/CDの機能が実装されました。
一方、GitHubは、Gitに基づくオンラインコードのホスティングシステムです。Web GUIを提供し、オープンな無料アカウントと、プライベート管理の有料アカウントがあります。ほとんどのオープンソースプロジェクトは、コードホスティングレポジトリーとして、GitHubを利用しています。
それでは、GitLabの導入方法を紹介します。
Composeを使うために、先にYAMLの構成ファイルdocker-compose-gitlab.ymlを作成します。
[r-user@gitlab-vm ~]$ vi docker-compose-gitlab.yml
version: '3'
services:
gitlab:
container_name: mygitlab
restart: always
image: gitlab/gitlab-ce:latest
ports:
- "80:80"
- "443:443"
- "10022:22"
volumes:
- './config:/etc/gitlab'
- './logs:/var/log/gitlab'
- './data:/var/opt/gitlab'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://xx.xx.xx.xx'
gitlab_rails['time_zone'] = 'Asia/Tokyo'
'http://xx.xx.xx.xx' の部分は、お使いのFloating IPを指定してください。
上記構成ファイルにより、“mygitlab”というコンテナが定義されます。Linuxインスタンスは、すでにSSH用の22ポートを使用しているのでGitLabのSSHポートを10022に指定します。
ほかのアプリで80ポートを使用している場合は、同じように別のポートに指定して変換してください。
この構成はあくまで検証環境なので、HTTPS設定していません。社外に公開する場合には、HTTPSを利用されることを強く推奨します。
下のComposeコマンドでコンテナを作成して起動します。
docker-compose -f "docker-compose-gitlab.yml" up -d
しばらく待ちますと、docker psでmygitlabというコンテナの立上げを確認できます。
この検証ではIPを使いますが、mygitlabinstance.comのようなドメインネームでGitLabにアクセスしたい場合は、ドメインがIPにバインドされていることを確認してください。例えば、host mygitlabinstance.comで確認できます。
ウェブブラウザで、Linuxインスタンスの外部IPを使って、最初のアクセスをしてみましょう。パスワードのリセット画面へリダイレクトされますので、管理者アカウントの初期パスワードを入力すると、ログイン画面にリダイレクトされます。(画面1)デフォルトのrootアカウントを使用してログインしてください。
(画面1)
Rootユーザーは管理者権限を持つため、プロジェクトを作成する前に、通常のユーザーを登録します。(画面2)初期画面でRegisterタブをクリックして登録することができます。
(画面2)
これで、GitLabのインストールは完了して、コード管理をすることができました。
次に、コードの自動ビルドとデプロイするのに不可欠なGitLab Runnerをインストールします。
下は、Shared型のRunnerをインストールしたもので、すべてのユーザーが使用可能です。
まずは、ブラウザからrootでログインします。画面トップのメニューにあるスパナのような“Admin Area” のアイコンをクリックして、左側のOverview、Runnersをクリックします。
(画面3)
GitLabをインストールされたインスタンスのリソースを確保するために、新しいインスタンスを立ち上げてGitLab runnerをインストールします。ここでは、ホストネームはGitLab-Runnerとなっています。
コンテナを起動します。同時に構成ボリュームをマウントします。
docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest
Runnerには2つの種類があります:
Shared Runners:プロジェクトをまたいで、共有して利用できるタイプ
Specific Runners:特定のプロジェクトに紐付けて、専用利用するタイプ
それぞれ下記のようなメリットが考えられます。
Shared Runners
・プロジェクトごとに毎回Runnerの環境を構築しなくても良い
・Runnerがアイドリング状態で遊び続け、リソースが無駄になることを抑止できる
Specific Runners
・自分のプロジェクトのビルドを実行する際に、ほかのプロジェクトのビルドが完了するまで待たされることが無い
・Runnerにプロジェクト固有の設定を追加できる
・別ユーザーと隔離された環境で自分のプロジェクトのジョブを実行できるので、セキュリティレベルを担保しやすい
https://dev.classmethod.jp/ci/gitlab-runner-ci-cd-1/ より引用
ここでは、Shared Runnerを登録します。
指定のないところ以外はEnterキーだけで進められます。
[r-user@gitlab-runner ~]$ docker exec -it gitlab-runner bash
root@bcd2a51670e3:/# gitlab-runner register
Runtime platform arch=amd64 os=linux pid=59 revision=21cb397c version=13.0.1
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
<URL> 画面3①のSet up a shared Runner manually の2.に記載されているURLを指定する
Please enter the gitlab-ci token for this runner:
<トークン> 画面3② のSet up a shared Runner manually の3.に記載されているtokenを指定する
Please enter the gitlab-ci description for this runner:
[bcd2a51670e3]:
Please enter the gitlab-ci tags for this runner (comma separated):
Registering runner... succeeded runner=6x-xG1MC
Please enter the executor: shell, ssh, virtualbox, kubernetes, docker+machine, docker-ssh+machine, custom, docker, docker-ssh, parallels:
dockerと入力する
Please enter the default Docker image (e.g. ruby:2.6):
docker:stableと入力する
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
(画面4)
無事インストールされました。
5. CI検証
最後に、これまでに構築した環境を使って、CI検証をしてみましょう。
CI/CDのためには、様々なツールを選択できますが、この記事ではgitlab-ce + gitlab-runner + dockerの組み合わせで検証していきます。
左から右に見て、最初に開発担当者が要件を満たしたら、コードをGitLabにsubmitします。GitLabはビルドを1回トリガーし、ユニットテストと統合テストの実行を開始します。テスト結果がパスするのを待った後、プロジェクトの責任者はCodeReview(省略可能)、グレースケールリリースを実施し、正式にオンラインで展開して、シェルの展開とDockerの展開をサポートします。
出典:GitLab CI / CDドキュメントからの画像
GitLabのWebIDEを使って、最初の簡単なCIプロジェクトを作ります。
先ほど作成した通常ユーザーを使ってログインしたら、新規プロジェクトを作成します。
(画面5)
GitLab CI/CD pipelinesは、プロジェクトごとに.gitlab-ci.ymlというYAMLファイルを使って設定します。
New Fileをクリックして、新しいファイル.gitlab-ci.ymlを作ります。
(画面6)
画面左下のCommit changesをクリックします。自動的にRunnerを使ってビルドします。画面左側のCI/CD、Jobsを選択すると、ビルド結果が表示されます。
(画面7)
詳細を調べると、gitlab-ci.ymlに定義したexit 1に問題が起きていることがわかります。
(画面8)
今度はexit 0に変更してみると、ビルドが成功しました。
(画面9)
ここまでで、パイプラインのビルドが完成しましたので、次はテスト、デプロイパイプラインに入ります。
次の画像は典型的なパイプラインです。ビルド、テスト、ステージング、本番の合計4つのステージがあります。各ステージには少なくとも1つのジョブがあり、テストには2つのジョブがあります。
GitLabは、タスクを左から右の順にRunnerに渡します。タスクが途中で処理されない場合、パイプライン全体が終了します。
これは、継続的インテグレーション(CI)および継続的リリース(CD)のプロセスです。
興味がある方は、是非試してみてください。
次回もクラウドネイティブの連載となり、楽天クラウドでのKubernetes構築を紹介します。
楽天クラウド:https://cloud.rakuten.co.jp/
柳 松
外資系ITメーカー入社、ストレージソリューションSEから始め、アーキテクト、プレセールス、ビジネスデベロップメントを経験。インフラ系から現職のクラウド系新規サービス開発にチャレンジ中。最近の趣味は読書。特に歴史と社会に興味を持っている。理科と違って、正解のない世界を面白く感じている。