当前位置:网站首页>TAP 文章系列-10 | 从应用感知能力谈 TAP 的约定服务
TAP 文章系列-10 | 从应用感知能力谈 TAP 的约定服务
2022-07-29 13:17:00 【VMware中国研发中心】
Tanzu Application Platform (TAP),VMware 在2022年1月正式发布的新一代PaaS平台,该平台一大特色即为应用感知能力,即在应用程序CICD的过程中平台将自动感知应用程序的开发框架及开发语言,那么在应用部署的过程中平台将根据以上自动判断的信息自动将应用部署的配置中注入最佳实践,比如应用安全加固、应用监控、应用自愈等约定,这种自动化的过程在TAP我们称其为约定服务(Convention Service)。可见其最大的优势及价值为通过应用感知、控制翻转、自动注入等设计理念及技术实现,可大幅减少应用运维团队及开发团队的在部署应用时的工作负担。
看到这里,相信您一定在思考一些问题,应用程序在 Kubernetes 上运行,应该如何遵循最佳约定,应该遵循哪些约定?
在解答您的疑惑之前,我们先一起来看一个普遍的场景,假设需要在Kubernetes集群中启动一个Nginx的服务,我们会怎么做,如下所示应该是解题思路之一吧?
第一步,编写nginx.yaml , 如下
apiVersion: apps/v1kind: Deploymentmetadata: name: my-nginxspec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: my-nginx labels: run: my-nginxspec: ports: - port: 80 protocol: TCP selector: run: my-nginx第二步,kubectl apply -f nginx.yaml
这样,您就可以为 Kubernetes 节点中分配一个端口并在浏览器中访问 nginx。但是,看到这里一些应用运维的专家就不同意了,并大吼到这不能在生产环境中使用,并解释道:这种启动方式存在以下问题:
http通信根本没有加密,已经公开了
由于 NodePort 将端口暴露给主机端,因此会产生主机被劫持的风险。
如果在外部发布,应该创建一个 Ingress 资源对象。
容器中的应用程序已经以root用户启动。
没有设置资源限制,因此存在无限 CPU / 内存使用的风险。
文件系统挂载应尽可能设置为只读。
……
然后,我们将以上发现的问题逐一解决编写到yaml文件中,但问题是这些设置不能为其他的容器统一设置并共用。在这种情况下,您需要在考虑其他应用程序“的特性的同时重复考虑如何优化使用最佳的推荐约定设置。您还需要了解特定框架所需的约定,即使它是像 nginx 这样的简单应用程序。
那么有没有一种自动化的方案,能够帮助开发人员以及应用运维人员简化这一块的操作呢?
答案当然是肯定的,让我们来深入的感受一下我们的TAP的约定服务吧!
1.约定服务概述
TAP的约定服务是实现“App-Aware Platform = 了解应用特性的平台”的功能之一,TAP应用感知平台根据这些应用程序特征为应用在部署过程中自动注入并设置这些最佳约定的机制。VMware认为,为在 Kubernetes 上运行的应用程序注入推荐约定应该是平台的工作,平台自动确定开发语言和框架并进入最佳约定的注入,而不是应用运维手册。
Convention Service as App-Aware 的特点是它不仅扫描 Kubernetes 脚本的有效性,还扫描容器镜像本身,主要使用 SBoM(Software Bills of Materials),在搜索了实际应用程序使用的库及其版本之后,约定服务将自动为应用程序的配置注入最佳约定。


- Developer convention service
- Spring Boot convention service
- Application Live View convention service
- Service intent convention service
2体验约定服务
2.1Developer Convention Service
- 您可以使用 Tanzu CLI Apps plug-in部署工作负载并包含标志 --live-update=true。
- 您可以通过 Tanzu Dev Tools for VSCode IDE extension使用 Tanzu: Live Update Start 选项部署工作负载。
- 在与工作负载关联的 PodTemplateSpec 上查找 apps.tanzu.vmware.com/live-update=true 注释。
- 验证应用了约定的镜像是否包含可以实时更新的进程,即检查创建 Cloud Native Buildpacks 的镜像是否支持 Process Reloading。
- 如满足以上两条,Developer Convention Service向 PodTemplateSpec 添加注释以修改 Knative 属性 minScale 和 maxScale ,使得 pod 的最小和最大数量为 1。这确保最终运行的 pod 在实时更新会话期间不会缩小到 0。
- 支持进程重载的 Java Buildpack 的行为
- 不支持进程重新加载的 NodeJS 构建包的行为
tanzu apps workload create tanzu-java-web-app \--git-repo https://github.com/HugoXiao1984/tanzu-java-web-app \--git-branch main \--type web \--live-update=true \--yes创建工作负载后,如果您检查 PodIntent文件,则发现 minScale: 1 和 maxScale: 1,这意味着Developer Conventions已按预期自动注入。
status: conditions: - lastTransitionTime: "2022-06-27T08:27:44Z" message: "" reason: Applied status: "True" type: ConventionsApplied - lastTransitionTime: "2022-06-27T08:27:44Z" message: "" reason: ConventionsApplied status: "True" type: Ready observedGeneration: 1 template: metadata: annotations: apps.tanzu.vmware.com/live-update: "true" autoscaling.knative.dev/maxScale: "1" autoscaling.knative.dev/minScale: "1" boot.spring.io/actuator: http://:8081/actuator boot.spring.io/version: 2.5.13 conventions.apps.tanzu.vmware.com/applied-conventions: |- developer-conventions/live-update-convention developer-conventions/add-source-image-label spring-boot-convention/spring-boot spring-boot-convention/spring-boot-graceful-shutdown spring-boot-convention/spring-boot-web spring-boot-convention/spring-boot-actuator appliveview-sample/app-live-view-connector appliveview-sample/app-live-view-appflavours appliveview-sample/app-live-view-systemproperties developer.apps.tanzu.vmware.com/image-source-digest: main/8aa9479d5355aa51588d39e04005a76609d08624 developer.conventions/target-containers: workload labels: app.kubernetes.io/component: run apps.tanzu.vmware.com/workload-type: myweb carto.run/workload-name: tanzu-java-web-app conventions.apps.tanzu.vmware.com/framework: spring-boot tanzu.app.live.view: "true" tanzu.app.live.view.application.actuator.port: "8081" tanzu.app.live.view.application.flavours: spring-boot tanzu.app.live.view.application.name: demo spec: containers: - env: - name: JAVA_TOOL_OPTIONS value: -Dmanagement.endpoint.health.probes.add-additional-paths="true" -Dmanagement.endpoint.health.show-details=always -Dmanagement.endpoints.web.base-path="/actuator" -Dmanagement.endpoints.web.exposure.include=* -Dmanagement.health.probes.enabled="true" -Dmanagement.server.port="8081" -Dserver.port="8080" -Dserver.shutdown.grace-period="24s" image: index.docker.io/znluo/[email protected]:d1fce7c186233920c697ca1722e17fd86db2151e27c1af0534378c5d27ca1371 name: workload ports: - containerPort: 8080 protocol: TCP resources: {} securityContext: runAsUser: 1000 serviceAccountName: default接下来,我们来看看Cloud Native Buildpacks 中不支持Process Reloading 的 NodeJS Buildpacks 的行为。让我们使用以下命令创建一个工作负载。同样重要的是“–live-update = true”参数。
tanzu apps workload create tanzu-nodejs-web-app \--git-repo https://github.com/HugoXiao1984/nodejs-hello-world \--git-branch master \--type web \--live-update=true \--yes创建工作负载后,当检查 Kubernetes Yaml时,minScale / maxScale 并没有被自动注入。虽然标签为apps.tanzu.vmware.com/live-update=true,但Convention Service 检测到镜像中的SBoM 不支持Process Reloading。因此,未设置 minScale / maxScale,但这也是预期的行为。
status: conditions: - lastTransitionTime: "2022-06-27T09:42:12Z" message: "" reason: Applied status: "True" type: ConventionsApplied - lastTransitionTime: "2022-06-27T09:42:12Z" message: "" reason: ConventionsApplied status: "True" type: Ready observedGeneration: 1 template: metadata: annotations: apps.tanzu.vmware.com/live-update: "true" conventions.apps.tanzu.vmware.com/applied-conventions: developer-conventions/add-source-image-label developer.apps.tanzu.vmware.com/image-source-digest: master/a837c6c25edc412fedcc501a4e6fef50d878adb5 developer.conventions/target-containers: workload labels: app.kubernetes.io/component: run apps.tanzu.vmware.com/workload-type: myweb carto.run/workload-name: tanzu-nodejs-web-app spec: containers: - env: - name: JAVA_TOOL_OPTIONS value: -Dmanagement.endpoint.health.probes.add-additional-paths="true" -Dmanagement.health.probes.enabled="true" image: index.docker.io/znluo/[email protected]:8efdc874bf8251d0eee9cdf75f67ccb29a1653e7e64bf62db2e095a91f9122b6 name: workload resources: {} securityContext: runAsUser: 1000 serviceAccountName: default2.2 Spring Boot Convention Service
2.2.1 Spring Boot convention
- spring-boot
apiVersion: conventions.apps.tanzu.vmware.com/v1alpha1kind: PodIntentmetadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"conventions.apps.tanzu.vmware.com/v1alpha1","kind":"PodIntent","metadata":{"annotations":{},"name":"spring-sample","namespace":"default"},"spec":{"template":{"spec":{"containers":[{"image":"springio/petclinic","name":"workload"}]}}}}...status: conditions: - lastTransitionTime: "..." # This status indicates that all worked as expected status: "True" type: ConventionsApplied - lastTransitionTime: "..." status: "True" type: Ready observedGeneration: 1 template: metadata: annotations: boot.spring.io/version: 2.3.3.RELEASE conventions.apps.tanzu.vmware.com/applied-conventions: |- spring-boot-convention/spring-boot labels: conventions.apps.tanzu.vmware.com/framework: spring-boot spec: containers: - image: index.docker.io/springio/[email protected]:... name: workload resources: {}2.2.2 Spring boot graceful shut down convention
- spring-boot-starter-tomcat
- spring-boot-starter-jetty
- spring-boot-starter-reactor-netty
- spring-boot-starter-undertow
- tomcat-embed-core
apiVersion: conventions.apps.tanzu.vmware.com/v1alpha1kind: PodIntentmetadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"conventions.apps.tanzu.vmware.com/v1alpha1","kind":"PodIntent","metadata":{"annotations":{},"name":"spring-sample","namespace":"default"},"spec":{"template":{"spec":{"containers":[{"image":"springio/petclinic","name":"workload"}]}}}}...status: conditions: - lastTransitionTime: "..." # This status indicates that all worked as expected status: "True" type: ConventionsApplied - lastTransitionTime: "..." status: "True" type: Ready observedGeneration: 1 template: metadata: annotations: boot.spring.io/version: 2.3.3.RELEASE conventions.apps.tanzu.vmware.com/applied-conventions: |- spring-boot-convention/spring-boot spring-boot-convention/spring-boot-graceful-shutdown labels: conventions.apps.tanzu.vmware.com/framework: spring-boot spec: containers: - env: - name: JAVA_TOOL_OPTIONS value: -Dserver.shutdown.grace-period="24s" image: index.docker.io/springio/[email protected]:... name: workload resources: {}2.2.3 Spring Boot Web convention
- spring-boot
- spring-boot-web
apiVersion: conventions.apps.tanzu.vmware.com/v1alpha1kind: PodIntentmetadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"conventions.apps.tanzu.vmware.com/v1alpha1","kind":"PodIntent","metadata":{"annotations":{},"name":"spring-sample","namespace":"default"},"spec":{"template":{"spec":{"containers":[{"image":"springio/petclinic","name":"workload"}]}}}}...status: conditions: - lastTransitionTime: "..." # This status indicates that all worked as expected status: "True" type: ConventionsApplied - lastTransitionTime: "..." status: "True" type: Ready observedGeneration: 1 template: metadata: annotations: boot.spring.io/version: 2.3.3.RELEASE conventions.apps.tanzu.vmware.com/applied-conventions: |- spring-boot-convention/spring-boot spring-boot-convention/spring-boot-web labels: conventions.apps.tanzu.vmware.com/framework: spring-boot spec: containers: - env: - name: JAVA_TOOL_OPTIONS value: -Dserver.port="8080" image: index.docker.io/springio/[email protected]:... name: workload ports: - containerPort: 8080 protocol: TCP resources: {}2.2.4 Spring Boot Actuator convention
- spring-boot-actuator
- 将 JAVA_TOOL_OPTIONS 环境变量中的管理端口设置为 8081。
- 将 JAVA_TOOL_OPTIONS 环境变量中的基本路径设置为 /actuator。
- 在访问Actuator的位置添加注释 boot.spring.io/actuator。
apiVersion: conventions.apps.tanzu.vmware.com/v1alpha1kind: PodIntentmetadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"conventions.apps.tanzu.vmware.com/v1alpha1","kind":"PodIntent","metadata":{"annotations":{},"name":"spring-sample","namespace":"default"},"spec":{"template":{"spec":{"containers":[{"image":"springio/petclinic","name":"workload"}]}}}}...status: conditions: - lastTransitionTime: "..." # This status indicates that all worked as expected status: "True" type: ConventionsApplied - lastTransitionTime: "..." status: "True" type: Ready observedGeneration: 1 template: metadata: annotations: boot.spring.io/actuator: http://:8080/actuator boot.spring.io/version: 2.3.3.RELEASE conventions.apps.tanzu.vmware.com/applied-conventions: |- spring-boot-convention/spring-boot spring-boot-convention/spring-boot-web spring-boot-convention/spring-boot-actuator labels: conventions.apps.tanzu.vmware.com/framework: spring-boot spec: containers: - env: - name: JAVA_TOOL_OPTIONS value: Dmanagement.endpoints.web.base-path="/actuator" -Dmanagement.server.port="8081" -Dserver.port="8080" image: index.docker.io/springio/[email protected]:... name: workload ports: - containerPort: 8080 protocol: TCP resources: {}2.2.5 Spring Boot Actuator Probes convention
- spring-boot-actuator 依赖存在且版本>= 2.6
- JAVA_TOOL_OPTIONS 环境变量不包含以下属性,或者,如果包含其中任何一个属性,则将其设置为 true 值:
- 使用主服务器端口(即 JAVA_TOOL_OPTIONS 上的 server.port 值)来设置 liveness 和 readiness 探针。
- 将以下属性和值添加到 JAVA_TOOL_OPTIONS 环境变量:
- Liveness probe: /livez
- Readiness probe: /readyz
apiVersion: conventions.apps.tanzu.vmware.com/v1alpha1kind: PodIntentmetadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"conventions.apps.tanzu.vmware.com/v1alpha1","kind":"PodIntent","metadata":{"annotations":{},"name":"spring-sample","namespace":"default"},"spec":{"template":{"spec":{"containers":[{"image":"springio/petclinic","name":"workload"}]}}}}...status: conditions: - lastTransitionTime: "..." # This status indicates that all worked as expected status: "True" type: ConventionsApplied - lastTransitionTime: "..." status: "True" type: Ready observedGeneration: 1 template: metadata: annotations: boot.spring.io/actuator: http://:8080/actuator boot.spring.io/version: 2.6.0 conventions.apps.tanzu.vmware.com/applied-conventions: |- spring-boot-convention/spring-boot spring-boot-convention/spring-boot-web spring-boot-convention/spring-boot-actuator labels: conventions.apps.tanzu.vmware.com/framework: spring-boot spec: containers: - env: - name: JAVA_TOOL_OPTIONS value: -Dmanagement.endpoint.health.probes.add-additional-paths="true" -Dmanagement.endpoints.web.base-path="/actuator" -Dmanagement.health.probes.enabled="true" -Dmanagement.server.port="8081" -Dserver.port="8080" image: index.docker.io/springio/[email protected]:... name: workload livenessProbe: httpGet: path: /livez port: 8080 scheme: HTTP ports: - containerPort: 8080 protocol: TCP readinessProbe: httpGet: path: /readyz port: 8080 scheme: HTTP resources: {}2.3Application Live View convention service
- 在 PodTemplateSpec 中添加一个标签tanzu.app.live.view: "true"
- 在 PodTemplateSpec 中添加一个标签tanzu.app.live.view.application.name: APP-NAME
- 将以下属性和值添加到 JAVA_TOOL_OPTIONS 环境变量:
status:conditions:- lastTransitionTime: "2021-10-26T11:26:35Z" status: "True" type: ConventionsApplied- lastTransitionTime: "2021-10-26T11:26:35Z" status: "True" type: ReadyobservedGeneration: 1template: metadata: annotations: conventions.apps.tanzu.vmware.com/applied-conventions: |- appliveview-sample/app-live-view-connector appliveview-sample/app-live-view-appflavours appliveview-sample/app-live-view-systemproperties labels: tanzu.app.live.view: "true" tanzu.app.live.view.application.flavours: spring-boot tanzu.app.live.view.application.name: petclinic spec: containers: - env: - name: JAVA_TOOL_OPTIONS value: -Dmanagement.endpoint.health.show-details=always -Dmanagement.endpoints.web.exposure.include=* image: index.docker.io/kdvolder/alv-spring-petclinic:[email protected]:1aa7bd228137471ea38ce36cbf5ffcd629eabeb8ce047f5533b7b9176ff51f98 name: workload resources: {}在注入约定后,应用可在TAP的Live View页面进行实时监控,如下所示 :


2.4Service intent conventions
apiVersion: conventions.apps.tanzu.vmware.com/v1alpha1 kind: PodIntent metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"conventions.apps.tanzu.vmware.com/v1alpha1","kind":"PodIntent","metadata":{"annotations":{},"name":"spring-sample","namespace":"default"},"spec":{"template":{"spec":{"containers":[{"image":"springio/petclinic","name":"workload"}]}}}} creationTimestamp: "..." generation: 1 name: spring-sample namespace: default resourceVersion: "..." uid: ... spec: serviceAccountName: default template: metadata: {} spec: containers: - image: springio/petclinic name: workload resources: {} status: conditions: - lastTransitionTime: "..." # This status indicates that all worked as expected status: "True" type: ConventionsApplied - lastTransitionTime: "..." status: "True" type: Ready observedGeneration: 1 template: metadata: annotations: boot.spring.io/actuator: http://:8080/actuator boot.spring.io/version: 2.3.3.RELEASE conventions.apps.tanzu.vmware.com/applied-conventions: |- spring-boot-convention/spring-boot spring-boot-convention/spring-boot-web spring-boot-convention/spring-boot-actuator spring-boot-convention/service-intent-mysql services.conventions.apps.tanzu.vmware.com/mysql: mysql-connector-java/8.0.21 labels: conventions.apps.tanzu.vmware.com/framework: spring-boot services.conventions.apps.tanzu.vmware.com/mysql: workload spec: containers: - env: - name: JAVA_TOOL_OPTIONS value: Dmanagement.endpoints.web.base-path="/actuator" -Dmanagement.server.port="8081" -Dserver.port="8080" image: index.docker.io/springio/[email protected]:... name: workload ports: - containerPort: 8080 protocol: TCP resources: {}3.价值总结
4.作者介绍

边栏推荐
- 人脸合成效果媲美StyleGAN,而它是个自编码器
- 【10点公开课】:快手GPU/FPGA/ASIC异构平台的应用探索
- C# autoCAD 几个经常用到的功能代码。
- The core principles of electronic games
- 「 工业缺陷检测深度学习方法」最新2022研究综述
- Go - reading (7), CopySheet Excelize API source code (the from and to the int)
- 万字长文,揭秘华为数据治理体系!
- "Industrial flaw detection depth study method" the latest 2022 research were reviewed
- 系列文章|云原生时代下微服务架构进阶之路 - Boris
- 少儿编程 电子学会图形化编程等级考试Scratch二级真题解析(选择题)2022年6月
猜你喜欢

R Error in :missing values are not allowed in subscripted assignments of data frames

Understand the yolov7 network structure

Py之eli5:eli5库的简介、安装、使用方法之详细攻略

小程序开发模板设计怎么做?
![[Numpy] np.select](/img/d6/5dfa767ad24dab3f7289d861011d00.jpg)
[Numpy] np.select

万字长文,揭秘华为数据治理体系!

The whole process of installing Oracle database on CentOS7

Sentinel 2A data preprocessing and calculation of six common vegetation indices in snap software

Gee engine modification UI interface graphic tutorial

Linux下 mysql5.7的彻底卸载
随机推荐
【论文阅读】异常检测的视频通过Self-Supervised和多任务学习
[Numpy] np.select
少儿编程 电子学会图形化编程等级考试Scratch二级真题解析(选择题)2022年6月
人脸合成效果媲美StyleGAN,而它是个自编码器
The most classic special effects scenes in 25 years
2022年七夕情人节有什么值得推荐的礼物选择?实用且高级礼物推荐
轻松学Pytorch-Pytorch可视化
关于ESI研究前沿的思考和使用方法研究
Gdb debugging common concepts finishing
【MySQL】ERROR 2002 (HY000): Can‘t connect to local MySQL server through socket ‘/tmp/mysql.sock‘
【C#】WCF和TCP消息通信练习,实现聊天功能
从KEIL仿真界面导出数据的技巧
线上支付,出款和收款
grid的使用
What should I do if the webpage is hijacked and redirected?Release net repair method
Leetcode67. 二进制求和
企业代码安全防护分类
HCIP第十三天笔记(BGP的路由过滤、BGP的社团属性、MPLS)
阿里云官方 Redis 开发规范!
C# autoCAD 几个经常用到的功能代码。