k8s CoreDNS服务搭建与配置

简介: 讲解 k8s CoreDNS服务的搭建与配置

01 引言

声明:本文为《Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)》的读书笔记

作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,这就需要一个集群范围内的DNS服务来完成从服务名到ClusterIP地址的解析。

02 DNS服务在k8s的发展

2.1 SkyDNS

在这里插入图片描述

在Kubernetes1.2版本时,DNS服务是由SkyDNS提供的,它由4个容器组成(kube2sky、skydns、etcd和healthz):

  • kube2sky容器:监控Kubernetes中Service 资源的变化,根据Service的名称和IP地址信息生成DNS记录,并将其保存到etcd 中;
  • skydns容器:从etcd中读取DNS记录,并为客户端容器应用提供DNS查询服务
  • healthz容器:提供对skydns服务的健康检查功能。

2.2 KubeDNS

在这里插入图片描述

从Kubernetes1.4版本开始,SkyDNS组件便被KubeDNS替换, 主要考虑的是SkyDNS组件之间通信较多,整体性能不高

KubeDNS由3个容器组成(kubedns、dnsmasq和sidecar),去掉了SkyDNS中的etcd存储,将DNS记录直接保存在内存中,以提高查询性能:

  • kubedns容器 :监控Kubernetes中Service资源的变化,根据Service的名称和IP地址生成DNS记录,并将DNS记录保存在内存中;
  • dnsmasq容器:从kubedns中获取DNS记录,提供DrS缓存,为客户端容器应用提供DNS查询服务;
  • sidecar容器:提供对kubedns和dnsmasq服务的健康检查功能。

2.3 CoreDNS

在这里插入图片描述
从Kubernetes1.11版本开始,Kubernetes集群的DNS服务由CoreDNS提供

  • 它是由go语言实现的一套高性能、插件式,易于扩展的DNS服务端;
  • 解决了KubeDNS的一些问题, 例如dnsmasq的安全漏洞、externalName不能使用stubDomains进行设置等等;
  • 支持自定义DNS记录及配置upstream DNS Server,可以统一管理Kubernetes基于服务的内部DNS和数据中心的物理DNS;
  • 它没有使用多个容器的架构,只用一个容器便实现了KubeDNS内3个容器的全部功能。

03 搭建CoreDNS服务

3.1 修改每个Node上kubelet的DNS启动参数

修改每个Node上kubelet的启动参数,在其中加上以下两个参数:

  • --cluster-dns=169.169.0.100:为DNS服务的ClusterIP地址。
  • --cluster-domain=cluster.local:为在DNS服务中设置的域名。

然后重启kubelet服务。

3.2 部署CoreDNS服务

部署CoreDNS服务时需要创建3个资源对象:1个ConfigMap、1个Deployment和1个Service

在启用了RBAC的集群中,还可以设置ServiceAccount、ClusterRole 、ClusterRoleBinding对CoreDNS容器进行权限设置。

3.2.1 ConfigMap

ConfigMap 的 "coredns" 主要设置CoreDNS的主配置文件Corefile的内容,其中可以定义各种域名的解析方式和使用的插件,示例如下:

apiVersion: v1
kind: ConfigMap
metadata:
    name: coredns
    namespace: kube-system 
    labels: 
        addonmanager.kubernetes.io/mode: EnsureExists
data:
    Corefile: | 
        cluster.local{
            errors
            health{
                lameduck 5s 
            }
            ready
            kubernetes cluster.local 169.169.0.0/16{ 
                fallthrough in-addr.arpa ip6.arpa
            }
            prometheus: 9153
            forward    ./etc/resolv.conf 
            cache 30 
            loop
            reload
            loadbalance
        }
        . {
            cache 30 
            loadbalance
            forward /etc/resolv.conf
        }

3.2.2 Deployment

Deployment 的“coredns” 主要设置CoreDNS容器应用的内容。

其中, replicas副本的数量通常应该根据集群的规模和服务数量确定,如果单个 CoreDNS进程不足以支撑整个集群的 DNS查询,则可以通过水平扩展提高查询能力。由于 DNS服务是 Kubernetes集群的关键核心服务,所以建议为其 Deployment设置自动扩缩容控制器,自动管理其副本数量。

另外,对资源限制部分(CPU限制和内存限制)的设置也应根据实际环境进行调整:

apiversion: apps/v1
kind: Deployment
metadata:
    name: coredns
    namespace: kube-system 
    labels:
        k8s-app: kube-dns
        kubernetes.io/name: "CoreDNS"
spec:
    replicas: 1
    strategy:
        type: RollingUpdate
        rollingUpdate:
            maxUnavailable: 1
    selector:
        matchLabels: 
            k8s-app: kube-dns
    template:
        metadata:
            labels:
                k8s-app: kube-dns
        spec:
        priorityClassName: system-cluster-critical 
        tolerations:
            - key: "CriticalAddonsonly"
              operator: "Exists"
        nodeSelector:
            kubernetes.io/os: linux 
        affinity:
            podAntiAffinity:
            preferredDuringSchedulingIgnoredDuringExecution: 
            - weight: 100
              podAffinityTerm:
                  labelSelector:
                    matchExpressions:
                    - key: k8s-app
                      operator: In
                      values: ["kube-dns"]
                topologyKey: kubernetes.io/hostname
        containers:
        - name: coredns
          image: coredns/coredns:1.7.0 
          imagePullPolicy: IfNotPresent
          resources:
            limits:
              memory: 170Mi
            requests:
              cpu: 100m
              memory: 70Mi
          args: ["-conf","/etc/coredns/Corefile" ]
        volumeMounts:
        - name: config-volume 
          mountPath: /etc/coredns 
          readOnly: true
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        - containerPort: 9153
          name: metrics
          protocol: TCP
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - a11
          readOnlyRootFilesystem: true 
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60 
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: 8181
            scheme: HTTP
        dnsPolicy: Default
        volumes:
        - name: config-volume
          configMap:
            name: coredns
            items:
            - key: Corefile
              path: Corefile

3.2.3 Service

Service“kube-dns” 是DNS服务的配置,这个服务需要设置固定的ClusterIP地址,也需要将所有Node上的kubelet启动参数--cluster-dns都设置为这个ClusterIP 地址:

apiVersion: v1
kind: Service
metadata:
    name: kube-dns
    namespace: kube-system 
    annotations:
        prometheus.io/port: "9153" 
        prometheus.io/scrape: "true" 
    labels:
        k8s-app: kube-dns
        kubernetes.io/cluster-service: "true" 
        kubernetes.io/name: "CoreDNS" 
spec:
    selector:
        k8s-app: kube-dns
    clusterIP: 169.169.0.100 
    ports:
    - name: dns
      port: 53
      protocol: UDP
    - name: dns-tcp
      port: 53
      protocol: TCP
    - name: metrics
      port: 9153
      protocol: TCP

使用kubectl create命令依次把资源对象创建,然后可以看到创建成功:
在这里插入图片描述

04 服务名的DNS解析

接下来使用一个带有 nslookup工具 的pod来验证DNS是否正常工作。

apiVersion: v1
kind: Pod
metadata:
    name: busybox
    namespace: default
spec:
containers:
- name: busybox
  image: gcr.io/google containers/busybox 
  command:
    - sleep
    - "3600"

在该容器成功启动后,通过kubectl exec<container_id>--nslookup进行测试:
在这里插入图片描述
可以看到,通过DNS服务器 169.169.0.100 成功解析了redis-master服务的IP地址 169.169.8.10


如果某个Service属于不同的命名空间,那么在进行Service查找时,**需要补充
Namespace的名称,将其组合成完整的域名**。

下面以查找kube-dns服务为例,将其所在Namespace“kube-system”补充在服务名之后,用 “.” 连接为 “kube- dns.kube-system,即可查询成功:
在这里插入图片描述
如果仅使用 "kube-dns" 进行查找,则会失败:

nslookup: can't resolve 'kube-dns'

05 CoreDNS配置

CoreDNS的主要功能是通过插件系统实现的,CoreDNS实现了一种链式插件结构,将DNS的逻辑抽象成了一个个插件,能够灵活组合使用。常用的插件如下:

插件 描述
loadbalance 提供基于DNS的负载均衡功能
loop 检测在DNS解析过程中出现的简单循环问题
cache 提供前端缓存功能
health 对Endpoint进行健康检查
kubernetes 从Kubernetes中读取zone数据
etcd 从etcd中读取zone数据,可用于自定义域名记录
file 从RFC 1035格式文件中读取zone数据
hosts 使用/etc/hosts文件或者其他文件读取zone数据,可用于自定义域名记录
auto 从磁盘中自动加载区域文件
reload 定时自动重新加载Corefile配置文件的内容
forward 转发域名查询到上游DNS服务器上
prometheus 为Prometheus系统提供采集性能指标数据的URL
pprof 在URL路径/debug/pprof下提供运行时的性能数据
log 对DNS查询进行日志记录
errors 对错误信息进行日志记录

5.1 示例一:设置插件

在下面的示例中为域名 “cluster.local” 设置了一系列插件,包括errors、 health、ready、kubernetes、prometheus、forward、cache、loop、reload和 loadbalance,在进行域名解析时,这些插件将以从上到下的顺序依次执行:

cluster.local {
    errors
    health{
        lameduck 5s
    }
    ready
    kubernetes cluster.local 169.169.0.0/16 {
        fallthrough in-addr.arpa ip6.arpa
    }
    prometheus: 9153
    forward    ./etc/resolv.conf 
    cache 30 
    loop
    reload
    loadbalance
}

5.2 示例二:自定义域名

另外,etcd和hosts插件都可以用于用户自定义域名记录

下面是使用etcd插件的配置示例,将以“.com”结尾的域名记录配置为从etcd中获取,并将域名记录保存在/skydns路径下:

{
    etcd com{
        path /skydns
        endpoint http://192.168.18.3:2379 
        upstream /etc/resolv.conf 
    }
    cache 160 com 
    loadbalance
    proxy /etc/resolv.conf
}

如果用户在etcd中插入一条“10.1.1.1 mycompany” DNS记录:

$ ETCDCTL_API=3 etcdctl put "/skydns/com/mycompany" '["host":"10.1.1.","ttl":60]'

客户端应用就能访问域名"mycompany.com"了:

$ nslookup mycompany.com
Server:                169.169.0.100
Address:            169.169.0.100#53

Name:                mycompany.com
Address:            10.1.1.1

5.3 示例三:转发域名查询到上游DNS服务器上

forward插件用于配置上游DNS服务器或其他DNS服务器,当在CoreDNS中查
询不到域名时,会到其他DNS服务器上进行查询。在实际环境中,可以将Kubernetes集群外部的DNS纳入CoreDNS,进行统一的DNS管理。

06 文末

本文主要讲解k8s里面的DNS服务搭建与配置,希望能帮助到大家,谢谢大家的阅读,本文完!

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
4天前
|
Kubernetes 负载均衡 应用服务中间件
深入理解 Kubernetes Ingress:路由流量、负载均衡和安全性配置
深入理解 Kubernetes Ingress:路由流量、负载均衡和安全性配置
|
5天前
|
Kubernetes 应用服务中间件 Docker
Kubernetes学习-集群搭建篇(二) 部署Node服务,启动JNI网络插件
Kubernetes学习-集群搭建篇(二) 部署Node服务,启动JNI网络插件
|
1天前
|
存储 弹性计算 Kubernetes
【阿里云云原生专栏】深入解析阿里云Kubernetes服务ACK:企业级容器编排实战
【5月更文挑战第20天】阿里云ACK是高性能的Kubernetes服务,基于开源Kubernetes并融合VPC、SLB等云资源。它提供强大的集群管理、无缝兼容Kubernetes API、弹性伸缩、安全隔离及监控日志功能。用户可通过控制台或kubectl轻松创建和部署应用,如Nginx。此外,ACK支持自动扩缩容、服务发现、负载均衡和持久化存储。多重安全保障和集成监控使其成为企业云原生环境的理想选择。
110 3
|
4天前
|
存储 Kubernetes 应用服务中间件
k8s-配置与存储-持久化存储-NFS 挂载、StorageClass 存储类 动态创建NFS-PV案例
k8s-配置与存储-持久化存储-NFS 挂载、StorageClass 存储类 动态创建NFS-PV案例
|
4天前
|
存储 Kubernetes Docker
k8s-配置与存储-配置管理
k8s-配置与存储-配置管理
|
5天前
|
Kubernetes 安全 API
Kubernetes学习-集群搭建篇(三) Node配置完善和API概述
Kubernetes学习-集群搭建篇(三) Node配置完善和API概述
Kubernetes学习-集群搭建篇(三) Node配置完善和API概述
|
5天前
|
运维 Kubernetes Linux
Kubernetes详解(九)——资源配置清单创建Pod实战
Kubernetes详解(九)——资源配置清单创建Pod实战
20 2
|
5天前
|
JSON Kubernetes API
Kubernetes详解(八)——Kubernetes资源配置清单
Kubernetes详解(八)——Kubernetes资源配置清单
14 2
|
5天前
|
存储 Kubernetes 数据安全/隐私保护
|
5天前
|
Kubernetes 前端开发 网络协议
Kubernetes服务
Kubernetes服务
33 0
Kubernetes服务

推荐镜像

更多