Set up DNS Proxy
DNS Proxy is a feature for providing the following capabilities:
- Propagating DNS entries of
Servicesacross clusters in a multi-cluster setup. - Populating DNS entries for
ServiceEntry.
Kubernetes provides DNS resolution only for Services in the local cluster.
When you need to provide name resolution for Services in a remote clusters or
use an internal-only hostname with ServiceEntry without having an additional
internal-only DNS server, DNS Proxy provides a way to resolve DNS names for such
cases.
Configuring DNS Proxy
To configure DNS proxy, configure ISTIO_META_DNS_CAPTURE flag as follows. You can choose either the cluster or per-proxy wide configuration.
Cluster wide configuration
To configure DNS proxy in the cluster, add ISTIO_META_DNS_CAPTURE proxy
metadata to the ConfigMap for MeshConfig. The name of the ConfigMap
has a format of istio-<revision_name>. For the details of revision, refer
to the overview of the revision
apiVersion: v1
data:
mesh: |-
...
defaultConfig:
proxyMetadata:
ISTIO_META_DNS_CAPTURE: "true"
...
kind: ConfigMap
metadata:
name: istio-<revision_name>
namespace: istio-system
Per-proxy configuration
To configure DNS proxy for a proxy, add the ISTIO_META_DNS_CAPTURE proxy
metadata annotation as follows:
kind: Deployment
metadata:
name: app1
namespace: ns1
spec:
...
template:
metadata:
annotations:
proxy.istio.io/config: |
proxyMetadata:
ISTIO_META_DNS_CAPTURE: "true"
...
Verifying
To verify everything is configured correctly, run the steps.
Name resolution for Service across clusters
After the multi-cluster setup,
deploy a Service only in one of the clusters to verify the cross-cluster name
resolution.
When you have the following example Service ns1/svc1,
you can find ClusterIP in Service.
$ kubectl get -n ns1 svc1
kind: Service
metadata:
name: svc1
namespace: ns1
spec:
...
ClusterIP: 210.200.1.1
...
Then, when using curl from the other cluster to the Service, it
should show the ClusterIP as follows.
curl -sS -v svc1.ns1.svc.cluster.local
* Trying 210.200.1.1:80...
Name resolution for ServiceEntry
Add a ServiceEntry with a hostname not registered in your DNS.
To verify the name resolution the following example has explicit address
192.168.123.123.
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: test-service-entry
spec:
addresses:
- "192.168.123.123"
hosts:
- not-existing-hostname.internal
ports:
- name: http
number: 80
protocol: HTTP
EOF
Then, try DNS resolution in a Pod where DNS Proxy is enabled. For example, if
you run a curl in the Pod, it should display the IP address as follows:
curl -sS -v not-existing-hostname.internal
* Trying 192.168.123.123:80...
IP auto-allocation for ServiceEntry
When using ServiceEntry with DNS Proxy, you can optionally enable IP
auto-allocation. When enabled, internal IP addresses (from the
240.240.0.0/16 range) are automatically allocated for ServiceEntry hosts
that don't specify explicit IP addresses in spec.addresses.
Enabling IP auto-allocation
To enable IP auto-allocation, follow the instructions for your control plane implementation:
TRAFFIC_DIRECTOR
For the TRAFFIC_DIRECTOR control plane implementation, configure IP
auto-allocation in the asm-options ConfigMap within the istio-system
namespace by setting ip_auto_allocation: "true".
The following example shows an asm-options ConfigMap with IP
auto-allocation enabled:
apiVersion: v1
kind: ConfigMap
metadata:
name: asm-options
namespace: istio-system
data:
# Enable IP auto-allocation for ServiceEntry (Rapid channel)
ip_auto_allocation: "true"
You can also apply this configuration using kubectl patch:
kubectl patch configmap/asm-options -n istio-system --type merge \
-p '{"data":{"ip_auto_allocation":"true"}}'
ISTIOD
For clusters using the ISTIOD control plane implementation (in-cluster
or managed ISTIOD), configure IP auto-allocation by adding
ISTIO_META_DNS_AUTO_ALLOCATE: "true" to your proxy metadata within
MeshConfig:
apiVersion: v1
data:
mesh: |-
defaultConfig:
proxyMetadata:
ISTIO_META_DNS_CAPTURE: "true"
ISTIO_META_DNS_AUTO_ALLOCATE: "true"
kind: ConfigMap
metadata:
name: istio-<revision_name>
namespace: istio-system
Verifying IP auto-allocation
You can verify the IP auto-allocation works using the following steps.
Before the verification, create a ServiceEntry without specifying
spec.addresses:
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: auto-allocated-service-entry
namespace: ns1
spec:
hosts:
- auto-allocated.internal
ports:
- name: http
number: 80
protocol: HTTP
resolution: DNS
EOF
1. Check allocated address in status.addresses (TRAFFIC_DIRECTOR only)
In the TRAFFIC_DIRECTOR implementation, the controller allocates a VIP and
populates the status.addresses field of the ServiceEntry:
$ kubectl get serviceentry auto-allocated-service-entry -n ns1 -o yaml
The output displays the allocated address under status.addresses:
status:
addresses:
- host: auto-allocated.internal
value: 240.240.0.1
2. Test DNS resolution from a Pod (TRAFFIC_DIRECTOR and ISTIOD)
In both TRAFFIC_DIRECTOR and ISTIOD implementations, send a request from a
Pod where DNS Proxy is enabled to verify that name resolution resolves to the
allocated VIP:
$ kubectl exec deploy/curl -n ns1 -- curl -sS -v http://auto-allocated.internal
The connection attempt should resolve to the automatically allocated VIP
(for example, 240.240.0.1:80):
* Trying 240.240.0.1:80...