认识k8s中CoreDNS和Ingress

Kubernetes Service通过虚拟IP地址或者节点端口为用户应用提供访问入口,然而这些IP地址和端口是动态分配的,如果用户重建一个服务,其分配的clusterIP和nodePort或者LoadBalancerIP都是会变化的,实际项目中无法把一个可变的入口发布出去供用户访问。为了解决这个问题,Kubernetes提供了内置的域名服务,用户定义的服务会自动获取域名,通过域名解析,可以对外向用户提供一个固定的服务访问地址。CoreDNS包含一个内存态DNS,以及其他controller类似的控制器。CoreDNS的实现原理是控制器监听Service和Endpoint的变化并配置DNS,客户端Pod在进行域名解析时,从CoreDNS中查询服务对应的地址记录。对于不同类型的Service,DNS规则是什么呢?DNS创建规则如下所示:

  • 普通Service(ClusterIP、nodePort、LoadBalancer类型的service),CoreDNS会为这些service创建FQDN,格式为:$svcname.$namespace.svc.$clusterdomain.
  • HeadLess类型的service,对于这类service,API-Server不会为其分配ClusterIP,CoreDNS为此类Service创建多条A记录,并且目标为每个就绪的PodIP。另外,每个Pod会拥有一个FQDN,格式为:$podname.$svcname.$namespace.svc.$clusterdomain的A记录指向PodIP。
  • ExternalName类型的service,此类service用来引用一个已经存在的域名,CoreDNS为该Service创建一个Cname记录指向目标域名。

接下来通过实际例子理解CoreDNS是如何工作的。首先部署2个nginx的pod作为后端服务,另外再部署一个service。pod和service的yaml文件如下所示

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-basic
spec:
  type: ClusterIP
  ports:
    - port: 80
      protocol: TCP
      name: http
  selector:
    app: nginx
~              

pod的service部署成功后,通过kubectl exec -it podName bash命令进入到pod中,查看pod的etc目录下的resolv.conf文件。

nameserver :  表示解析域名时使用该地址指定的主机为域名服务器。其中域名服务器是按照文件中出现的顺序来查询的,且只有当第一个nameserver没有反应时才查询下面的nameserver。

search:它的多个参数指明域名查询顺序。当要查询没有域名的主机,主机将在由search声明的域中分别查找。

domain:声明主机的域名。很多程序用到它,如邮件系统;当为没有域名的主机进行DNS查询时,也要用到。如果没有域名,主机名将被使用,删除所有在第一个点( .)前面的内容。

需要注意domain和search不能共存,在上述的pod里面的resolv.conf文件就只有search的定义,没有domain的定义。

当前service的ClusterIP是:10.99.151.150,在pod里面通过域名访问部署的nginx的服务,即部署的nginx pod. curl nginx-basic.default.svc.cluster.local.可以看到域名的格式是$serviceName.$namespaceName.svc.$cluserDomain。clusterDomain如果不修改,默认是cluster.local.当通过域名访问时,请求转发到的service的ClusterIP地址上,故最终访问到了后端的服务。

以上就是CoreDNS工作原理,接下来看看Ingress是如何工作的,以下是对service和ingress的一个简单对比结果。

Ingress包含两部分处理逻辑,一部分是ingress是一层代理,负责根据hostname和path将流量转发到不同的服务上,使得一个负责均衡器用于多个后台服务。Kubernetes Ingress Spec是转发规则的集合。另外一部分是Ingress Controller,controller负责DNS配置,负载均衡配置等。下面是一个定义ingress的yaml文件例子。

接下来通过实际例子看看ingress是如何工作,在理解ingress工作过程中,还需要用到上面部署的nginx的service和nginx的pod。

首先是通过helm安装ingress,具体安装命令如下所示

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx --create-namespace --namespace ingress

安装完成后,查看ingress namespace,可以看到启动了ingress-controller的pod,另外还创建了一个service,默认情况下service是LoadBanlancer类型,为了后面演示在外网访问的过程,这里把service类型修改成NodePort类型。

 接着是编写创建Ingress的yaml文件,下面是ingress的yaml文件内容,里面配置了tls的secret,因为这个例子后续是通过https访问nginx服务,故需要配置证书,即生成key和crt,存放到secret对象中,rules中指定了转发规则。

这里是通过x509对"ingress.demo.com"域名签发证书,执行命令后会生成key和crt。

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=ingress.demo.com/O=ingress" -addext "subjectAltName = DNS:ingress.demo.com"

 创建secret对象存放生成的key和crt。

kubectl create secret tls ingress-tls --cert=./tls.crt --key=./tls.key

查看创建好的sercret对象,可以看到里面将key和crt存放了,这样ingress就可以通过secret获取到key和crt信息,完成https的访问。

接着在node节点上通过curl命令尝试访问部署的nginx服务,因为签发证书的域名设置的是ingress.demo.com,故这里在header中设置Host是ingress.demo.com. 10.111.26.96是ingress的IP地址。

curl -H "Host: ingress.demo.com" https://10.111.26.96  -v -k

 http的curl的结果如下所示:可以看到我们访问的入口是ingress,ingress在通过niginx的service,然后就访问到了部署的nginx pod。

 https的curl结果如下所示:因为是https访问,所以有TLS握手的过程,但是证书验证的过程失败了,导致访问nginx的返回了503.在证书配置过程中可能还有些问题,需要单独查找原因。

在安装ingress的时候还创建了NodePort类型的ingress service,所以还可以在外网访问nginx服务,ip地址是node的公网地址,端口32058是NodePort类型的ingress service的对外的端口。外网访问的情况下,请求入口是ingress的service接收请求,然后转发到ingress对象上,下面日志可以看到请求的Location是https://ingress.demo.com,ingress再访问nginx的service,service再访问nginx的pod,最终完成整个访问。

 以上就是ingress工作过程,可以看到通过ingress可以实现https的访问,增加了安全性。但是在实际项目中用ingress做负载均衡也存在问题,例如ingress只能基于URL进行负载均衡,如果想实现更多规则的负载均衡就不行,例如基于header等。故在实际项目中还需要其他手段才能完成负载均衡。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

taoli-qiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值