[TOC]
/etc/resolv.conf
這個文件是 linux 里的一個配置文件,做 dns 解析用的
https://linux.die.net/man/5/resolv.conf
在 k8s pod 里長這個樣子卿泽,pod 里面執(zhí)行 cat /etc/resolv.conf
nameserver 172.23.0.10
search backend.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5
其中 nameserver
就是 coredns
的 service
(也就是 kube-dns
) 的 ip (虛擬ip泼菌,也叫 vip
)
search
是搜索順序, backend
是pod所在命名空間
options
是一些選項
ndots 含義
ndots
意思就是 點號.
(dot) 的個數(shù)
ndots: 5
就是 5個點號
5個點號
的意思就是說
對于一個 域名嘲更, 如果不是完全限定名(即某個域名不是以.
結(jié)尾茬暇, a.com
不是燃观, a.com.
是)
且點號數(shù)量少于5個
, 那么就按照 search
的順序织阅,依次解析
如果點號大于或者等于5, 直接解析
如上面的 search 配置項表達(dá)的解析順序就是
- backend.svc.cluster.local
- svc.cluster.local
- cluster.local
- localdomain
舉例說明
假設(shè)有兩個服務(wù)绎签,A
和B
枯饿, A
現(xiàn)在要請求 B
的接口 GET /api/b/users
那么請求可以長這個樣子 GET http://B/api/b/usres
, B
服務(wù)的name 可以當(dāng)成 域名來用
HTTP 報文如下
GET /api/b/users HTTP/1.1
Host: B
Accept: */*
Content-Type: application/json
實際解析域名的時候,按照順序解析诡必,解析到就返回 ip
順序如下
- B.backend.svc.cluster.local
- B.svc.cluster.local
- B.cluster.local
- B.localdomain
- B
也就是說我們訪問B的服務(wù)奢方,域名的寫法可以有很多種,都是支持的,如:
GET http://B/api/b/usres
GET http://B.backend/api/b/usres
GET http://B.backend.svc/api/b/usres
既然有這么多種寫法爸舒,那么有沒有最優(yōu)解呢蟋字?
數(shù)量對比試驗
ndots=5, 域名點號=4
# cat /etc/resolv.conf
nameserver 172.23.0.10
search backend.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5
# host -av r-wz9f2fc78874fa04.redis.rds.aliyuncs.com
Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com.backend.svc.cluster.local"
Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com.svc.cluster.local"
Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com.cluster.local"
Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com.localdomain"
Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29554
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. IN ANY
;; ANSWER SECTION:
r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. 19 IN A 172.16.4.243
Received 116 bytes from 172.23.0.10#53 in 0 ms
通過日志可以發(fā)現(xiàn)
- 此時配置里的點號是5,
ndots:5
- 而我們的域名包含4個點
.
扭勉, 4小于5鹊奖,所以按照seacrh順序添加后綴之后依次解析,都解析不到的情況下不加后綴去解析,日志Trying
可以證明這一點
可以看出來涂炎,策略就是: 優(yōu)先把域名當(dāng)成內(nèi)網(wǎng)的來解析忠聚,內(nèi)網(wǎng)解析不到就當(dāng)成外網(wǎng)去解析
ndots=4, 域名點號=4
# cat /etc/resolv.conf
nameserver 172.23.0.10
search backend.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:4
# host -av r-wz9f2fc78874fa04.redis.rds.aliyuncs.com
Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37171
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. IN ANY
;; ANSWER SECTION:
r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. 30 IN A 172.16.4.243
Received 116 bytes from 172.23.0.10#53 in 1 ms
通過日志可以發(fā)現(xiàn)
- 此時配置里的點號是4设哗,
ndots:4
- 而我們的域名包含4個點
.
, 4不
小于4两蟀,所以不
按照seacrh順序解析网梢,直接拿來解析,日志Trying
可以證明這一點
ndots=3, 域名點號=4
# cat /etc/resolv.conf
nameserver 172.23.0.10
search backend.svc.cluster.local svc.cluster.local cluster.local
options ndots:3
# host -av r-wz9f2fc78874fa04.redis.rds.aliyuncs.com
Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 549
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. IN ANY
;; ANSWER SECTION:
r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. 30 IN A 172.16.4.243
Received 116 bytes from 172.23.0.10#53 in 1 ms
- 此時配置里的點號是3垫竞,
ndots:3
- 而我們的域名包含4個點
.
澎粟, 4不
小于3蛀序,所以不
按照seacrh順序解析欢瞪,直接拿來解析,日志Trying
可以證明這一點
上面都是外網(wǎng)域名徐裸,接下來試一下內(nèi)網(wǎng)的
ndots=3, 內(nèi)網(wǎng)域名點號=1
# cat /etc/resolv.conf
nameserver 172.23.0.10
search backend.svc.cluster.local svc.cluster.local cluster.local
options ndots:3
# host -av b.backend
Trying "b.backend.backend.svc.cluster.local"
Trying "b.backend.svc.cluster.local"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41190
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;agent-app-service.backend.svc.cluster.local. IN ANY
;; AUTHORITY SECTION:
cluster.local. 30 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1568253402 7200 1800 86400 30
Received 154 bytes from 172.23.0.10#53 in 1 ms
- 1小于3遣鼓,所以會嘗試;
- 在嘗試第二次的時候就找到了
如何調(diào)整
終上所述重贺,對于內(nèi)網(wǎng)域名骑祟、外網(wǎng)域名,我們都希望盡可能少的進(jìn)行 DNS 解析气笙,以便提升性能
對于內(nèi)網(wǎng)域名次企,這個好說,因為都是我們的代碼可以控制的潜圃,可以改缸棵;外網(wǎng)域名改不了,著重研究一下
我們的服務(wù)對于外部調(diào)用比較頻繁的大概有三類 redis
mongodb
es
-
redis
r-xxx.redis.rds.aliyuncs.com
4個點號
-
mongodb
dds-xxx.mongodb.rds.aliyuncs.com
4個點號
-
es
es-xxx.elasticsearch.aliyuncs.com
3個點號
想要外網(wǎng)地址不走k8s解析的谭期,可以取最小值3
堵第;
所以,我們可以設(shè)置點號數(shù)量為 3
- 對于外部調(diào)用隧出,
3
可以覆蓋踏志,直接解析 - 對于內(nèi)部調(diào)用,直接要求大家寫成全限定名
serviceName.namespace.svc.cluster.local.
胀瞪,也是直接解析的
之所以不設(shè)置為1
(畢竟設(shè)置為1也是可以的)针余, 就是想保留這個特性,在手動測試的時候凄诞,因為不追求性能涵紊,所以可以少寫一點,如 get http://b/api/users
很方便
如何修改
ndots
默認(rèn)的值是1幔摸, coredns
將其設(shè)置成5了
但是摸柄,想要修改 ndots
,不是去修改 coredns
的配置既忆,走了一些彎路驱负,這里貼出來
coredns
首先想的是去修改 CoreDNS 的配置項
把 coredns
的配置文件復(fù)制出來嗦玖,可以看見
其配置文件并沒有 ndots
選項
nameserver 100.100.2.136
nameserver 100.100.2.138
options timeout:2 attempts:3 rotate single-request-reopen
手動修改
進(jìn)入容器里面手動修改是沒有用的,需要重啟網(wǎng)絡(luò)模塊才會生效
一重啟容器沒了跃脊,改了等于白改
init containers
initContainers
也是一堆坑
k8s yaml
其實k8s
給我們提供了參數(shù)宇挫,叫做 dnsConfig
, 如下所示
dnsConfig:
options:
- name: ndots
value: '3'
dnsPolicy: ClusterFirst
所以最后酪术,我們選擇了使用 k8s yaml
的方式來修改器瘪,對于老的服務(wù)直接修改;對于新的服務(wù)绘雁,在上線模板里配置好這個值
參考文章
https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/