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等,请参考文档:点击访问。