Loading...
MySQL 9.5 Reference Manual 9.5의 7.1.14 Network Namespace Support의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
network namespace는 host 시스템으로부터의 네트워크 스택을 논리적으로 복사한 것입니다. network namespace는 컨테이너나 가상 환경을 구성하는 데 유용합니다. 각 namespace는 자체 IP 주소, 네트워크 인터페이스, 라우팅 테이블 등을 가집니다. 기본 또는 global namespace는 host 시스템의 물리적 인터페이스가 존재하는 namespace입니다.
namespace별 주소 공간은 MySQL 연결이 namespace를 가로지를 때 문제를 유발할 수 있습니다. 예를 들어, 컨테이너나 가상 네트워크에서 실행되는 MySQL 인스턴스의 네트워크 주소 공간은 host 머신의 주소 공간과 다를 수 있습니다. 이로 인해, 한 namespace의 주소에서 오는 클라이언트 연결이 MySQL 서버 입장에서는 다른 주소에서 오는 것으로 보이는 현상이 발생할 수 있으며, 심지어 클라이언트와 서버가 같은 머신에서 실행되더라도 그렇습니다.
두 프로세스가 IP 주소 203.0.113.10 을 가진 host에서 실행되지만 서로 다른 namespace를 사용하는 경우를 생각해 보십시오. 연결은 다음과 같은 결과를 낼 수 있습니다:
1$> mysql --user=admin --host=203.0.113.10 --protocol=tcp 2 3mysql> SELECT USER(); 4+--------------------+ 5| USER() | 6+--------------------+ 7| [email protected] | 8+--------------------+
이 경우, 기대되는 USER() 값은 [email protected] 입니다. 이러한 동작은 연결이 시작된 주소가 보이는 것과 다를 경우 계정 권한을 적절히 부여하기 어렵게 만들 수 있습니다.
이 문제를 해결하기 위해, MySQL은 TCP/IP 연결에 사용할 network namespace를 지정할 수 있게 하여, 연결의 양 끝점이 합의된 공통 주소 공간을 사용하도록 합니다.
MySQL은 network namespace를 구현하는 플랫폼에서 이를 지원합니다. MySQL 내부의 지원 대상은 다음과 같습니다:
다음 섹션에서는 MySQL에서 network namespace를 사용하는 방법을 설명합니다:
MySQL에서 network namespace support를 사용하기 전에, 다음 host 시스템 선행 조건을 충족해야 합니다:
참고
MySQL 내부에서는, network namespace별 host 파일에 지정된 이름에 대해 호스트 이름 확인이 동작하지 않는다는 알려진 제한이 있습니다. 예를 들어, red namespace의 호스트 이름 주소가 /etc/netns/red/hosts 파일에 지정되어 있는 경우, 해당 이름으로 바인딩하는 것은 서버와 클라이언트 양쪽에서 모두 실패합니다. 우회 방법은 호스트 이름 대신 IP 주소를 사용하는 것입니다.
CAP_SYS_ADMIN 운영 체제 권한을 활성화해야 합니다.주의
CAP_SYS_ADMIN 활성화는 프로세스가 namespace 설정 외에 다른 특권 작업도 수행할 수 있게 하기 때문에 보안에 민감한 작업입니다. 그 영향에 대한 설명은 https://man7.org/linux/man-pages/man7/capabilities.7.html을 참조하십시오.
CAP_SYS_ADMIN 은 시스템 관리자가 명시적으로 활성화해야 하므로, 기본적으로 MySQL 바이너리에는 network namespace support가 활성화되어 있지 않습니다. 시스템 관리자는 CAP_SYS_ADMIN 과 함께 MySQL 프로세스를 실행하는 것의 보안적 영향에 대해 평가한 후에 이를 활성화해야 합니다.
다음 예제의 지침은 red 및 blue 라는 이름을 가진 network namespace를 설정합니다. 사용자가 선택하는 이름은 다를 수 있으며, host 시스템의 네트워크 주소와 인터페이스 또한 다를 수 있습니다.
여기에 표시된 커맨드는 root 운영 체제 사용자로 실행하거나, 각 커맨드 앞에 sudo 를 붙여 실행하십시오. 예를 들어 ip 나 setcap 커맨드를 root 가 아닌 상태에서 실행하려면 sudo ip 또는 sudo setcap 을 사용하십시오.
network namespace를 구성하려면 ip 커맨드를 사용합니다. 일부 작업의 경우, ip 커맨드는 특정 namespace(이미 존재해야 함) 안에서 실행되어야 합니다. 이러한 경우, 커맨드는 다음과 같이 시작합니다:
1ip netns exec namespace_name
예를 들어, 다음 커맨드는 red namespace 안에서 loopback 인터페이스를 활성화합니다:
1ip netns exec red ip link set lo up
red 및 blue 라는 이름의 namespace를 추가하고, 각 namespace에 namespace 간 링크로 사용되는 자체 가상 이더넷 디바이스와 자체 loopback 인터페이스를 추가하려면 다음과 같이 합니다:
1ip netns add red 2ip link add veth-red type veth peer name vpeer-red 3ip link set vpeer-red netns red 4ip addr add 192.0.2.1/24 dev veth-red 5ip link set veth-red up 6ip netns exec red ip addr add 192.0.2.2/24 dev vpeer-red 7ip netns exec red ip link set vpeer-red up 8ip netns exec red ip link set lo up 9 10ip netns add blue 11ip link add veth-blue type veth peer name vpeer-blue 12ip link set vpeer-blue netns blue 13ip addr add 198.51.100.1/24 dev veth-blue 14ip link set veth-blue up 15ip netns exec blue ip addr add 198.51.100.2/24 dev vpeer-blue 16ip netns exec blue ip link set vpeer-blue up 17ip netns exec blue ip link set lo up 18 19# if you want to enable inter-subnet routing... 20sysctl net.ipv4.ip_forward=1 21ip netns exec red ip route add default via 192.0.2.1 22ip netns exec blue ip route add default via 198.51.100.1
namespace 간 링크를 도식화하면 다음과 같습니다:
1red global blue 2 3192.0.2.2 <=> 192.0.2.1 4(vpeer-red) (veth-red) 5 6 198.51.100.1 <=> 198.51.100.2 7 (veth-blue) (vpeer-blue)
존재하는 namespace와 링크를 확인하려면:
1ip netns list 2ip link list
global 및 이름 있는 namespace의 라우팅 테이블을 보려면:
1ip route show 2ip netns exec red ip route show 3ip netns exec blue ip route show
red 및 blue 링크와 namespace를 제거하려면:
1ip link del veth-red 2ip link del veth-blue 3 4ip netns del red 5ip netns del blue 6 7sysctl net.ipv4.ip_forward=0
network namespace support를 포함하는 MySQL 바이너리가 실제로 namespace를 사용할 수 있도록 하려면, 이들 바이너리에 CAP_SYS_ADMIN capability를 부여해야 합니다. 다음 setcap 커맨드는 MySQL 바이너리가 있는 디렉터리로 위치를 변경했다고 가정합니다(시스템에 맞게 pathname을 조정하십시오):
1cd /usr/local/mysql/bin
해당 바이너리에 CAP_SYS_ADMIN capability를 부여하려면:
1setcap cap_sys_admin+ep ./mysqld 2setcap cap_sys_admin+ep ./mysql 3setcap cap_sys_admin+ep ./mysqlxtest
CAP_SYS_ADMIN capability를 확인하려면:
1$> getcap ./mysqld ./mysql ./mysqlxtest 2./mysqld = cap_sys_admin+ep 3./mysql = cap_sys_admin+ep 4./mysqlxtest = cap_sys_admin+ep
CAP_SYS_ADMIN capability를 제거하려면:
1setcap -r ./mysqld 2setcap -r ./mysql 3setcap -r ./mysqlxtest
주의
이전에 setcap 을 적용한 바이너리를 재설치하는 경우, setcap 을 다시 사용해야 합니다. 예를 들어, in-place MySQL 업그레이드를 수행하는 경우, CAP_SYS_ADMIN capability를 다시 부여하지 않으면 namespace 관련 오류가 발생합니다. 이름 있는 namespace에 대한 주소 바인딩 시도에 대해 서버는 다음과 같은 에러와 함께 실패합니다:
1[ERROR] [MY-013408] [Server] setns() failed with error 'Operation not permitted'
--network-namespace 옵션을 사용하여 호출한 클라이언트는 다음과 같이 실패합니다:
1ERROR: Network namespace error: Operation not permitted
앞서 설명한 host 시스템 선행 조건이 충족되었다고 가정하면, MySQL은 연결의 listening (inbound) 측에 대한 서버 측 namespace와 연결의 outbound 측에 대한 클라이언트 측 namespace를 구성할 수 있게 해 줍니다.
서버 측에서는, bind_address, admin_address, mysqlx_bind_address 시스템 변수가, 들어오는 연결을 listen할 IP 주소 또는 호스트 이름에 대해 사용할 network namespace를 지정하는 확장된 구문을 가집니다.
주소에 대한 namespace를 지정하려면, 슬래시와 namespace 이름을 추가합니다. 예를 들어, 서버 my.cnf 파일에는 다음과 같은 라인이 있을 수 있습니다:
1[mysqld] 2bind_address = 127.0.1.1,192.0.2.2/red,198.51.100.2/blue 3admin_address = 102.0.2.2/red 4mysqlx_bind_address = 102.0.2.2/red
다음 규칙이 적용됩니다:
/ns 접미사로 지정해야 합니다./ns 접미사가 없는 주소는 host 시스템 global namespace를 사용합니다. 따라서 global namespace가 기본값입니다./ns 접미사가 있는 주소는 이름이 ns 인 namespace를 사용합니다.bind_address 및 mysqlx_bind_address는 여러 개의 콤마로 구분된 주소 목록을 허용하므로, 변수 값은 global namespace, 이름 있는 namespace, 또는 이들의 혼합에 있는 주소를 지정할 수 있습니다.서버 시작 동안 namespace 사용 시도가 에러를 발생시키면, 서버는 시작되지 않습니다. X Plugin에 대해 플러그인 초기화 중에 에러가 발생하여 어떤 주소에도 바인딩할 수 없는 경우, 플러그인은 초기화 시퀀스에 실패하며 서버는 이를 로드하지 않습니다.
클라이언트 측에서는, network namespace를 다음 컨텍스트에서 지정할 수 있습니다:
--network-namespace 옵션을 사용합니다. 예를 들어:1mysql --host=192.0.2.2 --network-namespace=red
--network-namespace 옵션이 생략되면, 연결은 기본(default) global namespace를 사용합니다.
CHANGE REPLICATION SOURCE TO 문장을 사용하고 NETWORK_NAMESPACE 옵션을 지정합니다. 예를 들어:1CHANGE REPLICATION SOURCE TO 2 SOURCE_HOST = '192.0.2.2', 3 NETWORK_NAMESPACE = 'red';
NETWORK_NAMESPACE 옵션이 생략되면, 복제 연결은 기본(global) namespace를 사용합니다.
다음 예제는 global, red, blue namespace에서 연결을 listen하는 MySQL 서버를 설정하고, red 및 blue namespace에서 연결하는 계정을 구성하는 방법을 보여줍니다. red 및 blue namespace는 이미 Host System Prerequisites에 설명된 대로 생성되어 있다고 가정합니다.
my.cnf 파일에 추가하고 서버를 시작합니다:1[mysqld] 2bind_address = 127.0.1.1,192.0.2.2/red,198.51.100.2/blue
이 값은 서버에게 global namespace의 loopback 주소 127.0.0.1, red namespace의 주소 192.0.2.2, blue namespace의 주소 198.51.100.2 에서 listen하도록 지시합니다.
1$> mysql -u root -h 127.0.0.1 -p 2Enter password: root_password 3 4mysql> CREATE USER 'red_user'@'192.0.2.2' 5 IDENTIFIED BY 'red_user_password'; 6mysql> CREATE USER 'blue_user'@'198.51.100.2' 7 IDENTIFIED BY 'blue_user_password';
1$> mysql -u red_user -h 192.0.2.2 --network-namespace=red -p 2Enter password: red_user_password 3 4mysql> SELECT USER(); 5+--------------------+ 6| USER() | 7+--------------------+ 8| [email protected] | 9+--------------------+
1$> mysql -u blue_user -h 198.51.100.2 --network-namespace=blue -p 2Enter password: blue_user_password 3 4mysql> SELECT USER(); 5+------------------------+ 6| USER() | 7+------------------------+ 8| [email protected] | 9+------------------------+
참고
USER() 에서 다른 결과가 표시될 수도 있습니다. DNS가 주소를 해당 호스트 이름으로 변환할 수 있도록 구성되어 있고 서버가 skip_name_resolve 시스템 변수를 활성화하지 않고 실행되는 경우, 호스트 이름을 포함하는 값을 반환할 수 있습니다.
또한 --network-namespace 옵션 없이 mysql 을 호출하여 연결 시도가 성공하는지, 그리고 성공한다면 USER() 값이 어떻게 영향을 받는지를 확인해 볼 수도 있습니다.
복제 모니터링 목적을 위해, 다음 정보 소스에는 연결에 적용되는 network namespace를 표시하는 컬럼이 있습니다:
replication_connection_configuration 테이블. Section 29.12.11.12, “The replication_connection_configuration Table”을 참조하십시오.SHOW REPLICA STATUS 문장.7.1.13 IPv6 Support
7.1.15 MySQL Server Time Zone Support