OpenShift是一個企業(yè)就緒型Kubernetes容器平臺码荔,提供WebUI及網(wǎng)絡(luò)、監(jiān)控感挥、日志收集缩搅、身份驗證和授權(quán)、CI/CD触幼、存儲等解決方案硼瓣,可以實現(xiàn)全棧自動化運維,基于Kubernetes而強于Kubernetes置谦。OpenShift需訂閱使用堂鲤,社區(qū)版OKD是免費的。本文講解OpenShift集群中的DNS ClusterOperator媒峡。
1瘟栖,DNS的使用場景
OpenShift集群中,使用DNS有下面三個地方:
- Pod訪問集群外的域名谅阿,比如“www.reibang.com”
- Pod通過服務(wù)的域名訪問集群中的服務(wù)半哟,即服務(wù)發(fā)現(xiàn)功能,需要通過DNS得到Cluster IP從而訪問到對應(yīng)的服務(wù)
- 集群外部通過域名訪問部署在OpenShift中的服務(wù)签餐,需要DNS來解析服務(wù)的集群外域名
下面部分解釋OpenShift 4是如何實現(xiàn)上述三個功能的(OpenShift 3使用了SkyDNS寓涨,有很大不同)
2,DNS工作原理
首先要知道Pod從哪里得到DNS服務(wù)的IP氯檐。在Linux系統(tǒng)中戒良,DNS服務(wù)器的IP保存在文件“/etc/resolv.conf”中,Pod也不例外男摧。任意選擇運行在集群中的Pod蔬墩,查看其“/etc/resolv.conf”文件译打,內(nèi)容如下:
~ $ cat /etc/resolv.conf
search apache-exporter.svc.cluster.local svc.cluster.local cluster.local okd-infra.example.com
nameserver 172.30.0.10
options ndots:5
172.30.0.10是名為“dns-default”的Service的Cluster IP,
kind: Service
apiVersion: v1
metadata:
name: dns-default
namespace: openshift-dns
selfLink: /api/v1/namespaces/openshift-dns/services/dns-default
uid: b850c113-a15d-493f-8be8-5302217106aa
resourceVersion: '10820'
creationTimestamp: '2020-05-20T13:24:26Z'
labels:
dns.operator.openshift.io/owning-dns: default
ownerReferences:
- apiVersion: operator.openshift.io/v1
kind: DNS
name: default
uid: b2aadbb6-c743-43d6-b0b5-83e039b319ab
controller: true
spec:
ports:
- name: dns
protocol: UDP
port: 53
targetPort: dns
- name: dns-tcp
protocol: TCP
port: 53
targetPort: dns-tcp
- name: metrics
protocol: TCP
port: 9153
targetPort: metrics
selector:
dns.operator.openshift.io/daemonset-dns: default
clusterIP: 172.30.0.10
type: ClusterIP
sessionAffinity: None
status:
loadBalancer: {}
該服務(wù)的后端是以DaemonSet方式部署在每臺宿主機上“dns-default-<id>” Pod拇颅,其中核心容器名字為“dns”奏司,運行CoreDNS,完成所有的地址解析和轉(zhuǎn)發(fā)工作(后面詳細(xì)介紹)樟插。
登錄一臺“dns-default-<id>” Pod韵洋,查看CoreDNS的配置文件(配置文件的含義可以參考官方文檔,這里不做介紹)黄锤,
sh-4.2# cat /etc/coredns/Corefile
.:5353 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf {
policy sequential
}
cache 30
reload
}
請求內(nèi)部域名由帶“kubernetes”插件的CoreDNS處理搪缨,請求外部域名由“forward”插件處理。
<1> Pod訪問外部域名
當(dāng)集群內(nèi)的Pod請求外部的域名如“www.toutiao.com”時鸵熟,從上面的分析可知副编,請求需要發(fā)送到配置在文件“/etc/reslov.conf”中的DNS服務(wù)器,該文件的內(nèi)容如下流强,
sh-4.2# cat /etc/resolv.conf
search okd-infra.example.com
nameserver 10.255.1.1
nameserver的IP和宿主機保持一致(實際文件就是拷貝宿主機的)痹届,這就簡單了,當(dāng)集群內(nèi)的Pod需要訪問外部的域名時打月,由外部的DNS服務(wù)器做解析队腐,和普通的Linux服務(wù)器DNS請求原理一致。
<2> 集群服務(wù)發(fā)現(xiàn)
CoreDNS的“kubernetes”插件實現(xiàn)了基于DNS的服務(wù)發(fā)現(xiàn)(還有一種服務(wù)發(fā)現(xiàn)基于Pod中的環(huán)境變量)奏篙,該插件解析的DNS name格式是這樣的:<service_name>.<namespace>. svc .cluster.local柴淘,解析出的地址是“service_name”的Cluster IP。
比如位于“my-exporter”NameSpace中的服務(wù)“rocketmq-exporter”秘通,登錄集群內(nèi)任意主機为严,通過集群內(nèi)的DNS服務(wù)做解析,
[core@master-1 ~]$ dig rocketmq-exporter.my-exporter.svc.cluster.local @172.30.0.10
; <<>> DiG 9.11.20-RedHat-9.11.20-1.fc32 <<>> rocketmq-exporter.my-exporter.svc.cluster.local @172.30.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61833
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: f31e6b5240840234 (echoed)
;; QUESTION SECTION:
;rocketmq-exporter.my-exporter.svc.cluster.local. IN A
;; ANSWER SECTION:
rocketmq-exporter.my-exporter.svc.cluster.local. 5 IN A 172.30.15.144
;; Query time: 1 msec
;; SERVER: 172.30.0.10#53(172.30.0.10)
;; WHEN: Wed Oct 28 10:29:37 UTC 2020
;; MSG SIZE rcvd: 157
解析出的172.30.15.144就是服務(wù)“rocketmq-exporter”的Cluster IP充易,
[core@master-1 ~]$ oc get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rocketmq-exporter ClusterIP 172.30.15.144 <none> 5557/TCP 2d1h
原理很簡單梗脾,安裝“kubernetes”插件的CoreDNS作為客戶端請求kubernetes API Server荸型,得到service盹靴、namespace、cluster domain瑞妇,cluster IP等信息稿静,然后將這些信息通過DNS A記錄(或AAAA記錄)的形式暴露出來給Pod訪問。
<3> 外部訪問集群內(nèi)的服務(wù)
安裝OpenShift 4需要一個安裝配置文件“install-config.yaml”辕狰,其中“baseDomain”和“metadata.name”組成了從集群外訪問內(nèi)部服務(wù)的域名改备,如下,
aneirin@host-1:~$ cat install-config.yaml
apiVersion: v1
baseDomain: example.com
compute:
- hyperthreading: Enabled
name: worker
replicas: 0
controlPlane:
hyperthreading: Enabled
name: master
replicas: 3
metadata:
name: okd-infra
......
配置集群外使用的DNS服務(wù)蔓倍,
.....
api IN A 10.1.95.9 ; haproxy IP
api-int IN A 10.1.95.9 ; haproxy IP
*.apps IN A 10.1.95.9 ; haproxy IP
筆者通過“bare metal”的方式安裝OpenShift集群悬钳,這種搭建方式?jīng)]有現(xiàn)成的“l(fā)oad balancer”可用盐捷,需要自己實現(xiàn)load balance功能,實際使用HAProxy默勾。通過上面DNS的配置將訪問集群的外部請求路由到HAProxy碉渡,服務(wù)后端是OpenShift的Router pod運行的宿主機,HAProxy配置片段母剥,
......
#---------------------------------------------------------------------
frontend ingress-http
bind 10.1.95.9:80
default_backend ingress-http
mode tcp
#---------------------------------------------------------------------
backend ingress-http
balance source
mode tcp
server worker-1 10.1.99.14:80 check port 80
server worker-2 10.1.99.15:80 check port 80
#---------------------------------------------------------------------
frontend ingress-https
bind 10.1.95.9:443
default_backend ingress-https
mode tcp
#---------------------------------------------------------------------
backend ingress-https
balance source
mode tcp
server worker-1 10.1.99.14:443 check port 443
server worker-2 10.1.99.15:443 check port 443
#---------------------------------------------------------------------
......
Router Pod使用了宿主機網(wǎng)絡(luò)滞诺,和宿主機使用同一個網(wǎng)絡(luò)棧,所以像訪問宿主機一樣訪問Router Pod环疼。
這一部分和Operator DNS的關(guān)系不大习霹,它屬于集群Ingress的范疇,就不深入了炫隶。
3淋叶,DNS相關(guān)組件介紹
DNS Operator使用DaemonSet部署CoreDNS,這樣保證集群中的每一個宿主機都有一個本地CoreDNS pod副本伪阶。DaemonSet部署的Pod含有三個容器:“dns”運行CoreDNS爸吮,完成核心的地址解析和轉(zhuǎn)發(fā)服務(wù),“dns-node-resolver”添加集群image registry的DNS name到宿主機的“/etc/hosts”文件望门,因為宿主機不請求集群的DNS服務(wù)形娇,它沒法知道image registry的IP地址,需要“dns-node-resolver”將image registry的地址信息加入宿主機的“/etc/hosts”文件筹误,如下桐早,最后一行就是“dns-node-resolver”添加的,
[core@master-1 ~]$ cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.30.238.6 image-registry.openshift-image-registry.svc \
image-registry.openshift-image-registry.svc.cluster.local # openshift-generated-node-resolver
還有一個名為 “kube-rbac-proxy”的容器和授權(quán)相關(guān)厨剪,不講解哄酝。當(dāng)Pod請求DNS name時,它不是直接請求本地的“dns-default-<id>” Pod祷膳,而是請求“openshift-dns”namespace中的“dns-default”服務(wù)陶衅,由該服務(wù)隨機選擇一個“dns-default-<id>” Pod完成查詢,當(dāng)然請求的“dns-default-<id>” Pod可能運行在別的宿主機上直晨。
總結(jié)
本文對OpenShift 4集群DNS服務(wù)的原理和相關(guān)組件做簡單介紹搀军,Kubernetes同樣有參考價值,有任何問題歡迎交流指正勇皇,也希望這篇文章能幫到正在努力前進的你罩句。