OpenShift ClusterOperator-DNS

OpenShift是一个企业就绪型Kubernetes容器平台,提供WebUI及网络、监控、日志收集、身份验证和授权、CI/CD、存储等解决方案,可以实现全栈自动化运维,基于Kubernetes而强于Kubernetes。OpenShift需订阅使用,社区版OKD是免费的。本文讲解OpenShift集群中的DNS ClusterOperator。
1,DNS的使用场景
OpenShift集群中,使用DNS有下面三个地方:

  • Pod访问集群外的域名,比如“www.jianshu.com
  • Pod通过服务的域名访问集群中的服务,即服务发现功能,需要通过DNS得到Cluster IP从而访问到对应的服务
  • 集群外部通过域名访问部署在OpenShift中的服务,需要DNS来解析服务的集群外域名

下面部分解释OpenShift 4是如何实现上述三个功能的(OpenShift 3使用了SkyDNS,有很大不同)
2,DNS工作原理
首先要知道Pod从哪里得到DNS服务的IP。在Linux系统中,DNS服务器的IP保存在文件“/etc/resolv.conf”中,Pod也不例外。任意选择运行在集群中的Pod,查看其“/etc/resolv.conf”文件,内容如下:

~ $ 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: {}

该服务的后端是以DaemonSet方式部署在每台宿主机上“dns-default-<id>” Pod,其中核心容器名字为“dns”,运行CoreDNS,完成所有的地址解析和转发工作(后面详细介绍)。
登录一台“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
}

请求内部域名由带“kubernetes”插件的CoreDNS处理,请求外部域名由“forward”插件处理。
<1> Pod访问外部域名
当集群内的Pod请求外部的域名如“www.toutiao.com”时,从上面的分析可知,请求需要发送到配置在文件“/etc/reslov.conf”中的DNS服务器,该文件的内容如下,

sh-4.2# cat /etc/resolv.conf 
search okd-infra.example.com
nameserver 10.255.1.1

nameserver的IP和宿主机保持一致(实际文件就是拷贝宿主机的),这就简单了,当集群内的Pod需要访问外部的域名时,由外部的DNS服务器做解析,和普通的Linux服务器DNS请求原理一致。
<2> 集群服务发现
CoreDNS的“kubernetes”插件实现了基于DNS的服务发现(还有一种服务发现基于Pod中的环境变量),该插件解析的DNS name格式是这样的:<service_name>.<namespace>. svc .cluster.local,解析出的地址是“service_name”的Cluster IP。
比如位于“my-exporter”NameSpace中的服务“rocketmq-exporter”,登录集群内任意主机,通过集群内的DNS服务做解析,

[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就是服务“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> 外部访问集群内的服务
安装OpenShift 4需要一个安装配置文件“install-config.yaml”,其中“baseDomain”和“metadata.name”组成了从集群外访问内部服务的域名,如下,

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服务,

.....
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集群,这种搭建方式没有现成的“load balancer”可用,需要自己实现load balance功能,实际使用HAProxy。通过上面DNS的配置将访问集群的外部请求路由到HAProxy,服务后端是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使用了宿主机网络,和宿主机使用同一个网络栈,所以像访问宿主机一样访问Router Pod。
这一部分和Operator DNS的关系不大,它属于集群Ingress的范畴,就不深入了。
3,DNS相关组件介绍
DNS Operator使用DaemonSet部署CoreDNS,这样保证集群中的每一个宿主机都有一个本地CoreDNS pod副本。DaemonSet部署的Pod含有三个容器:“dns”运行CoreDNS,完成核心的地址解析和转发服务,“dns-node-resolver”添加集群image registry的DNS name到宿主机的“/etc/hosts”文件,因为宿主机不请求集群的DNS服务,它没法知道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”的容器和授权相关,不讲解。当Pod请求DNS name时,它不是直接请求本地的“dns-default-<id>” Pod,而是请求“openshift-dns”namespace中的“dns-default”服务,由该服务随机选择一个“dns-default-<id>” Pod完成查询,当然请求的“dns-default-<id>” Pod可能运行在别的宿主机上。
总结
本文对OpenShift 4集群DNS服务的原理和相关组件做简单介绍,Kubernetes同样有参考价值,有任何问题欢迎交流指正,也希望这篇文章能帮到正在努力前进的你。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352