如果 Azure-Samples/aks-store-demo 使用了 Score 会怎样?

2025/1/3 21:03:22

本文主要是介绍如果 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-serviceproduct-servicestore-frontrabbitmq。还有一个 [docker-compose.yml](https://github.com/Azure-Samples/aks-store-demo/blob/main/docker-compose.yml) 文件,它包含更多服务,例如 makeline-servicestore-adminvirtual-customervirtual-workerai-servicemongodb

让我们来关注 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 文件;

  • 他们应该知道如何在本地运行 mongodbrabbitmq 容器;

  • 他们应该手动将连接到 mongodbrabbitmq 数据库的信息注入工作负载的环境变量中。这些值在两个地方是硬编码的。

  • 如果他们需要设置外部的 mongodbrabbitmq,是否也需要了解或学习相关的知识呢?

再次提到,Docker Compose 非常有帮助,但正如我们所观察到的,开发人员需要做的事情和要了解的知识还很多,这影响了他们将高质量的代码和功能提供给最终用户。

Kubernetes # 容器编排

让我们现在看看这些示例应用程序如何在 Kubernetes 上部署。

要使用 Kubernetes 部署这些示例应用程序,你可以查看此教程或另一个教程。
此 Microsoft Azure 文档中的教程 或 另一个教程。

你可以找到这些文件,也可以找到这些工具,包括纯 Kubernetes 清单文件,Helm 图表 或者 Kustomize 资源。非常方便,有三种流行的方式来部署容器化工作负载到 Kubernetes。这说明学习起来非常方便。

我们来关注一下makeline-service,及其两个依赖rabbitmqmongodb

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 中运行 mongodbrabbitmq 容器;
  • 他们应该手动将连接到 mongodbrabbitmq 数据库的信息注入工作负载的环境变量中。这些值在这两个地方被硬编码。
  • 如果他们需要提供外部的 mongodbrabbitmq,是否也需要了解这些?
  • 如果需要在 Kubernetes 资源中应用安全、可观测性和治理信息(如在 Deployment 上设置 securityContext,注入 Istio 边车代理标签,添加成本中心标签和可观测性标签等),他们也需要了解吗?
得分

这里就要介绍Score,一个CNCF沙盒项目,能够帮助开发人员更简单地描述如何部署他们的容器化工作负载。开发人员需要为每个工作负载创建一个独立于环境和平台的Score文件。各种Score实现(如score-composescore-k8s等)会自动生成相关技术细节和基础设施依赖。最后,开发人员可以用docker composekubectl来部署生成的文件。

展示代码!没错,确实,让我们用我们之前提到的 makeline-service 及其 rabbitmqmongodb 依赖为例,开发者会这样定义 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 中配置 mongodbrabbitmq 的依赖项,他们也不需要重复硬编码的信息来连接到这些服务。

真酷,对吧?!

在这里可以找到所有工作负载的Score文件所在位置,如果你想了解更多,可以查看更多例子。

来展示一下魔法吧!当然,咱们来看看下面这两个 Score 实现的实例:score-composescore-k8s(如下所示)。

score-compose

现在,让我们通过 score-compose 来部署配置文件,使用 Docker Compose。

首先,我们需要设置本地的 score-compose 工作区:

    score-compose init

这将启用 score-compose 的默认提供程序。你可以在这里找到这些默认提供程序的实现代码。默认支持 mongodbamqp(即 rabbitmq)、mysqlpostgresrediss3(即 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 提供器。你可以在这里找到这些默认提供器的具体实现(这里):默认支持 mongodbamqp(即 rabbitmq)、mysqlpostgresredis 等。你也可以使用自己的提供器,实际上,平台工程师会为开发人员提供这些提供器。

其次,我们需要基于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-composescore-k8s 是两个默认、非常流行和强大的Score实现。

等不及想要看看CNCF社区会将这个Score项目及其项目默认实现和提供程序提升到下一个层次!真是太激动人心了!

资源
  • 被接受为 CNCF 沙盒项目 | CNCF
  • 为 Apache Kafka 编写自定义的 score-compose 提供程序 | Score
  • Humanitec-DemoOrg/aks-store-demo: 将 Azure-Samples/aks-store-demo 集成到 Score 和 Humanitec 中 | GitHub
  • 平台工程实践:使用 Score 和 Humanitec 部署在线商店示例应用程序


这篇关于如果 Azure-Samples/aks-store-demo 使用了 Score 会怎样?的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程