Multi-cloud support is the same as multi-cluster support. No additional components or specific installation is required to enable multi-cluster, simply install the Gateway controller in each cluster.
The EPIC Gateway template and EPIC Gateway configuration includes the configuration object can-be-shared. This is set in the EPIC Gateway, it cannot be set from the cluster GatewayAPI. When set to true the gateway can be shared.
The screenshot above shows the Gateway Templates in the Gateway Service Manager, note the gatewayhttps and istiohttps are show as Multi-cluster true reflecting can-be-shared: true in the template.
A Gateway constructed from a set of resources.
graph LR A[gatewayClassConfig] --> B B[gatewayClass] --> C C[gateway] --> D D["route (httpRoute)"] --> E E[service]
The initial cluster Gateway resource and EPIC Gateway are created, then the subsequent cluster Gateway resources. In each cluster the gatewayClassConfig and gatewayClass should be the same. These names are not used by EPIC in the process of merging the gateway and its routes, but are enforced to make it easier to troubleshoot and display in the EPIC Console.
The existing EPIC Gateway to be shared is referenced by it EPIC Gateway UUID. This
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
annotations:
acnodal.io/epic-config: epic-gateway/uswest-gtwapi
acnodal.io/epic-link: /api/epic/accounts/epictest/proxies/ff2ac5e8-beed-4181-96cb-244dbd104ae9
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"gateway.networking.k8s.io/v1alpha2","kind":"Gateway","metadata":{"annotations":{},"name":"uswest-gtwapi","namespace":"demoapi"},"spec":{"gatewayClassName":"uswest-gtwapi","listeners":[{"allowedRoutes":{"namespaces":{"from":"All"}},"name":"gwapi","port":443,"protocol":"HTTPS"}]}}
creationTimestamp: "2022-04-19T18:16:17Z"
finalizers:
- epic.acnodal.io/controller
generation: 1
name: uswest-gtwapi
namespace: demoapi
resourceVersion: "2543805"
uid: ff2ac5e8-beed-4181-96cb-244dbd104ae9
spec:
gatewayClassName: uswest-gtwapi
listeners:
- allowedRoutes:
namespaces:
from: All
name: gwapi
port: 443
protocol: HTTPS
status:
addresses:
- type: IPAddress
value: 72.52.101.1
- type: Hostname
value: uswest-gtwapi-demoapi-epictest-uswest.epick8sgw.net
conditions:
- lastTransitionTime: "2022-04-19T18:16:17Z"
message: Announced to EPIC
observedGeneration: 1
reason: Valid
status: "True"
type: Ready
To share this gateway, the subsequent gateway resources adds the UUID to the new Gateway using the annotation acnodal.io/epic-sharing-key In these examples, two clusters, one upsteam on bare metal and the other on GCP are sharing this Gateway.
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
annotations:
acnodal.io/epic-config: epic-gateway/uswest-gtwapi
acnodal.io/epic-link: /api/epic/accounts/epictest/proxies/ff2ac5e8-beed-4181-96cb-244dbd104ae9
acnodal.io/epic-sharing-key: ff2ac5e8-beed-4181-96cb-244dbd104ae9
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"gateway.networking.k8s.io/v1alpha2","kind":"Gateway","metadata":{"annotations":{"acnodal.io/epic-sharing-key":"ff2ac5e8-beed-4181-96cb-244dbd104ae9"},"name":"uswest-gtwapi","namespace":"demoapi"},"spec":{"gatewayClassName":"uswest-gtwapi","listeners":[{"allowedRoutes":{"namespaces":{"from":"All"}},"name":"gwapi","port":443,"protocol":"HTTPS"}]}}
creationTimestamp: "2022-04-19T18:23:15Z"
finalizers:
- epic.acnodal.io/controller
generation: 1
name: uswest-gtwapi
namespace: demoapi
resourceVersion: "5256593"
uid: afef5e7a-10c4-4659-b94d-69ff0d3460e0
spec:
gatewayClassName: uswest-gtwapi
listeners:
- allowedRoutes:
namespaces:
from: All
name: gwapi
port: 443
protocol: HTTPS
status:
addresses:
- type: IPAddress
value: 72.52.101.1
- type: Hostname
value: uswest-gtwapi-demoapi-epictest-uswest.epick8sgw.net
conditions:
- lastTransitionTime: "2022-04-19T18:23:16Z"
message: Announced to EPIC
observedGeneration: 1
reason: Valid
status: "True"
type: Ready
The gateway and route resources do not need to share the same names, they should reflect configuration that makes sense in your application.
Creating a cluster gateway resource instantiates at an EPIC Gateway instance based upon the gateway template. EPIC has controllers that dynamically update the initial Envoy Configuration. The endpoint controller that maintains the list of POD IP addresses in the cluster. It includes an Envoy End Point Discover Server that updates Envoys cluster configuration. Endpoints from each cluster are added by the endpoint controller.
Single cluster gateway resources can be referenced by multiple route objects. Multicluster uses the same logic. According to rules is the GatewayAPI, cluster httproute are merged and converted into the EPIC Gateways Envoys filter_chains. The resulting Envoy Configuration can be inspected using the Gateway Service Manager
envoyAPI: v3
envoyResources:
clusters:
- name: 7d45bae8-77e8-4858-bf89-3e8111d2fd14
value: |
name: 7d45bae8-77e8-4858-bf89-3e8111d2fd14
connect_timeout: 2s
type: EDS
eds_cluster_config:
eds_config:
resource_api_version: V3
api_config_source:
api_type: GRPC
transport_api_version: V3
grpc_services:
- envoy_grpc:
cluster_name: eds-server
lb_policy: ROUND_ROBIN
health_checks:
- interval: 5s
timeout: 5s
no_traffic_interval: 5s
unhealthy_threshold: 3
healthy_threshold: 3
tcp_health_check: {}
- name: 34bd6bef-029e-4c80-89fc-23ccb817e62f
value: |
name: 34bd6bef-029e-4c80-89fc-23ccb817e62f
connect_timeout: 2s
type: EDS
eds_cluster_config:
eds_config:
resource_api_version: V3
api_config_source:
api_type: GRPC
transport_api_version: V3
grpc_services:
- envoy_grpc:
cluster_name: eds-server
lb_policy: ROUND_ROBIN
health_checks:
- interval: 5s
timeout: 5s
no_traffic_interval: 5s
unhealthy_threshold: 3
healthy_threshold: 3
tcp_health_check: {}
- name: 70196186-404f-442e-b5ac-6e563620e56c
value: |
name: 70196186-404f-442e-b5ac-6e563620e56c
connect_timeout: 2s
type: EDS
eds_cluster_config:
eds_config:
resource_api_version: V3
api_config_source:
api_type: GRPC
transport_api_version: V3
grpc_services:
- envoy_grpc:
cluster_name: eds-server
lb_policy: ROUND_ROBIN
health_checks:
- interval: 5s
timeout: 5s
no_traffic_interval: 5s
unhealthy_threshold: 3
healthy_threshold: 3
tcp_health_check: {}
listeners:
- name: TCP-443
value: |
name: TCP-443
address:
socket_address:
address: "::"
ipv4_compat: yes
port_value: 443
protocol: TCP
filter_chains:
- filters:
- name: envoy.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ff2ac5e8-beed-4181-96cb-244dbd104ae9
server_name: epicuswest
add_user_agent: true
use_remote_address: true
via: epicuswest
route_config:
name: local_route
virtual_hosts:
- name: "*"
domains:
- "*"
routes:
- route:
weighted_clusters:
clusters:
- name: 7d45bae8-77e8-4858-bf89-3e8111d2fd14
weight: 1
total_weight: 1
match:
prefix: "/api"
headers:
- name: "epic"
string_match:
exact: "dev1"
- route:
weighted_clusters:
clusters:
- name: 34bd6bef-029e-4c80-89fc-23ccb817e62f
weight: 1
total_weight: 1
match:
prefix: "/api"
- route:
weighted_clusters:
clusters:
- name: 70196186-404f-442e-b5ac-6e563620e56c
weight: 1
total_weight: 1
match:
prefix: "/"
http_filters:
- name: envoy.filters.http.bandwidth_limit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.bandwidth_limit.v3.BandwidthLimit
stat_prefix: bandwidth_limiter_default
enable_mode: REQUEST_AND_RESPONSE
limit_kbps: 1000
fill_interval: 0.1s
- name: envoy.filters.http.router
transport_socket:
name: envoy.transport_socket.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificate_sds_secret_configs:
- name: wildcard-https-cert
sds_config:
resource_api_version: V3
ads: {}
secrets:
- name: wildcard-https-cert
ref:
name: wildcard-epick8sgw-net-tls
namespace: epic-epictest
nodeID: epic-epictest.ff2ac5e8-beed-4181-96cb-244dbd104ae9
serialization: yaml
The distribution of requests among clusters is controlled via the cluster Gateway controller. For example, scaling a deployment in one of the clusters will result in a larger percentage of traffic being sent to that cluster.
Using httpRoute backendRefs weight provides more granular control over the distribution amount Services/PODs. When EPIC merges the routing rules, it will create a weight from the combined rules. For example, if each cluster has a rule with 100%, each cluster will receive 50%. EPIC sums the weights on each backendRef and creates a distribution that equals 100%
httpRoute can also be used to distribute specific requests to different clusters, creating a unique httpRoute in a cluster will result requests being forward to that cluster.
Additional information is available in the Multi-cluster documentation.