美文网首页
OpenShift ClusterOperator-DNS

OpenShift ClusterOperator-DNS

作者: aneirin | 来源:发表于2020-11-03 18:39 被阅读0次

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同样有参考价值,有任何问题欢迎交流指正,也希望这篇文章能帮到正在努力前进的你。

相关文章

网友评论

      本文标题:OpenShift ClusterOperator-DNS

      本文链接:https://www.haomeiwen.com/subject/wejivktx.html