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 release archive file 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 pods 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
logLevel
andenableCoreDump
fields 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#
Create a namespace named
simpleserver
:$ kubectl create namespace simpleserver
Apply the
istio-injection
label to thesimpleserver
namespace:$ kubectl label namespace simpleserver istio-injection=enabled --overwrite
Change to the Aspen Mesh release directory.
Install the
simpleserver
dual-stack service in thesimpleserver
namespace:$ helm install simpleserver-dualstack samples/simpleserver/ \ --set mode=dualstack \ --namespace simpleserver
Create the sleep single-stack service#
Create a namespace named
sleep
:$ kubectl create namespace sleep
Apply the
istio-injection
label to thesleep
namespace:$ kubectl label namespace sleep istio-injection=enabled --overwrite
Change to the Aspen Mesh release directory.
Create the
sleep
service account, service, and deployment in thesleep
namespace:$ kubectl apply -f samples/sleep/sleep.yaml --namespace sleep
Verify that the control plane and data plane are configured for dual-stack networking#
In the Aspen Mesh release directory, execute the script to verify your dual-stack configuration:
$ ./tools/verify-dual-stack.sh simpleserver
Did the script complete without errors?
Yes: Go to the next task.
No: Correct the errors identified by the script and then execute it again.
Verify that the DNS server can return IPv4 and IPv6 addresses#
Use the
sleep
service to verify that the DNS server can return an IPv4 (type A) record for thesimpleserver
service:$ 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
simpleserver
service and its IPv4 address, like this:Name: simpleserver-dualstack.simpleserver.svc.cluster.local Address: 10.122.180.62
Use the
sleep
service to verify that the DNS server can return an IPv6 (type AAAA) record for thesimpleserver
service:$ 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
simpleserver
service 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
sleep
sidecar and thesimpleserver
sidecar—and between thesimpleserver
sidecar and container—may differ from the IP family used between thesleep
container 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
sleep
sidecar and thesimpleserver
sidecar—and between thesimpleserver
sidecar and container—may differ from the IP family used between thesleep
container and sidecar.
Verify IPv4 and IPv6 connectivity between clients outside your cluster and services inside your service mesh#
Get the IPv4 address of your ingress gateway service:
If you’re using a cloud provider:
LB=$(kubectl get service istio-ingressgateway --namespace <ingressNamespaceName> \ -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')
If you’re using bare metal:
LB=$(kubectl get service istio-ingressgateway --namespace <ingressNamespaceName> \ -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
Verify IPv4 connectivity between clients outside your cluster and services inside your service mesh:
$ 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:
If you’re using a cloud provider:
LB=$(kubectl get service istio-ingressgateway --namespace <ingressNamespaceName> \ -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')
If you’re using bare metal:
LB=$(kubectl get service istio-ingressgateway --namespace <ingressNamespaceName> \ -o=jsonpath='{.status.loadBalancer.ingress[1].ip}')
Verify IPv6 connectivity between clients outside your cluster and services inside your service mesh:
$ 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
simpleserver
dual-stack service:$ helm uninstall simpleserver-dualstack --namespace simpleserver --wait
Delete the
simpleserver
namespace:$ kubectl delete namespace simpleserver
Delete the
sleep
namespace:$ 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 part of your service mesh:
Look at the manifest for the service.
Are the
.spec.ipFamilyPolicy
and.spec.ipFamilies
fields 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.ipFamilyPolicy
and.spec.ipFamilies
fields 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 pods with sidecars:
$ 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 the Aspen Mesh release 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: Correct the errors identified by the script and then execute it again.
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 part of the service 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 part of the service 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.