ingress将来自集群外部的HTTP和HTTPS路由暴露给集群内的服务(k8s Service),流量路由规则由ingress资源来定义。简单的来说,ingress能够将不同域名+ 路径(如 aaa.com/api)映射到集群内的k8s service上。
将下面用一张图来理解ingress的作用;你可以将ingress controller理解为一个nginx反向代理,ingress理解为你为nginx配置的路由规则,而service就是你的upstream server提供的服务。
如果这是你需要的,请继续往下看。
?
用户需已经创建好了自己的业务应用,并通过集群服务(k8s service)暴露服务。集群服务可参考文档:点击查看。
?
如无特殊需求,用户只需要创建一个Ingress Controller类型的应用即可。
?
?
进入发布,为Ingress Controller创建配型类型为Yaml的环境。
Deployment和3个configMap的样例如下,请按以下要求调整Yaml内容:
① (必选)将Deployment配置中的{{IngressClass}}替换为你自己设定的名称,设定后不可更改,如果有多个ingress-controller的需求,请确保名字不要重复。命名规则必须以小写字母开头,只能包含小写字母、数字、"."和"-",即符合正则规则 [a-z]([-a-z0-9]*[a-z0-9]);
② (可选)Ingress Controller默认的资源分配策略为CPU:1核,内存:2G,请根据自身的需求调整资源分配;
③ (可选)根据自己的要求调整ConfigMap中的参数。
注意:containerPort固定为80 和 443,不要更改。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ingress-nginx
annotations:
component.version: "1.8.2"
component.revision: "1"
spec:
selector:
matchLabels:
app: ingress-nginx
template:
metadata:
labels:
app: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- ingress-nginx
topologyKey: "kubernetes.io/hostname"
serviceAccountName: nginx-ingress-controller
initContainers:
- name: init-sysctl
image: registry-cn-zhangjiakou-vpc.ack.aliyuncs.com/acs/busybox:v1.29.2
command:
- /bin/sh
- -c
- |
if [ "$POD_IP" != "$HOST_IP" ]; then
mount -o remount rw /proc/sys
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
sysctl -w kernel.core_uses_pid=0
fi
securityContext:
capabilities:
drop:
- ALL
add:
- SYS_ADMIN
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
containers:
- name: nginx-ingress-controller
image: registry-cn-zhangjiakou-vpc.ack.aliyuncs.com/acs/aliyun-ingress-controller:v1.8.2-aliyun.1
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
resources:
limits:
cpu: 1
memory: 2Gi
requests:
cpu: 1
memory: 2Gi
args:
- /nginx-ingress-controller
- --election-id=ingress-controller-leader-nginx
- --configmap=$(POD_NAMESPACE)/nginx-configuration-{{ConfigId}}
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services-{{ConfigId}}
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services-{{ConfigId}}
- --annotations-prefix=nginx.ingress.kubernetes.io
- --ingress-class={{IngressClass}}
- --watch-ingress-without-class
- --controller-class=k8s.io/ingress-nginx
- --v=2
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
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 5
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
runAsUser: 101
allowPrivilegeEscalation: true
volumeMounts:
- name: localtime
mountPath: /etc/localtime
readOnly: true
nodeSelector:
beta.kubernetes.io/os: linux
volumes:
- name: localtime
hostPath:
path: /etc/localtime
type: File
configMap_1
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configuration-{{ConfigId}}
labels:
app: ingress-nginx
data:
log-format-upstream: '$remote_addr - [$remote_addr] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $req_id $host [$proxy_alternative_upstream_name]'
proxy-body-size: 20m
proxy-connect-timeout: "10"
max-worker-connections: "65536"
enable-underscores-in-headers: "true"
reuse-port: "true"
worker-cpu-affinity: "auto"
server-tokens: "false"
ssl-redirect: "false"
allow-backend-server-header: "true"
ignore-invalid-headers: "true"
generate-request-id: "true"
upstream-keepalive-timeout: "900"
#forwarded-for-header: "X-Real-IP"
#compute-full-forwarded-for: "true"
#hsts: "false"
#enable-vts-status: "true"
#use-proxy-protocol: "true"
configMap_2
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services-{{ConfigId}}
configMap_3
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services-{{ConfigId}}
① nginx-configuration-xxx
聚石塔的Ingress Controller底层实现是nginx,nginx-configuration-xxx是设定nginx参数的地方,支持的参数可参考:
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/
② tcp-services 和?udp-services功能参见:
https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/
编辑完成保存配置即可。
发布成功后,此时Ingress Controller已经成功的部署起来了。
为Ingress Controller(本质上是一个nginx)创建SLB接入,接入端口为80、443。
监听端口和RS端口都填80;
注意:SLB监听端口可以改,但RS端口固定为80。
?
负载均衡协议要选:TCP。
?
监听端口和RS端口都填443。
注意:SLB监听端口可以改,但RS端口固定为443。
?
负载均衡协议要选:TCP。
此时,我们已经部署起来了Ingress Conroller,同时为它配置了流量接入,下一步需要创建Ingress资源,指定路由规则。
?
注意:Ingress资源(可以理解为HTTP路由规则)是创建在你的业务应用中的,而不是你刚才创建的Ingress Controller应用中。
?
路由规则是针对业务应用的,首先找到你需要路由的业务应用。如本例中的"lingfeng_docker_h5",暴露的端口为8080。
?
?
填写项 |
说明 |
Ingress Class |
选择流程第一步创建的Ingress Controller。 |
域名 |
你需要路由的domain。 |
路径 |
转发的path,无特殊需求填写/即可。 如果需要根据不同的路径转发不同后端service,请参考本文档的【高级实践-URI路径扇出】 |
开启TLS |
如果需要HTTPS,则选择开启。 |
TLS Key |
域名对应证书的私钥,证书私钥内容,为PEM编码格式。如: -----BEGIN RSA PRIVATE KEY----- MII.... -----END RSA PRIVATE KEY----- |
TLS Cert |
域名对应证书的证书内容,为PEM编码格式。如: -----BEGIN CERTIFICATE----- MIIF...... -----END CERTIFICATE----- 如果你需要HTTPS安全认证,请一定要在证书过期前更新你的证书配置。 |
会话保持 |
如需开启,请选择会话保持方式,目前仅支持Cookie方式。 |
Cookie名称 |
会话保持方式为Cookie时指定,如果不指定,则由nginx来默认。 默认策略: a. 默认的cookie名称为INGRESSCOOKIE; b. 默认未设置cookie过期时间,那么表示这是一个浏览器会话期 cookie 。一个浏览器会话结束于浏览器被关闭时,这意味着浏览器会话期 cookie 在浏览器被关闭时会被移除。然而,很多Web浏览器支持会话恢复功能,这个功能可以使浏览器保留所有的tab标签,然后在重新打开浏览器的时候将其还原。与此同时,cookie 也会恢复,就跟从来没有关闭浏览器一样。 c. 如果有自定义cookie需求,请参考本文档的【高级实践-自定义Cookie策略】。 |
服务 |
路由规则对应的后端服务。(要确保服务和ingress controller在同一个集群。比如都在正式环境集群 或 测试环境集群,否则这里看不到服务) a. 服务名称:选择业务暴露的K8S Service Name。 b. 服务端口:填写业务暴露的服务端口,如本例的8080。 c. 权重:该服务占比,为整数。 请暂时不要配置多个服务,多个服务是为后续灰度发布使用,我们正在加紧支持。 |
到这我们已经创建好了路由规则,可以根据域名+路径路由到我们业务服务了,可以看下效果。
说明:由于本例中的证书是自签名的证书,因此浏览器提示不安全,实际使用中请使用CA签发的合规证书。
?
如果你需要自定义Cookie的一些策略,比如Cookie的超时时间,保存路径等,则可以通过高级规则来配置。
如下图设置Cookie的超时时间。
参数说明:
1)nginx.ingress.kubernetes.io/session-cookie-max-age? : Cookie超时时间,单位为秒;
2)其他更详细的说明请参考nginx ingress controller的说明:https://kubernetes.github.io/ingress-nginx/examples/affinity/cookie/。
如果你需要类似下面这样效果的转发,请继续往下看。
www.example.com -> /foo service1:4200
/bar service2:8080
实现URI扇出,请按以下步骤操作:
1)路径填写规则
路径是支持正则表达式的,如上面的/foo转发,可以配置为:/foo(/|$)(.*) ;
同理/bar可配置为/bar(/|$)(.*) ;
?
2)配置url重写规则
路径规则需配合url重写才能生效。url重写规则可在高级规则中指定,指定方式如下:
路径:即上面我们说的正则写法。
高级规则:
url重写:名称固定为 nginx.ingress.kubernetes.io/rewrite-target/$2,值 /$2?表示从路径中的"/"隔开的第二段开始作为访问的URI片段。
以本例子举例来看:
① www.example.com/foo 相当于访问 你的服务:服务端口/;
② www.example.com/foo/ 相当于访问 你的服务:服务端口/;
③ www.example.com/foo/new 相当于访问 你的服务:服务端口/new? ;
④ www.example.com/foo/new/v2 相当于访问 你的服务:服务端口/new/v2?。
更详细的说明请参考nginx ingress controller的说明:点击查看。
?
其他更多详细参数,如client_max_body_size等,请参考文档:点击访问。