使用Kubernetes进行蓝绿部署

使用 Kubernetes 进行蓝绿部署。

spring-boot_on_kubernetes.png

Purpose

Windows 11 の Linux でクラウド開発します。

こちらから記事の一覧がご覧いただけます。

 

实现

Windows 11 の WSL で稼働する Ubuntu の Kubernetes クラスターにて、コンテナアプリのブルーグリーンデプロイを実践してみます。

この記事では、Kubernetes におけるブルーグリーンデプロイの手順を説明していますが、これが唯一の正しい方法ではありません。実際には、他にも多くの手順が存在します。したがって、この記事を参考にしながら、他の情報も収集することをお勧めします。

技术专题

ブルーグリーンデプロイとは?

こちらを展開してご覧いただけます。ブルーグリーンデプロイメント

ブルーグリーンデプロイは、アプリケーションの新しいバージョンを本番環境にデプロイする際に、従来の運用方法とは異なり、新しいバージョンを本番環境に構築し、そこでアプリケーションをテストした後、従来の本番環境と切り替える方法です。

内容

通常、ブルーの本番環境とグリーンの新しい本番環境を用意します。最初はブルーがアクティブな本番環境として稼働し、グリーンはアクティブではありません。

新しいバージョンのアプリケーションをグリーン環境にデプロイしてテストし、問題がなければトラフィックをグリーン環境に切り替えます。

これにより、ダウンタイムを最小限に抑え、システムの信頼性を高めることができます。

开发环境

    Windows 11 Home 22H2 を使用しています。

WSL の Ubuntu を操作していきますので macOS の方も参考にして頂けます。

WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます
> wsl –version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.1 LTS
Release: 22.04

Java JDK ※ こちらの関連記事からインストール方法をご確認いただけます
$ java -version
openjdk version “11.0.18” 2023-01-17
OpenJDK Runtime Environment (build 11.0.18+10-post-Ubuntu-0ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.18+10-post-Ubuntu-0ubuntu122.04, mixed mode, sharing)

Maven ※ こちらの関連記事からインストール方法をご確認いただけます
$ mvn -version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.18, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64

Docker ※ こちらの関連記事からインストール方法をご確認いただけます
$ docker –version
Docker version 23.0.1, build a5ee5b1

Kubernetes ※ こちらの関連記事からインストール方法をご確認いただけます
$ minikube version
minikube version: v1.29.0
commit: ddac20b4b34a9c8c857fc602203b6ba2679794d3

kubectl ※ こちらの関連記事からインストール方法をご確認いただけます
$ kubectl version –short
Client Version: v1.26.1
Kustomize Version: v4.5.7
Server Version: v1.26.1

在这篇文章中,我们主要介绍了如何在Ubuntu的终端上进行操作。对于初次学习如何使用Vim进行复制粘贴的人来说,我们在以下文章中详细介绍了步骤。请务必尝试一下。

 

請原生地用中文重新解釋以下內容,只需要一個選項:

藍綠部署的規範

※ 本文中所述内容。

識別するタグ内容エンドポイントJSON レスポンスv1現用のサービス/api/data{“message”:”Hello Blue!”}v2更新するサービス/api/data{“message”:”Hello Green!”}

Kubernetes マニュフェスト

Nokindファイル内容1Serviceservice-prod.yaml本番環境 エンドポイント2Serviceservice-dev.yaml検証環境 エンドポイント3Deploymentdeployment-v1.yaml現用のアプリケーション4Deploymentdeployment-v2.yaml更新するアプリケーション

ブルーグリーンデプロイする手順

v1 アプリのコンテナイメージの作成

こちらを展開して手順をご覧いただけます。Java アプリ作成
こちらの関連記事で手順がご確認いただけます。
https://qiita.com/fsdg-adachi_h/items/37ac0082a3228e4de570
プロジェクトフォルダに移動します。
※ ~/tmp/hello-spring-boot をプロジェクトフォルダとします。
$ cd ~/tmp/hello-spring-boot

v1 アプリのソースコードを作成します。
$ vim src/main/java/com/example/springboot/controller/HelloController.java

ファイルの内容
※ コードの内容を一部省略しています。

HelloController.java
@RestController
@RequestMapping(“/api”)
public class HelloController {
@GetMapping(“/data”)
public Map<String, String> getData() {
Map<String, String> map = Map.of(“message”, “Hello Blue!”);
return map;
}
}

v1 アプリをビルドします。
$ mvn clean package

コンテナイメージ作成
こちらの関連記事で手順がご確認いただけます。
https://qiita.com/fsdg-adachi_h/items/9c07e20b4124d8c5f972
Docker デーモンを起動します。
$ sudo service docker start
* Starting Docker: docker [ OK ]

v1 アプリをコンテナイメージにビルドします。
$ docker build –no-cache -t app-hello-spring-boot:v1 .

v1 アプリのコンテナイメージを確認します。
$ docker images | grep app-hello-spring-boot
app-hello-spring-boot v1 c61d32929a90 58 seconds ago 390MB

在这个过程中,我们成功创建了 v1 应用的自定义容器镜像。

将应用程序部署到 Kubernetes 集群中。

获取容器镜像

您可以在相关文章中查看操作步骤。

 

开始一个Kubernetes集群。

$ minikube start

将v1应用程序的容器映像导入到Minikube中。

$ minikube image load app-hello-spring-boot:v1

检查Minikube上的容器镜像。

$ minikube image ls | grep app-hello-spring-boot
docker.io/library/app-hello-spring-boot:v1

创建 Kubernetes 清单文件

我将创建生产环境的服务清单文件。

$ vim service-prod.yaml

文件的内容 de

apiVersion: v1
kind: Service
metadata:
  name: app-service-prod
spec:
  type: LoadBalancer
  selector:
    app: app
    version: v1
  ports:
  - port: 80
    targetPort: 8080

v1 アプリ deployment マニュフェストファイルを作成します。

$ vim deployment-v1.yaml

文件的内容 de

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
        version: v1
    spec:
      containers:
      - name: app
        image: app-hello-spring-boot:v1
        ports:
        - containerPort: 8080

确认Kubernetes集群连接目标。

$ kubectl config current-context
minikube

部署v1应用于Kubernetes集群。

$ kubectl apply -f deployment-v1.yaml
deployment.apps/app-v1 created
$ kubectl apply -f service-prod.yaml
service/app-service-prod created

检查 Kubernetes 集群的状态。

$ kubectl get pods,services,deployments
NAME                          READY   STATUS    RESTARTS   AGE
pod/app-v1-56dddcc497-s9gd6   1/1     Running   0          19m

NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/app-service-prod   LoadBalancer   10.101.34.176   <pending>     80:31015/TCP     19m
service/kubernetes         ClusterIP      10.96.0.1       <none>        443/TCP          21m

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/app-v1   1/1     1            1           19m

Minikube はローカルで稼働する Kubernetes クラスターであり、LoadBalancer タイプのサービスに外部 IP を割り当てる機能が備わっていないため、EXTERNAL-IP が になります。しかし、minikube service コマンドを使用することで、Minikube の仮想マシン上で、Service リソースに割り当てられた LoadBalancer にアクセスすることができます。

別ターミナルから app-service-prod に接続する URL を取得します。

$ minikube service app-service-prod
?  デフォルトブラウザーで default/app-service-prod サービスを開いています...
?  http://127.0.0.1:41087
❗  Docker ドライバーを linux 上で使用しているため、実行するにはターミナルを開く必要があります。

別ターミナルから curl コマンドで app-service-prod サービスの URL を確認します。

$ curl http://127.0.0.1:41087/api/data
{"message":"Hello Blue!"}
在此之前的工作中,已经完成了将 v1 应用程序部署到 Kubernetes 集群中的部署。

使用v2版本创建应用程序的容器镜像。

こちらを展開して手順をご覧いただけます。Java アプリ作成
v2 アプリのソースコードを作成します。
$ vim src/main/java/com/example/springboot/controller/HelloController.java

ファイルの内容
※ コードの内容を一部省略しています。

HelloController.java
@RestController
@RequestMapping(“/api”)
public class HelloController {
@GetMapping(“/data”)
public Map<String, String> getData() {
Map<String, String> map = Map.of(“message”, “Hello Green!”);
return map;
}
}

v2 アプリをビルドします。
$ mvn clean package

コンテナイメージ作成
v2 アプリをコンテナイメージにビルドします。
$ docker build –no-cache -t app-hello-spring-boot:v2 .

v1 アプリのコンテナイメージを確認します。
$ docker images | grep app-hello-spring-boot
app-hello-spring-boot v2 c61d32929a90 58 seconds ago 390MB

ここまでの作業で v2 アプリのカスタムコンテナイメージが作成できました。

将v2应用程序部署到Kubernetes集群中。

导入容器镜像

v2 アプリのコンテナイメージを Minikube に取り込みます。

$ minikube image load app-hello-spring-boot:v2

Minikube 上のコンテナイメージを確認します。

$ minikube image ls | grep app-hello-spring-boot
docker.io/library/app-hello-spring-boot:v2
docker.io/library/app-hello-spring-boot:v1

创建Kubernetes清单

创建验证环境服务清单文件。

$ vim service-dev.yaml

文件内容

apiVersion: v1
kind: Service
metadata:
  name: app-service-dev
spec:
  type: LoadBalancer
  selector:
    app: app
    version: v2
  ports:
  - port: 80
    targetPort: 8080

创建V2应用部署清单文件。

$ vim deployment-v2.yaml

文件的内容

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
        version: v2
    spec:
      containers:
      - name: app
        image: app-hello-spring-boot:v2
        ports:
        - containerPort: 8080

v2 アプリを Kubernetes クラスターにデプロイします。

$ kubectl apply -f deployment-v2.yaml
deployment.apps/app-v2 created
$ kubectl apply -f service-dev.yaml
service/app-service-dev created

查询 Kubernetes 集群的状态。

$ kubectl get pods,services,deployments
NAME                          READY   STATUS    RESTARTS   AGE
pod/app-v1-56dddcc497-s9gd6   1/1     Running   0          34m
pod/app-v2-6b587b579-zpxlp    1/1     Running   0          26s

NAME                       TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/app-service-dev    LoadBalancer   10.106.214.150   <pending>     80:32513/TCP     13s
service/app-service-prod   LoadBalancer   10.101.34.176    <pending>     80:31015/TCP     34m
service/kubernetes         ClusterIP      10.96.0.1        <none>        443/TCP          36m

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/app-v1   1/1     1            1           34m
deployment.apps/app-v2   1/1     1            1           26s

別ターミナルから app-service-dev に接続する URL を取得します。

$ minikube service app-service-dev
?  デフォルトブラウザーで default/app-service-dev サービスを開いています...
?  http://127.0.0.1:34167
❗  Docker ドライバーを linux 上で使用しているため、実行するにはターミナルを開く必要があります。

我們可以從另一個終端中使用curl指令來確認app-service-prod服務的URL。

$ curl http://127.0.0.1:41087/api/data
{"message":"Hello Blue!"}
当请求 app-service-prod 服务的 URL 时,将显示 v1 应用程序的更新之前的输出。

使用curl命令从另一个终端验证app-service-dev服务的URL。

$ curl http://127.0.0.1:34167/api/data
{"message":"Hello Green!"}
我们能够将v2应用程序部署到Kubernetes集群,并作为能够通过app-service-dev服务的URL访问的应用程序。此外,在实际发布之前,我们可以使用app-service-dev服务的URL进行功能验证。这是蓝绿部署的一个目的。

切换到新的部署

将 app-service-prod 服务的 URL 重定向到 deployment-v2 部署。

$ vim service-prod.yaml

文件的内容

apiVersion: v1
kind: Service
metadata:
  name: app-service-prod
spec:
  type: LoadBalancer
  selector:
    app: app
    version: v2
  ports:
  - port: 80
    targetPort: 8080

将 app-service-prod 的更新部署到 Kubernetes 集群上。

$ kubectl apply -f service-prod.yaml
service/app-service-prod configured

Kubernetes クラスターの状態を確認します。

$ kubectl get pods,services,deployments
NAME                          READY   STATUS    RESTARTS   AGE
pod/app-v1-56dddcc497-s9gd6   1/1     Running   0          44m
pod/app-v2-6b587b579-zpxlp    1/1     Running   0          10m

NAME                       TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/app-service-dev    LoadBalancer   10.106.214.150   <pending>     80:32513/TCP     10m
service/app-service-prod   LoadBalancer   10.101.34.176    <pending>     80:31015/TCP     44m
service/kubernetes         ClusterIP      10.96.0.1        <none>        443/TCP          46m

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/app-v1   1/1     1            1           44m
deployment.apps/app-v2   1/1     1            1           10m

別ターミナルから curl コマンドで app-service-prod サービスの URL を確認します。

$ curl http://127.0.0.1:41087/api/data
{"message":"Hello Green!"}
请求 app-service-prod 服务的 URL,展示了更新后 v2 应用的输出。部署到生产环境的工作已经完成。

当出现问题时的回溯

如果在部署服务到最新版本后遇到问题,需要将其回滚到先前正常运行的部署状态。这是蓝绿部署的一个目标。

将 app-service-prod 服务的 URL 重定向到 deployment-v1 部署。

$ vim service-prod.yaml

文件内容

apiVersion: v1
kind: Service
metadata:
  name: app-service-prod
spec:
  type: LoadBalancer
  selector:
    app: app
    version: v1
  ports:
  - port: 80
    targetPort: 8080

将 app-service-prod 的更新部署到 Kubernetes 集群中。

$ kubectl apply -f service-prod.yaml
service/app-service-prod configured

检查 Kubernetes 集群的状态。

$ kubectl get pods,services,deployments
NAME                          READY   STATUS    RESTARTS   AGE
pod/app-v1-56dddcc497-s9gd6   1/1     Running   0          49m
pod/app-v2-6b587b579-zpxlp    1/1     Running   0          15m

NAME                       TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/app-service-dev    LoadBalancer   10.106.214.150   <pending>     80:32513/TCP     15m
service/app-service-prod   LoadBalancer   10.101.34.176    <pending>     80:31015/TCP     49m
service/kubernetes         ClusterIP      10.96.0.1        <none>        443/TCP          51m

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/app-v1   1/1     1            1           49m
deployment.apps/app-v2   1/1     1            1           15m

从另一个终端使用curl命令来确认app-service-prod服务的URL。

$ curl http://127.0.0.1:41087/api/data
{"message":"Hello Blue!"}
请求 app-service-prod 服务的 URL,显示了 v1 应用在更新之前的输出。回滚部署已完成。

部署后需要注意的事项。

v2 アプリのデプロイに成功したので v1 アプリのデプロイメントを Kubernetes クラスターから削除します。

$ kubectl delete deployment app-v1
deployment.apps "app-v1" deleted

确认 Kubernetes 集群的状态。

$ kubectl get pods,services,deployments
NAME                         READY   STATUS    RESTARTS   AGE
pod/app-v2-6b587b579-zpxlp   1/1     Running   0          27m

NAME                       TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/app-service-dev    LoadBalancer   10.106.214.150   <pending>     80:32513/TCP     26m
service/app-service-prod   LoadBalancer   10.101.34.176    <pending>     80:31015/TCP     60m
service/kubernetes         ClusterIP      10.96.0.1        <none>        443/TCP          63m

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/app-v2   1/1     1            1           27m

我确认了v1应用的部署已被删除。

综上所述

我在WSL Ubuntu的Kubernetes集群上成功实践了蓝绿部署。

クラウド開発においては、Kubernetes の基本的な理解は重要です。また、Ubuntu を使用することで Linux の知識も身につけることができます。最初は難しく感じるかもしれませんが、少しずつ進めていくことで自信を持って取り組むことができるようになります。

どうでしたか? WSL Ubuntu で、Kubernetes クラスターでのブルーグリーンデプロイを手軽に体験することができます。ぜひお試しください。今後もクラウド開発手法などを紹介していきますので、ぜひお楽しみにしてください。

推荐内容

 

广告
将在 10 秒后关闭
bannerAds