Service资源对象的作用
- 服务发现(发现一组提供了相同服务的Pod):标签选择器,在同一namespace中筛选符合的条件的Pod
实际上并非由Service资源自己完成,而是借助于另一种称为Endpoints/EndpointSlice完成的; - 负载均衡(Service作为流量入口和负载均衡器,其入口为ClusterIP):这组筛选出的Pod的IP地址,将作为该Service的后端服务器;
- 为该组Pod所代表的服务提供一个名称:依赖于Cluster DNS,对于每个Service,自动生成一个A、PTR和SRV记录
Service资源对象的四种类型
CLusterIP : 集群内部通信类型,默认
ExternalName :通过指定名称从集群内访问集群外部资源
NodePort:通过暴漏节点IP:Port使外面可以访问到集群内的服务
LoadBalancer:云厂商使用的负载均衡器,可通过metallb和openelb来模拟
# 特殊配置项,流量策略
externalTrafficPolicy:
Cluster: Service会将流量调度至任何一个可用后端Pod之上,而不关心Pod运行于哪个节点
Local: 外部LB,只能把流量转发给运行有该Service关联的Pod的Node之上;
ClusterIP类型Service示例:
kind: Service
apiVersion: v1
metadata:
name: demoapp-svc
namespace: default
spec:
type: ClusterIP
selector:
app: demoapp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
NodePort其实是个增强版本的ClusterIP
NodePort类型的Service示例:
kind: Service
apiVersion: v1
metadata:
name: demoapp-nodeport-svc
spec:
type: NodePort
selector:
app: demoapp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 31398
externalTrafficPolicy: Local # 或者Cluster
LoadBalancer是个增强版的NodePort
LoadBalancer类型Service示例:
kind: Service
apiVersion: v1
metadata:
name: demoapp-loadbalancer-svc
spec:
type: LoadBalancer
selector:
app: demoapp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
ExternalName类型的Service示例
kind: Service
apiVersion: v1
metadata:
name: externalname-redis-svc
namespace: default
spec:
type: ExternalName
externalName: redis.haogedu.com
ports:
- protocol: TCP
port: 6379
targetPort: 6379
nodePort: 0
selector: {}
Service的名称解析 ClusterDNS(CoreDNS)
Cluster DNS(CoreDNS)是Kubernetes集群的必备附件,负责为Kubernetes提供名称解析和服务发现
每个Service资源对象,在CoreDNS上都会自动生成一个遵循“
示例:
# 登录到pod容器内部,执行域名解析,查看域名解析记录结果:
host -t A demoapp-svc
demoapp.default.svc.cluster.local has address 10.110.19.16
# 反向解析,IP反解为name
host -t PTR 10.110.19.16
16.19.110.10.in-addr.arpa domain name pointer demoapp.default.svc.cluster.local.
Pod上的DNS解析策略
Kubernetes支持在单个Pod资源规范上自定义DNS解析策略和配置,并组合生效
- spec.dnsPolicy:解析策略
- spec.dnsConfig:名称解析机制
解析策略
- Default:从运行在的节点继承DNS名称解析相关的配置
- ClusterFirst:于集群DNS服务上解析集群域内的名称,其他域名的解析则交由从节点继承而来的上游名称服务器
- ClusterFirstWithHostNet:专用于在设置了hostNetwork的Pod对象上使用的ClusterFirst策略
- None:用于忽略Kubernetes集群的默认设定,而仅使用由dnsConfig自定义的配置
名称解析机制
- nameservers <[]string>:DNS名称服务器列表,附加于由dnsPolicy生成的DNS名称服务器之后
- searches <[]string>:DNS名称解析时的搜索域,附加由于dnsPolicy生成的搜索域之后
- options <[]Object>:DNS解析选项列表,同dnsPolicy生成的解析选项合并成最终生效的定义
示例(自定义名称解析机制):
apiVersion: v1
kind: Pod
metadata:
name: pod-with-dnspolicy
namespace: default
spec:
containers:
- name: demo
image: ikubernetes/demoapp:v1.0
imagePullPolicy: IfNotPresent
dnsPolicy: None
dnsConfig:
nameservers:
- 10.96.0.10
- 223.5.5.5
- 223.6.6.6
searches:
- svc.cluster.local
- cluster.local
- ilinux.io
options:
- name: ndots
value: "5"
Headless Service(无头服务)
Service的各类型中,ClusterIP、NodePort和LoadBalancer都为其Service配置一个ClusterIP,CoreDNS上,这些Service对象的A记录也解析为它的ClusterIP
那些没有ClusterIP的Service则称为Headless Service,它们又可以为分两种情形
- 有标签选择器,或者没有标签选择器,但有着与Service对象同名的Endpoint资源
Service的DNS名称直接解析为后端各就绪状态的Pod的IP地址
调度功能也将由DNS完成
各Pod IP相关PTR记录将解析至Pod自身的名称,假设Pod IP为a.b.c.d,则其名称为a-b-c-d.. .svc.
这种类型也就是狭义上的Headless Service - 无标签选择器且也没有与Service对象同名的Endpoint资源
Service的DNS名称将会生成一条CNAME记录,对应值由Service对象上的spec.externalName字段指定
External Service示例:
kind: Service
apiVersion: v1
metadata:
name: externalname-redis-svc
namespace: default
spec:
type: ExternalName
externalName: redis.haogedu.com
ports:
- protocol: TCP
port: 6379
targetPort: 6379
nodePort: 0
selector: {}
Headless Service示例
kind: Service
apiVersion: v1
metadata:
name: demoapp-headless-svc
spec:
clusterIP: None
selector:
app: demoapp
ports:
- port: 80
targetPort: 80
name: http
示例svc通过endpoint访问外部集群外部服务:
apiVersion: v1
kind: Endpoints
metadata:
name: mysql-external
namespace: default
subsets:
- addresses:
- ip: 172.29.9.51
- ip: 172.29.9.52
ports:
- name: mysql
port: 3306
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: mysql-external
namespace: default
spec:
type: ClusterIP
ports:
- name: mysql
port: 3306
targetPort: 3306
protocol: TCP
CoreDNS配置
CoreDNS的配置都存储在名为coredns的ConfigMap对象中,该对象位于kube-system名称空间中
kubectl get cm -n kube-system coredns -o yaml
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30 {
disable success cluster.local
disable denial cluster.local
}
loop
reload
loadbalance
}
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
CoreDNS上常用的插件简介
插件名称 | 插件功能 |
---|---|
errors | 启用错误日志 |
health | 启用CoreDNS进程自身的健康状态检测功能,默认的端点为8080端口上的/health,路径/health固定,但可使用自定义的套接字,例如“health localhost:8081” |
ready | 启用CoreDNS进程自身的就绪状态报告功能,默认的端点为8181端口上的/ready,路径/ready固定,但可使用自定义的套接字,例如“health localhost:8082” |
kubernetes | 用于从kubernetes集群加载区域解析相关的数据,从而为Kubernetes集群提供内部服务解析功能 |
prometheus | 启用CoreDNS内置的Prometheus格式的指标,默认的端点为8181端口上的/metrics”,路径/metrics固定,但可使用自定义的套接字,例如“health localhost:8083” |
forward(或proxy) | 将DNS名称查询请求转发给指定的其它DNS服务器;Kubernetes CoreDNS 默认配置中的forward指令能够将对所有域名的查询请求转发给(宿主机的)/etc/resolv.conf文件中指定的DNS服务器 |
cache | 启用对DNS查询结果的缓存功能;查询结果来自后端服务且开销较高时能产生高价值;默认缓存时长为3600s |
loop | 启用DNS查询过程中的环路检测功能,该插件会在检测到环路时停止查询操作 |
reload | 允许自动重载更改的Corefile配置 |
loadbalance | 基于随机算法,为A、AAAA或MX类型的资源记录的多条查询结果上启用负载均衡功能 |
hosts | 使用类似于/etc/hosts网格的文件格式提供区域解析数据,仅支持A、AAAA和PTR记录类型 |
bind | 为服务器配置段指定要监听的IP地址或网络接口,格式为“bind ADDRESS |
CoreDNS查询路由概述
- CoreDNS处理DNS查询的方式
1、针对每个套接字,CoreDNS会生成一个服务器(dnsserver.Server)
2、一个套接字上存在多个配置段(Server Block)时,CoreDNS将组合这些配置段生成单个服务器上的多个独立配置段,并将发往该套接字的DNS查询请求路由到最佳匹配的目标配置段
3、若不存在匹配的服务器配置段,则返回SERVERFAIL - CoreDNS的插件可大致分为两类
1、负责处理请求的常规插件(Normal Plugin),这些插件才是插件链中的有效组成部分,例如errors、kubernetes和forward等
2、不处理请求的特殊插件,它们仅用来修改Server或Server Block中的配置,例如health、tls、startup、shutdown和root等插件,这类插件不会作为服务器配置段的插件链中的有效组成部署 - 常规插件可再次划分为两种类型
1、负责以某种方式处理请求的插件
2、后端插件这类插件不是区域数据源,它们的运行方式是在自身处理完成后,会将查询传递给下一个插件
用于配置区域数据的来源,例如etcd、file和kubernetes等 这类插件通常要为其负责的区域生成最终结果,它要么能正常响应查询,要么返回NXDOMAIN 但也可以使用fallthrough改变这种响应行为:未发现查询的目标资源记录时,将DNS查询请求转交给插件链中的下一个插件,随后终结于另一个后端插件,或再次由fallthrought改变这种行为
CoreDNS查询路由示例
coredns.io:5300 {
file /etc/coredns/zones/coredns.io.db
}
magedu.com:53 {
errors
log
file /etc/coredns/zones/magedu.com.db
}
magedu.net:53 {
file /etc/coredns/zones/magedu.net.db
}
.:53 {
errors
log
health
rewrite name jenkins.haoge.com jenkins.jenkins.svc.cluster.local
kubernetes cluster.local 10.244.0.0/16
file /etc/coredns/haoge.db haoge.org
forward . /etc/resolv.conf
cache 30
}
CoreDNS的kuberntes插件
插件的配置参数简介
插件名称 | 插件功能 |
---|---|
endpoint | 指定kubernetes API Server的URL,默认为CoreDNS Pod所使用的ServiceAccount可接入的自身所在集群的API Server |
tls | 用于建立远程k8s连接时要使用的tls证书、私钥和CA证书 |
kubeconfig | 用于谁到远程k8s时使用的kubeconfig文件 |
namespaces | 仅对外暴露(提供Service名称解析)的k8s名称空间的列表,默认为所有名称空间 |
labels | namespace资源对象的标签选择器,匹配到的namespace中的Service才会对外暴露 |
pods | 为Pod生成基于IP的资源记录时的处理模式,disabled:不处理Pod级别的名称解析请求,默认配置;insecure:不检查k8s,而直接返回一个带有IP地址的A记录;verified:若同一namespace中存在具有匹配的IP地址的Pod,则返回A记录 |
noendpoints | 禁止endpoint相关的资源记录,所有endpoint查询和headless查询都将生成NXDOMAIN |
fallthrough | 若当前插件解析失败,则仅将针对指定zone列表中的查询请求继续交由插件链中后续的插件进行处理 |
ignore empty_service | 为没有任何就绪的Service返回NXDOMAIN |
CoreDNS的rewrite插件
在CoreDNS内部对查询及响应进行重写,重写过程对客户端透明
语法:rewrite [continue|stop] FIELD [TYPE] [(FROM TO)|TTL] [OPTIONS]
一般来说,重写查询的name比较常见
# 语法:rewrite [continue|stop] name [exact|prefix|suffix|substring|regex] STRING STRING [OPTIONS]
示例(1):
rewrite name regex (jenkins.*)\.haoge\.com {1}.jenkins.svc.cluster.local
隐式的响应重写,可以定义在rewrite name规则的OPTIONS中
rewrite name regex (jenkins.*)\.haoge\.com {1}.jenkins.svc.cluster.local answer auto
显式报文重写,要使用明确定义的answer规则进行
rewrite stop {
name regex (jenkins.*)\.haoge\.com {1}.jenkins.svc.cluster.local
answer name (jenkins.*)\.jenkins.\.svc\.cluster\.local {1}.haoge.com
}
CoreDNS配置示例(自定义hosts风格解析库):
Corefile: |
.:53 {
errors
health {
lameduck 15s
}
ready
hosts {
192.168.139.20 k8s-master01.haoge.com
192.168.139.23 k8s-node01.haoge.com
192.168.139.24 k8s-node02.haoge.com
fallthrough
}
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
prefer_udp
}
cache 30
loop
reload
loadbalance
}
CoreDNS配置示例(将外部域名的解析全部交由指定的外部DNS服务器):
Corefile: |
.:53 {
errors
health {
lameduck 15s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . 172.29.9.252 172.29.9.253{
prefer_udp
}
cache 30
loop
reload
loadbalance
}
最后编辑:于浩 更新时间:2025-06-10 18:08