草庐IT

k8s教程(service篇)-DNS服务搭建和配置

杨林伟 2024-07-30 原文

文章目录

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服务搭建与配置,希望能帮助到大家,谢谢大家的阅读,本文完!

有关k8s教程(service篇)-DNS服务搭建和配置的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  4. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  5. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  6. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  7. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  8. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  9. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  10. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

随机推荐