github.com/oam-dev/kubevela@v1.9.11/design/vela-core/route.md (about) 1 # Route Trait Design 2 3 The main idea of [route trait](https://github.com/oam-dev/catalog/tree/master/traits/routetrait) is to let users have an entrypoint to visit their App. 4 5 In k8s world, if you want to do so, you have to understand K8s [Service](https://kubernetes.io/docs/concepts/services-networking/service/) 6 , [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/), [Ingress Controllers](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/). 7 It's not easy to get all of these things work well. 8 9 The route trait will help you setup service, ingress automatically according your workload, along with the mTLS enabled. 10 11 The schema is also clean and easy to understand. 12 13 ```go 14 15 // RouteSpec defines the desired state of Route 16 type RouteSpec struct { 17 // WorkloadReference to the workload whose metrics needs to be exposed 18 WorkloadReference corev1.ObjectReference `json:"workloadRef,omitempty"` 19 20 // Host is the host of the route 21 Host string `json:"host"` 22 23 // TLS indicate route trait will create SSL secret using cert-manager with specified issuer 24 // If this is nil, route trait will use a selfsigned issuer 25 TLS *TLS `json:"tls,omitempty"` 26 27 // Rules contain multiple rules of route 28 Rules []Rule `json:"rules"` 29 30 // Provider indicate which ingress controller implementation the route trait will use, by default it's nginx-ingress 31 Provider string `json:"provider,omitempty"` 32 33 // IngressClass indicate which ingress class the route trait will use, by default it's nginx 34 IngressClass string `json:"ingressClass,omitempty"` 35 } 36 37 // Rule defines to route rule 38 type Rule struct { 39 // Path is location Path, default for "/" 40 Path string `json:"path,omitempty"` 41 42 43 // RewriteTarget will rewrite request from Path to RewriteTarget path. 44 RewriteTarget string `json:"rewriteTarget,omitempty"` 45 46 // CustomHeaders pass a custom list of headers to the backend service. 47 CustomHeaders map[string]string `json:"customHeaders,omitempty"` 48 49 // DefaultBackend will become the ingress default backend if the backend is not available 50 DefaultBackend corev1.ObjectReference `json:"defaultBackend,omitempty"` 51 52 // Backend indicate how to connect backend service 53 // If it's nil, will auto discovery 54 Backend *Backend `json:"backend,omitempty"` 55 } 56 57 type TLS struct { 58 IssuerName string `json:"issuerName,omitempty"` 59 60 // Type indicate the issuer is ClusterIssuer or NamespaceIssuer 61 Type IssuerType `json:"type,omitempty"` 62 } 63 64 type IssuerType string 65 66 const ( 67 ClusterIssuer IssuerType = "ClusterIssuer" 68 NamespaceIssuer IssuerType = "Issuer" 69 ) 70 71 // Route will automatically discover podSpec and label for BackendService. 72 // If BackendService is already set, discovery won't work. 73 // If BackendService is not set, the discovery mechanism will work. 74 type Backend struct { 75 // ReadTimeout used for setting read timeout duration for backend service, the unit is second. 76 ReadTimeout int `json:"readTimeout,omitempty"` 77 // SendTimeout used for setting send timeout duration for backend service, the unit is second. 78 SendTimeout int `json:"sendTimeout,omitempty"` 79 // BackendService specifies the backend K8s service and port 80 BackendService *BackendServiceRef `json:"backendService,omitempty"` 81 } 82 83 type BackendServiceRef struct { 84 // Port allow you direct specify backend service port. 85 Port intstr.IntOrString `json:"port,omitempty"` 86 // ServiceName allow you direct specify K8s service for backend service. 87 ServiceName string `json:"serviceName,omitempty"` 88 } 89 ``` 90 91 Route Trait specifies a target workload by using `workloadRef`, in OAM system, this field will be filled automatically 92 by OAM runtime. 93 94 Besides `workloadRef`, one Route will have only one `host` and many rules. `host` is actually your app's visiting URL. 95 It's required and will be used to generate mTLS secrets. 96 97 Route Trait designed to be compatible with different ingress controller implementations, the `provider` field will allow 98 you to give a specified ingress controller type. The `ingressClass` field will allow you to set the ingressClass. 99 Currently, only nginx-ingress is supported. 100 101 The `tls` field allow you to specify a TLS for this route with an IssuerName, the IssuerName pointing to an [Issuer Object](https://cert-manager.io/docs/concepts/issuer/) 102 created by cert-manager. Cert-manager and ingress controller will handle certificate creation and binding. 103 104 Currently, vela-cli will create an Issuer Object automatically by using the email defined in `vela init` workflow. 105 106 ```yaml 107 apiVersion: cert-manager.io/v1 108 kind: Issuer 109 metadata: 110 name: oam-env-<env.name> 111 namespace: <env.namespace> 112 spec: 113 acme: 114 # Email address used for ACME registration 115 email: <env.email> 116 # The ACME server URL 117 server: https://acme-v02.api.letsencrypt.org/directory 118 # Name of a secret used to store the ACME account private key, the key will be automatically created by cert-manager 119 privateKeySecretRef: 120 name: oam-env-<env.name>.key 121 # Enable the HTTP-01 challenge provider, there are many other solvers besides http01. 122 solvers: 123 - http01: 124 ingress: 125 class: nginx 126 ``` 127 128 If `tls` field in route trait not specified, mTLS will be disabled by default. You can also manually configure ingress later. 129 130 If no rule specified, route trait will create one rule automatically and match with the port. 131 132 For every rule, we will create an ingress. In the rule, you could specify `path`, `rewriteTarget`, `customHeaders` 133 and `defaultBackend`. All rules will using the same `tls`, `host` and `provider`. 134 135 `defaultBackend` will become the ingress default backend with K8s Object(apiVersion/kind/name). 136 137 `backend` of the rule is completely optional. 138 139 If backendService is specified, it will use it as backend of this rule. If not, 140 the route trait can automatically discovery backend settings from workload. 141 142 ## Discovery mechanism 143 144 1. Check ChildResource of the workload, if there already has an existing K8s service match the Backend port, use it. 145 2. If there's no k8s service, this means we need to create one. In order to create K8s service, we need two information 146 `Container Port` and `Pod SelectorLabels`. 147 - 2.1 Use [`PodSpecable` mechanism](https://github.com/crossplane/oam-kubernetes-runtime/blob/master/design/one-pager-podspecable-workload.md), 148 route trait will check `WorkloadDefinition` for podSpec field, with the `podSpec` field, we can easily find the container port. 149 * If podSpecPath` is specified, we will use the workload labels as `Pod SelectorLabels`. 150 * If `workload.oam.dev/podspecable: true` but no `podSpecPath`, will use `spec.Template` as `PodTemplate`, which means 151 we can get `Pod SelectorLabels` from `spec.Template.Labels`. 152 - 2.2 Use ChildResource: If No `PodSpecable` mechanism found in workload, we will continue discovery child resources of workload. If there 153 is a valid `PodTemplate` structure in child resource, we will regard it as discovery target, use the same strategy like 154 `workload.oam.dev/podspecable: true` but no `podSpecPath`.