[TIP] Docker 룰이 포함된 iptables 룰 저장 및 복구

리눅스/DNS|2022. 12. 22. 16:53
반응형

[TIP] Docker 룰이 포함된 iptables 룰 저장 및 복구

 

iptables 기본 룰에서 docker 컨테이너등을 실행하면 컨테이너가 사용하는 포트의 연결을 위해

자동으로 iptables 룰이 추가됩니다.

하지만 iptables 룰을 잘못 수정하였다가 컨테이너 서비스가 먹통 되는 일이 생기는데 이를 방지하기 위해

iptables 룰을 주기적으로 저장해 두어야 합니다.

 

-----------------------------------

# iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-USER  all  --  0.0.0.0/0            0.0.0.0/0           
DOCKER-ISOLATION-STAGE-1  all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (2 references)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            192.168.96.2         tcp dpt:3306
ACCEPT     tcp  --  0.0.0.0/0            192.168.96.3         tcp dpt:443
ACCEPT     tcp  --  0.0.0.0/0            192.168.96.4         tcp dpt:9000
ACCEPT     tcp  --  0.0.0.0/0            192.168.96.3         tcp dpt:80

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0           
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0           
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-USER (1 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           

-----------------------------------

 

현재 iptables 룰 저장

# iptables-save > iptables_20221222.rules

 

백업한 iptables 룰 복원

# iptables-restore < iptables_20221222.rules

 

혹시 백업해둔 룰이 없을땐 서비스 중지를 감수하고 docker 를 재시작 하면 컨테이너가 구동되면서 iptables 룰이 재구성 됩니다.

# systemctl restart docker

 

반응형

댓글()

5. Docker 이미지 생성 (컨테이너 현재 상태 저장)

반응형

5. Docker 이미지 생성 (컨테이너 현재 상태 저장)

 

php 컨테이너의 경우 라이브러리 등을 추가 설치하고 docker compose down 및 up -d 명령을 사용하여 컨테이너를 재가동 하면

컨테이너에 설치한 라이브러리 파일이 초기화 되어져 다시 라이브러리를 설치하고 php 컨테이너를 재시작 해주어야 합니다.

이런 번거로움을 줄이기 위해서 라이브러리 설치 후 아래와 같이 컨테이너의 마지막 상태를 이미지로 저장할 수 있습니다.

 

실행중인 php 컨테이너를 중지합니다.

# docker compose stop php

중지한 php 컨테이너의 ID 를 확인 합니다.

# docker ps -a |grep php |awk {'print $1'}
891757604a66

중지한 컨테이너 ID 값을 이용하여 새로운 이미지를 만듭니다.

# docker commit 891757604a66 php:8.2.0-fpm_update1
sha256:1e7354a1a3030c6cf7e842f200bb3c9319e99fc700f68f8b363410b5a8e48c64

 

생성된 이미지 리스트를 확인합니다.

# docker images
REPOSITORY   TAG                 IMAGE ID       CREATED          SIZE
php          8.2.0-fpm_update1   1e7354a1a303   11 minutes ago   450MB
php          8.2.0-fpm           51dbab2b7efc   13 days ago      450MB
mysql        8.0.31              7484689f290f   2 weeks ago      538MB
httpd        2.4.54              157dcdf23d6c   2 weeks ago      145MB


다음 php 컨테이너를 생성할때 새로운 이미지 기반으로 생성하도록 합니다.

# vi docker-compose.yml

...
    php:
        image: php:8.2.0-fpm_update1
...


이제 php 컨테이너를 삭제 해도 이미지 기반으로 생성 및 구동할때, 이미 이전에 설치한 라이브러리가 있는것을 확인 할 수 있습니다.

 

반응형

댓글()

4. Docker PHP 환경 설정 및 MySQL 연동, 기타 라이브러리 활성화

반응형

4. Docker PHP 환경 설정하기 (php.ini)

 

1) PHP 환경 설정 방법

 

php 컨테이너 내의 설정 파일 (php.ini) 를 호스트 서버로 복사하고 호스트 서버의 php.ini 파일을 사용하도록 해야 합니다.

컨테이너가 구동중인 상태에서 아래와 같이 파일을 복사 합니다.

 

php 컨테이너의 /usr/local/etc/php/php.ini-development 파일을 /home/sysdocu/php/conf/ 디렉토리 아래에 php.ini 이름으로 복사.

# mkdir -p /home/sysdocu/php/conf

# docker cp php:/usr/local/etc/php/php.ini-development /home/sysdocu/php/conf/php.ini

 

기본적으로 소스내 PHP 태그없이도 코드 인식이 가능하도록하고 한국 표준시를 출력하도록 설정합니다.

# vi /home/sysdocu/php/conf/php.ini

short_open_tag = On
date.timezone = "Asia/Seoul"

 

호스트 서버에서 php.ini 파일을 사용할 수 있도록 docker-compose.yml 파일을 수정합니다.

# vi docker-compose.yml

...
    php:
        image: php:8.2.0-fpm
        container_name: php
        restart: unless-stopped
        ports:
            - "9000:9000"
        volumes:
            - /home/sysdocu/httpd/html:/var/www/html
            - /home/sysdocu/php/conf/php.ini:/usr/local/etc/php/php.ini
        command:
            - /bin/sh
            - -c
            - |
              echo "security.limit_extensions = .html .htm .php" >> /usr/local/etc/php-fpm.d/www.conf
              php-fpm

...

 

변경된 컨테이너를 적용합니다.

# docker compose stop php
# docker rm -v php
# docker compose up -d php

 

2) mysql 연동 및 테스트

 

php 컨테이너에서 docker-php-ext-install 명령을 이용해 필요한 라이브러리를 설치해줍니다. (mysqli.so 파일 생성)

# docker exec -it php /bin/bash

root@8e2d3bf1c94f:/var/www/html# docker-php-ext-install mysqli

 

호스트 서버에서 설정 파일을 열고 아래 행을 주석 해제 합니다.

# vi /home/sysdocu/php/conf/php.ini

extension=mysqli

 

변경 사항을 적용합니다.

# docker compose restart php

 

웹 소스를 수정하여 MySQL 연동이 잘 되는지 테스트 해봅니다.

아래 소스 코드를 이용하여 작성한 뒤 웹브라우저에서 접근하면 확인이 가능합니다.

 

# vi /home/sysdocu/httpd/html/index.html

MySQL Connect TEST<br>
<?
$conn = mysqli_connect("mysql", "sysdocu", "12345678", "sysdocudb"); # 여기에서 mysql 은 컨테이너 이름

if ($conn) {
    echo "MySQL 연결 성공";
} else {
    echo "MySQL 연결 실패";
}

$result = mysqli_query($conn, "SELECT VERSION() AS VERSION");
$data = mysqli_fetch_assoc($result);
echo "<br>Version : " . $data['VERSION'];
?>

 

3) 기타 라이브러리 활성화

 

주로 사용하는 curl, gd, mbstring, openssl 라이브러리를 활성해 보겠습니다.

(사실 gd 만 추가 설치, 나머지는 재설치 과정)

mysqli 설치하는 방법과 같이 컨테이너에 접근하여 라이브러리를 설치하면 되지만,

그냥 설치 명령을 내리면 컨테이너에 필요한 패키지가 없다며 에러가 출력되므로

사전에 필요한 패키지를 설치하고 라이브러리 설치를 진행합니다.

# docker exec -it php /bin/bash

 

제일 먼저 리포지토리를 정리해야 패키지 설치가 잘 되므로 업데이트를 해줍니다.

root@8e2d3bf1c94f:/var/www/html# apt -y update

 

(curl 라이브러리 설치)

root@8e2d3bf1c94f:/var/www/html# apt -y install libcurl4-openssl-dev

root@8e2d3bf1c94f:/var/www/html# docker-php-ext-install curl

 

(gd 라이브러리 설치)

root@8e2d3bf1c94f:/var/www/html# apt -y install zlib1g-dev libpng-dev

root@8e2d3bf1c94f:/var/www/html# docker-php-ext-install gd

gd 는 기본 허용 모듈에서 빠져 있기 때문에 사용을 위해 아래와 같이 추가 구성해줍니다.

root@8e2d3bf1c94f:/var/www/html# docker-php-ext-configure --with-gd

 

(mbstring 라이브러리 설치)

root@8e2d3bf1c94f:/var/www/html# apt -y install libonig-dev

root@8e2d3bf1c94f:/var/www/html# docker-php-ext-install mbstring

 

(openssl 라이브러리 설치)

root@8e2d3bf1c94f:/var/www/html# cd /usr/src/php/ext/openssl
root@233900ce6ef9:/usr/src/php/ext/openssl# cp config0.m4 config.m4
root@233900ce6ef9:/usr/src/php/ext/openssl# phpize
root@233900ce6ef9:/usr/src/php/ext/openssl# # apt -y install libssl-dev
root@233900ce6ef9:/usr/src/php/ext/openssl# docker-php-ext-install openssl

 

라이브러리 설치 완료 후 php 컨테이너를 재시작 하면 phpinfo 화면에서 설치한 모듈이 보여지게 됩니다.

# docker compose restart php

# docker exec php php -i |grep -i gd

 

반응형

댓글()

3. Docker MySQL 환경 설정 및 DB, 사용자 계정 생성

반응형

3. Docker MySQL 환경 설정 및 DB, 사용자 계정 생성

 

1) MySQL 환경 설정 방법

 

MySQL 컨테이너 내의 data 디렉토리와 my.cnf 설정 파일을 호스트 서버로 복사해오면 데이터 및 설정 관리가 수월해 집니다.

컨테이너가 구동중인 상태에서 아래와 같이 파일을 복사 합니다.

 

mysql 컨테이너의 /var/lib/mysql 디렉토리를 /home/sysdocu/mysql/data 디렉토리로 복사

# mkdir /home/sysdocu/mysql
# docker cp mysql:/var/lib/mysql/ /home/sysdocu/mysql/

# mv /home/sysdocu/mysql/mysql /home/sysdocu/mysql/data

 

mysql 컨테이너의 my.cnf 파일을 /home/sysdocu/mysql/conf/my.cnf 로 복사

# mkdir /home/sysdocu/mysql/conf
# docker cp mysql:/etc/my.cnf /home/sysdocu/mysql/conf/my.cnf

 

호스트 서버에서 변경사항을 적용할 수 있도록 docker-compose.yml 파일을 수정합니다.

# vi docker-compose.yml

...
    mysql:
        image: mysql:8.0.31
        container_name: mysql
        restart: unless-stopped
        tty: true
        ports:
            - "3306:3306"
        environment:
            MYSQL_HOST: localhost
            MYSQL_ROOT_PASSWORD: 12345678 # 초기 mysql root 비밀번호
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
            TZ: Asia/Seoul
        volumes:
            - /home/sysdocu/mysql/data/:/var/lib/mysql/
            - /home/sysdocu/mysql/conf/my.cnf:/etc/my.cnf
...

 

변경된 컨테이너를 적용합니다.

# docker compose stop mysql
# docker rm -v mysql
# docker compose up -d mysql

 

my.cnf 변경사항이 잘 적용되는지 확인해 봅니다.

# vi /home/sysdocu/mysql/conf/my.cnf

[mysqld]
max_connections = 10000

 

# docker compose restart mysql

 

MySQL 에 접근하여 변경된 값을 확인합니다.

# docker exec -it mysql /bin/bash
bash-4.4# mysql -u root -p
Enter password: (docker-compose.yml 에서 설정한 root 비밀번호 입력)

 

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 10000 |
+-----------------+-------+
1 row in set (0.00 sec)

 

2) DB, 사용자 계정 생성

 

MySQL 에 접근하여 DB, 사용자 계정 생성 및 권한을 할당 합니다.

(암호화 방식은 기본값인 caching_sha2_password 로 정함)

 

# docker exec -it mysql /bin/bash
bash-4.4# mysql -u root -p
Enter password: (docker-compose.yml 에서 설정한 root 비밀번호 입력)

 

mysql> create databases sysdocudb;

mysql> create user 'sysdocu'@'localhost' identified with caching_sha2_password by '12345678';
mysql> grant all privileges on sysdocudb.* to 'sysdocu'@'localhost'; 
mysql> grant grant option on sysdocudb.* to 'sysdocu'@'localhost'; 
mysql> flush privileges;

 

컨테이너 밖에서 접근을 하면 (호스트 서버 또는 다른 컨테이너) 외부 IP 에서 접근한 것으로 간주하기 때문에

접근 호스트명만 바꿔서 동일한 계정으로 추가 생성 해줍니다.

 

mysql> create user 'sysdocu'@'%' identified with caching_sha2_password by '12345678';
mysql> grant all privileges on sysdocudb.* to 'sysdocu'@'%'; 
mysql> grant grant option on sysdocudb.* to 'sysdocu'@'%'; 
mysql> flush privileges;

 

3) MySQL root 패스워드 변경

 

추후 MySQL root 패스워드를 변경하고자 할 경우 mysql 로그인 후 아래와 같이 쿼리를 실행하면 됩니다.

mysql> use mysql;

mysql> alter user root@localhost identified by 'NEWPASSWD';

mysql> alter user root@'%' identified by 'NEWPASSWD';

mysql> flush privileges; 

 

4) data dump 방법

 

DB 를 운영하면서 백업은 필수 진행해야 합니다.

호스트 서버의 data 디렉토리를 압축해도 되지만, mysqldump 명령으로 백업하고자 할때는

아래와 같이 실행하여 간단히 백업을 할 수 있습니다.

 

# docker exec mysql /usr/bin/mysqldump -u root -p12345678 sysdocudb > sysdocudb.sql

 

 

 

 

반응형

댓글()

2. Docker httpd 환경 설정하기 (PHP 연동, Virtualhost 및 SSL 적용)

반응형

2. Docker httpd 환경 설정하기 (PHP 연동, Virtualhost 및 SSL 적용)

 

1) httpd 기본 환경 설정 방법

httpd 컨테이너 내의 설정 파일 (conf) 를 호스트 서버로 복사하고 호스트 서버의 conf 디렉토리를 사용하도록 해야 합니다.

컨테이너가 구동중인 상태에서 아래와 같이 파일을 복사 합니다.

 

httpd 컨테이너의 /usr/local/apache2/conf 디렉토리를 /home/sysdocu/httpd/ 디렉토리 아래로 복사.

# docker cp httpd:/usr/local/apache2/conf/ /home/sysdocu/httpd/

 

호스트 서버에서 httpd 에 대한 conf 설정과 logs 확인이 가능하도록 docker-compose.yml 파일을 수정합니다.

그리고 아래 SSL 인증서 사용을 위해 호스트 서버와 컨테이너의 포트 (443) 도 연결 설정을 해줍니다.

# vi docker-compose.yml

...
    httpd:
        image: httpd:2.4.54
        container_name: httpd
        restart: unless-stopped
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - /home/sysdocu/httpd/html/:/usr/local/apache2/htdocs/
            - /home/sysdocu/httpd/conf/:/usr/local/apache2/conf/
            - /home/sysdocu/httpd/logs/:/usr/local/apache2/logs/
...

 

변경된 컨테이너를 적용합니다.

# docker compose stop httpd
# docker rm -v httpd
# docker compose up -d httpd

 

 

2) PHP 연동

 

PHP 연동에 필요한 httpd 모듈을 활성화 합니다.

# vi /home/sysdocu/httpd/conf/httpd.conf

LoadModule deflate_module /usr/local/apache2/modules/mod_deflate.so    # 주석 해제
LoadModule proxy_module /usr/local/apache2/modules/mod_proxy.so    # 주석 해제
LoadModule proxy_fcgi_module /usr/local/apache2/modules/mod_proxy_fcgi.so    # 주석 해제
...
# 아래 확장자는 php 컨테이너로 포워딩 처리
ProxyPassMatch ^/(.*\.html(/.*)?)$ fcgi://php:9000/var/www/html/$1    # 추가
ProxyPassMatch ^/(.*\.htm(/.*)?)$ fcgi://php:9000/var/www/html/$1    # 추가
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
    # 추가

 

설정 적용을 위해 httpd 컨테이너를 재시작 합니다.

# docker compose restart httpd

 

3) virtualhost 설정

 

아래 파일에서 virtualhost 부분을 사용할 수 있도록 주석 제거하고 virtualhost 설정 파일을 수정합니다.

# vi /home/sysdocu/httpd/conf/httpd.conf

<Directory />
    AllowOverride none
    Require all granted    # 수정
</Directory>

Include conf/extra/httpd-vhosts.conf    # 주석 해제

 

# vi /home/sysdocu/httpd/conf/extra/httpd-vhosts.conf

<VirtualHost *:80>
    DocumentRoot "/home/sysdocu/httpd/html"
    ServerName sysdocu.tistory.com
    ErrorLog "logs/sysdocu.tistory.com-error_log"
    CustomLog "logs/sysdocu.tistory.com-access_log" common
</VirtualHost>

 

컨테이너 재시작 후 웹브라우저에서 잘 출력되는지 다시 확인해봅니다.

# docker compose restart httpd

 

('403 Forbidden' 에러가 출력될 경우)

/home/sysdocu 와 같이 홈 소스 디렉토리가 있는지 확인하고 접근 권한 (퍼미션 755) 을 확인해 봅니다.

 

4) SSL 발급 및 설정

 

준비된 SSL 인증서가 없으므로 Let's encrypt 에서 발급받아 사용해 봅니다.

https://sysdocu.tistory.com/1546

 

인증서 파일을 발급 받았으면 컨테이너에서 인증서 파일 인식이 가능하도록 복사해 줍니다.

# mkdir /home/sysdocu/httpd/conf/ssl
# cp -arp /etc/letsencrypt/archive/sysdocu.tistory.com /home/sysdocu/httpd/conf/ssl/

 

httpd 설정 파일을 아래와 같이 수정합니다.

# vi /home/sysdocu/httpd/conf/httpd.conf

LoadModule ssl_module modules/mod_ssl.so    # 주석 해제
Include conf/extra/httpd-ssl.conf    # 주석 해제

 

# vi /home/sysdocu/httpd/conf/extra/httpd-ssl.conf

#SSLSessionCache        "shmcb:/usr/local/apache2/logs/ssl_scache(512000)"    # 주석 처리
#SSLSessionCacheTimeout  300    # 주석 처리

<VirtualHost *:443>
DocumentRoot /home/sysdocu/httpd/html
ServerName sysdocu.tistory.com:443
...
SSLEngine on
SSLCertificateFile conf/ssl/sysdocu.tistory.com/cert1.pem
SSLCertificateKeyFile conf/ssl/sysdocu.tistory.com/privkey1.pem
SSLCertificateChainFile conf/ssl/sysdocu.tistory.com/fullchain1.pem
</VirtualHost>

 

설정 적용을 위해 컨테이너를 재시작하면 웹브라우저에서 https 로 접근하여 인증서 확인이 가능합니다.

# docker compose restart httpd

 

반응형

댓글()

1. Ubuntu 22.04 에서 Docker 사용하기 (APM 기본 설치)

반응형

 

[ Docker 설치 ]

1. 패키지 목록 최신화 및 업그레이드
# apt -y update

# apt -y upgrade
# apt -y install apt-transport-https ca-certificates curl gnupg lsb-release

2. Docker 공식 GPG 설치
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg |gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

3. Docker 공식 저장소 추가
# echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" |tee /etc/apt/sources.list.d/docker.list > /dev/null

4. Docker 설치 및 확인

# apt -y update
# apt -y install docker-ce docker-ce-cli containerd.io
# docker --version

5. Compose 설치 및 확인

도커 컨테이너 구동 명령시 옵션으로 환경 값을 줄 수 있는데, 이경우 명령 라인이 길어지는 불편함이 있습니다.

docker-compose 는 이런 불편함을 없애고, 미리 준비한 환경을 파일(.yml) 을 사용하며 여러 컨테이너를 한 번에 관리할 수 있습니다.

 

1) Plugin 형태로 사용할 경우 (매뉴얼 진행 형태)
# apt -y install docker-compose-plugin
# docker compose version

 

2) Standalone 형태로 사용할 경우
# curl -SL https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# docker-compose --version

 


[ Docker 삭제 ]

1. Docker 관련 패키지를 제거
# apt purge docker-ce docker-ce-cli containerd.io

2. 호스트의 이미지, 컨테이너, 볼륨 또는 사용자 지정 구성파일 제거 (모든 이미지, 컨테이너 및 볼륨 수동 삭제)
# rm -rf /var/lib/docker
# rm -rf /var/lib/containerd

 


[ APM 설치 ]

1. 설치 및 확인
특정 버전을 명시하지 않으면 최신 버전의 이미지가 다운로드 됩니다.
사용 예) docker pull {이미지}:{버전}
# docker pull httpd:2.4.54
# docker pull php:8.2.0-fpm
# docker pull mysql:8.0.31

 

다운로드 된 이미지 리스트를 출력합니다.

# docker images

 

(기타 명령 - 설치)

# docker search mysql    // 다운로드 가능한 이미지 출력

# docker pull mysql         // mysql:8.0.31 와 같이 특정 버전을 지정하지 않으면 최신 버전이 설치됩니다.

                                           (mysql 또는 mysql:latest)

                                           아래 URL 에서 제공하는 버전을 확인 할 수 있습니다.

                                           https://hub.docker.com/_/mysql

                                           https://hub.docker.com/_/php

                                           https://hub.docker.com/_/httpd

 

(기타 명령 - 삭제)

이미지 삭제는 컨테이너 우선 삭제 후 가능합니다.

# docker ps                                 // 컨테이너 리스트 출력

# docker rm cea0f7b8d47f          // 출력된 컨테이너 ID 로 컨테이너 삭제

# docker images                          // 이미지 리스트 출력

# docker rmi httpd                        // 이미지 삭제

* 참고

이미지 삭제시 아래와 같은 메세지가 출력되는 경우는 REPOSITORY 가 같고 버전의 차이가 없는 경우입니다.

(예 : httpd:2.4.54 와 httpd:latest 가 같은 버전일 경우)
Error response from daemon: conflict: unable to delete 157dcdf23d6c (must be forced) - image is referenced in multiple repositories

아래와 같이 -f 옵션으로 강제 삭제를 하게 되면 두개의 이미지가 동시 삭제 됩니다.

# docker rmi -f 157dcdf23d6c


2. 가동

APM 환경 파일을 컨테이너와 연결하여 생성합니다.
# vi docker-compose.yml

version: '3.9'

services:
    httpd:
        image: httpd:2.4.54
        container_name: httpd
        restart: unless-stopped # 서버 부팅시 컨테이너 가동
        ports:
            - "80:80"
        volumes:
            - /home/sysdocu/httpd/html/:/usr/local/apache2/htdocs/ # 웹 소스 파일 경로

    mysql:
        image: mysql:8.0.31
        container_name: mysql
        restart: unless-stopped
        tty: true
        ports:
            - "3306:3306"
        environment:
            MYSQL_HOST: localhost
            MYSQL_ROOT_PASSWORD: 12345678 # 초기 mysql root 비밀번호
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
            TZ: Asia/Seoul

    php:
        image: php:8.2.0-fpm
        container_name: php
        restart: unless-stopped
        ports:
            - "9000:9000"
        volumes:
            - /home/sysdocu/httpd/html/:/var/www/html/  # php 소스 코드를 사용하기 위해 필수 설정
        command:
            - /bin/sh
            - -c
            - |
              echo "security.limit_extensions = .html .htm .php" >> /usr/local/etc/php-fpm.d/www.conf  # 특정 확장자만 php 소스 코드 사용
              php-fpm

 

파일 맨 위에 compose version 은 docker 버전에 맞추어 사용해야 합니다. 아래 URL 에서 확인이 가능합니다.

https://docs.docker.com/compose/compose-file/compose-versioning/#compatibility-matrix

 

이제 컨테이너를 가동합니다.

# docker compose up -d               // 백그라운드로 전체 서비스 (컨테이너) 올리기

* 이 작업이 선행 되어야 컨테이너 별로 제어 (시작/중지) 가 가능함

 

index.html 를 만들고 브라우저로 접속하면 아래 내용 (New index) 이 출력되는것을 확인할 수 있습니다.

# echo "New index" > /home/sysdocu/httpd/html/index.html

 

그리고 변경된 내용이 httpd 컨테이너 내에도 확인됩니다.

( 실 데이터 저장 위치 : /home/sysdocu/httpd/html/ )

# docker exec -it httpd /bin/bash

root@771473b9edc0:/usr/local/apache2# cd htdocs
root@771473b9edc0:/usr/local/apache2/htdocs# cat index.html 
New index

 

현재 컨테이너 구동 상태입니다.

# docker compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
httpd               "httpd-foreground"       httpd               running             0.0.0.0:80->80/tcp, :::80->80/tcp
mysql               "docker-entrypoint.s…"   mysql               running             0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp
php                 "docker-php-entrypoi…"   php                 running             0.0.0.0:9000->9000/tcp, :::9000->9000/tcp

 

(기타 명령)

# docker compose images       // 올려진 서비스 (컨테이너) 가 사용중인 이미지 리스트 출력. (모든 이미지 출력 : docker images)

# docker compose ps               // 올려진 서비스 (컨테이너) 출력

# docker compose stop php     // 올려진 서비스 (컨테이너) 선택 중지

# docker compose start php     // 올려진 서비스 (컨테이너) 선택 시작

# docker rm -v php                    // 올려진 서비스 (컨테이너) 삭제
# docker compose up -d php    // 하나의 서비스 (컨테이너) 만 구동

 

모든 컨테이너를 더이상 사용하지 않을때 아래와 같이 내립니다.

# docker compose down    // 컨테이너 중지 및 삭제

 

반응형

댓글()

Ubuntu 22.04 Desktop 설치 후 한글 사용하기 외 PC 로 활용할 기본 프로그램 목록

리눅스/OS 일반|2022. 11. 15. 10:10
반응형

한글 사용하기

1. settings - Region & Language - Install / Remove Languages -> Korean 박스 체크

reboot

2. terminal - ibus-setup

3. input method - add - korean 검색 - korean - Hangul add

4. settings - input sources - + 클릭 - Korean - Korean (Hangul) add

5. 바탕화면 우측 상단에 add된 Korean(hangul) 선택

[출처] https://jay-daily.tistory.com/201

 

 

우분투 소프트웨어에서 설치

remmina, filezilla, telegram, gedit, 스크린샷

 

 

동영상 플레이어

# apt -y install smplayer

기본 프로그램 등록 : 셋팅 > 기본 응용 프로그램 > 영상 (SMPlayer) 선택

 

 

네이버 웨일 브라우저

 

 

반응형

댓글()

FCM 을 활용한 PUSH 메세지 보내기 (2024-11-23)

프로그래밍/Android (Java)|2022. 10. 19. 16:16
반응형

New Project > Empty Views Activity 선택

Language : Java

Minimum SDK : API 24

이 상태로 진행하였습니다.

 

 

build.gradle 수정 (프로젝트 수준)

 

아래 내용을 파일에 추가 합니다.

...

buildscript {

    dependencies {
        classpath("com.google.gms:google-services:4.4.2")
    }
}

 

 

build.gradle 수정 (앱 수준)

 

아래 내용을 추가 합니다.

중간에 주석 부분도 추가해줍니다. 없을 경우 바로 아랫줄에 구문 에러 메세지가 출력됩니다.

plugins {
    alias(libs.plugins.android.application)
    id("com.google.gms.google-services")
}

...

dependencies {

    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:2.0.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    implementation(platform("com.google.firebase:firebase-bom:33.6.0"))
    implementation("com.google.firebase:firebase-analytics")
    implementation("com.google.firebase:firebase-messaging:24.1.0")
    implementation("com.google.firebase:firebase-core:21.1.1")
}

 

 

google-services.json 생성

 

Firebase console 페이지에 접근해서 프로젝트에 APP 을 추가합니다.

추가하는 과정에서 google-services.json 파일을 다운로드 받을 수 있으며,

해당 파일은 app 디렉토리 안에 넣어 놓습니다.

 

 

build.gradle 페이지에서 [Sync Now] 버튼을 눌러줍니다.

 

 

MyFirebaseMessagingService.java 생성

package kr.sysdocu.fcm;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;

import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onNewToken(@NonNull String token) {
        super.onNewToken(token);
        // token을 서버로 전송해서 저장하고 싶은 경우 이곳에 코드 입력
    }

    @Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        String messageContent;

        // 푸시 메시지 데이터 처리
        if (!remoteMessage.getData().isEmpty()) {
            // Data Payload 처리
            messageContent = remoteMessage.getData().get("message");
            String title = remoteMessage.getData().get("title");
            showNotification(title, messageContent); // 아래에서 정의한 알람을 실행하는 부분
        } else if (remoteMessage.getNotification() != null) {
            // Notification Payload 처리
            messageContent = remoteMessage.getNotification().getBody();
        } else {
            messageContent = "No Content";
        }

    }

    // 알람을 띄운다
    private void showNotification(String title, String message) {
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        String channelId = "default_channel_id";

        // Android 8.0 (API 26) 이상에서는 알림 채널을 생성해야 함
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    channelId,
                    "Default Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            notificationManager.createNotificationChannel(channel);
        }

        // 알림 클릭 시 실행할 Intent 정의
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 기존 Activity 스택 제거 후 실행

        // PendingIntent 생성
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this,
                0,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE // 최신 상태 유지
        );

        // 알림 빌더 구성
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
                .setContentTitle(title)                     // 알림 제목
                .setContentText(message)                    // 알림 메시지
                .setSmallIcon(R.drawable.ic_icon)           // 알림 아이콘
                .setAutoCancel(true)                        // 알림 터치 후 제거
                .setContentIntent(pendingIntent);           // 알림 클릭 시 실행될 PendingIntent 설정

        // 알림 표시
        notificationManager.notify(0, notificationBuilder.build());
    }

}

 

 

MainActivity.java 수정

여기에서 코드를 작성할때 파란색 부분은 okhttp 라이브러리를 이용해 토큰을 웹서버로 전송하기 위한 부분입니다.

필요시 같이 작성하면 됩니다.

 

앱수준 build.gradle 파일에 dependencies 추가후 sync 맞추기

implementation("com.squareup.okhttp3:okhttp:4.11.0")

 

package kr.sysdocu.fcm;

import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.messaging.FirebaseMessaging;

public class MainActivity extends AppCompatActivity {

    private final OkHttpClient client = new OkHttpClient();

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 이 안의 부분은 처음 토큰을 받아올때 한 번만 실행 됩니다.
        FirebaseMessaging.getInstance().getToken().addOnSuccessListener(new OnSuccessListener<String>() {
            @Override
            public void onSuccess(String token) {

                // 토큰을 토스트로 간단히 확인
                Toast toast = Toast.makeText(getApplicationContext(), "TOKEN : " + token, Toast.LENGTH_LONG);
                toast.show();

                // 서버로 토큰 전송 (ssl 사용)
                new Thread(() -> {
                    try {
                        String url = "https://fcm.sysdocu.kr/register.html?token=" + token;
                        String result = run(url);
                        // 결과 처리 (예: 로그 출력)
                        System.out.println(result);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }).start();

            }
        });
    }

    // okhttp 라이브러리 사용
    // run 메서드는 클래스 수준에 정의해야 합니다.
    public String run(String url) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .build();
        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }

}

 

 

activity_main.xml 수정

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="#DFE5E5"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textColor="@color/black"
        android:text="토큰은 웹서버에서 확인하세요." />

</LinearLayout>

 

 

AndroidManifest.xml

 

아래 내용을 추가합니다.

(생략)

<uses-permission android:name="android.permission.INTERNET"/>


...

// <application> 안에 아래 내용 추가

<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

(생략)

 

프로젝트를 빌드하여 apk 파일을 생성하고, 핸드폰에 설치합니다.

 

잠깐, 앱을 실행하기 전에 아래 내용 확인해주세요.

위 소스에서 사용되었던 서버 URL (https://fcm.sysdocu.kr/register.html) 에 해당되는 파일을 미리 생성해 놓도록 합니다.

access log 에 접근 로그가 남아 token 확인을 쉽게하기 위함이니 빈 파일도 괜찮습니다.

 

 

PUSH 발송 테스트

 

방법1)

Firebase Console 에서 프로젝트 선택 > '실행' 메뉴 > 'Messaging' 메뉴 > (첫 번째 캠페인 만들기) 버튼 클릭 > Firebase 알림 메세지 체크 후 [만들기]

출력된 화면에서 적절한 내용으로 모두 입력 후 [검토] 버튼을 누르면, 앱을 설치한 모든 Device 로 FCM 메세지가 발송 됩니다.

 

방법2)

PHP 코드를 아래와 같이 작성 합니다.

현재 (2024년 11월) 는 이전에 사용하던 방식에서 FCM HTTP API의 v1 버전으로 전송 방식이 바뀌었습니다.

 

1) 사용자 계정 키 (json) 다운로드

서비스 계정 키 다운로드를 위해 Firebase Console (https://console.firebase.google.com/ ) 로 이동합니다.

프로젝트 설정 > 서비스 계정 > 새 비공개 키 생성 클릭. 

JSON 파일을 다운로드합니다.

다운로드 한 파일은 PHP 생성할 위치로 복사합니다.

 

2) php 파일 작성

v1 API 는 OAuth2 인증을 사용해야 하므로 google/apiclient 패키지를 설치합니다.

# composer require google/apiclient

 

아래 파란색 부분을 적절한 값으로 수정하여 작성합니다.

# vi fcm_send.php

<?php
require 'vendor/autoload.php';

use Google\Auth\Credentials\ServiceAccountCredentials;
use GuzzleHttp\Client;

function sendFCMMessage($serviceAccountPath, $projectId, $token, $title, $body) {
    // FCM 엔드포인트 URL
    $url = "https://fcm.googleapis.com/v1/projects/$projectId/messages:send";

    // 메시지 페이로드
    $message = [
        'message' => [
            'token' => $token,
            'data' => [
                'title' => $title,
                'message' => $body
            ]
        ]
    ];

    // Google OAuth2 인증
    $credentials = new ServiceAccountCredentials(
        'https://www.googleapis.com/auth/firebase.messaging',
        json_decode(file_get_contents($serviceAccountPath), true)
    );

    $accessToken = $credentials->fetchAuthToken()['access_token'];

    // HTTP 요청 헤더
    $headers = [
        'Authorization' => 'Bearer ' . $accessToken,
        'Content-Type' => 'application/json',
    ];

    // HTTP 클라이언트
    $client = new Client();

    try {
        // FCM 메시지 요청
        $response = $client->post($url, [
            'headers' => $headers,
            'body' => json_encode($message)
        ]);

        echo "Response: " . $response->getBody();
    } catch (Exception $e) {
        echo "Error: " . $e->getMessage();
    }
}

// 서비스 계정 JSON 파일 경로
$serviceAccountPath = './your-service-account.json';

// Firebase 프로젝트 ID
$projectId = 'your-project-id';

// FCM 토큰, 제목, 내용
$token = 'your-device-token';
$title = 'Test Title';
$body = 'Test Body';

// 메시지 전송 함수 호출
sendFCMMessage($serviceAccountPath, $projectId, $token, $title, $body);
?>

 

이제 작성한 파일을 실행만 하면 입력해놓은 특정 디바이스로 (token) FCM 메세지가 전송됩니다.

# php fcm_send.php

 

반응형

댓글()

MySQL (MariaDB) 로그들 logrotate 설정하기

리눅스/MySQL|2022. 10. 7. 17:03
반응형

MySQL (MariaDB) 에는 여러 로그가 있지만 그 중 general log 에 사용하기 적합한 logrotate 설정법 입니다.

binary log 파일은 my.cnf 환경 설정 파일에서 보관 일수를 정할 수 있기 때문에 디스크를 많이 사용하지 않지만

general log 는 제한없이 하나의 파일에 계속 데이터가 누적되기 때문입니다.

아래와 같이 설정을 하면 mysql 재시작 없이 자동적으로 설정한 값에 의해 로그 파일이 분리, 삭제 됩니다.

 

우선 logrotate 설정 파일이 모여 있는 디렉토리로 이동 후 mysql 설치된 디렉토리의 샘플 mysql-log-rotate 파일을 가져와서 수정 합니다.

 

# cd /etc/logrotate.d

# cp -arp /usr/local/mysql/support-files/mysql-log-rotate .

# vi mysql-log-rotate

/usr/local/mysql/data/general_query.log {
    create 660 mysql mysql    # 생성되는 파일 퍼미션 및 권한
    daily                                  # 매일 실행
    rotate 10                           # 로그파일 보관 개수
    missingok                         # 로그파일이 없어도 에러처리하지 않음
    compress                         # 로그 파일 압축 보관
    postrotate                        # 여기부터 끝까지는 로그파일 처리 후 동작 스크립트 입니다.
        # just if mariadbd is really running
        if test -x /usr/local/mysql/bin/mysqladmin && \
           /usr/local/mysql/bin/mysqladmin -uroot -p12345678 ping &>/dev/null
        then
           /usr/local/mysql/bin/mysqladmin -uroot -p12345678 --local flush-general-log
        fi
    endscript
}

 

패스워드와 파일 변경 후 flush 할 로그 파일을 명시합니다.

여러개의 로그파일을 flush 하고자 할 경우 아래와 같이 띄어쓰기로 구분하여 사용합니다.

 

--local flush-error-log flush-engine-log flush-general-log flush-slow-log

 

설정이 잘 되었는지 미리 확인 (실행) 하는 방법은 아래와 같습니다.

 

# logrotate -f /etc/logrotate.d/mysql-log-rotate

 

참고로 flush-general-log 등의 옵션은 DB 버전에 따라 제공되거나 그렇지 않습니다.

테스트 환경은 MariaDB 10.6.9 이며 flush-general-log 옵션이 확인되었지만,

mysql 8.0.26 버전에서는 해당 옵션이 확인되지 않아서 명령 실행이 불가능 했습니다.

 

반응형

댓글()

httpd 에서 Redirect 또는 ErrorDocument 설정이 동작하지 않을때

리눅스/APACHE|2022. 10. 6. 15:09
반응형

VirtualHost 설정에서 리다이렉트 설정을 하였거나,

Redirect / https://sysdocu.tistory.com

 

404 에러 페이지를 별도로 만든 경우

ErrorDocument 404 /error.html

 

동작하지 않을땐 아래와 같은 부분을 체크해 봅니다.

 

[에러 로그 확인]

[Thu Oct 06 14:59:04.976450 2022] [proxy_fcgi:error] [pid 204935:tid 140273396987648] [client 192.168.10.2:51192] AH01071: Got error 'Primary script unknown'

 

[해결]

 

1) 디렉토리 옵션 변경

<Directory /home/sysdocu/public_html/*>
    AllowOverride none    # 이 부분이 all 로 되어 있다면 none 으로 변경합니다.
    Options FollowSymLinks
    Require all granted
</Directory>

 

2) 프록시 옵션 추가

ProxyErrorOverride on

 

이후 httpd 를 재시작 하고 확인하면 접근이 잘 됩니다.

 

반응형

댓글()

mariabackup 을 이용한 MariaDB 10.6.9 Replication 구성하기

리눅스/MySQL|2022. 9. 19. 10:10
반응형

percona-xtrabackup 패키지는 MySQL 또는 MariaDB 서버의 서비스 중지 없이 Replication 을 구성하기 위한 명령어 입니다.

아래 내용은 CentOS 8 환경에서 MariaDB 10.6.9 버전으로 테스트 하였습니다.

사용자 계정이나 패스워드, 디렉토리 등은 사용자 환경에 따라 다르므로 명령 실행시 확인 후 실행하시기 바랍니다.

- master 서버 : 192.168.10.2

- slave 서버 : 192.168.10.3

- 참고1 : percona-xtrabackup 패키지는 MySQL 과 MariaDB 둘 다 가능합니다. 다만 설치 버전에 따라 지원가능한 DB 버전이 다르며 MySQL 은 xtrabackup, MariaDB 는 mariabackup 이라는 명령을 사용하는것이 큰 차이점 입니다.

(redo 로그를 기록하는 파일이 다름)

 

- LINK : xtrabackup 을 이용한 MySQL 8.0.28 Replication 구성하기

 

1. 설치

 

(인터넷 연결 가능할 경우)

master 서버와 slave 서버에 xtrabackup 을 설치 합니다.

# yum -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm

# yum -y install percona-xtrabackup-24

 

(인터넷 연결 불가의 경우)

사설망에서 DB를 운영할 경우 서버에 없는 패키지는 설치 파일을 다운 받아 복사하여 설치하면 됩니다.

서버 환경에 따라 필요한 패키지가 다를 수 있으며 이는 아래 rpm 명령으로 의존성 확인이 가능합니다.

 

# wget https://vault.centos.org/centos/8/AppStream/x86_64/os/Packages/libev-4.24-6.el8.x86_64.rpm

# wget https://vault.centos.org/centos/8/BaseOS/x86_64/os/Packages/perl-DBI-1.641-1.el8.x86_64.rpm

# wget https://vault.centos.org/centos/8/AppStream/x86_64/os/Packages/perl-DBD-MySQL-4.046-3.module_el8.3.0+419+c2dec72b.x86_64.rpm

# wget https://vault.centos.org/centos/8/BaseOS/x86_64/os/Packages/rsync-3.1.3-12.el8.x86_64.rpm

# wget https://repo.percona.com/yum/release/8/RPMS/x86_64/percona-xtrabackup-80-8.0.28-21.1.el8.x86_64.rpm 

 

필요한 패키지를 다운로드 한 후 DB 서버로 옮깁니다. (scp 또는 rsync 등으로 복사하면 됩니다. 방법은 생략)

그리고 아래 순서에 따라 설치합니다.

 

# rpm -ivh libev-4.24-6.el8.x86_64.rpm

# rpm -ivh perl-DBI-1.641-1.el8.x86_64.rpm

# rpm -ivh perl-DBD-MySQL-4.046-3.module_el8.3.0+419+c2dec72b.x86_64.rpm

# rpm -ivh rsync-3.1.3-12.el8.x86_64.rpm

# rpm -ivh percona-xtrabackup-80-8.0.28-21.1.el8.x86_64.rpm

 

2. 원본 데이터 백업

 

(master 서버에서)

# mariabackup --defaults-file=/etc/my.cnf --backup --user=root --password=12345678 --target-dir=/mariabackup --no-lock --port=3306 --socket=/tmp/mysql.sock

 

백업이 완료되면 /mariabackup 디렉토리가 생성되며 하단에 백업 파일들이 존재하게 됩니다.

data 디렉토리 내 파일들과 mariabackup 관련된 로그가 있습니다.

 

3. 데이터 이전

 

(master 서버에서)

master 서버에 백업된 데이터를 slave 서버로 복사합니다.

# rsync -avzPog /mariabackup root@192.168.10.3:/

 

4. 데이터 복원

 

(slave 서버에서)

mysqld 데몬을 중지하고 기존 data 디렉토리를 삭제 합니다. (mv 명령으로 디렉토리 이름 변경 권장)

가져온 데이터를 복구하는 과정에서 기존 data 디렉토리내 파일이 있으면 실행이 되지 않기 때문입니다.

 

백업중 작성된 redo 로그를 데이터에 적용합니다.

# mariabackup --prepare --target-dir=/mariabackup

 

> --use-memory=10G 와 같이 본 작업에 사용할 시스템 메모리양을 어느정도 할당 해주면 빠른처리가 가능합니다.

> redo 로그 적용 도중에 아래와 같은 에러 메세지가 출력 될 경우 --innodb_force_recovery=1 옵션을 추가 합니다.

2022-10-14  8:47:54 0 [Note] InnoDB: Set innodb_force_recovery=1 to ignore corrupted pages.
2022-10-14  8:47:54 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
[00] FATAL ERROR: 2022-10-14 08:47:54 mariabackup: innodb_init() returned 11 (Generic error).

하지만 백업 과정에서 문제가 생겼을 수 있으므로 master 서버에서 몇 번 더 백업을 반복 시도해 보는것도 좋습니다.

 

백업 파일을 이동합니다. (--copy-back 를 사용하면 복사)
# mariabackup --move-back --datadir=/usr/local/mysql/data --target-dir=/mariabackup

 

root 로 복원하였기 때문에 복원된 파일의 권한이 root 로 되어 있습니다.

mysql 가동을 위해 data 디렉토리의 권한을 설정을 합니다.

# chmod 755 /usr/local/mysql/data
# chown mysql.mysql -R /usr/local/mysql/data

# systemctl start mysqld

 

5. 로그 포지션 설정 및 동기화 시작

 

백업본의 xtrabackup_binlog_info 에 있는 mysql-bin 파일명과 position 값 참고하여
replication 을 적용합니다.

 

(slave 서버에서)

# cat /usr/local/mysql/data/xtrabackup_info |grep binlog_pos

binlog_pos = filename 'binlog.000002', position '943'    // 출력된 내용을 참고

 

# mysql -p

mysql> stop slave;

mysql> reset slave;

mysql> change master to master_host='192.168.10.2', master_user='repl',
master_password='12345678', master_log_file='binlog.000002',
master_log_pos=943;

mysql> start slave;

 

정상적으로 동기화 된 것을 확인할 수 있습니다.

mysql> show slave status \G;

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

 

반응형

댓글()