Kubernetes(二十五)Service(四)服务发现

说明:'严格意义上'并不是讲解service,讲的是'core-dns',只是二者的关俩深度比较广

一  官网文档

说明: 本文主要讲解Service的'服务发现'机制,依赖于'core-dns'这个'add-on插件'

升级core-dns

二   服务发现

(1)问题引入

我们可以通过 Service '生成的 ClusterIP(VIP)' 来访问 Pod 提供的服务,但是在使用的时候还有一个'问题':我们'怎么知道'某个应用的 VIP 呢?

场景: 比如我们'有两个应用',一个是 api 应用,一个是 db 应用,'两个应用'都是通过 Deployment 进行管理的,并且都'通过 Service 暴露'出了端口提供服务

api 需要连接到 db 这个应用,我们只知道 'db 应用的名称'和 'db 对应的 Service 的名称',但是'并不知道'它的 VIP 地址,我们知道了 VIP 的地址是不是就行了?

++++  '如何解决'  ++++

早期'环境变量'、后期'Core-dns'-->可以理解为'集群内置'的'dns服务器'

(2)服务查找

①  环境变量

'了解'该参数即可

查看Pod中'注入的'环境变量

为了解决'上面的'问题,在之前的版本中,Kubernetes 采用了'环境变量'的方法

'特点': 每个 Pod 启动的时候,会把系统中'已有kubernetes中的Service'注入到环境变量中,通过环境变量设置'所有服务的 IP 和 port 信息',这样 Pod 中的应用可以通过'读取环境变量'来获取依赖'服务的地址信息',这种方法使用起来'相对简单'

'缺点': 依赖的服务必须在 'Pod 启动之前'就存在,不然是'不会被注入'到环境变量中的-->也即后面创建的Service是'不会注入'到到这个Pod中,除非Pod'重启'-->因为:'环境变量是系统启动后才注入的'

②  core-dns

1)kubernetes服务

说明: 这个就是之前说过的'自己创建'Service和Endpoints --> 类似于把'集群外二进制的etcd'引入到'kubernetes集群内'

2)core-dns

参考博客

由于上面'环境变量'这种方式的'局限性',我们需要一种更加'智能'的方案

比较'理想的方案':那就是可以直接使用 'Service 的名称',因为 Service 的名称'不会变化',我们不需要去关心'分配的' ClusterIP 的地址,因为这个地址并'不是固定不变的',所以如果我们'直接使用' Service 的名字,然后对应的 ClusterIP '地址的转换能够自动完成'就很好了。

我们知道'名字'和 'IP' 直接的转换是不是和我们平时'访问的网站'非常类似啊?他们之间的转换功能'通过 DNS' 就可以解决了,同样的'Kubernetes 也提供了 DNS 的方案'来解决上面的服务发现的问题

+++++++++++++++++++++'分割线1'+++++++++++++++++++++

DNS 服务'不是一个独立'的系统服务,而是作为'一种 addon 插件'而存在,现在'比较推荐'的插件: 'CoreDNS',kubernets'新版本'中已经默认是 CoreDNS 了

备注:kubernetes'早期插件'是kube-dns,但是kube-dns '默认'一个 Pod 中需要'3个容器'配合使用,CoreDNS 只需要一个容器即可

+++++++++++++++++++++'分割线2'+++++++++++++++++++++

CoreDns 是用 'GO语言' 写的高性能,高扩展性的 DNS 服务,基于 'HTTP/2 Web 服务 Caddy' 进行编写的。

CoreDns 内部采用'插件机制',所有功能都是'对应插件'形式编写,用户也可以'扩展'自己的插件

+++++++++++++++++++++'分割线3'+++++++++++++++++++++

查看Kubernetes 部署 CoreDns 时的'默认配置'-->'Corefile'

1)每个 '{}' 代表一个 'zone',格式是 "Zone:port{}", 其中"."代表默认zone

2)'{} 内'的每个名称代表'插件的名称',只有配置的插件才会启用

3)当'解析域名时',会先匹配 zone'都未匹配会执行默认 zone',然后 zone 内的插件从'上到下'依次执行,匹配后返回处理(执行过的插件从下到上依次处理返回逻辑),不再执行下一个插件

备注: 这个顺序并'不是配置文件内'谁在前面的顺序.而是core/dnsserver/'zdirectives.go内'的顺序

3)core-dns的设置 

CoreDNS 的 Service 地址一般情况下'是固定的',CoreDNS 的 Service 地址就是 '10.96.0.10-->默是第10个'

备注1: 该 IP 被分配后,kubelet 会将使用 '--cluster-dns=<dns-service-ip>' 参数配置的 DNS 传递给'每个Pod中的容器'。

备注2: DNS 名称也需要域名,本地域可以使用参数--cluster-domain = <default-local-domain> '在 kubelet 中配置'

 

以下是'命令行'的方式,官方说'废弃了','不建议'用

4)创建Service 生成的 DNS 记录

备注: 为了防止core-dns做'无效的'解析,最好写上'service的全路径'

①  普通Service

普通的 Service: 会生成 'servicename.namespace.svc.cluster.local' 的域名,会解析到 Service 对应的 ClusterIP 上

备注1: 在 Pod 之间的调用可以'简写成' servicename.namespace

备注2: 如果处于'同一个命名空间'下面,甚至可以'省略简写'成 'servicename'

②  Headless Service

'无头服务',就是把 clusterIP 设置为 'None' 的,访问'Headless Service'会被解析为指定 Pod 的 IP 列表

命名形式: 'podname'.headless-service-name.namespace.svc.cluster.local 访问到'具体的'某一个 Pod

5) dns策略

需要注意的是 'Default' 并'不是默认的 DNS 策略',如果'未明确指定' dnsPolicy,则'使用 ClusterFirst'

各'参数'的含义

了解'coredns'对应的pod 

kubectl get pods -n kube-system coredns-6d56c8448f-pz2j7 '-o yaml'

备注: 实际coredns相关pod中的'/etc/resolv.conf'默认是node中的'/etc/resolv.conf'

需求: '自定义'pod中的/etc/resolv.conf

Pod中进行'自定义配置'-->'必须配置这两个参数'

dnsPolicy: None

dnsConfig:

+++'案例如下'+++
apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: dns-example
spec:
  containers:
    - name: test
      image: nginx
  dnsPolicy: "None"
  dnsConfig:
    nameservers:
      - 1.2.3.4
    searches:
      - ns1.svc.cluster-domain.example
      - my.dns.search.suffix
    options:
      - name: ndots
        value: "2"
      - name: edns0

说明: /etc/resolv.conf'自己生成'

结果

nameserver 1.2.3.4
search ns1.svc.cluster-domain.example my.dns.search.suffix
options ndots:2 edns0

三   给pod中注入一条记录

1)方式1:hostALias

说明: '1.7+之后'提供的新特性

说明: 观察容器中'/etc/hosts'的变化

2)PodPreset

说明: 设置的话默认给'ns下所有的Pod'注入相应的记录 -->'准入控制器'

3)hosts插件

具体: 修改coredns这个'deployment'的configmap

coredns '自带 hosts 插件','开箱即用',允许像配置 hosts 一样配置'自定义 DNS 解析'

kubectl edit cm -n kube-system coredns  --> '在线编辑'

说明1: configmap'热更新'需要'1~2'分钟才生效

说明2: 生效后作用全局-->所有的'ns'

说明3: 并没有在所有container的'/etc/hosts'本地解析注入

四  给Pod添加DNS解析记录

(1)StatefulSet自动给Pod添加DNS解析记录

我们都知道 'StatefulSet 中的 Pod' 是拥有'单独的 DNS 记录'的

举例: 比如一个 'StatefulSet 名称'为 etcd,而它关联的 'Headless SVC 名称'为 etcd-headless,那么 CoreDNS 就会为它的'每个 Pod 解析'如下的记录:

etcd-0.etcd-headless.default.svc.cluster.local

etcd-1.etcd-headless.default.svc.cluster.local

+++++++++++++++++++'问题抛出'+++++++++++++++++++

除了 StatefulSet 管理的 Pod 之外,'其他的 Pod' 是否也可以'生成 DNS 记录'呢?

(2)普通Pod添加DNS解析记录

强调: hostname 和 pod 的名字是'有区别的'

Pod 规范中包含一个'可选的 hostname 字段',可以用来'指定 Pod 的主机名',当这个字段被设置时,它将'优先于 Pod 的名字'成为该 Pod 的主机名

举个例子:给定一个 hostname 设置为 "my-host" 的 Pod,该 Pod 的主机名将被设置为 "my-host",Pod 规约还有一个'可选的 subdomain 字段',可以用来指定 Pod 的子域名

举个例子:某 Pod 的 hostname 设置为 'foo',subdomain 设置为 'bar', 在名字空间 'my-namespace' 中对应的完全限定域名为 'foo.bar.my-namespace.svc.cluster-domain.example'

+++++++++++++++++'在DNS中的记录'+++++++++++++++++

<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>
# individual-pods-example.yaml
apiVersion: v1
kind: Service
metadata:
  name: default-subdomain
spec:
  selector:
    name: busybox
  clusterIP: None
  ports:
  - name: foo # Actually, no port is needed.
    port: 1234
    targetPort: 1234
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox1
  labels:
    name: busybox
spec:
  hostname: busybox-1             '核心关注1'
  subdomain: default-subdomain    '核心关注2'
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    name: busybox
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox2
  labels:
    name: busybox
spec:
  hostname: busybox-2
  subdomain: default-subdomain
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    name: busybox

结论: 看到有 'ANSWER 记录'回来了

强调: 'hostname' 和 'subdomain' 二者都'必须显式指定',缺一不可

五  添加一个自定义的dns服务器

六   coredns官网

说明: 本文主要是'扩展'知识

各个插件

七  5s超时

service ip是如何避免冲突

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值