2020 It邦幫忙鐵人賽 系列文章
由於我比較熟悉 GCP / GKE 的服務,這篇的操作過程都會以 GCP 平台作為範例,不過操作過程大體上是跨平台通用的。
寫文章真的是體力活,覺得我的文章還有參考價值,請左邊幫我點讚按個喜歡,右上角幫我按個追縱,底下歡迎留言討論。給我一點繼續走下去的動力。
對我的文章有興趣,歡迎到我的網站上 https://chechiachang.github.io 閱讀其他技術文章,有任何謬誤也請各方大德直接聯繫我,感激不盡。
HAproxy 全名是 High Availability Proxy,是一款開源 TCP/HTTP load balancer,他可以
HAProxy 還有其他非常多的功能,想了解細節可以來看原理解說文件
我們今天的範例是在後端的 redis 與 clients 中間多放一層 HAProxys
+-------+ +--------+ +------------+ +---------+
|Clients|---|HAProxys|----|redis master|----|sentinels|
+-------+ +--------+ +------------+ +---------+
可能有人會問說,那前兩天講的 redis sentinel,跑去哪裡了。
sentinel 還在正常運作,負責監測 redis 狀態與 failover,只是 client 不再透過 sentinel 去取得 master,而是透過 HAProxy。
我把我的寶藏都在這了https://github.com/chechiachang/haproxy-kubernetes
下載下來的 .sh ,跑之前養成習慣貓一下
cat install.sh
#!/bin/bash
# redis-db-credentials should already exists
#kubectl create secret generic redis-db-credentials \
--from-literal=REDIS_PASSWORD=123456
# Update haproxy.cfg as configmap
kubectl create configmap haproxy-config \
--from-file=haproxy.cfg \
--output yaml \
--dry-run | kubectl apply -f -
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
這邊做的事情有幾件
簡單看一下 deployment
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: haproxy
spec:
replicas: 3
template:
metadata:
labels:
app: haproxy
app.kubernetes.io/name: haproxy
component: haproxy
spec:
volumes:
- name: haproxy-config
configMap:
name: haproxy-config
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: "app"
operator: "In"
values:
- "haproxy"
topologyKey: kubernetes.io/hostname
containers:
- name: haproxy
image: haproxy:2.0.3-alpine
command: ["haproxy", "-f", "/usr/local/etc/haproxy/config/haproxy.cfg"]
readinessProbe:
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 1
successThreshold: 2
failureThreshold: 2
tcpSocket:
port: 26999
port: 6379
volumeMounts:
- name: haproxy-config
mountPath: /usr/local/etc/haproxy/config
resources:
requests:
cpu: 10m
memory: 30Mi
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-db-credentials
key: REDIS_PASSWORD
ports:
- containerPort: 8000
name: http
- containerPort: 9000
name: https
- containerPort: 26999
name: stats
- containerPort: 6379
name: redis
看一下 service
kind: Service
apiVersion: v1
metadata:
name: haproxy-service
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800 # 3 hr
selector:
app: haproxy
ports:
- name: http
protocol: TCP
port: 8000
- name: https
protocol: TCP
port: 9000
- name: stats
protocol: TCP
port: 26999
- name: redis
protocol: TCP
port: 6379
- name: redis-exporter
protocol: TCP
port: 8404
kubectl get po | grep haproxy
haproxy-56d94f857f-gmd4s 1/1 Running 0 47d
haproxy-56d94f857f-p2vj6 1/1 Running 0 47d
haproxy-56d94f857f-vhz8b 1/1 Running 0 47d
看一下 haproxy.cfg
# https://cbonte.github.io/haproxy-dconv/2.0/configuration.html
# https://github.com/prometheus/haproxy_exporter
# https://www.haproxy.com/blog/haproxy-exposes-a-prometheus-metrics-endpoint/
# curl http://localhost:8404/metrics
# curl http://localhost:8404/stats
frontend stats
mode http
timeout client 30s
bind *:8404
option http-use-htx
http-request use-service prometheus-exporter if { path /metrics }
stats enable
stats uri /stats
stats refresh 10s
# Redis
frontend redis_gate
mode tcp
timeout client 7d
bind 0.0.0.0:6379 name redis
default_backend redis_servers
backend redis_servers
mode tcp
timeout connect 3s
timeout server 7d
option tcp-check
tcp-check connect
tcp-check send AUTH\ "${REDIS_PASSWORD}"\r\n
tcp-check send PING\r\n
tcp-check expect string PONG
tcp-check send info\ replication\r\n
tcp-check expect string role:master
tcp-check send QUIT\r\n
tcp-check expect string +OK
server R1 redis-2-redis-ha-announce-0:6379 check inter 1s
server R2 redis-2-redis-ha-announce-1:6379 check inter 1s
server R3 redis-2-redis-ha-announce-2:6379 check inter 1s
HAProxy 會維護 backend 的 proxy stats,找到三台 redis 中,是 master 的這台
Running Log
kubectl logs -f haproxy-123-123456789
[WARNING] 273/153936 (1) : Server redis_servers/R2 is DOWN, reason: Layer7 timeout, info: " at step 6 of tcp-check (expect string 'role:master')", check duration: 1000ms. 2 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[WARNING] 273/153937 (1) : Server redis_servers/R3 is DOWN, reason: Layer7 timeout, info: " at step 6 of tcp-check (expect string 'role:master')", check duration: 1001ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
HAProxy 去 redis 問,你是 master 嗎,兩個人回不是,只有一個回 role:master,所以把 client 導過去