知乎专栏 |
正常情况 Service 只是暴露了端口,这个端口是可以对外访问的,但是80端口只有一个,很多 Service 都要使用 80端口,这时就需要使用虚拟主机技术。
多个 Service 共同使用一个 80 端口,通过域名区分业务。这就是 Ingress 存在的意义。
# 查看已有配置 kubectl describe ingress test # 修改配置 kubectl edit ingress test # 来重新载入配置 kubectl replace -f ingress.yaml
自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=bar.foo.com/O=bar.foo.com"
如果是购买的SSL证书,通常有两个问题,*.key 和 *.pem,这里的 pem 证书就是 cert 证书。
[root@agent-5 tmp]# kubectl create secret tls netkiller --key netkiller.cn.key --cert netkiller.cn.pem secret/netkiller created [root@agent-5 tmp]# kubectl get secret netkiller NAME TYPE DATA AGE netkiller kubernetes.io/tls 2 26s
yaml 中添加 tls 配置项
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx name: netkiller-test namespace: project spec: rules: - host: project.netkiller.cn http: paths: - backend: service: name: netkiller-test port: number: 80 path: /netkiller-test-service pathType: ImplementationSpecific tls: - hosts: - project.netkiller.cn secretName: netkiller
+----------+ Ingress +---------+ Pod +----------+ | internet | ---------> | Service | --------> | Pod Node | +----------+ +---------+ +----------+
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: springboot spec: backend: service: name: springboot port: number: 80
Ingress / ---> /api --> api-service:8080 www.netkiller.cn ---------> | ---> /usr --> usr-service:8080 \ ---> /img --> img-service:8080
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: uri-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: www.netkiller.cn http: paths: - path: /api backend: serviceName: api-service servicePort: 8080 - path: /usr backend: serviceName: usr-service servicePort: 8080 - path: /img backend: serviceName: img-service servicePort: 8080
www.netkiller.cn --| Ingress |-> www.netkiller.cn www:80 | --------------> | img.netkiller.cn --| |-> img.netkiller.cn img:80
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: vhost-ingress spec: rules: - host: www.netkiller.cn http: paths: - backend: serviceName: www servicePort: 80 - host: img.netkiller.cn http: paths: - backend: serviceName: img servicePort: 80
http://www.netkiller.cn/1100 => /article/1100
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: rewrite-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /article/$1 spec: rules: - host: www.netkiller.cn http: paths: # 可以有多个(可以正则) - path: /($/.*) backend: serviceName: article servicePort: 80
# 该注解只在配置了HTTPS之后才会生效进行跳转 nginx.ingress.kubernetes.io/ssl-redirect: "true" # 强制跳转到https,不论是否配置了https证书 nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
三种annotation按匹配优先级顺序:
canary-by-header > canary-by-cookie > canary-weight
# Release Version apiVersion: v1 kind: Service metadata: name: hello-service labels: app: hello-service spec: ports: - port: 80 protocol: TCP selector: app: hello-service --- # canary Version apiVersion: v1 kind: Service metadata: name: canary-hello-service labels: app: canary-hello-service spec: ports: - port: 80 protocol: TCP selector: app: canary-hello-service
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: canary annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "30" spec: rules: - host: canary.netkiller.cn http: paths: - backend: serviceName: canary-hello-service
$ for i in $(seq 1 10); do curl http://canary.netkiller.cn; echo '\n'; done
annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "canary"
$ for i in $(seq 1 5); do curl -H 'canary:always' http://canary.netkiller.cn; echo '\n'; done
annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "canary" nginx.ingress.kubernetes.io/canary-by-header-value: "true"
$ for i in $(seq 1 5); do curl -H 'canary:true' http://canary.netkiller.cn; echo '\n'; done
增加下面配置项
nginx.ingress.kubernetes.io/proxy-connect-timeout: '300' nginx.ingress.kubernetes.io/proxy-read-timeout: '300' nginx.ingress.kubernetes.io/proxy-send-timeout: '300'
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/proxy-connect-timeout: '300' nginx.ingress.kubernetes.io/proxy-read-timeout: '300' nginx.ingress.kubernetes.io/proxy-send-timeout: '300' name: netkiller-test namespace: project spec: rules: - host: project.netkiller.cn http: paths: - backend: service: name: netkiller-test port: number: 80 path: /netkiller-test-service pathType: ImplementationSpecific tls: - hosts: - project.netkiller.cn secretName: netkiller