部署到 Kubernetes

本示例演示了将 Dubbo 应用部署到 Kubernetes 并直接使用 API-SERVER 作为注册中心重用 Kubernetes 原生服务的用法示例。本示例的局限性在于,每个 Dubbo 应用都需要被授予访问 API-SERVER 特定资源的权限。同时,对于中小型集群来说,直接访问和监控 API-SERVER 并非问题。但是,对于更大规模的集群,它可能会给 API-SERVER 的稳定性带来一定的挑战。此外,您可以考虑使用 Dubbo 控制平面将 Dubbo 应用部署到 Kuberntes。此解决方案不需要授予 Dubbo 应用访问 API-SERVER 的权限,也不需要担心 API-SERVER 连接过多数据平面带来的稳定性问题。

您可以按照以下步骤轻松地将 Dubbo 服务部署到 Kubernetes 集群。查看 [完整代码示例地址](https://github.com/apache/dubbo-samples/tree/master/3-extensions/registry /dubbo-samples-kubernetes)

1 总体目标

  • 将 Dubbo 应用部署到 Kubernetes
  • 实现基于 Kubernetes 内置服务的服务发现
  • 将 Dubbo 应用连接到 Kubernetes 生命周期

2 基本流程

  1. 创建一个 Dubbo 应用 ( dubbo-samples-kubernetes )
  2. 构建容器镜像并将其推送到镜像仓库 ( dubbo-demo 示例镜像 )
  3. 分别将 Dubbo Provider 和 Dubbo Consumer 部署到 Kubernetes
  4. 验证服务发现和调用是否正常

3 详细步骤

3.1 环境要求

请确保本地安装了以下环境,以提供容器运行时、Kubernetes 集群和访问工具

使用以下命令启动本地 Kubernetes 集群

minikube start

使用 kubectl 检查集群是否已启动并运行,以及 kubectl 是否绑定到默认本地集群

kubectl cluster-info

3.2 前提条件

由于示例 Dubbo 项目都部署在 Pod 中并与 API-SERVER 交互,因此存在相应的权限要求。这里我们创建一个独立的 ServiceAccount 并绑定必要的 Roles。所有 Dubbo Kubernetes 之后的所有资源都将使用这里新创建的 ServiceAccount。

通过以下命令,我们创建了一个独立的 Namespace dubbo-demo 和 ServiceAccount dubbo-sa

# Initialize namespace and account
kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/dubbo-samples-kubernetes/dubbo-samples-apiserver-provider/src/main/resources/k8s/ServiceAccount.yml

# switch namespace
kubens dubbo-demo

3.3 部署到 Kubernetes

3.3.1 部署 Provider

# Deploy the Service
kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/dubbo-samples-kubernetes/dubbo-samples-apiserver-provider/src/main/resources/k8s/Service.yml

# Deploy Deployment
kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/dubbo-samples-kubernetes/dubbo-samples-apiserver-provider/src/main/resources/k8s/Deployment.yml

上面的命令创建了一个名为 dubbo-samples-apiserver-provider 的服务,请注意,此处的服务名称与项目中的 dubbo 应用名称相同。

然后 Deployment 部署了 3 个副本的 Pod 实例,并启动了 Provider。您可以使用以下命令检查启动日志。

# View pod list
kubectl get pods -l app=dubbo-samples-apiserver-provider

# View pod deployment logs
kubectl logs your-pod-id

3.3.2 部署 Consumer

# Deploy the Service
kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/dubbo-samples-kubernetes/dubbo-samples-apiserver-consumer/src/main/resources/k8s/Service.yml

# Deploy Deployment
kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/dubbo-samples-kubernetes/dubbo-samples-apiserver-consumer/src/main/resources/k8s/Deployment.yml

部署 Consumer 和 Provider 的方式相同,这里也保持 K8S 服务和 Dubbo Consumer 名称一致:dubbo-samples-apiserver-consumer。

检查启动日志,Consumer 完成了对 Provider 服务的消费。

# View pod list
kubectl get pods -l app=dubbo-samples-apiserver-consumer

# View pod deployment logs
kubectl logs your-pod-id

您可以看到如下日志输出

[22/04/22 01:10:24:024UTC]main INFO deploy.DefaultApplicationDeployer:[DUBBO]Dubbo Application[1.1](dubbo-samples-apiserver-consumer) is ready.,dubbo version:3.0.7,current host :172.17.0.6
         result: hello, Kubernetes Api Server

3.4 修改项目并打包(可跳过)

示例项目和相关镜像已经准备就绪,本节仅供需要修改示例并查看部署效果的用户参考。查看这里 完整代码示例地址

设置 Dubbo 项目使用 Kubernetes 作为注册中心。这里,DEFAULT_MASTER_HOST 指定了默认的 API-SERVER 集群地址 kubernetes.default.srv,并还指定了 namespace、trustCerts 两个参数

dubbo.application.name=dubbo-samples-apiserver-provider
dubbo.application.metadataServicePort=20885
dubbo.registry.address=kubernetes://DEFAULT_MASTER_HOST?registry-type=service&duplicate=false&namespace=dubbo-demo&trustCerts=true
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.application.qosEnable=true
dubbo.application.qosAcceptForeignIp=true
dubbo.provider.token=true

如果您想在本地打包镜像,可以使用 jib-maven-plugin 插件打包镜像

# Package and push the image
mvn compile jib:build

Jib 插件会自动打包并发布镜像。请注意,对于本地开发,您需要将 jib 插件配置中的 docker 仓库组织 apache/dubbo-demo 更改为具有您自身权限的组织(包括其他 kubernetes 清单中的 dubboteam,以确保 kubernetes 部署您自己的自定义镜像),如果您遇到 jib 插件身份验证问题,请参考 [相应链接](https://github.com/GoogleContainerTools/jib/blob/master/docs/faq.md#what-should-i-do-when-the- registry-responds-with-unauthorized) 配置 docker 仓库身份验证信息。您可以在命令行中直接指定 mvn compile jib:build -Djib.to.auth.username=x -Djib.to.auth.password=x -Djib.from.auth.username=x -Djib.from.auth.username=x,或者使用 docker-credential-helper。

4 最佳实践

待定

  • 就绪探针
  • 存活探针
  • ci/cd 访问 Skalfold

5 附录 k8s 清单

ServiceAccount.yml

apiVersion: v1
kind: Namespace
metadata:
  name: dubbo-demo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dubbo-demo
  name: dubbo-role
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "watch", "list", "update", "patch"]
  - apiGroups: ["", "service.dubbo.apache.org"]
    resources: ["services", "endpoints", "virtualservices", "destinationrules"]
    verbs: ["get", "watch", "list"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dubbo-sa
  namespace: dubbo-demo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dubbo-sa-bind
  namespace: dubbo-demo
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: dubbo-role
subjects:
  - kind: ServiceAccount
    name: dubbo-sa

Service.yml

apiVersion: v1
kind: Service
metadata:
  name: dubbo-samples-apiserver-provider
  namespace: dubbo-demo
spec:
  clusterIP: None
  selector:
    app: dubbo-samples-apiserver-provider
  ports:
    - protocol: TCP
      port: 20880
      targetPort: 20880

Deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dubbo-samples-apiserver-provider
  namespace: dubbo-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: dubbo-samples-apiserver-provider
  template:
    metadata:
      labels:
        app: dubbo-samples-apiserver-provider
    spec:
      serviceAccountName: dubbo-sa
      containers:
        - name: server
          image: apache/dubbo-deemo:dubbo-samples-apiserver-provider_0.0.1
          ports:
            - containerPort: 20880
          livenessProbe:
            httpGet:
              path: /live
              port: 22222
            initialDelaySeconds: 5
            periodSeconds: 5
          readinessProbe:
            httpGet:
              path: /ready
              port: 22222
            initialDelaySeconds: 5
            periodSeconds: 5
          startupProbe:
            httpGet:
              path: /startup
              port: 22222
            failureThreshold: 30
            periodSeconds: 10

Service.yml

apiVersion: v1
kind: Service
metadata:
  name: dubbo-samples-apiserver-consumer
  namespace: dubbo-demo
spec:
  clusterIP: None
  selector:
    app: dubbo-samples-apiserver-consumer
  ports:
    - protocol: TCP
      port: 20880
      targetPort: 20880

Deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dubbo-samples-apiserver-consumer
  namespace: dubbo-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dubbo-samples-apiserver-consumer
  template:
    metadata:
      labels:
        app: dubbo-samples-apiserver-consumer
    spec:
      serviceAccountName: dubbo-sa
      containers:
        - name: server
          image: apache/dubbo-demo:dubbo-samples-apiserver-consumer_0.0.1
          ports:
            - containerPort: 20880
          livenessProbe:
            httpGet:
              path: /live
              port: 22222
            initialDelaySeconds: 5
            periodSeconds: 5
          readinessProbe:
            httpGet:
              path: /ready
              port: 22222
            initialDelaySeconds: 5
            periodSeconds: 5
          startupProbe:
            httpGet:
              path: /startup
              port: 22222
            failureThreshold: 30
            periodSeconds: 10

上次修改时间:2023 年 1 月 2 日:Enhance en docs (#1798) (95a9f4f6c1c)