如果 Azure-Samples/aks-store-demo 使用了 Score 会怎样?
在这篇文章里,我们看看如何将Azure-Samples/aks-store-demo运行到Docker Compose或带有Score的Kubernetes集群,并看看它如何让开发体验更简单!
名为 Azure-Samples/aks-store-demo 的仓库是一个很好的例子,展示了如何用不同编程语言部署微服务容器,并与 RabbitMQ 和 MongoDB 等数据库通信。此外,还可选择部署一个与 OpenAI 或 Azure OpenAI 通信的容器化应用程序。
非常适合学习!即使这些应用是由微软员工创建和维护的,你也可以将它们部署到任何 Kubernetes 集群,甚至可以直接使用 Docker 和 Docker Compose 在本地运行。
Docker-compose可以参考Azure 官方文档中的教程,了解如何使用 Docker Compose 部署这些示例应用。
你可以找到第一个 [docker-compose-quickstart.yml](https://github.com/Azure-Samples/aks-store-demo/blob/main/docker-compose-quickstart.yml)
文件,它包含了 order-service
、product-service
、store-front
和 rabbitmq
。还有一个 [docker-compose.yml](https://github.com/Azure-Samples/aks-store-demo/blob/main/docker-compose.yml)
文件,它包含更多服务,例如 makeline-service
、store-admin
、virtual-customer
、virtual-worker
、ai-service
和 mongodb
。
让我们来关注 makeline-service
, 其两个依赖项 rabbitmq
以及 mongodb
。
services:
mongodb:
image: mongo:6.0.6
container_name: 'mongo'
restart: always
ports:
- 27017:27017
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.runCommand('ping').ok"]
# 检查 MongoDB 是否存活
interval: 30s
timeout: 10s
retries: 5
networks:
- 后端服务
rabbitmq:
image: rabbitmq:3.13.2-management-alpine
container_name: 'rabbitmq'
restart: always
environment:
- "RABBITMQ_DEFAULT_USER=username"
- "RABBITMQ_DEFAULT_PASS=password"
# 设置 RabbitMQ 默认用户名和密码
ports:
- 15672:15672
- 5672:5672
healthcheck:
test: ["CMD", "rabbitmqctl", "status"]
# 检查 RabbitMQ 是否存活
interval: 30s
timeout: 10s
retries: 5
volumes:
- ./rabbitmq_enabled_plugins:/etc/rabbitmq/enabled_plugins
# RabbitMQ 启用插件路径
networks:
- 后端服务
makeline-service:
build: src/makeline-service
container_name: 'makeline-service'
restart: always
ports:
- 3001:3001
healthcheck:
test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://makeline-service:3001/health"]
# 检查 makeline-service 是否存活
interval: 30s
timeout: 10s
retries: 5
environment:
- ORDER_QUEUE_URI=amqp://rabbitmq:5672
# 订单队列 URI
- ORDER_QUEUE_USERNAME=username
# 订单队列用户名
- ORDER_QUEUE_PASSWORD=password
# 订单队列密码
- ORDER_QUEUE_NAME=orders
# 订单队列名称
- ORDER_DB_URI=mongodb://mongodb:27017
# 订单数据库 URI
- ORDER_DB_NAME=orderdb
# 订单数据库名称
- ORDER_DB_COLLECTION_NAME=orders
# 订单数据库集合名称
networks:
- 后端服务
depends_on:
rabbitmq:
condition: 服务健康
# 取决于 RabbitMQ 服务健康状态
mongodb:
condition: 服务健康
# 取决于 MongoDB 服务健康状态
真酷,作为一名开发者,我可以使用 docker compose
在本地运行 makeline-service
的容器及其依赖项,真好!
但是,开发人员在这种情况下面临的负担和认知压力是这样的:
-
他们应该了解 Docker Compose 的语法、网络等方面的知识;
-
他们应该维护 Docker Compose 文件;
-
他们应该知道如何在本地运行
mongodb
和rabbitmq
容器; -
他们应该手动将连接到
mongodb
和rabbitmq
数据库的信息注入工作负载的环境变量中。这些值在两个地方是硬编码的。 - 如果他们需要设置外部的
mongodb
或rabbitmq
,是否也需要了解或学习相关的知识呢?
再次提到,Docker Compose 非常有帮助,但正如我们所观察到的,开发人员需要做的事情和要了解的知识还很多,这影响了他们将高质量的代码和功能提供给最终用户。
Kubernetes # 容器编排让我们现在看看这些示例应用程序如何在 Kubernetes 上部署。
要使用 Kubernetes 部署这些示例应用程序,你可以查看此教程或另一个教程。
此 Microsoft Azure 文档中的教程 或 另一个教程。
你可以找到这些文件,也可以找到这些工具,包括纯 Kubernetes 清单文件,Helm 图表 或者 Kustomize 资源。非常方便,有三种流行的方式来部署容器化工作负载到 Kubernetes。这说明学习起来非常方便。
我们来关注一下makeline-service
,及其两个依赖rabbitmq
和mongodb
:
apiVersion: v1
data:
rabbitmq_enabled_plugins: |
[rabbitmq_management,rabbitmq_prometheus,rabbitmq_amqp1_0].
kind: ConfigMap
metadata:
name: rabbitmq-enabled-plugins
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: rabbitmq
spec:
serviceName: rabbitmq
replicas: 1
selector:
matchLabels:
app: rabbitmq
template:
metadata:
labels:
app: rabbitmq
spec:
nodeSelector:
"kubernetes.io/os": linux
containers:
- name: rabbitmq
image: mcr.microsoft.com/mirror/docker/library/rabbitmq:3.10-management-alpine
ports:
- containerPort: 5672
name: rabbitmq-amqp
- containerPort: 15672
name: rabbitmq-http
env:
- name: RABBITMQ_DEFAULT_USER
value: "username"
- name: RABBITMQ_DEFAULT_PASS
value: "password"
resources:
requests:
cpu: 10m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
volumeMounts:
- name: rabbitmq-enabled-plugins
mountPath: /etc/rabbitmq/enabled_plugins
subPath: enabled_plugins
volumes:
- name: rabbitmq-enabled-plugins
configMap:
name: rabbitmq-enabled-plugins
items:
- key: rabbitmq_enabled_plugins
path: enabled_plugins
---
apiVersion: v1
kind: Service
metadata:
name: rabbitmq
spec:
selector:
app: rabbitmq
ports:
- name: rabbitmq-amqp
port: 5672
targetPort: 5672
- name: rabbitmq-http
port: 15672
targetPort: 15672
type: ClusterIP
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
serviceName: mongodb
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
nodeSelector:
"kubernetes.io/os": linux
containers:
- name: mongodb
image: mcr.microsoft.com/mirror/docker/library/mongo:4.2
ports:
- containerPort: 27017
name: mongodb
resources:
requests:
cpu: 5m
memory: 75Mi
limits:
cpu: 25m
memory: 1024Mi
livenessProbe:
exec:
command:
- mongosh
- --eval
- db.runCommand('ping').ok
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
ports:
- port: 27017
selector:
app: mongodb
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: makeline-service
spec:
replicas: 1
selector:
matchLabels:
app: makeline-service
template:
metadata:
labels:
app: makeline-service
spec:
nodeSelector:
"kubernetes.io/os": linux
containers:
- name: makeline-service
image: ghcr.io/azure-samples/aks-store-demo/makeline-service:latest
ports:
- containerPort: 3001
env:
- name: ORDER_QUEUE_URI
value: "amqp://rabbitmq:5672"
- name: ORDER_QUEUE_USERNAME
value: "username"
- name: ORDER_QUEUE_PASSWORD
value: "password"
- name: ORDER_QUEUE_NAME
value: "orders"
- name: ORDER_DB_URI
value: "mongodb://mongodb:27017"
- name: ORDER_DB_NAME
value: "orderdb"
- name: ORDER_DB_COLLECTION_NAME
value: "orders"
resources:
requests:
cpu: 1m
memory: 6Mi
limits:
cpu: 5m
memory: 20Mi
startupProbe:
httpGet:
path: /health
port: 3001
failureThreshold: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 3001
failureThreshold: 3
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 3001
failureThreshold: 5
initialDelaySeconds: 3
periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
name: makeline-service
spec:
type: ClusterIP
ports:
- name: http
port: 3001
targetPort: 3001
selector:
app: makeline-service
就算比 Docker Compose 稍微麻烦一点点,我就能轻松部署应用到 Kubernetes,这也太牛了!
但这里有对开发人员的认知负担来说。
- 他们应该熟悉 Kubernetes(如语法、网络等),并且最好还了解 Helm 和/或 Kustomize(如何将值注入到正确的字段等);
- 他们也需要负责维护这些 Kubernetes 文件;
- 他们应该知道如何在 Kubernetes 中运行
mongodb
和rabbitmq
容器; - 他们应该手动将连接到
mongodb
和rabbitmq
数据库的信息注入工作负载的环境变量中。这些值在这两个地方被硬编码。 - 如果他们需要提供外部的
mongodb
或rabbitmq
,是否也需要了解这些? - 如果需要在 Kubernetes 资源中应用安全、可观测性和治理信息(如在
Deployment
上设置securityContext
,注入 Istio 边车代理标签,添加成本中心标签和可观测性标签等),他们也需要了解吗?
这里就要介绍Score,一个CNCF沙盒项目,能够帮助开发人员更简单地描述如何部署他们的容器化工作负载。开发人员需要为每个工作负载创建一个独立于环境和平台的Score文件。各种Score实现(如score-compose
,score-k8s
等)会自动生成相关技术细节和基础设施依赖。最后,开发人员可以用docker compose
或kubectl
来部署生成的文件。
展示代码!没错,确实,让我们用我们之前提到的 makeline-service
及其 rabbitmq
和 mongodb
依赖为例,开发者会这样定义 Score 文件(如下面所示):
apiVersion: score.dev/v1b1 # API版本,用于指定配置文件的版本
metadata:
name: makeline-service
containers:
makeline-service:
image: ghcr.io/azure-samples/aks-store-demo/makeline-service:1.5.1
variables:
ORDER_QUEUE_URI: "amqp://${resources.orders-queue.host}:${resources.orders-queue.port}" # 订单队列的AMQP URI
ORDER_QUEUE_USERNAME: "${resources.orders-queue.username}"
ORDER_QUEUE_PASSWORD: "${resources.orders-queue.password}"
ORDER_QUEUE_NAME: "orders"
ORDER_DB_URI: "${resources.orders-database.connection}" # 订单数据库的连接URI
ORDER_DB_NAME: "orderdb"
ORDER_DB_COLLECTION_NAME: "orders"
livenessProbe:
httpGet:
path: /health, # 健康检查路径
port: 3001, # 健康检查端口
readinessProbe:
httpGet:
path: /health, # 健康检查路径
port: 3001, # 健康检查端口
resources:
limits:
memory: "20Mi" # 内存限制
cpu: "5m" # CPU限制
requests:
memory: "6Mi" # 内存请求
cpu: "1m" # CPU请求
service:
ports:
http:
port: 3001
targetPort: 3001
resources:
orders-queue:
type: amqp
id: orders-queue
orders-database:
type: mongodb
开发人员不需要为了针对多个平台或环境而写多个文件,这个 Score 文件保持不变。相关的 Score 实现及其提供程序会处理这些问题,让开发人员无需关心。之前提到的与 Docker compose 文件和 Kubernetes 配置文件相关的大部分甚至所有负担和认知负荷已经被移除或简化了。开发人员不再需要担心在 Docker Compose 或 Kubernetes 中配置 mongodb
或 rabbitmq
的依赖项,他们也不需要重复硬编码的信息来连接到这些服务。
真酷,对吧?!
在这里可以找到所有工作负载的Score文件所在位置,如果你想了解更多,可以查看更多例子。
来展示一下魔法吧!当然,咱们来看看下面这两个 Score 实现的实例:score-compose
和 score-k8s
(如下所示)。
现在,让我们通过 score-compose
来部署配置文件,使用 Docker Compose。
首先,我们需要设置本地的 score-compose
工作区:
score-compose init
这将启用 score-compose
的默认提供程序。你可以在这里找到这些默认提供程序的实现代码。默认支持 mongodb
、amqp
(即 rabbitmq
)、mysql
、postgres
、redis
、s3
(即 minio
)等。你也可以自定义这些提供程序,实际上,平台工程师会为开发人员提供这些自定义的提供程序。
其次,我们需要根据Score文件(或得分文件)来创建Docker Compose文件。
使用 score-compose 命令生成如下文件:
apps/order/score.yaml
apps/product/score.yaml
apps/store-front/score.yaml
apps/store-admin/score.yaml
apps/makeline/score.yaml
最后,运行这个生成的 compose.yaml
。
执行此命令来构建并启动Docker容器,如果有需要的话: docker compose up --build -d
就这样,你根本不需要去了解或学习Docker Compose(确实,你需要在你的机器上安装Docker和Docker Compose工具)。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa94154f047c ghcr.io/azure-samples/aks-store-demo/product-service:1.5.1 "./product-service" 38 seconds ago Up 14 seconds aks-store-demo-product-service-product-service-1
51f3b0de2a48 ghcr.io/azure-samples/aks-store-demo/makeline-service:1.5.1 "./main" 38 seconds ago Up 14 seconds 3001/tcp aks-store-demo-makeline-service-makeline-service-1
b608ed30d6fa ghcr.io/azure-samples/aks-store-demo/order-service:1.5.1 "docker-entrypoint.s…" 38 seconds ago Up 15 seconds 3000/tcp aks-store-demo-order-service-order-service-1
f6eb76c47f27 ghcr.io/azure-samples/aks-store-demo/store-admin:1.5.1 "/docker-entrypoint.…" 38 seconds ago Up 15 seconds 80/tcp, 8081/tcp aks-store-demo-store-admin-store-admin-1
ec852c04d166 ghcr.io/azure-samples/aks-store-demo/store-front:1.5.1 "/docker-entrypoint.…" 38 seconds ago Up 14 seconds 80/tcp, 8080/tcp aks-store-demo-store-front-store-front-1
ed39a9b5a354 mongo:7 "docker-entrypoint.s…" 39 seconds ago Up 37 seconds (healthy) 27017/tcp aks-store-demo-mongo-ENMnhn-1
6e4197ba7784 rabbitmq:3-management-alpine "docker-entrypoint.s…" 39 seconds ago Up 36 seconds (healthy) 4369/tcp, 5671-5672/tcp, 15671-15672/tcp, 15691-15692/tcp, 25672/tcp aks-store-demo-rabbitmq-RdWyvb-1
a7a590866b63 nginx:1 "/docker-entrypoint.…" 39 seconds ago Up 36 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp aks-store-demo-routing-CWlOTJ-1
score-k8s
现在,我们通过 score-k8s
部署这些 Score 文件到 Kubernetes 上。
首先,我们需要设置初始化本地 score-k8s
工作区。
score-k8s 运行初始化脚本
这将启用默认的 score-k8s
提供器。你可以在这里找到这些默认提供器的具体实现(这里):默认支持 mongodb
、amqp
(即 rabbitmq
)、mysql
、postgres
、redis
等。你也可以使用自己的提供器,实际上,平台工程师会为开发人员提供这些提供器。
其次,我们需要基于Score文件,生成Kubernetes清单文件。
score-k8s 生成如下配置文件 \
apps/makeline/score.yaml \
apps/order/score.yaml \
apps/product/score.yaml \
apps/store-admin/score.yaml \
apps/store-front/score.yaml
最后,你通过如下命令使用 kubectl
推送生成的 manifests.yaml
文件。
kubectl apply -f manifests.yaml
运行这个命令来应用 manifests.yaml
文件中的配置。
就这样,你不需要了解或学习任何关于Kubernetes的知识,不过你需要访问Kubernetes集群,并且已经在你的机器上安装了kubectl
。
$ kubectl get all,secrets
NAME 就绪 状态 重启次数 运行时间
pod/makeline-service-6dbbd7d87c-zv6bw 1/1 Running 1 (61s ago) 2m1s
pod/mongo-makeline-service-f587824d-0 1/1 Running 0 2m1s
pod/order-service-964c5d745-rqzff 1/1 Running 0 2m1s
pod/product-service-69748fc7cd-hfbwc 1/1 Running 0 2m1s
pod/rabbitmq-order-service-536fdcc5-0 1/1 Running 0 2m1s
pod/store-admin-957f48c68-fzvhp 1/1 Running 0 2m
pod/store-front-68fcdbbd4b-2d4d4 1/1 Running 0 2m
NAME 类型 CLUSTER-IP EXTERNAL-IP PORT(S) 运行时间
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2m54s
service/makeline-service ClusterIP 10.96.233.39 <none> 3001/TCP 2m1s
service/mongo-makeline-service-f587824d ClusterIP 10.96.132.140 <none> 27017/TCP 2m1s
service/order-service ClusterIP 10.96.133.185 <none> 3000/TCP 2m1s
service/product-service ClusterIP 10.96.187.196 <none> 3002/TCP 2m1s
service/rabbitmq-order-service-536fdcc5 ClusterIP 10.96.185.130 <none> 5672/TCP,15672/TCP 2m1s
service/store-admin ClusterIP 10.96.11.168 <none> 8081/TCP 2m1s
service/store-front ClusterIP 10.96.33.231 <none> 8080/TCP 2m
NAME 就绪 最新 可用 运行时间
deployment.apps/makeline-service 1/1 1 1 2m1s
deployment.apps/order-service 1/1 1 1 2m1s
deployment.apps/product-service 1/1 1 1 2m1s
deployment.apps/store-admin 1/1 1 1 2m1s
deployment.apps/store-front 1/1 1 1 2m
NAME 期望 当前 就绪 运行时间
replicaset.apps/makeline-service-6dbbd7d87c 1 1 1 2m1s
replicaset.apps/order-service-964c5d745 1 1 1 2m1s
replicaset.apps/product-service-69748fc7cd 1 1 1 2m1s
replicaset.apps/store-admin-957f48c68 1 1 1 2m1s
replicaset.apps/store-front-68fcdbbd4b 1 1 1 2m
NAME 就绪 运行时间
statefulset.apps/mongo-makeline-service-f587824d 1/1 2m1s
statefulset.apps/rabbitmq-order-service-536fdcc5 1/1 2m1s
NAME 类型 数据量 运行时间
secret/mongo-makeline-service-f587824d Opaque 1 2m1s
secret/rabbitmq-order-service-536fdcc5-secret Opaque 3 2m1s
结束了!
所以,开发人员只需要专注于给自己的客户提供价值,他们不需要直接处理Kubernetes或云基础设施等。Score的存在是为了让平台工程师能够提供并展示他们自己的Score实现和提供者。这都是为了实现高效且无缝的协作和抽象化,在大规模环境中运行。score-compose
和 score-k8s
是两个默认、非常流行和强大的Score实现。
等不及想要看看CNCF社区会将这个Score项目及其项目默认实现和提供程序提升到下一个层次!真是太激动人心了!
资源共同学习,写下你的评论
评论加载中...
作者其他优质文章