LoginSignup
1
1

OCI DevOps & OKE におけるカナリアリリース

Last updated at Posted at 2023-12-13

CANARY Environment

環境概要図

環境概要図

OKE

以下チュートリアルを参照して、Kubernetesクラスタを構築します。

本でも環境では、3 Node としています。

Oracle Container Engine for Kubernetes(OKE)をプロビジョニングしよう

  1. OKEクラスターのプロビジョニング
  2. CLI実行環境(Cloud Shell)の準備

OCIR

以下チュートリアルを参照して、OCIRにリポジトリを作成します。

Oracle Cloud Infrastructure(OCI) DevOpsことはじめ-OKE編-

  1. アーティファクト
  • 3-1. OCIRのセットアップ

<パラメータ>
コンパートメント:対象とするコンパートメント
リポジトリ名:canary
アクセス:パブリック

Ingress Controller Setup

サンプルコードを取得します。

git clone https://github.com/oracle-japan/devops-deploy-strategy.git

ディレクトリの内容を確認します。

ls devops-deploy-strategy
deploy-strategy-bg  deploy-strategy-canary  README.md

deploy-strategy-canary ディレクトリに移動して、ingress controller をセットアップします。

cd deploy-strategy-canary
kubectl apply -f ingress-controller.yaml 
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created

3個の ingress-nginx-controller のステータスが Running であることを確認します。

kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-4jptb        0/1     Completed   0          43m
ingress-nginx-admission-patch-5pch2         0/1     Completed   1          43m
ingress-nginx-controller-8574b6d7c9-4nskl   1/1     Running     0          43m
ingress-nginx-controller-8574b6d7c9-6k5zp   1/1     Running     0          43m
ingress-nginx-controller-8574b6d7c9-hpf62   1/1     Running     0          43m

LoadBalancer ingress-nginx-controller の EXTERNAL-IP が表示されていることを確認します。

kubectl get services -n ingress-nginx
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.96.107.235   132.xxx.xxx.xxx   80:32487/TCP,443:32238/TCP   44m
ingress-nginx-controller-admission   ClusterIP      10.96.101.214   <none>            443/TCP                      44m

Namespace Create

対象のKubernetesクラスタに、CANARY用のNamespaceを作成します。

kubectl create ns canary
namespace/canary created

canaryのNamespaceができていること確認します。

kubectl get ns
NAME              STATUS   AGE
blue              Active   11m
canary            Active   10s
default           Active   5h58m
green             Active   11m
ingress-nginx     Active   153m
kube-node-lease   Active   5h58m
kube-public       Active   5h58m
kube-system       Active   5h58m

OCI DevOps Setup

1. プロジェクトの作成

OCI DevOps環境の事前準備はこちらを参照して作成します。

Oracle Cloud Infrastructure(OCI) DevOps事前準備

ここでは、以下の名前で作成します。

トピック名:devops-deploy-strategy
プロジェクト名:canary

2. 環境 作成

作成したプロジェクトを選択して、「環境」を選択します。
左メニューから「環境」を選択します。

環境 作成

「環境の作成」ボタンをクリックします。

環境 作成

以下の設定を行い、「次」ボタンをクリックします。

  • 環境タイプ:Oracle Kubernetesエンジン
  • 名前:canary-cluster

環境 作成

環境 作成

以下の設定を行って、「環境 作成」ボタンをクリックします。

  • リージョン:対象クラスタのリージョン
  • コンパートメント:対象のコンパートメント
  • クラスタ:対象のクラスタ(ここでは cluster1)

環境 作成

環境 作成

パンくずリストから「canary」を選択します。

環境 作成

3. コード・リポジトリ 作成

左メニューから「コード・リポジトリ」を選択します。

コード・リポジトリ 作成

「リポジトリの作成」ボタンをクリックします。

コード・リポジトリ 作成

以下の設定を行い、「リポジトリの作成」ボタンをクリックします。

  • リポジトリ名:strategy-canary
  • デフォルト・ブランチ・オプション:main

コード・リポジトリ 作成

コード・リポジトリ 作成

「HTTPS」ボタンをクリックして、コマンドの「コピー」テキストをクリック後、コマンドを実行してクローンします。

コード・リポジトリ 作成

クローンしたディレクトリにサンプルコードをコピーします。

cp -pR devops-deploy-strategy/deploy-strategy-canary/* ./strategy-canary/
ls strategy-canary/
build_spec.yaml  canary-app.yaml  content.html  Dockerfile  ingress-controller.yaml

作成したリポジトリにサンプルコードをプッシュします。

cd strategy-canary
git add -A .
git commit -m "first commit"
[main f70c893] first commit
 5 files changed, 787 insertions(+)
 create mode 100644 Dockerfile
 create mode 100644 build_spec.yaml
 create mode 100644 canary-app.yaml
 create mode 100644 content.html
 create mode 100644 ingress-controller.yaml
git branch -M main
git push -u origin main
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 2 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 3.82 KiB | 3.82 MiB/s, done.
Total 7 (delta 0), reused 0 (delta 0), pack-reused 0
To https://devops.scmservice.uk-london-1.oci.oraclecloud.com/namespaces/orasejapan/projects/canary/repositories/strategy-canary
   0a0612a..f70c893  main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

リポジトリを確認すると、サンプルコードが表示されています。

コード・リポジトリ 作成

4. アーティファクト 作成

Kubernetesクラスタにデプロイする際に必要となるマニフェストファイルをアーティファクトレジストリにアップロードします。最初にアーティファクトレジストリにリポジトリを作成します。

アップロードするマニフェストファイル内にある、コンテナイメージのパスを変更します。

cd strategy-canary
vim canary-app.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld
spec:
  selector:
    matchLabels:
      app: helloworld
  replicas: 3
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      containers:
        - name: helloworld
          # enter the path to your image, be sure to include the correct region prefix
          image: lhr.ocir.io/orasejapan/canary/canary-app:${BUILDRUN_HASH}
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  #annotations:
   #service.beta.kubernetes.io/oci-load-balancer-shape: "100Mbps"
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: helloworld
---
# main-ingress.yaml with networking.k8s.io/v1 version
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: helloworld-ing
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules: 
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: helloworld
                port:
                  number: 80

ハンバーガーメニューから「開発者サービス」-「アーティファクト・レジストリ」を選択します。

アーティファクト 作成

「リポジトリの作成」ボタンをクリックします。

アーティファクト 作成

以下の設定を行い、「作成」ボタンをクリックします。

  • 名前:artifact-repository-canary
  • コンパートメント:対象となるコンパートメント
  • 不変アーティファクト:チェックを外す

アーティファクト 作成

アーティファクト 作成

マニフェストファイルをアップロードします。「アーティファクトのアップロード」ボタンをクリックします。

アーティファクト 作成

以下の設定を行い、「コピー」テキストをクリックします。

  • アーティファクト・パス:canary-app.yaml
  • バージョン:1
  • Uplad method:Cloud Shell

アーティファクト 作成

コピーした内容をペーストして、「./<file-name>」の箇所を「./blue-grenn-app.yaml」に変更してコマンドを実行します。

oci artifacts generic artifact upload-by-path \
>   --repository-id ocid1.artifactrepository.oc1.uk-london-1.0.amaaaaaassl65iqau22cohp5ulfb5ion66vkd4uz2aerbyr3olbyav7b5k5q \
>   --artifact-path canary-app.yaml \
>   --artifact-version 1 \
>   --content-body ./canary-app.yaml

以下の結果が返ってくればアップロード完了です。

{
  "data": {
    "artifact-path": "canary-app.yaml",
    "compartment-id": "ocid1.compartment.oc1..aaaaaaaagp3t6j5zjzg3hrau4i3rtcxvl64cxbcdgpid5smp6avpnfecegqa",
    "defined-tags": {},
    "display-name": "canary-app.yaml:1",
    "freeform-tags": {},
    "id": "ocid1.genericartifact.oc1.uk-london-1.0.amaaaaaassl65iqadlt552fyxu47nmxxtxl3sb22ak4pui6xrlstojc4stha",
    "lifecycle-state": "AVAILABLE",
    "repository-id": "ocid1.artifactrepository.oc1.uk-london-1.0.amaaaaaassl65iqau22cohp5ulfb5ion66vkd4uz2aerbyr3olbyav7b5k5q",
    "sha256": "d41bb6efd5988e3fbb9646963e1477863bcb567237f4dfd77cf46384b95b9e8c",
    "size-in-bytes": 1126,
    "time-created": "2023-01-27T06:50:01.017000+00:00",
    "version": "1"
  }
}

「閉じる」ボタンをクリックします。

アーティファクト 作成

ブラウザを更新するとアップロードしたアーティファクトがリストされます。

アーティファクト 作成

OCI DevOpsの「canary」プロジェクト画面に戻って、アーティファクトに対象のOCIRとアーティファクトレジストリのリポジトリを登録します。

OCI DevOpsの左目メニューから「アーティファクト」を選択します。

アーティファクト 作成

「アーティファクトの追加」ボタンをクリックします。

アーティファクト 作成

以下の設定を行い、「追加」ボタンをクリックします。

  • 名前:ocir-repogitory-canary
  • タイプ:コンテナ・イメージ・リポジトリ
  • コンテナ・レジストリのイメージへの完全修飾パスを入力してください:マニフェストファイルに指定したリポジトリを設定してください

アーティファクト 作成

アーティファクト 作成

「アーティファクトの追加」ボタンをクリックします。

アーティファクト 作成

以下の設定を行い、「選択」ボタンをクリックします。

  • 名前:artifact-repogitory-canary
  • タイプ:Kubernetesマニフェスト

アーティファクト 作成

以下の設定を行い、「選択」ボタンをクリックします。

  • リージョン:対象となるリージョン
  • コンパートメント:対象となるコンパートメント
  • アーティファクト・レジストリ・リポジトリ:artifact-repository-canary

アーティファクト 作成

アーティファクト 作成

「アーティファクト」の「選択」ボタンをクリックします。

アーティファクト 作成

「canary-app.yaml:v1」にチェックを入れて、「選択」ボタンをクリックします。

アーティファクト 作成

アーティファクト 作成

最後に「追加」ボタンをクリックします。

アーティファクト 作成

登録したOCIRとアーティファクト・レジストリのリポジトリがリストされていることを確認します。

アーティファクト 作成

パンくずリストから「canary」を選択します。

アーティファクト 作成

5. デプロイメント・パイプライン 作成

デプロイメント・パイプラインを作成します。
左メニューから「デプロイメント・パイプライン」を選択します。

デプロイメント・パイプライン 作成

「パイプラインの作成」ボタンをクリックします。

デプロイメント・パイプライン 作成

以下の設定を行い、「パイプラインの作成」ボタンをクリックします。

  • パイプライン名:deploy-to-oke

デプロイメント・パイプライン 作成

デプロイメント・パイプライン 作成

「ステージの追加」ボタンをクリックします。

デプロイメント・パイプライン 作成

「カナリア戦略」を選択して、「次」ボタンをクリックします。

デプロイメント・パイプライン 作成

デプロイメント・パイプライン 作成

以下の設定を行い、「アーティファクトの選択」ボタンをクリックします。

  • デプロイメント・タイプ:OKE
  • ステージ名:deploy-strategy-canary
  • 環境:canary-cluster
  • カナリア・ネームスペース:canary
  • NGINXイングレス名:helloworld-ing

デプロイメント・パイプライン 作成

「artifact-repository-canary」を選択して、「変更の保存」ボタンをクリックします。

デプロイメント・パイプライン 作成

デプロイメント・パイプライン 作成

「次」ボタンをクリックします。

デプロイメント・パイプライン 作成

検証制御は、「なし」のままにして、「次」ボタンをクリックします。

デプロイメント・パイプライン 作成

以下の設定を行い、「次」ボタンをクリックします。

  • ステージ名:canary
  • ランプアップ制限%:25

デプロイメント・パイプライン 作成

デプロイメント・パイプライン 作成

以下の設定を行い、「次」ボタンをクリックします。

  • ステージ名:confirm

デプロイメント・パイプライン 作成

デプロイメント・パイプライン 作成

以下の設定を行い、「追加」ボタンをクリックします。

  • ステージ名:deploy
  • 本番ネームスペース:default

デプロイメント・パイプライン 作成

デプロイメント・パイプライン 作成

完了と表示されることを確認して、「閉じる」ボタンをクリックします。

デプロイメント・パイプライン 作成

デプロイメント・パイプライン 作成

パンくずリストから「canary」を選択します。

デプロイメント・パイプライン 作成

6. ビルド・パイプライン 作成

ビルド・パイプラインを作成します。
左メニューから「ビルド・パイプライン」を選択します。

ビルド・パイプライン 作成

「ビルド・パイプラインの作成」ボタンをクリックします。

ビルド・パイプライン 作成

以下の設定を行い、「作成」ボタンをクリックします。

  • 名前:image-build-ship

ビルド・パイプライン 作成

ビルド・パイプライン 作成

「ステージの追加」ボタンをクリックします。

ビルド・パイプライン 作成

「マネージド・ビルド」を選択して、「次」ボタンをクリックします。

ビルド・パイプライン 作成

ビルド・パイプライン 作成

以下の設定を行い、「選択」ボタンをクリックします。

  • ステージ名:container-image-build
  • ビルド仕様ファイル・パス:build_spec.yaml

ビルド・パイプライン 作成

以下の設定を行い、「選択」ボタンをクリックします。

  • ソース:接続タイプ:OCIコード・リポジトリ
  • strategy-canary にチェックを入れる
  • ブランチの選択:main

ビルド・パイプライン 作成

ビルド・パイプライン 作成

「追加」ボタンをクリックします。

ビルド・パイプライン 作成

「+」をクリックして、「ステージの追加」を選択します。

ビルド・パイプライン 作成

「アーティファクトの配信」を選択して、「次」ボタンをクリックします。

ビルド・パイプライン 作成

ビルド・パイプライン 作成

以下の設定を行い、「アーティファクトの選択」ボタンをクリックします。

  • ステージ名:container-image-ship

ビルド・パイプライン 作成

「ocir-repository-canary」にチェックを入れて、「追加」ボタンをクリックします。

ビルド・パイプライン 作成

ビルド・パイプライン 作成

「ビルド構成/結果アーティファクト名」に「canary_image」と設定を行い、「追加」ボタンをクリックします。

ビルド・パイプライン 作成

ビルド・パイプライン 作成

「+」をクリックして、「ステージの追加」を選択します。

ビルド・パイプライン 作成

「デプロイメントのトリガー」を選択して、「次」ボタンをクリックします。

ビルド・パイプライン 作成

ビルド・パイプライン 作成

以下の設定を行い、「デプロイメント・パイプラインの選択」ボタンをクリックします。

  • ステージ名:connect-to-deployment-pipeline

ビルド・パイプライン 作成

「deploy-to-oke」にチェックを入れて、「変更の保存」ボタンをクリックします。

ビルド・パイプライン 作成

ビルド・パイプライン 作成

最後に「追加」ボタンをクリックします。

ビルド・パイプライン 作成

パンくずリストから「canary」を選択します。

ビルド・パイプライン 作成

7. トリガー 作成

ソースコード更新後のプッシュをトリガーにCanaryを実行する設定を行います。
左メニューから「トリガー」を選択します。

トリガー 作成

「トリガーの作成」ボタンをクリックします。

トリガー 作成

以下の設定を行い、「選択」ボタンをクリックします。

  • 名前:deploy-strategy-canary
  • ソース接続:OCIコード・リポジトリ

トリガー 作成

「strategy-canary」にチェックを入れて、「変更の保存」ボタンをクリックします。

トリガー 作成

トリガー 作成

「アクションの追加」ボタンをクリックします。

トリガー 作成

「プッシュ」にチェックを入れて、「選択」ボタンをクリックします。

トリガー 作成

「image-build-ship」にチェックを入れて、「選択」ボタンをクリックします。

トリガー 作成

トリガー 作成

「アクションの追加」ボタンをクリックします。

トリガー 作成

最後に、「作成」ボタンをクリックします。

トリガー 作成

以上で完了です。

カナリア 実行

ソースコードを変更して、first バジョンとしてデプロイします。

cd strategy-canary

表示されるテキストの「Hello, Canary deploy !!」を「Hello, Canary first!!」に変更します。

vim content.html
<!DOCTYPE html>
<html lang="ja">
<head>

<meta charset="UTF-8">

<title>Blue-Green</title>

</head>
<body>

<h1>Hello, Canary deploy !!</h1> #「Canary deploy first!!」に変更

</body>
</html>

コード・リポジトリにプッシュします。

git add -A .
git commit -m "second commit"
[main 1e304fc] second commit
 2 files changed, 2 insertions(+), 2 deletions(-)
git branch -M main
git push -u origin main
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 2 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 496 bytes | 496.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2)
To https://devops.scmservice.uk-london-1.oci.oraclecloud.com/namespaces/orasejapan/projects/canary/repositories/strategy-canary
   f70c893..1e304fc  main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

デプロイメント・パイプラインの承認処理を手動で実行します。
「confirm」のハンバーガーメニューから「承認」を選択します。

カナリア 実行

「OK」と入力して、「承認」ボタンをクリックします。

カナリア 実行

デプロイメント・パイプラインが成功したことを確認します。

カナリア 実行

ブラウザからアクセスるために、EXTERNAL-IPを確認します。

kubectl get ingress
NAME             CLASS    HOSTS   ADDRESS           PORTS   AGE
helloworld-ing   <none>   *       193.xxx.xxx.xxx   80      10m

ブラウザを起動してアクセスします。

http://193.xxx.xxx.xxx/content.html

以下表示されることを確認します。

カナリア 実行

second バージョンとしてデプロイを実行しながらカナリアを確認します。

表示されるテキストの「Hello, Canary deploy first!!」を「Hello, Canary second!!」に変更します。

vim content.html
<!DOCTYPE html>
<html lang="ja">
<head>

<meta charset="UTF-8">

<title>Blue-Green</title>

</head>
<body>

<h1>Hello, Canary deploy first!!</h1> #「Canary deploy second!!」に変更

</body>
</html>

コード・リポジトリにプッシュします。

git add -A .
git commit -m "third commit"
[main dbeed1d] third commit
 1 file changed, 1 insertion(+), 1 deletion(-)
git branch -M main
git push -u origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 311 bytes | 311.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2)
To https://devops.scmservice.uk-london-1.oci.oraclecloud.com/namespaces/orasejapan/projects/canary/repositories/strategy-canary
   1305812..dbeed1d  main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

デプロイメント・パイプラインの承認処理前に、default namespaceにデプロイされている「Hello, Canary deploy first!!」とcanary namespaceにデプロイされている「Hello, Canary deploy second!!」の両方がブラウザで表示されることを確認します。
canary namespaceにデプロイされている「Hello, Canary deploy second!!」は、デプロイメント・パイプライン作成時に設定した25%割合で表示されます。

承認処理待ちであることを確認します。

カナリア 実行

ブラウザの更新ボタンを数回押しながら、以下二つの表示が行われることを確認します。

default namespaceにデプロイされている「Hello, Canary deploy first!!」

カナリア 実行

canary namespaceにデプロイされている「Hello, Canary deploy second!!」

カナリア 実行

確認後、デプロイメント・パイプラインの承認処理を手動で実行します。
「confirm」のハンバーガーメニューから「承認」を選択します。

カナリア 実行

「OK」と入力して、「承認」ボタンをクリックします。

カナリア 実行

デプロイメント・パイプラインが成功したことを確認します。

カナリア 実行

再度、ブラウザからアクセスます。何度更新ボタンを押しても「Hello, Canary deploy second!!」と表示されることを確認します。

カナリア 実行

承認処理前では、25%の割合でcanary namespaceにトラフィックシフトされていましたが、承認処理後はdefault namespace上のアプリケーションが更新されて、100%の割合で「Hello, Canary deploy second!!」と表示されます。

承認処理待ちの間、canary namespaceのIngressは、「canary-weight: "25"」となっています。

kubectl get ingress -o yaml -n canary
apiVersion: v1
items:
- apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class: nginx
      nginx.ingress.kubernetes.io/canary: "true"
      nginx.ingress.kubernetes.io/canary-by-header: redirect-to-canary
      nginx.ingress.kubernetes.io/canary-weight: "25"
・
・<省略>
・

承認処理後は、canary namespaceのIngressは、「canary-weight: "0"」となります。

kubectl get ingress -o yaml -n canary
apiVersion: v1
items:
- apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class: nginx
      nginx.ingress.kubernetes.io/canary: "true"
      nginx.ingress.kubernetes.io/canary-by-header: redirect-to-canary
      nginx.ingress.kubernetes.io/canary-weight: "0"
・
・<省略>
・
1
1
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
1
1