Ingress初体验

前言
1
2
3
4
5
6
7
8
9
service暴露的三种方式ClusterIP、NodePort与LoadBalance,这三种都是在service的维度提供的。
service的作用体现在2个方面:
1. 对集群内部,它不断跟踪pod的变化更新endpoint中对应pod的对象,提供了ip不断变化的pod的服务发现机制。
2. 对集群外部,它类似负载均衡器,可以在集群内外部对pod进行访问。

但单独用service暴露服务的方式在实际生产环境中不太适用:
1. ClusterIP的方式只能在集群内部访问
2. NodePort方式在测试环境使用还行,但是有成百上千服务在集群中运行时,NodePort的端口管理很是麻烦。
3. LoadBalance方式受限于云平台,而且需要额外费用。最大缺点是每个service用一个LB既浪费又麻烦。

ingress

1
2
3
4
ingress则只需要一个NodePort或者一个LB就可满足所有service对外服务的需求。
ingress相当于一个7层负载均衡器,是k8s对反向代理的一个抽象。
Ingress Contronler 通过与 Kubernetes API 交互,能够动态的获取cluster中Ingress rules的变化,生成一段 Nginx 配置,再写到 Nginx-ingress-control的 Pod 里,reload pod 使规则生效。
从而实现注册的service及其对应域名/IP/Port的动态添加和解析。

mark

  • ingress组成
    1
    包括:ingress controller和ingress resources
1
2
ingress controller:核心是一个deployment,实现方式有很多,比如nginx、contour、haproxy、Istio,需要编写的yaml有deploy、service、serviceaccount。其中service类型可以是NodePort或者LoadBalancer.
ingress-controller的形式都是一个pod,里面跑着daemon程序和反向代理程序。daemon负责不断监控集群的编号,根据ingress对象生成配置并应用新配置到反向代理,比如nginx-ingress就是动态生成nginx配置,动态更新upstream,并在需要的时候reload程序应用新配置。
1
2
ingress
ingress resources: 就是一个类型为ingress的k8s api对象,通过yaml文件来配置。ingress通过http或https暴露集群内部service,给service提供外部URL、负载均衡、SSL/TLS能力以及基于host的方式代理。ingress要依靠ingress-controller来具体实现以上功能。

部署ingress-controller

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# yaml部署,mandatory.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
resources:
- ingresses/status
verbs:
- update

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: nginx-ingress-role
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
# Defaults to "<election-id>-<ingress-class>"
# Here: "<ingress-controller-leader>-<nginx>"
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
- "ingress-controller-leader-nginx"
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nginx-ingress-clusterrole-nisa-binding
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nginx-ingress-clusterrole
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
serviceAccountName: nginx-ingress-serviceaccount
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.21.0
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
# www-data -> 33
runAsUser: 33
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
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
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# service-ingress.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
#nodePort: 80
- name: https
port: 443
targetPort: 443
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx

配置ingress

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
# 方式一
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-1
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
# 配置七层域名
- host: liyk.key1024.cn
http:
paths:
# 配置Context Path
- path: /nginx1
backend:
serviceName: myapp-svc
servicePort: 80
- path: /nginx2
backend:
serviceName: nginx
servicePort: 80

# 说明
接着在hosts文件中添加一条解析规则:${ingress_IP} foo.bar.com,这时通过在浏览器中访问:foo.bar.com/coffee或者foo.bar.com/tea即可访问对应的后端service了

使用curl时的操作:curl -H "Host: foo.bar.com" http://${ingress_IP}/coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 方式二
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: cafe-ingress
spec:
rules:
# 配置七层域名
- host: tea.foo.bar.com
http:
paths:
- backend:
serviceName: tea-svc
servicePort: 80
- host: coffee.foo.bar.com
http:
paths:
- backend:
serviceName: coffee-svc
servicePort: 80
  • HTTPS TLS类型
    1
    2
    3
    # 生成证书
    openssl genrsa -out tls.key 2048
    openssl req -new -x509-key tls.key -out tls.crt -subj /C=CN/ST/Beijing/L=Beijing/O=DevOps/CN=tomcat.key1024.cn -days 3650
1
2
# 创建secret
kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# tomcat-ingress-tls.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: tomcat-ingress-tls
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- tomcat.key1024.cn
secretName: tomcat-ingress-secret
rules:
- host: tomcat.key1024.cn
http:
paths:
- path: /
backend:
serviceName: tomcat-svc
servicePort: 80
-------------本文结束感谢您的阅读-------------
原创技术分享,感谢您的支持。