Skip to content

Commit f617f96

Browse files
committed
Add proposal for configurable pod resolv.conf
1 parent ecca8af commit f617f96

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Custom /etc/resolv.conf
2+
* Status: pending
3+
* Version: alpha
4+
* Implementation owner: Bowei Du <[bowei@google.com](mailto:bowei@google.com)>, Zihong Zheng <[zihongz@google.com](mailto:zihongz@google.com)>
5+
6+
# Overview
7+
The `/etc/resolv.conf` in a pod is managed by Kubelet and its contents are generated based on `pod.dnsPolicy`. For `dnsPolicy: Default`, `resolv.conf` is copied from the node where the pod is running. If the `dnsPolicy` is `ClusterFirst`, the contents of the resolv.conf is the hosts `resolv.conf` augmented with the following options:
8+
9+
* Search paths to add aliases for domain names in the same namespace and cluster suffix.
10+
* `options ndots` to 5 to ensure the search paths are searched for all potential matches.
11+
12+
The configuration of both search paths and `ndots` results in query amplification of five to ten times for non-cluster internal names. This is due to the fact that each of the search path expansions must be tried before the actual result is found. This order of magnitude increase of query rate imposes a large load on the kube-dns service. At the same time, there are user applications do not need the convenience of the name aliases and do not wish to pay this performance cost.
13+
14+
15+
## Existing workarounds
16+
17+
The current work around for this problem is to specify an FQDN for name resolution. Any domain name that ends with a period (e.g. `foo.bar.com.`) will not be search path expanded. However, use of FQDNs is not well-known practice and imposes application-level changes. Cluster operators may not have the luxury of enforcing such a change to applications that run on their infrastructure.
18+
19+
It is also possible for the user to insert a short shell script snippet that rewrites `resolv.conf` on container start-up. This has the same problems as the previous approach and is also awkward for the user. This also forces the container to have additional executable code such as a shell or scripting engine which increases the applications security surface area.
20+
21+
22+
# Proposal sketch
23+
24+
Add a new `pod.dnsPolicy: Custom` that allows for user customization of `resolv.conf`.
25+
26+
27+
## Pod API example
28+
29+
In the example below, the user wishes to add the pod namespace and a custom expansion to the search path, as they do not use the other name aliases:
30+
31+
```yaml
32+
# Pod spec
33+
apiVersion: v1
34+
kind: Pod
35+
metadata:
36+
namespace: ns1
37+
name: example
38+
spec:
39+
containers:
40+
- name: example
41+
image: example
42+
dnsPolicy: Custom
43+
dnsParams:
44+
searchPaths:
45+
- $NAMESPACE.svc.$CLUSTER
46+
- my.dns.search.suffix
47+
- $HOST
48+
options:
49+
- ndots: 2
50+
```
51+
52+
Given the following host `/etc/resolv.conf`:
53+
54+
```bash
55+
nameserver 1.2.3.4
56+
search foo.com
57+
options: ndots: 1
58+
```
59+
60+
The pod will get the following `/etc/resolv.conf`:
61+
62+
```bash
63+
nameserver 10.240.0.10
64+
# Populated from searchPaths
65+
search ns1.svc.cluster.local my.dns.search.suffix foo.com
66+
# Populated from options
67+
options ndots: 2
68+
```
69+
70+
## More examples
71+
72+
The following is a Pod dnsParams that only contains the host search paths:
73+
74+
```yaml
75+
dnsParams:
76+
searchPaths:
77+
- $HOST
78+
```
79+
80+
Override `ndots` and add custom search path. Note that overriding the ndot may break the functionality of some of the search paths the
81+
82+
```yaml
83+
dnsParams:
84+
searchPaths:
85+
- my.custom.suffix
86+
- $HOST
87+
options:
88+
- ndots: 3
89+
```
90+
91+
# API changes
92+
93+
```go
94+
type PodSpec struct {
95+
...
96+
DNSPolicy: string
97+
DNSParams: *PodDNSParams
98+
}
99+
100+
type PodDNSParams struct {
101+
SearchPaths: []string
102+
options: []string
103+
}
104+
105+
// This will not appear in types.go but is here for explication purposes.
106+
type DNSParamsSubstitution string
107+
const (
108+
DNSParamsSearchPathNamespace = "$NAMESPACE"
109+
DNSParamsSearchPathClusterDomain = "$CLUSTER"
110+
DNSParamsSearchPathHostPaths = "$HOST"
111+
)
112+
```
113+
114+
## Semantics
115+
### searchPath
116+
If `dnsPolicy: Custom` is used, then the `search` line will be constructed from the entries listed in `dnsParams.searchPath`:
117+
```go
118+
// Note: pseudocode does not include input validation.
119+
func SearchPath(params *PodDNSParams) {
120+
var searchPath []string
121+
for _, entry := range params.SearchPath {
122+
if entry == "$HOST" {
123+
searchPath = append(searchPath, HostSearchPaths...)
124+
break
125+
}
126+
labels := strings.Split(entry, ".")
127+
for i := range labels {
128+
if labels[0] == "$" {
129+
labels[i] = Substitute(labels[i])
130+
}
131+
}
132+
entry := string.Join(labels, ".")
133+
searchPath = append(searchPath, entry)
134+
}
135+
return searchPath
136+
}
137+
```
138+
139+
#### Substitutions
140+
`Substitute` will replace labels that being with `$` with values for the given Pod:
141+
142+
| Substitution | Description |
143+
| ---- | ---- |
144+
| `$NAMESPACE` | Namespace of the Pod |
145+
| `$CLUSTER` | Kubernetes cluster domain (e.g. `cluster.local`) |
146+
| `$HOST` | Host search paths. This is a special substitution that must appear at the end of the `searchPaths` list |
147+
148+
### options
149+
Each element of options will be copied unmodified as an options line.
150+
151+
### Invalid configurations
152+
153+
The follow configurations will result in an invalid Pod spec:
154+
155+
* An invalid domain name/substitution appears in `searchPaths`.
156+
* `dnsParams` is MUST be empty unless `dnsPolicy: Custom` is used.
157+
* Number of final search paths exceeds 5 (glibc limit).
158+
* `$HOST` is not the last item in `searchPaths`.
159+
* `ndots` is greater than 15 (glibc limit).
160+
161+
# References
162+
163+
* [Kubernetes DNS name specification](https://github.com/kubernetes/dns/blob/master/docs/specification.md)
164+
* [`/etc/resolv.conf manpage`](http://manpages.ubuntu.com/manpages/zesty/man5/resolv.conf.5.html)

0 commit comments

Comments
 (0)