このブログでは、CircleCI プラットフォームをすぐにお使いいただけるように、Orbs の使用方法について分かりやすく説明します。Orbs を使用すると、プロジェクト全体でコンフィグを共有、標準化、簡素化できます。また、コンフィグのベストプラクティスリファレンスとして Orbs を使用することもできます。概要については、\ Orbs とは を参照してください。利用可能な Orbs の完全なリストについては、CircleCI Orbs レジストリでご覧いただけます。

使用されているテクノロジー

このブログの内容を理解するには、次のテクノロジーとツールの基本を理解しておく必要があります。

  • Docker - コンテナを使用してアプリケーションを作成、デプロイ、および実行するために使用されます。Docker は、繰り返しが可能な開発、ビルド、テスト、および本番環境を提供します。
  • CircleCI - 継続的インテグレーションと継続的デプロイメント(CI/CD)に使用されます。
  • Kubernetes - ホストのクラスタ全体でコンテナ化されたアプリケーションのデプロイ、スケーリング、および管理を自動化するために使用されます。これにより、クラウドコンピューティングの費用が削減され、運用とアーキテクチャも簡素化されます。
  • Git - ソフトウェア開発時にソースコードの変更を追跡するための分散バージョン管理システム。
  • Google Kubernetes Engine (GKE) - Kubernetes クラスタを実行するための Google のクラウドソリューション。

GKE のセットアップ

Kubernetes は、特定のベンダーに依存しないクラスタおよびコンテナ管理ツールであり、2014 年に Google がオープンソースにしています。「ホストのクラスタ間でアプリケーションコンテナのデプロイ、スケーリング、および操作を自動化するためのプラットフォーム」を提供します。上記の特長により、クラウドコンピューティングの費用が削減され、運用とアーキテクチャも簡素化されます。GKE のクイックスタートガイドは、こちらのドキュメントサイトから参照できます。

Google Cloud Platform アカウントをお持ちでない場合は、こちらから取得できます。ログインしたら、circle-ci-demo という ID のプロジェクトを作成して下さい。

次に、Cloud SDK をダウンロードしてインストールする必要があります。Clould SDK は、Google Cloud Platform 製品およびサービスのコマンドラインインターフェイスであり、後で使用するツール gcloud も含まれます。

コマンドラインで、次のコマンドをターミナルに入力して、プロジェクトが実際に存在していることを確認します。

gcloud projects list

gcloud projects list

次のコマンドをターミナルに入力して、gcloud 環境を初期化します。

gcloud init

次のコマンドを入力して認証します。

gcloud auth login

kubectl は、Kubernetes クラスタに対してコマンドを実行するためのコマンドラインインターフェイスです。次のコマンドをターミナルに入力して、インストールしましょう。

gcloud components install kubectl

circle-ci-cluster という名前を付けて、GKE で コンテナクラスタ を作成します。GCP コンソールから同じ操作を行うことができますが、次のように入力してコマンドラインからも実行できます。

gcloud container clusters create circle-ci-cluster

次のコマンドを使用して、クラスタが正常に作成されたことを確認できます。

gcloud container clusters list

次のような出力になるはずです。

gcloud clusters list

別のコンピュータから GCP コンソールで作成された、あるいは、プロジェクトの別のメンバーによって作成されたクラスタに対して kubectl コマンドを実行するには、お使いの環境で kubeconfig エントリを生成する必要があります。次のコマンドを実行して kubeconfig エントリを生成します。

gcloud container clusters get-credentials circle-ci-cluster

クラスタが正しく設定されていることを確認するには、次のコマンドを実行します。

kubectl config current-context

次のような出力になるはずです。

Docker のセットアップ

Docker は、ソフトウェアコンテナ内におけるアプリケーションのデプロイを自動化するオープンソースツールです。コンテナを使用してアプリケーションをデプロイすることを コンテナ化 と呼びます。 柔軟性、軽量化、互換性、移植性、拡張性、およびスタック可能という特長があることから、コンテナの人気が高まっています。Docker の詳細については、こちらの Web ページで参照できます。

単純な Node.js アプリケーションのDocker 化

単純な nodejs アプリケーションを Docker 化するために、Dockerfile がこのプロジェクトでは必要です。 Dockerfile は、ユーザーがイメージをアセンブルするためにコマンドラインで呼び出すことができるすべてのコマンドが含まれるテキストファイルです。このプロジェクトで使用する Dockerfile を以下に示します。

# Set the base image to use for subsequent instructions
FROM node:alpine

# Add metadata to an image 
LABEL app="simple-node-application"

# Directive to set environmental variables key to value pair
ENV NPM_CONFIG_LOGLEVEL warn

# Set the working directory for any subsequent ADD, COPY, CMD, ENTRYPOINT, 
# or RUN instructions that follow it in the Dockerfile
WORKDIR /usr/src/app

# Copy files or folders from source to the dest path in the image's filesystem.
COPY package.json /usr/src/app/
COPY . /usr/src/app/

# Execute any commands on top of the current image as a new layer and commit the results.
RUN npm install --production

# Define the network ports that this container will listen on at runtime.
EXPOSE 3000

# Configure the container to be run as an executable.
ENTRYPOINT ["npm", "start"]

次のコマンドを使用して、イメージをビルドしてタグを付けることができます。

docker build -t circleci-gke:v1

ターミナルから次のコマンドを実行して、イメージが正常に作成されたことを確認します。

docker image

次のような出力になるはずです。

List Docker Images

ターミナルから次のコマンドを実行して、イメージをローカルでテストします。

docker run -p 3000:3000 circleci-gke:v1

https://127.0.0.1:3000 にアクセスして、ブラウザでアプリケーションにアクセスできるようになります。

次のステップでは、イメージの管理を簡単にするために、タグを付けてレジストリにプッシュします。開発者、テスト担当者、および CircleCI などの CI/CD システムは、アプリケーション開発のプロセスで作成されたイメージをレジストリを使用して保存する必要があります。次のコマンドを使用して、イメージにタグを付けることができます。

docker tag circleci-gke:v1 gcr.io/circle-ci-demo/circleci-gke:v1

次に、イメージを Google の Container Registry(GCR)にプッシュします:

docker push gcr.io/circle-ci-demo/circleci-gke:v1

これで、作業した結果である、コンテナ化した Docker イメージをレジストリにプッシュしましたので、circle-ci-cluster クラスタにアプリケーションをデプロイできるようになりました。

デプロイメントのための Kubernetes マニフェストの設定

Kubernetes は、設定に YAML を使用します。外部からデプロイメントにアクセスできるようにするには、LoadBalancer タイプの Kubernetes Service が必要です。

Kubernetes Service は、ポッドの論理セットと、ポッドにアクセスするためのポリシーを定義して抽象化したものです。Kubernetes Services の詳細については、こちらを参照してください

Kubernetes Deployments は、クラスタで実行されているステートレスサービスを管理します。この目的は、同一のポッドのセットの実行を継続し、制御された方法(デフォルトではローリングアップデートを実行)でアップグレードすることです。Kubernetes Deployments の詳細については、こちらを参照してください

Kubernetes Service と Deployment の .yaml ファイルを保存するフォルダを作成します。この例では、フォルダに admin という名前を付けています。以下の内容の 2 つのファイルをこのフォルダに作成します。

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: production-circle-demo
  labels:
    app: simple-backend
spec:
  selector:
    matchLabels:
      app: ci-deploy
      tier: backend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: ci-deploy
        tier: backend
    spec:
      containers:
        - image: gcr.io/circle-ci-demo/circleci-gke:v1
          name: rusty-pangolin
          ports:
            - containerPort: 3000
              name: ci-deploy
app-deployment.yaml


apiVersion: v1
kind: Service
metadata:
  name: circle-service
  labels:
    app: circle
spec:
  ports:
    - port: 3000
  selector:
    app: ci-deploy
    tier: backend
  type: LoadBalancer
app-service.yaml


Kubernetes マニフェストは admin フォルダにあるため、admin フォルダに対して次のコマンドを実行して、両方を検証できます。

kubectl apply --validate=true --dry-run=true -f admin/

次のような出力になるはずです。

これで、アプリケーションをデプロイできるようになりました。次のコマンドを使用して、デプロイします:

kubectl apply --validate=true   -f admin/

次のような出力になるはずです。

このアプリケーションにアクセスするには、次のコマンドを使用して、外部 IP を取得します。

kubectl get services

http://<EXTERNAL-IP>:3000 でこのアプリケーションにアクセスできます。私の場合のアドレスは、http://35.246.104.239:3000/ でした。

GitHub からアプリケーションを自動的にチェックアウトし、ビルドし、テストし、GKE で実行中のインスタンスを更新するにはどうしたらよいでしょうか?CircleCI を使用することで、これらの操作が可能になります。

CircleCI の設定

GKE への基本的なデプロイメントが完了しましたので、選択した VCS に変更がプッシュされたときにアプリケーションを更新する方法が必要になります。 CircleCI と GitHubを統合します。CircleCI のコンフィグ は、プロジェクトのルートフォルダの .circleci ディレクトリに .yml ファイルの形式で保存されます。つまり、コンフィグのパスは .circleci/config.yml です。

CircleCI Orbs の使用

アプリケーションを GKE にデプロイするために独自のスクリプトを書く必要はありません。CircleCI Orbs を使用することにより、構成済みのコマンド、ジョブ、および Executor をコンフィグファイルにインポートでき、多くの時間を節約できます。Orbs キーを使用して、このプロジェクトで次の Orbs を呼び出します。

  • node: circleci/node@1.0.1 - すべてのアプリケーションの依存関係をインストールするために使用されます。

  • gcr: circleci/gcp-gcr@0.0.2 - GCR を操作するための Orb。

  • gcp-gke: circleci/gcp-gke@0.1.0 - GKE と連携する Orb。

Orbs は次の要素から構成されます。

  • コマンド
  • ジョブ - 実行可能なコマンドまたはステップのセット
  • Executor - Docker、マシン、macOS やその環境の他のパラメーターなど、ステップが実行される環境を定義します。

このプロジェクトの場合、config.yml ファイルには次のコード行が含まれます。

version: 2.1
orbs:
  node: circleci/node@1.0.1
  gcp-gke: circleci/gcp-gke@0.1.0
  gcr: circleci/gcp-gcr@0.0.2
jobs:
  build:
    description: Install npm
    # machine option runs your jobs in a dedicated, ephemeral VM that has the following specifications:
    machine: true
    steps:
      - checkout
      # Install node
      - node/install
      # Install npm
      - node/install-npm
      # Download and cache dependencies
      - node/with-cache:
          steps:
            - run:
                name: Install application dependencies
                command: npm install
          # Save cache
          cache-key: package.json
          # Ignore non-checksum cache hits
          use-strict-cache: true
  Build-Push-Image-Docker:
    description: Build and push image to Google Container Registry
    machine: true
    steps:
      - checkout
      - gcr/gcr-auth
      - gcr/build-image:
          image: circle-gke
          tag: "v2" #Change version number e.g to 'v3' when updating application
      - gcr/push-image:
          image: circle-gke
          tag: "v2" #Change version number e.g to 'v3' when updating application
    
  deploy:
    description: Deploy application to Google Kubernetes Engine
    machine: true
    steps:
      # Install `gcloud` and `kubectl` if not already installed.
      - gcp-gke/install
      # Initialize the `gcloud` CLI.
      - gcp-gke/init
      # Update a deployment Docker image.
      - gcp-gke/rollout-image:
          deployment: circle-ci-cluster
          container: dominic-backend
          image: gcr.io/circle-ci-demo/circle-gke:v2 # change version when updating
workflows:
  build_update_deploy:
    jobs:
      - build
      - Build-Push-Image-Docker:
          requires:
            - build
      - deploy:
          requires:
            - Build-Push-Image-Docker

CircleCI コンフィグファイルの変更を GitHub にプッシュします。

CircleCI アカウントがない場合は、作成します。GitHub でサインアップできます。CircleCI ダッシュボードから Add Project をクリックし、表示されたリストからプロジェクトを追加します。

CircleCI で変更を行う前に、GCP と通信する方法が必要です。この場合、作成されたイメージを GCR にプッシュし、デプロイされたインスタンスを新しいイメージを使用して更新するために CircleCI が必要となります。GCP でサービスアカウントを使用します。ここに記載されている手順で、サービスアカウントを作成します。サービスアカウントに、そのプロジェクトの編集者の権限を付与します。

サービスアカウントのキー構造を以下に示します。

注: これはサンプルのサービスアカウントの例です(実際に使用されていません)。 悪意のある攻撃者が Cloud Platform のリソースにアクセスする恐れがあるため、サービスアカウントをコードリポジトリに絶対にコミットしないでください。

サービスアカウントの内容をコピーし、右上の歯車アイコンをクリックして、プロジェクトの 環境変数 として追加します。

ビルド設定の下の Environmental Variables をクリックします。

GCLOUD_SERVICE_KEY としてサービスキーを追加します。GOOGLE_COMPUTE_ZONE も追加する必要があります。次のコマンドを実行して、取得できます。

gcloud container clusters describe circle-ci-cluster

注: 自分で作成したクラスタを使用してください。.

私のクラスタでは、ゾーンが europe-west2-a になっており下部で確認できます。ユーザーが場所によって、ゾーンは異なる場合があります。

GOOGLE_PROJECT_ID, は、コンソールの project-info カードから直接取得できます。

これで CircleCI 環境が設定されました。新しいビルドをトリガーして、パイプラインが正しく動作することをテストできます。 ワークフローは、以下のようになります。

GKE 上のアプリケーションへのアクセス

次のコマンドを実行して、外部 IP を取得できます。

kubectl get services

たとえば、私は、http://35.246.118.41:3000/ にあるアプリケーションにアクセスする必要がありました。

結論

CircleCI Orbs を使用すると、CircleCI コンフィグの記述が簡素化されるため、生産性が向上します。Orbs は共有できるため、作成済みのコマンド、ジョブ、および Executor をコンフィグファイルで使用でき、時間を節約できます。

Orbs の使用は CircleCI と GKE のデプロイに限定されません。Orb レジストリ で利用可能な Orbs のリストを確認し、クラウドプラットフォーム、プログラミング言語などに適合する Orbs を見つけることができます。


Dominic Motuka 氏は Andela 社の DevOps エンジニアであり、コンフィグ管理、CI/CD、DevOps プロセスを活用した、AWS および GCP の本番環境へのデプロイのサポート、自動化、最適化について 4 年以上の実務経験があります。