Cloud/Kubernetes

HAProxy 서버 설치

Happy@Cloud 2024. 10. 6. 02:22

이 가이드는 Ubuntu 기준으로 작성되어 있습니다.

CentOS 기반의 가이드는 여기를 참조하세요. 

 

1. 설치
apt-get install -y haproxy

 

2. 설정

아래 예제를 참조하여 작성하십시오. 
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
vi /etc/haproxy/haproxy.cfg

global
	log /dev/log	local0
	log /dev/log	local1 notice
	chroot /var/lib/haproxy
	stats socket /run/haproxy/admin.sock mode 660 level admin
	stats timeout 30s
	user haproxy
	group haproxy
	daemon

	# Default SSL material locations
	ca-base /etc/ssl/certs
	crt-base /etc/ssl/private

	# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
	log	global
	mode	http
	option	httplog
	option	dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
	errorfile 400 /etc/haproxy/errors/400.http
	errorfile 403 /etc/haproxy/errors/403.http
	errorfile 408 /etc/haproxy/errors/408.http
	errorfile 500 /etc/haproxy/errors/500.http
	errorfile 502 /etc/haproxy/errors/502.http
	errorfile 503 /etc/haproxy/errors/503.http
	errorfile 504 /etc/haproxy/errors/504.http
	maxconn                 3000

listen stats
    bind :9000
    mode http
    stats enable
    stats uri /
    monitor-uri /healthz

frontend api-server
    bind *:6443
    default_backend api-server
    mode tcp
    option tcplog

backend api-server
    balance source
    mode tcp
    server controlplane controlplane.msa.edutdc.com:6443 check

frontend http-in
    bind *:80
    mode tcp
    option tcplog
    default_backend http-backend

frontend https-in
    bind *:443
    mode tcp
    option tcplog
    default_backend https-backend

backend http-backend
    mode tcp
    server worker1 worker1.msa.edutdc.com:30080
    server worker2 worker2.msa.edutdc.com:30080

backend https-backend
    mode tcp
    server worker1 worker1.msa.edutdc.com:30443
    server worker2 worker2.msa.edutdc.com:30443

ingress-nginx contrller 서비스 객체를 Node port로 오픈해야 합니다. 

3. 적용
systemctl restart haproxy

 


Pod에서 haproxy서버 통해 outbound 시 Troubleshooting

Pod내에서 외부 사이트(예: github.com)를 접속할 때 haproxy서버가 설치된 VM을 통해 나가게 됩니다. 

http통신이라면 문제가 없지만, https 통신시에는 문제가 됩니다. 

예를 들어, https://github.com으로 통신을 시도하면 github.com의 주소가 실제 외부 IP가 아닌 haproxy 서버의 IP로 해석이 됩니다. 

SSL통신을 할 때는 먼저 SSL Handshake라고 해서 대상 서버에서 인증서를 다운로드 하고 그 인증서의 유효성을 체크합니다. 

그런데 실제 github.com이 아닌 haproxy서버로 접속하게 되고, haproxy서버로 부터 인증서를 다운로드 하려 합니다. 

당연히 haproxy서버에는 github.com의 SSL인증서가 없습니다. 

haproxy서버는 이 요청을 ingress 컨트롤러로 proxying하게 됩니다. 

그리고 ingress 컨트롤러는 kubernetes의 SSL 인증서를 리턴하게 됩니다. 

결과적으로 github.com의 SSL 인증서가 아니라 kubernetes의 SSL 인증서가 다운로드 되므로 SSL Handshake는 실패하게 됩니다. 

 

테스트를 위해 Git Pod를 하나 생성합니다. 

kubectl run gitpod -it --image bitnami/git -- sh

생성된 파드 안에서 아래 명령으로 실제 주소로 연결되는지 haproxy서버로 연결되는지 테스트 합니다. 

curl -v github.com

또는 실제로 git repository를 다운로드 해 봅니다. 

git clone https://github.com/hiondal/subride-front.git

만약 아래와 같은 에러가 난다면 솔루션에 따라 조치 합니다.  

# git clone https://github.com/hiondal/subride-config.git
Cloning into 'subride-config'...
fatal: unable to access 'https://github.com/hiondal/subride-config.git/': SSL certificate problem: self-signed certificate

 

솔루션은 github.com의 실제 주소로 연결하도록 DNS에 github.com의 IP를 등록해 주면 됩니다. 

Kubernetes Pod의 DNS는 coredns입니다. 

coredns 파드는 ConfigMap 'coredns'에서 정보를 주입 받습니다. 

따라서 ocredns 컨피그맵에 github.com의 실제 주소를 지정하고, coredns 파드를 재시작하면 됩니다. 

kubectl edit cm coredns -n kube-system

아래 'ready' 하단에 있는 'hosts' 섹션과 같이 실제 IP를 추가합니다. 

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        hosts {
            20.205.243.166 github.com
            fallthrough
        }
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2024-09-25T08:31:52Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "4050036"
  uid: c8f8d48b-627b-49f0-8deb-f8ca626b6d65

 

coredns Pod를 재시작합니다. 

kubectl rollout restart deploy coredns -n kube-system

 

이제 테스트 Git Pod를 삭제하고 재생성한 후 Git clone을 테스트 해 봅니다.