Profile picture

[ESXI] ESXI로 SAMBA, NFS, DNS, DB, WEB 서버 구축하기

JaehyoJJAng2023년 06월 03일

네트워크 구성도

image
web 서버와 MySQL 서버는 도커로 올릴 예정.


ESXi 설정

  • 모든 서비스 서버는 CentOS 7 버전에서 운용됨.
  • 윈도우 PC는 클라이언트 전용 PC
  • MySQL / WEB 서버는 Docker로 배포 - Docker-Compose로 설정 파일 관리

1. NGW SSH 설정

외부(맥북)에서 NGW 서버에 접속하여 내부 서버들(NFS,DB 등)에 접근할 것이기 때문에 NGW 서버의 /etc/hosts 파일에 각 서버 이름과 IP를 설정해주도록 하자.

각 서버별 IP는 아래와 같다.

Server IP Address
web 10.11.0.100
nfs 10.11.0.101
db 10.11.0.102
samba 10.11.0.103
dns 10.11.0.104
echo -e "10.11.0.100 web\n10.11.0.101 nfs\n10.11.0.102 db\n10.11.0.103 smb\n10.11.0.104 dns" | tee -a \
/etc/hosts

/etc/hosts의 변경 내용을 적용하기 위해 network 서비스 재시작

$ systemctl restart network

빠른 접속을 위해 NGW 머신에서 SSH 인증키 생성

$ cd ~/.ssh
$ ssh-keygen -t rsa

각 서버에 키 복사

$ for IP in $(seq 100 104); do ssh-copy-id -i ./id_rsa 10.11.0.${IP}; done

2. NGW 랜카드 설정

랜카드 ens192를 static으로 설정

$ cat > /etc/sysconfig/network-scripts/ifcfg-ens192 << EOF
TYPE=Ethernet
BOOTPROTO=none
NAME=ens192
DEVICE=ens192
ONBOOT=yes
IPADDR=192.168.219.140
NETMASK=255.255.255.0
GATEWAY=192.168.219.1
DNS1=8.8.8.8
DNS2=8.8.4.4
EOF

랜카드 ens224(내부망 NIC) 새로 설정

cat > /etc/sysconfig/network-scripts/ifcfg-ens224 << EOF
TYPE=Ethernet
BOOTPROTO=none
NAME=ens224
DEVICE=ens224
ONBOOT=yes
IPADDR=10.11.0.1
NETMASK=255.255.255.0
EOF

3. 서버 포트그룹 지정

  • NGW 머신 제외 모든 서버들은 NIC가 'Internal' 포트그룹에 속해있어야함.

1. NGW 하드웨어 구성
image


2. nfs 하드웨어 구성
image


3. MySQL(db) 하드웨어 구성
image


4. Samba 하드웨어 구성
image


5. dns 하드웨어 구성
image


서버 구성

1. web 서버

NGW 서버의 터미널에서 web 서버로 ssh 접속하자.

root@ngw# ssh web


미리 배포되어있는 도커 이미지를 사용하여 컨테이너를 올려보자.

version: "3.2"

services:
  web:
    image: yshrim12/vm-web:latest
    restart: always
    ports:
      - "80:8000"
    networks:
      - "vm-net"
    environment:
      TZ: "Asia/Seoul"
    container_name: vm-web

networks:
  vm-net:
    driver: bridge
    external: false

컨테이너를 실행해보자.

$ docker-compose up -d --build

컨테이너가 정상적으로 올라왔는지 컨테이너 상태 및 로그를 조회해보자.

$ docker ps
CONTAINER ID   IMAGE                    COMMAND                   CREATED              STATUS              PORTS                                   NAMES
2c9933931aa4   yshrim12/vm-web:latest   "uvicorn main:app --…"   About a minute ago   Up About a minute   0.0.0.0:80->8000/tcp, :::80->8000/tcp   vm-web

$ docker logs vm-web
INFO:     Will watch for changes in these directories: ['/apps']
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [1] using StatReload
ERROR:    Error loading ASGI app. Could not import module "main".

curl 명령으로 웹이 정상적으로 동작하는지 확인하자.

$ curl localhost
"안녕하세요. 메인 페이지입니다"

정상적으로 동작한다.


1-1 웹 포트 개방

  • 타 클라이언트(Windows 10)가 접속할 수 있도록 방화벽을 허용해야 한다.

현재 방화벽의 허용 목록은 아래와 같다

$ firewall-cmd --list-all | grep -A1 "services"
  services: dhcpv6-client ssh
  ports:

포트와 서비스를 허용해주자.

$ firewall-cmd --permanent --zone=public --add-port=80/tcp
success
$ firewall-cmd --permanent --zone=public --add-service=http
success
$ firewall-cmd --reload

2. db 서버

NGW 서버의 터미널에서 db 서버로 ssh 접속하자.

root@ngw# ssh db

db 서버도 웹서버와 마찬가지로 도커 환경에서 MySQL 서비스를 올릴 것이므로 도커를 설치해줘야 한다.

위 포스팅을 참고하여 도커를 설치해주도록 하자.


도커 설치가 정상적으로 끝났다면 MySQL을 배포하기 위해 docker-compose.yaml을 작성하도록 하자.

version: "3.2"

services:
  mysql:
    image: mysql:latest
    restart: always
    volumes:
      - type: volume
        source: "mysql-data"
        target: "/var/lib/mysql"
      - type: volume
        source: "mysql-log"
        target: "/var/log/mysql"
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      TZ: "Asia/Seoul"
    networks:
      - "db-network"
    container_name: mysql

volumes:
  mysql-data: {}
  mysql-log: {}

networks:
  db-network:
    driver: bridge
    external: false

yaml 작성이 끝났다면 컨테이너를 생성해보자.

$ docker-compose up -d --build

컨테이너가 정상적으로 배포됐는지 확인

$ docker-compose ps --services mysql
mysql

2-1. DB 포트 개방

타 서버에서 DB 접근을 위해 MySQL(3306) 포트를 개방해줘야 한다.

$ firewall-cmd --permanent --zone=public --add-service=mysql
$ firewall-cmd --permanent --zone=public --add-port=3306/tcp
$ firewall-cmd --reload

3. Samba 서버

NGW 서버의 터미널에서 samba 서버로 ssh 접속하자.

root@ngw# ssh samba

Samba 설치

samba 패키지 설치

$ yum install -y samba

공유 폴더 생성

$ mkdir -p /var/samba/share
$ chmod 777 -R /var/samba/share

samba 유저 생성

$ adduser smb
$ passwd smb
$ smbpasswd -a smb

삼바 설정 (/etc/samba/smb.conf)

# 맨 아래에 이어 붙이기
$ cat >> /etc/samba/smb.conf << EOF
[share]
        comment = Share Directory # 설명(주석)
        path = /var/samba/share # 경로
        browserable = yes # yes = 모두가 읽을 수 있음, no = 허가된 사용자만
        writable = yes # yes = 모두가 저장할 수 있음, no = 허가된 사용자만
        valid users = smb # 인가된 사용자
        create mask = 0777 # 파일을 만들면 자동으로 777권한을 부여
        directory mask = 0777 # 폴더를 만들면 자동으로 777권한을 부여
EOF

smb 서비스 재시작

$ systemctl enable --now smb.service
$ systemctl enable --now nmb.service

3-1 삼바 포트 개방

타 서버에서 smb 서비스 접근을 위해 samba 서비스를 개방해줘야 한다.

$ firewall-cmd --permanent --zone=public --add-service=samba
$ firewall-cmd --reload

4. NFS 서버

NGW 서버의 터미널에서 nfs 서버로 ssh 접속하자.

root@ngw# ssh nfs

패키지 업데이트

yum update -y

NFS에 필요한 패키지 설치

yum install -y nfs-utils

마운트 포인트 생성

# 디렉토리 생성
mkdir -p /var/nfs/share

# 권한 수정
chmod 707 /var/nfs/share

10.11.0.0/24 대역만 nfs 폴더를 마운트 할 수 있도록 /etc/exports 파일에 아래 내용 추가

cat >> /etc/exports << EOF
/var/nfs/share 10.11.0.0/24(rw,sync)
EOF

nfs 설정 파일 편집
아래 서비스들 주석 해제

  • LOCKD_TCPPORT = 3280322
  • LOCKD_UDPPORT = 3276957
  • MOUNTD_PORT = 89263
  • STATD_PORT = 662
sed -i '/^#LOCKD_TCPPORT/s/^#//' /etc/sysconfig/nfs
sed -i '/^#LOCKD_UDPPORT/s/^#//' /etc/sysconfig/nfs
sed -i '/^#MOUNTD_PORT/s/^#//' /etc/sysconfig/nfs
sed -i '/^#STATD_PORT/s/^#//' /etc/sysconfig/nfs

nfs-server 재시작

systemctl restart nfs-server

/etc/exports 파일 내용 적용

exportfs -r

exportfs 적용 내용 출력 및 포트 확인

# exports 적용 내용 확인
$ exportfs -v 
/var/nfs/share	10.11.0.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)

# rpcbind가 사용중인 포트 출력
$ rpcinfo -p  
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp    662  status
    100024    1   tcp    662  status
    100005    1   udp    892  mountd
    100005    1   tcp    892  mountd
    100005    2   udp    892  mountd
    100005    2   tcp    892  mountd
    100005    3   udp    892  mountd
    100005    3   tcp    892  mountd
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    3   udp   2049  nfs_acl
    100021    1   udp  32769  nlockmgr
    100021    3   udp  32769  nlockmgr
    100021    4   udp  32769  nlockmgr
    100021    1   tcp  32803  nlockmgr
    100021    3   tcp  32803  nlockmgr
    100021    4   tcp  32803  nlockmgr

4-1 nfs 포트 개방

# TCP: 111,892,2049,32803
firewall-cmd --permanent --zone=public --add-port=111/tcp
firewall-cmd --permanent --zone=public --add-port=892/tcp
firewall-cmd --permanent --zone=public --add-port=2049/tcp
firewall-cmd --permanent --zone=public --add-port=32803/tcp

# UDP: 111,892,2049,32769
firewall-cmd --permanent --zone=public --add-port=111/udp
firewall-cmd --permanent --zone=public --add-port=892/udp
firewall-cmd --permanent --zone=public --add-port=2049/udp
firewall-cmd --permanent --zone=public --add-port=32803/udp

# 방화벽 재시작
firewall-cmd --reload

5. DNS 서버

NGW 서버의 터미널에서 dns 서버로 ssh 접속하자.

root@ngw# ssh dns

bind 설치

$ yum install -y bind bind-chroot bind-utils

DNS 설정
/etc/named.conf 파일의 내용 전부 지우고 아래 내용으로 붙여넣기

$ cat > /etc/named.conf << EOF
options {
        listen-on port 53 { 127.0.0.1; [퍼블릭 대역폭]; [프라이빗 대역폭]; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { localhost; [퍼블릭 대역폭]; [프라이빗 대역폭]; };
        forwarders { 8.8.8.8; 8.8.4.4; }; 					

        recursion yes;

        dnssec-enable yes;
        dnssec-validation yes;

        /* Path to ISC DLV key */
        bindkeys-file "/etc/named.iscdlv.key";

        managed-keys-directory "/var/named/dynamic";

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};
view "internal" {
        zone "." IN {
                type hint;
                file "named.ca";
        };

        include "/etc/named.rfc1912.zones";
        include "/var/named/[원하는 도메인명].shop.zones";
};
EOF

image


/var/named 경로에 zones 설정

/var/named/[위에서 설정한 도메인명].shop.zones

$ cat > /var/named/jaehyo.shop.zones << EOF
zone "[설정한 도메인명]" IN {
        type master;
        file "[설정한 도메인명].shop.db";
        allow-update { none; };		
};

zone "[프라이빗 대역폭 역주소].in-addr.arpa" IN {
        type master;
        file "[프라이빗 대역폭 역주소].in-addr.arpa.db";
        allow-update { none; };	
};
EOF

image


Zone 파일 생성

/var/named/[설정한 도메인명].shop.db

$ cat > /var/named/jaehyo.shop.db << EOF
$TTL    86400	
@       IN      SOA     [설정한 도메인].shop.   root.[설정한 도메인].shop.(
                        2022041401 ; Serial
                        3h         ; Refresh
                        1h         ; Retry
                        1w         ; Expire
                        1h )       ; Minimum

        IN      NS      ns.[설정한 도메인].shop.
        IN      MX 10   ns.[설정한 도메인].shop.
ns      IN      A       [DNS 서버 주소]
web   IN      A         [WEB 서버 주소]
EOF

image


/var/named/[프라이빗 역주소].in-addr.arpa.db

$ cat > /var/named/0.11.10.in-addr.arpa.db << EOF
$TTL    86400
@       IN      SOA     [설정 도메인].shop. root.[설정 도메인].shop.(
                        2022041401 ; Serial
                        3h         ; Refresh
                        1h         ; Retry
                        1w         ; Expire
                        1h )       ; Minimum

        IN      NS      ns.[설정 도메인].shop.
[끝주소]     IN      PTR     ns.[설정 도메인].shop.
[끝주소]     IN      PTR     web.[설정 도메인].shop.
EOF

image


named.conf 유효성 체크

$ named-checkconf /etc/named.conf
$ named-checkconf /var/named/jaehyo.shop.db
$ named-checkconf /var/named/jaehyo.shop.zones

명령어 입력 시 아무 내용이 출력되지 않는다면 문제가 없음.


named 서비스 재기동

systemctl enable --now named.service

5-1 dns 포트 개방

firewall-cmd --permanent --add-service=dns
firewall-cmd --reload

서버 테스트

1. WEB 접속 테스트

1. 윈도우 클라이언트에서 내부 웹 서버(10.11.0.100:80/)에 접속
image


2. 윈도우 클라이언트에서 내부 웹 서버(10.11.0.100:80/conn)에 접속
image


2. DB 접속 테스트

web 서버에서 /conn 경로로 curl 요청 보내보기
(db 접속 로직이며 db가 정상적으로 동작한다면 'db connection completed!' 메시지를 리턴함)

[root@web apps]# curl localhost/conn
{"message":"20231113 18:35 - DB connection completed!"}

3. Samba 테스트

윈도우 10에서 Samba를 이용한 파일 공유 테스트를 진행해보자.

검색창에 "\\[samba 서버 주소]"로 검색
\\[10.11.0.104]
image
image


로그인 정보를 입력하고 나면 삼바 서버의 공유 폴더를 정상적으로 사용할 수 있게된다.
image


share 폴더에 loveme.txt 파일을 생성해보자.
image
image


4. NFS 테스트

NGW 서버의 터미널에서 web(nfs client) 서버로 ssh 접속하자.

root@ngw# ssh web

NFS 설치

yum install -y nfs-utils

마운트 정보 확인(nfs 서버: 10.11.0.103)

[root@web ~]# showmount -e 10.11.0.103
Export list for 10.11.0.103:
/var/nfs/share 10.11.0.0/24

마운트 포인트 생성

$ mkdir -p /var/web/share

nfs 서버의 /var/nfs/share 폴더를 웹서버의 /var/web/share 폴더와 마운트

$ mount -t nfs 10.11.0.103:/var/nfs/share /var/web/share

df 명령어로 마운트 등록됐는지 확인

$ df -h  | tail -n 1
10.11.0.103:/var/nfs/share   10G  1.6G  8.5G  16% /var/web/share

/etc/fstab에 마운트 정보 등록

cat >> /etc/fstab << EOF
10.11.0.103:/var/nfs/share /var/web/share nfs defaults 0 0
EOF

web 서버의 /var/web/share 폴더에 'loveme.txt' 텍스트 파일 생성

touch /var/web/share/loveme.txt 

nfs 서버로 ssh 접속 후 /var/nfs/share 폴더로가서 loveme.txt 파일이 있는지 확인

# nfs 서버 접속
ssh root@10.11.0.103

# 파일 확인
ls -lh /var/nfs/share/

image


5. DNS 테스트

  • 1번 ~ 5번 과정은 NGW 서버에서 진행

1. NAT 서버(NGW 머신)에서 DNS 재설정

# dhcpd에서 내부망 DNS 서버 주소 추가하기
$ vi /etc/dhcp/dhcpd.conf

//
option domain-name-servers [DNS서버 주소], 8.8.8.8, 8.8.4.4;
//

image


2. dhcp 재기동

systemctl restart dhcpd

3. 외부망 NIC(ens192)에 내부 DNS 서버 주소 추가

$ vi /etc/sysconfig/network-scripts/ifcfg-ens192

// 중간에 DNS1 바꾸고 나머지 뒤로
IPADDR=192.168.219.140
NETMASK=255.255.255.0
GATEWAY=192.168.219.1
DNS1=10.11.0.105
DNS2=8.8.8.8
DNS3=8.8.4.4
//

4. 네트워크 및 dhcpd 재시작

systemctl restart network
systemctl restart dhcpd

5. 도메인으로 핑 테스트

$ ping -c 2 ns.jaehyo.shop
PING ns.jaehyo.shop (10.11.0.105) 56(84) bytes of data.
64 bytes from dns (10.11.0.105): icmp_seq=1 ttl=64 time=0.184 ms
64 bytes from dns (10.11.0.105): icmp_seq=2 ttl=64 time=0.214 ms

--- ns.jaehyo.shop ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.184/0.199/0.214/0.015 ms

성공적으로 도메인과 통신.


6. DNS 서버(dns,10.11.0.105)에서 테스트

# dhcp 재할당을 위해 네트워크 매니저 재시작
systemctl restart NetworkManager

# 도메인으로 핑 테스트
ping -c 2 ns.jaehyo.shop
PING ns.jaehyo.shop (10.11.0.105) 56(84) bytes of data.
64 bytes from ns.jaehyo.shop (10.11.0.105): icmp_seq=1 ttl=64 time=0.029 ms
64 bytes from ns.jaehyo.shop (10.11.0.105): icmp_seq=2 ttl=64 time=0.040 ms

--- ns.jaehyo.shop ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.029/0.034/0.040/0.008 ms

7. 웹 서버(web,10.11.0.100)에서 테스트

# 네트워크 매니저 재시작
systemctl restart NetworkManager

# 내부 DNS 주소 할당 확인
cat /etc/resolv.conf
nameserver 10.11.0.105
nameserver 8.8.8.8
nameserver 8.8.4.4

# 도메인으로 핑 테스트
ping -c 2 ns.jaehyo.shop
PING ns.jaehyo.shop (10.11.0.105) 56(84) bytes of data.
64 bytes from ns.jaehyo.shop (10.11.0.105): icmp_seq=1 ttl=64 time=0.161 ms
64 bytes from ns.jaehyo.shop (10.11.0.105): icmp_seq=2 ttl=64 time=0.210 ms

--- ns.jaehyo.shop ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.161/0.185/0.210/0.028 ms

8. 윈도우 10에서 DNS 주소로 접속해보기
image
정상적으로 접근 완료


Loading script...