networking/v1alpha3/service_entry.proto (638 lines of code) (raw):

// Copyright 2018 Istio Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; import "google/api/field_behavior.proto"; import "networking/v1alpha3/sidecar.proto"; import "networking/v1alpha3/workload_entry.proto"; import "analysis/v1alpha1/message.proto"; import "meta/v1alpha1/status.proto"; // $schema: istio.networking.v1alpha3.ServiceEntry // $title: Service Entry // $description: Configuration affecting service registry. // $location: https://istio.io/docs/reference/config/networking/service-entry.html // $aliases: [/docs/reference/config/networking/v1alpha3/service-entry] // `ServiceEntry` enables adding additional entries into Istio's // internal service registry, so that auto-discovered services in the // mesh can access/route to these manually specified services. A // service entry describes the properties of a service (DNS name, // VIPs, ports, protocols, endpoints). These services could be // external to the mesh (e.g., web APIs) or mesh-internal services // that are not part of the platform's service registry (e.g., a set // of VMs talking to services in Kubernetes). In addition, the // endpoints of a service entry can also be dynamically selected by // using the `workloadSelector` field. These endpoints can be VM // workloads declared using the `WorkloadEntry` object or Kubernetes // pods. The ability to select both pods and VMs under a single // service allows for migration of services from VMs to Kubernetes // without having to change the existing DNS names associated with the // services. // // The following example declares a few external APIs accessed by internal // applications over HTTPS. The sidecar inspects the SNI value in the // ClientHello message to route to the appropriate external service. // // ```yaml // apiVersion: networking.istio.io/v1 // kind: ServiceEntry // metadata: // name: external-svc-https // spec: // hosts: // - api.dropboxapi.com // - www.googleapis.com // - api.facebook.com // location: MESH_EXTERNAL // ports: // - number: 443 // name: https // protocol: TLS // resolution: DNS // ``` // // The following configuration adds a set of MongoDB instances running on // unmanaged VMs to Istio's registry, so that these services can be treated // as any other service in the mesh. The associated DestinationRule is used // to initiate mTLS connections to the database instances. // // ```yaml // apiVersion: networking.istio.io/v1 // kind: ServiceEntry // metadata: // name: external-svc-mongocluster // spec: // hosts: // - mymongodb.somedomain # not used // addresses: // - 192.192.192.192/24 # VIPs // ports: // - number: 27018 // name: mongodb // protocol: MONGO // location: MESH_INTERNAL // resolution: STATIC // endpoints: // - address: 2.2.2.2 // - address: 3.3.3.3 // ``` // // and the associated DestinationRule // // ```yaml // apiVersion: networking.istio.io/v1 // kind: DestinationRule // metadata: // name: mtls-mongocluster // spec: // host: mymongodb.somedomain // trafficPolicy: // tls: // mode: MUTUAL // clientCertificate: /etc/certs/myclientcert.pem // privateKey: /etc/certs/client_private_key.pem // caCertificates: /etc/certs/rootcacerts.pem // ``` // // The following example uses a combination of service entry and TLS // routing in a virtual service to steer traffic based on the SNI value to // an internal egress firewall. // // ```yaml // apiVersion: networking.istio.io/v1 // kind: ServiceEntry // metadata: // name: external-svc-redirect // spec: // hosts: // - wikipedia.org // - "*.wikipedia.org" // location: MESH_EXTERNAL // ports: // - number: 443 // name: https // protocol: TLS // resolution: NONE // ``` // // And the associated VirtualService to route based on the SNI value. // // ```yaml // apiVersion: networking.istio.io/v1 // kind: VirtualService // metadata: // name: tls-routing // spec: // hosts: // - wikipedia.org // - "*.wikipedia.org" // tls: // - match: // - sniHosts: // - wikipedia.org // - "*.wikipedia.org" // route: // - destination: // host: internal-egress-firewall.ns1.svc.cluster.local // ``` // // The virtual service with TLS match serves to override the default SNI // match. In the absence of a virtual service, traffic will be forwarded to // the wikipedia domains. // // The following example demonstrates the use of a dedicated egress gateway // through which all external service traffic is forwarded. // The 'exportTo' field allows for control over the visibility of a service // declaration to other namespaces in the mesh. By default, a service is exported // to all namespaces. The following example restricts the visibility to the // current namespace, represented by ".", so that it cannot be used by other // namespaces. // // ```yaml // apiVersion: networking.istio.io/v1 // kind: ServiceEntry // metadata: // name: external-svc-httpbin // namespace : egress // spec: // hosts: // - example.com // exportTo: // - "." // location: MESH_EXTERNAL // ports: // - number: 80 // name: http // protocol: HTTP // resolution: DNS // ``` // // Define a gateway to handle all egress traffic. // // ```yaml // apiVersion: networking.istio.io/v1 // kind: Gateway // metadata: // name: istio-egressgateway // namespace: istio-system // spec: // selector: // istio: egressgateway // servers: // - port: // number: 80 // name: http // protocol: HTTP // hosts: // - "*" // ``` // // And the associated `VirtualService` to route from the sidecar to the // gateway service (`istio-egressgateway.istio-system.svc.cluster.local`), as // well as route from the gateway to the external service. Note that the // virtual service is exported to all namespaces enabling them to route traffic // through the gateway to the external service. Forcing traffic to go through // a managed middle proxy like this is a common practice. // // ```yaml // apiVersion: networking.istio.io/v1 // kind: VirtualService // metadata: // name: gateway-routing // namespace: egress // spec: // hosts: // - example.com // exportTo: // - "*" // gateways: // - mesh // - istio-egressgateway // http: // - match: // - port: 80 // gateways: // - mesh // route: // - destination: // host: istio-egressgateway.istio-system.svc.cluster.local // - match: // - port: 80 // gateways: // - istio-egressgateway // route: // - destination: // host: example.com // ``` // // The following example demonstrates the use of wildcards in the hosts for // external services. If the connection has to be routed to the IP address // requested by the application (i.e. application resolves DNS and attempts // to connect to a specific IP), the resolution mode must be set to `NONE`. // // ```yaml // apiVersion: networking.istio.io/v1 // kind: ServiceEntry // metadata: // name: external-svc-wildcard-example // spec: // hosts: // - "*.bar.com" // location: MESH_EXTERNAL // ports: // - number: 80 // name: http // protocol: HTTP // resolution: NONE // ``` // // The following example demonstrates a service that is available via a // Unix Domain Socket on the host of the client. The resolution must be // set to STATIC to use Unix address endpoints. // // ```yaml // apiVersion: networking.istio.io/v1 // kind: ServiceEntry // metadata: // name: unix-domain-socket-example // spec: // hosts: // - "example.unix.local" // location: MESH_EXTERNAL // ports: // - number: 80 // name: http // protocol: HTTP // resolution: STATIC // endpoints: // - address: unix:///var/run/example/socket // ``` // // For HTTP-based services, it is possible to create a `VirtualService` // backed by multiple DNS addressable endpoints. In such a scenario, the // application can use the `HTTP_PROXY` environment variable to transparently // reroute API calls for the `VirtualService` to a chosen backend. For // example, the following configuration creates a non-existent external // service called foo.bar.com backed by three domains: us.foo.bar.com:8080, // uk.foo.bar.com:9080, and in.foo.bar.com:7080 // // ```yaml // apiVersion: networking.istio.io/v1 // kind: ServiceEntry // metadata: // name: external-svc-dns // spec: // hosts: // - foo.bar.com // location: MESH_EXTERNAL // ports: // - number: 80 // name: http // protocol: HTTP // resolution: DNS // endpoints: // - address: us.foo.bar.com // ports: // http: 8080 // - address: uk.foo.bar.com // ports: // http: 9080 // - address: in.foo.bar.com // ports: // http: 7080 // ``` // // With `HTTP_PROXY=http://localhost/`, calls from the application to // `http://foo.bar.com` will be load balanced across the three domains // specified above. In other words, a call to `http://foo.bar.com/baz` would // be translated to `http://uk.foo.bar.com/baz`. // // The following example illustrates the usage of a `ServiceEntry` // containing a subject alternate name // whose format conforms to the [SPIFFE standard](https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md): // // ```yaml // apiVersion: networking.istio.io/v1 // kind: ServiceEntry // metadata: // name: httpbin // namespace : httpbin-ns // spec: // hosts: // - example.com // location: MESH_INTERNAL // ports: // - number: 80 // name: http // protocol: HTTP // resolution: STATIC // endpoints: // - address: 2.2.2.2 // - address: 3.3.3.3 // subjectAltNames: // - "spiffe://cluster.local/ns/httpbin-ns/sa/httpbin-service-account" // ``` // // The following example demonstrates the use of `ServiceEntry` with a // `workloadSelector` to handle the migration of a service // `details.bookinfo.com` from VMs to Kubernetes. The service has two // VM-based instances with sidecars as well as a set of Kubernetes // pods managed by a standard deployment object. Consumers of this // service in the mesh will be automatically load balanced across the // VMs and Kubernetes. // // ```yaml // apiVersion: networking.istio.io/v1 // kind: WorkloadEntry // metadata: // name: details-vm-1 // spec: // serviceAccount: details // address: 2.2.2.2 // labels: // app: details // instance-id: vm1 // --- // apiVersion: networking.istio.io/v1 // kind: WorkloadEntry // metadata: // name: details-vm-2 // spec: // serviceAccount: details // address: 3.3.3.3 // labels: // app: details // instance-id: vm2 // ``` // // Assuming there is also a Kubernetes deployment with pod labels // `app: details` using the same service account `details`, the // following service entry declares a service spanning both VMs and // Kubernetes: // // ```yaml // apiVersion: networking.istio.io/v1 // kind: ServiceEntry // metadata: // name: details-svc // spec: // hosts: // - details.bookinfo.com // location: MESH_INTERNAL // ports: // - number: 80 // name: http // protocol: HTTP // resolution: STATIC // workloadSelector: // labels: // app: details // ``` package istio.networking.v1alpha3; option go_package = "istio.io/api/networking/v1alpha3"; // ServiceEntry enables adding additional entries into Istio's internal // service registry. // // <!-- crd generation tags // +cue-gen:ServiceEntry:groupName:networking.istio.io // +cue-gen:ServiceEntry:versions:v1beta1,v1alpha3,v1 // +cue-gen:ServiceEntry:annotations:helm.sh/resource-policy=keep // +cue-gen:ServiceEntry:labels:app=istio-pilot,chart=istio,heritage=Tiller,release=istio // +cue-gen:ServiceEntry:subresource:status // +cue-gen:ServiceEntry:scope:Namespaced // +cue-gen:ServiceEntry:resource:categories=istio-io,networking-istio-io,shortNames=se,plural=serviceentries // +cue-gen:ServiceEntry:printerColumn:name=Hosts,type=string,JSONPath=.spec.hosts,description="The hosts associated with the ServiceEntry" // +cue-gen:ServiceEntry:printerColumn:name=Location,type=string,JSONPath=.spec.location,description="Whether the service is external to the // mesh or part of the mesh (MESH_EXTERNAL or MESH_INTERNAL)" // +cue-gen:ServiceEntry:printerColumn:name=Resolution,type=string,JSONPath=.spec.resolution,description="Service resolution mode for the hosts // (NONE, STATIC, or DNS)" // +cue-gen:ServiceEntry:printerColumn:name=Age,type=date,JSONPath=.metadata.creationTimestamp,description="CreationTimestamp is a timestamp // representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. // Clients may not set this value. It is represented in RFC3339 form and is in UTC. // Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" // +cue-gen:ServiceEntry:preserveUnknownFields:false // +cue-gen:ServiceEntry:spec:required // --> // // <!-- go code generation tags // +kubetype-gen // +kubetype-gen:groupVersion=networking.istio.io/v1alpha3 // +genclient // +k8s:deepcopy-gen=true // istiostatus-override: ServiceEntryStatus: istio.io/api/networking/v1alpha3 // --> // +kubebuilder:validation:XValidation:message="only one of WorkloadSelector or Endpoints can be set",rule="(has(self.workloadSelector)?1:0)+(has(self.endpoints)?1:0)<=1" // +kubebuilder:validation:XValidation:message="CIDR addresses are allowed only for NONE/STATIC resolution types",rule="!(has(self.addresses) && self.addresses.exists(k, k.contains('/')) && (has(self.resolution) && self.resolution != 'STATIC' && self.resolution != 'NONE'))" // +kubebuilder:validation:XValidation:message="NONE mode cannot set endpoints",rule="(!has(self.resolution) || self.resolution == 'NONE') ? !has(self.endpoints) : true" // +kubebuilder:validation:XValidation:message="DNS_ROUND_ROBIN mode cannot have multiple endpoints",rule="(has(self.resolution) && self.resolution == 'DNS_ROUND_ROBIN') ? (!has(self.endpoints) || size(self.endpoints) == 1) : true" message ServiceEntry { // The hosts associated with the ServiceEntry. Could be a DNS // name with wildcard prefix. // // 1. The hosts field is used to select matching hosts in VirtualServices and DestinationRules. // 2. For HTTP traffic the HTTP Host/Authority header will be matched against the hosts field. // 3. For HTTPs or TLS traffic containing Server Name Indication (SNI), the SNI value // will be matched against the hosts field. // // **NOTE 1:** When resolution is set to type DNS and no endpoints // are specified, the host field will be used as the DNS name of the // endpoint to route traffic to. // // **NOTE 2:** If the hostname matches with the name of a service // from another service registry such as Kubernetes that also // supplies its own set of endpoints, the ServiceEntry will be // treated as a decorator of the existing Kubernetes // service. Properties in the service entry will be added to the // Kubernetes service if applicable. Currently, only the following // additional properties will be considered by `istiod`: // // 1. subjectAltNames: In addition to verifying the SANs of the // service accounts associated with the pods of the service, the // SANs specified here will also be verified. // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=256 // +protoc-gen-crd:list-value-validation:XValidation:message="hostname cannot be wildcard",rule="self != '*'" repeated string hosts = 1 [(google.api.field_behavior) = REQUIRED]; // The virtual IP addresses associated with the service. Could be CIDR // prefix. For HTTP traffic, generated route configurations will include http route // domains for both the `addresses` and `hosts` field values and the destination will // be identified based on the HTTP Host/Authority header. // If one or more IP addresses are specified, // the incoming traffic will be identified as belonging to this service // if the destination IP matches the IP/CIDRs specified in the addresses // field. If the Addresses field is empty, traffic will be identified // solely based on the destination port. In such scenarios, the port on // which the service is being accessed must not be shared by any other // service in the mesh. In other words, the sidecar will behave as a // simple TCP proxy, forwarding incoming traffic on a specified port to // the specified destination endpoint IP/host. Unix domain socket // addresses are not supported in this field. // +kubebuilder:validation:MaxItems=256 // +protoc-gen-crd:list-value-validation:MaxLength=64 repeated string addresses = 2; // The ports associated with the external service. If the // Endpoints are Unix domain socket addresses, there must be exactly one // port. // +listType=map // +listMapKey=name // +kubebuilder:validation:MaxItems=256 // +kubebuilder:validation:XValidation:message="port number cannot be duplicated",rule="self.all(l1, self.exists_one(l2, l1.number == l2.number))" repeated ServicePort ports = 3; // Location specifies whether the service is part of Istio mesh or // outside the mesh. Location determines the behavior of several // features, such as service-to-service mTLS authentication, policy // enforcement, etc. When communicating with services outside the mesh, // Istio's mTLS authentication is disabled, and policy enforcement is // performed on the client-side as opposed to server-side. enum Location { // Signifies that the service is external to the mesh. Typically used // to indicate external services consumed through APIs. MESH_EXTERNAL = 0; // Signifies that the service is part of the mesh. Typically used to // indicate services added explicitly as part of expanding the service // mesh to include unmanaged infrastructure (e.g., VMs added to a // Kubernetes based service mesh). MESH_INTERNAL = 1; }; // Specify whether the service should be considered external to the mesh // or part of the mesh. Location location = 4; // Resolution determines how the proxy will resolve the IP addresses of // the network endpoints associated with the service, so that it can // route to one of them. The resolution mode specified here has no impact // on how the application resolves the IP address associated with the // service. The application may still have to use DNS to resolve the // service to an IP so that the outbound traffic can be captured by the // Proxy. Alternatively, for HTTP services, the application could // directly communicate with the proxy (e.g., by setting HTTP_PROXY) to // talk to these services. enum Resolution { // Assume that incoming connections have already been resolved (to a // specific destination IP address). Such connections are typically // routed via the proxy using mechanisms such as IP table REDIRECT/ // eBPF. After performing any routing related transformations, the // proxy will forward the connection to the IP address to which the // connection was bound. NONE = 0; // Use the static IP addresses specified in endpoints (see below) as the // backing instances associated with the service. STATIC = 1; // Attempt to resolve the IP address by querying the ambient DNS, // asynchronously. If no endpoints are specified, the proxy // will resolve the DNS address specified in the hosts field, if // wildcards are not used. If endpoints are specified, the DNS // addresses specified in the endpoints will be resolved to determine // the destination IP address. DNS resolution cannot be used with Unix // domain socket endpoints. DNS = 2; // Attempt to resolve the IP address by querying the ambient DNS, // asynchronously. Unlike `DNS`, `DNS_ROUND_ROBIN` only uses the // first IP address returned when a new connection needs to be initiated // without relying on complete results of DNS resolution, and connections // made to hosts will be retained even if DNS records change frequently // eliminating draining connection pools and connection cycling. // This is best suited for large web scale services that // must be accessed via DNS. The proxy will resolve the DNS address // specified in the hosts field, if wildcards are not used. DNS resolution // cannot be used with Unix domain socket endpoints. DNS_ROUND_ROBIN = 3; }; // Service resolution mode for the hosts. Care must be taken // when setting the resolution mode to NONE for a TCP port without // accompanying IP addresses. In such cases, traffic to any IP on // said port will be allowed (i.e. `0.0.0.0:<port>`). Resolution resolution = 5; // One or more endpoints associated with the service. Only one of // `endpoints` or `workloadSelector` can be specified. // +kubebuilder:validation:MaxItems=4096 repeated WorkloadEntry endpoints = 6; // Applicable only for MESH_INTERNAL services. Only one of // `endpoints` or `workloadSelector` can be specified. Selects one // or more Kubernetes pods or VM workloads (specified using // `WorkloadEntry`) based on their labels. The `WorkloadEntry` object // representing the VMs should be defined in the same namespace as // the ServiceEntry. WorkloadSelector workload_selector = 9; // A list of namespaces to which this service is exported. Exporting a service // allows it to be used by sidecars, gateways and virtual services defined in // other namespaces. This feature provides a mechanism for service owners // and mesh administrators to control the visibility of services across // namespace boundaries. // // If no namespaces are specified then the service is exported to all // namespaces by default. // // The value "." is reserved and defines an export to the same namespace that // the service is declared in. Similarly the value "*" is reserved and // defines an export to all namespaces. // // For a Kubernetes Service, the equivalent effect can be achieved by setting // the annotation "networking.istio.io/exportTo" to a comma-separated list // of namespace names. repeated string export_to = 7; // If specified, the proxy will verify that the server certificate's // subject alternate name matches one of the specified values. // // NOTE: When using the workloadEntry with workloadSelectors, the // service account specified in the workloadEntry will also be used // to derive the additional subject alternate names that should be // verified. repeated string subject_alt_names = 8; } // ServicePort describes the properties of a specific port of a service. message ServicePort { // A valid non-negative integer port number. // +kubebuilder:validation:XValidation:message="port must be between 1-65535",rule="0 < self && self <= 65535" uint32 number = 1 [(google.api.field_behavior) = REQUIRED]; // The protocol exposed on the port. // MUST BE one of HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP|TLS. // TLS implies the connection will be routed based on the SNI header to // the destination without terminating the TLS connection. // +kubebuilder:validation:MaxLength=256 string protocol = 2; // Label assigned to the port. // +kubebuilder:validation:MaxLength=256 string name = 3 [(google.api.field_behavior) = REQUIRED]; // The port number on the endpoint where the traffic will be // received. If unset, default to `number`. // +kubebuilder:validation:XValidation:message="port must be between 1-65535",rule="0 < self && self <= 65535" uint32 target_port = 4; } message ServiceEntryStatus { // Current service state of ServiceEntry. // More info: https://istio.io/docs/reference/config/config-status/ // +optional // +patchMergeKey=type // +patchStrategy=merge repeated meta.v1alpha1.IstioCondition conditions = 1; // Includes any errors or warnings detected by Istio's analyzers. // +optional // +patchMergeKey=type // +patchStrategy=merge repeated analysis.v1alpha1.AnalysisMessageBase validation_messages = 2; // Resource Generation to which the Reconciled Condition refers. // When this value is not equal to the object's metadata generation, reconciled condition calculation for the current // generation is still in progress. See https://istio.io/latest/docs/reference/config/config-status/ for more info. // +optional int64 observed_generation = 3; // Above this is just a copy of the common IstioStatus since proto cannot embed an anonymous message whole cloth // List of addresses which were assigned to this ServiceEntry. // +optional repeated ServiceEntryAddress addresses = 10; } // minor abstraction to allow for adding hostnames if relevant message ServiceEntryAddress{ // Value is the address (192.168.0.2) string value = 1; // Host is the name associated with this address string host = 2; }