Concourse を使用した Kubernetes Engine での Helm チャートの継続的デリバリー

このチュートリアルでは、GKE、Helm、Concourse を使用してソフトウェア リリース プロセスを作成する方法を示します。 Helm は Kubernetes マニフェストの管理を支援するツールです。 Concourse は Helm を利用してアプリケーションを継続的にデプロイします。

このチュートリアルの結果は次のようになります。

  • アプリケーション ソースコード用と Helm チャート用の 2 つのソースコード リポジトリが作成されます。
  • アプリケーションは Docker コンテナとしてパッケージ化されてから、クラスタにインストールされ、Helm チャートとして構成されます。

リリースを開始するには、Git タグを 2 つのリポジトリのどちらかに push します。

アーキテクチャ

次の図は、システムのアーキテクチャの概要を示しています。

アークテクチャの概要

Concourse は、ビルド、テスト、およびリリースのプロセスのステップをコード化するために使用できる、継続的デリバリー パイプラインをアセンブルします。Concourse では、パイプラインの段階をジョブと呼びます。各ジョブは、リソースを入力として受け取り、出力としてリソースを作成できます。

このチュートリアルでは、次の Concourse リソースタイプを使用します。

Helm を使用すると、Kubernetes マニフェストをテンプレート化し、ユニットとしてそれらを構成、インストール、アップグレードできます。Helm でアプリケーションをインストールするためのチャートとしてアプリケーションを定義する必要があります。各 Helm チャートには、マニフェストをパラメータ化するために使用できる値ファイルがあります。たとえば、アプリケーションのデプロイに使用する Docker イメージを定義する値があるとします。この値は、チャートをインストールまたはアップグレードするたびに変更される可能性があります。チャートの各インストールを「リリース」と呼びます。リリースを使用して、アプリケーションのインスタンスをアップグレードまたはロールバックします。

リポジトリを使用してチャートを共有できます。このチュートリアルでは、Cloud Storage を使用してプライベートのチャート リポジトリを作成します。

次の図は、チャート、リポジトリ、リリースの関係を示しています。

チャート、リポジトリ、リリースの相互関係

このチュートリアルでは、次の Concourse のスクリーンショットに示す継続的デリバリー パイプラインを構築します。入力と出力は暗い色のボックスで表示されています。パイプライン ジョブは緑色のボックスで表示されています。

継続的デリバリー パイプライン

スクリーンショットに示されているように、build-image ジョブではアプリケーション ソース コード(app-source)を入力として受け取ります。新しいタグがアプリケーション ソースコードに push されると、Concourse は build-image ジョブを実行します。ビルドプロセスはコードをチェックアウトし、Docker ビルドを実行して、イメージを Container Registry に push します。これは、app-image と呼ばれるパイプラインで出力としてラベル付けされます。アプリケーション Docker イメージは、パイプライン内の次のジョブ deploy-chart の入力です。また、deploy-chart ジョブは、チャート ソース コード(chart-source)を入力として受け取ります。

アプリケーション イメージとチャート ソースコードの両方が使用可能になると、deploy-chart ジョブが開始され、以下が実行されます。

  • リポジトリやタグなど、アプリケーション イメージに関する情報を取得します。
  • Cloud Source Repositories からチャートのソースコードをチェックアウトします。
  • Helm クライアントを使用してチャートをパッケージ化します。
  • Cloud Storage の Helm プラグインを使用して、パッケージ化したチャートを Cloud Storage のプライベート チャート リポジトリにアップロードします。
  • 前のスクリーンショットで dev-site と呼ばれる Concourse Helm リソースを使用して、チャートを GKE クラスタにインストールします。

目標

  • Cloud Shell を開き、GKE クラスタを作成し、ID とユーザー管理スキームを構成します。
  • サンプル アプリケーションをダウンロードし、Git リポジトリを作成して、それを Cloud Source Repositories にアップロードします。
  • Helm を使用して Concourse を GKE にデプロイします。
  • アプリケーションのインストールと更新をするように、Concourse パイプラインを構成します。
  • パイプラインをトリガーするためにアプリケーション コードの変更をデプロイします。
  • Helm チャートの変更をデプロイし、その変更がクラスタにロールアウトされるようにします。

料金

このチュートリアルでは、以下の GCP の課金対象となるコンポーネントを使用しています。

  • GKE
  • Cloud Storage

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。

始める前に

  1. GCP プロジェクトを選択または作成します。

    [リソースの管理] ページに移動

  2. プロジェクトに対して課金が有効になっていることを確認します。

    課金を有効にする方法について

  3. GKE、Cloud Source Repositories、Compute Engine API を有効にします。

    APIを有効にする

環境設定

チュートリアルを実行するために必要なインフラストラクチャと ID を構成します。

Cloud Shell インスタンスの起動

Google Cloud Platform Console から Cloud Shell を開きます。チュートリアルの残りの部分は、Cloud Shell から実行します。

Cloud Shell を開く

GKE クラスタを作成する

Concourse ポッドがソースコードのダウンロード、画像の push、Cloud Storage チャート リポジトリへの画像のアップロードを行えるようにするために、cloud-source-repos-rostorage-fullスコープを持つクラスタが必要です。

次のコマンドを実行して、GKE クラスタを作成し、Concourse と Helm チャートのサンプルをデプロイします。

gcloud container clusters create concourse --image-type ubuntu \
    --machine-type n1-standard-2 --zone us-central1-f \
    --scopes cloud-source-repos-ro,storage-full

サンプルコードをダウンロードする

このチュートリアルでは、既存のアプリケーション、Helm チャート、およびパイプラインを使用します。このチュートリアル用に作成した Cloud Storage バケットからサンプルコードをダウンロードし、Cloud Shell の中に抽出します。

wget https://gke-concourse.storage.googleapis.com/sample-app-v4.zip
unzip sample-app-v4.zip
cd concourse-continuous-delivery-master

Helm を使用した Concourse のデプロイ

Helm を使用してチャート リポジトリから Concourse をデプロイします。

Helm をインストールする

  1. Cloud Shell で Helm バイナリをダウンロードしてインストールします。

    wget https://storage.googleapis.com/kubernetes-helm/helm-v2.6.2-linux-amd64.tar.gz

  2. ファイルを抽出します。

    tar zxfv helm-v2.6.2-linux-amd64.tar.gz
    cp linux-amd64/helm .

  3. ユーザー アカウントにクラスタの cluster-admin 役割が付与されていることを確認します。

    kubectl create clusterrolebinding user-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)

  4. Helm のサーバー側である Tiller がチャートをデプロイするために使用できるサービス アカウントを作成します。

    kubectl create serviceaccount tiller --namespace kube-system

  5. Tiller サービス アカウントにクラスタの cluster-admin 役割を付与します。

    kubectl create clusterrolebinding tiller-admin-binding --clusterrole=cluster-admin --serviceaccount=kube-system:tiller

  6. Concourse のサービス アカウントに cluster-admin 役割を付与して、すべての名前空間にリソースをデプロイできるようにします。

    kubectl create clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:default concourse-admin

  7. Helm を初期化して、クラスタに Tiller をインストールします。

    ./helm init --service-account=tiller
    ./helm update

  8. Helm プラグインをインストールし、プライベート チャート リポジトリを Cloud Storage バケットで初期化します。最初のコマンドでは、現在のプロジェクト ID を環境変数に保存します。2 番目のコマンドでは、プロジェクト ID を使用してバケットの一意の名前を作成します。この名前はその後のコマンドで使用するために別の環境変数に格納されます。

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-helm-repo
    ./helm plugin install https://github.com/viglesiasce/helm-gcs.git --version v0.1.1
    gsutil mb -l us-central1 gs://$BUCKET
    ./helm gcs init gs://$BUCKET

  9. Helm が正しくインストールされていることを確認します。

    ./helm version

    次のような出力が表示されます。Helm が正しくインストールされている場合は、クライアントとサーバーの両方に v2.6.2 が表示されます。

    Client: &version.Version{SemVer:"v2.6.2",
    GitCommit:"012cb0ac1a1b2f888144ef5a67b8dab6c2d45be6",
    GitTreeState:"clean"}Server: &version.Version{SemVer:"v2.6.2",
    GitCommit:"012cb0ac1a1b2f888144ef5a67b8dab6c2d45be6",
    GitTreeState:"clean"}

    Helm が Tiller プロセスにアクセスできなかったというメッセージが表示されたら、しばらく待ってからもう一度お試しください。Tiller を初期化するのに最大で 2 分かかることがあります。

Concourse をデプロイする

  1. Cloud Shell で、Concourse インストール環境に渡す構成値を含むファイルを作成します。最初のコマンドでは openssl コマンドを使用して、Concourse 管理ユーザーのパスワードとして使用されるランダムな文字列を生成します。

    export PASSWORD=$(openssl rand -base64 15)
    cat > concourse.yaml <<EOF
    concourse:
      password: $PASSWORD
      baggageclaimDriver: overlay
    web:
      service:
        type: LoadBalancer
    EOF

  2. Helm を使用して Concourse チャートをデプロイします。

    ./helm install stable/concourse --name concourse -f concourse.yaml --version 0.10.0

  3. 3〜4 分待ってから、concourse-web ポッドが実行されて準備が整っていることを確認します。

    kubectl get pods -l app=concourse-web

    ポッドの準備が整うと、次のような出力が表示されます。

    NAME                             READY     STATUS    RESTARTS   AGE
    concourse-web-2711520304-483vw   1/1       Running   0          3m

  4. Concourse のコマンドライン ツール、fly をダウンロードします。

    export SERVICE_IP=$(kubectl get svc \
        --namespace default concourse-web \
        -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    wget -O fly "http://$SERVICE_IP:8080/api/v1/cli?arch=amd64&platform=linux"
    chmod +x fly

  5. Concourse インストール環境に対して fly CLI を認証します。

    ./fly -t local login -u concourse -p $PASSWORD -c http://$SERVICE_IP:8080

  6. Concourse ユーザー インターフェースの URL を取得します。

    export SERVICE_IP=$(kubectl get svc \
        --namespace default concourse-web \
        -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    printf "Concourse URL: [http://$SERVICE_IP:8080]\nUsername: concourse\nPassword: $PASSWORD\n"

    このコマンドにより、URL、ユーザー名、パスワードが出力されます。

  7. ブラウザで、前のコマンドで取得した URL にアクセスします。これによって、Concourse に移動します。

  8. Concourse で、右上隅の [login] ボタンをクリックし、[main] をクリックします。
  9. 前のコマンドのユーザー名とパスワードでログインします。

Identity and Access Management を構成する

Concourse で Container Registry にイメージを push できるようにするために、Cloud Identity Access Management(Cloud IAM)サービス アカウントを作成します。

  1. Cloud Shell でサービス アカウントを作成します。

    gcloud iam service-accounts create concourse --display-name concourse

  2. 後のコマンドで使用するために、サービス アカウントのメールアドレスと現在のプロジェクト ID を環境変数に格納します。

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:concourse" --format='value(email)')
    export PROJECT=$(gcloud info --format='value(config.project)')

  3. storage.admin 役割をサービス アカウントにバインドします。

    gcloud projects add-iam-policy-binding $PROJECT \
        --role roles/storage.admin --member serviceAccount:$SA_EMAIL

  4. サービス アカウントキーをダウンロードします。後のステップで、Concourse をインストールして、このキーを GKE にアップロードします。

    gcloud iam service-accounts keys create concourse-sa.json \
        --iam-account $SA_EMAIL

アプリケーションのデプロイ

このセクションでは、ソースコード リポジトリを作成し、パイプラインを構成して作成し、アプリケーションをデプロイし、変更してから、再度デプロイします。

ソースコード リポジトリの作成

このチュートリアルでは、アプリケーション ソースコードの処理用、および Helm チャートを定義するソースコード用の 2 つのリポジトリを使用します。これらのリポジトリのいずれかを変更すると、デプロイが更新されます。

  1. リポジトリを作成します。

    gcloud source repos create chart-source
    gcloud source repos create app-source

  2. これらのリポジトリの Git commit にユーザー名とメールアドレスを設定します。[EMAIL_ADDRESS] を Git メールアドレスに置き換え、[USERNAME] を Git ユーザー名に置き換えてください。

    git config --global user.email "[EMAIL_ADDRESS]"
    git config --global user.name "[USERNAME]"

  3. チャートとアプリケーションのソースコードをローカル リポジトリから Cloud Source Repositories に push します。

    export PROJECT=$(gcloud info --format='value(config.project)')
    for repo in app-source chart-source; do
    cd $repo
    git init && git add . && git commit -m 'Initial commit'
    git config credential.helper gcloud.sh
    git remote add google \
        https://source.developers.google.com/p/$PROJECT/r/$repo
        git push --all google
    cd ..
    done

パイプラインを構成して作成する

Concourse では、パイプラインにパラメータを挿入することができます。この機能を使用して、パイプラインをパラメータ化したり、ソースコード リポジトリにチェックインすべきでない秘密情報を挿入したりできます。

  1. Cloud Shell で、構成ファイルを作成します。

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-helm-repo
    export TOKEN_SECRET=$(kubectl get serviceaccount default -o jsonpath="{.secrets[0].name}")
    export CLUSTER_CA=$(kubectl get secret $TOKEN_SECRET -o jsonpath='{.data.ca\.crt}')
    export TOKEN=$(kubectl get secret $TOKEN_SECRET -o jsonpath='{.data.token}' | base64 --decode)

    cat > params.yaml <<EOF chart_name: nginx release_name: dev-site bucket: $BUCKET cluster_ca: $CLUSTER_CA token: $TOKEN project: $PROJECT service_account_json: '$(cat concourse-sa.json)' EOF

  2. Cloud Shell で fly CLI を使用し、パイプライン ファイルをアップロードします。

    ./fly -t local set-pipeline -p dev-site-deploy \
        -c pipeline.yaml -l params.yaml -n

  3. パイプラインの一時停止を解除して有効にします。

    ./fly -t local unpause-pipeline -p dev-site-deploy

  4. ブラウザで Concourse を更新します。

    パイプラインが表示されます。

    更新されたパイプライン

初めてのアプリケーションのデプロイ

パイプラインは、アプリケーションまたはチャート ソースコード リポジトリのいずれかに Git タグが push されたときにトリガーされるように構成されています。各リポジトリで最初のタグを push すると、初めてアプリケーションがデプロイされます。

  1. Cloud Shell で、Git タグを作成して push します。

    for repo in app-source chart-source; do
        cd $repo
        git tag v1.0.0
        git push google --tags
        cd ..
    done

  2. ブラウザで Concourse に移動します。1~2 分後に build-image ジョブの周りで黄色の囲みが点滅し、パイプラインが開始されたことを示します。

    パイプラインの実行

アプリケーションの変更のデプロイ

  1. パイプラインが完了したら、ローカルポートをコンテナに転送してバージョンを取得することにより、現在デプロイされているウェブサーバーのバージョンを確認します。

    export POD_NAME=$(kubectl get pods --namespace default \
        -l "app=nginx,release=dev-site" \
        -o jsonpath="{.items[0].metadata.name}")
    kubectl port-forward $POD_NAME 8080:80 &
    curl -is localhost:8080 | grep 'Server\|color'

    ウェブサーバーで nginx の安定バージョンが実行されていること、青色に設定されていることがわかります。

    Server: nginx/1.14.0
    <h1 style="color:blue;">Welcome to the sample app!</h1>

  2. ポート転送を停止します。

    killall kubectl

  3. アプリケーションのサブディレクトリに移動します。

    cd app-source

  4. Dockerfile で使用されるウェブサーバーのバージョンを stable から latest に変更します。

    sed -i s/stable/latest/ Dockerfile

  5. ソースを commit してタグ付けします。

    git add Dockerfile
    git commit -m 'Use latest NGINX'
    git tag v2.0.0

  6. コードを Cloud Source Repositories に push します。

    git push google --mirror

  7. Cloud Shell で fly CLI を使用して、ソースコードの新しいタグを今すぐ強制的にチェックするように Concourse に対して指示します。

    ../fly -t local check-resource -r dev-site-deploy/app-source

    パイプラインが再び起動します。

  8. パイプラインが完了したら、次のコマンドを再実行して nginx のバージョンを確認します。

    export POD_NAME=$(kubectl get pods --namespace default \
        -l "app=nginx,release=dev-site" \
        -o jsonpath="{.items[0].metadata.name}")
    kubectl port-forward $POD_NAME 8080:80 &
    curl -is localhost:8080 | grep 'Server\|color'

    nginx のバージョンが最新バージョンにアップグレードされています。

    Server: nginx/1.15.0
    <h1 style="color:blue;">Welcome to the sample app!</h1>

  9. ポート転送を停止します。

    killall kubectl

次に、チャート構成を変更して、更新をトリガーします。

チャートへの変更のデプロイ

チャート定義には、アプリケーションのデフォルト ページを定義する Kubernetes 構成マップが含まれています。この構成マップを更新して、アプリケーションのインデックス ページを変更します。

  1. Cloud Shell で、チャートのサブディレクトリに移動します。

    cd ../chart-source/

  2. 構成マップで色の文字列を置き換えることによって、見出しの色を青色から緑色に変更します。

    sed -i s/blue/green/ templates/config-map.yaml

  3. Git を使ってソースコードを commit し、タグ付けします。

    git add templates/config-map.yaml
    git commit -m 'Use green for page heading'

  4. パイプラインを開始するために、タグ付けを行い、コードを push します。

    git tag v2.0.0
    git push google --mirror

  5. fly コマンドを使用して、ソースコードの新しいタグを今すぐ強制的にチェックするように Concourse に対して指示します。

    ../fly -t local check-resource -r dev-site-deploy/chart-source

    Concourse では、パイプラインはチャートのデプロイジョブから開始されます。

  6. Cloud Shell で、アプリケーションの出力を確認します。

    export POD_NAME=$(kubectl get pods \
        -n default -l "app=nginx,release=dev-site" \
        -o jsonpath="{.items[0].metadata.name}")
    kubectl port-forward $POD_NAME 8080:80 &
    curl -is localhost:8080 | grep 'Server\|color'

    次の出力が表示されます。今回は、サーバーが青色ではなく緑色のマークアップで応答します。

    Server: nginx/1.15.0
    <h1 style="color:green;">Welcome to the sample app!</h1>

クリーンアップ

次の手順では、このチュートリアルで作成したすべてのリソースを削除して、不要な料金が課されないようにします。

  1. Concourse インストール環境を削除します。

    ../helm delete --purge concourse

  2. サービス アカウントを削除します。

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:concourse" \
        --format='value(email)')
    gcloud iam service-accounts delete $SA_EMAIL

  3. GKE クラスタを削除します。

    gcloud container clusters delete concourse --zone us-central1-f

  4. ソースコード リポジトリを削除します。

    gcloud source repos delete app-source --quiet
    gcloud source repos delete chart-source --quiet

  5. バケットを削除します。

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-helm-repo
    gsutil -m rm -r gs://$BUCKET

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...