一逆皮、HAproxy Ingress 控制器
1.1 HAproxy Ingress 簡介
HAProxy Ingress watches in the k8s cluster and how it builds HAProxy configuration
和 Nginx 相類似,HAproxy 通過監(jiān)視 kubernetes api 獲取到 service 后端 pod 的狀態(tài)秽梅,動(dòng)態(tài)更新 haproxy 配置文件抹蚀,以實(shí)現(xiàn)七層的負(fù)載均衡环壤。
HAproxy Ingress 控制器具備的特性如下:
- Fast钞诡,Carefully built on top of the battle-tested HAProxy load balancer. 基于 haproxy 性能有保障
- Reliable,Trusted by sysadmins on clusters as big as 1,000 namespaces, 2,000 domains and 3,000 ingress objects. 可靠接箫,支持1000最多1000個(gè)命名空間和 2000多個(gè)域名
- Highly customizable朵诫,100+ configuration options and growing. 可定制化強(qiáng),支持100多個(gè)配置選項(xiàng)
- 通過使用一個(gè) IP 地址和端口路由入口流量來簡化基礎(chǔ)架構(gòu)废累。根據(jù)主機(jī)請求頭和請求路徑將請求路由到正確的 Pod脱盲。
- 利用世界上最快钱反,使用最廣泛的軟件負(fù)載平衡器 HAProxy。在性能诈铛,可靠性和安全性方面,HAProxy 設(shè)定了新標(biāo)準(zhǔn)耳峦。
- 使用內(nèi)置的 SSL 終止焕毫,速率限制和 IP 白名單來保護(hù)您的集群。
- 使用 HAProxy 的任何負(fù)載平衡算法(包括循環(huán)循签,最少連接疙咸,URL 哈希和隨機(jī))來平衡 Pod 之間的流量。
- 開箱即用的第7層卓越的可觀察性可盡早避免出現(xiàn)問題贼穆。HAProxy 附帶有一個(gè)儀表板兰粉,該儀表板可顯示吊艙的運(yùn)行狀況,當(dāng)前請求率愕秫,響應(yīng)時(shí)間等。
HAProxy 的流量過載保護(hù)可帶來更高的吞吐量戴甩。服務(wù)器不會(huì)收到超出其處理能力的更多請求等恐。
HAproxy ingress 控制器版本
- 社區(qū)版备蚓,基于 haproxy 社區(qū)高度定制符合 ingress 的控制器郊尝,功能相對有限
- 企業(yè)版战惊,haproxy 企業(yè)版本,支持很多高級特性和功能吞获,大部分高級功能在企業(yè)版本中實(shí)現(xiàn)
1.2 HAproxy 控制器安裝
haproxy ingress 安裝相對簡單,官方提供了安裝的 yaml 文件刁绒,先將文件下載查看一下 kubernetes 資源配置烤黍,包含的資源類型有:
- ServiceAccount 和 RBAC 認(rèn)證授權(quán)關(guān)聯(lián)
- RBAC 認(rèn)證 Role、ClusterRole嫂丙、 ClusterRoleBinding
- Service 后端的一個(gè) service
- DaemonSet HAproxy 最核心的一個(gè)控制器规哲,關(guān)聯(lián)認(rèn)證 ServiceAccount 和配置 ConfigMap,定義了一個(gè) nodeSelector隅肥,label 為 role: ingress-controller,將運(yùn)行在特定的節(jié)點(diǎn)上
- ConfigMap 實(shí)現(xiàn) haproxy ingress 自定義配置
安裝文件路徑https://haproxy-ingress.github.io/resources/haproxy-ingress.yaml
1议双、創(chuàng)建命名空間,haproxy ingress 部署在 ingress-controller 這個(gè)命名空間藕坯,先創(chuàng)建 ns
2宗雇、安裝 haproxy ingress 控制器
3赔蒲、檢查 haproxy ingress 安裝情況良漱,檢查 haproxy ingress 核心的DaemonSets,發(fā)現(xiàn) DS 并未部署 Pod矾兜,原因是配置文件中定義了nodeSelector 節(jié)點(diǎn)標(biāo)簽選擇器患久,因此需要給 node 設(shè)置合理的標(biāo)簽
4、 給 node 設(shè)置標(biāo)簽返帕,讓 DaemonSets 管理的 Pod 能調(diào)度到 node 節(jié)點(diǎn)上篙挽,生產(chǎn)環(huán)境中根據(jù)情況定義,將實(shí)現(xiàn) haproxy ingress 功能的節(jié)點(diǎn)定義到特定的節(jié)點(diǎn)观腊,對個(gè) node 節(jié)點(diǎn)的訪問算行,需要借助于負(fù)載均衡實(shí)現(xiàn)統(tǒng)一接入,本文主要以探究 haproxy ingress 功能儡陨,因此未部署負(fù)載均衡調(diào)度器,可根據(jù)實(shí)際的情況部署骗村。以 node-1 和 node-2 為例:
5、再次查看 ingress 部署情況笼痛,已完成部署琅拌,并調(diào)度至 node-1 和 node-2 節(jié)點(diǎn)上
6、 查看 haproxy ingress 的日志刻坊,通過查詢?nèi)罩究芍辰鄠€(gè) haproxy ingress 是通過選舉實(shí)現(xiàn)高可用 HA 機(jī)制。
其他資源包括 ServiceAccount灾而,ClusterRole扳剿,ConfigMaps 請單獨(dú)確認(rèn),至此 HAproxy ingress controller 部署完畢。另外兩種部署方式:
Deployment 部署方式(http://dwz.date/cmP9)
Helm 部署方式(http://dwz.date/cmPB)
二癣猾、haproxy ingress 使用
2.1 haproxy ingress 基礎(chǔ)
Ingress 控制器部署完畢后需要定義 Ingress 規(guī)則,以方便 Ingress 控制器能夠識(shí)別到 service 后端 Pod 的資源夸盟,這個(gè)章節(jié)我們將來介紹在 HAproxy Ingress Controller 環(huán)境下 Ingress 的使用像捶。
1、環(huán)境準(zhǔn)備释簿,創(chuàng)建一個(gè) deployments 并暴露其端口
#創(chuàng)建應(yīng)用并暴露端口
[root@node-1 haproxy-ingress]# cat haproxy-ingress-nginx-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: haproxy-ingress-demo
name: haproxy-ingress-demo
spec:
replicas: 3
selector:
matchLabels:
app: haproxy-ingress-demo
template:
metadata:
labels:
app: haproxy-ingress-demo
spec:
containers:
- image: nginx:1.17.0
name: nginx
---
apiVersion: v1
kind: Service
metadata:
name: haproxy-ingress-demo
namespace: default
spec:
clusterIP: 10.109.197.67
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: haproxy-ingress-demo
type: ClusterIP
#查看應(yīng)用
[root@node-1 haproxy-ingress]# kubectl get deployments haproxy-ingress-demo
NAME READY UP-TO-DATE AVAILABLE AGE
haproxy-ingress-demo 1/1 1 1 10s
#查看service情況
[root@node-1 haproxy-ingress]# kubectl get services haproxy-ingress-demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
haproxy-ingress-demo ClusterIP 10.109.197.67 <none> 80/TCP 17s
2庶溶、創(chuàng)建 ingress 規(guī)則,如果有多個(gè) ingress 控制器,可以通過 ingress.class 指定類型為 haproxy
[root@node-1 haproxy-ingress]# cat ingress-demo.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: haproxy-ingress-demo
labels:
ingresscontroller: haproxy
annotations:
kubernetes.io/ingress.class: haproxy
spec:
rules:
- host: www.happylau.cn
http:
paths:
- path: /
backend:
serviceName: haproxy-ingress-demo
servicePort: 80
3行疏、應(yīng)用 ingress 規(guī)則套像,并查看 ingress 詳情,查看 Events 日志發(fā)現(xiàn)控制器已正常更新
[root@node-1 haproxy-ingress]# kubectl apply -f ingress-demo.yaml
ingress.extensions/haproxy-ingress-demo created
#查看詳情
[root@node-1 haproxy-ingress]# kubectl describe ingresses haproxy-ingress-demo
Name: haproxy-ingress-demo
Namespace: default
Address:
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
www.happylau.cn
/ haproxy-ingress-demo:80 (10.244.2.166:80)
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"haproxy"},"labels":{"ingresscontroller":"haproxy"},"name":"haproxy-ingress-demo","namespace":"default"},"spec":{"rules":[{"host":"www.happylau.cn","http":{"paths":[{"backend":{"serviceName":"haproxy-ingress-demo","servicePort":80},"path":"/"}]}}]}}
kubernetes.io/ingress.class: haproxy
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 27s ingress-controller Ingress default/haproxy-ingress-demo
Normal CREATE 27s ingress-controller Ingress default/haproxy-ingress-demo
Normal UPDATE 20s ingress-controller Ingress default/haproxy-ingress-demo
Normal UPDATE 20s ingress-controller Ingress default/haproxy-ingress-demo
4贞让、測試驗(yàn)證 ingress 規(guī)則震桶,可以將域名寫入到 hosts 文件中征绎,我們直接使用 gcurl 測試,地址指向 node-1 或 node-2 均可
[root@node-1 haproxy-ingress]# curl http://www.happylau.cn --resolve www.happylau.cn:80:10.254.100.101
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a >nginx.org</a>.<br/>
Commercial support is available at
<a >nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
5柴墩、測試正常凫岖,接下來到 haproxy ingress controller 中剛查看對應(yīng)生成規(guī)則配置文件
[root@node-1 ~]# kubectl exec -it haproxy-ingress-bdns8 -n ingress-controller /bin/sh
#查看配置文件
/etc/haproxy # cat /etc/haproxy/haproxy.cfg
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# # HAProxy Ingress Controller
# # --------------------------
# # This file is automatically updated, do not edit
# #
# 全局配置文件內(nèi)容
global
daemon
nbthread 2
cpu-map auto:1/1-2 0-1
stats socket /var/run/haproxy-stats.sock level admin expose-fd listeners
maxconn 2000
hard-stop-after 10m
lua-load /usr/local/etc/haproxy/lua/send-response.lua
lua-load /usr/local/etc/haproxy/lua/auth-request.lua
tune.ssl.default-dh-param 2048
ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
ssl-default-bind-options no-sslv3 no-tls-tickets
#默認(rèn)配置內(nèi)容
defaults
log global
maxconn 2000
option redispatch
option dontlognull
option http-server-close
option http-keep-alive
timeout client 50s
timeout client-fin 50s
timeout connect 5s
timeout http-keep-alive 1m
timeout http-request 5s
timeout queue 5s
timeout server 50s
timeout server-fin 50s
timeout tunnel 1h
#后端服務(wù)器哥放,即通過service服務(wù)發(fā)現(xiàn)機(jī)制,和后端的Pod關(guān)聯(lián)
backend default_haproxy-ingress-demo_80
mode http
balance roundrobin
acl https-request ssl_fc
http-request set-header X-Original-Forwarded-For %[hdr(x-forwarded-for)] if { hdr(x-forwarded-for) -m found }
http-request del-header x-forwarded-for
option forwardfor
http-response set-header Strict-Transport-Security "max-age=15768000"
server srv001 10.244.2.166:80 weight 1 check inter 2s #后端Pod的地址
server srv002 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv003 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv004 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv005 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv006 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv007 127.0.0.1:1023 disabled weight 1 check inter 2s
backend _error404
mode http
http-request use-service lua.send-404
#前端監(jiān)聽的80端口轉(zhuǎn)發(fā)規(guī)則踩身,并配置有https跳轉(zhuǎn)挟阻,對應(yīng)的主機(jī)配置在/etc/haproxy/maps/_global_http_front.map文件中定義
frontend _front_http
mode http
bind *:80
http-request set-var(req.base) base,lower,regsub(:[0-9]+/,/)
http-request redirect scheme https if { var(req.base),map_beg(/etc/haproxy/maps/_global_https_redir.map,_nomatch) yes }
http-request set-header X-Forwarded-Proto http
http-request del-header X-SSL-Client-CN
http-request del-header X-SSL-Client-DN
http-request del-header X-SSL-Client-SHA1
http-request del-header X-SSL-Client-Cert
http-request set-var(req.backend) var(req.base),map_beg(/etc/haproxy/maps/_global_http_front.map,_nomatch)
use_backend %[var(req.backend)] unless { var(req.backend) _nomatch }
default_backend _default_backend
#前端監(jiān)聽的443轉(zhuǎn)發(fā)規(guī)則峭弟,對應(yīng)域名在/etc/haproxy/maps/ _front001_host.map文件中
frontend _front001
mode http
bind *:443 ssl alpn h2,http/1.1 crt /ingress-controller/ssl/default-fake-certificate.pem
http-request set-var(req.hostbackend) base,lower,regsub(:[0-9]+/,/),map_beg(/etc/haproxy/maps/_front001_host.map,_nomatch)
http-request set-header X-Forwarded-Proto https
http-request del-header X-SSL-Client-CN
http-request del-header X-SSL-Client-DN
http-request del-header X-SSL-Client-SHA1
http-request del-header X-SSL-Client-Cert
use_backend %[var(req.hostbackend)] unless { var(req.hostbackend) _nomatch }
default_backend _default_backend
#狀態(tài)監(jiān)聽器
listen stats
mode http
bind *:1936
stats enable
stats uri /
no log
option forceclose
stats show-legends
#監(jiān)控健康檢查
frontend healthz
mode http
bind *:10253
monitor-uri /healthz
查看主機(jī)名隱射文件瞒瘸,包含有前端主機(jī)名和轉(zhuǎn)發(fā)到后端 backend 的名稱
/etc/haproxy/maps # cat /etc/haproxy/maps/_global_http_front.map
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# # HAProxy Ingress Controller
# # --------------------------
# # This file is automatically updated, do not edit
# #
#
www.happylau.cn/ default_haproxy-ingress-demo_80
通過上面的基礎(chǔ)配置可以實(shí)現(xiàn)基于 haproxy 的七層負(fù)載均衡實(shí)現(xiàn),haproxy ingress controller 通過 kubernetes api 動(dòng)態(tài)識(shí)別到 service 后端規(guī)則配置并更新至haproxy.cfg 配置文件中情臭,從而實(shí)現(xiàn)負(fù)載均衡功能實(shí)現(xiàn)玉组。
2.2 動(dòng)態(tài)更新和負(fù)載均衡
后端 Pod 是實(shí)時(shí)動(dòng)態(tài)變化的惯雳,haproxy ingress 通過 service 的服務(wù)發(fā)現(xiàn)機(jī)制鸿摇,動(dòng)態(tài)識(shí)別到后端 Pod 的變化情況,并動(dòng)態(tài)更新 haproxy.cfg 配置文件拙吉,并重載配置(實(shí)際不需要重啟 haproxy 服務(wù)),本章節(jié)將演示 haproxy ingress 動(dòng)態(tài)更新和負(fù)載均衡功能往史。
1佛舱、動(dòng)態(tài)更新,我們以擴(kuò)容 pod 的副本為例订歪,將副本數(shù)從 replicas=1 擴(kuò)容至 3 個(gè)
[root@node-1 ~]# kubectl scale --replicas=3 deployment haproxy-ingress-demo
deployment.extensions/haproxy-ingress-demo scaled
[root@node-1 ~]# kubectl get deployments haproxy-ingress-demo
NAME READY UP-TO-DATE AVAILABLE AGE
haproxy-ingress-demo 3/3 3 3 43m
#查看擴(kuò)容后Pod的IP地址
[root@node-1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
haproxy-ingress-demo-5d487d4fc-5pgjt 1/1 Running 0 43m 10.244.2.166 node-3 <none> <none>
haproxy-ingress-demo-5d487d4fc-pst2q 1/1 Running 0 18s 10.244.0.52 node-1 <none> <none>
haproxy-ingress-demo-5d487d4fc-sr8tm 1/1 Running 0 18s 10.244.1.149 node-2 <none> <none>
2肆捕、查看 haproxy 配置文件內(nèi)容,可以看到 backend 后端主機(jī)列表已動(dòng)態(tài)發(fā)現(xiàn)新增的pod 地址
backend default_haproxy-ingress-demo_80
mode http
balance roundrobin
acl https-request ssl_fc
http-request set-header X-Original-Forwarded-For %[hdr(x-forwarded-for)] if { hdr(x-forwarded-for) -m found }
http-request del-header x-forwarded-for
option forwardfor
http-response set-header Strict-Transport-Security "max-age=15768000"
server srv001 10.244.2.166:80 weight 1 check inter 2s #新增的pod地址
server srv002 10.244.0.52:80 weight 1 check inter 2s
server srv003 10.244.1.149:80 weight 1 check inter 2s
server srv004 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv005 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv006 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv007 127.0.0.1:1023 disabled weight 1 check inter 2s
3慎陵、查看 haproxy ingress 日志,日志中提示 HAProxy updated without needing to reload席纽,即配置動(dòng)態(tài)識(shí)別,不需要重啟 haproxy 服務(wù)就能夠識(shí)別,自從1.8后haproxy 能支持動(dòng)態(tài)配置更新的能力诈豌,以適應(yīng)微服務(wù)的場景,詳情查看文章說明(http://dwz.date/cmPV)
[root@node-1 ~]# kubectl logs haproxy-ingress-bdns8 -n ingress-controller -f
I1227 12:21:11.523066 6 controller.go:274] Starting HAProxy update id=20
I1227 12:21:11.561001 6 instance.go:162] HAProxy updated without needing to reload. Commands sent: 3
I1227 12:21:11.561057 6 controller.go:325] Finish HAProxy update id=20: ingress=0.149764ms writeTmpl=37.738947ms total=37.888711ms
4彤蔽、接下來測試負(fù)載均衡的功能庙洼,為了驗(yàn)證測試效果镊辕,往 pod 中寫入不同的內(nèi)容征懈,以測試負(fù)載均衡的效果
[root@node-1 ~]# kubectl exec -it haproxy-ingress-demo-5d487d4fc-5pgjt /bin/bash
root@haproxy-ingress-demo-5d487d4fc-5pgjt:/# echo "web-1" > /usr/share/nginx/html/index.html
[root@node-1 ~]# kubectl exec -it haproxy-ingress-demo-5d487d4fc-pst2q /bin/bash
root@haproxy-ingress-demo-5d487d4fc-pst2q:/# echo "web-2" > /usr/share/nginx/html/index.html
[root@node-1 ~]# kubectl exec -it haproxy-ingress-demo-5d487d4fc-sr8tm /bin/bash
root@haproxy-ingress-demo-5d487d4fc-sr8tm:/# echo "web-3" > /usr/share/nginx/html/index.html
5揩悄、測試驗(yàn)證負(fù)載均衡效果,haproxy 采用輪詢的調(diào)度算法,因此可以明顯看到輪詢效果
[root@node-1 ~]# curl http://www.happylau.cn --resolve www.happylau.cn:80:10.254.100.102
web-1
[root@node-1 ~]# curl http://www.happylau.cn --resolve www.happylau.cn:80:10.254.100.102
web-2
[root@node-1 ~]# curl http://www.happylau.cn --resolve www.happylau.cn:80:10.254.100.102
web-3
這個(gè)章節(jié)驗(yàn)證了 haproxy ingress 控制器動(dòng)態(tài)配置更新的能力亏娜,相比于 nginx ingress 控制器而言蹬挺,haproxy ingress 控制器不需要重載服務(wù)進(jìn)程就能夠動(dòng)態(tài)識(shí)別到配置,在微服務(wù)場景下將具有非常大的優(yōu)勢溯泣;并通過一個(gè)實(shí)例驗(yàn)證了 ingress 負(fù)載均衡調(diào)度能力。
2.3 基于名稱虛擬主機(jī)
這個(gè)小節(jié)將演示 haproxy ingress 基于虛擬云主機(jī)功能的實(shí)現(xiàn)发乔,定義兩個(gè)虛擬主機(jī) news.happylau.cn 和 sports.happylau.cn雪猪,將請求各自轉(zhuǎn)發(fā)至 haproxy-1 和haproxy-2
1、 準(zhǔn)備環(huán)境測試環(huán)境译仗,創(chuàng)建兩個(gè)應(yīng)用 haproxy-1 和 haproxy 并暴露服務(wù)端口
[root@node-1 ~]# cat haproxy-ingress-nginx-test-1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: haproxy-1
name: haproxy-1
spec:
replicas: 3
selector:
matchLabels:
app: haproxy-1
template:
metadata:
labels:
app: haproxy-1
spec:
containers:
- image: nginx:1.7.9
name: nginx
---
apiVersion: v1
kind: Service
metadata:
name: haproxy-1
namespace: default
spec:
clusterIP: 10.109.197.67
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: haproxy-1
type: ClusterIP
[root@node-1 ~]# cat haproxy-ingress-nginx-test-2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: haproxy-2
name: haproxy-2
spec:
replicas: 3
selector:
matchLabels:
app: haproxy-2
template:
metadata:
labels:
app: haproxy-2
spec:
containers:
- image: nginx:1.7.9
name: nginx
---
apiVersion: v1
kind: Service
metadata:
name: haproxy-2
namespace: default
spec:
clusterIP: 10.109.197.68
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: haproxy-2
type: ClusterIP
查看應(yīng)用
[root@node-1 ~]# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
haproxy-1 1/1 1 1 39s
haproxy-2 1/1 1 1 36s
查看service
[root@node-1 ~]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
haproxy-1 ClusterIP 10.109.197.67 <none> 80/TCP 55s
haproxy-2 ClusterIP 10.109.197.68 <none> 80/TCP 52s
2纵菌、定義 ingress 規(guī)則休涤,定義不同的主機(jī)并將請求轉(zhuǎn)發(fā)至不同的 service 中
[root@node-1 ~]# cat ingress-virtualhost.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: haproxy-ingress-virtualhost
annotations:
kubernetes.io/ingress.class: haproxy
spec:
rules:
- host: news.happylau.cn
http:
paths:
- path: /
backend:
serviceName: haproxy-1
servicePort: 80
- host: sports.happylau.cn
http:
paths:
- path: /
backend:
serviceName: haproxy-2
servicePort: 80
#應(yīng)用ingress規(guī)則并查看列表
[root@node-1 haproxy-ingress]# kubectl apply -f ingress-virtualhost.yaml
ingress.extensions/haproxy-ingress-virtualhost created
[root@node-1 haproxy-ingress]# kubectl get ingresses haproxy-ingress-virtualhost
NAME HOSTS ADDRESS PORTS AGE
haproxy-ingress-virtualhost news.happylau.cn,sports.happylau.cn 80 8s
查看ingress規(guī)則詳情
[root@node-1 haproxy-ingress]# kubectl describe ingresses haproxy-ingress-virtualhost
Name: haproxy-ingress-virtualhost
Namespace: default
Address:
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
news.happylau.cn
/ haproxy-1:80 (10.244.2.168:80)
sports.happylau.cn
/ haproxy-2:80 (10.244.2.169:80)
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"haproxy"},"name":"haproxy-ingress-virtualhost","namespace":"default"},"spec":{"rules":[{"host":"news.happylau.cn","http":{"paths":[{"backend":{"serviceName":"haproxy-1","servicePort":80},"path":"/"}]}},{"host":"sports.happylau.cn","http":{"paths":[{"backend":{"serviceName":"haproxy-2","servicePort":80},"path":"/"}]}}]}}
kubernetes.io/ingress.class: haproxy
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 37s ingress-controller Ingress default/haproxy-ingress-virtualhost
Normal CREATE 37s ingress-controller Ingress default/haproxy-ingress-virtualhost
Normal UPDATE 20s ingress-controller Ingress default/haproxy-ingress-virtualhost
Normal UPDATE 20s ingress-controller Ingress default/haproxy-ingress-virtualhost
3功氨、測試驗(yàn)證虛擬機(jī)主機(jī)配置,通過 curl 直接解析的方式忱详,或者通過寫 hosts 文件
4跺涤、查看配置配置文件內(nèi)容监透,配置中更新了 haproxy.cfg 的 front 段和 backend 段的內(nèi)容
/etc/haproxy/haproxy.cfg 配置文件內(nèi)容
backend default_haproxy-1_80 #haproxy-1后端
mode http
balance roundrobin
acl https-request ssl_fc
http-request set-header X-Original-Forwarded-For %[hdr(x-forwarded-for)] if { hdr(x-forwarded-for) -m found }
http-request del-header x-forwarded-for
option forwardfor
http-response set-header Strict-Transport-Security "max-age=15768000"
server srv001 10.244.2.168:80 weight 1 check inter 2s
server srv002 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv003 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv004 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv005 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv006 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv007 127.0.0.1:1023 disabled weight 1 check inter 2s
#haproxy-2后端
backend default_haproxy-2_80
mode http
balance roundrobin
acl https-request ssl_fc
http-request set-header X-Original-Forwarded-For %[hdr(x-forwarded-for)] if { hdr(x-forwarded-for) -m found }
http-request del-header x-forwarded-for
option forwardfor
http-response set-header Strict-Transport-Security "max-age=15768000"
server srv001 10.244.2.169:80 weight 1 check inter 2s
server srv002 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv003 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv004 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv005 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv006 127.0.0.1:1023 disabled weight 1 check inter 2s
server srv007 127.0.0.1:1023 disabled weight 1 check inter 2s
配置關(guān)聯(lián)內(nèi)容
/ # cat /etc/haproxy/maps/_global_http_front.map
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# # HAProxy Ingress Controller
# # --------------------------
# # This file is automatically updated, do not edit
# #
#
news.happylau.cn/ default_haproxy-1_80
sports.happylau.cn/ default_haproxy-2_80
2.4 URL 自動(dòng)跳轉(zhuǎn)
haproxy ingress 支持自動(dòng)跳轉(zhuǎn)的能力胀蛮,需要通過 annotations 定義佛点,通過ingress.kubernetes.io/ssl-redirect 設(shè)置即可,默認(rèn)為 false鸳玩,設(shè)置為 true 即可實(shí)現(xiàn) http 往 https 跳轉(zhuǎn)的能力演闭,當(dāng)然可以將配置寫入到 ConfigMap 中實(shí)現(xiàn)默認(rèn)跳轉(zhuǎn)的能力,本文以編寫 annotations 為例米碰,實(shí)現(xiàn)訪問 http 跳轉(zhuǎn) https 的能力。
1虐译、定義 ingress 規(guī)則吴趴,設(shè)置 ingress.kubernetes.io/ssl-redirect 實(shí)現(xiàn)跳轉(zhuǎn)功能
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: haproxy-ingress-virtualhost
annotations:
kubernetes.io/ingress.class: haproxy
ingress.kubernetes.io/ssl-redirect: true #實(shí)現(xiàn)跳轉(zhuǎn)功能
spec:
rules:
- host: news.happylau.cn
http:
paths:
- path: /
backend:
serviceName: haproxy-1
servicePort: 80
- host: sports.happylau.cn
http:
paths:
- path: /
backend:
serviceName: haproxy-2
servicePort: 80
按照上圖測試了一下功能,未能實(shí)現(xiàn)跳轉(zhuǎn)實(shí)現(xiàn)跳轉(zhuǎn)的功能厢拭,開源版本中未能找到更多文檔說明,企業(yè)版由于鏡像需要認(rèn)證授權(quán)下載供鸠,未能進(jìn)一步做測試驗(yàn)證陨闹。
2.5 基于 TLS 加密
haproxy ingress 默認(rèn)集成了一個(gè)
1、生成自簽名證書和私鑰
[root@node-1 haproxy-ingress]# openssl req -x509 -newkey rsa:2048 -nodes -days 365 -keyout tls.key -out tls.crt
Generating a 2048 bit RSA private key
...........+++
.......+++
writing new private key to 'tls.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:GD
Locality Name (eg, city) [Default City]:ShenZhen
Organization Name (eg, company) [Default Company Ltd]:Tencent
Organizational Unit Name (eg, section) []:HappyLau
Common Name (eg, your name or your server's hostname) []:www.happylau.cn
Email Address []:573302346@qq.com
2寨闹、創(chuàng)建 Secrets觅廓,關(guān)聯(lián)證書和私鑰
[root@node-1 haproxy-ingress]# kubectl create secret tls haproxy-tls --cert=tls.crt --key=tls.key
secret/haproxy-tls created
[root@node-1 haproxy-ingress]# kubectl describe secrets haproxy-tls
Name: haproxy-tls
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.crt: 1424 bytes
tls.key: 1704 bytes
3杈绸、編寫 ingress 規(guī)則帖蔓,通過 tls 關(guān)聯(lián) Secrets
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: haproxy-ingress-virtualhost
annotations:
kubernetes.io/ingress.class: haproxy
spec:
tls:
- hosts:
- news.happylau.cn
- sports.happylau.cn
secretName: haproxy-tls
rules:
- host: news.happylau.cn
http:
paths:
- path: /
backend:
serviceName: haproxy-1
servicePort: 80
- host: sports.happylau.cn
http:
paths:
- path: /
backend:
serviceName: haproxy-2
servicePort: 80
4塑娇、應(yīng)用配置并查看詳情,在 TLS 中可以看到 TLS 關(guān)聯(lián)的證書
[root@node-1 haproxy-ingress]# kubectl apply -f ingress-virtualhost.yaml
ingress.extensions/haproxy-ingress-virtualhost configured
[root@node-1 haproxy-ingress]# kubectl describe ingresses haproxy-ingress-virtualhost
Name: haproxy-ingress-virtualhost
Namespace: default
Address:
Default backend: default-http-backend:80 (<none>)
TLS:
haproxy-tls terminates news.happylau.cn,sports.happylau.cn
Rules:
Host Path Backends
---- ---- --------
news.happylau.cn
/ haproxy-1:80 (10.244.2.168:80)
sports.happylau.cn
/ haproxy-2:80 (10.244.2.169:80)
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"haproxy"},"name":"haproxy-ingress-virtualhost","namespace":"default"},"spec":{"rules":[{"host":"news.happylau.cn","http":{"paths":[{"backend":{"serviceName":"haproxy-1","servicePort":80},"path":"/"}]}},{"host":"sports.happylau.cn","http":{"paths":[{"backend":{"serviceName":"haproxy-2","servicePort":80},"path":"/"}]}}],"tls":[{"hosts":["news.happylau.cn","sports.happylau.cn"],"secretName":"haproxy-tls"}]}}
kubernetes.io/ingress.class: haproxy
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 37m ingress-controller Ingress default/haproxy-ingress-virtualhost
Normal CREATE 37m ingress-controller Ingress default/haproxy-ingress-virtualhost
Normal UPDATE 7s (x2 over 37m) ingress-controller Ingress default/haproxy-ingress-virtualhost
Normal UPDATE 7s (x2 over 37m) ingress-controller Ingress default/haproxy-ingress-virtualhost
5埋酬、測試 https 站點(diǎn)訪問烧栋,可以看到安全的 https 訪問
三、寫在最后
haproxy 實(shí)現(xiàn) ingress 實(shí)際是通過配置更新 haproxy.cfg 配置珍特,結(jié)合 service 的服務(wù)發(fā)現(xiàn)機(jī)制動(dòng)態(tài)完成 ingress 接入,相比于 nginx 來說扎筒,haproxy 不需要重載實(shí)現(xiàn)配置變更酬姆。在測試 haproxy ingress 過程中,有部分功能配置驗(yàn)證沒有達(dá)到預(yù)期辞色,更豐富的功能支持在 haproxy ingress 企業(yè)版中支持,社區(qū)版能支持藍(lán)綠發(fā)布和 WAF 安全掃描功能诱篷,詳情可以參考社區(qū)文檔 haproxy 藍(lán)綠發(fā)布和 WAF 安全支持雳灵。
haproxy ingress 控制器目前在社區(qū)活躍度一般,相比于 nginx悯辙,traefik,istio 還有一定的差距针贬,實(shí)際環(huán)境中不建議使用社區(qū)版的 haproxy ingress。
四桦他、參考文檔
官方安裝文檔:https://haproxy-ingress.github.io/docs/getting-started/
haproxy ingress 官方配置:https://www.haproxy.com/documentation/hapee/1-7r2/traffic-management/k8s-image-controller/
博客參考文檔:https://cloud.tencent.com/developer/article/1564819
五谆棱、附錄配置文件詳解
#RBAC認(rèn)證賬號(hào)圆仔,和角色關(guān)聯(lián)
apiVersion: v1
kind: ServiceAccount
metadata:
name: ingress-controller
namespace: ingress-controller
---
# 集群角色坪郭,訪問資源對象和具體訪問權(quán)限
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: ingress-controller
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
resources:
- ingresses/status
verbs:
- update
---
#角色定義
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: ingress-controller
namespace: ingress-controller
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
- create
- update
---
#集群角色綁定ServiceAccount和ClusterRole關(guān)聯(lián)
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-controller
subjects:
- kind: ServiceAccount
name: ingress-controller
namespace: ingress-controller
- apiGroup: rbac.authorization.k8s.io
kind: User
name: ingress-controller
---
#角色綁定
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: ingress-controller
namespace: ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-controller
subjects:
- kind: ServiceAccount
name: ingress-controller
namespace: ingress-controller
- apiGroup: rbac.authorization.k8s.io
kind: User
name: ingress-controller
---
#后端應(yīng)用的service定義
apiVersion: v1
kind: Service
metadata:
name: ingress-default-backend
namespace: ingress-controller
spec:
ports:
- port: 8080
selector:
run: ingress-default-backend
---
#haproxy ingress配置歪沃,實(shí)現(xiàn)自定義配置功能
apiVersion: v1
kind: ConfigMap
metadata:
name: haproxy-ingress
namespace: ingress-controller
---
#haproxy ingress核心的DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
run: haproxy-ingress
name: haproxy-ingress
namespace: ingress-controller
spec:
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
run: haproxy-ingress
template:
metadata:
labels:
run: haproxy-ingress
spec:
hostNetwork: true #網(wǎng)絡(luò)模式為hostNetwork,即使用宿主機(jī)的網(wǎng)絡(luò)
nodeSelector: #節(jié)點(diǎn)選擇器嫌松,將調(diào)度至包含特定標(biāo)簽的節(jié)點(diǎn)
role: ingress-controller
serviceAccountName: ingress-controller #實(shí)現(xiàn)RBAC認(rèn)證授權(quán)
containers:
- name: haproxy-ingress
image: quay.io/jcmoraisjr/haproxy-ingress
args:
- --default-backend-service=$(POD_NAMESPACE)/ingress-default-backend
- --configmap=$(POD_NAMESPACE)/haproxy-ingress
- --sort-backends
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: stat
containerPort: 1936
livenessProbe:
httpGet:
path: /healthz
port: 10253
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
出處:http://dwz.date/cmQf
可聯(lián)系本人vx:17812796384