diff --git a/website/source/docs/platform/k8s/service-sync.html.md b/website/source/docs/platform/k8s/service-sync.html.md new file mode 100644 index 0000000000..e47ed8ff89 --- /dev/null +++ b/website/source/docs/platform/k8s/service-sync.html.md @@ -0,0 +1,274 @@ +--- +layout: "docs" +page_title: "Service Sync - Kubernetes" +sidebar_current: "docs-platform-k8s-service-sync" +description: |- + One of the primary query interfaces to Consul is the DNS interface. The Consul DNS interface can be exposed for all pods in Kubernetes using a stub-domain configuration. +--- + +# Syncing Kubernetes and Consul Services + +The services in Kubernetes and Consul can be automatically synced so that Kubernetes +services are available to Consul agents and services in Consul can be available +as first-class Kubernetes services. This functionality is provided by the +[consul-k8s project](https://github.com/hashicorp/consul-k8s) and can be +automatically installed and configured using the +[Consul Helm chart](/docs/platform/k8s/helm.html). + +**Why sync Kubernetes services to Consul?** Kubernetes services synced to the +Consul catalog enable Kubernetes services to be accessed by non-Kubernetes +nodes that are part of the Consul cluster or by other distinct Kubernetes +clusters. For non-Kubernetes nodes, they can access services using the standard +[Consul DNS](/docs/agent/dns.html) or HTTP API. + +**Why sync Consul services to Kubernetes?** Syncing Consul services to +Kubernetes services enables non-Kubernetes services (such as external to +the cluster) to be accessed in a native Kubernetes way: using kube-dns, +environment variables, etc. This makes it very easy to automate external +service discovery, including hosted services like databases. + +## Installation and Configuration + +The service sync is done using an external long-running process in the +[consul-k8s project](https://github.com/hashicorp/consul-k8s). This process +can run both in or out of a Kubernetes cluster. However, running this within +the Kubernetes cluster is generally easier since it is automated using the +[Helm chart](/docs/platform/k8s/helm.html). + +To install the sync, enable the catalog sync feature using +[Helm values](/docs/platform/k8s/helm.html#configuration-values-) and +upgrade the installation using `helm upgrade` for existing installs or +`helm install` for a fresh install. + +```yaml +syncCatalog: + enabled: true +``` + +This will enable services to sync _in both directions_. You can also choose +to only sync Kubernetes services to Consul or vice versa by disabling a direction. +See the [Helm configuration](/docs/platform/k8s/helm.html#configuration-values-) +for more information. + +-> **Before installing,** please read the introduction paragraphs for the +reference documentation below for both +[Kubernetes to Consul](/docs/platform/k8s/service-sync.html#kubernetes-to-consul) and +[Consul to Kubernetes](/docs/platform/k8s/service-sync.html#consul-to-kubernetes) +sync to understand how the syncing works. + +### Authentication + +The sync process must authenticate to both Kubernetes and Consul to read +and write services. + +For Consul, the process accepts both the standard CLI flag `-token` and +the environment variable `CONSUL_HTTP_TOKEN`. This should be set to an +Consul [ACL token](/docs/guides/acl.html) if ACLs are enabled. This +can also be configured using the Helm chart to read from a Kubernetes +secret. + +For Kubernetes, a valid kubeconfig file must be provided with cluster +and auth information. The sync process will look into the default locations +for both in-cluster and out-of-cluster authentication. If `kubectl` works, +then the sync program should work. + +## Kubernetes to Consul + +This sync registers Kubernetes services to the Consul catalog automatically. + +This enables discovery and connection to Kubernetes services using native +Consul service discovery such as DNS or HTTP. This is particularly useful for +non-Kubernetes nodes. This also causes all discoverable services to be part of +a central service catalog in Consul for further syncing into alternate +Kubernetes clusters or other platforms. + +### Kubernetes Service Types + +Not all Kubernetes services are externally accessible. The sync program by +default will only sync services of the following types or configurations. +If a service type is not listed below, then the sync program will ignore that +service type. + +#### NodePort + +[NodePort services](https://kubernetes.io/docs/concepts/services-networking/service/#nodeport) +register a static port that every node in the K8S cluster listens on. + +For NodePort services, a Consul service instance will be created for each +node that has the representative pod running. While Kubernetes configures +a static port on all nodes in the cluster, this limits the number of service +instances to be equal to the nodes running the target pods. + +The service instances registered will be registered to the K8S node name +that each instance lives on. This is guaranteed unique by Kubernetes. An +existing node entry will be used if it is already part of the Consul +cluster (for example if you're running a client agent on all Kubernetes +nodes). This allows the normal agent health checks for that node to continue +working. + +#### LoadBalancer + +For LoadBalancer services, a single service instance will be registered with +the external IP of the created load balancer. Because this is already a load +balancer, only one service instance will be registered with Consul rather +than registering each individual pod endpoint. + +#### External IPs + +Any service type may specify an +"[external IP](https://kubernetes.io/docs/concepts/services-networking/service/#external-ips)" +configuration. The external IP must be configured by some other system, but +any service discovery will resolve to this set of IP addresses rather than a +virtual IP. + +If an external IP list is present, a service instance in Consul will be created +for each external IP. It is assumed that if an external IP is present that it +is routable and configured by some other system. + +### Sync Enable/Disable + +By default, all valid services (as explained above) are synced. This default +can be changed as configuration to the sync process. Syncing can also be +explicitly enabled or disabled using an annotation: + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: my-service + annotations: + "consul.hashicorp.com/service-sync": false +``` + +### Service Name + +When a Kubernetes service is synced to Consul, the name of the service in Consul +by default will be the value of the "name" metadata on that Kubernetes service. +This makes it so that service sync works with zero configuration changes. +This can be overridden using an annotation to specify the Consul service name: + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: my-service + annotations: + "consul.hashicorp.com/service-name": my-consul-service +``` + +**If a conflicting service name exists in Consul,** the sync program will +register additional instances to that same service. Therefore, services inside +and outside of Kubernetes should have different names unless you want either +side to potentially connect. This default behavior also enables gracefully +transitioning a service from outside of K8S to inside, and vice versa. + +### Service Ports + +When syncing the Kubernetes service to Consul, the Consul service port will be +the first defined port in the service. Additionally, all ports will be +registered in the service instance metadata with the key "port-X" where X is +the name of the port and the value is the externally accessible port. + +The default service port can be overridden using an annotation: + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: my-service + annotations: + "consul.hashicorp.com/service-port": "http" +``` + +The annotation value may a name of a port (recommended) or an exact port value. + +### Service Tags + +A service registered in Consul from K8S will always have the tag "k8s" added +to it. Additional tags can be specified with a comma-separated annotation value +as shown below. This will also automatically include the "k8s" tag which can't +be disabled. + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: my-service + annotations: + "consul.hashicorp.com/service-tags": "primary,foo" +``` + +### Service Meta + +A service registered in Consul from K8S will set the `external-source` key to +"kubernetes". This can be used by API consumers, the UI, CLI, etc. to filter +service instances that are set in k8s. The Consul UI (in Consul 1.2.3 and later) +will read this value to show a Kubernetes icon next to all externally +registered services. + +Additional metadata can be specified using annotations. The "KEY" below can be +set to any key. This allows setting multiple meta values: + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: my-service + annotations: + "consul.hashicorp.com/service-meta-KEY": "value" +``` + +## Consul to Kubernetes + +This syncs Consul services into first-class Kubernetes services. +Each Consul service is synced to an +[ExternalName](https://kubernetes.io/docs/concepts/services-networking/service/#externalname) +service in Kubernetes. The external name is configured to be the Consul +DNS entry. + +This enables external services to be discovered using native Kubernetes +tooling. This can be used to ease software migration into or out of Kubernetes, +across platforms, to and from hosted services, and more. + +-> **Requires Consul DNS in Kubernetes:** This feature requires that +[Consul DNS](/docs/platform/k8s/dns.html) is configured within Kubernetes. +In the future we hope to remove this requirement by syncing the instance +addresses directly into service endpoints. + +### Sync Enable/Disable + +All Consul services visible with the given Consul ACL token to the sync process +will be synced to Kubernetes. + +There is no way to change this behavior per service. For the opposite sync +direction (Kubernetes to Consul), you can use Kubernetes annotations to disable +a sync per service. This is not currently possible for Consul to Kubernetes +sync and the ACL token must be used to limit what services are synced. + +In the future, we hope to support per-service configuration. + +### Service Name + +When a Consul service is synced to Kubernetes, the name of the Kubernetes +service will match exactly within Kubernetes. + +A service name prefix can be specified to the sync program. If specified, this +prefix will be attached to Consul services within Kubernetes. This defaults to +no prefix. The prefix can be specified using the `-k8s-service-prefix` flag +and can also be specified using Helm configuration. + +**If a conflicting service is found,** the service will not be synced. This +does not match the Kubernetes to Consul behavior, but given the current +implementation we must do this because Kubernetes can't mix both CNAME and +Endpoint-based services. + +### Kubernetes Service Labels and Annotations + +Any Consul services synced to Kubernetes will be labeled and annotated. +An annotation `consul.hashicorp.com/synced` will be set to "true" to note +that this is a synced service from Consul. + +Additionally, a label `consul=true` will be specified so that label selectors +can be used with `kubectl` and other tooling to easily filter all Consul-synced +services. + diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 056c553e66..372f8de59b 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -311,6 +311,9 @@