LoginSignup
13
8

More than 5 years have passed since last update.

この記事は 富士通クラウドテクノロジーズ Advent Calendar 2017の17日目の記事です。

16日目は@clutterさんの「OK, Google. サーバーをスペックアップして」でした。
最近はやりの音声アシスタントをサーバのスペックアップに使うという発想面白くていいですね。

今回私はgitlab-ciとansibleでgolangのデプロイ環境を整えるお話をしたいと思います。

gitlab-ciとは

  • gitlab バージョン8以降にデフォルトで付いているCIツールです。
  • 特別な設定が不要で、リポジトリに.gitlab-ci.ymlを追加するだけで利用できます。

デプロイ環境の概要

image.png

  • gitlabにpushするとgitlab runnerが動き出します。
  • gitlab runnerがデプロイのため以下の動作をするように.gitlab-ciを作成します。
    1. ソースをビルドしgitlab上に保存
    2. ビルドでできたバイナリをvmへ転送
    3. AnsibleでVMにinit.dでサービス登録

ディレクトリ構成

gitlab.com/UminoShohei05/go-gitlabci
├── .gitlab-ci.yml
├── ansible
│   ├── inventories
│   └── roles
└── server/
  • .gitlab-ciはビルドからAnsibleの実行まで行うジョブが定義されています。
  • ansibleにはgoのバイナリをserviceとして登録するplay-bookが入っています。
  • serverにはHelloWorld!を返すだけのgo+echoでできたAPIが入っています。
  • OSはCentos6.7で試しています。

やってみる

まずはビルドジョブの作成

build_jobではserver/にあるソースをビルドし、できたバイナリをgitlab上に保存します。
ビルドジョブは以下のようになります。

.gitlab-ci.yml
build_job:
  image: golang:1.8
  stage: build
  script:
    - mkdir -p $GOPATH/src/gitlab.com/UminoShohei05/go-gitlabci/server
    - mv $CI_PROJECT_DIR/server/* $GOPATH/src/gitlab.com/UminoShohei05/go-gitlabci/server
    - cd $GOPATH/src/gitlab.com/UminoShohei05/go-gitlabci/server/
    - go get -u github.com/golang/dep/cmd/dep
    - dep ensure
    - go build -o test-api
    - cp test-api $CI_PROJECT_DIR
  artifacts:
    paths:
    - test-api

ジョブの内容を解説していきます。

image

使いたいdockerイメージを指定します。

script

実行したい命令を記述していきます。
今回はビルドするため一度GOPATHに移動し、ビルドでできた成果物をartifactsで使うために$CI_PROJECT_DIRにコピーしています。
$CI_PROJECT_DIRは、CI実行時にリポジトリがクローンされるディレクトリを表しています。
これはPredefined variablesというCI上で使うために元から定義されている変数で、詳細はこちらで確認することができます。

artifacts

ジョブの中で作成した成果物などをpathで指定してgitlab上に保存できます。
pathは$CI_PROJECT_DIRからの相対パスとなっています。
今回artifactsではpathのみ指定していますが、成果物の名前を変更したり、保存期間を指定することもできます。(何も指定しないと無限に残り続けます)
保存されたartifactsは画像のようにgitlab上からzip形式でダウンロードすることもできます。

Repository
artifacts1

CI/CD -> Pipeline
artifacts2

デプロイジョブの作成

deploy_jobではbuild_jobでできたバイナリのサーバへの転送と、Ansibleを使いバイナリをinit.dでサーバにサービス登録します。
デプロイジョブは以下のようになります。

.gitlab-ci.yml
deploy_job:
  image: webdevops/ansible
  stage: deploy
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan $SERVER_IP  >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - scp test-api root@$SERVER_IP:/opt/api/bin/release
    - cd ansible
    - ansible-playbook -i inventories/production.yaml deploy-api.yaml

before script

scriptを実行する前の準備を記述していきます。
今回のデプロイジョブではscpやAnsibleでSSH keyを使うためssh-agentへの鍵の登録を行い、known_hostsへホストの登録をしています。

また、SSH keyはリポジトリに入れることが憚られるため、gitlabのSecret variablesという機能を使い参照できるようにしています。
画像のようにgitlab上でKeyとValueを入れ登録すると、CI上で$Keyで参照することができます。
APIのアクセスキーやシークレットキーの登録などもこちらで行うと安全に使えます。
secret_variables

script

scpコマンドを見てもらうとわかるように、前のジョブでartifactsに保存したtest-apiをそのまま使っています。このように前のジョブの成果物を引き継ぎたい時にartifactsは便利です。
デプロイのジョブは最後にserviceにtest-apiを登録するansibleを流して終了です。
Ansibleの内容については今回使ったリポジトリを貼っておくので、こちらで確認をしてみてください。

動作確認

ちゃんとデプロイされているか一応動作確認をしてみます。
動作確認

さいごに

今回はデプロイをするだけの簡単なgitlab-ciですが、実際に仕事で使うにはbuildの前にlintやtestを追加するとより良いと思います。
また、今回は最低限の機能しか使っていませんが、指定されたブランチのpush時のみジョブを指定するonlyやジョブの障害時や失敗した場合に実行されるジョブを定義するwhenなど様々な機能があります。
一方で、gitlab-ciはpassphraseのついたssh keyが使えなかったり、パラメータを取るようなジョブの場合は向いていなかったりもします。
個人的にはgitlab-ciの機能面だけでなく、設定いらずで管理するツールも増えない部分にメリットを感じているので、gitlab-ciをこれからもっと使っていきたいなと思います。

あしたは@cooの「ニフクラの物理ネットワークを支える人たち」です。宜しくお願いします!

13
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
8