How to expose Kubernetes services to external traffic using Istio Gateway

Rafael Natali
Marionete
Published in
14 min readAug 9, 2022

Use a Gateway to manage inbound and outbound traffic for your mesh, letting you specify which traffic you want to enter or leave the Istio mesh.

In a previous article, I explained the concept of a Service Mesh.

This article demonstrates how to expose Kubernetes services deployed in the Service Mesh to outside traffic using HTTP and HTTPS endpoints.

From the author- Made with Excalidraw

Table of Contents

· Motivation
·
Test Environment
·
Before you begin
·
Determining the ingress IP and ports
·
Scenario 1 — HTTP endpoint
·
Scenario 2 — HTTPS endpoint
Scenario Overview
Secure Gateways — HTTPS endpoint — single domain
Secure Gateways — HTTPS endpoint — wildcard
· Summary
·
References

Motivation

In the project I’m working on right now, I undertook the implementation of the Istio Service Mesh. The first task was to migrate the two Kubernetes Ingresses configured using the NGINX ingress to the Istio Gateway with TLS\SSL.

As this is the first time executing such a task, I looked at Istio’s official documentation and set up a local test environment to validate the steps.

Firstly, I chose to test exposing the service using just HTTP. Secondly, I would add the TLS\SSL part. As for the TLS\SSL, I will generate certificates for one specific domain and a wildcard certificate. As a result, I’d have a broader understanding of the process.

Test Environment

The test environment had the following tech stack:

  • macOS Monterey version 12.3.1
  • Apple M1 Pro
  • minikube version v1.26.0
  • K8s version v1.22.7
  • Istio version 1.13.3
  • OpenSSL 3.0.5 5 Jul 2022 (Library: OpenSSL 3.0.5 5 Jul 2022)

Check the official documentation on how to install Istio

Before you begin

1. Configure the local machine to resolve the app Fully Qualified Domain Name (FQDN)

sudo vi /etc/hosts
127.0.0.1 httpbin.example.com

2. Start minikube with a specific K8s version:

minikube start — kubernetes-version=v1.22.7

3. (in a different shell) Start the minikube tunnel

minikube tunnel

Keep this shell open until the end of the tests.

4. Deploy the httpbin sample application:

  • Make sure your current directory is the istio directory.
  • Start the httpbin sample.
kubectl apply -f samples/httpbin/httpbin.yaml

Determining the ingress IP and ports

1. Execute the following command to determine the istio-ingressgateway external load balancers EXTERNAL-IP:

kubectl get svc istio-ingressgateway -n istio-system

Output:

NAME                 TYPE         CLUSTER-IP    EXTERNAL-IP PORT(S) AGEistio-ingressgateway LoadBalancer 10.97.117.233 127.0.0.1 15021:31373/TCP,80:32343/TCP,443:32525/TCP,31400:32279/TCP,15443:31536/TCP 21d

2. Set the ingress IP and ports:

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath=’{.status.loadBalancer.ingress[0].ip}’)export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath=’{.spec.ports[?(@.name==”http2")].port}’)export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath=’{.spec.ports[?(@.name==”https”)].port}’)export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath=’{.spec.ports[?(@.name==”tcp”)].port}’)

These variables are used later when testing the access to the applications using curl.

Scenario 1 — HTTP endpoint

Configuring ingress using an Istio gateway — HTTP endpoint

An ingress Gateway describes a load balancer operating at the edge of the mesh that receives incoming HTTP/TCP connections. It configures exposed ports, protocols, etc. but, unlike Kubernetes Ingress Resources, does not include any traffic routing configuration. Traffic routing for ingress traffic is instead configured using Istio routing rules, exactly in the same way as for internal service requests.

Configure a Gateway on port 80 for HTTP traffic declared in the VirtualService:

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "httpbin.example.com"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /delay
route:
- destination:
port:
number: 8000
host: httpbin
EOF

Accessing the httpbin application

curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200"

Output:

HTTP/1.1 200 OK
server: istio-envoy
date: Fri, 08 Jul 2022 18:00:47 GMT
content-type: text/html; charset=utf-8
access-control-allow-origin: *
access-control-allow-credentials: true
content-length: 0
x-envoy-upstream-service-time: 34

Understanding what happened

In the preceding steps, I deployed an app (httpbin) inside the service mesh and exposed an HTTP endpoint (port 8080) . The istio-ingressgateway service opens the port 80 to service mesh external traffic. The Gateway configuration resources allow the external traffic to enter the Istio service mesh and the Virtual Service makes the traffic management and policy features to the httpbin app, making it available to external traffic.

Clean-up

kubectl delete gateways.networking.istio.io httpbin-gateway
kubectl delete virtualservices.networking.istio.io httpbin
kubectl delete -f samples/httpbin/httpbin.yaml

Scenario 2 — HTTPS endpoint

Scenario Overview

To implement TLS/SSL using the istio-ingress gateway, proceed as follows:

  1. Define the domain for the hosts, e.g., *.abctest.com, test.xyz.local.
  2. Generate a digital certificate and keys for the domain. I’ll show how to use digital certificates for a single domain and wildcard certificates.
  3. Create a K8s Secret in the istio-system namespace with the key and certificate generated in step 2.
  4. Create one Gateway per namespace with a servers: section for port 443, and specify values for credentialName to be the same as the secret created in the previous step.
  5. Configure the gateway ingress traffic routes. Define the corresponding virtual service for each resource in each namespace.

Next two sections will present the TLS\SSL configuration for a single domain and using a wildcard certificate.

Secure Gateways — HTTPS endpoint — single domain

This task shows how to expose a secure HTTPS service using simple TLS.

Make sure to perform the steps in the Before you begin and Determining the ingress IP and ports sections.

Generate client and server certificates and keys

For this task, you can use your favourite tool to generate certificates and keys. The commands below use OpenSSL.

Since version 58, Chrome requires SSL certificates to use SAN (Subject Alternative Name) instead of the popular Common Name (CN). Additional steps are necessary to make a self-signed certificate to work. The commands below were based on: Fixing Chrome 58+ [missing_subjectAltName] with OpenSSL when using self-signed certificates.

Create a root certificate and private key to sign the certificates for your services:

mkdir -p temp/certsopenssl genrsa -des3 -out temp/certs/rootCA.key 2048openssl req -x509 -new -nodes -key temp/certs/rootCA.key -sha256 -days 1024 -out temp/certs/rootCA.pem

You’ll have to enter a passphrase for the root certificates and the certificate information.

Enter pass phrase for temp/certs/rootCA.key:
Verifying - Enter pass phrase for temp/certs/rootCA.key:
Enter pass phrase for temp/certs/rootCA.key:You are about to be asked to enter information that will be incorporated into your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:UK
State or Province Name (full name) []:England
Locality Name (eg, city) []:London
Organization Name (eg, company) []:mycompany
Organizational Unit Name (eg, section) []:section
Common Name (eg, fully qualified host name) []:httpbin.example.com
Email Address []:your-administrative-address@your-awesome-existing-domain.com

Create the OpenSSL configuration file temp/certs/server.csr.cnf :

[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[dn]
C=UK
ST=England
L=London
O=mycompany
OU=section
emailAddress=your-administrative-address@your-awesome-existing-domain.com
CN = httpbin.example.com

Create the temp/certs/v3.ext file in order to create a X509 v3 certificate instead of a v1 which is the default:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = httpbin.example.com

Create a certificate and a private key for httpbin.example.com:

openssl req -new -sha256 -nodes -out temp/certs/httpbin.example.com.csr -newkey rsa:2048 -keyout temp/certs/httpbin.example.com.key -config temp/certs/server.csr.cnfopenssl x509 -req -in temp/certs/httpbin.example.com.csr -CA temp/certs/rootCA.pem -CAkey temp/certs/rootCA.key -CAcreateserial -out temp/certs/httpbin.example.com.crt -days 500 -sha256 -extfile temp/certs/v3.ext

Add the rootCA.pem certificate to the Chrome browser. Mark it as trust in the Keychain.

Configure a TLS ingress gateway for a single domain

Create a secret for the ingress gateway:

kubectl create -n istio-system secret tls httpbin-credential --key=temp/certs/httpbin.example.com.key --cert=temp/certs/httpbin.example.com.crt

Define a gateway with a servers: section for port 443, and specify values for credentialName to be httpbin-credential. The values are the same as the secret’s name. The TLS mode should have the value of SIMPLE.

It’s a Istio Security Best Practice to avoid overly broad hosts configurations.

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygateway
spec:
selector:
istio: ingressgateway # use istio default ingress gateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: httpbin-credential # must be the same as secret
hosts:
- httpbin.example.com
EOF

Configure the gateway’s ingress traffic routes. Define the corresponding virtual service.

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "httpbin.example.com"
gateways:
- mygateway
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /delay
route:
- destination:
port:
number: 8000
host: httpbin
EOF

Accessing the httpbin application via HTTPS

Send an HTTPS request to access the httpbin service through HTTPS:

curl -v -HHost:httpbin.example.com --resolve "httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" \
--cacert temp/certs/httpbin.example.com.crt "https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418"

Results:

* Added httpbin.example.com:443:127.0.0.1 to DNS cache
* Hostname httpbin.example.com was found in DNS cache
* Trying 127.0.0.1:443...
* Connected to httpbin.example.com (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: temp/certs/httpbin.example.com.crt
* CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=UK; ST=England; L=London; O=mycompany; OU=section; emailAddress=your-administrative-address@your-awesome-existing-domain.com; CN=httpbin.example.com
* start date: Jul 31 15:34:56 2022 GMT
* expire date: Dec 13 15:34:56 2023 GMT
* subjectAltName: host "httpbin.example.com" matched cert's "httpbin.example.com"
* issuer: C=UK; ST=England; L=London; O=mycompany; OU=section; CN=httpbin.example.com; emailAddress=your-administrative-address@your-awesome-existing-domain.com
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x12d80e800)
> GET /status/418 HTTP/2
> Host:httpbin.example.com
> user-agent: curl/7.79.1
> accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
< HTTP/2 418
< server: istio-envoy
< date: Sun, 31 Jul 2022 15:36:46 GMT
< x-more-info: http://tools.ietf.org/html/rfc2324
< access-control-allow-origin: *
< access-control-allow-credentials: true
< content-length: 135
< x-envoy-upstream-service-time: 32
<
-=[ teapot ]=- _...._
.' _ _ `.
| ."` ^ `". _,
\_;`"---"`|//
| ;/
\_ _/
`"""`
* Connection #0 to host httpbin.example.com left intact

Access via browser and see the certificate:

Accessing httpbin app securely — Image from author

Understanding what happened

In the preceding steps, I used OpenSSL to generate root certificates and use my local machine as a Certificate Authority. A certificate was created specifically for the domain httpbin.example.com and added to my local keychain. These processes allow the usage of TLS/SSLlocally.

A K8s secret is created to store the certificate and private key in the cluster.

A Gateway is configured to listen in the secure port 443 with TLS as SIMPLE. Meaning the TLS communication is terminated in the istio-ingressgateway. The ingress gateway retrieves certificate information corresponding to a specific credentialName.

The Virtual Service make the traffic management and policy features to the httpbin app.

Clean-up

  • Remove the certificate from the Keychain
# istio resources
kubectl delete gateway mygateway
kubectl delete virtualservice httpbin
kubectl delete -n istio-system secret httpbin-credential
kubectl delete -f samples/httpbin/httpbin.yaml
# certificate files
rm -rf temp/certs/rootCA.*
rm -rf temp/certs/httpbin.example.com.*

Secure Gateways — HTTPS endpoint wildcard

The previous task describes how to configure an ingress gateway to expose an specific HTTPS service using simple TLS. This task shows how to expose services using a wildcard certificate.

Make sure to perform the steps in the Before you begin and Determining the ingress IP and ports sections.

Additionally, for this task, deploy the helloworld sample application:

kubectl apply -f samples/helloworld/helloworld.yaml

and update the /etc/hosts file:

sudo vi /etc/hosts
127.0.0.1 helloworld.example.com

Generate client and server certificates and keys

For this task, you can use your favourite tool to generate certificates and keys. The commands below use OpenSSL.

Since version 58, Chrome requires SSL certificates to use SAN (Subject Alternative Name) instead of the popular Common Name (CN). Additional steps are necessary to make a self-signed certificate to work. The commands below were based on: Fixing Chrome 58+ [missing_subjectAltName] with OpenSSL when using self-signed certificates.

Create a root certificate and private key to sign the certificates for your services:

mkdir -p temp/certsopenssl genrsa -des3 -out temp/certs/rootCA.key 2048openssl req -x509 -new -nodes -key temp/certs/rootCA.key -sha256 -days 1024 -out temp/certs/rootCA.pem

You’ll have to enter a passphrase for the root certificates and the certificate information.

Country Name (2 letter code) [AU]:UK
State or Province Name (full name) [Some-State]:England
Locality Name (eg, city) []:London
Organization Name (eg, company) [Internet Widgits Pty Ltd]:mycompany
Organizational Unit Name (eg, section) []:section
Common Name (e.g. server FQDN or YOUR name) []:*.example.comEmail Address []:your-administrative-address@your-awesome-existing-domain.com

Create the OpenSSL configuration file temp/certs/server.csr.cnf :

[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[dn]
C=UK
ST=LN
L=London
O=Beazley
OU=mda
emailAddress=your-administrative-address@your-awesome-existing-domain.com
CN = *.example.com

Create the temp/certs/v3.ext file in order to create a X509 v3 certificate instead of a v1 which is the default:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = httpbin.example.com
DNS.2 = helloworld.example.com

Create a certificate and a private key for *.example.com:

openssl req -new -sha256 -nodes -out temp/certs/wildcard.example.com.csr -newkey rsa:2048 -keyout temp/certs/wildcard.example.com.key -config temp/certs/server.csr.cnfopenssl x509 -req -in temp/certs/wildcard.example.com.csr -CA temp/certs/rootCA.pem -CAkey temp/certs/rootCA.key -CAcreateserial -out temp/certs/wildcard.example.com.crt -days 500 -sha256 -extfile temp/certs/v3.ext

Add the rootCA.pem certificate to the Chrome browser.

Configure a TLS ingress gateway with wildcard domain

Create a secret for the ingress gateway:

kubectl create -n istio-system secret tls wildcard-credential --key=temp/certs/wildcard.example.com.key --cert=temp/certs/wildcard.example.com.crt

Define a gateway with a servers: section for port 443, and specify values for credentialName to be wildcard-credential. The values are the same as the secret’s name. The TLS mode should have the value of SIMPLE.

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygateway
spec:
selector:
istio: ingressgateway # use istio default ingress gateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: wildcard-credential # must be the same as secret
hosts:
- '*.example.com'
EOF

Configure the gateway’s ingress traffic routes. Define the corresponding virtual services for httpbin and helloworld.

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "httpbin.example.com"
gateways:
- mygateway
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /delay
route:
- destination:
port:
number: 8000
host: httpbin
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- "helloworld.example.com"
gateways:
- mygateway
http:
- match:
- uri:
exact: /hello
route:
- destination:
host: helloworld
port:
number: 5000
EOF

Accessing the httpbin application via HTTPS

Send an HTTPS request to access the httpbin service through HTTPS:

curl -v -HHost:httpbin.example.com --resolve "httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" --cacert temp/certs/wildcard.example.com.crt  "https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418"

Results:

Attention to the Server certificate where you can see we are using the wildcard certificate.

* Added httpbin.example.com:443:127.0.0.1 to DNS cache
* Hostname httpbin.example.com was found in DNS cache
* Trying 127.0.0.1:443...
* Connected to httpbin.example.com (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: temp/certs/wildcard.example.com.crt
* CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=UK; ST=England; L=London; O=mycompany; OU=section; emailAddress=your-administrative-address@your-awesome-existing-domain.com; CN=*.example.com
* start date: Jul 31 16:00:33 2022 GMT
* expire date: Dec 13 16:00:33 2023 GMT
* subjectAltName: host "httpbin.example.com" matched cert's "httpbin.example.com"
* issuer: C=UK; ST=England; L=London; O=mycompany; OU=section; CN=*.example.com; emailAddress=your-administrative-address@your-awesome-existing-domain.com
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x12d012800)
> GET /status/418 HTTP/2
> Host:httpbin.example.com
> user-agent: curl/7.79.1
> accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
< HTTP/2 418
< server: istio-envoy
< date: Sun, 31 Jul 2022 16:05:44 GMT
< x-more-info: http://tools.ietf.org/html/rfc2324
< access-control-allow-origin: *
< access-control-allow-credentials: true
< content-length: 135
< x-envoy-upstream-service-time: 5
<
-=[ teapot ]=-_...._
.' _ _ `.
| ."` ^ `". _,
\_;`"---"`|//
| ;/
\_ _/
`"""`
* Connection #0 to host httpbin.example.com left intact

Access via browser and see the certificate:

Accessing httpbin app securely with a wildcard certificate — Image from author

Accessing the helloworld application via https

Send an HTTPS request to access the helloworld service through HTTPS:

curl -v -HHost:helloworld.example.com --resolve "helloworld.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" \
--cacert temp/certs/wildcard.example.com.crt "https://helloworld.example.com:$SECURE_INGRESS_PORT/hello"

Results:

Attention to the Server certificate where you can see we are using the wildcard certificate.

* Added helloworld.example.com:443:127.0.0.1 to DNS cache
* Hostname helloworld.example.com was found in DNS cache
* Trying 127.0.0.1:443...
* Connected to helloworld.example.com (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: temp/certs/wildcard.example.com.crt
* CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=UK; ST=England; L=London; O=mycompany; OU=section; emailAddress=your-administrative-address@your-awesome-existing-domain.com; CN=*.example.com
* start date: Jul 31 16:00:33 2022 GMT
* expire date: Dec 13 16:00:33 2023 GMT
* subjectAltName: host "helloworld.example.com" matched cert's "helloworld.example.com"
* issuer: C=UK; ST=England; L=London; O=mycompany; OU=section; CN=*.example.com; emailAddress=your-administrative-address@your-awesome-existing-domain.com
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x14e80ca00)
> GET /hello HTTP/2
> Host:helloworld.example.com
> user-agent: curl/7.79.1
> accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
< HTTP/2 200
< content-type: text/html; charset=utf-8
< content-length: 60
< server: istio-envoy
< date: Sun, 31 Jul 2022 16:10:49 GMT
< x-envoy-upstream-service-time: 977
<
Hello version: v1, instance: helloworld-v1-776f57d5f6-dk9xs
* Connection #0 to host helloworld.example.com left intact

Access via browser and see the certificate:

Accessing helloworld app securely with a wildcard certificate — Image from author

Understanding what happened

This task is an alternative to the previous. The main difference is that I'm creating one certificate that can be used for multiple hosts.

When creating the certificate and private key the CN=*.example.com is used meaning it accepts all hosts for the example.com domain. This is matched in the hosts entry for the Gateway.

To illustrate this functionality, 2 sample applications and 2 Virtual Services are configured to direct traffic for each application.

Clean-up

  • Remove the certificate from the Keychain
# istio resources
kubectl delete gateway mygateway
kubectl delete virtualservice httpbin
kubectl delete virtualservice helloworld
kubectl delete -n istio-system secret wildcard-credential
kubectl delete -f samples/httpbin/httpbin.yaml
kubectl delete -f samples/helloworld/helloworld.yaml
# certificate files
rm -rf temp/certs/rootCA.*
rm -rf temp/certs/wildcard.example.com.*

Summary

In this article, I walk you through the necessary configurations to expose services inside a Service Mesh to external traffic. The first scenario covered an HTTP endpoint. The second scenario examined the HTTPS configurations. In the second scenario, I presented two possible paths; one using a single domain and another with a wildcard certificate.

--

--