MySQL Orchestrator - HA(High Availability) - 4 - 인증 설정 - Proxy 를 이용한 로드밸런스 접속

Share

Last Updated on 3월 19, 2022 by Jade(정현호)

안녕하세요 
이번 포스팅에서는 Orchestrator 의 인증 설정 과 Nginx 활용한 Proxy 접속 또는 로드밸런스 접속 설정에 대해서 확인 해 보도록 하겠습니다. 


아래 이전 글에서 이어지는 연재 글로 설치 및 구성 환경은 이전 글을 참조하시면 됩니다.
  • Orchestrator 1 - 기능 설명 및 설치
  • Orchestrator 2 - 리팩토링 Failover Automated Recovery
  • Orchestrator 3 - VIP 설정 - 자동 Replication 설정

Orchestrator's authentication

Orchestrator 는 웹 콘솔에서 Takeover 나 복제 stop/start 등의 컨트롤이 가능 합니다 그래서 설정을 통해 적절한 인증을 통해 접속을 하고 계정에 따라서 다른 role 이 필요 하게 됩니다.
      

authentication 종류

Orchestrator 에서도 웹 콘솔 접속과 컨트롤에 대한 인증과 롤에 대한 기능을 지원하고 있습니다.

기본설정은 별다른 인증 절차(로그인) 없이 접속이 되는 형태 입니다

Orchestrator 에서 설정할 수 있는 authentication 는 3가지가 있습니다.

  • basic authentication
  • basic extended(multi) authentication
  • Headers authentication

basic 과 basic extended(multi) 는 거의 유사하며, Basic 에서 read only 롤이 추가된 것이 basic extended(multi) 입니다.
       

basic authentication

basic authentication 계정 1개에 대해서 로그인이 가능하도록 설정 하는 형태로 계정정보를(ID/PW) 를 알지 못하면 접속하지 못하는 인증 형태 입니다(Guest 유형이 없음)

Orchestrator 의 설정 파일인 orchestrator.conf.json 을 수정한 후 Orchestrator 를 재시작 해야 합니다.

아래 3개의 파라미터에 대해서 수정을 합니다.

"AuthenticationMethod": "basic",
"HTTPAuthUser": "dba_team",
"HTTPAuthPassword": "dba_team1!",

 • AuthenticationMethod : basic, multi, proxy  3개 항목을 입력 할 수 있습니다.
 • HTTPAuthUser / HTTPAuthPassword : basic 및 multi(extended basic) 에서 사용자 ID,PW 를 입력 합니다.


설정을 완료 후 Orchestrator 를 재시작 후 웹 콘솔에 접속을 합니다.
그러면 아래와 같이 인증정보인 아이디/패스워드 물어보게 됩니다. 설정한 ID/PW 를 입력 합니다.




접속 완료후 우측 상단에서는 로그인한 계정명이 확인되며, Home -> Status 메뉴에도 계정명과 권한 롤이 확인 됩니다.


     

Multi authentication

이번에는 Multi authentication 으로 설정을 변경하도록 하겠습니다

orchestrator.conf.json 파일 에서 아래와 같이 수정을 하였습니다.

"AuthenticationMethod": "multi",
"HTTPAuthUser": "dba_team",
"HTTPAuthPassword": "dba_team1!",

AuthenticationMethod 에서 basic 에서 multi 로 변경 하였습니다.
Orchestrator 를 재시작 후 다시 접속을 합니다.

만약 로그인 팝업이 나오지 않는다면 접속한적이 없는 브라우저를 사용하거나 사용하는 브라우저의 인터넷 사용기록 캐시를 삭제 해보시기 바랍니다.




이번에는 접속을 해서 "readonly" 라는 계정을 사용하여 로그인을 합니다.

패스워드는 입력 하지 않아도 됩니다.




그럼 로그인한 계정명에서 read only 라고 확인되고 롤에서도 read only 라고 확인 됩니다




인스턴스 상세 메뉴를 진입하여도 이전과 달리 변경에 대한 메뉴 나오지 않으며 변경 관련(Takeover , read only 변경 등) 된 내용은 실행할 수 없는, 즉 보기만 가능한 Read Only 로만 웹 콘솔을 이용하게 됩니다.

DBA 나 DB 팀이 아닌 개발팀 등에서 현재 Replication Cluster 현황이나 상태 정보를 확인 하고자 할 때 해당 readonly 계정으로 사용하면 제어 기능 없이 view의 기능으로만 사용할 수 있습니다.


        

Headers authentication

이번에는 Headers(Proxy) authentication 를 설정하도록 하겠습니다. Headers authentication 를 사용하기 위해서는 Apache  나 Nginx 와 같은 reverse proxy 기능을 할 수 있는 웹 서버와 같이 사용해야 합니다.

포스팅에서는 MySQL Slave Pool 로드밸런스 접속을 Nginx's Proxy 를 사용하여 진행하였기 때문에 인증에 필요한 웹 서버도 같이 Nginx 로 사용하였습니다.
       

Nginx 및 패키지 설치

아이디, 패스워드를 설정하는 기능은 Apache 웹 서버에서 많이 사용되고 유틸리티가 제공되는 HTTP basic authentication 를 활용하여 Nginx 에서도 같이 사용할 것 입니다(Nginx 에서는 유틸리티가 없음)

htpasswd 라는 툴을 통해서 인증정보가 담긴 파일을 생성할 수 있으며, 해당 파일은 Apache HTTP 웹 서버와 관련된 패키지 입니다. 해당 유틸리티를 통해서 인증 정보를 생성하고, 생성된 파일은 Nginx 에서 사용할 수 있습니다.

아래 와 같이 패키지 설치를 진행 합니다.(root 로 진행)

-- EPEL 레파지토리 설치
~]# yum -y install epel-release yum-utils


-- 패키지 설치
~]# yum install httpd-tools nginx nginx-mod-stream


-- apache httpd 서비스 비활성화
~]# systemctl disable httpd


httpd-tools 를 설치 하는 과정에서 httpd server 도 같이 설치가 됨으로 시작되는 것을 방지 하기 위해서 서비스 disable 도 하였습니다.



인증정보 설정

htpasswd 를 통해서 아래와 같이 인증 파일을 생성 합니다.(root 유저로 진행)

~]# cd /etc/nginx/conf.d

-- Admin Account
~]# htpasswd -bc orchestrator.htpasswd db_admin1 db_admin1

-- Admin Account
~]# htpasswd -b orchestrator.htpasswd db_admin2 db_admin2

-- Admin Account
~]# htpasswd -b orchestrator.htpasswd db_admin3 db_admin3


-- Read Only Account
~]# htpasswd -b orchestrator.htpasswd dev1 dev1


-c 옵션은 파일을 생성을 의미하며 그 다음 부터는 -b 옵션만 사용하여 해당 파일에 인증정보를 추가 할 수 있습니다.

htpasswd [옵션] [파일명] 아이디 패스워드   순으로 지정하여 사용하면 됩니다

~]# strings orchestrator.htpasswd 
db_admin1:$xxxxx
db_admin2:$xxxxx
db_admin3:$xxxxx
dev1:$xxxxx


db_admin1,2,3 은 관리자 계정으로 사용할 것이며(컨트롤 가능 유저), dev1 는 Read only 롤(권한) 으로 사용할 유저 입니다.


Nginx conf 설정

Nginx 를 orchestrator 로 접속 되도록 설정 파일인 conf 파일을 수정하여 설정 합니다.

[참고] orchestrator 에서 Apache 를 사용하여 Headers(Proxy) authentication 설정은 아래 문서를 참조하시면 됩니다. 


Nginx conf 디렉토리 이동후 기본 파일을 백업 후 수정 하여 사용 하도록 하겠습니다

--디렉토리 이동
~]# cd /etc/nginx/conf.d


-- 파일 백업
~]# cp default.conf default.conf.ori


-- conf 파일 수정
~]# vi default.conf 


-- 아래 내용으로 변경
server {
    listen       80;
    server_name  192.168.56.104 default;

    access_log  /var/log/nginx/default.access.log  main;
    error_log /var/log/nginx/default.error.log error;

    location / {
      auth_basic "orchestrator";
      auth_basic_user_file  /etc/nginx/conf.d/orchestrator.htpasswd;
      proxy_pass_request_headers on;
      proxy_hide_header Authorization;
      set $orchestrator_auth $remote_user;
      proxy_set_header X-Forwarded-User $orchestrator_auth;
      proxy_pass http://127.0.0.1:3000;
    }

}


위의 내용에서 server_name 에서 dns 나 호스트네임에 설정된 호스트나 사용하는 서버의 IP 로 변경 하면 됩니다.

설정이 완료 되었다면 Nginx 를 재시작 합니다.(root 로 실행)

~]# systemctl restart nginx



orchestrator.conf.json 수정

orchestrator 의 설정 파일 orchestrator.conf.json 를 수정하도록 하겠습니다.

1)

"ListenAddress": ":3000",


TO


"ListenAddress": "127.0.0.1:3000",



2)

"AuthenticationMethod": "multi",


TO


"AuthenticationMethod": "proxy",



3)

"AuthUserHeader": "",


TO


"AuthUserHeader": "X-Forwarded-User",



4)

"PowerAuthUsers": [
 "*"
],


TO


"PowerAuthUsers": [
 "db_admin1","db_admin2","db_admin3"
],


4개의 파라미터 를 수정하였습니다.

  • ListenAddress : 기본은 모든 IP 대역에서 Listen 이 가능하고 포트는 3000 으로 설정되어 있습니다.
                               설정은 로컬에서만 접속이 가능하도록 127.0.0.1 로 설정 하였습니다.
                               Nginx 를 거치지 않고 3000포트로 접속을 막기 위해서 입니다.



  • AuthenticationMethod: basic 또는 multi 로 설정된 부분을 proxy 로 변경 합니다.


  • AuthUserHeader : Nginx 에서 설정한 Proxy Header 인 X-Forwarded-User 으로 설정


  • PowerAuthUsers: Power User 는 Admin 유저로 사용할 유저명을 입력 하면 됩니다.
                                   기본 값인 * 로 사용시 htpasswd 에서 생성한 모든 유저가 Admin 롤을 가지게 됩니다.
                                   Read only 롤이 아닌 관리자로 사용할 계정에 대해서만 명시적으로 기재 하면 됩니다.


파일 수정이 완료 되었다면 Orchestrator 를 재시작 합니다


추가로 3000 포트를 방화벽에서 Open 해두고 3000 포트로 접속시 80 포트로 Redirect 를 설정하는 방법도 고려 할 수 있습니다.
기존 Nginx 의 default.conf 파일에서 아래 내용을 추가 하면 3000번 포트로 접속시 80포트로 Redirect 시키게 됩니다.

server {
    listen 192.168.56.104:3000;
    server_name 10.107.11.38;

    return 301 http://$host$request_uri;

}


listen 과 server_name 에 들어가는 IP 는 포스팅 시스템의 서버IP 로 실제 사용시 사용하는 IP 나 호스트네임 등을 사용하면 됩니다.


Nginx 를 통한 접속

Nginx 를 설정하였기 때문에 80포트로 접속이 가능한 상태입니다. 접속을 하면 아래와 같이 인증 정보 확인 팝업창이 나타납니다.

이전 단계에서 생성한 계정을 입력 하여 로그인을 합니다.




접속이 되었다면 Home -> Status 로 이동해서 보면 아래와 같이 접속한 정보 와 롤(admin 인지 Read only) 를 확인 할 수 있으며, 우측 상단에도 접속한 로그인 아이디도 확인 할 수 있습니다.




생성한 다른 계정도 접속을 시도를 해보겠습니다.




인증 로그인 창이 팝업되지 않는다면 아래와 같이 인터넷 사용 기록 캐시 정보를 삭제를 하시면 됩니다.




생성한 다른 계정 역시도 접속 및 Admin 으로 확인 되는 것을 확인 할 수 있습니다.




Admin 롤의 계정으로 접속을 하면 인스턴스 정보로 진입하면 아래 이미지와 같이 컨트롤이 가능함을 확인 할 수 있습니다.




conf.json 에서 PowerAuthUsers 에 입력하지 않은 dev1 계정으로 접속을 해보도록 하겠습니다.
접속을 해서 확인하면 롤이 read only 인 것을 확인 할 수 있습니다.





인스턴스 정보를 보면 컨트롤이 가능한 부분이 제외된 View 기능만 제공되는 것을 확인 할 수 있습니다.




conf.json 에서 ListenAddress": "127.0.0.1:3000" 로 설정하였기 때문에 직접 접속을 하면 아래와 접속이 불가한것을 확인 할 수 있습니다. 80포트(Nginx) 를 이용하여 접속이 가능하기 때문에 3000 포트가 OS 방화벽에서 오픈 되어 있을 경우 다시 Close 를 해도 됩니다




이렇게 구성을 하게 되면 DB관리자의 계정과 그외 이용자를 위한 Read Only 용 계정의 분리해서 사용할 수 있게 됩니다.
        

Nginx Proxy 를 이용한 접속

이전 포스팅에서 마스터 VIP 와 Slave VIP 를 생성 하였고 Failover/Takeover 등을 진행하였습니다.

Slave 노드 수 만큼 생성되는 다수의 Slave 노드 VIP 에 대해서 접속 및 로드밸런스를 사용하기 위해서는 추가적인 작업이 필요 합니다.

예를 들어 DNS 로브밸런스 , NAT(Proxy) 로드밸런스 등의 방법이 있을 것 같습니다,

포스팅에서는 위와 같은 다수의 Slave 노드 VIP 에 해서 Proxy 기능으로 사용을 하려고 합니다. 그리고 Proxy 툴에는 여러가지가 있습니다

포스팅에서 다루는 Nginx 는 Proxy 의 한 종류 이며 필수나 해당 방법만 있는 것은 아닙니다.

이전 단계에서 인증 설정을 위해서 Apache 또는 Nginx 와 같은 웹 서버가 필요하여 구성을 하였기 때문에 해당 Nginx 를 같이 활용하고자 포스팅에서는 Nginx 를 Proxy 툴로 사용하였습니다.
           

Nginx stream 설정

Nginx 는 http proxy 이외 TCP,UDP 프토콜도 Proxy 를 지원하고 있습니다(nginx-mod-stream)

[nginx.com/blog/tcp-load-balancing-in-nginx-plus-r5]


그래서 Nginx 를 웹 서버 형태로 Front 로 사용하면서 Backend 로 PHP, Java WAS(Tomcat ...), Node.js ,Django 등과 연계해서 사용을 주로 하고 있으며 위에서 언급한 내용과 같이 TCP, UDP 프로토콜 역시 Proxy 를 지원하기 때문에 보통의 Proxy Tool 로도 많이 사용되기도 하며 Nginx 를 웹 서버라는 표현 대신 Proxy Server 로 불리기도 합니다.

TCP,UDP Proxy 를 사용하기 위해서는 stream 을 사용을 하면 됩니다. 

먼저 nginx.conf 에서 stream 블럭을 신규로 추가하도록 하겠습니다.

~]# cd /etc/nginx
~]# vi nginx.conf

http {

}

## http {} 블럭 아래에 추가

stream {
include stream.d/acs_cluster.conf;
}


stream 은 http 와 동일한 레벨 입니다. 그래서 stream {} 블럭이 http 블럭안에 선언 될 경우 에러가 발생됩니다.
http{} 블럭 아래 별도로 stream 블럭을 위의 내용과 같이 추가 합니다.

그 다음 디렉토리를 생성 후 mysql 3306 proxy 내용을 설정 하도록 하겠습니다.

~]# mkdir -p /etc/nginx/stream.d

~]# cd /etc/nginx/stream.d

~]# vi acs_cluster.conf


### 아래내용을 입력 ###

upstream acs_rw {
    server 192.168.56.38:3306;
    zone tcp_mem 64k;
}

upstream acs_ro {
    server 192.168.56.39:3306 max_fails=3 fail_timeout=1s;
    server 192.168.56.40:3306 max_fails=3 fail_timeout=1s;
    zone tcp_mem 64k;
}

server {
    listen 192.168.56.98:3306;
    proxy_pass acs_rw;
    proxy_connect_timeout 2s;
        }

server {
    listen 192.168.56.99:3306;
    proxy_pass acs_ro;
    proxy_connect_timeout 2s;
        }


Server : 서버 블럭에서는 listen , proxy_pass , proxy_connect_timeout 을 설정 하였습니다.
                 listen 에서는 접속을 받을 포트 번호, 포트를 바인딩 할 IP 번호를 입력 하였습니다.
                 해당 IP 는 아래에서 Assign 할 가상 IP 로 서비스 VIP 역활로 사용할 것 입니다.


Upstream  : 업스트림 에서는 스트림명을 설정하여 다수의 업스트림셋을 사용할 수 있습니다.
                       포스팅에서는 rw 용 업스트림(마스터) 과 Slave 에 접속할 ro 업스트림을 생성하였습니다.
                       ro 업스트림에는 Slave 노드 VIP 를 모두 기재(포스팅에서는 2개임) 하였습니다.
                       업스트림의 기본 분배방식은 라운드로빈 방식입니다.
                       IP 39 와 40 2개에 대해서 라운드 로빈 방식으로 로드밸런스 되게 됩니다.


[참고1] 포스팅에서 다루는 부분은 stream에 필요한 내용만 기술되어 있습니다 해당 부분 이외 Nginx 자체적으로 설정 할 부분이 더 있을 수 있습니다.

추가적인 Nginx 에 대한 추가 정보는 아래 포스팅을 참조하시면 됩니다.



[참고2] 보통의 Proxy 툴을 이용하게 되면 최종 목적지 서비스 에서는 중간 다리 역활을 하는 Proxy 서버가 출발지(Source) 로 확인 되게 됩니다.
즉 Nginx Proxy 를 통해서 접속을 할 경우 MySQL 에서는 접속Host(IP) 가 Nginx 로 확인 되게 됩니다.

이는 NAT Forwarding 형태로 접속하거나 Nginx 와 같은 각종 Proxy 솔루션을 이용할 경우 보통의 경우 중간 서버(Proxy) 가 Source 서버로 확인 되는 경우가 많이 있습니다.


[참고3] 포스팅에서는 Orchestrator 용 Repository DB의 MySQL 포트를 3307 로 변경 하여 사용 중입니다.
포스팅과 같이 Orchestrator 와 Orchestrator Repository DB 가 설치된 환경에서 Nginx 를 위와 같이 설정하게 되면 3306 포트의 충돌이 발생될 수 있습니다.

Orchestrator Repository DB 의 포트를 변경 하거나 Repository DB 의 bind-address 를 127.0.0.1 로 변경 해야 합니다.
포스팅에서는 3307로 포트를 변경 하여 진행 하였습니다.
       

VIP 생성 및 Nginx 재시작

Slave 노드 VIP 가 DB 호스트(노드) 당 1개씩 생성 되어 있기 때문에 VIP 에 대한 VIP 1개, 즉 서비스 VIP 가 필요 합니다
(client 는 1개의 VIP 를 설정하여 사용)

그래서 Nginx 및 Orchestrator 가 구성된 서버에 서비스용 VIP 를 Assign 하도록 하겠습니다
필수는 아니지만 Master VIP 에 대한 VIP도 생성 하도록 하겠습니다

가령 서비스 VIP 의 대역대가 틀리거나 망이 틀리는 등의 이유가 있다면 Master 서비스 VIP 도 생성해서 사용할 수도 있습니다
(즉 환경 및 구성에 따라 달라짐)


아이피는 아래와 같이 Assign 하도록 하겠습니다
Master RW 용 서비스 VIP : 192.168.56.98
Slave RO 용 서비스 VIP : 192.168.56.99

~]# ifconfig enp0s8:0 192.168.56.98 up

~]# ifconfig enp0s8:1 192.168.56.99 up

*  포스팅의 Orchestrator 서버 환경에서는 enp0s8 를 사용하였습니다.

이전 단계에서 Nginx 에서 서비스 VIP 98,99 에 대한 Listen 설정은 되어 있는 상태 입니다.
listen 192.168.56.98:3306;
...

listen 192.168.56.99:3306;
...

VIP 가 할당이 완료되었다면 nginx 를 재시작 합니다.

~]# systemctl restart nginx



[참고] Nginx 시작시 Permission denied 에러 발생 할 경우!

SELinux 를 사용하는(활성화된) 환경에서 3306 포트를 지정하고 Nginx 를 시작할 경우 아래와 같은 에러가 systemd 로그에 기록될 경우가 있습니다.

~]# journalctl -xe
Aug 25 nginx[12335]: nginx: [emerg] bind() to 0.0.0.0:3306 failed (13: Permission denied)
Aug 25 systemd[1]: nginx.service: control process exited, code=exited status=1
Aug 25 systemd[1]: Failed to start nginx - high performance web server.


SELinux 와 관련된 에러로 SELinux 를 비활성화 하거나 아래와 같이 SELinux 의 정책에 추가를 진행을 하면 됩니다.

~]# cd /tmp
-- 정책 추가 문 생성
~]# auditallow -a -M mysqld_port_t_name_bind_allow


-- 정책 추가
~]# semodule -i mysqld_port_t_name_bind_allow.pp

       

로드밸런스 테스트

별도의 다른 서버에서 RW VIP 와 RO VIP 에 대해서 아래의 2개의 쿼리를 2초간 실행되는 형태로 수행을 해두었습니다.

select @@hostname;
show variables like 'read_only';

Slave VIP 로 접속한 터미널을 보면 접속한 DB 호스트네임 이 계속 변경 됨을 확인 할 수 있습니다

        

Slave 인스턴스 Down

Slave DB 인스턴스 중에 1개를 종료 해보도록 하겠습니다.


acs3 DB 인스턴스를 종료하면 Slave 서비스 VIP 로 접속되는 서버 2개 중에서 1개가 제외되고 남은 1개 DB에 정상적으로 접속되는 것을 확인 할 수 있습니다.


종료된 DB 인스턴스를 다시 시작 하면 Nginx 에서는 해당 인스턴스에 접속이 가능하기 때문에 다시 2개의 VIP 로 로드밸란스 되어 접속되게 됩니다.
(Nginx 의 Upstream 에 IP 와 포트 정보가 입력되어 있습니다)

종료된 DB 인스턴스를 다시 시작 해보도록 하겠습니다.

        

Master 인스턴스 Down

이번에는 마스터 DB 인스턴스를 down 하여서 Failover 가 되도록 해보겠습니다.


마스터 노드인 acs 호스트가 가지고 있던 노드 VIP 가 acs2 노드로 Relocate 되었습니다.
또한 acs2 호스트에서 Assign 되어있는 Slave 노드 VIP 는 종료가 되어 Slave 서비스 VIP 로 접속시 acs3 호스트로만 접속이 되는 것을 확인 할 수 있습니다.

[추가 내용]

포스팅에서는 Proxy 를 Nginx 를 사용하는 예시로 소개가 되어 있습니다. 추가로 HAProxy 를 통해서도 Client Side HA(또는 로드밸런싱) 를 사용할 수 있습니다. 
HAProxy 의 External-Script 를 통한 Healthcheck 방법을 이용한다면 vip 방식이 아니 다른 형태로도 구성 및 사용이 가능함으로 내용을 참조해 보셔도 좋을것 같습니다.

         

conclusion

여기까지 해서 Orchestrator 에 대한 설치, 구성 부터 해서 Takeover(promote) Recovery(Failover),VIP, 인증 등의 내용 등을 확인 해보았습니다.

Orchestrator 는 계속 업데이트도 되고 있으면서 웹 UI 에서 많은 부분이 진행 할수 있거나 상태를 확인 할 수 있는 점, hooking 기능을 제공 하여 다양한 활용을 할 수 있는 점, 인증 관련 기능을 제공함으로써 관리자 와 비 관리자 롤을 나눠서 사용할 수 있다는 점, 그리고 Takeover 나 Failover 가 손 쉽게 사용 할 수 있다는 점이 가장 큰 장점 인 것 같습니다.

추가적으로 확인 되는 내용은 계속 업데이트 하도록 하겠습니다.


Ref
 • github.com/orchestrator/security
 • docs.nginx.com/tcp-udp-load-balancer
 • percona.com/read-only-webui-orchestrator
 • nginx.com/blog/tcp-load-balancing-in-nginx-plus-r5



관련된 다른 글

 

 

 

 

 



0
글에 대한 당신의 생각을 기다립니다. 댓글 의견 주세요!x