使用Kubernetes进行蓝绿部署
使用 Kubernetes 进行蓝绿部署。
Purpose
Windows 11 の Linux でクラウド開発します。
こちらから記事の一覧がご覧いただけます。
实现
Windows 11 の WSL で稼働する Ubuntu の Kubernetes クラスターにて、コンテナアプリのブルーグリーンデプロイを実践してみます。
この記事では、Kubernetes におけるブルーグリーンデプロイの手順を説明していますが、これが唯一の正しい方法ではありません。実際には、他にも多くの手順が存在します。したがって、この記事を参考にしながら、他の情報も収集することをお勧めします。
技术专题
ブルーグリーンデプロイとは?
ブルーグリーンデプロイは、アプリケーションの新しいバージョンを本番環境にデプロイする際に、従来の運用方法とは異なり、新しいバージョンを本番環境に構築し、そこでアプリケーションをテストした後、従来の本番環境と切り替える方法です。
内容
通常、ブルーの本番環境とグリーンの新しい本番環境を用意します。最初はブルーがアクティブな本番環境として稼働し、グリーンはアクティブではありません。
新しいバージョンのアプリケーションをグリーン環境にデプロイしてテストし、問題がなければトラフィックをグリーン環境に切り替えます。
これにより、ダウンタイムを最小限に抑え、システムの信頼性を高めることができます。
开发环境
- Windows 11 Home 22H2 を使用しています。
WSL の Ubuntu を操作していきますので macOS の方も参考にして頂けます。
> 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
請原生地用中文重新解釋以下內容,只需要一個選項:
藍綠部署的規範
※ 本文中所述内容。
Kubernetes マニュフェスト
ブルーグリーンデプロイする手順
v1 アプリのコンテナイメージの作成
こちらの関連記事で手順がご確認いただけます。
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
将应用程序部署到 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!"}
使用v2版本创建应用程序的容器镜像。
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!"}
使用curl命令从另一个终端验证app-service-dev服务的URL。
$ curl http://127.0.0.1:34167/api/data
{"message":"Hello Green!"}
切换到新的部署
将 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 重定向到 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!"}
部署后需要注意的事项。
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 クラスターでのブルーグリーンデプロイを手軽に体験することができます。ぜひお試しください。今後もクラウド開発手法などを紹介していきますので、ぜひお楽しみにしてください。
推荐内容