kubernetes中部署DNS
-
先吐槽一下,最近研究k8s的dns,看了很多相关博客,发现很多都是一样的内容,大部分都是转载或者copy,也不验证一下就发出来,给我无形中挖了很多坑。再次先谴责一下这些人!
-
开始正题!
-
使用场景:ubuntu16.04, kubernetes1.4及以上, 集群没有搭建CA等认证!其他场景仅作参考!
1.为什么要部署DNS
kubernetes 提供了 service 的概念可以通过 VIP(Service IP 是 virtual IP(VIP)) 访问 pod 提供的服务,但是在使用的时候还有一个问题:怎么知道某个应用的 VIP?比如我们有两个应用,一个 app,一个 是 db,每个应用使用 rc或deployment进行管理,并通过 service 暴露出端口提供服务。app 需要连接到 db 应用,我们只知道 db 应用的名称,但是并不知道它的 VIP 地址。这就涉及到了==服务发现==的问题了。
- 针对以上问题,k8s提供了三种==服务发现==的方法:
方法1.通过kubernetes 提供的 API 查询
该方法较为简单,但问题较多。首先每个应用都要在启动的时候编写查询依赖服务的逻辑,这本身就是重复和增加应用的复杂度;其次这也导致应用需要依赖 kubernetes,不能够单独部署和运行(当然如果通过增加配置选项也是可以做到的,但这又是增加复杂度)。
方法2.环境变量
K8S默认支持,这一方法是参照docker的。每个 pod 启动时候,k8s会将之前存在的所有服务的 IP 和 port 信息通过环境变量的形式写入到新启动的pod中,这样 pod中的应用可以通过读取环境变量来获取依赖服务的地址信息。但是有个很大的问题:依赖的服务必须在 pod 启动之前就存在,不然就不会出现在环境变量中。
方法3.DNS(最理想的方案)
应用只需要知道服务的具体名字,不需要关心服务的实际的 ip 地址,中间的==服务名--IP==转换由DNS自动完成。名字和 ip 之间的转换就是 DNS 系统的功能。
2.DNS 版本介绍
DNS 服务不是独立的系统服务,而是一种 ==addon== ,作为==插件==来安装的,不是 kubernetes 集群必须的(==但是非常推荐安装==)。可以把它看做运行在集群上的应用,只不过这个应用比较特殊而已。 目前常用的DNS配置方式有两种,在 1.3 之前使用 etcd + kube2sky + skydns + exechealthz的方式,在 1.3 之后可以使用 kubedns + dnsmasq +sidecar 的方式。
下面对这些组件功能进行介绍
- 1.3版本前
- etcd: DNS存储
- kube2sky: 通过K8S API监视Service资源的变化,将service注册到etcd
- skydns: 提供DNS域名解析服务,为集群中的Pod提供DNS查询服务
- exechealthz: 提供对skydns服务的健康检查功能
架构图
- 1.3版本后
- kubedns: 通过K8S API监视Service资源的变化,并使用树形结构在内存中保存DNS记录
- dnsmasq: 提供DNS域名解析服务,为集群中的Pod提供DNS查询服务
- exechealthz: 提供对kubedns和dnsmasq两个服务的健康检查功能,更加完善
架构图
从中可以看出kubedns替代了 etcd和 kube2sky这两个功能,为dnsmasq提供查询服务,使用树形结构在内存中保存DNS记录
dnsmasq在kube-dns插件中的作用: 通过kubedns容器获取DNS规则,在集群中提供DNS查询服务 提供DNS缓存,提高查询性能 降低kubedns容器的压力、提高稳定性
3.搭建DNS
网上有很多搭建的教程,本人一一尝试!发现都没成功!很尴尬!可能是因为k8s版本不同或k8s集群搭建方式不同,又或者是引入了ServiceAccount 、token和认证等模块。此处就不详细介绍。 通过本人不懈努力(请允许我装个B..),终于实现了一个精简版DNS方案:kubedns + dnsmasq + exechealthz,具体的yaml文件可点击这里查看。
废话不多说,直接上内容!
dns-rc.yaml
apiVersion: v1 kind: ReplicationController metadata: name: kube-dns-v15 namespace: kube-system labels: k8s-app: kube-dns version: v15 kubernetes.io/cluster-service: "true" spec: replicas: 1 selector: k8s-app: kube-dns version: v15 template: metadata: labels: k8s-app: kube-dns version: v15 kubernetes.io/cluster-service: "true" spec: containers: - name: kubedns image: registry.cn-hangzhou.aliyuncs.com/sjq-k8s/kubedns-amd64:1.5 resources: # TODO: Set memory limits when we've profiled the container for large # clusters, then set request = limit to keep this container in # guaranteed class. Currently, this container falls into the # "burstable" category so the kubelet doesn't backoff from restarting it. limits: cpu: 100m memory: 200Mi requests: cpu: 100m memory: 100Mi livenessProbe: httpGet: path: /healthz port: 8080 scheme: HTTP initialDelaySeconds: 60 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 readinessProbe: httpGet: path: /readiness port: 8081 scheme: HTTP # we poll on pod startup for the Kubernetes master service and # only setup the /readiness HTTP server once that's available. initialDelaySeconds: 30 timeoutSeconds: 5 args: # command = "/kube-dns" - --kube_master_url=http://192.168.122.10:8080 - --domain=cluster.local. - --dns-port=10053 ports: - containerPort: 10053 name: dns-local protocol: UDP - containerPort: 10053 name: dns-tcp-local protocol: TCP - name: dnsmasq image: registry.cn-hangzhou.aliyuncs.com/sjq-k8s/dnsmasq:1.1 args: - --cache-size=1000 - --no-resolv - --server=127.0.0.1#10053 ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP - name: healthz image: registry.cn-hangzhou.aliyuncs.com/sjq-k8s/exechealthz-amd64:1.0 resources: # keep request = limit to keep this container in guaranteed class limits: cpu: 10m memory: 20Mi requests: cpu: 10m memory: 20Mi args: - -cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null - -port=8080 ports: - containerPort: 8080 protocol: TCP dnsPolicy: Default # Don't use cluster DNS.
其中的镜像由于被墙,所以直接被我替换成了本人阿里云上的镜像,可以直接下载使用, 其中- --kube_master_url=http://192.168.122.10:8080 中的IP记得换成自己的master ip和port
dns-svc.yaml
apiVersion: v1 kind: Service metadata: name: kube-dns namespace: kube-system labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" kubernetes.io/name: "KubeDNS" spec: selector: k8s-app: kube-dns clusterIP: 192.168.3.10 ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP
其中将clusterIP: 192.168.3.10 中的ip换成你实际定义的dns集群ip。
创建rc和service
$ kubectl create -f skydns-rc.yaml replicationcontroller "kube-dns-v15" created $ kubectl create -f skydns-svc.yaml service "kube-dns" created
查看是否running
$ kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE kube-dns-v15-32902 3/3 Running 0 2m $ $ kubectl get svc -n kube-system NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns 192.168.3.10 <none> 53/UDP,53/TCP 7m
4.验证dns是否有效
通过启动一个带有nslookup工具的busybox来验证DNS服务是否能够正常工作:
busybox.yaml
apiVersion: v1 kind: Pod metadata: name: busybox namespace: default spec: containers: - image: busybox command: - sleep - "3600" imagePullPolicy: IfNotPresent name: busybox restartPolicy: Always
启动
$ kubectl create -f busybox.yaml pod "busybox" created
pod成功运行后,通过kubectl exec <容器Id> nslookup进行测试
$ kubectl exec busybox -- nslookup kubernetes Server: 192.168.3.10 Address 1: 192.168.3.10 kube-dns.kube-system.svc.cluster.local Name: kubernetes Address 1: 192.168.3.1 kubernetes.default.svc.cluster.local
成功!
如果测试的服务的命名空间不是default,那么一定要加上命名空间,不然会报下面的错误
$ kubectl exec busybox -- nslookup kube-dns nslookup: can't resolve 'kube-dns' Server: 192.168.3.10 Address 1: 192.168.3.10 kube-dns.kube-system.svc.cluster.local
加上命名空间后
$ kubectl exec busybox -- nslookup kube-dns.kube-system Server: 192.168.3.10 Address 1: 192.168.3.10 kube-dns.kube-system.svc.cluster.local Name: kube-dns.kube-system Address 1: 192.168.3.10 kube-dns.kube-system.svc.cluster.local
5.实际搭建截图
创建成功图
验证成功图
可能的问题

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Prometheus监控
架构 优点 外部依赖少,性能优秀,部署方便 完善的数据模型,丰富的插件集成 提供强大的查询语言 模块构成 Server:核心服务模块,采样并存储时间序列数据(默认管理面板端口9090) Retrieval 采样模块 Storage 存储模块 PromQL 查询模块 PushGateway(可选组件):数据网关代理模块,采样数据临时存储,与server通信 Export:数据导出模块,导出服务监控数据。 Alertmanager:告警模块。接受prometheus上出发alertrules的告警,合并去重聚合处理,并发送出去(支持企业微信,邮箱,钉钉,webhook等等) Grafna:比Prometheus原生UI更强大的可视化界面(类似于Kibana的可视化分析平台),更专注于服务器及应用性能的分析,如CPU、内存、流量等等的图表分析 时间序列 若干标签关联下的指标采样值,随着时间维度的推进,构成一条时间序列 命名规范:应用名称 _ 监测对像 _ 数值类型 _ 单位,比如http_request_total 所有指标值采用float64类型存储 图表类型 Counter:计数值,只增...
- 下一篇
Kubernetes(六) - Secret和私有仓库认证
对一个公司来说安全也是最为重要的因为可能一旦出现安全问题可能这个公司就完了,所以对密码管理是一个长久不变的话题,Kubernetes对密码管理提供了Secret组件进行管理,最终映射成环境变量,文件等方式提供使用,统一进行了管理 更换方便,并且开发人员并不需要关心密码降低了密码的受众范围从而保障了安全. Kubernetes官方文档:https://kubernetes.io/docs/reference/ Kubernetes官方Git地址:https://github.com/kubernetes/kubernetes PS:本系列中使用 KubernetesV1.8 RancherV1.6.14 1. 初始化Secret 首先我们需要初始化一个Secret,使用Yaml文件创建时需要使用base64之后的内容作为Value $ echo -n "admin" | base64 YWRtaW4= $ echo -n "1f2d1e2e67df" | base64 MWYyZDFlMmU2N2Rm 老规矩通过yaml的方式创建我们的Secret配置文件可以看到已经生效了 > v...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS关闭SELinux安全模块
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS7,8上快速安装Gitea,搭建Git服务器