Last Updated on 1월 1, 2024 by Jade(정현호)
안녕하세요
이번 포스팅에서는 CentOS 8 버전에서 APM 스택을 구성하는 내용에 대해서 확인해보도록 하겠습니다.
Contents
APM
APM 은 Apache PHP MariaDB/MySQL 의 약자로 웹 서버를 구축하고 PHP 로 작성된 웹 어플리케이션을 구동하기 위해 이전부터 많이 사용해온 스택입니다.
PHP 를 구동 하기 위한 서버 스택의 구성은 여러가지 방식으로 할 수 있습니다.
• Apache + PHP(mod_php) + MySQL 나 MariaDB
• Apache + PHP-FPM + MySQL 나 MariaDB
• Nginx + PHP-FPM + MySQL 나 MariaDB
이번 글에서는 dnf(rpm)으로 Apache + PHP-FPM + MariaDB(MySQL) 내용을 확인해보겠습니다.
설치 환경
OS: CentOS 8.3
Apache 2.4.37 + PHP-FPM 7.4.13 + MariaDB 10.3.17
설치순서는 Apache MariaDB PHP-FPM 순으로 설치하겠습니다
CentOS 7 버전에서의 APM 설치 구성은 아래 포스팅을 참조하시면 됩니다.
CentOS 7.8 버전에서의 구성 내용을 포함하고 있습니다.
Rocky Linux 8 버전에서 APM 설치 구성은 아래 포스팅을 참조하시면 됩니다.
사전 환경 구성
외부 Repository 구성
user$ sudo dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
user$ sudo dnf -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
사전 필요 패키지 설치
user$ sudo dnf -y install gcc gcc-c++ \
pcre-devel make git openssl wget vim \
unzip GeoIP-devel git tree cmake \
expat-devel libxml2-devel \
openssl openssl-devel python3 \
curl gnupg2 libxslt-devel gd-devel \
perl-ExtUtils-Embed
Apache
Apache 설치
user$ sudo dnf -y install httpd httpd-devel \
apr apr-util apr-devel apr-util-devel \
apr-util-openssl mod_proxy_html apr-util \
libnghttp2 mod_http2 mod_ssl httpd-tools
버전 확인
user$ curl --head http://localhost/
Server: Apache/2.4.37 (centos) OpenSSL/1.1.1g
user$ httpd -V
Server version: Apache/2.4.37 (centos)
Server built: Nov 4 2020 03:20:37
MariaDB
MariaDB 설치
user$ sudo dnf -y install mariadb \
mariadb-common mariadb-devel \
mariadb-server mariadb-server-utils \
mariadb-gssapi-server
MariaDB 대신 MySQL 을 설치를 하려고 할 경우 아래의 패키지로 설치를 하면 됩니다.
user$ sudo dnf -y install mysql \
mysql-common mysql-devel mysql-server \
mysql-libs mysql-selinux
기본 파라미터 추가
user$ cd /etc/my.cnf.d
user$ sudo vi mariadb-server.cnf
[mysqld] <-- 절에 아래 내용을 추가로 입력해 줍니다.
user=mysql
server-id=1
log_bin = binlog
expire_logs_days=10
innodb_buffer_pool_size = 384M
innodb_file_per_table=TRUE
# bind-address=0.0.0.0
character-set-client-handshake=OFF
skip-character-set-client-handshake
max_allowed_packet=500M
init_connect=SET collation_connection = utf8mb4_general_ci
init_connect=SET NAMES utf8mb4
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
[참고] MySQL 로 설치한 경우 설정할 파일명은 아래와 같습니다.
/etc/my.cnf.d/mysql-server.cnf
MariaDB 시작/중지
MariaDB 중지
user$ sudo systemctl stop mariadb
MariaDB 기동
user$ sudo systemctl start mariadb
[참고] MySQL 로 설치한 경우 서비스명은 mysqld 입니다.
접속 확인
user$ sudo mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.3.17-MariaDB-log MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
PHP
REMI PHP 7.4 설치
user$ sudo dnf -y install php74 php74-php-common \
php74-php-fpm php74-php-gd php74-php-xml \
php74 php74-php-devel php74-libzip \
php74-php-mysqlnd php74-php-opcache \
php74-php-mbstring php74-php-pdo \
php74-php-pecl-imagick-devel php74-php-pecl-mcrypt \
php74-php-pecl-zip php74-php-bcmath \
curl curl-devel php74-php-pecl-imagick \
libpng libpng-devel libwebp libwebp-devel \
libXpm libXpm-devel openssl openssl-devel \
autoconf zlib zlib-devel freetype freetype-devel \
gd gd-devel libmcrypt libmcrypt-devel \
libtool-ltdl-devel libxml2-devel \
libxml2 libcurl libcurl-devel php74-php-soap \
php74-php-pecl-crypto php74-php-pecl-mysql
버전 확인
user$ php74 -v
PHP 7.4.13 (cli) (built: Nov 24 2020 10:03:34) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.13, Copyright (c), by Zend Technologies
php.ini 파일 수정
user$ cd /etc/opt/remi/php74/
user$ sudo vi php.ini
아래 5개는 주석 제거 및 내용 수정
date.timezone = Asia/Seoul
expose_php = Off
post_max_size = 500M
upload_max_filesize = 200M
memory_limit = 512M
PHP-FPM 설정
포스팅에서는 Apache 와 PHP의 연동을 PHP-FPM 으로 사용하였습니다. 그렇기 때문에 PHP-FPM 에 대한 설정이 필요 합니다.
Apache는 mod_php 를 통해서 Apache 와 PHP 와의 연동 설정이 기존 부터 사용하던 보통의 방식이지만 최근에는 PHP-FPM 이 성능상 더 좋기 이점이 있어서 PHP-FPM 을 많이 사용하는 추세입니다.
php-fpm.conf 파일 수정
user$ cd /etc/opt/remi/php74/
user$ sudo vi php-fpm.conf
include=/etc/opt/remi/php74/php-fpm.d/*.conf
--> 주석이 해제되어 있는지 확인
daemonize = yes
-> 주석으로 되어 있다면 주석을 해제합니다.
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
;log_level = notice
-> PHP-FPM 데몬의 Log level Default 는 notice 입니다.
-> 문제에 대한 분석이나 초기 설정 후 확인 등이 필요하다면 debug 레벨로 변경하여 사용해도 됩니다.
www.conf 파일 수정
pool 에 해당하는 설정으로 파일 별로 pool 을 생성할 수 있으며 pool 별로 포트와 이름 등을 달리하여 시작할 수 있습니다.
포스팅에서는 기본 생성되어 있는 www pool 을 수정하여 사용하였습니다.
user$ cd /etc/opt/remi/php74/php-fpm.d
user$ sudo cp www.conf www.conf.ori
user$ sudo vi www.conf
; pool name ('www' here)
[www]
-> PHP Pool 이름을 지정하는 항목입니다.
-> 프로그램명이나 사이트 명이나, 업무가 있다면 업무명 등을 입력하여도 됩니다.
-> Pool 혹은 Container의 식별, 이름입니다. 기본으로 www 지정되어 있습니다.
-> Pool은 conf 파일 별로 여러 개의 Pool을 만들 수 있습니다. 이때는 Pool 별로 이름을 지정하여 겹치지 않게 해야 합니다.
# 아래 내용과 같이 되어 있는지 확인 및 주석이 되어 있다면 주석을 해제합니다.
user = apache
group = apache
listen.acl_users = apache
listen = /var/opt/remi/php74/run/php-fpm/www.sock
=> 이부분은 접속을 받는 방식을 설정하는 부분으로 Socket(UDS) 방식으로 사용하거나 IP 방식으로 사용하거나 둘 중 하나를 선택하여 설정해야 합니다.
=> IP 방식으로는 아래와 같이 지정할 수 있습니다.
listen = 123.123.123.123.123:9000
listen = 127.0.0.1:9000
listen = 9000 <== 이와 같이 IP 없이 포트만 기재하면 모든 주소에서 접속이 가능한 상태입니다.
(listen on a TCP socket to all addresses)
소켓 방식은 아래와 같이 파일명을 지정해주면 됩니다.
listen = listen = /var/opt/remi/php74/run/php-fpm/www.sock
포스팅에서는 같은 서버에서 apache 와 php-fpm 사용하는 설정으로 할 것임으로 socket 을 사용하여 설정하도록 하겠습니다
같은 서버내 라도 IP를 사용할 수 있고 사용하여도 됩니다.
PHP-FPM 프로세스
프로세스 수와 관련된 pm 으로 시작하는 파라미터 가 있습니다
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 40
pm.max_requests = 500
* 위의 설정값은 예시입니다.
pm.max_children 는 설정된 PHP Pool(여기서는 www) 내에서 가동할 수 있는 최대 자식 프로세스 수를 의미합니다.
pm.start_servers 는 php-fpm 을 실행할 때 초기에 생성하는 자식 프로세스의 개수입니다.
pm.min_spare_servers 는 idle 상태의 자식 프로세스 개수가 이 개수보다 작으면 자식 프로세스를 생성합니다.
pm.max_spare_servers 는 idle 상태의 자식 프로세스의 최대 개수를 의미합니다.
pm.max_requests 는 각 프로세스가 최대 request를 처리하면 수입니다.
500 으로 설정되어 있다면 500번 request 후 프로세스를 다시 생성합니다.
점진적인 메모리 증가에 대한 부분을 방지할 수 있습니다.
apache 에서 유사한 설정으로는 MaxRequestsPerChild 있습니다.
[참고] 메모리 사용현황 및 세션 계산
아래 명령어를 이용하면 현재 fork된 php-fpm 프로세스 당 메모리 사용량을 확인할 수 있습니다.
user$ ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'
시스템에 가용한 메모리나 사용할 정도에서 프로세스당 사용메모리를 나누어서 최대 자식프로세스 개수를 산정해도 되겠습니다
ex) PHP에 6GB 를 사용하려고 함 , PHP-FPM이 현재 사용중인 메모리량이 대략 60MB 임
6000MB / 60MB = 자식 프로세스 개수 100개 로 설정
이와 같이 각 시스템 마다 메모리 상황을 고려하여 적절한 pm.max_children 값을 선정하여 설정하면 되겠습니다.
로그 설정
로그 관련된 내용의 주석 해제와 변경을 합니다
access.log = /var/opt/remi/php74/log/php-fpm/$pool.access.log
-> 주석 해제 및 경로 지정
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
--> 주석제거
slowlog = /var/opt/remi/php74/log/php-fpm/$pool.slow.log
--> 주석제거, 파일명 변경
request_slowlog_timeout = 5
--> 주석제거, 내용변경
--> 단위는 초로 5는 예시입니다. 해당 시간은 선택해서 변경하시면 됩니다.
catch_workers_output = yes
-> 주석 제거
-> main error log 파일에 worker 의 에러 로그가 같이 기록되게 됩니다.
php_admin_value[error_log] = /var/opt/remi/php74/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
-> 주석 제거
PHP Opcache 파라미터
[참고] PHP 5.5 버전 부터 기본에 포함되었으며 이전에는 zend optimizer 를 별도로 설치 및 plugin 하여 사용하였습니다.
사용 용도는 컴파일 / 실행 / 결과 의 순으로 처리되는 PHP에 대해서 Opcache(예전의 Zend Optimizer)를
이용하여 컴파일 된 PHP 코드를 메모리에 Cache 해서 접속요청에 더 빠르게 응답을 줄 수 있는 기능입니다
php7.x 버전부터 Opcache 의 기본 메모리가 128M 입니다.
메모리를 변경하거나 다른 파라미터를 조정하고자 한다면 10-opcache.ini 에서 설정할 수 있습니다.
user$ cd /etc/opt/remi/php74/php.d
user$ sudo vi 10-opcache.ini
10-opcache.ini 파일에는 opcache 의 활성화 내용부터 해서 기본적으로 사용 될수 있는 파라미터는 주석이 해제되어 활성화가 되어 있는 상태입니다.
opcache의 파라미터의 간략한 설명은 아래와 같습니다.
opcache.enable=1 - Zend Opacache 활성화 여부 결정 , 1일때 활성화됨
opcache.enable_cli=1 - PHP CLI 버전에서(명령행 버전에서도) Zend Opcache 활성화 여부 결정
opcache.memory_consumption - 캐쉬에 사용할 메모리 크기. 7.0부터 기본 크기는 128M
opcache.interned_strings_buffer=8 - 메모리에서 interned 문자열을 위해 사용할 메모리량
opcache.fast_shutdown=1 - 활성화 시 accelerated code 에 대해서 사용되어짐
opcache.interned_strings_buffer - Opcache 가 사용하는 내부 스트링( class name 이나 file등)을 저장하기 위한 메모리의 크기.
opcache.max_accelerated_files - Opcache 가 캐쉬할 최대 파일 갯수.
opcache.validate_timestamps - Default 1 / 0(off)이 아닐 경우 opcache.revalidate_freq 에 설정된
시간마다 코드와 캐쉬의 변경 여부를 체크한다.
validate_timestamps 가 꺼져 있을 경우 코드의 변경 여부를 체크하지 않으므로 PHP 소스가 수정되어도 반영되지 않는다.
그러므로 변경 사항을 반영하려면 httpd 를 재기동하거나 httpd 에 SIGUSR2 시그널을 전송해야 한다.
opcache.file_cache_only=1 - makes sure that the in-memory opcache is disabled and only files are used, which is what you want for CLI.
1 로 설정할 경우 in-memory opcache 사용이 안됨 = php-fpm 에서 사용할 수 없음
그래서 메모리 관련하여 수정이 필요 할 경우 아래와 같이 용량을 늘려서 사용할 수 있습니다.
opcache.memory_consumption=256
-> 입력의 예시이며 단위는 MB입니다.
-> 이 부분(메모리 변경) 은 필수는 아닙니다.
-> 사용시 앞에 주석(;) 을 제거합니다.
PHP-FPM 재시작
설정이 완료되었다면 PHP-FPM 을 재시작 합니다.
[root]]# sudo systemctl restart php74-php-fpm
* PHP-FPM 설치 후 자동으로 기동 되어 있을 수 있음
프로세스 및 포트 오픈 확인
[root]]# ps -ef| grep php
root 62849 1 0 11:26 00:00:00 php-fpm: master process (/etc/php-fpm.conf)
apache 62850 62849 0 11:26 00:00:00 php-fpm: pool www
apache 62851 62849 0 11:26 00:00:00 php-fpm: pool www
apache 62852 62849 0 11:26 00:00:00 php-fpm: pool www
apache 62853 62849 0 11:26 00:00:00 php-fpm: pool www
apache 62854 62849 0 11:26 00:00:00 php-fpm: pool www
listen을 Unix Socket 으로 사용할 경우
[root]]# ls -al /var/opt/remi/php74/run/php-fpm/
srw-rw----+ 1 root root 0 11월 29 11:35 www.sock
listen을 IP 으로 사용할 경우
[root]]# netstat -antp | grep 9000
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 6389/php-fpm: master
Apache 설정
httpd.conf 파일 수정
/etc/httpd/conf/httpd.conf 파일 수정
user$ sudo vi /etc/httpd/conf/httpd.conf
ServerName www.example.com:80
-> 주석 해제
-> 아래쪽에 2개 내용추가
ServerTokens Prod
ServerSignature Off
아래 Directory 사이의 내용을 변경합니다.
<Directory "/var/www/html">
.... 사이의 내용...
</Directory>
#Options Indexes FollowSymLinks
-> 주석 처리 후 아래 내용으로 입력
Options MultiViews FollowSymLinks
-> 내용 추가
#AllowOverride None
-> 주석 처리 후 아래 내용으로 입력
AllowOverride All
-> 내용 추가
00-proxy.conf 파일 수정
user$ cd /etc/httpd/conf.modules.d/
user$ sudo vi 00-proxy.conf
아래 4개 내용 추가
ProxyRequests Off
ProxyErrorOverride on
ProxyTimeout 600
ProxyPreserveHost On
[참고] PHP-FPM 과 연결되는 Proxy_Pass 설정은 아래 파일내에 대부분이 설정되어 있습니다.
/etc/httpd/conf.d/php74-php.conf
방화벽 설정 및 Apache 재시작
OS 방화벽을 오픈 합니다.
# 80 포트 추가
user$ sudo firewall-cmd --permanent --add-port=80/tcp
# 80 포트 삭제(참고)
user$ sudo firewall-cmd --permanent --remove-port=80/tcp
# 정책 재반영 및 방화벽 정책 확인
user$ sudo firewall-cmd --reload;firewall-cmd --list-all
[참고] 클라우드 사용시 클라우드 네트워크의 보안 정책이나 클라우드의 방화벽도 오픈을 해줘야 합니다.
PHP 정상 작동 여부 확인을 위해 phpinfo.php 파일을 생성합니다.
[root]]# cd /var/www/html
[root]]# sudo vi phpinfo.php
<?php
phpinfo();
?>
Apache 재시작
user$ sudo systemctl restart httpd
접속 테스트
http://ip주소/phpinfo.php
이어지는 글
연관된 다른 글
RHEL의 소스를 기반으로 만들어지며 RHEL에서 최대한 추가나 제거를 자제하는 것을 원칙으로 가장 유사하게 Rebuild 한 배포판 입니다.
Principal DBA(MySQL, AWS Aurora, Oracle)
핀테크 서비스인 핀다에서 데이터베이스를 운영하고 있어요(at finda.co.kr)
Previous - 당근마켓, 위메프, Oracle Korea ACS / Fedora Kor UserGroup 운영중
Database 외에도 NoSQL , Linux , Python, Cloud, Http/PHP CGI 등에도 관심이 있습니다
purityboy83@gmail.com / admin@hoing.io
안녕하세요 ^^
가르침에 따라 본문의 내용을 보고 모두 설정을 하였습니다.
정상적인 결과까지 확인을 하였습니다만,
phpinfo페이지가 열리지 않네요.
아마 포트가 방화벽에 막혀 있나 싶기도 하고....
어디 부분을 참고해서 확인해 봐야 할련지요 ?
[root@web html]# sudo vi phpinfo.php
[root@web html]# sudo systemctl restart httpd
[root@web html]# sudo firewall-cmd --permanent --remove-port=80/tcp
success
[root@web html]# sudo firewall-cmd --permanent --add-port=80/tcp
success
[root@web html]# sudo firewall-cmd --reload;firewall-cmd --list-all
success
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client ssh
ports: 80/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@web html]# sudo systemctl restart httpd
[root@web html]# ls -l
total 4
-rw-r--r--. 1 root root 21 Jul 22 09:40 phpinfo.php
[root@web html]#
안녕하세요
오라클 클라우드에서 보안정책 설정에서 80포트는 오픈하셨나요?
혹시 selinux 로 인하여 안될수도 있으니 sudo audit2allow -a 를 실행하여 어떤 결과가 나오는지도 체크 해보시기 바랍니다.
php-fpm 이 기동되어 있는지도 확인해보시면 좋을것 같네요 ps -ef| grep php
감사합니다.
보안 정책이라 함은
네트워킹-가상 클라우드 네트워크 에서 보안 목록 에 수신규칙 추가를 말씀하시는거죠 ?
강좌 보고 그대로 따라 추가했습니다.
아니오 0.0.0.0/0 TCP 모두 80 포트 80 에 대한 TCP 트래픽입니다. HTTP Web Port
그리고
[root@web html]# sudo audit2allow -a
[root@web html]# php-fpm
[22-Jul-2021 10:56:53] ERROR: An another FPM instance seems to already listen on /run/php-fpm/www.sock
[22-Jul-2021 10:56:53] ERROR: FPM initialization failed
[root@web html]# ps -ef| grep php
root 1297 1 0 Jul21 ? 00:00:03 php-fpm: master process (/etc/php-fpm.conf)
apache 1321 1297 0 Jul21 ? 00:00:00 php-fpm: pool www
apache 1322 1297 0 Jul21 ? 00:00:00 php-fpm: pool www
apache 1323 1297 0 Jul21 ? 00:00:00 php-fpm: pool www
apache 1324 1297 0 Jul21 ? 00:00:00 php-fpm: pool www
apache 1325 1297 0 Jul21 ? 00:00:00 php-fpm: pool www
root 44721 1 0 09:16 ? 00:00:00 php-fpm: master process (../remi/php74/php-fpm.conf)
apache 44722 44721 0 09:16 ? 00:00:00 php-fpm: pool www
apache 44723 44721 0 09:16 ? 00:00:00 php-fpm: pool www
apache 44724 44721 0 09:16 ? 00:00:00 php-fpm: pool www
apache 44725 44721 0 09:16 ? 00:00:00 php-fpm: pool www
apache 44726 44721 0 09:16 ? 00:00:00 php-fpm: pool www
root 46271 6079 0 10:57 pts/0 00:00:00 grep --color=auto php
[root@web html]#
이런 상황입니다.
뭘 손을 대야 하는지를 몰라 먼산만 쳐다 보고 있습니다.
도움 좀 주십시요.
안녕하세요
php-fpm: master process (/etc/php-fpm.conf)
remi-php 가 아닌 기본 php-fpm 도 같이 동작하고 있는걸로 보이네요
sudo systemctl stop php-fpm
sudo systemctl disable php-fpm
sudo systemctl restart php74-php-fpm
로 기본 php-fpm 은 중지하시고 나서 remi-php-fpm 을 재시작 해보세요
코멘트의 지면길이상 작성하신 코멘트의 일부내용은 수정이 될 예정입니다
추가 문의 사항 중 내용이 길다면 별도의 게시판이나 메일을 부탁드립니다.
감사합니다.
네. 뭐가 어디서 잘못되었는지 모두 삭제후 다시 해봐야 겠습니다. ㅠㅠ
안녕하세요
다시 한번 해보시고 안되시면 메일로 남겨주시면 더 도움을 드리겠습니다.
admin@hoing.io
감사합니다.