[HAProxy] 무중단 배포
HAProxy를 사용할 경우 무중단 배포나 교체, scale-in을 달성하는 것은 어렵지 않다.
HAProxy 설정파일을 변경 후에 reload하면 그 자체로도 다운타임 없이 교체를 수행하므로, 설정파일을 잘 갈아끼우는 것만으로도 무중단 배포가 된다.
한번 시도해보자.
같은 동작을 하는 간단한 서버를 2개 실행한다.
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
http.HandleFunc("/fast", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"ok"}`))
fmt.Println("fast")
})
http.HandleFunc("/slow", func(w http.ResponseWriter, r *http.Request) {
// 5초 대기
time.Sleep(5 * time.Second)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"ok"}`))
fmt.Println("slow")
})
// 서버 시작
http.ListenAndServe(":8081", nil)
}package main
import (
"fmt"
"net/http"
"time"
)
func main() {
http.HandleFunc("/fast", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"ok"}`))
fmt.Println("fast")
})
http.HandleFunc("/slow", func(w http.ResponseWriter, r *http.Request) {
// 5초 대기
time.Sleep(5 * time.Second)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"ok"}`))
fmt.Println("slow")
})
// 서버 시작
http.ListenAndServe(":8082", nil)
}

그리고 HAProxy에서 일단은 하나만 라우팅한다.
frontend test-front
mode http
bind *:8000
default_backend test-back
backend test-back
server master 0.0.0.0:8081

잘 연결되었고

그걸 찌르는 녀석을 하나 띄웠다.
중간에 뭔가 끊긴다면 이 녀석이 감지할 것이다.
package main
import (
"fmt"
"net/http"
"time"
)
func attack(i int) {
fmt.Println("Start attack")
for {
// localhost:3000에 GET 요청을 보냄
req, err := http.NewRequest("GET", "http://127.0.0.1:8000/slow", nil)
if err != nil {
panic(err)
}
// 요청 보내기
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
resp.Body.Close()
fmt.Println("checked", i)
// 0.1초 대기
time.Sleep(time.Millisecond * 100)
}
}
func main() {
// 스레드 5개 띄우고 대기하기
for i := 0; i < 5; i++ {
go attack(i)
}
// 무한 대기
for {
}
}

그러고 돌려보면, 잘 돌아갈 것이다.
그러면 이제 서버를 교체해보자.

서버 목적지만 바꿔서 reload하면
중단 없이 요청이 계속해서 이어지고 있는 것을 볼 수 있을 것이다.
서버를 스케일아웃하고 싶다면 저 backend server 목록을 추가해서 reload하면 되고, 서버 일부를 다운하고 싶다면 빼서 reload하면 된다.
Blue-Green 배포 같은 것도 그냥 한번에 교체해서 reload하는 식으로 처리하면 된다. 나머지는 응용의 영역이다.
참조
https://www.haproxy.com/blog/rolling-updates-and-blue-green-deployments-with-kubernetes-and-haproxy