OCI DevOps和OKE中的金丝雀发布

金丝雀环境

环境总览图

環境概要図

好的 de)

参考以下的教程,搭建Kubernetes集群。

在这本书中,我们将环境描述为3个节点。

让我们为 Kubernetes (OKE)启动Oracle容器引擎。

    1. 准备OKE集群的配置

 

    准备CLI执行环境(云Shell)

OCIR could be paraphrased as “OCIR可以被改写为”.

请参考以下教程,在OCIR中创建一个代码库。

Oracle Cloud基础设施 (OCI) 的DevOps入门—OKE编-

    手工艺品
    3-1. OCIRのセットアップ

<参数>
隔间:目标隔间
仓库名称:金丝雀
访问:公共

Ingress 控制器设置

获取示例代码。

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

命名空间创建

在目标Kubernetes集群中创建一个专为CANARY用途的Namespace。

kubectl create ns canary
namespace/canary created

确认canary的命名空间是否已经创建。

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设置

1. 创建项目

请参考此处创建OCI DevOps环境的预备工作。

Oracle云基础设施(OCI)的DevOps事前准备工作

在这里,将以以下名称创建。

话题名称:DevOps部署策略
项目名称:金丝雀

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
アーティファクト 作成

复制内容并粘贴,在“./”处更改为“./blue-green-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的“金丝雀”项目页面,并将目标OCIR和艺术品注册仓库添加到艺术品中。

在OCI DevOps的左侧菜单中选择“构件”。

アーティファクト 作成

点击”添加工具/物品”按钮。

アーティファクト 作成

请进行以下设置,并点击“添加”按钮。

    • 名前:ocir-repogitory-canary

 

    • タイプ:コンテナ・イメージ・リポジトリ

 

    コンテナ・レジストリのイメージへの完全修飾パスを入力してください:マニフェストファイルに指定したリポジトリを設定してください
アーティファクト 作成
アーティファクト 作成

点击“添加物品”按钮。

アーティファクト 作成

进行以下设置,然后点击“选择”按钮。

    • 名前:artifact-repogitory-canary

 

    タイプ:Kubernetesマニフェスト
アーティファクト 作成

进行以下设置,并点击“选择”按钮。

    • リージョン:対象となるリージョン

 

    • コンパートメント:対象となるコンパートメント

 

    アーティファクト・レジストリ・リポジトリ:artifact-repository-canary
アーティファクト 作成
アーティファクト 作成

点击”选择”按钮下的”Artifact”。

アーティファクト 作成

请勾选「canary-app.yaml:v1」,然后点击「选择」按钮。

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

请最后点击“添加”按钮。

アーティファクト 作成

确认OCIR(Oracle Cloud Infrastructure Registry)和Artifact Registry的存储库是否已被列出。

アーティファクト 作成

从面包屑列表中选择“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
ビルド・パイプライン 作成

勾选「部署到 OKE」选项,并点击「保存更改」按钮。

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

最后点击“新增”按钮。

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

从面包屑列表中选择“canary”。

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

7. 创建触发器 qì)

我們將進行一項設定,根據源代碼更新後的推送觸發Canary進行執行。請從左側菜單選擇「觸發」。

トリガー 作成

点击“创建触发器”按钮。

トリガー 作成

进行以下设置并点击“选择”按钮。

    • 名前:deploy-strategy-canary

 

    ソース接続:OCIコード・リポジトリ
トリガー 作成

在「策略-针灸点」复选框中勾选,并点击「保存更改」按钮。

トリガー 作成
トリガー 作成

点击”添加动作”按钮。

トリガー 作成

在”推送”选项上打勾,并点击”选择”按钮。

トリガー 作成

勾选”图像构建船”,然后点击”选择”按钮。

トリガー 作成
トリガー 作成

点击”添加操作”按钮。

トリガー 作成

最后,点击“创建”按钮。

トリガー 作成

以上是结束了。

金丝雀执行

修改源代码,并将其作为首个版本部署。

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'.

手动执行部署流水线的批准过程。
从“确认”汉堡菜单中选择“批准”。

カナリア 実行

输入「好的」,然后点击“确认”按钮。

カナリア 実行

确认部署流程成功。

カナリア 実行

为了通过浏览器访问,需要确认外部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

我会确认以下所述的内容。

カナリア 実行

在部署第二个版本时,同时进行金丝雀测试。

将显示的文本“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'.

在批准部署管道之前,我们将确保在默认命名空间中部署的“Hello,Canary deploy first!!”和在canary命名空间中部署的“Hello,Canary deploy second!!”两者都能在浏览器中显示出来。

在canary命名空间中部署的“Hello,Canary deploy second!!”将会以我们在创建部署管道时设置的25%比例进行展示。

确认等待处理。

カナリア 実行

我会一边按几次浏览器的刷新按钮,同时确认以下两个显示是否出现。

在默认命名空间中部署的是“Hello, 首次金丝雀部署!”

カナリア 実行

在Canary命名空间上部署的是”你好,Canary第二次部署!”

カナリア 実行

在确认之后,手动执行部署流水线的批准处理。
从“确认”菜单中选择“批准”。

カナリア 実行

請輸入「OK」並且點擊「確認」按鈕。

カナリア 実行

确认部署流程成功完成。

カナリア 実行

我会再次从浏览器访问页面,并多次点击更新按钮以确保屏幕上显示”Hello, Canary deploy second!!”。

カナリア 実行

在处理前,有25%的流量被转移到金丝雀命名空间,但在处理后,应用程序被更新到默认命名空间,并且以100%的比例显示“Hello, Canary deploy second!!”。

在等待确认处理期间,canary命名空间的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命名空间的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"
・
・<省略>
・
bannerAds