自定义容器交付

如果默认的 webservice 组件类型不能满足你的团队,并且你希望获得一种更简单的方式来部署业务应用。 本指南将为你提供帮助。 在此之前,你必须获得平台管理员的权限。

简化 webservice 类型

默认的 webservice 组件类型有超过 10 个属性。 也许你的开发者只需要配置镜像路径和资源限制。 对于其他属性,团队可以设置默认值。如果是这样,你可以更改 webservice 定义。

  1. 更改 UI schema 以隐藏某些字段

这种方式只适合 UI 用户。

image

在定义详情页面,用户可以自定义 UI schema 来设置 UI 表单。 例如,如果要隐藏 ExposeType 字段,只需要设置 disable 为 true

  1. ...
  2. - jsonKey: exposeType
  3. uiType: Select
  4. label: ExposeType
  5. disable: true
  6. ...

更多参考: UI Schema

  1. 更改定义并增删字段

如果要完全删除或添加某些字段,则应编辑组件定义。

本指南需要先学习 CUE 语言。

  1. vela def get webservice > custom-webservice.cue

参考CUE基础组件定义文档,了解如何自定义 custom-webservice.cue

编辑完成之后:

  1. vela def apply custom-webservice.cue

创建一个新的组件类型来部署 war 包

如果你的团队使用 war 包来部署 Java 应用。 在 KubeVela 中,你可以创建一个新的组件类型来部署 War 包。

  1. "java-war": {
  2. alias: ""
  3. annotations: {}
  4. attributes: {
  5. workload: {
  6. definition: {
  7. apiVersion: "apps/v1"
  8. kind: "Deployment"
  9. }
  10. type: "deployments.apps"
  11. }
  12. status: {
  13. customStatus: #"""
  14. ready: {
  15. readyReplicas: *0 | int
  16. } & {
  17. if context.output.status.readyReplicas != _|_ {
  18. readyReplicas: context.output.status.readyReplicas
  19. }
  20. }
  21. message: "Ready:\(ready.readyReplicas)/\(context.output.spec.replicas)"
  22. """#
  23. healthPolicy: #"""
  24. ready: {
  25. updatedReplicas: *0 | int
  26. readyReplicas: *0 | int
  27. replicas: *0 | int
  28. observedGeneration: *0 | int
  29. } & {
  30. if context.output.status.updatedReplicas != _|_ {
  31. updatedReplicas: context.output.status.updatedReplicas
  32. }
  33. if context.output.status.readyReplicas != _|_ {
  34. readyReplicas: context.output.status.readyReplicas
  35. }
  36. if context.output.status.replicas != _|_ {
  37. replicas: context.output.status.replicas
  38. }
  39. if context.output.status.observedGeneration != _|_ {
  40. observedGeneration: context.output.status.observedGeneration
  41. }
  42. }
  43. isHealth: (context.output.spec.replicas == ready.readyReplicas) && (context.output.spec.replicas == ready.updatedReplicas) && (context.output.spec.replicas == ready.replicas) && (ready.observedGeneration == context.output.metadata.generation || ready.observedGeneration > context.output.metadata.generation)
  44. """#
  45. }
  46. }
  47. description: ""
  48. labels: {}
  49. type: "component"
  50. }
  51. template: {
  52. output: {
  53. apiVersion: "apps/v1"
  54. kind: "Deployment"
  55. metadata: {
  56. name: context.name
  57. namespace: context.namespace
  58. }
  59. spec: {
  60. replicas: parameter.replicas
  61. selector: {
  62. matchLabels: {
  63. "app.oam.dev/component": context.name
  64. }
  65. }
  66. template: {
  67. metadata: {
  68. labels: {
  69. "app.oam.dev/name": context.appName
  70. "app.oam.dev/component": context.name
  71. "app.oam.dev/revision": context.revision
  72. }
  73. }
  74. spec: {
  75. initContainers: [{
  76. name: "prepare-war"
  77. image: "busybox"
  78. if parameter["deployToRoot"] != _|_ {
  79. if parameter["deployToRoot"] {
  80. command: ["wget", "-O", "/usr/local/tomcat/webapps/ROOT.war", parameter["warURL"]]
  81. }
  82. }
  83. if parameter["deployToRoot"] == _|_ {
  84. command: ["wget", "-P", "/usr/local/tomcat/webapps/", parameter["warURL"]]
  85. }
  86. volumeMounts: [{
  87. name: "webapps"
  88. mountPath: "/usr/local/tomcat/webapps"
  89. }]
  90. }]
  91. containers: [{
  92. name: context.name
  93. image: "tomcat:" + parameter["envVersion"]
  94. if parameter["cpu"] != _|_ {
  95. resources: {
  96. limits: cpu: parameter.cpu
  97. requests: cpu: parameter.cpu
  98. }
  99. }
  100. if parameter["memory"] != _|_ {
  101. resources: {
  102. limits: memory: parameter.memory
  103. requests: memory: parameter.memory
  104. }
  105. }
  106. ports: [{
  107. containerPort: 8080
  108. name: "webapp"
  109. }]
  110. _envs: {
  111. custom: *parameter["env"] | []
  112. inner: [
  113. if parameter["javaOpts"] != _|_ {
  114. {
  115. name: "JAVA_OPTS"
  116. value: parameter.javaOpts
  117. }
  118. },
  119. ]
  120. }
  121. env: _envs.custom + _envs.inner
  122. volumeMounts: [{
  123. name: "webapps"
  124. mountPath: "/usr/local/tomcat/webapps"
  125. }]
  126. }]
  127. volumes: [{
  128. name: "webapps"
  129. emptyDir: {}
  130. }]
  131. }
  132. }
  133. }
  134. }
  135. outputs: {
  136. services: {
  137. kind: "Service"
  138. apiVersion: "v1"
  139. metadata: {
  140. name: context.name
  141. namespace: context.namespace
  142. }
  143. spec: {
  144. selector: "app.oam.dev/component": context.name
  145. ports: [{
  146. port: 8080
  147. }]
  148. type: "ClusterIP"
  149. }
  150. }
  151. }
  152. parameter: {
  153. // +usage=The URL of the war package.
  154. warURL: string
  155. // +usage=Select a environment version([tomcat version]-[jdk version])
  156. envVersion: *"8-jdk8" | "9-jdk8" | "10-jdk8" | "8-jdk11" | "9-jdk11" | "10-jdk11" | "8-jdk17" | "9-jdk17" | "10-jdk17"
  157. // +usage=Specifies the number of replicas.
  158. replicas: *1 | int
  159. // +usage=Define arguments by using environment variables
  160. env?: [...{
  161. name: string
  162. value?: string
  163. }]
  164. // +usage=Setting the Java Opts configuration.
  165. javaOpts?: string
  166. // +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
  167. cpu?: string
  168. // +usage=Specifies the attributes of the memory resource required for the container.
  169. memory?: =~"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"
  170. deployToRoot?: bool
  171. }
  172. }

复制上面的定义来创建一个文件 java-war.cue,然后:

  1. vela def apply java-war.cue

现在,其他开发人员可以使用 war URL 创建应用,例如:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: nanoservice
  5. namespace: e2e-test
  6. spec:
  7. components:
  8. - name: catalog
  9. properties:
  10. envVersion: 8-jdk8
  11. replicas: 1
  12. warURL: https://static.kubevela.net/example/java-example/nanoservice/catalog.war
  13. type: java-war
  14. - name: customer
  15. properties:
  16. envVersion: 8-jdk8
  17. replicas: 1
  18. warURL: https://static.kubevela.net/example/java-example/nanoservice/customer.war
  19. type: java-war
  20. - dependsOn:
  21. - catalog
  22. - customer
  23. name: order
  24. properties:
  25. env:
  26. - name: CATALOG_HOST
  27. value: catalog
  28. - name: CUSTOMER_HOST
  29. value: customer
  30. envVersion: 8-jdk8
  31. javaOpts: -Xms512m -Xmx512m -Xss256K
  32. replicas: 1
  33. warURL: https://static.kubevela.net/example/java-example/nanoservice/order.war
  34. traits:
  35. - properties:
  36. domains:
  37. - nanoservice.beijing.kubevela.net
  38. rules:
  39. - path:
  40. type: PathPrefix
  41. value: /order
  42. port: 8080
  43. type: http-route
  44. type: java-war
  45. policies:
  46. - name: e2e-test
  47. properties:
  48. clusters:
  49. - local
  50. namespace: e2e-test
  51. type: topology
  52. workflow:
  53. steps:
  54. - name: deploy2-e2e-test
  55. properties:
  56. policies:
  57. - e2e-test
  58. type: deploy

java-app

这个例子包括三个组件,order 服务依赖 catalog 和 customer 服务。 开发者只需要关心 war 包 URL 和 tomcat/JRE 版本,Java开发者对此都很熟悉。 开发人员应将 war 包上传到仓库,例如 Jfrog。 获取下载 URL 以分配给 warURL 字段。

同样,你可以创建一个组件类型来部署 Jar 包和其他二进制包。