Verify dual-stack functionality and configure your services#
Overview#
When to follow these instructions#
Follow the instructions below only as part of a dual-stack clean installation and only when other instructions tell you to do so. Perform the tasks in order.
Install the debug sidecar proxy#
Introduction#
The Aspen Mesh Platform chart includes a script (verify-dual-stack.sh) to verify your dual-stack configuration and provide information on your services and pods. If you install the debug sidecar proxy instead of the standard sidecar proxy, the script can also provide port information for your on-mesh pods (those with sidecars), which includes the addresses that your applications are listening on.
Install the debug sidecar proxy#
Install the debug sidecar proxy.
Because you won’t be collecting debug information, you can leave the
logLevelandenableCoreDumpfields commented out when adding information to your Aspen Mesh override values file.
Verify dual-stack functionality using sample services and applications#
Introduction#
Before you make any changes to your services and applications, verify dual-stack functionality using sample services and applications. Perform the following tasks in order.
Install the simpleserver dual-stack service and gateway#
In a terminal window on your computer, make sure you’re in the Aspen Mesh Platform chart directory.
Create a namespace named
simpleserver:$ kubectl create namespace simpleserver
Enable automatic sidecar injection in the
simpleservernamespace:$ kubectl label namespace simpleserver istio-injection=enabled --overwrite
Install the
simpleserverdual-stack service in thesimpleservernamespace:$ helm install simpleserver-dualstack samples/simpleserver/ \ --set mode=dualstack \ --namespace simpleserver
Create the sleep single-stack service#
In a terminal window on your computer, make sure you’re in the Aspen Mesh Platform chart directory.
Create a namespace named
sleep:$ kubectl create namespace sleep
Enable automatic sidecar injection in the
sleepnamespace:$ kubectl label namespace sleep istio-injection=enabled --overwrite
Create the
sleepservice account, service, and deployment in thesleepnamespace:$ kubectl apply -f samples/sleep/sleep.yaml --namespace sleep
Verify that the control plane and data plane are configured for dual-stack networking#
In a terminal window on your computer, make sure you’re in the Aspen Mesh Platform chart directory.
Execute the script to verify your dual-stack configuration:
$ ./tools/verify-dual-stack.sh simpleserver
If the script indicates an error, make the suggested change, then go to step 2.
Verify that the DNS server can return IPv4 and IPv6 addresses#
Use the
sleepservice to verify that the DNS server can return an IPv4 (type A) record for thesimpleserverservice:$ kubectl exec -it --namespace sleep \ $(kubectl get pod --selector app=sleep --namespace sleep -o jsonpath="{.items[0].metadata.name}") \ -- nslookup -type=a simpleserver-dualstack.simpleserver.svc.cluster.local
The last two lines of the output should include the domain name of the
simpleserverservice and its IPv4 address, like this:Name: simpleserver-dualstack.simpleserver.svc.cluster.local Address: 10.122.180.62
Use the
sleepservice to verify that the DNS server can return an IPv6 (type AAAA) record for thesimpleserverservice:$ kubectl exec -it --namespace sleep \ $(kubectl get pod --selector app=sleep --namespace sleep -o jsonpath="{.items[0].metadata.name}") \ -- nslookup -type=aaaa simpleserver-dualstack.simpleserver.svc.cluster.local
The last two lines of the output should include the domain name of the
simpleserverservice and its IPv6 address, like this:Name: simpleserver-dualstack.simpleserver.svc.cluster.local Address: fd00:abcd:2:122::44e5
Verify IPv4 and IPv6 data-plane connectivity#
Verify IPv4 connectivity between services in your service mesh:
$ kubectl exec -it --namespace sleep \ $(kubectl get pod --selector app=sleep --namespace sleep -o jsonpath="{.items[0].metadata.name}") \ -- curl simpleserver-dualstack.simpleserver:8090/headers -4
The output should include either an IPv4 remote address and
ipv4 handler, like this:remote addr: 127.0.0.1:58660 host addr: simpleserver-dualstack.simpleserver:8090 ipv4 handler
Or an IPv6 remote address and
ipv6 handler, like this:remote addr: [::1]:34312 host addr: simpleserver-dualstack.simpleserver:8090 ipv6 handler
Note
Sidecars are free to choose the IP family they use to address containers and other sidecars. Therefore, the IP family used between the
sleepsidecar and thesimpleserversidecar—and between thesimpleserversidecar and container—may differ from the IP family used between thesleepcontainer and sidecar.Verify IPv6 connectivity between services in your service mesh:
$ kubectl exec -it --namespace sleep \ $(kubectl get pod --selector app=sleep --namespace sleep -o jsonpath="{.items[0].metadata.name}") \ -- curl simpleserver-dualstack.simpleserver:8090/headers -6
The output should include either an IPv4 remote address and
ipv4 handler, like this:remote addr: 127.0.0.1:58660 host addr: simpleserver-dualstack.simpleserver:8090 ipv4 handler
Or an IPv6 remote address and
ipv6 handler, like this:remote addr: [::1]:34312 host addr: simpleserver-dualstack.simpleserver:8090 ipv6 handler
Note
Sidecars are free to choose the IP family they use to address containers and other sidecars. Therefore, the IP family used between the
sleepsidecar and thesimpleserversidecar—and between thesimpleserversidecar and container—may differ from the IP family used between thesleepcontainer and sidecar.
Verify IPv4 and IPv6 connectivity between off-cluster clients and on-mesh services#
Get the IPv4 address of your ingress gateway service:
Cloud provider
LB=$(kubectl get service istio-ingressgateway --namespace <ingressNamespaceName> \ -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')
Bare metal
LB=$(kubectl get service istio-ingressgateway --namespace <ingressNamespaceName> \ -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
Verify IPv4 connectivity between off-cluster clients and on-mesh services:
$ curl -4 ${LB}
Does the output indicate that the connection succeeded?
Yes:
Go to step 4.
No:
Contact Aspen Mesh Support.
Get the IPv6 address of your ingress gateway service:
Cloud provider
LB=$(kubectl get service istio-ingressgateway --namespace <ingressNamespaceName> \ -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')
Bare metal
LB=$(kubectl get service istio-ingressgateway --namespace <ingressNamespaceName> \ -o=jsonpath='{.status.loadBalancer.ingress[1].ip}')
Verify IPv6 connectivity between off-cluster clients and on-mesh services:
$ curl -6 "http://[${LB}]"
Does the output indicate that the connection succeeded?
Yes:
Go to the next task.
No:
Contact Aspen Mesh Support.
Delete the verification environment#
Uninstall the
simpleserverdual-stack service:$ helm uninstall simpleserver-dualstack --namespace simpleserver --wait
Delete the
simpleservernamespace:$ kubectl delete namespace simpleserver
Delete the
sleepnamespace:$ kubectl delete namespace sleep
Configure your services for dual-stack networking#
Introduction#
OpenShift 4.7 and later and Kubernetes 1.20 and later include fields that you use to configure dual-stack networking for services:
.spec.ipFamilyPolicy.spec.ipFamilies
Recommended IP family specification for dual-stack networking#
This is the recommended IP family specification for dual-stack networking:
spec:
ipFamilyPolicy: RequireDualStack
ipFamilies: # Either IPv4 or IPv6 can be listed first.
- IPv4
- IPv6
Fields in the recommended IP family specification for dual-stack networking#
This table describes the fields in the recommended IP family specification for dual-stack networking:
Field |
Description |
|---|---|
|
|
|
Either |
Configure your services for dual-stack networking#
Follow these steps for each of your services that you want to support dual-stack networking, regardless of whether the service is on-mesh:
Look at the manifest for the service.
Are the
.spec.ipFamilyPolicyand.spec.ipFamiliesfields set as shown in Recommended IP family specification for dual-stack networking above?Yes:
Stop. The service is configured correctly for dual-stack networking.
No:
Go to step 3.
Set the
.spec.ipFamilyPolicyand.spec.ipFamiliesfields as shown in Recommended IP family specification for dual-stack networking.Delete the service:
$ kubectl delete -f <serviceManifestFilename> --namespace <namespaceName>
Create the service:
$ kubectl create -f <serviceManifestFilename> --namespace <namespaceName>
Restart all on-mesh pods:
$ kubectl delete pods --namespace <namespaceName> --selector security.istio.io/tlsMode=istio
Verify your dual-stack configuration#
Verify your dual-stack configuration#
Follow these steps for each namespace that contains services that should support dual-stack networking:
In a terminal window on your computer, make sure you’re in the Aspen Mesh Platform chart directory.
Execute the script to verify your dual-stack configuration:
$ ./tools/verify-dual-stack.sh <namespaceName>
Did the script complete without errors?
Yes:
Use the script output to verify that your applications support dual-stack networking. See Verify that your applications support dual-stack networking.
No:
Make the suggested change, then go to step 2.
Uninstall the debug sidecar proxy#
Introduction#
Now that you’ve completed verifying your dual-stack configuration, you can uninstall the debug sidecar proxy.
Uninstall the debug sidecar proxy#
Verify that your applications support dual-stack networking#
Introduction#
In addition to configuring your services for dual-stack networking, you must verify that applications that are on-mesh—and that you want to respond to requests on both IPv4 and IPv6 addresses—are designed to listen on both IPv4 and IPv6 addresses. If an application doesn’t listen on one type of address, clients that make an HTTP request to that type of address will receive a 500 error (clients that make a TCP request will receive a connection-refused error).
How a service responds#
The following table illustrates how a service responds to a request from a client based on the service’s IP family specification and the addresses the application listens on. The combination shown in the last row ensures the desired behavior.
When a service’s IP family specification is set for |
And the application listens on |
Then |
|---|---|---|
IPv4 only |
IPv4 only |
- IPv4: Requests are proxied and routed over IPv4 only. |
IPv4 only |
IPv6 only |
- IPv4: The client receives a 500 error. |
IPv4 only |
IPv4 and IPv6 |
- IPv4: Requests are proxied and routed over IPv4 only. |
IPv6 only |
IPv4 only |
- IPv4: (Requests can’t be made over IPv4.) |
IPv6 only |
IPv6 only |
- IPv4: (Requests can’t be made over IPv4.) |
IPv6 only |
IPv4 and IPv6 |
- IPv4: (Requests can’t be made over IPv4.) |
IPv4 and IPv6 |
IPv4 only |
- IPv4: Requests are proxied and routed over IPv4 only. |
IPv4 and IPv6 |
IPv6 only |
- IPv4: The client receives a 500 error. |
IPv4 and IPv6 |
IPv4 and IPv6 |
- IPv4: Requests are proxied and routed over IPv4 or IPv6. |
Addresses that your applications should listen on#
Applications that are on-mesh—and that you want to respond to requests on both IPv4 and IPv6 addresses—should be designed to listen on both of the following addresses:
0.0.0.0(IPv4)::(IPv6)
Note
Listening on the localhost addresses (127.0.0.1 and ::1) is not supported.
Verify that your applications support dual-stack networking#
If one of your services isn’t responding as expected, ask the application developer to update the application so it listens on both the IPv4 and IPv6 addresses in Addresses that your applications should listen on.