Kubernete Service

本文最后更新于 2025年8月14日 上午

Service服务是微服务架构中的核心概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,通过内置的负载均衡器将请求分发到后端的多个容器应用上。

定义

Service用于为一组提供服务的Pod对象抽象一个稳定的网络地址,是Kubernetes实现微服务架构的核心概念。通过Service的定义设置的访问地址是DNS域名格式的服务名称。但对于客户端应用来说,网络访问方式并没有改变。Service还提供了负载均衡器功能,可以将请求负载分发到各个Pod容器上。

配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: v1
kind: Service
metadata:
name: string
namespace: string
labels:
- name: string
annotations:
- name: string
spec:
selector: []
type: string
clusterIP: string
sessionAffinity: string
ports:
- name: string
protocol: string
port: int
targetPort: int
nodePort: int
status:
loadBanlancer:
ingress:
ip: string
hostname: string
字段路径 类型 说明
apiVersion string API 版本,例如 v1,决定了 Kubernetes 使用的资源定义版本。
kind string 资源类型,这里是 Service,表示定义一个服务。
metadata.name string Service 名称,必须在同一命名空间中唯一。
metadata.namespace string 所属命名空间,不指定时默认为 default
metadata.labels map<string,string> 标签(键值对),用于资源的标识和选择器匹配。
metadata.annotations map<string,string> 注解(键值对),用于存储非标识性元数据,如说明、外部系统信息等。
spec.selector map<string,string> Pod 标签选择器,指定 Service 要关联的 Pod(通过标签匹配)。
spec.type string Service 类型: -ClusterIP(默认):只在集群内部可访问。 -NodePort:在每个节点暴露一个端口对外访问。 -LoadBalancer:使用云服务商的负载均衡器。 -ExternalName:通过 DNS 名称代理到外部服务。
spec.clusterIP string Service 的虚拟 IP(Cluster IP)。由 Kubernetes 分配或手动指定。
spec.sessionAffinity string 会话亲和性: -None(默认):无会话保持。 -ClientIP:同一客户端 IP 始终访问同一 Pod。
spec.ports[].name string 端口名称,可选,用于区分不同用途的端口。
spec.ports[].protocol string 协议类型,如 TCP(默认)或 UDP
spec.ports[].port int Service 暴露的端口号。
spec.ports[].targetPort int/string 对应 Pod 容器上的端口号(或端口名)。
spec.ports[].nodePort int type=NodePort时,节点对外暴露的端口号(范围:30000-32767)。
status.loadBalancer.ingress[].ip string 负载均衡器分配的外部 IP 地址(仅 LoadBalancer类型)。
status.loadBalancer.ingress[].hostname string 负载均衡器分配的外部主机名(仅 LoadBalancer类型)。

概念

Service主要用于提供网络服务,通过Service的定义,能够为客户端应用提供稳定的访问地址和负载均衡功能,以及屏蔽后端变化。

应用

创建一个网络服务模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# webapp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 2
selecotr:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: kubeguide/tomcat-app:v1
ports:
- containerPort:8080

部署deployment后,会创建两个Pod ,它们具备不同的IP地址信息。

在外部进行访问的时候 ,服务端既不应该将实际的服务端口暴露到系统之外,同时也必然对外提供一个统一的服务接口,这里就需要通过Service这个资源对象完成对外部请求的支持和分发

kubebernetes提供了expose命令 ,来直接完成控制器对应Service的创建。

1
2
kubectl expose deployment webapp
service/webapp exposed

会创建对应的服务

1
2
3
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
webapp ClusterIP 169.169.140.242 <NONE> 8080/TCP 14s

查看服务可以查询到它所管理的endpoint 地址信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# kubectl describe service webapp
Name: webapp
Namespace: default
Labels: <none>
Annotations: <app=webapp>
Selector: app=webapp
Type: ClusterIP
IP: 169.169.140.229
IPs: 169.169.140.229
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
Endpoints: 10.0.95.22:8080 , 10.0.95.23:8080
Session Affinity: None
Events: <none>

也可以通过命令查询service关联的 endpoint 资源对象

1
2
3
# kubectl get endpoints

# kubectl get endpointslices

Service 自动完成了负载分发工作

负载均衡机制

负载均衡机制主要由kubeproxy负责实现

kube-proxy的代理模式

  • iptables模式

    • 优点 转发效率高,稳定
    • iptables规则没有对后端的健康检查机制。可能会出现无法获知Pod状态导致的服务不可靠。需要使用readinessProbe探针确定服务可用性。每次新建Service或Endpoint发生变化是,kube-proxy都会刷新本Node的全部iptables规则,可以通过调整策略来控制同步时间
    1
    2
    3
    iptables:
    minSyncPeriod: 1s
    syncPeriod: 30s

    minSyncPeriod: 同步iptables规则的最短时间间隔

    • 属性为0时,表示Service或Endpoint发生变化就会立刻同步规则
    • 设置较大值时可能会导致间隔时间过长

    syncPeriod: 设置iptables规则的同步时间间隔,用于与Service或EndpointSlice变化无关的iptables规则的同步,以及用于定时清理iptables规则

  • ipvs 模式

    • ipvs模式基于Linux操作系统内核的netfilter钩子函数,类似于iptables模式,使用散列表作为底层数据结构,并且工作在内核空间,这使得ipvs模式比iptables模式的转发性能更高,延迟更低,同步效率也更高
    • ipvs支持的负载均衡策略
      • rr (Round Robin): 轮询
      • wrr (Weighted Round Robin):加权轮询
      • lc (Least Connection):最小连接数
      • wlc (Weighted Least Connection):加权最小连接数
      • lblc (Locality Based Least Connection):基于地域的最小连接数
      • lblcr (Locality Based Least Connection with Replication):带副本的基于地域的最小连接数
      • sh (Source Hashing): 源地址散列
      • dh (Destination Hashing):目的地址散列
      • sed (Shortest Expected Delay):最短期望延时
      • nq (Neve Queue):永不排队
  • kernelspace模式

    • 基于windows内核数据包转发规则的代理模式

会话保持机制

Service支持通过设置sessionAffinity来实现基于客户端IP地址的会话保持机制,可以将某个客户端来源IP地址发起的请求转发到后端的某个Pod上,之后从相同的客户端IP发起的请求都将被转发到相同的后端Pod上。同时可以配置客户端保持会话的最长时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
ports:
- protocol: TCP
port: 8080
targetPort: 8080
selector:
app: webapp

流量策略

通过设置 spec.internalTrafficPolicy 和 spec.externalTrafficPolicy 设置流量路由策略

internalTrafficPolicy

Cluster : 将从内部源发起的流量路由到所有处于Ready状态的Endpoint

Local: 将从内部源发起的流量仅路由到本地Node上处于Ready状态的Endpoint,如果没有Ready的Endpoint,则丢弃该流量

externalTrafficPolicy

Cluster : 将从外部源发起的流量路由到所有处于Ready状态的Endpoint

Local: 将从外部源发起的流量仅路由到本地Node上处于Ready状态的Endpoint,如果没有Ready的Endpoint,则丢弃该流量

ProxyTerminatingEndpoints

发往正在停止的Endpoint的流量策略。开启ProxyTerminatingEndpoints特性门控进行启用,当流量策略为Local时,kube-proxy将检测本地Node上存在的Endpoint并且所有Endpoint都处于停止中状态,但是服务仍然就绪且可以接受请求。

负载均衡

多端口设置

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- port: 8080
targetPort: 8080
- port: 8085
targetPort: 8085
name: management
selector:
app: webapp

或者多协议配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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: 169.169.0.100
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP

外部服务定义为Service

不再使用标签绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
---
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subnets:
- addresses:
- ip: 1.2.3.4
ports:
- port: 80

Serviced 的类型

ClusterIP

Kubernetes默认会自动设置Service的虚拟IP地址,仅可被集群中的客户端应用访问

kube-apiserver服务的启动参数—service-cluster-ip-range设置了Service的IP地址范围,系统将自动从这个IP地址池中为Service分配一个可用的IP地址

地址也可用手动指定,但是必须未被其他应用所使用,且在地址池范围内。

NodePort

将Service的端口号映射到每个Node的一个端口号上,这样集群中的任意Node都可以作为Service的访问入口地址,即NodeIP:NodePort

NodePort类型用于将Service暴露到Node上,这样集群外的客户端可用通过Node的IP地址访问集群中的Service

LoadBalancer

将Service映射到一个已存在的负载均衡器的IP地址上,通常在公有云环境下使用

通常在使用外部负载均衡器的云平台时,可用设置Service的类型为LoadBalancer,用于将内部Service映射到云平台的负载均衡器上。

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion:v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
clusterIP: 10.0.171.239

服务创建成功后,会向Service的配置信息中补充LoadBalancer的IP地址

1
2
3
4
status:
loadBalancer:
ingress:
- ip: 192.0.2.127

ExternalName

将Service映射为一个外部域名地址,通过externalName字段进行设置

1
2
3
4
5
6
7
8
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com

当外部请求尝试访问my-service.prod.svc.cluster.local时 会自动替换为 my.database.example.com

无头服务

当服务没有入口访问地址(clusterIP),那么kube-proxy不会为器创建负载转发规则,而服务名的解析机制根据无头服务是否设置了标签选择器而采取不同策略

  1. 设置了标签选择器

如果设置了标签选择器,则Kubernetes将根据标签选择器查询后端Pod列表,自动创建Endpoints列表,将服务名的解析机制设置为:当客户段访问该服务名时,得到的是全部Endpoints列表

1
2
3
4
5
6
7
8
9
10
11
12
13
# nginx-headless-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
clusterIP: None
selector:
app: nginx
  1. 未设置标签选择器

如果Headless Service 没有设置标签选择器,则Kubernetes不会自动创建对应的Endpoints列表。DNS

会根据下列条件尝试对该服务名设置DNS记录

  • 如果Service的类型未ExternalName,则尝试将服务名的DNS记录设置为外部名称对应的CNAME记录
  • 对于其他类型的Service,系统将对Service后端处于Ready状态的Endpoint创建DNS记录,针对IPV4地址创建A记录,针对IPV6地址类型创建AAAA记录

为服务设置外部IP

在某些环境下,如果可以通过某个集群外部IP地址访问集群,可以将Service暴露给外部IP地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
selector:
app: webapp
ports:
- protocol: TCP
port: 8080
targetPort: 8080
externaleIPs:
- 192.168.18.100

服务发现

服务发现机制指在一个Kubernetes集群中客户端应用如何获取后端服务的访问地址。Kubernetes提供了两种机制供客户端应用以固定的方法获取后端服务的访问地址

环境变量

在一个Pod运行起来时,系统会自动为其容器运行环境注入所有集群中有效Service的信息。

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 8080
selector:
app: webapp

在Pod中查看环境变量

1
2
3
4
5
6
7
WEBAPP_SERVICE_HOST=169.169.81.175
WEBAPP_SERVICE_PORT=8080
WEBAPP_PORT=tcp://169.169.81.175:8080
WEBAPP_PORT_8080_TCP=tcp://169.169.81.175:8080
WEBAPP_PORT_8080_TCP_PROTO=tcp
WEBAPP_PORT_8080_TCP_PORT=8080
WEBAPP_PORT_8080_TCP_ADDR=169.169.81.175

使用变量名尝试访问

1
curl <http://$>{WEBAPP_SERVICE_HOST}:${WEBAPP_SERVICE_PORT}

DNS

Service 在Kubernetes系统中遵循DNS命名规范,DNS域名的表示方法为

<servicename>.<namespace>.svc.<clusterdomain>

servicename: 服务名

namespace: 命名空间名

clusterdomain: k8s集群设置的域名后缀

当在服务中为端口号设置了name,在DNS中也会添加该端口号的DNS记录

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 8080
name: http
selector:
app: webapp

对应解析记录

1
2
3
4
5
6
# nslookup -q=srv _http._tcp.webapp.default.svc.cluster.local
Server 169.169.0.100
Address 169.169.0.100#53

_http._tcp.webapp.default.svc.cluster.local service= 0 100 8080
webapp.default.svc.cluster.local

DNS 服务

需要在每个Node上设置kubelet的启动参数 ,在其中加上以下两个参数

— cluster-dns = 169.169.0.100 : 是DNS服务的ClusterIP地址

— cluster-domain = cluster.local : 是DNS服务中设置的域名

部署CoreDNS

ConfigMap 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
labels:
addonmananger.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
}

Deployment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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:
preferredDuringSchedulingIngoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpression:
- key: k8s-app
operator: In
values: ["kube-dns"]
topologyKey: kubernetes.io/hostname
containers:
- name: coredns
image: coredns/coredns: 1.9.0
imagePullPolicy: IfNotPersent
resources:
limits:
memroy: 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:
- all
readOnlyRootFilesystem: true
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /ready
port: 8080
scheme: HTTP
dnsPolicy: Default
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile

Service “kube-dns”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
portocol: TCP
- name: metrics
port: 9153
portocol: TCP

创建服务

1
kubectl create -f coredns.yaml

CoreDNS的配置

  • loadbalance : 提供基于DNS的负载均衡功能
  • loop : 检测在DNS解析过程中出现的简单循环问题
  • cache : 提供前端缓存功能
  • health : 对Endpoint进行健康检查
  • kubernetes : 从Kubernetes中读取Zone数据
  • etcd : 从etcd中读取Zone数据,可用于自定义域名记录
  • file : 从RFC1035格式文件中读取Zone数据
  • hosts : 使用/etc/hosts 文件或者其他文件读取Zone数据,可用于自定义域名记录
  • auto : 从磁盘中自动加载区域文件
  • reload : 定时自动重新加载Corefile配置文件的内容
  • forward : 转发域名查询到上游DNS服务器中
  • prometheus : 为Prometheus系统提供采集性能指标数据的URL
  • pprof : 在URL路径/debug/pprof下提供运行时的性能数据
  • log : 对DNS查询进行记录
  • errors : 对错误信息进行日志记录

Service 和 Pod的 DNS 相关特性

Service 的DNS域名

对于Service来说,Kubernetes会设置一个如下格式的DNS域名

1
<service-name>.<namespace-name>.svc.<cluster-domain>

Pod的DNS域名

对于Pod来说,Kubernetes会设置一个如下格式的DNS域名

1
<pod-ip>.<namespace>.pod.<cluster-domain>

对于关联了服务的Pod,则被设置为

1
<pod-ip>.<service-name>.<namespace>.svc.<cluster-domain>

自定hostname和subdomain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Pod
metadata:
name: webapp1
labels:
app: webapp1
spec:
hostname: webapp-1
subdomain: mysubdomain
containers:
- name: webapp-1
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080

对应的域名配置

1
<pod-hostname>.<pod-subdomain>.<namespace-name>.svc.<cluster-domain>

如果创建了一个无头服务关联的Pod 则域名会被设置为

1
<pod-hostname>.<headless-service-name>.<namespace-name>.svc.<cluster-domain>

FQDN 格式的Pod主机名设置

在默认情况下,Pod的各容器内的主机名为Pod名称。

可以通过—fqdh 可以查询主机的全名

1
2
3
4
5
6
# kubectl exec -it webapp1 --hash
root@webapp-1:/usr/local/tocam# hostname
webapp-1

# hostname --fqdn
webapp-1.mysubdomain.default.svc.cluster.local

可以在setHostnameAsFQDN=ture 来直接查询服务的全域主机名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Pod
metadata:
name: webapp1
labels:
app: webapp1
spec:
setHostnameAsFQDN: true
hostname: webapp-1
subdomain: mysubdomain
containers:
- name: webapp1
image: kubeguide/tomcat-app:v1
imagePullPolicy: IfNotPersent
ports:
- containerPort: 8080

Pod的DNS策略

Kubernetes可以在Pod的dnsPolicy 字段中设置几种不同的DNS策略,目前支持的DNS策略如下

  • Default : 继承Pod 所在Node的域名解析设置
  • ClusterFirst : 优先使用Kubernetes环境的DNS服务,并且将非集群域名后缀的域名都转发给系统配置的上游DNS服务器,这也是系统的默认值
  • ClusterFirstWithHostNet : 专用于以hostNetwork模式运行的Pod
  • None : 忽略Kubernetes集群的DNS配置,允许用户手动通过dnsConfig字段自定义DNS配置

Pod的自定义配置

  • nameservers : 用于域名解析的DNS服务器列表。
  • searches : 用于域名搜索的DNS域名后缀。
  • options : 配置其他可选DNS参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion:
kind: Pod
metadata:
name: custom-dns
spec:
containers:
- name: custom-dns
image: tomcat
imagePullPolicy: IfNotPersent
ports:
- containerPort: 8080
dnsPolicy: "None"
dnsConfig:
nameservers:
- 8.8.8.8
searches:
- nsl.svc.cluster-domain.example
- my.dns.search.suffix
options:
- name: ndots
value: "2"
- name: edns0

Ingress

Kuberntes使用了一个Ingress资源,用于定义策略和一个提供路由转发服务的Ingress Controller。

使用Ingress提供路由服务时,ingress Controller 基于Ingress规则将客户端请求直接转发到Service对应的后端Endpoint上,这样会跳过kube-proxy设置的路由转发规则,以提高转发效率。

Ingress 配置部署

Namespace :

1
2
3
4
apiVersion: v1
kind: Namespace
metadata:
name: nginx-ingress

ServiceAccount :

1
2
3
4
5
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress
namespace: nginx-ingress

RBAC 资源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
kind: ClusterRole
apiVersion: rabc.authorization.k8s.io/v1
metadata:
name: nginx-ingress
rule:
- apiGroups:
- ""
resources:
- services
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- update
- create
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- list
- apiGroups:
- ""
resources:
- extensions
resources:
- ingress
verbs:
- list
- watch
- get
- apiGroups:
- "extensions"
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- k8s.nginx.org
resources:
- virtualservers
- virtualserverroutes
- globalconfigurations
- transportservers
- policies
verbs:
- list
- watch
- get
- apiGroups:
- k8s.nginx.org
resources:
- virtualserver/status
- virtualsererroutes/status
verbs:
- update
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nginx-ingress
subjects:
- kind: ServiceAccount
name: nginx-ingress
namespace: nginx-ingress
roleRef:
kind: ClusterRole
name: nginx-ingress
apiGroup: rbac.authorization.k8s.io

Secrets :

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Secret
metadata:
name: default-server-secret
namespace: nginx-ingress
type: Opaque
data:
tls.crt: base64_code
tls.key: base64_code

ConfigMap:

1
2
3
4
5
6
7
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-config
namespace: nginx-ingress
data:
...

Deployment:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress
namespace: nginx-ingress
spec:
replicas: 1
selector:
matchLabels:
app: nginx-ingress
template:
metadata:
labels:
app: nginx-ingress
spec:
serviceAccountName: nginx-ingress
containers:
- image: nginx/nginx-ingress:1.7.2
imagePullPolicy: IfNotPresent
name: nginx-ingress
ports:
- name: http
containerPort: 80
hostPort: 80
- name: https
containerPort: 443
hostPort: 443
securityContext:
allowPrivilegeEscalation: true
runAsUser: 101
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
args:
- -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
- -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
- -ingress-class=nginx

创建Ingress策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mywebsite-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: mywebsite.com
http:
paths:
- path: /demo
pathType: ImplementationSpecific
backend:
service:
name: webapp
port:
number: 8080

Ingress规则

  • rule :
    • host : 基于域名的访问,客户端请求将作用于指定域名的客户端请求
    • http.paths : 一组根据路径进行转发的规则设置,每个路径都应配置相应的后端服务信息。只有host和path都匹配上才会进行转发
    • backend : 目标后端服务,包括服务的名称和端口号

对外部服务的引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource-backend
spec:
defaultBackend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: static-assets
rules:
- http
paths:
- path: /icons
pathType: ImplementationSpecific
backend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: icon-asserts

IngressClassName 和IgressClass 资源对象

通过IgressClass 对象来配置 指定Ingress 使用哪个Controller

1
2
3
4
5
6
7
8
9
10
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: external-lb
spec:
controller: example.com/ingress-controller
parametes:
apiGroup: k8s.example.com
kind: IngressParametes
name: external-lb

创建Ingress 对象指定 使用IngressClass 中的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
ingressClassName: external-lb
rules:
- host:"*.example.com"
http:
paths:
- path: /example
pathType: Prefix
backend:
service:
name: example-service
port:
number: 80

设置Ingress的 作用范围

1
2
3
4
5
6
7
8
9
10
11
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: external-lb-1
spec:
controller: example.com/ingress-controller
parameters:
scope: Cluster
apiGroup: k8s.example.net
kind: ClusterIngressParameter
name: external-config-1

设置以命名空间为作用范围的ingress策略

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: external-lb-2
spec:
controller: example.com/ingress-controller
parameters:
scope: Namespace
apiGroup: k8s.example.com
kind: IngressParameter
namespace: external-configuration
name: external-config

设置默认ingress配置策略

1
2
3
4
5
6
7
8
9
10
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
name: nginx-example
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx

Ingress 策略配置

转发给单个后端服务

1
2
3
4
5
6
7
8
9
10
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
defaultBackend:
service:
name: webapp
port:
number: 8080

将同一域名的不同URL路径转发给不同的后端服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: mywebsite.com
http:
paths:
- path: /web
pathType: ImplementationSpecific
backend:
service:
name: web-service
port:
number: 8080
- path: /api
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 8081

将HTTP请求根据不同的域名转发给不同的后端服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: servicel
port:
number: 80
- host: bar.foo.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service2
port:
number: 80

不适用域名的转发规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- http:
paths:
- path: /demo
pathType: Prefix
backend:
service:
name: webapp
port:
number: 8080

Ingress Gateway

Kubernetes 为了提供更丰富的协议转发支持,定义了Gateway API,它可以声明以下基类资源

  • GatewayClass : 用于表示Gateway的类型
  • Gateway : 网管实例
  • Route : 路由规则

定义示例

定义GatewayClass

1
2
3
4
5
6
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: example-class
spec:
controllerName: example.com/gateway-controller

定义Gateway

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-httproute
spec:
parentRefs:
- name: example-gateway
hostname:
- "www.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /login
backendRefs:
- name: example-svc
port: 8080

Kubernete Service
http://gadoid.io/2025/08/14/Kubernetes-服务/
作者
Codfish
发布于
2025年8月14日
许可协议