久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

SkyDNS工作原理是什么

169次閱讀
沒有評論

共計(jì) 5953 個(gè)字符,預(yù)計(jì)需要花費(fèi) 15 分鐘才能閱讀完成。

這篇文章主要講解了“SkyDNS 工作原理是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學(xué)習(xí)“SkyDNS 工作原理是什么”吧!

SkyDNS2 是 SkyDNS Version 2.x 的統(tǒng)稱,其官方文檔只有 README.md,網(wǎng)上能找到的資料也不多,因此需要我們自行對代碼進(jìn)行一定的分析,才能對其有更好的理解,這就是本文的工作,通過走讀 SkyDNS 的代碼,了解其內(nèi)部架構(gòu)及其工作原理。

SkyDNS 工作原理

SkyDNS Server 的工作,依賴后端 Key-Value 存儲的支持。當(dāng)前支持 etcd 或 etcd3 作為 Backend(架構(gòu)圖中藍(lán)色部分),為 SkyDNS 提供配置和數(shù)據(jù)的管理。

通過環(huán)境變量 ETCD_MACHINES 進(jìn)行 etcd cluster 的配置,如果 Backend 為 etcd3,還需要設(shè)置 etcd 中 /v2/keys//skydns/config/etcd3 為 true。SkyDNS 中有 etcd client 模塊,負(fù)責(zé)與 ETCD_MACHINES 的通信。

SkyDNS 主要對應(yīng)的 etcd key path 如下:

/v2/keys/skydns/config
/v2/keys/skydns/local/skydns/east/production/rails
/v2/keys/skydns/local/skydns/dns/stub
/v2/keys/skydns/local/skydns/...

通過如下環(huán)境變量的配置,支持 prometheus 監(jiān)控(架構(gòu)圖中棕色部分)。如果想 disable prometheus 監(jiān)控,則配置環(huán)境變量 PROMETHEUS_PORT 的值為 0 即可。

Port = os.Getenv(PROMETHEUS_PORT)
Path = envOrDefault(PROMETHEUS_PATH ,  /metrics)
Namespace = envOrDefault(PROMETHEUS_NAMESPACE ,  skydns)
Subsystem = envOrDefault(PROMETHEUS_SUBSYSTEM ,  skydns)

如果 /v2/keys/skydns/config/nameservers 有值,則 SkyDNS 解析不了的 Domain,會 forward 到對應(yīng)的這些 IP:Port 構(gòu)成的 nameservers,由它們進(jìn)行解析(架構(gòu)圖中綠色部分)。

參考官方文檔 https://github.com/skynetservices/skydns/blob/master/README.md 完成參數(shù)配置后,便可啟動 SkyDNS。

SkyDNS Server 的啟動過程如下:

創(chuàng)建 etcd client 對象;

dns_addr 和 nameservers 參數(shù)合法性檢查;

加載啟動參數(shù)到 etcd,覆蓋 /v2/keys/skydns/config 中原有數(shù)據(jù);

配置 SkyDNS Server 參數(shù)的 default 值,并創(chuàng)建 SkyDNS server 對象;

去 etcd 中加載 …/dns/stub/ domain /xx 數(shù)據(jù)作為 server 的 stub zones 數(shù)據(jù),并啟動對 …/dns/stub/ 的 watcher,一旦有數(shù)據(jù)更新,就加載到 server 的 stub zones 數(shù)據(jù)中;

注冊 SkyDNS metrics 到 prometheus;

然后在 /v2/keys/skydns/config/dns_addr 配置的 interface 和 port 上開啟 tcp/udp 監(jiān)聽服務(wù)并 block 住,由此開始提供 DSN 服務(wù)。

在 github.com/skynetservices/skydns/server/server.go 中的 ServeDNS 方法覆蓋了 miekg/dns/server 中的 ServeMux.ServeDNS 方法,由自實(shí)現(xiàn)的 ServeDNS 提供來處理 DNS client 的請求。

github.com/skynetservices/skydns/server/server.go
// ServeDNS is the handler for DNS requests, responsible for parsing DNS request, possibly forwarding
// it to a real dns server and returning a response.
func (s *server) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {
 // Check cache first.
 m1 := s.rcache.Hit(q, dnssec, tcp, m.Id)
 if m1 != nil {
 // Still round-robin even with hits from the cache.
 // Only shuffle A and AAAA records with each other.
 if q.Qtype == dns.TypeA || q.Qtype == dns.TypeAAAA {s.RoundRobin(m1.Answer)
 return
 for zone, ns := range *s.config.stub {if strings.HasSuffix(name,  .  + zone) || name == zone {metrics.ReportRequestCount(req, metrics.Stub)
 resp := s.ServeDNSStubForward(w, req, ns)
 if resp != nil {s.rcache.InsertMessage(cache.Key(q, dnssec, tcp), resp)
 metrics.ReportDuration(resp, start, metrics.Stub)
 metrics.ReportErrorCount(resp, metrics.Stub)
 return
 if name == s.config.Domain {
 if q.Qtype == dns.TypeSOA {m.Answer = []dns.RR{s.NewSOA()}
 return
 if q.Qtype == dns.TypeDNSKEY {
 if s.config.PubKey != nil {m.Answer = []dns.RR{s.config.PubKey}
 return
 if q.Qclass == dns.ClassCHAOS {
 if q.Qtype == dns.TypeTXT {
 switch name {
 case  authors.bind. :
 fallthrough
 case s.config.Domain:
 hdr := dns.RR_Header{Name: q.Name, Rrtype: dns.TypeTXT, Class: dns.ClassCHAOS, Ttl: 0}
 authors := []string{ Erik St. Martin ,  Brian Ketelsen ,  Miek Gieben ,  Michael Crosby}
 for _, a := range authors {m.Answer = append(m.Answer,  dns.TXT{Hdr: hdr, Txt: []string{a}})
 for j := 0; j   len(authors)*(int(dns.Id())%4+1); j++ {q := int(dns.Id()) % len(authors)
 p := int(dns.Id()) % len(authors)
 if q == p {p = (p + 1) % len(authors)
 m.Answer[q], m.Answer[p] = m.Answer[p], m.Answer[q]
 return
 case  version.bind. :
 fallthrough
 case  version.server. :
 hdr := dns.RR_Header{Name: q.Name, Rrtype: dns.TypeTXT, Class: dns.ClassCHAOS, Ttl: 0}
 m.Answer = []dns.RR{ dns.TXT{Hdr: hdr, Txt: []string{Version}}}
 return
 case  hostname.bind. :
 fallthrough
 case  id.server. :
 // TODO(miek): machine name to return
 hdr := dns.RR_Header{Name: q.Name, Rrtype: dns.TypeTXT, Class: dns.ClassCHAOS, Ttl: 0}
 m.Answer = []dns.RR{ dns.TXT{Hdr: hdr, Txt: []string{localhost}}}
 return
 // still here, fail
 m.SetReply(req)
 m.SetRcode(req, dns.RcodeServerFailure)
 return
 switch q.Qtype {
 case dns.TypeNS:
 if name != s.config.Domain {
 break
 // Lookup s.config.DnsDomain
 records, extra, err := s.NSRecords(q, s.config.dnsDomain)
 if isEtcdNameError(err, s) {m = s.NameError(req)
 return
 m.Answer = append(m.Answer, records...)
 m.Extra = append(m.Extra, extra...)
 case dns.TypeA, dns.TypeAAAA:
 records, err := s.AddressRecords(q, name, nil, bufsize, dnssec, false)
 if isEtcdNameError(err, s) {m = s.NameError(req)
 return
 m.Answer = append(m.Answer, records...)
 case dns.TypeTXT:
 records, err := s.TXTRecords(q, name)
 if isEtcdNameError(err, s) {m = s.NameError(req)
 return
 m.Answer = append(m.Answer, records...)
 case dns.TypeCNAME:
 records, err := s.CNAMERecords(q, name)
 if isEtcdNameError(err, s) {m = s.NameError(req)
 return
 m.Answer = append(m.Answer, records...)
 case dns.TypeMX:
 records, extra, err := s.MXRecords(q, name, bufsize, dnssec)
 if isEtcdNameError(err, s) {m = s.NameError(req)
 return
 m.Answer = append(m.Answer, records...)
 m.Extra = append(m.Extra, extra...)
 default:
 fallthrough // also catch other types, so that they return NODATA
 case dns.TypeSRV:
 records, extra, err := s.SRVRecords(q, name, bufsize, dnssec)
 if err != nil {if isEtcdNameError(err, s) {m = s.NameError(req)
 return
 logf(got error from backend: %s , err)
 if q.Qtype == dns.TypeSRV { // Otherwise NODATA
 m = s.ServerFailure(req)
 return
 // if we are here again, check the types, because an answer may only
 // be given for SRV. All other types should return NODATA, the
 // NXDOMAIN part is handled in the above code. TODO(miek): yes this
 // can be done in a more elegant manor.
 if q.Qtype == dns.TypeSRV {m.Answer = append(m.Answer, records...)
 m.Extra = append(m.Extra, extra...)
 if len(m.Answer) == 0 { // NODATA response
 m.Ns = []dns.RR{s.NewSOA()}
 m.Ns[0].Header().Ttl = s.config.MinTtl}

上面代碼邏輯比較復(fù)雜,細(xì)節(jié)上需要你慢慢去理解,簡短的可以總結(jié)如下:

如架構(gòu)圖中標(biāo)注的線路 1:如果在 SkyDNS 維護(hù)的 cache 中找到對應(yīng) Msg,則從 cache 中讀取并返回 Msg 給 DNS client;

如架構(gòu)圖中標(biāo)注的線路 2:如果在 cache 中沒有對應(yīng)的記錄,并且是需要 DNS forward 的場景(比如 name 匹配到 stub zones 等),則將請求 forward 到對應(yīng)的 DNS servers 進(jìn)行處理;

如架構(gòu)圖中標(biāo)注的線路 3:如果在 cache 中沒有對應(yīng)的記錄,并且 Question Type 為 A /AAAA,SRV 等類型時(shí),就通過 etcd client 去 etcd cluster 中獲取對應(yīng)的 Rule,并構(gòu)造 Msg 返回。

感謝各位的閱讀,以上就是“SkyDNS 工作原理是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對 SkyDNS 工作原理是什么這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-08-16發(fā)表,共計(jì)5953字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 潼南县| 崇义县| 崇礼县| 宝丰县| 五大连池市| 福清市| 乌什县| 宜宾市| 沈丘县| 蒲江县| 临江市| 宜丰县| 贵港市| 固镇县| 突泉县| 隆林| 河北省| 上高县| 华安县| 仁化县| 小金县| 九龙县| 荥阳市| 乌什县| 镇雄县| 桂东县| 江西省| 贺州市| 沅江市| 连平县| 健康| 南康市| 工布江达县| 宕昌县| 双鸭山市| 固原市| 九寨沟县| 江源县| 南投县| 将乐县| 合水县|