Cluster Peering on Kubernetes

    To establish a cluster peering connection on Kubernetes, you need to enable the feature in the Helm chart and create custom resource definitions for each side of the peering.

    The following Custom Resource Definitions (CRDs) are used to create and manage a peering connection:

    • PeeringAcceptor: Generates a peering token and accepts an incoming peering connection.
    • : Uses a peering token to make an outbound peering connection with the cluster that generated the token.

    You must implement the following requirements to create and use cluster peering connections with Kubernetes:

    • Consul 1.13 Alpha 2 or later
    • At least two Kubernetes clusters
    • The Kubernetes clusters must be running in a flat network
    • The network must be running on Consul on Kubernetes v.0.45 or later

    To establish cluster peering through Kubernetes, deploy clusters with the following Helm values.

    values.yaml

    1. image: "hashicorp/consul:1.13.0-alpha2"
    2. peering:
    3. enabled: true
    4. connectInject:
    5. enabled: true
    6. meshGateway:
    7. enabled: true
    8. replicas: 1

    Install Consul on Kubernetes on each Kubernetes cluster by applying values.yaml using the Helm CLI.

    1. $ export HELM_RELEASE_NAME=cluster-name
    1. $ export HELM_RELEASE_NAME=cluster-name
    1. $ helm install ${HELM_RELEASE_NAME} hashicorp/consul --version "0.45.0" --values values.yaml
    1. $ helm install ${HELM_RELEASE_NAME} hashicorp/consul --version "0.45.0" --values values.yaml

    To peer Kubernetes clusters running Consul, you need to create a peering token and share it with the other cluster.

    1. In cluster-01, create the PeeringAcceptor custom resource.

      1. apiVersion: consul.hashicorp.com/v1alpha1
      2. kind: PeeringAcceptor
      3. metadata:
      4. name: cluster-02 ## The name of the peer you want to connect to
      5. spec:
      6. peer:
      7. secret:
      8. name: "peering-token"
      9. key: "data"
      10. backend: "kubernetes"

      Cluster Peering on Kubernetes - 图2

      acceptor.yml

      1. apiVersion: consul.hashicorp.com/v1alpha1
      2. kind: PeeringAcceptor
      3. metadata:
      4. name: cluster-02 ## The name of the peer you want to connect to
      5. spec:
      6. peer:
      7. secret:
      8. name: "peering-token"
      9. key: "data"
      10. backend: "kubernetes"
      1. $ kubectl apply --filename acceptor.yml
      1. $ kubectl apply --filename acceptor.yml
    2. Save your peering token so that you can export it to the other cluster.

      1. $ kubectl get secret peering-token --output yaml > peering-token.yml
      1. $ kubectl get secret peering-token --output yaml > peering-token.yml
    3. Apply the peering token to the second cluster.

      1. $ kubectl apply --filename peering-token.yml
    4. In “cluster-02,” create the PeeringDialer custom resource.

      1. apiVersion: consul.hashicorp.com/v1alpha1
      2. kind: PeeringDialer
      3. name: cluster-01 ## The name of the peer you want to connect to
      4. spec:
      5. peer:
      6. secret:
      7. name: "peering-token"
      8. key: "data"

      dialer.yml

      1. apiVersion: consul.hashicorp.com/v1alpha1
      2. kind: PeeringDialer
      3. metadata:
      4. name: cluster-01 ## The name of the peer you want to connect to
      5. spec:
      6. peer:
      7. secret:
      8. name: "peering-token"
      9. key: "data"
      10. backend: "kubernetes"
    5. Apply the PeeringDialer resource to the second cluster.

      1. $ kubectl apply --filename dialer.yml
      1. $ kubectl apply --filename dialer.yml
    1. For the service in “cluster-02” that you want to export, add the following annotations to your service’s pods. This service is referred to as “backend-service” in the following steps.

      1. ##…
      2. annotations:
      3. "consul.hashicorp.com/connect-inject": "true"
      4. "consul.hashicorp.com/transparent-proxy": "false"
      5. ##…

      Cluster Peering on Kubernetes - 图4

      backend-service.yml

      1. ##…
      2. annotations:
      3. "consul.hashicorp.com/connect-inject": "true"
      4. "consul.hashicorp.com/transparent-proxy": "false"
      5. ##…
    2. In “cluster-02,” create an ExportedServices custom resource.

      1. apiVersion: consul.hashicorp.com/v1alpha1
      2. kind: ExportedServices
      3. metadata:
      4. name: default ## The name of the partition containing the service
      5. spec:
      6. services:
      7. name: backend-service ## The name of the service you want to export
      8. consumers:
      9. peerName: cluster-01 ## The name of the peer that receives the service

      1. apiVersion: consul.hashicorp.com/v1alpha1
      2. kind: ExportedServices
      3. metadata:
      4. name: default ## The name of the partition containing the service
      5. spec:
      6. services:
      7. name: backend-service ## The name of the service you want to export
      8. consumers:
      9. peerName: cluster-01 ## The name of the peer that receives the service
    3. Create service intentions for the second cluster.

      1. apiVersion: consul.hashicorp.com/v1alpha1
      2. kind: ServiceIntentions
      3. metadata:
      4. name: backend-deny
      5. spec:
      6. name: backend-service
      7. sources:
      8. - name: "*"
      9. - name: frontend-service
      10. action: allow

      Cluster Peering on Kubernetes - 图6

      intention.yml

      1. apiVersion: consul.hashicorp.com/v1alpha1
      2. kind: ServiceIntentions
      3. metadata:
      4. name: backend-deny
      5. spec:
      6. destination:
      7. name: backend-service
      8. sources:
      9. - name: "*"
      10. action: deny
      11. - name: frontend-service
      12. action: allow
    4. Apply the service file, the ExportedServices resource, and the intentions to the second cluster.

      1. $ kubectl apply --filename backend-service.yml --filename exportedsvc.yml --filename intention.yml
    5. To confirm that you peered your clusters, in “cluster-01,” query the /health HTTP endpoint.

      1. $ curl "localhost:8500/v1/health/connect/backend?peer=cluster-02"
      1. $ curl "localhost:8500/v1/health/connect/backend?peer=cluster-02"
    6. For the services in “cluster-01” that you want to access the “backend-service,” add the following annotations to the service file.

      1. ##…
      2. annotations:
      3. "consul.hashicorp.com/connect-inject": "true"
      4. "consul.hashicorp.com/transparent-proxy": "false"
      5. "consul.hashicorp.com/connect-service-upstreams": "backend-service.svc.cluster-02.peer:1234"
      6. ##…

      frontend-service.yml

      1. ##…
      2. annotations:
      3. "consul.hashicorp.com/connect-inject": "true"
      4. "consul.hashicorp.com/transparent-proxy": "false"
      5. "consul.hashicorp.com/connect-service-upstreams": "backend-service.svc.cluster-02.peer:1234"
      6. ##…
    7. Apply the service file to the first cluster.

      1. $ kubectl apply --filename frontend-service.yml
      1. $ kubectl apply --filename frontend-service.yml
    8. Run the following command and check the output to confirm that you peered your clusters successfully.

      1. $ curl localhost:1234
      2. {
      3. name”: backend-service”,
      4. ##…
      5. body”: Response from backend”,
      6. code”: 200
      7. }
      1. $ curl localhost:1234
      2. {
      3. name”: backend-service”,
      4. ##…
      5. body”: Response from backend”,
      6. code”: 200
      7. }

    To end a peering connection, delete both the PeeringAcceptor and PeeringDialer resources.

    1. $ curl "localhost:8500/v1/health/connect/backend?peer=cluster-02"