Sending Requests Using Istio Egress Gateway ​
Learn how to configure and use the Istio egress Gateway to allow outbound traffic from your Kyma runtime cluster to specific external destinations. Test your configuration by sending an HTTPS request to an external website using a sample Deployment.
Prerequisites ​
Steps ​
Export the following value as an environment variable:
bashexport NAMESPACE={service-namespace}Create a new namespace for the sample application:
bashkubectl create ns $NAMESPACE kubectl label namespace $NAMESPACE istio-injection=enabled --overwriteEnable the egress Gateway in the Istio custom resource:
bashkubectl apply -f - <<EOF apiVersion: operator.kyma-project.io/v1alpha2 kind: Istio metadata: name: default namespace: kyma-system labels: app.kubernetes.io/name: default spec: components: egressGateway: enabled: true EOFEnable additional sidecar logs to see the egress Gateway being used in requests:
bashkubectl apply -f - <<EOF apiVersion: telemetry.istio.io/v1 kind: Telemetry metadata: name: mesh-default namespace: istio-system spec: accessLogging: - providers: - name: envoy EOFApply the
curlDeployment to send the requests:bashkubectl apply -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: curl namespace: ${NAMESPACE} --- apiVersion: v1 kind: Service metadata: name: curl namespace: ${NAMESPACE} labels: app: curl service: curl spec: ports: - port: 80 name: http selector: app: curl --- apiVersion: apps/v1 kind: Deployment metadata: name: curl namespace: ${NAMESPACE} spec: replicas: 1 selector: matchLabels: app: curl template: metadata: labels: app: curl spec: terminationGracePeriodSeconds: 0 serviceAccountName: curl containers: - name: curl image: curlimages/curl command: ["/bin/sleep", "infinity"] imagePullPolicy: IfNotPresent volumeMounts: - mountPath: /etc/curl/tls name: secret-volume volumes: - name: secret-volume secret: secretName: curl-secret optional: true EOFExport the name of the
curlPod:bashexport SOURCE_POD=$(kubectl get pod -n "$NAMESPACE" -l app=curl -o jsonpath={.items..metadata.name})Define a ServiceEntry which adds the
kyma-project.iohostname to the mesh:bashkubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: kyma-project namespace: $NAMESPACE spec: hosts: - kyma-project.io ports: - number: 443 name: tls protocol: TLS resolution: DNS EOFCreate an egress Gateway, DestinationRule, and VirtualService to direct traffic:
bashkubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: istio-egressgateway namespace: ${NAMESPACE} spec: selector: istio: egressgateway servers: - port: number: 443 name: tls protocol: TLS hosts: - kyma-project.io tls: mode: PASSTHROUGH --- apiVersion: networking.istio.io/v1 kind: DestinationRule metadata: name: egressgateway-for-kyma-project namespace: ${NAMESPACE} spec: host: istio-egressgateway.istio-system.svc.cluster.local subsets: - name: kyma-project --- apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: direct-kyma-project-through-egress-gateway namespace: ${NAMESPACE} spec: hosts: - kyma-project.io gateways: - mesh - istio-egressgateway tls: - match: - gateways: - mesh port: 443 sniHosts: - kyma-project.io route: - destination: host: istio-egressgateway.istio-system.svc.cluster.local subset: kyma-project port: number: 443 - match: - gateways: - istio-egressgateway port: 443 sniHosts: - kyma-project.io route: - destination: host: kyma-project.io port: number: 443 weight: 100 EOFSend an HTTPS request to the Kyma project website:
bashkubectl exec -n "$NAMESPACE" "$SOURCE_POD" -c curl -- curl -sSL -o /dev/null -D - https://kyma-project.ioIf successful, you get a response from the website similar to this one:
HTTP/2 200 accept-ranges: bytes age: 203 ...Check the logs of the Istio egress Gateway:
kubectl logs -l istio=egressgateway -n istio-systemIf successful, the logs contain the request made by the egress Gateway:
{"requested_server_name":"kyma-project.io","upstream_cluster":"outbound|443||kyma-project.io",[...]}Enhance Security by Implementing NetworkPolicies ​
Istio by default cannot securely enforce that egress traffic goes through the egress gateway. It only enables the flow through sidecar proxies. Kubernetes Network Policies can be used to restrict namespace traffic, so it only goes through the istio egress gateway. Network policies are the Kubernetes way to enforce traffic rules in the namespace.
Support for NetworkPolicies depends on the Kubernetes CNI plugin used in the cluster. By default, SAP BTP, Kyma runtime uses the CNI configuration provided and managed by Gardener, which supports NetworkPolicies. However, if you’ve made any changes, make sure to check the relevant documentation.
In Gardener-based clusters, such as SAP BTP, Kyma runtime, the Network Policy restricting DNS traffic may not work as expected.
It is due to the local DNS service used in discovery working outside the CNI. In such cases, define the ipBlocks with the IP CIDR of the kube-dns service in the NetworkPolicy to allow proper DNS resolution.
- Fetch the IP address of the
kube-dnsservice:bashexport KUBE_DNS_ADDRESS=$(kubectl get svc -n kube-system kube-dns -o jsonpath='{.spec.clusterIP}') - Create a NetworkPolicy with the fetched IP address in the ipBlocks section. The NetworkPolicy allows only egress traffic to the Istio egress gateway, blocking all other egress traffic.bash
kubectl apply -f - <<EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: network-policy-allow-egress-traffic namespace: ${NAMESPACE} spec: egress: - ports: - port: 53 protocol: UDP to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system - ipBlock: cidr: ${KUBE_DNS_ADDRESS}/32 - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: istio-system podSelector: {} policyTypes: - Egress EOF - Send an HTTPS request to the Kyma project website:bashIf successful, you get a response from the website similar to this one:
kubectl exec -n "$NAMESPACE" "$SOURCE_POD" -c curl -- curl -sSL -o /dev/null -D - https://kyma-project.ioHTTP/2 200 accept-ranges: bytes age: 203 ... - Send an HTTPS request to an external website:bashThe request should fail with an error message similar to this one:
kubectl exec -n "$NAMESPACE" "$SOURCE_POD" -c curl -- curl -sSL -o /dev/null -D - https://www.google.comcurl: (35) Recv failure: Connection reset by peer command terminated with exit code 35
You have successfully secured the egress traffic in the $NAMESPACE namespace by using Istio egress gateway and Kubernetes Network Policies.