連載
» 2019年09月03日 05時00分 公開

コンテナベースのCI/CD本番事例大解剖(3):Kubernetesを前提としたCI/CDパイプラインの具体例と、本番運用に必要なもの (1/2)

Kubernetes、コンテナ技術を活用したCI/CD基盤におけるサービス開発について、リクルートテクノロジーズの事例を基に解説する連載。今回は、インフラエンジニア視点からKubernetesを前提としたCI/CDの具体例について解説します。

[宮地克弥,リクルートテクノロジーズ]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

 本連載「コンテナベースのCI/CD本番事例大解剖」では、リクルートテクノロジーズが取り組んだ事例を基に、Kubernetes、コンテナ技術を活用したCI/CD(継続的インテグレーション/継続的デリバリー)基盤におけるサービス開発について解説します。第1〜3回では、「Kubernetes、Dockerをコア技術に据えてサービスを構築した際に、開発、保守運用においてどのような影響があったのか」について、インフラアーキテクト、アプリエンジニア、インフラエンジニアそれぞれの視点から紹介します。

 連載第2回の前回はアプリ開発者の視点から紹介しました。今回は、インフラエンジニア視点から、Kubernetesを前提としたCI/CDの具体例について解説します。

Kubernetesを前提とした開発について

 Kubernetesを利用する上で最も重要な準備の一つとして、CI/CD環境があります。Kubernetesにアプリケーションをデプロイするには、最低でも下記の手順を踏む必要があります。

  1. Dockerイメージのビルド
  2. 「Deployment」「ConfigMap」などのmanifestの組み立て(コンテナのimage tagや、「dev」「stg」「prod」など各環境に向けた変更)
  3. 各環境に合わせたconfigのデプロイ

 これらを毎回手動で行うのは、現実的ではありません。そこで、これらの作業を自動化するために、CD環境が必要になります。

 今回のプロジェクトではCI/CDツールとして「Concourse CI」を選択しました。選定した理由、他ツールとの比較に関しては連載第1回で解説しています。

Concourse CI

 Concourse CIはPivotal社によるオープンソースソフトウェア(OSS)のCI/CDツールです。yamlを使ってパイプラインを記述し、コンテナベースで各タスクが実行されます。

 基本的な機能に関しては、こちらのチュートリアルにまとまっているため、本連載では割愛します。ここでは、Kubernetes(コンテナ環境)で利用する上で最低限必要なCI/CDのフローと、連載第2回の「パイプラインの高速化」の項で解説したパイプラインを組むための具体的な方法を紹介します。

パイプラインの具体例

 上記のパイプライン模式図を基にConcourse CI上へデプロイすると、下記サンプルのように表示されます。

パイプラインのサンプル

groups:
  - name: test
    jobs:
      - build-image
      - unit-test
      - lint
      - success-notify
 
resource_types:
  - name: kubernetes
    type: docker-image
    source:
      repository: zlabjp/kubernetes-resource
      tag: "1.12"
  - name: slack-notification
    type: docker-image
    source:
      repository: cfcommunity/slack-notification-resource
      tag: latest
  - name: slack-alert
    type: docker-image
    source:
      repository: arbourd/concourse-slack-alert-resource
  - name: pull-request
    type: docker-image
    source:
      repository: teliaoss/github-pr-resource
      tag: latest
 
resources:
  - name: repository
    type: pull-request
    source:
      repository: ((repository))
      access_token: ((access-token))
  - name: app-docker-image-base
    type: docker-image
    source:
      repository: asia.gcr.io/example-project/app/base
      username: _json_key
      password: ((gcp-service-account))
  - name: app-docker-image
    type: docker-image
    source:
      repository: asia.gcr.io/example-project/app
      username: _json_key
      password: ((gcp-service-account))
  - name: notify
    type: slack-alert
    source:
      url: ((slack-webhook))
  - name: deploy-notify
    type: slack-notification
    source:
      url: ((slack-webhook))
jobs:
  - name: build-image
    plan:
      - get: repository
        trigger: true
        version: every
      - put: app-docker-image-base
        params:
          cache_from:
            - api-docker-image-base
          cache: true
          additional_tags: repository/.git/ORIG_HEAD
          build: repository
          dockerfile: repository/app/Dockerfile
          target_name: base
        on_failure:
        ## 失敗時の通知
      - put: app-docker-image
        get_params:
          skip_download: true
        params:
          cache_from:
            - app-docker-image-base
          cache: true
          additional_tags: repository/.git/ORIG_HEAD
          build: repository
          dockerfile: repository/app/Dockerfile
          target_name: app
        on_failure:
        ## 失敗時の通知
  - name: unit-test
    plan:
      - aggregate:
          - get: repository
            trigger: true
            passed:
              - build-image
          - get: app-docker-image
      - task: unit-test
        image: app-docker-image
        # unit-testの実行
        on_failure:
          ## 失敗時の通知
        on_success:
          ## 成功時の通知
  - name: lint
    plan:
      - aggregate:
          - get: repository
            trigger: true
            passed:
              - build-image
          - get: app-docker-image
      - task: lint
        image: app-docker-image
        ## lintの実行
        on_failure:
          ## 失敗時の通知
        on_success:
          ## 成功時の通知
  - name: success-notify
    plan:
      - get: repository
        trigger: true
        passed:
          - lint
          - unit-test
      - task: notify-msg
          ## 成功時の通知

パイプラインの構成

 Concourse CIのパイプラインは大きく以下の3つの定義に分かれています。

  • resource_types:
    パイプラインで利用したいresourceを定義する
  • resources:
    ジョブで利用するために、resourceの詳細を定義する
  • jobs:
    実行されるジョブを定義する

 このパイプライン全体の流れの概略は、下記のようになります。

  1. 各種resource_typesの定義
  2. resourcesの設定
  3. 各ジョブの実行
    1. アプリケーションのイメージのビルド
    2. unit-testの実行、lintの実行
    3. 成功の通知
       1|2 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。