Create egress gateway

Egress traffic

Traffic that’s outbound from a pod that has an Istio sidecar also passes through that sidecar’s container, (more precisely, through Envoy). Therefore, the accessibility of external services depends on the configuration of that Envoy proxy.

By default, Istio configures the Envoy proxy to enable requests for unknown services. Although this provides a convenient way of getting started with Istio, it’s generally a good idea to put stricter controls in place.

Egress traffic without egress gateway Egress traffic without egress gateway

Allow only registered access

You can configure Service Mesh Manager to permit access only to specific external services. For details, see External Services.

Egress gateway

Egress gateways define an exit point from your Istio mesh for outgoing traffic. Egress gateways also allow you to apply Istio features on the traffic that exits the mesh, for example monitoring, routing rules, or retries.

Egress traffic using egress gateway Egress traffic using egress gateway

Why do you need egress gateways? For example:

  • Your organization requires some, or all, outbound traffic to go through dedicated nodes. These nodes could be separated from the rest of the nodes for the purposes of monitoring and policy enforcement.
  • The application nodes of a cluster don’t have public IPs, so the in-mesh services that run on them cannot access the internet directly. Allocating public IPs to the egress gateway nodes and routing egress traffic through the gateway allows for controlled access to external services.

CAUTION:

Using an egress gateway doesn’t restrict outgoing traffic, it only routes it through the egress gateway. To limit access only to selected external services, see External Services.

Create egress gateway

To create an egress gateway and route egress traffic through it, complete the following steps.

Note: The YAML samples work with the Service Mesh Manager demo application. Adjust their parameters (for example, namespace, service name, and so on) as needed for your environment.

CAUTION:

Using an egress gateway doesn’t restrict outgoing traffic, it only routes it through the egress gateway. To limit access only to selected external services, see External Services.
  1. Create an egress gateway using the IstioMeshGateway resource.

    CAUTION:

    By the default, the IstioMeshGateway pod is running without root privileges, therefore it cannot use ports under 1024. Either use ports above 1024 as targetports (for example, 8080 instead of 80) or run the gateway pod with root privileges by setting spec.runAsRoot: true in the IstioMeshGateway custom resource.

    For testing, you can download and apply the following resource to create a new egress gateway deployment and a corresponding service in the smm-demo namespace.

    apiVersion: servicemesh.cisco.com/v1alpha1
    kind: IstioMeshGateway
    metadata:
      name: egress-demo
      namespace: smm-demo
    spec:
      istioControlPlane:
        name: cp-v115x
        namespace: istio-system
      deployment:
        replicas:
          max: 1
          min: 1
      service:
        ports:
        - name: http
          port: 80
          protocol: TCP
          targetPort: 8080
        type: ClusterIP
      type: egress
    
    kubectl apply -f egress-meshgateway.yaml
    

    Expected output:

    istiomeshgateway.servicemesh.cisco.com/egress-demo created
    
  2. Create a Gateway resource for the egress gateway. The Gateway resource connects the Istio configuration resources and the deployment of a matching gateway. Apply the following Gateway resource to configure the outbound port (80 in the previous example) on the egress gateway that you have defined in the previous step.

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: egress-demo
      namespace: smm-demo
    spec:
      selector:
        gateway-name: egress-demo
        gateway-type: egress
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"
    kubectl apply -f egress-gateway.yaml
    

    Expected output:

    gateway.networking.istio.io/egress-demo created
    
  3. Define a VirtualService resource to direct traffic from the sidecars to the egress gateway.

    Apply the following VirtualService to direct traffic from the sidecars to the egress gateway, and also from the egress gateway to the external service. Edit the VirtualService to match the external service you want to permit access to.

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin-egress
      namespace: smm-demo
    spec:
      hosts:
      - httpbin.org
      gateways:
      - egress-demo
      - mesh
      http:
      - match:
        - gateways:
          - mesh
          port: 80
        route:
        - destination:
            host: egress-demo.smm-demo.svc.cluster.local
            port:
              number: 80
      - match:
        - gateways:
          - egress-demo
          port: 80
        route:
        - destination:
            host: httpbin.org
            port:
              number: 80
    
    kubectl apply -f egress-virtualservice.yaml
    

    Expected output:

    virtualservice.networking.istio.io/httpbin-egress created
    
  4. Test access to the external service.

    If you have installed the Service Mesh Manager demo application and used the examples in the previous steps, you can run the following command to start requests from the notifications-v1 workload to the external http-bin service:

    kubectl -n smm-demo set env deployment/notifications-v1 'REQUESTS=http://httpbin.org/get#1'
    
    • If everything is set up correctly, the new egress gateway appears on the MENU > GATEWAYS page. The new egress gateway on the <strong>MENU &gt; GATEWAYS</strong> page The new egress gateway on the <strong>MENU &gt; GATEWAYS</strong> page
    • If there is egress traffic, the gateway appears on theMENU > GATEWAYS page (make sure to select the relevant namespace). Note that the traffic from the gateway to the external service is visible only if you create a ServiceEntry resource for the external service. The new egress gateway on the <strong>MENU &gt; TOPOLOGY</strong> page The new egress gateway on the <strong>MENU &gt; TOPOLOGY</strong> page
  5. If needed, permit access only to specific external services. For details, see External Services.

IstioMeshGateway CR reference

This section describes the fields of the IstioMeshGateway custom resource.

apiVersion (string)

Must be servicemesh.cisco.com/v1alpha1

kind (string)

Must be IstioMeshGateway

spec (object)

The configuration and parameters of the IstioMeshGateway.

spec.type (string, required)

Type of the mesh gateway. Ingress gateways define an entry point into your Istio mesh for incoming traffic, while egress gateways define an exit point from your Istio mesh for outgoing traffic. Possible values:

  • ingress
  • egress

spec.istioControlPlane (object, required)

Specifies the istiocontrolplane cr the istio-proxy connects to by a namespaced name. When upgrading to a new Istio version (thus to a new control plane), this should be upgraded.

For example:

spec:
  istioControlPlane:
    name: cp-v115x
    namespace: istio-system

spec.deployment (object)

Configuration options for the Kubernetes istio-proxy deployment. Metadata like labels and annotations can be set here for the deployment or pods as well, in spec.deployment.metadata.annotations or spec.deployment.podMetadata.annotations.

spec.service (object, required)

Configuration options for the Kubernetes service. Annotations can be set here as well as in spec.service.metadata.annotations, they are often useful in cloud loadbalancer cases, for example to specify some configuration for AWS.

For example:

  service:
    ports:
      - name: tcp-status-port
        port: 15021
        protocol: TCP
        targetPort: 15021
      - name: http
        port: 80
        protocol: TCP
        targetPort: 8080
    type: LoadBalancer

spec.runAsRoot (true | false)

Whether to run the gateway in a privileged container. If not running as root, only ports higher than 1024 can be opened on the container. Default value: false