8.1 Ingress為彌補NodePort不足而生
NodePort存在的不足:
-
-
只支持4層負載均衡
8.2 Pod與Ingress的關系
-
通過Service相關聯
-
通過Ingress Controller實現Pod的負載均衡
-
支持TCP/UDP 4層和HTTP 7層
-

8.3 Ingress Controller
為了使Ingress資源正常工作,集群必須運行一個Ingress Controller(負載均衡實現)。
所以要想通過ingress暴露你的應用,大致分為兩步:
-
部署Ingress Controller
-
創建Ingress規則
整體流程如下:

Ingress Controller有很多實現,我們這里采用官方維護的Nginx控制器。
注意事項:
-
鏡像地址修改成國內的:lizhenliang/nginx-ingress-controller:0.20.0
-
# kubectl apply -f ingress-controller.yaml # kubectl get pods -n ingress-nginx NAME READY STATUS RESTARTS AGE nginx-ingress-controller-5r4wg 1/1 Running 0 13s nginx-ingress-controller-x7xdf 1/1 Running 0 13s
此時在任意Node上就可以看到該控制監聽的80和443端口:
# netstat -natp |egrep ":80|:443" tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 104750/nginx: maste tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 104750/nginx: maste
80和443端口就是接收來自外部訪問集群中應用流量,轉發對應的Pod上。
其他主流控制器:
Traefik: HTTP反向代理、負載均衡工具
8.4 Ingress 規則
接下來,就可以創建ingress規則了。
在ingress里有三個必要字段:
-
host:訪問該應用的域名,也就是域名解析
-
serverName:應用的service名稱
-
serverPort:service端口
1、HTTP訪問
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.ctnrs.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
生產環境:example.ctnrs.com 域名是在你購買域名的運營商上進行解析,A記錄值為K8S Node的公網IP(該Node必須運行了Ingress controller)。
測試環境:可以綁定hosts模擬域名解析("C:\Windows\System32\drivers\etc\hosts"),對應IP是K8S Node的內網IP。例如:
192.168.31.62 example.ctnrs.com
2、HTTPS訪問
四。創建https方式訪問網站
1.創建cfssl.sh,並執行此腳本,默認加載到bin目錄變成可執行文件
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 chmod +x cfssl* mv cfssl_linux-amd64 /usr/bin/cfssl mv cfssljson_linux-amd64 /usr/bin/cfssljson mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
2.創建certs.sh
cat > ca-config.json <<EOF { "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } } cat > ca-csr.json <<EOF { "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "Beijing", "ST": "Beijing" } ] } EOF cfssl gencert -initca ca-csr.json | cfssljson -bare ca - cat > blog.ctnrs.com-csr.json <<EOF { "CN": "blog.ctnrs.com", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing" } ] } EOF cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes blog.ctnrs.com-csr.json | cfssljson -bare blog.ctnrs.com kubectl create secret tls blog-ctnrs-com --cert=blog.ctnrs.com.pem --key=blog.ctnrs.com-key.pem
3.創建ingress.yaml 證書里的域名和ingress里的域名要一樣
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- blog.ctnrs.com
secretName: example-ctnrs-com
rules:
- host: blog.ctnrs.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
4.直接網頁訪問即可
3、根據URL路由到多個服務
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: url-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foobar.ctnrs.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 80
- host: foobar.ctnrs.com
http:
paths:
- path: /bar
backend:
serviceName: service2
servicePort: 80
工作流程:
foobar.ctnrs.com -> 178.91.123.132 -> / foo service1:80
/ bar service2:80
4、基於名稱的虛擬主機
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.ctnrs.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: bar.ctnrs.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
工作流程:
foo.bar.com --| |-> service1:80
| 178.91.123.132 |
bar.foo.com --| |-> service2:80
HTTP:配置Nginx常用參數
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
kubernetes.io/ingress.class: "nginx“
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
rules:
- host: example.ctnrs.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
HTTPS:禁止訪問HTTP強制跳轉到HTTPS(默認開啟)
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
annotations:
kubernetes.io/ingress.class: "nginx“
nginx.ingress.kubernetes.io/ssl-redirect: 'false'
spec:
tls:
- hosts:
- sslexample.ctnrs.com
secretName: secret-tls
rules:
- host: sslexample.ctnrs.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
如果域名只解析到一台Ingress controller,是存在單點的,掛了就不能提供服務了。這就需要具備高可用,有兩種常見方案:

左邊:雙機熱備,選擇兩台Node專門跑Ingress controller,然后通過keepalived對其做主備。用戶通過VIP訪問。
右邊:高可用集群(推薦),前面加一個負載均衡器,轉發請求到后端多台Ingress controller。
