ingress產生的原因
ClusterIP的方式只能在集群內部訪問
NodePort方式的話,測試環境使用還行,當有幾十上百的服務在集群中運行時,NodePort的端口管理是災難。
LoadBalance方式受限於雲平台,且通常在雲平台部署ELB還需要額外的費用。
所幸k8s還提供了一種集群維度暴露服務的方式,也就是ingress。ingress可以簡單理解為service的service,他通過獨立的ingress對象來制定請求轉發的規則,把請求路由到一個或多個service中。這樣就把服務與請求規則解耦了,可以從業務維度統一考慮業務的暴露,而不用為每個service單獨考慮,下面是一個簡單的ingress應用圖,實現了簡單的請求轉發
ingress和ingress-controller
ingress對象:
指的是k8s中的一個api對象,一般用yaml配置。作用是定義請求如何轉發到service的規則,可以理解為配置模板。
ingress-controller:
具體實現反向代理及負載均衡的程序,對ingress定義的規則進行解析,根據配置的規則來實現請求轉發。
簡單來說,ingress-controller才是負責具體轉發的組件,通過各種方式將它暴露在集群入口,外部對集群的請求流量會先到ingress-controller,而ingress對象是用來告訴ingress-controller該如何轉發請求,比如哪些域名哪些path要轉發到哪些服務等等。
ingress-controller並不是k8s自帶的組件,實際上ingress-controller只是一個統稱,用戶可以選擇不同的ingress-controller實現,目前,由k8s維護的ingress-controller只有google雲的GCE與ingress-nginx兩個,其他還有很多第三方維護的ingress-controller,具體可以參考 官方文檔。但是不管哪一種ingress-controller,實現的機制都大同小異,只是在具體配置上有差異。一般來說,ingress-controller的形式都是一個pod,里面跑着daemon程序和反向代理程序。daemon負責不斷監控集群的變化,根據ingress對象生成配置並應用新配置到反向代理,比如nginx-ingress就是動態生成nginx配置, 動態更新upstream,並在需要的時候reload程序應用新配置。為了方便,后面的例子都以k8s官方維護的nginx-ingress為例。
為服務添加ingress的實現

2 我們的ingress是支持https的,所以需要為你的域名配置對應的證書,我們在配置文件里添加

3 自動為ingress-controller里的配置文件添加nginx配置項,然后自動reload它,讓它生效

當有新的ingress服務注冊之后,配置文件會發生變化

4 你的服務對應的nginx是在自己服務的ymal里進行配置的,一般來說,微服務的網關層都應該建立 一個ingress-nginx來對外提供服務!
- 注明ingress的名稱
- 填寫之前建立的密文名稱(ingress https 證書)
- 填寫你的服務所在的namespace,不寫默認為default
- 填寫你要轉發的服務的域名
- 填寫你服務的名稱和pod的端口
# 構建反射代理
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: hello-world-ingress
namespace: saas
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
tls:
- hosts:
- www.abc.com
secretName: saas-tls
rules:
- host: www.abc.com
http:
paths:
- backend:
serviceName: hello-world
servicePort: 9001
## start server www.abc.com
server {
server_name www.abc.com ;
listen 80 ;
listen [::]:80 ;
listen 443 ssl http2 ;
listen [::]:443 ssl http2 ;
set $proxy_upstream_name "-";
# PEM sha: c24ba9e405ed77662c0fd7546a908ef45ca76066
ssl_certificate /etc/ingress-controller/ssl/default-fake-certificate.pem;
ssl_certificate_key /etc/ingress-controller/ssl/default-fake-certificate.pem;
ssl_certificate_by_lua_block {
certificate.call()
}
location ~* "^/" {
set $namespace "saas";
set $ingress_name "hello-world-ingress";
set $service_name "hello-world";
set $service_port "{0 9001 }";
set $location_path "/";
rewrite_by_lua_block {
lua_ingress.rewrite({
force_ssl_redirect = true,
use_port_in_redirects = false,
})
balancer.rewrite()
plugins.run()
}
header_filter_by_lua_block {
plugins.run()
}
body_filter_by_lua_block {
}
log_by_lua_block {
balancer.log()
monitor.call()
plugins.run()
}
if ($scheme = https) {
more_set_headers "Strict-Transport-Security: max-age=15724800; includeSubDomains";
}
port_in_redirect off;
set $balancer_ewma_score -1;
set $proxy_upstream_name "saas-hello-world-9001";
set $proxy_host $proxy_upstream_name;
set $pass_access_scheme $scheme;
set $pass_server_port $server_port;
set $best_http_host $http_host;
set $pass_port $pass_server_port;
set $proxy_alternative_upstream_name "";
client_max_body_size 1m;
proxy_set_header Host $best_http_host;
# Pass the extracted client certificate to the backend
# Allow websocket connections
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Request-ID $req_id;
proxy_set_header X-Real-IP $the_real_ip;
proxy_set_header X-Forwarded-For $the_real_ip;
proxy_set_header X-Forwarded-Host $best_http_host;
proxy_set_header X-Forwarded-Port $pass_port;
proxy_set_header X-Forwarded-Proto $pass_access_scheme;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Scheme $pass_access_scheme;
# Pass the original X-Forwarded-For
proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
# mitigate HTTPoxy Vulnerability
# https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
proxy_set_header Proxy "";
# Custom headers to proxied server
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering off;
proxy_buffer_size 4k;
proxy_buffers 4 4k;
proxy_request_buffering on;
proxy_http_version 1.1;
proxy_cookie_domain off;
proxy_cookie_path off;
# In case of errors try the next upstream server before returning an error
proxy_next_upstream error timeout;
proxy_next_upstream_timeout 0;
proxy_next_upstream_tries 3;
proxy_pass http://upstream_balancer;
proxy_redirect off;
}
}
## end server www.abc.com