Linux 세미 프로젝트

freshness·2024년 6월 14일
post-thumbnail

문제

Client → WEB LB(SSL) → WAS(NFS) → DB LB → DB(iSCSI, 이중화)

  • 특이사항
    • 문제 구현 시 정방향 구성으로 구현하게 될 경우 뒷 방향의 구성이 안되어 있는 상태로 테스트가 불가할 것이라고 판단해 역방향으로 구현
    • NFS, iSCSI 서버의 경우 처음 vagrant up 시에는 정상적으로 동작하지만 추후 vagrant 를 종료하고 다시 켤 때 프로세스 순서 상 가장 먼저 올라와야할 서비스이기 때문에 낮은 번호의 VM 머신으로 지정해 사용하는 것을 권장
  • 구현 순서
    • IP → DNS → iSCSI → DB(이중화) → DB LB → NFS → WAS → WEB LB → SSL 적용
  • VM 은 Client 포함 총 10대로 구성

IP

  • IP 구성
    • 공통
      • DNS : 192.168.10.200
      • G/W : 192.168.10.1
    • 그 외
      • VM1 (192.168.10.20) - Client
      • VM2 (192.168.10.2) - WEB LoadBalancer
      • VM3 (192.168.10.3) - Web SERVER
      • VM4 (192.168.10.4) - Web SERVER
      • VM5 (192.168.10.5) - DB LoadBalancer
      • VM6 (192.168.10.6) - DB1
      • VM7 (192.168.10.7) - DB2
      • VM8 (192.168.10.8) - NFS
      • VM9 (192.168.10.9) - iSCSI
        • vagrantfile 의 if i == 1if i == 9 로 가상디스크 VM을 9번으로 변경
        • (주의) NFS, iSCSI 서버는 VM1,2 로 놓는 것을 추천
      • VM10 (192.168.10.100) - DNS
  • 구현
    • VM1 부터 10까지 모두 설정(IP는 구성에 맞게 변경)
    • nmcli con add type ethernet ifname eth2 con-name static ipv4.addresses 192.168.10.20/24 ipv4.gateway 192.168.10.1 ipv4.dns 192.168.10.100 ipv4.dns-priority 1 ipv4.method manual
    • nmcli con up static

DNS

  • 목표
    • 모든 IP 대역의 DNS 서버 등록
    • 정방향, 역방향 모두 구현
    • 도메인은 sesac.cloud.com 을 사용
  • 구현
    • yum install -y bind
    • vi /etc/named.conf 설정
      • 변경
        • listen-on port 53 { 127.0.0.1; }; → listen-on port 53 { any; };
        • listen-on-v6 port 53 { ::1; }; → listen-on-v6 port 53 { none; };
        • allow-query { localhost; }; → allow-query { any; };
      • 추가
          57   │ zone "sesac.cloud.com" IN {
          58type master;
          59file "sesac.cloud.zone";
          60};
          6162   │ zone "10.168.192.in-addr.arpa" IN {
          63type master;
          64file "192.168.10.zone";
          65};
      • named-checkconf /etc/named.conf → 무응답 = OK
    • Zone 설정
      • sesac.cloud.zone
        • cp /var/named/named.empty /var/named/sesac.cloud.zone

             1$TTL 3H
             2   │ @   IN SOA  ns.sesac.cloud.com rname.invalid. (
             30   ; serial
             4   │                     1D  ; refresh
             5   │                     1H  ; retry
             6   │                     1W  ; expire
             7   │                     3H )    ; minimum
             8   │     NS  ns.sesac.cloud.com.
             9   │ ns  A   192.168.10.100
            10   │ client  A   192.168.10.20
            11   │ weblb   A   192.168.10.2
            12   │ web1    A   192.168.10.3
            13   │ web2    A   192.168.10.4
            14   │ dblb    A   192.168.10.5
            15   │ db1 A   192.168.10.6
            16   │ db2 A   192.168.10.7
            17   │ nfs A   192.168.10.8
            18   │ iscsi   A   192.168.10.9
        • named-checkzone sesac.cloud.zone /var/named/sesac.cloud.zone → OK

        • chown :named /var/named/sesac.cloud.zone

      • 192.168.10.zone
        • cp /var/named/sesac.cloud.zone /var/named/192.168.10.zone
        • vi /var/named/192.168.10.zone
             1$TTL 3H
             2   │ @   IN SOA  ns.sesac.cloud.com rname.invalid. (
             30   ; serial
             4   │                     1D  ; refresh
             5   │                     1H  ; retry
             6   │                     1W  ; expire
             7   │                     3H )    ; minimum
             8   │     NS  ns.sesac.cloud.com.
             9100 PTR ns.sesac.cloud.com.
            1020  PTR client.sesac.cloud.com.
            112   PTR weblb.sesac.cloud.com.
            123   PTR web1.sesac.cloud.com.
            134   PTR web2.sesac.cloud.com.
            145   PTR dblb.sesac.cloud.com.
            156   PTR db1.sesac.cloud.com.
            167   PTR db2.sesac.cloud.com.
            178   PTR nfs.sesac.cloud.com.
            189   PTR iscsi.sesac.cloud.com.
          • named-checkzone 192.168.10.zone /var/named/192.168.10.zone → OK
          • chown :named /var/named/192.168.10.zone
    • 서비스 시작 및 등록
      • systemctl enable --now named.service
    • 방화벽 설정
      • firewall-cmd --add-service=dns --permanent
      • firewall-cmd --reload

iSCSI

  • 목표

    • 20G 디스크를 각 10G의 용량을 가진 2개의 논리 불륨으로 변환
    • 각각의 논리 볼륨을 DB1, DB2 서버의 /var/lib/mysql 폴더에 마운트
  • 구현 순서

    • 디스크 → 파티셔닝 → 물리 볼륨화 → 볼륨 그룹 생성 → 논리 볼륨 생성
      • 물리 볼륨(2) → 볼륨 그룹(1) → 논리 볼륨(2) 형태로 생성 계획
  • 구현

    • fdisk /dev/sdb → /dev/sdb1 (10G), /dev/sdb2 (10G) 생성

    • pvcreate /dev/sdb1 /dev/sdb2

    • vgcreate basic_vg /dev/sdb1 /dev/sdb2

    • lvcreate -n lv1 -L 10G basic_vg

    • lvcreate -n lv2 -l 2558 basic_vg

      • 10G 생성에 2560의 PE(Physical Extent) 가 필요하지만 2개가 모자라 2558로 논리 볼륨 생성(= 표시되는 용량은 10G)
    • lvdisplay - 논리 볼륨 상태 확인

    • dnf install -y targetcli

    • iSCSI TARGET 설정

      • targetcli
      • iSCSI 1 생성
        • backstores/block create dev=/dev/sdb1 name=block1
        • iscsi/ create wwn=iqn.2024-06.com.cloud.sesac:target1
        • iscsi/iqn.2024-06.com.cloud.sesac:target1/tpg1/acls create wwn=iqn.2024-06.com.cloud.sesac:initiator1
        • iscsi/iqn.2024-06.com.cloud.sesac:target1/tpg1/luns create /backstores/block/block1
      • iSCSI2 는 1의 반복
      • 최종 iSCSI

      • systemctl enable --now target
      • firewall-cmd --add-service=iscsi-target --permanent
      • firewall-cmd --reload
    • iSCSI INITIATOR 설정

      • dnf install -y iscsi-initiator-utils
      • systemctl enable --now iscsi
      • vi /etc/iscsi/initiatorname.iscsi
        • Target 설정에서 acl에 등록한 initiator 이름 입력
        • InitiatorName=iqn.2024-06.com.cloud.sesac:initiator1
      • iscsiadm -m discovery -t st -p 192.168.10.10 - Target과 연결 확인
      • iscsiadm -m node -T iqn.2024-06.com.cloud.sesac:target1 -l
      • lsblk 로 장치 확인
      • 2는 1의 반복
    • iSCSI 장치 /var/lib/mysql 로 마운트 ( DB1, DB2 )
      - fdisk /dev/sdb
      - mkfs -t xfs /dev/sdb1
      - mkdir -p /var/lib/mysql
      - /var/lib/mysql 은 mariadb 설치 후 자동 설치되는 폴더지만 먼저 마운트 하기위해 미리 생성해두고 진행
      - vi /etc/fstab → /dev/sdb1 /var/lib/mysql xfs _netdev 0 0
      - iSCSI 로 장착된 장치는 영구 마운트 시 4번째 옵션을 defaults가 아닌 _netdev로 부여
      - mount -a
      - mount | grep /dev/sdb1 - 마운트 확인

      DB 이중화

    • 목표

      • 데이터베이스 서버를 이중화로 구성
      • WEB 연동을 위해 유저 생성 및 DB, TABLE을 생성
    • 구현

      • MASTER
        • dnf install -y mariadb-server
        • systemctl enable --now mariadb
        • firewall-cmd --add-service=mysql
        • mysql_secure_installation - 초기 보안 설정
        • vi /etc/my.cnf.d/mariadb-server.cnf
          • [mysqld] 섹션 설정
            • autocommit=0
            • server-id=100 ( 임의, 다른 서버와 중복 금지)
            • log-bin=mysql-bin ( 임의 )
        • systemctl restart mariadb
        • mysql -u root -p → 로컬 DB, root 유저로 접속
        • WEB 연동 사전 작업
          • 모든 기준은 index.php 기준으로 작성
          • index.php의 내용 임의 변동 시 직접 관련 세팅 변경 필수
            <?php
            $server_addr = "192.168.10.20";
            $user_name = "web_user";
            $password = "123";
            $db_name = "web_db";
            $connection = mysqli_connect($server_addr, $user_name, $password, $db_name);
            $query = "SELECT * FROM web_tab";
            $rst = mysqli_query($connection, $query);
            
            if (mysqli_num_rows($rst) > 0) {
              while($i = mysqli_fetch_assoc($rst)) {
                echo "id : "  .  $i["id"]  .  " | name : "  .  $i["name"]  .  "<br>" ;
              }
            }
            mysqli_close($connection);
            ?>
            
          • CREATE DATABASE web_db;
          • CREATE TABLE web_tab(id int AUTO_INCREMENT PRIMARY KEY, name VARCHAR(10));
            • desc web_db.web_tab;
            • INSERT INTO web_db.web_tab(name) VALUES ("CHOI");
            • INSERT INTO web_db.web_tab(name) VALUES ("KIM");
          • CREATE USER 'web_user'@'%' IDENTIFIED BY "123";
            • web_user는 모든 IP 에서 접근 가능하며 비밀번호는 123으로 지정
          • GRANT ALL ON web_db.web_tab TO 'web_user'@'%';
            • web_user는 web_db.web_tab에 모든 권한 부여
        • 이중화 세팅
          • GRANT replication slave ON *.* TO 'web_user'@'%';
            • web_user에게 모든 DB, 모든 TABLE에 대한 slave 복제 권한 부여
          • FLUSH PRIVILEGES**;**
          • SHOW MASTER STATUS;
            • FILE, POSITION의 값들은 이후 slave 설정 DB에서 입력하게 된다.
            • FILE ↔ master_log_file // POSITION ↔ master_log_pos
          • mysqldump --all-databases -u root -p > rep.dump
            • MASTER DB 백업
          • scp ./rep.dump vagrant@db2.sesac.cloud.com:/tmp
            • MASTER DB 백업 → SLAVE DB로 이동
      • SLAVE
        • dnf install -y mariadb-server
        • systemctl enable --now mariadb
        • firewall-cmd --add-service=mysql
        • mysql_secure_installation
        • /etc/my.cnf.d/mariadb-server.cnf
          • [mysqld] 섹션 설정
            • autocommit=0
            • server-id=100 ( 임의, 다른 서버와 중복 금지)
            • log-bin=mysql-bin ( 임의 )
            • read-only=1
        • mysql -u root -p < /tmp/rep.dump
          • MASTER DB 백업 복원
        • mysql -u root -p
        • CHANGE MASTER TO master_host='db1.sesac.cloud.com', master_user='web_user', master_password='123', master_log_file='mysql-bin-0000 01', master_log_pos=1519;
          - master_log_file과 master_log_pos는 master 의 status 값에 달라질 수 있다.
        • start slave;
          • 읽기 전용(=read only)일 경우 stop slave 없이 모든 쓰기 작업 불가(백업 등)
          • 별도 작업이 필요할 때 stop slave 후 시작할 것
      • 이중화 연결 확인
        • (MASTER) INSERT INTO web_db.web_tab(name) VALUES ("SHIN");
        • (MASTER) commit;
        • (SLAVE) SELECT * FROM web_db.web_tab;
          • SHIN 이 존재하는 행이 존재하면 OK

DB Load Balancer

  • 목표
    • 로드 밸런서를 통해 접속 시 DB에 접근 가능하도록 한다.
  • 구현
    • dnf install -y haproxy policycoreutils-python-utils
    • vi /etc/haproxy/haproxy.cfg
      • 주요 변경
        • mode http → mode tcp
        • bind :5000 → bind :3306 (mysql port)
        • server app 127.0.0.1:5000 → server db1 db1.sesac.cloud.com:3306
          • app → db1 은 default_backend를 임의 변경했기 때문
      • acl url_static, use_backend static, backend static 전체 라인 삭제
          26   │ defaults
          27   │     mode                    tcp
          43...                    ...
          44#---------------------------------------------------------------------
          45# main frontend which proxys to the backends
          46#---------------------------------------------------------------------
          47   │ frontend main
          48bind *:3306
          49   │     default_backend             db
          5051#---------------------------------------------------------------------
          52# round robin balancing between the various backends
          53#---------------------------------------------------------------------
          54   │ backend db
          55   │     balance     roundrobin
          56   │     server  db1 db1.sesac.cloud.com:3306 check
          57   │     server  db2 db2.sesac.cloud.com:3306 check
    • firewall-cmd --add-port=3306/tcp
    • semanage port -a -t http_port_t 3306 -p tcp
    • 적용 확인
      • dnf install -y mariadb (=클라이언트 전용 패키지)
      • mysql -u web_user -h dblb.sesac.cloud.com -p
        • 로드밸런서 주소를 통해 DB 접근이 가능한지 접속 확인
        • root 사용자는 로컬에서만 접속이 되기 때문에 web_user로 접속

NFS

  • 목표
    • NFS 서버의 디렉토리를 web1, web2 서버로 공유한다.
  • 구현
    • 서버
      • dnf install -y nfs-utils
      • mkdir /seondo
      • vi /etc/exports
        /seondo web1.sesac.cloud.com(rw,sync)
        /seondo web2.sesac.cloud.com(rw,sync)
      • exportfs -r → /etc/exports 갱신
      • systemctl enable --now nfs-server.service
      • firewall-cmd --add-service=nfs
    • 클라이언트 * 2(자동 마운트-직접) ¹
      • dnf install -y nfs-utils autofs
      • vi /etc/auto.master.d/web1.autofs → autofs는 고정, web1은 임의
        • /- /etc/auto.web1
      • vi /etc/auto.web1
        • /var/www/html -rw,sync nfs.sesac.cloud.com:/seondo
      • systemctl enable --now autofs
    • 마운트 확인
      • mount | grep /var/www/html

WEB SERVER

  • 목표
    • 웹 서버를 통해 DB에 있는 테이블 정보를 읽어온다.
    • NFS로 연결한 폴더의 index.php를 web1, web2가 공유하며 웹 서버 연결을 구현
  • 구현
    • dnf install -y httpd php php-mysqlndpolicycoreutils-python-utils
    • systemctl enable --now httpd
    • firewall-cmd --add-service=http
    • semanage boolean -m --on httpd_can_network_connect_db
    • semanage boolean -m --on httpd_use_nfs
    • 웹 서비스 동작 확인
      • curl localhost/index.php

Web LoadBalancer

  • 목표
    • 로드 밸런서를 통해 접속 시 WEB 서버에 접근 가능하도록 한다.
  • 구현
    • dnf install -y haproxy policycoreutils-python-utils
    • vi /etc/haproxy/haproxy.cfg
      • 주요 변경
        • bind :5000→ bind :80
        • server app 127.0.0.1:5000 → server web1 web1.sesac.cloud.com:80
      • acl url_static, use_backend static, backend static 전체 라인 삭제
          39#---------------------------------------------------------------------
          40# main frontend which proxys to the backends
          41#---------------------------------------------------------------------
          42   │ frontend main
          43bind *:80
          44   │     default_backend             web
          45#---------------------------------------------------------------------
          46# round robin balancing between the various backends
          47#---------------------------------------------------------------------
          48   │ backend web
          49   │     balance     roundrobin
          50   │     server  web1 web1.sesac.cloud.com:80 check
          51   │     server  web2 web2.sesac.cloud.com:80 check
    • firewall-cmd --add-port=3306/tcp
    • semanage port -a -t http_port_t 3306 -p tcp
    • 적용 확인
      • curl weblb.sesac.cloud.com/index.php

WEB LoadBalancer SSL 적용

  • 목표
    • WEB LoadBalancer에 SSL을 적용시켜 외부에서 내부로 요청을 보낼 때 암호화된 통신을 할 수 있도록 한다.
  • 구현
    • dnf install -y mod_ssl openssl
    • cd /etc/pki/tls
      • 개인키, csr 등 생성 파일의 경로를 쉽게 지정하기 위해 위 디렉토리에서 작업
    • openssl genrsa -out ./private/private.key 2048
    • openssl req -new -key ./private/private.key -out ./certs/cert.csr
      • csr 생성 시 이름을 Web LoadBalancer의 도메인과 이름을 같게 해주어야 한다.
        • Common Name (eg, your name or your server's hostname) []: weblb.sesac.cloud.com
    • openssl x509 -req -signkey ./private/private.key -in ./certs/cert.csr -out ./certs/cert.crt
    • cat ./private/private.key ./certs/cert.crt > ./cert.pem
      • private key와 cert.crt를 합쳐 cert.pem을 만들어 인증한다.
    • vi /etc/haproxy/haproxy.cfg
        39#---------------------------------------------------------------------
        40# main frontend which proxys to the backends
        41#---------------------------------------------------------------------
        42   │ frontend main
        43bind *:80
        44bind *:443 ssl crt /etc/pki/tls/cert.pem
        45   │     default_backend             web
    • firewall-cmd --add-port=443/tcp
    • systemctl restart haproxy
  • 확인 방법
    • curl --insecure https://weblb.sesac.cloud.com/index.php
      • —insecure : 셀프 인증은 웹에서 정상적으로 동작하지 않기 때문에 인증 절차를 넘기고 이후 프로세스를 진행 ( 443 포트로의 진입은 확인 가능)

¹ 마운트 선택 가이드

  • 간접 - 만들려는 폴더가 먼저 존재하면 안됨
  • 와일드카드 - 서버와 클라이언트 폴더의 이름이 같아야 하며 폴더 전체를 공유

0개의 댓글