이 콘텐츠는 선택한 언어로 제공되지 않습니다.
Chapter 3. Connectivity Link platform engineer workflow
This section of the walkthrough shows how as a platform engineer you can deploy a Gateway that provides secure communication and is protected and ready for use by application development teams. It also shows how to use this Gateway in multiple clusters in different geographic regions.
Prerequisites
In multicluster environments, you must perform the following steps in each cluster individually, unless specifically excluded.
3.1. Step 1 - Set your environment variables 링크 복사링크가 클립보드에 복사되었습니다!
Procedure
Set the following environment variables, which are used for convenience in this guide:
export zid=change-to-your-DNS-zone-ID export rootDomain=demo.example.com export gatewayNS=api-gateway export gatewayName=external export devNS=toystore export AWS_ACCESS_KEY_ID=xxxx export AWS_SECRET_ACCESS_KEY=xxxx export AWS_REGION=us-east-1 export clusterIssuerName=lets-encrypt export EMAIL=foo@example.comIn this example,
zidis your hosted zone ID displayed in the AWS Route 53 console.rootDomainis the top-level AWS Route 53 domain name that you will use for Connectivity Link.NoteThis guide uses environment variables for convenience only. If you know the environment variable values, you can set up the required
.yamlfiles in way that suits your needs.
3.2. Step 2 - Set up a DNS provider secret 링크 복사링크가 클립보드에 복사되었습니다!
The DNS provider supplies a credential to access the DNS zones that Connectivity Link can use to set up DNS configuration. You must ensure that this credential has access to only the zones that you want managed.
You must apply the following Secret resources to each cluster. If you are adding an additional cluster, add them to the new cluster.
Procedure
If your Gateway namespace does not already exist, create it as follows:
kubectl create ns ${gatewayNS}If the secret for your DNS provider credentials was not already created when installing Connectivity Link, create this secret in your Gateway namespace as follows:
kubectl -n ${gatewayNS} create secret generic aws-credentials \ --type=kuadrant.io/aws \ --from-literal=AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ --from-literal=AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEYBefore adding a TLS issuer, you must also create the credentials secret in the
cert-managernamespace as follows:kubectl -n cert-manager create secret generic aws-credentials \ --type=kuadrant.io/aws \ --from-literal=AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ --from-literal=AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
3.3. Step 3 - Add a TLS issuer 링크 복사링크가 클립보드에 복사되었습니다!
To secure communication to the Gateways, you will define a TLS issuer for TLS certificates. This example uses Let’s Encrypt, but you can use any certificate issuer supported by cert-manager.
Procedure
Enter the following command to define a TLS issuer. This example uses Let’s Encrypt, which you must also apply to all clusters:
kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: ${clusterIssuerName} spec: acme: email: ${EMAIL} privateKeySecretRef: name: le-secret server: https://acme-v02.api.letsencrypt.org/directory solvers: - dns01: route53: hostedZoneID: ${zid} region: ${AWS_REGION} accessKeyIDSecretRef: key: AWS_ACCESS_KEY_ID name: aws-credentials secretAccessKeySecretRef: key: AWS_SECRET_ACCESS_KEY name: aws-credentials EOFWait for the
ClusterIssuerto become ready as follows:kubectl wait clusterissuer/${clusterIssuerName} --for=condition=ready=true
3.4. Step 4 - Set up a Gateway 링크 복사링크가 클립보드에 복사되었습니다!
For Connectivity Link to balance traffic using DNS across two or more clusters, you must define a Gateway with a shared host. You will define this by using an HTTPS listener with a wildcard hostname based on the root domain. As mentioned earlier, you must apply these resources to all clusters.
For now, the Gateway is set to accept an HTTPRoute from the same namespace only. This allows you to restrict who can use the Gateway until it is ready for general use.
Procedure
Enter the following command to create the Gateway:
kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: ${gatewayName} namespace: ${gatewayNS} labels: kuadrant.io/gateway: "true" spec: gatewayClassName: istio listeners: - allowedRoutes: namespaces: from: Same hostname: "*.${rootDomain}" name: api port: 443 protocol: HTTPS tls: certificateRefs: - group: "" kind: Secret name: api-${gatewayName}-tls mode: Terminate EOFCheck the status of your Gateway as follows:
kubectl get gateway ${gatewayName} -n ${gatewayNS} -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}' kubectl get gateway ${gatewayName} -n ${gatewayNS} -o=jsonpath='{.status.conditions[?(@.type=="Programmed")].message}'Your Gateway should be accepted and programmed, which means valid and assigned an external address.
However, if you check your HTTPS listener status as follows, you will see that it is not yet programmed or ready to accept traffic due to bad TLS configuration:
kubectl get gateway ${gatewayName} -n ${gatewayNS} -o=jsonpath='{.status.listeners[0].conditions[?(@.type=="Programmed")].message}'Connectivity Link can help with this by using a TLSPolicy, which is described in the next step.
3.4.1. Optional: Configure metrics to be scraped from the Gateway instance 링크 복사링크가 클립보드에 복사되었습니다!
If you have Prometheus set up in your cluster, you can configure a PodMonitor to scrape metrics directly from the Gateway pod. This configuration is required for metrics such as istio_requests_total. You must add the following configuration in the namespace where the Gateway is running:
kubectl apply -f - <<EOF
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: istio-proxies-monitor
namespace: ${gatewayNS}
spec:
selector:
matchExpressions:
- key: istio-prometheus-ignore
operator: DoesNotExist
podMetricsEndpoints:
- path: /stats/prometheus
interval: 30s
relabelings:
- action: keep
sourceLabels: ["__meta_kubernetes_pod_container_name"]
regex: "istio-proxy"
- action: keep
sourceLabels:
["__meta_kubernetes_pod_annotationpresent_prometheus_io_scrape"]
- action: replace
regex: (\d+);(([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})
replacement: "[\$2]:\$1"
sourceLabels:
[
"__meta_kubernetes_pod_annotation_prometheus_io_port",
"__meta_kubernetes_pod_ip",
]
targetLabel: "__address__"
- action: replace
regex: (\d+);((([0-9]+?)(\.|$)){4})
replacement: "\$2:\$1"
sourceLabels:
[
"__meta_kubernetes_pod_annotation_prometheus_io_port",
"__meta_kubernetes_pod_ip",
]
targetLabel: "__address__"
- action: labeldrop
regex: "__meta_kubernetes_pod_label_(.+)"
- sourceLabels: ["__meta_kubernetes_namespace"]
action: replace
targetLabel: namespace
- sourceLabels: ["__meta_kubernetes_pod_name"]
action: replace
targetLabel: pod_name
EOF
For more information on configuring metrics, see the Connectivity Link Observability Guide.
3.5. Step 5 - Configure your Gateway policies and HTTP route 링크 복사링크가 클립보드에 복사되었습니다!
While your Gateway is now deployed, it has no exposed endpoints and your HTTPS listener is not programmed. Next, you can set up a TLSPolicy that leverages your CertificateIssuer to set up your HTTPS listener certificates.
You will define an AuthPolicy that will set up a default HTTP 403 response for any unprotected endpoints, as well as a RateLimitPolicy that will set up a default artificially low global limit to further protect any endpoints exposed by this Gateway.
You will also define a DNSPolicy with a load balancing strategy, and an HTTPRoute for your Gateway to communicate with your backend application API.
3.5.1. Set the TLS policy 링크 복사링크가 클립보드에 복사되었습니다!
Procedure
Set the
TLSPolicyfor your Gateway as follows:kubectl apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: TLSPolicy metadata: name: ${gatewayName}-tls namespace: ${gatewayNS} spec: targetRef: name: ${gatewayName} group: gateway.networking.k8s.io kind: Gateway issuerRef: group: cert-manager.io kind: ClusterIssuer name: ${clusterIssuerName} EOFCheck that your TLS policy was accepted by the controller as follows:
kubectl get tlspolicy ${gatewayName}-tls -n ${gatewayNS} -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}'
3.5.2. Set the Auth policy 링크 복사링크가 클립보드에 복사되었습니다!
Procedure
Set a default, deny-all
AuthPolicyfor your Gateway as follows:kubectl apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: AuthPolicy metadata: name: ${gatewayName}-auth namespace: ${gatewayNS} spec: targetRef: group: gateway.networking.k8s.io kind: Gateway name: ${gatewayName} defaults: rules: authorization: "deny": opa: rego: "allow = false" EOFCheck that your auth policy was accepted by the controller as follows:
kubectl get authpolicy ${gatewayName}-auth -n ${gatewayNS} -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}'
3.5.3. Set the rate limit policy 링크 복사링크가 클립보드에 복사되었습니다!
Procedure
Set the default
RateLimitPolicyfor your Gateway as follows:kubectl apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: RateLimitPolicy metadata: name: ${gatewayName}-rlp namespace: ${gatewayNS} spec: targetRef: group: gateway.networking.k8s.io kind: Gateway name: ${gatewayName} defaults: limits: "low-limit": rates: - limit: 2 window: 10s EOFNoteIt might take a few minutes for the
RateLimitPolicyto be applied depending on your cluster. The limit in this example is artificially low to show it working easily.To check your rate limits have been accepted, enter the following command:
kubectl get ratelimitpolicy ${gatewayName}-rlp -n ${gatewayNS} -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}'
3.5.4. Set the DNS policy 링크 복사링크가 클립보드에 복사되었습니다!
Procedure
Set the
DNSPolicyfor your Gateway as follows:kubectl apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: DNSPolicy metadata: name: ${gatewayName}-dnspolicy namespace: ${gatewayNS} spec: targetRef: name: ${gatewayName} group: gateway.networking.k8s.io kind: Gateway providerRefs: - name: aws-credentials loadBalancing: weight: 120 geo: EU defaultGeo: true EOFNoteThe
DNSPolicywill use the DNS ProviderSecretthat you defined earlier. Thegeoin this example isEU, but you can change this to suit your requirements.Check that your
DNSPolicyhas been accepted as follows:kubectl get dnspolicy ${gatewayName}-dnspolicy -n ${gatewayNS} -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}'
3.5.5. Create an HTTP route 링크 복사링크가 클립보드에 복사되었습니다!
For test purposes, this section assumes that the toystore application is deployed. For more information, see Chapter 4, Connectivity Link application developer workflow.
Procedure
Create an
HTTPRouteto test your Gateway as follows:kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: test namespace: ${gatewayNS} labels: service: toystore spec: parentRefs: - name: ${gatewayName} namespace: ${gatewayNS} hostnames: - "test.${rootDomain}" rules: - backendRefs: - name: toystore port: 80 EOFCheck your Gateway policies are enforced as follows:
kubectl get dnspolicy ${gatewayName}-dnspolicy -n ${gatewayNS} -o=jsonpath='{.status.conditions[?(@.type=="Enforced")].message}' kubectl get authpolicy ${gatewayName}-auth -n ${gatewayNS} -o=jsonpath='{.status.conditions[?(@.type=="Enforced")].message}' kubectl get ratelimitpolicy ${gatewayName}-rlp -n ${gatewayNS} -o=jsonpath='{.status.conditions[?(@.type=="Enforced")].message}'Check your HTTPS listener is ready as follows:
kubectl get gateway ${gatewayName} -n ${gatewayNS} -o=jsonpath='{.status.listeners[0].conditions[?(@.type=="Programmed")].message}'
3.6. Step 6 - Test connectivity and deny all auth 링크 복사링크가 클립보드에 복사되었습니다!
You can use curl to test your endpoint connectivity and auth.
Procedure
Enter the following command:
curl -w "%{http_code}" https://$(kubectl get httproute test -n ${gatewayNS} -o=jsonpath='{.spec.hostnames[0]}')You should see an HTTP
403response.
3.7. Step 7 - Open up the Gateway for other namespaces 링크 복사링크가 클립보드에 복사되었습니다!
Because you have configured the Gateway, secured it with Connectivity Link policies, and tested it, you can now open it up for use by other teams in other namespaces.
Procedure
Enter the following command:
kubectl patch gateway ${gatewayName} -n ${gatewayNS} --type='json' -p='[{"op": "replace", "path": "/spec/listeners/0/allowedRoutes/namespaces/from", "value":"All"}]'
3.8. Step 8 - Extend the Gateway to multiple clusters and configure geo-based routing 링크 복사링크가 클립보드에 복사되었습니다!
Procedure
To distribute this Gateway across multiple clusters, repeat this setup process for each cluster.
By default, this will implement a round-robin DNS strategy to distribute traffic evenly across the different clusters. Setting up your Gateways to serve clients based on their geographic location is straightforward with your current configuration.
Assuming that you have deployed Gateway instances across multiple clusters as per this guide, the next step involves updating the DNS controller with the geographic regions of the visible Gateways.
For instance, if you have one cluster in North America and another in the EU, you can direct traffic to these Gateways based on their location by configuring the appropriate policy. For your North American cluster, you can create a DNSPolicy and set the
loadBalancing:geofield toUS.