Kubernetes 权威指南 - 深入掌握Service
1. Service 定义详情
YAML 格式的Service 定义文件的完整内容如下:
apiVersion: v1 // Required
kind: Service // Required
metadata:
name: string // Required
namespace: string // Required
labels:
- name: string
annotations:
- name: string
spec: // Required
selector: [] // Required
type: string // Required
clusterIP: string
sessionAffinity: string
ports:
- name: string
protocol: string
port: int
targetPort: int
nodePort: int
status:
loadBalancer:
ingress:
ip: string
hostname: string
下表对Service的定义文件模板的各属性的说明:
属性名称 | 取值类型 | 是否必选 | 取值说明 |
---|---|---|---|
apiVersion | string | Required | v1 |
kind | string | Required | Service |
metadata | object | Required | 元数据 |
metadata.name | string | Required | Service名称,需符合RFC1035规范 |
metadata.namespace | string | Required | 命名空间,不指定系统时将使用名为default 的命名空间 |
metadata.labels[] | list | - | 自定义标签属性列表 |
metadata.annotations[] | list | - | 自定义注解属性列表 |
spec | object | Required | 详细描述 |
spec.selector[] | list | Required | Label Selector配置,将选择具有指定Label标签的Pod作为管理范围 |
spec.type | string | Required | Service的类型,指定Service的访问方式,默认值为ClusterIP 。1. ClusterIP :虚拟的服务IP地址,该地址用于Kubernetes集群内部的Pod访问,在Node上kube-proxy 通过设置的iptables规则进行转发。2. NodePort :使用宿主机的端口,使能够访问各Node的外部客户端通过Node的IP地址和端口号就能访问服务。3. LoadBalancer :使用外接负载均衡器完成到服务的负载分发,需要在spec.status.loadBalancer 字段指定外部负载均衡器的IP地址,并同时定义nodePort 和clusterIP ,用于公有云环境。 |
spec.clusterIP | string | - | 虚拟服务IP地址,当type=ClusterIP 时,如果不指定,则系统进行自动分配,也可以手工指定;当type=LoadBalancer 时,则需要指定 |
spec.sessionAffinity | string | - | 是否支持Session ,可选值为ClusterIP ,默认值为空。 ClientIP :表示将同一个客户端的访问请求都转发到同一个后端Pod |
spec.ports[] | list | - | Service 需要暴露的端口列表 |
spec.ports[].name | string | - | 端口名称 |
spec.ports[].protocol | string | - | 端口协议,支持TCP和UDP,默认值为TCP |
spec.ports[].port | int | - | 服务监听的端口号 |
spec.ports[].targetPort | int | - | 需要转发到后端 Pod 的端口号 |
spec.ports[].nodePort | int | - | 当spec.type=NodePort 时,需要指定映射到物理机的端口号 |
Status | object | - | 当spec.type=LoadBalancer 时,设置外部服负载均衡器的地址,用于公有云环境 |
staus.loadBalancer | object | - | 外部负载均衡器 |
status.loadBalancer.ingress | object | - | 外部负载均衡器 |
status.loadBalancer.ingress.ip | string | - | 外部负载均衡器 |
status.loadBalancer.ingress.hostname | string | - | 外部负载均衡器 |
2. Service 的基本用法
一般来说,容器应用都是通过TCP/IP机制及监听IP和端口号来实现。
# cat > webapp-rc.yaml << EOF
---
apiVersion: v1
kind: ReplicationController
metadata:
name: webapp
spec:
replicas: 2
template:
metadata:
name: webapp
labels:
app: webapp
spec:
containers:
- name: webapp
image: tomcat
ports:
- containerPort: 8080
EOF
创建该 RC:
# kubectl create -f webapp-rc.yaml
获取 Pod 的 IP 地址:
# kubectl get pods -l app=webapp -o yaml | grep podIP
那么就可以直接通过这两个Pod的IP地址和端口号访问Tomcat服务。
直接通过Pod的IP地址和端口号可以访问到容器应用内的服务,但是Pod的IP地址是不可靠的,例如当Pod所在的Node发生故障时,Pod将被Kubernetes重新调度到另一台Node,Pod的IP地址将发生变化。
如果容器应用本身是分布式的部署,通过多个实例共同提供服务,就需要在这些实例的前端设置一个负载均衡器来实现请求分发。 Kubernetes中的Service就是用于解决这个问题的核心组件。
方式一:Kubernetes提供了一种快速的方法,即通过kubectl expose
命令来创建Service:
# kubectl expose rc webapp
service "webapp" exposed
# kubectl get svc
那么,接下来就可以通过Service的IP地址和Service的端口号访问该Service了。
方式二:除了使用kubectl expose
命令创建service,我们也可以通过配置文件定义Service
,再通过kubectl create
命令进行创建:
# cat > webapp_service.yaml << EOF
---
apiVersion:v1
kind: Service
metadata:
name: webapp
spec:
ports:
- port: 8081
targetPort: 8080
selector:
app: webapp
EOF
其中,Service定义中的关键字段是prots
和selector
。 selector
定义部分设置的是后端Pod所拥有的label: app=webapp
。
目前 Kubernetes 提供了两种负载分发策略:RoundRobin
和SessionAffinity
,具体说明如下:
- RoundRobin:轮询模式,即轮询将请求转发到后端的各个Pod上。 默认策略
- SessionAffinity:基于客户端IP地址进行会话保持的模式,相同的客户端发起的请求都将被转发到后端相同的Pod上。
默认采用RoundRobin
轮询模式进行负载分发,但是也可以通过设置service.spec.sessionAffinity=ClientIP
来启用SessionAffinity
策略。
2.1 多端口 Service
在Service的定义中也可以设置多个端口。
....
ports:
- port: 8081
targetPort: 8080
name: web
- port: 8005
targetPort: 8005
name: management
....
2.2 外部服务 Service
我们可以将 Service 的标签选择器设置为空,再手动创建一个EndPoints
资源与之绑定。
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
通过该定义创建的是一个不带标签选择器的Service,即无法选择后端的Pod,系统不会自动创建Endpoint
,因此需要手动创建一个和该Service
同名的Endpoint
,用于指向实际的后端访问地址。
创建Endpoint
的配置文件内容如下:
kind: Endpoints
apiVersion: v1
metadata:
name: my-service
subsets:
- addresses:
- IP: 1.2.3.4
ports:
- port: 80
如此依赖,访问该Service将会被路由到由用户自定义的后端Endpoint
上。
Headless Service
即不为Service设置ClusterIP(入口IP地址),仅通过Label Selector将后端的Pod列表搜返回给调用的客户端。
apiVersion: v1
kind: Service
metadata:
name: nginx
labels: null
app: nginx
spec:
ports:
- port: 80
ClusterIP: None
selector:
app: nginx
Service就不再具有一个特定的ClusterIP地址,对其进行访问降火的包含Label "app=nginx"的全部Pod IP列表。
从集群外部访问Pod或Service
可以将Pod或Service的端口号映射到宿主机,以使客户端应用能够通过物理机访问容器应用。
1. 单一容器级别的 hostPort 设置
---
apiVersion: v1
kind: Pod
metadata:
name: webapp
labels:
app: webapp
spec:
containers:
- name: webapp
image: tomcat
ports:
- containerPort: 8080
hostPort: 8081 // 这里设置单一容器级别的 hostPort 端口
2. Pod级别的 hostNetwork 设置
通过设置Pod级别的hostNetwork=true
,该Pod中的所有容器的端口号都将被直接映射到物理机上。
在这是
hostNetwork=true
时需要注意,在容器的ports
定义部分如果不指定hostPort
,则默认hostPort
等于containerPort
,
如果指定了hostPort
,则该hostPort
必须等于containerPort
的值:
apiVersion: v1
kind: Pod
metadata:
name: webapp
labels:
app: webapp
spec:
hostNetwork: true // 这里设置Pod级别的 hostNetwork
containers:
- name: webapp
image: tomcat
ports:
- containerPort: 8080
将 Service 通过 nodePort 方式将端口号映射到物理机
- 通过设置
nodePort
映射到物理机,同时设置Service的类型为NodePort
:
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
type: NodePort // type设置为 NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 8081 // 设置 nodePort 端口,将所有节点上的该端口映射到该Service
selector:
app: webapp
外部子系统通过该集群内所有 Node 节点的该端口,即可访问到该 Service 。
- 通过设置 LoadBalancer 映射到云服务商提供的 LoadBalancer 地址。 这种做法仅用于在公有云服务提供商的云平台上设置 Service 的场景。
以下示例,对该Service的访问请求将会通过LoadBalancer
转发到后端Pod上,负载分发的实现方式则依赖于云服务提供商的LoadBalancer 的实现机制:
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
type: LoadBalancer // type设置为LoadBalancer
loadBalancerIP: 78.11.24.19 // 设置集群的LoadBalancerIP
clusterIP: 10.0.171.239
ports:
- port: 80
targetPort: 9376
nodePort: 30061
selector:
app: webapp
status:
loadBalancer:
ingress:
- ip: 146.148.47.155 // 将会设置为云服务提供商提供的LB IP地址
DNS 服务搭建和配置指南
KubeDNS
KubeDNS 由 3 个容器组成:kubedns
、dnsmasq
和sidecar
,将DNS记录直接保存在内存中,以提高查询性能。
kubedns
容器监控Kubernetes中Service资源的变化,根据Service的名称和IP地址生成DNS记录,并将DNS记录保存在内存中;dnsmasq
容器从kubedns
中获取DNS记录,提供DNS缓存,为客户端容器应用提供DNS查询服务;sidecar
提供对kubedns
和dnsmasq
服务的健康检查功能。
CoreDNS
从 Kubernetes 1.11 版本开始,Kubernetes集群的DNS服务由 CoreDNS
提供。 CoreDNS是 CNCF基金会的一个项目,是用 Go 语言实现的高性能、插件式、以扩展的DNS服务端。 CoreDNS解决了KubeDNS的一些问题,例如dnsmasq
的安全漏洞、externalName
不能使用stubDomains
设置,等等。
CoreDNS
支持自定义DNS记录及配置upstream DNS Server
,可以统一管理Kubernetes基于服务的内部DNS和数据中心的物理DNS。
CoreDNS 没有使用多个容器的架构,只用一个容器便实现了 KubeDNS 内 3 个容器的全部功能。
在创建 DNS 服务之前修改每个 Node 上的 kubelet 的启动参数
修改每个kubelet的启动参数,加上以下两个参数:
--cluster-dns=clusterIP #clusterIP是具体配置的k8s可用的ip地址
--cluster-domain=cluster.local #配置DNS服务中设置的域名
修改启动参数可在:10-kubeadm.conf 或在kubelet其他加载的配置文件中添加配置(比如1.18的, /etc/sysconfig/kubelet)
使用
kubeadm
安装的集群,可以在/var/lib/kubelet/config.yaml
修改clusterDNS
的地址信息,以及clusterDomain
的域名信息。
配置完之后重启kubelet服务。
创建 CoreDNS 应用
在部署 CoreDNS 应用前,至少需要创建一个 ConfigMap
、一个Deployment
和一个Service
共3个资源对象。
在启用了 RBAC 的集群中,还可以设置 ServiceAccount
、ClusterRole
、ClusterRoleBinding
对CoreDNS容器进行权限设置。
CoreDNS 的配置说明
CoreDNS 的主要功能是通过插件系统实现的。 CoreDNS 实现了一种链式插件结构,将DNS的逻辑抽象成了一个个插件,能够灵活组合使用。
常用插件如下:
- 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 服务器。
- proxy:转发特定的域名查询到多个其他 DNS 服务器,同时提供到多个 DNS 服务器的负载均衡功能。
- prometheus:为 Promethus 系统提供采集性能指标数据的 URL。
- pprof:在 URL 路径
/debug/pprof
下提供运行时的性能数据。 - log:对 DNS 查询进行日志记录。
- errors:对错误信息进行日志记录。
例如使用 file
插件配置自定义域解析:
(1). 编辑deployment 定义 zone 文件挂载路径(注意CoreDNS pod所在的每一个宿主机都需要有该文件)
volumes:
- configMap:
defaultMode: 420
items:
- key: Corefile
path: Corefile
name: coredns
name: config-volume
- hostPath:
path: /tmp/test.org.zone // 宿主机上zone文件存放的位置
type: FileOrCreate // 如果不存在该文件,则默认创建空白文件
name: test-zone
(2). 编辑 deployment 定义 zone 文件的容器挂载位置
volumeMounts:
- mountPath: /etc/coredns
name: config-volume
readOnly: true
- mountPath: /tmp/test.org.zone // 在容器内部的挂载路径
name: test-zone
readOnly: true
(3). 编辑 ConfigMap 配置文件,添加自定义域的解析规则
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
loop
reload
loadbalance
}
test.org:53 { // 添加自定义域的转发规则
file /tmp/test.org.zone // 使用 file 插件读取 zone 文件
}
(4). 添加 zone 文件权威域的解析记录(默认动态加载)
$ORIGIN test.org.
@ 3600 IN SOA ns1.test.org. mail.test.org. (
2022051501
20M
5M
5D
1D
)
@ 86400 IN NS ns1.test.org.
3600 IN NS ns2.test.org.
www IN A 1.1.1.1
IN TXT "Hello"
(5). 测试
##### 获取 kube-dns 的 svc IP地址
# kubectl get svc kube-dns -n kube-system
##### 开始解析
# dig www.test.org @10.96.0.10
例如使用 etcd
插件配置自定义域解析:
(1). 编辑 deployment 定义etcd所使用的证书文件挂载路径
volumeMounts:
- mountPath: /etc/coredns
name: config-volume
readOnly: true
- mountPath: /server.crt // 挂载到根路径
name: etcd-cert
readOnly: true
- mountPath: /server.key
name: etcd-key
readOnly: true
- mountPath: /ca.crt
name: etcd-ca
readOnly: true
volumes:
- configMap:
defaultMode: 420
items:
- key: Corefile
path: Corefile
name: coredns
name: config-volume
- hostPath:
path: /etc/kubernetes/pki/etcd/server.crt
type: FileOrCreate
name: etcd-cert
- hostPath:
path: /etc/kubernetes/pki/etcd/server.key
type: FileOrCreate
name: etcd-key
- hostPath:
path: /etc/kubernetes/pki/etcd/ca.crt
type: FileOrCreate
name: etcd-ca
(2). 编辑 coredns 的 configmap 配置文件,添加 etcd 插件的配置
etcd test2.com {
path /test2_dns_test
endpoint http://192.168.22.210:2379
tls /server.crt /server.key /ca.crt
fallthrough
}
其中,
tls
指令需要根据先后顺序依次指定服务端证书、服务端私钥、自签ca证书。
参考文档链接:https://coredns.io/plugins/etcd/#syntax
(3). 在 etcd 库中添加解析记录
kubectl exec -n kube-system etcd-k8s01.localdomain -it -- etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key put /test2_dns_test/com/test2/www '{"host": "2.2.2.2", "ttl": 60}'
注意:这里需要指定证书路径。
(4). 开始测试。
这部分暂未达成。跳过。
Pod 级别的 DNS 配置说明
除了使用集群范围的 DNS 服务(比如CoreDNS),在Pod级别也能设置DNS的相关策略和配置。
在 Pod 的 YAML 配置文件中通过spec.dnsPolicy
字段设置 DNS 策略。
可选取值如下:
- Default:继承Pod所在宿主机的DNS设置。
- ClusterFirst:优先使用Kubernetes环境的DNS服务,将无法解析的域名转发到从宿主机继承的DNS服务器。
- ClusterFirstWithHostNet:与ClusterFirst相同,对于以
hostNetwork
模式运行的Pod,应明确指定使用该策略。 - None:忽略Kubernetes环境的DNS配置,通过
spec.dnsConfig
自定义DNS配置。 该选项在 1.14 版本升级为稳定版。
自定义DNS配置可以通过 spec.dnsConfig
字段设置:
- nameservers:一组DNS服务器的列表,最多可以设置3个。
- searches:一组用于域名搜索的DNS域名后缀,最多可以设置6个。
- options:配置其他可选DNS参数,例如
ndots
、timeout
等,以name
或name/value
对的形式表示。
以下是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.local
- my.dns.search.suffix
options:
- name: ndots
value: '2'
- name: edns0
该 Pod 被成功创建之后,容器内的DNS配置文件/etc/resolv.conf
的内容将被系统设置为:
nameserver: 1.2.3.4
search ns1.svc.cluster.local my.dns.search.suffix
options ndots:2 edns0
表示该 Pod 完全使用自定义的 DNS 配置,不再使用 Kubernetes 环境的 DNS 服务。
Ingress: HTTP 7层路由机制
从 Kubernetes 1.1 开始新增 Ingress 资源对象,用于将不同的URL的访问请求转发到后端不同的 Service,以实现 HTTP 层的业务路由机制。
Kubernetes 使用了一个 Ingress 策略定义和一个具体的 Ingress Controller,两者结合实现了一个完整的 Ingress 负载均衡器。
使用 Ingress 进行负载分发时,Ingress Controller 基于 Ingress 规则将客户端请求直接转发到 Service 对应的后端 Endpoint(Pod) 上,这样会跳过kube-proxy
的转发功能,kube-proxy
不再起作用。
为使用 Ingress,需要创建 Ingress Controller(带一个默认backend服务)和Ingress策略设置来共同完成。 下面通过一个例子分三步说明 Ingress Controller 和 Ingress 策略的配置方法,以及客户端如何访问 Ingress 提供的服务。
创建 Ingress Controller 和默认的 backend 服务
在 Kubernetes 中,Ingress Controller 将以 Pod 的形式运行,监控 APIServer
的/ingress
接口后端的backend
services,如果Service
发生变化,则Ingress Controller应自动更新其转发规则。
下面的例子使用 Nginx 来实现一个 Ingress Controller,需要实现的基本逻辑如下:
- 监听
API Server
,获取全部 Ingress 的定义。 - 基于 Ingress 的定义,生成 Nginx 所需的配置文件
/etc/nginx/nginx.conf
。 - 执行
nginx -s reload
命令,重新加载nginx.conf
配置文件的内容。
这里使用谷歌提供的nginx-ingress-controller
镜像来创建Ingress Controller
。 该Ingress Controller以 DaemonSet 的形式进行创建,在每个 Node 上都将启动一个 Nginx 服务。
这里为Nginx容器设置了hostPort
,将容器应用监听的80和443端口号映射到物理机上,是的客户端应用可以通过常见形式的 URL 地址来访问该 Ingress Controller。 这使得 Nginx 类似于通过 NodePort 映射到物理机的 Service,成为替代kube-proxy
的 HTTP 层的 LoadBalancer:
以下为
ingress_deploy_aliyun.yaml
配置文件。
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
---
# Source: ingress-nginx/templates/controller-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx
namespace: ingress-nginx
automountServiceAccountToken: true
---
# Source: ingress-nginx/templates/controller-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
data:
allow-snippet-annotations: 'true'
---
# Source: ingress-nginx/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
name: ingress-nginx
rules:
- apiGroups:
- ''
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
- namespaces
verbs:
- list
- watch
- apiGroups:
- ''
resources:
- nodes
verbs:
- get
- apiGroups:
- ''
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
- apiGroups:
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io
resources:
- ingressclasses
verbs:
- get
- list
- watch
---
# Source: ingress-nginx/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
name: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx
namespace: ingress-nginx
rules:
- apiGroups:
- ''
resources:
- namespaces
verbs:
- get
- apiGroups:
- ''
resources:
- configmaps
- pods
- secrets
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- ''
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io
resources:
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- ''
resources:
- configmaps
resourceNames:
- ingress-controller-leader
verbs:
- get
- update
- apiGroups:
- ''
resources:
- configmaps
verbs:
- create
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
---
# Source: ingress-nginx/templates/controller-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx
namespace: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-service-webhook.yaml
apiVersion: v1
kind: Service
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller-admission
namespace: ingress-nginx
spec:
type: ClusterIP
ports:
- name: https-webhook
port: 443
targetPort: webhook
appProtocol: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
annotations:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: LoadBalancer
externalTrafficPolicy: Local
ipFamilyPolicy: SingleStack
ipFamilies:
- IPv4
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
appProtocol: http
- name: https
port: 443
protocol: TCP
targetPort: https
appProtocol: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
revisionHistoryLimit: 10
minReadySeconds: 0
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
spec:
dnsPolicy: ClusterFirst
containers:
- name: controller
image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.1
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
- --election-id=ingress-controller-leader
- --controller-class=k8s.io/ingress-nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
runAsUser: 101
allowPrivilegeEscalation: true
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
- name: webhook
containerPort: 8443
protocol: TCP
volumeMounts:
- name: webhook-cert
mountPath: /usr/local/certificates/
readOnly: true
resources:
requests:
cpu: 100m
memory: 90Mi
nodeSelector:
kubernetes.io/os: linux
serviceAccountName: ingress-nginx
terminationGracePeriodSeconds: 300
volumes:
- name: webhook-cert
secret:
secretName: ingress-nginx-admission
---
# Source: ingress-nginx/templates/controller-ingressclass.yaml
# We don't support namespaced ingressClass yet
# So a ClusterRole and a ClusterRoleBinding is required
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: nginx
namespace: ingress-nginx
spec:
controller: k8s.io/ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
# before changing this value, check the required kubernetes version
# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
name: ingress-nginx-admission
webhooks:
- name: validate.nginx.ingress.kubernetes.io
matchPolicy: Equivalent
rules:
- apiGroups:
- networking.k8s.io
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- ingresses
failurePolicy: Fail
sideEffects: None
admissionReviewVersions:
- v1
clientConfig:
service:
namespace: ingress-nginx
name: ingress-nginx-controller-admission
path: /networking/v1/ingresses
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: ingress-nginx-admission
namespace: ingress-nginx
annotations:
helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ingress-nginx-admission
annotations:
helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
rules:
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
verbs:
- get
- update
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ingress-nginx-admission
annotations:
helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
name: ingress-nginx-admission
namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: ingress-nginx-admission
namespace: ingress-nginx
annotations:
helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- create
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ingress-nginx-admission
namespace: ingress-nginx
annotations:
helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
name: ingress-nginx-admission
namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: ingress-nginx-admission-create
namespace: ingress-nginx
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
spec:
template:
metadata:
name: ingress-nginx-admission-create
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
spec:
containers:
- name: create
image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
imagePullPolicy: IfNotPresent
args:
- create
- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
- --namespace=$(POD_NAMESPACE)
- --secret-name=ingress-nginx-admission
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
securityContext:
allowPrivilegeEscalation: false
restartPolicy: OnFailure
serviceAccountName: ingress-nginx-admission
nodeSelector:
kubernetes.io/os: linux
securityContext:
runAsNonRoot: true
runAsUser: 2000
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: ingress-nginx-admission-patch
namespace: ingress-nginx
annotations:
helm.sh/hook: post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
spec:
template:
metadata:
name: ingress-nginx-admission-patch
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
spec:
containers:
- name: patch
image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
imagePullPolicy: IfNotPresent
args:
- patch
- --webhook-name=ingress-nginx-admission
- --namespace=$(POD_NAMESPACE)
- --patch-mutating=false
- --secret-name=ingress-nginx-admission
- --patch-failure-policy=Fail
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
securityContext:
allowPrivilegeEscalation: false
restartPolicy: OnFailure
serviceAccountName: ingress-nginx-admission
nodeSelector:
kubernetes.io/os: linux
securityContext:
runAsNonRoot: true
runAsUser: 2000
定义 Ingress 策略
本例对mywebsite.com
网站的访问设置 Ingress 策略,定义对其/demo
路径的访问转发到后端webapp
Service 的规则:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mywebsite-test-ingress
spec:
defaultBackend:
service:
name: nginx-svc
port:
number: 80
rules:
- host: test.com
http:
paths:
- path: /demo
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
这个Ingress的定义,说明对目标地址http://mywebsite.com/demo
的访问都将被转发到集群中的Service webapp即 webapp:8080/demo
上。
在Ingress 生效之前,需要先将webapp服务部署完成。 否则需要注意Ingress中path
的定义,需要与后端真实 Service 提供的 path 一致,否则将被转发到一个不存在的path
上,引发错误。