Version: v1.0
Crossplane
云服务是应用程序的一部分。
云服务是 Component 还是 Trait?
可以考虑以下做法:
- 使用
ComponentDefinition的场景:- 你想要允许最终用户明确声明云服务的实例并使用它,并在删除应用程序时释放该实例。
- 使用
TraitDefinition的场景:- 你不想让最终用户拥有声明或发布云服务的任何控制权,而只想给他们消费云服务,甚至可以由其他系统管理的云服务的方式。在这种情况下,会广泛使用
Service Binding特性。
- 你不想让最终用户拥有声明或发布云服务的任何控制权,而只想给他们消费云服务,甚至可以由其他系统管理的云服务的方式。在这种情况下,会广泛使用
在本文档中,我们将以阿里云的 RDS(关系数据库服务)和阿里云的 OSS(对象存储服务)为例。在单个应用程序中,它们是 Traits,在多个应用程序中,它们是 Components。此机制与其他云提供商相同。
安装和配置 Crossplane
KubeVela 使用 Crossplane 作为云服务提供商。请参阅 Installation 安装 Crossplane Alibaba provider v0.5.0。
如果你想配置任何其他 Crossplane providers,请参阅 Crossplane Select a Getting Started Configuration。
$ kubectl crossplane install provider crossplane/provider-alibaba:v0.5.0# 注意这里的 xxx 和 yyy 是你自己云资源的 AccessKey 和 SecretKey。$ kubectl create secret generic alibaba-account-creds -n crossplane-system --from-literal=accessKeyId=xxx --from-literal=accessKeySecret=yyy$ kubectl apply -f provider.yaml
provider.yaml 如下。
apiVersion: v1kind: Namespacemetadata:name: crossplane-system---apiVersion: alibaba.crossplane.io/v1alpha1kind: ProviderConfigmetadata:name: defaultspec:credentials:source: SecretsecretRef:namespace: crossplane-systemname: alibaba-account-credskey: credentialsregion: cn-beijing
注意:我们目前仅使用阿里提供的 Crossplane。但是在不久的将来,我们将使用 Crossplane 作为 Kubernetes 的云资源供应商。
注册 ComponentDefinition 和 TraitDefinition
注册 ComponentDefinition alibaba-rds 为 RDS 云资源生产者
将工作负载类型 alibaba-rds 注册到 KubeVela。
apiVersion: core.oam.dev/v1beta1kind: ComponentDefinitionmetadata:name: alibaba-rdsnamespace: vela-systemannotations:definition.oam.dev/description: "Alibaba Cloud RDS Resource"spec:workload:definition:apiVersion: database.alibaba.crossplane.io/v1alpha1kind: RDSInstanceschematic:cue:template: |output: {apiVersion: "database.alibaba.crossplane.io/v1alpha1"kind: "RDSInstance"spec: {forProvider: {engine: parameter.engineengineVersion: parameter.engineVersiondbInstanceClass: parameter.instanceClassdbInstanceStorageInGB: 20securityIPList: "0.0.0.0/0"masterUsername: parameter.username}writeConnectionSecretToRef: {namespace: context.namespacename: parameter.secretName}providerConfigRef: {name: "default"}deletionPolicy: "Delete"}}parameter: {// +usage=RDS engineengine: *"mysql" | string// +usage=The version of RDS engineengineVersion: *"8.0" | string// +usage=The instance class for the RDSinstanceClass: *"rds.mysql.c1.large" | string// +usage=RDS usernameusername: string// +usage=Secret name which RDS connection will write tosecretName: string}
注册 ComponentDefinition alibaba-oss 为 OSS 云资源生产者
apiVersion: core.oam.dev/v1beta1kind: ComponentDefinitionmetadata:name: alibaba-ossnamespace: vela-systemannotations:definition.oam.dev/description: "Alibaba Cloud RDS Resource"spec:workload:definition:apiVersion: oss.alibaba.crossplane.io/v1alpha1kind: Bucketschematic:cue:template: |output: {apiVersion: "oss.alibaba.crossplane.io/v1alpha1"kind: "Bucket"spec: {name: parameter.nameacl: parameter.aclstorageClass: parameter.storageClassdataRedundancyType: parameter.dataRedundancyTypewriteConnectionSecretToRef: {namespace: context.namespacename: parameter.secretName}providerConfigRef: {name: "default"}deletionPolicy: "Delete"}}parameter: {// +usage=OSS bucket namename: string// +usage=The access control list of the OSS bucketacl: *"private" | string// +usage=The storage type of OSS bucketstorageClass: *"Standard" | string// +usage=The data Redundancy type of OSS bucketdataRedundancyType: *"LRS" | string// +usage=Secret name which RDS connection will write tosecretName: string}
引用 Secret 注册 ComponentDefinition webconsumer
apiVersion: core.oam.dev/v1beta1kind: ComponentDefinitionmetadata:name: webconsumerannotations:definition.oam.dev/description: A Deployment provides declarative updates for Pods and ReplicaSetsspec:workload:definition:apiVersion: apps/v1kind: Deploymentschematic:cue:template: |output: {apiVersion: "apps/v1"kind: "Deployment"spec: {selector: matchLabels: {"app.oam.dev/component": context.name}template: {metadata: labels: {"app.oam.dev/component": context.name}spec: {containers: [{name: context.nameimage: parameter.imageif parameter["cmd"] != _|_ {command: parameter.cmd}if parameter["dbSecret"] != _|_ {env: [{name: "username"value: dbConn.username},{name: "endpoint"value: dbConn.endpoint},{name: "DB_PASSWORD"value: dbConn.password},]}ports: [{containerPort: parameter.port}]if parameter["cpu"] != _|_ {resources: {limits:cpu: parameter.cpurequests:cpu: parameter.cpu}}}]}}}}parameter: {// +usage=Which image would you like to use for your service// +short=iimage: string// +usage=Commands to run in the containercmd?: [...string]// +usage=Which port do you want customer traffic sent to// +short=pport: *80 | int// +usage=Referred db secret// +insertSecretTo=dbConndbSecret?: string// +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)cpu?: string}dbConn: {username: stringendpoint: stringpassword: string}
关键词是 annotation // + insertSecretTo = dbConn,KubeVela 将知道该参数是 K8s 的 secret,它将解析该 secret 并将数据绑定到 CUE 接口 dbConn 中。
output 可以引用 dbConn 获取数据。dbConn 的名称没有限制。 关键词是 +insertSecretTo,它定义了数据绑定机制。以上只是一个例子。
准备 TraitDefinition service-binding 进行 env-secret mapping
至于应用程序中的数据绑定,KubeVela 建议定义一个 trait 以完成工作。我们已经准备了一个方便的 trait。此 trait 非常适合将资源的信息绑定到 pod spec 的环境变量中.
apiVersion: core.oam.dev/v1beta1kind: TraitDefinitionmetadata:annotations:definition.oam.dev/description: "binding cloud resource secrets to pod env"name: service-bindingspec:appliesToWorkloads:- webservice- workerschematic:cue:template: |patch: {spec: template: spec: {// +patchKey=namecontainers: [{name: context.name// +patchKey=nameenv: [for envName, v in parameter.envMappings {name: envNamevalueFrom: {secretKeyRef: {name: v.secretif v["key"] != _|_ {key: v.key}if v["key"] == _|_ {key: envName}}}},]}]}}parameter: {// +usage=The mapping of environment variables to secretenvMappings: [string]: [string]: string}
借助这种 service-binding trait,开发人员可以显式设置参数 envMappings,以映射所有环境变量。例子如下。
...traits:- type: service-bindingproperties:envMappings:# environments refer to db-conn secretDB_PASSWORD:secret: db-connkey: password # 1) If the env name is different from secret key, secret key has to be set.endpoint:secret: db-conn # 2) If the env name is the same as the secret key, secret key can be omitted.username:secret: db-conn# environments refer to oss-conn secretBUCKET_NAME:secret: oss-connkey: Bucket...
你可以通过查看 the end user usage workflow 了解其使用方式。