Browsing Tag

리눅스

IT/Linux/Kubernetes

[Linux] Cannot allocate memory, 캐시 메모리 제거 및 swap 생성

안녕하세요. ManVSCloud 김수현입니다.

오늘은 최근 제 블로그가 간헐적 끊김이 있어 확인 후
Memory 부족 원인을 파악하고 해결까지에 대한 내용을 작성해보았습니다.


Symptom & Identify the cause

어제 블로그에 포스팅 후 블로그 페이지가 정상적으로 출력되지 않는 현상이 발생했습니다.
서버 접속 시 Cannot allocate memory 에러가 발생하는 중이었으며 명령어 입출력이 정상적이지않은 상태라 우선 인스턴스 재부팅을 진행하게 되었습니다.

-bash: fork: Cannot allocate memory

대시보드에서 자원 사용률을 살펴보았는데 다른 자원 사용률은 정상인데 유독 Memory만 90% 이상 사용 중!! Memory 문제가 있는 것을 알게되었습니다.

VSZ, RSS 확인 시 Apache, PHP에서만 대량 사용 중이라 웹 로그를 먼저 확인해보았습니다.
1주일 단위로 logrotate가 걸려있어 최근 로그만 파악할 수 있는 상태였는데 우선 공격성으로 대량 접근하는 IP가 존재하는지 확인하였고 의심되는 IP는 WAF에서 추가 검토하였는데 따로 공격성 접근은 아닌 것으로 파악되었습니다.

[root@ip-10-0-1-68 httpd]# cat /var/log/httpd/access_log | awk '{print $1}' | sort -n | uniq -c | grep -Ev "10.0|172.16|192.168|-" | sort -rn | head -n 10
    399 88.150.-.-
    319 121.125.-.-
    200 125.141.-.-
    186 63.141.-.-
     83 66.249.-.-
     75 66.249.-.-
     49 117.111.-.-
     46 52.79.-.-
     37 66.249.-.-
     36 45.146.-.-

sar를 이용하여 추가 검토를 진행하였습니다.
인스턴스 재시작 후에도 메모리 사용량이 80% 이상 계속 유지 중이었습니다.

[root@ip-10-0-1-68 ~]# sar -r
Linux 4.14.193-149.317.amzn2.x86_64 (ip-10-0-1-68.ap-northeast-2.compute.internal) 	05/22/2021 	_x86_64_	(1 CPU)

12:00:02 AM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
12:10:01 AM     65860    941080     93.46         0    103936   4407680    437.73    785580     28120       120
12:20:01 AM     58924    948016     94.15         0    106820   4414144    438.37    789028     31556       176
12:30:01 AM     66768    940172     93.37         0    103328   4410048    437.97    784968     28244       208
12:40:01 AM     64996    941944     93.55         0    102724   4410256    437.99    787600     26904       232
12:50:01 AM     61056    945884     93.94         0    103356   4414996    438.46    792132     26448        40
01:00:01 AM     68052    938888     93.24         0     96388   4412948    438.25    787572     24756       112
01:10:01 AM     63336    943604     93.71         0    100240   4414108    438.37    789356     27116       112
01:20:02 AM     65780    941160     93.47         0    102172   4408852    437.85    785084     29272       112
01:30:01 AM     61096    945844     93.93         0    108252   4408644    437.83    
.
. [생략]
.
08:26:04 AM       LINUX RESTART
08:36:33 AM       LINUX RESTART
08:40:02 AM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
08:50:01 AM    192852    814088     80.85      2088    365732   3775100    374.91    401104    280868       296
09:00:01 AM    203284    803656     79.81      2088    378252   3162244    314.04    376764    289192       328
09:10:01 AM    195364    811576     80.60      2088    378620   3171048    314.92    384684    289380       332
09:20:01 AM    194748    812192     80.66      2088    379568   3173428    315.16    383840    290344       328
09:30:01 AM    181256    825684     82.00      2088    379744   3187564    316.56    407336    280344       328
Average:       193501    813439     80.78      2088    376383   3293877    327.12    390746    286026       322

마지막으로 free 명령어로 확인해보니 buff/cache가 비워지지 않고 그대로 남아있는 상태였습니다.

[root@ip-10-0-1-68 ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:            983         448         125          60         408         338
Swap:             0           0           0

우선 아래 명령어를 이용하여 캐시 메모리를 지우고 메모리 확보를 진행 하였습니다.

[root@ip-10-0-1-68 ~]# sync && echo 3 > /proc/sys/vm/drop_caches
[root@ip-10-0-1-68 ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:            983         435         365          60         182         358
Swap:             0           0           0

(sync && echo 3 > /proc/sys/vm/drop_caches 명령어에 대해서는 아래에서 추가적인 설명을 하도록하겠습니다.)

이후 메모리는 정상화 되었으나 추가적인 조치를 하지 않으면 동일한 장애가 다시 발생할 수 있어 우선 swap을 생성하기로 했습니다.


Create Swap

약 2~3G 정도 크기의 볼륨을 생성해줍니다.
swap 볼륨을 추가할 인스턴스와 연결을 시켜줍니다.
[root@ip-10-0-1-68 ~]# fdisk -l
Disk /dev/xvda: 15 GiB, 16106127360 bytes, 31457280 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 66F46060-ED00-4D14-9841-F5CB6310A14A

Device       Start      End  Sectors Size Type
/dev/xvda1    4096 31457246 31453151  15G Linux filesystem
/dev/xvda128  2048     4095     2048   1M BIOS boot

Partition table entries are not in disk order.


Disk /dev/xvdb: 3 GiB, 3221225472 bytes, 6291456 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

연결이 잘됐는지 확인 후 이제 파티션을 아래와 같이 생성해주었습니다.

[root@ip-10-0-1-68 ~]# fdisk /dev/xvdb
Welcome to fdisk (util-linux 2.30.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xb9e2e385.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-6291455, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-6291455, default 6291455): 

Created a new partition 1 of type 'Linux' and of size 3 GiB.

Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): 82
Changed type of partition 'Linux' to 'Linux swap / Solaris'.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

[root@ip-10-0-1-68 ~]# fdisk -l | tail -n 9
Disk /dev/xvdb: 3 GiB, 3221225472 bytes, 6291456 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb9e2e385

Device     Boot Start     End Sectors Size Id Type
/dev/xvdb1       2048 6291455 6289408   3G 82 Linux swap / Solaris

swap 파티션이 잘 생성되었다면 mkswap으로 swap을 만들어주고 blkid에 나온 UUID를 참고하여 /etc/fstab에 추가해줍니다.
이 부분을 잘못 추가하게될 경우 정상 부팅이 되지않아 번거로운 추가 작업이 생길 수 있으니 잘 추가해줍시다.

[root@ip-10-0-1-68 ~]# mkswap /dev/xvdb1
[root@ip-10-0-1-68 ~]# blkid /dev/xvdb1
/dev/xvdb1: UUID="dc082f63-27d8-41b1-ad74-8b019162f766" TYPE="swap" PARTUUID="b9e2e385-01"
[root@ip-10-0-1-68 ~]# vi /etc/fstab

UUID=dc082f63-27d8-41b1-ad74-8b019162f766       swap    swap    defaults        0 0

[root@ip-10-0-1-68 ~]# swapon -a
[root@ip-10-0-1-68 ~]# swapon -s
Filename				Type		Size	Used	Priority
/dev/xvdb1                             	partition	3144700	0	-2

swapon 명령어에 -a 옵션을 주면 /etc/fstab에 있는 swap 파티션을 모두 enable 합니다.
-s 옵션은 사용중인 스왑 장치를 요약하여 볼 수 있습니다.

저는 볼륨을 2개 추가하여 하여 swap 볼륨 하나가 장애가 발생하더라도 나머지 하나로 작동할 수 있도록 해두었습니다.

[root@ip-10-0-1-68 ~]# swapon -s
Filename				Type		Size	Used	Priority
/dev/xvdb1                             	partition	3144700	0	-2
/dev/xvdc1                             	partition	3144700	0	-3

[root@ip-10-0-1-68 ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:            983         461         332          60         188         328
Swap:          6141           0        6141

Swapfile

swap 볼륨을 따로 추가할 수 없을 수도 있습니다.
그때는 swapfile을 만들어서 사용할 수 있는데 간단하게 swapfile을 만드는 방법만 설명하겠습니다.

// dd 명령어를 이용해서 용량 지정 및 swap파일을 만들어줍니다. 
(mkdir로 디렉토리 만들어두는 것 아닙니다.)
[root@manvscloud-test-pub-kr2 ~]# dd if=/dev/zero of=/swapfile bs=1MiB count=4096
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB) copied, 12.3267 s, 348 MB/s
//권한 변경
[root@manvscloud-test-pub-kr2 ~]# chmod 600 /swapfile
//스왑 생성
[root@manvscloud-test-pub-kr2 ~]# mkswap /swapfile
Setting up swapspace version 1, size = 4194300 KiB
no label, UUID=4e0d57c0-dd8f-4527-af2d-659ce04921b7

이후 /etc/fstab에 등록해주고 swapon -a 해주는 것은 동일합니다.

/swap01                          swap                swap    defaults        0 0

sync && echo 3 > /proc/sys/vm/drop_caches

Linux에서 아래 명령어를 이용하여 캐시를 비울 수 있습니다.

  • PageCache만 비우기
    sync && echo 1 > /proc/sys/vm/drop_caches
    (= sync; echo 1 > /proc/sys/vm/drop_caches)
  • dentries와 inodes 비우기
    sync && echo 2 > /proc/sys/vm/drop_caches
    (= sync; echo 2 > /proc/sys/vm/drop_caches)
  • PageCache, dentries, inodes 모두 비우기
    sync && echo 3 > /proc/sys/vm/drop_caches
    (= sync; echo 3 > /proc/sys/vm/drop_caches)

sync를 통해 파일 시스템 버퍼를 플러시합니다.
(개발쪽은 잘 모르지만 JAVA나 Python에서 flush() 함수가 버퍼 비우는 용도로 사용되는걸 본 적이 있습니다)

단 echo 3을 사용한다면 모두 비우기가 가능하지만 디스크 I/O가 활발한 시스템에서 사용하게 된다면 CPU 자원 사용량이 일시적으로 상승합니다.

  • pagecache : 리눅스 커널에 의해 사용되는 기본 디스크 캐시.
    대부분의 경우 커널은 디스크에서 읽거나 디스크에 쓸 때 페이지 캐시를 참조합니다.
    I/O 속도와 퍼포먼스를 높이기 위해 시스템이 할당한 임시 메모리 저장소로 임시 메모리에 저장된 파일을 다시 읽을 때 해당 메모리에서 바로 불러오기에 디스크의 읽기,쓰기 속도가 빨라집니다. (Windows에서는 동일한 역할로 페이지 파일이 있습니다.)
  • dentries : dcache, 즉 디렉토리 항목 캐시입니다. 경로/파일명을 특정 dentry로 변환하여 빠른 조회를 제공하며 디스크가 아닌 RAM에 저장됩니다. (inode를 검색하여 수행됩니다.)
  • inodes : 파일과 디렉토리에 관한 정보를 담고 있는 자료 구조
    (물리적 위치, 크기, 생성 일시, 권한)
[root@ip-10-0-1-68 ~]# vmstat -m | head -n 1; vmstat -m | grep proc_inode_cache
Cache                       Num  Total   Size  Pages
proc_inode_cache          13570  13570    688     23

⬆ (위 명령어로 inode 캐시값 확인이 가능합니다.)

※ TIP-1 (Slab) 😎

서비스 프로세스 할당량을 계산해보아도 전체 메모리에 비해 유휴 메모리가 없을 때가 있을 것입니다. 이는 커널에서 메모리를 사용하고 있기때문인데 커널에서 사용하고 있는 메모리는 slab 메모리 영역을 확인하면 얼마나 사용하고 있는지 알 수 있습니다.

[root@ip-10-0-1-68 ~]# cat /proc/meminfo | grep Slab
Slab:              48832 kB

Slab에 대한 내용이 깊이있게 설명되어 있는 곳은 링크로 남겨두었으니 참고바랍니다.

  • Slab : 메모리 영역 중 커널이 직접 사용하는 영역을 Slab영역이며 dentries와 inodes 캐시가 이 영역에 해당됩니다.
    (slabtop 명령어를 이용하여 현재 시스템의 slab 자료 구조 상태를 확인할 수 있습니다.)
[root@ip-10-0-1-68 ~]# slabtop
 Active / Total Objects (% used)    : 232162 / 241799 (96.0%)
 Active / Total Slabs (% used)      : 7662 / 7662 (100.0%)
 Active / Total Caches (% used)     : 74 / 101 (73.3%)
 Active / Total Size (% used)       : 55501.21K / 58750.71K (94.5%)
 Minimum / Average / Maximum Object : 0.01K / 0.24K / 9.50K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
 39580  39403  99%    0.20K   1979	 20	 7916K vm_area_struct
 38080  38080 100%    0.06K    595	 64	 2380K anon_vma_chain
 30072  30072 100%    0.19K   1432	 21	 5728K dentry
 19136  19089  99%    0.09K    416	 46	 1664K anon_vma
 15504  14550  93%    0.04K    152	102	  608K Acpi-Namespace
 15210  15210 100%    0.13K    507	 30	 2028K kernfs_node_cache
 13570  13570 100%    0.67K    590	 23	 9440K proc_inode_cache
 10868  10476  96%    0.60K    418	 26	 6688K inode_cache
  7808   6525  83%    0.03K     61	128	  244K kmalloc-32
  5746   4799  83%    0.94K    169	 34	 5408K xfs_inode
  5248   3838  73%    0.06K     82	 64	  328K kmalloc-64
  5180   3660  70%    0.57K    185	 28	 2960K radix_tree_node
  3822   2783  72%    0.09K     91	 42	  364K kmalloc-96
  3264   2517  77%    0.25K    102	 32	  816K kmalloc-256
  3248   3248 100%    0.07K     58	 56	  232K Acpi-Operand
  3072   3072 100%    0.02K     12	256        48K kmalloc-16
  3060   3060 100%    0.05K     36	 85	  144K ftrace_event_field
  2560   2560 100%    0.01K	 5	512        20K kmalloc-8
  2037   1762  86%    0.19K     97	 21	  388K kmalloc-192
  1610   1610 100%    0.09K     35	 46	  140K trace_event_file
  1536   1258  81%    0.50K     48	 32	  768K kmalloc-512
  1344   1046  77%    0.12K     42	 32	  168K kmalloc-128

※ TIP-2 (vfs_cache_pressure) 😎

vfs_cache_pressure는 리눅스 커널의 vm구조와 관련된 파라미터입니다.
vfs_cache_pressure를 이용해서 커널에게 디렉토리와 inode Object에 대한 캐시로 사용된 메모리를 반환하도록하는데 이 값이 0일 경우 커널이 오브젝트에 대한 캐시를 반환하지 않아 Out Of Memory가 발생합니다.
보통 이 값이 100으로 설정되어 있으나 자주 캐시를 반환하기 위해서는 이 값을 변경해주어야하며 값이 높아질수록 메모리에서 캐시를 보관하지 않게되어 dentries와 inodes 캐시를 줄일 수 있습니다.

[root@ip-10-0-1-68 ~]# cat /proc/sys/vm/vfs_cache_pressure
100

기본값은 100으로 되어있습니다.
/proc/sys/vm/vfs_cache_pressure 에 값을 지정해주는 것은 일회성이니 sysctl.conf에 설정해줍니다.

[root@ip-10-0-1-68 ~]# vi /etc/sysctl.conf 이후 아래값을 추가 및 저장, load 해줍니다
vm.vfs_cache_pressure = 10000
[root@ip-10-0-1-68 ~]# sysctl -p

Personal Comments and Wrap-up

아직 캐시 메모리를 비우고 swap 생성만 해두었습니다.
이걸로 완벽하게 해결됐다고 보기는 어렵습니다. 이후 메모리 사용량 경보를 추가하여 알림 설정을 하고 현재 오토스케일링 추가를 생각하고 있습니다.
(우선 오토스케일링 추가 전 서버 내 자원 최적화 작업을 먼저 진행해야겠습니다.)

그리고 이번 메모리 최적화에 도움주신 리눅서님에게 감사의 인사올립니다.
(아… 난 왜 swap을 잊고있었지? 매번 감사합니다…🙇🏻‍♂️ 덕분에 이번 기회로 메모리에 대해 많이 공부한 것같습니다.)

IT/Linux/Kubernetes

Rocky Linux 8.3 Release Candidate 1 출시 / Test Installation

안녕하세요. ManVSCloud 김수현입니다.

어제 일자로 기다리던 ROCKY LINUX 8.3 RELEASE CANDIDATE 1이 출시되었습니다.
아직 불안정한 시험판으로 나오긴 했으나 상당히 기대되지 않을 수 없습니다.

Rocky Linux 는 CentOS 프로젝트의 창시자인 Gregory Kurtzer 가 시작한 프로젝트로 현재의 CentOS 처럼 RHEL 의 공개 소스를 가져와서 다시 빌드하고 패키징하는 것을 목표로 하고 있으며 심지어 RHEL 의 버그까지 똑같이 재연하는 것을 목표로 하고 있습니다.

레드햇 측에서 CentOS 프로젝트가 CentOS 8 지원을 2021 년 말에 종료하는 것을 발표했었습니다. CentOS 7 버전이 2024 년까지 계속 지원될 예정이지만 CentOS 8의 지원 종료 기간이 2021년 12월 31일로 정해지며  Red Hat Enterprise Linux 8 에 대한 무료 배포판 역할이 사라지게 된 것입니다.

물론 아직까지 지원 종료가 되어버린 CentOS4,5,6을 사용하는 유저들도 존재하는 것으로 알고있습니다. 2024년도 이후 CentOS 7 마저 지원이 종료된다면 보안 패치의 부재와 Repo 중단으로 많은 불편함이 존재할 것입니다.

기존 CentOS 8 유저나 OS 버전 업이 필요할 경우 CentOS Stream으로 전환이 필요하게됩니다.

https://www.lesstif.com/lpt/centos-8-centos-stream-98927171.html

CentOS 가 종료되고 CentOS Stream 로 전환되는 22년부터는 아래와 같은 관계가 됩니다.

https://www.lesstif.com/lpt/centos-8-centos-stream-98927171.html

즉, 안정성 입증이 어려워졌고 신뢰성이 떨어진 현재 CentOS를 더 사용하기 애매해져버린 상황입니다.

오늘은 어제 발표된 ROCKY LINUX 8.3 RELEASE CANDIDATE 1을 간단하게 설치해보는 것까지 진행해볼 것이고 이후 서비스 운영부분까지 테스트해볼 예정입니다.


설치

설치는 간단하게 “Rocky-8.3-x86_64-minimal” 로 설치했습니다.
좌측에 Rocky Linux가 매력있는 듯합니다.

아직 정식 출시가 아닌 RC라 개발 및 테스트 목적으로만 사용하시길 바랍니다.

설치 및 부팅 후 CLI 콘솔 화면에서 Rocky 로고가 나옵니다.
Rocky Linux 설치 시 cockpit이 설치가 되어있나봅니다.

  • cokpit : Web UI 기반의 모니터링 및 관리 툴입니다.
원래는 9090포트입니다. (포트포워딩 해둬서 9999상태)
[아래 네트워크 작업을 한 뒤 확인 한 것]

NAME이 Rocky Linux로 나오네요.
멋있습니다.

네트워크 설정을 간단히 마쳐주고 간단하게 이런저런 설치만 해보았습니다.

Rocky Linux 8.3 AppStream 에서 dnf 로 php 설치 시 기본 버전이 7.2로 되어있습니다.

dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm

위 명령어처럼 EPEL 저장소를 추가해주어야 dnf module list php 명령어를 입력했을 때 추가 버전을 확인할 수 있을 것입니다.

그외에도 ImageMagick을 설치 시 –set-enabled powertools 을 해주어야하는 부분 역시 CentOS 8과 동일했습니다.

dnf install -y epel-release
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf config-manager --set-enabled powertools
dnf install -y ImageMagick ImageMagick-devel
pecl install imagick
echo "extension=imagick.so" > /etc/php.d/20-imagick.ini
cat /etc/php.d/20-imagick.ini

# Repo 추가 및 사용 방법도 CentOS8과 동일함

vi /etc/yum.repos.d/MariaDB.repo

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.5/centos8-amd64
module_hotfixes=1
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

dnf install MariaDB-server MariaDB-client –disablerepo=AppStream

그 외에도 이런 저런 간단한 설치들을 하는데에 크게 문제없이 잘 되는듯보였습니다.
간단한 설치 테스트는 여기서 마치고 이후에는 CentOS 7에서 서비스를 CentOS8로 이전, 서비스 정상 작동 여부까지 확인 해볼 것입니다.


후기

오래 전부터 기다리고 있던 Rocky Linux의 RC 1 이 나와서 정말 기뻤습니다.
이번 설치 테스트 때 GUI 설치 후 GUI 구경을 못해본 게 아쉬운데 다음 테스트 때 설치해서 구경해야겠습니다.

Rocky Linux의 정식 출시를 응원하며 글을 마무리하도록 하겠습니다.

긴글 읽어주셔서 감사합니다.

IT/Linux/Kubernetes

PHP8.0.1 컴파일 설치 (APM+wordpress)

안녕하세요. ManVSCloud 김수현입니다.

오늘은 2021-01-07에 나온 PHP 8.0.1 버전을 컴파일 설치해보려고 합니다.

테스트는 WordPress까지 연동하여 정상적으로 플러그인 설치 및 글쓰기가 되는지까지 확인할 것입니다.

Environment

CentOS Linux release 7.7.1908 (Core) x86_64
CPU : Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz (4core)
Memory : 16G
(PHP 컴파일 시 out of memory 발생하여 인스턴스 크기를 m4.xlarge로 하여 테스트 했습니다.)
Apache : httpd-2.4.6-97.el7.centos.x86_64
PHP : PHP 8.0.1 (cli)
MariaDB : MariaDB-server-10.4.17-1.el7.centos.x86_64
WordPress : 5.6

Apache와 MariaDB는 RPM으로 설치하였습니다.

Basic Install & Setting

1  cat -n /etc/selinux/config
2  sed -i '7s/enforcing/disabled/g' /etc/selinux/config
3  yum install gcc gcc* make cmake libtool wget zip unzip autoconf automake libjpeg-devel libpng-devel freetype-devel libxml2-devel libicu* hspell libvoikko enchant-devel libffi-devel libcurl-devel libldap* sqlite-devel "Image*" *imap-devel pam-devel openssl-devel firebird-devel aspell-devel readline-devel net-snmp-devel libsodium-devel yum install libtidy libtidy-devel libxslt-devel git bzip2-devel 

#(위에서 설치가 안될 수도 있습니다. 이후 epel 추가 후 재설치하면 나머지가 설치됩니다.)

4  init 6

원활한 설치를위해 selinux 기능을 꺼주고 기본 라이브러리들을 설치해준 뒤
재시작을 해줍니다.
(기본 라이브러리는 사용하실 부분만 골라서 설치하셔도 됩니다.)

Apache & MariaDB Install

[Apache]

yum install httpd httpd-devel -y
cp -avp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf_org

#[root@ip-10-0-1-238 conf]# cat -n /etc/httpd/conf/httpd.conf | grep Indexes
#135 # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#144 Options Indexes FollowSymLinks

sed -i '144s/Indexes//g' /etc/httpd/conf/httpd.conf
#(144번줄에 있는 Indexes를 제거해주도록 하겠습니다.)

#[root@ip-10-0-1-238 ~]# cat -n /etc/httpd/conf/httpd.conf | grep -A 3 "Directory /"
#102 <Directory />
#103 AllowOverride none
#104 Require all denied
#105 </Directory>

perl -p -i -e '$.==104 and print " Require all granted\n"' /etc/httpd/conf/httpd.conf
sed -i '105s/ Require all denied/#&/' /etc/httpd/conf/httpd.conf
#(104 번줄에 접근 허용 설정 및 denied 부분은 주석 처리해주겠습니다.)

#[root@ip-10-0-1-238 ~]# cat -n /etc/httpd/conf/httpd.conf | grep -A 4 "Directory /"
#102 <Directory />
#103 AllowOverride none
#104 Require all granted
#105 # Require all denied
#106 </Directory>

cat << EOF >> /etc/httpd/conf/httpd.conf
ServerTokens Prod
ServerSignature Off
<IfModule mpm_prefork_module>
StartServers 40 
MinSpareServers 25 
MaxSpareServers 100 
ServerLimit 1024 
MaxRequestWorkers 1024 
MaxConnectionsPerChild 0
</IfModule>
IndexIgnore *
EOF

cat /etc/httpd/conf/httpd.conf | tail -n 11
#위 명령어로 httpd.conf에 옵션이 잘 들어갔는지 확인합니다.

cat << EOF > /etc/httpd/conf.d/vhost.conf
<VirtualHost *:80>
ServerName php.manvscloud.com
DocumentRoot /home/php/wordpress/
</VirtualHost>
EOF

mkdir -p /home/php/wordpress

apachectl -S
#위 명령어로 virtual host가 정상적으로 추가되었는지 확인합니다.

systemctl enable httpd
systemctl start httpd

[MariaDB]

cat << EOF > /etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.4/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
EOF

yum install MariaDB-server MariaDB-client -y

systemctl enable mariadb
systemctl start mariadb

mysql -uroot -p

create database wordpress;
create user 'manvscloud'@'localhost' identified by 'PW';
grant all privileges on wordpress.* to 'manvscloud'@'localhost';
flush privileges;
exit

PHP 8.0.1

cd /usr/local/src
wget https://www.php.net/distributions/php-8.0.1.tar.gz
tar zxvf php-8.0.1.tar.gz
./configure –help > phpconf_help.txt

생성한 phpconf_help.txt 를 잘 읽어보자. ★★★★★

아래는 php 컴파일 중에 설치가 덜 되거나 추가로 설정해주어야하는 부분이 있어
정리해보았습니다.
(oracle, postgresql 제외)

컴파일 중 oniguruma가 없다는 에러가 발생했습니다.
(No package ‘oniguruma’ found)

oniguruma-devel를 설치해주어야하는데 epel-release 설치를 하지 않고
oniguruma-devel를 설치할 경우 패키지를 찾을 수 없습니다.

(No package oniguruma-devel available.)

yum install epel-release
yum install oniguruma-devel

-. libzip
configure: error: Package requirements (libzip >= 0.11 libzip != 1.3.1 libzip != 1.7.0) were not met:No package ‘libzip’ found

CentOS7에서 libzip yum으로 설치할 경우 0.10.1-8.el7으로만 설치되어 따로 컴파일해주었습니다.

cd /usr/local/src
wget https://libzip.org/download/libzip-1.7.3.tar.gz
tar zxvf libzip-1.7.3.tar.gz
cd libzip-1.7.3
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/libzip

libzip 1.7.3 버전을 컴파일 하기위해서는 cmake 3.0.2 이상이 필요했습니다.
CMake Error at CMakeLists.txt:1 (cmake_minimum_required):
CMake 3.0.2 or higher is required. You are running version 2.8.12.2


wget https://github.com/Kitware/CMake/releases/download/v3.18.5/cmake-3.18.5-Linux-x86_64.tar.gz
tar zxvf cmake-3.18.5-Linux-x86_64.tar.gz
mv cmake-3.18.5-Linux-x86_64 /usr/local/cmake

/usr/local/cmake/bin/cmake -DCMAKE_INSTALL_PREFIX=/usr/local/libzip
make && make install

export PKG_CONFIG_PATH=/usr/local/libzip/lib64/pkgconfig
(이후 /etc/profile 에 넣어 줍시다.)

-. ldap
cp -frp /usr/lib64/libldap* /usr/lib

./configure --prefix=/usr/local/php \
--with-apxs2=/usr/bin/apxs \
--with-config-file-path=/etc/ \
--with-config-file-scan-dir=/etc/php.d \
--enable-gd \
--with-zlib \
--with-freetype \
--with-jpeg \
--with-curl \
--with-pear \
--with-openssl \
--enable-bcmath \
--with-bz2 \
--enable-calendar \
--enable-ctype \
--enable-dba \
--enable-dom \
--with-enchant \
--enable-exif \
--with-ffi \
--enable-fileinfo \
--enable-filter \
--enable-ftp \
--with-gettext \
--with-gmp \
--with-iconv \
--enable-intl \
--with-ldap \
--enable-mbstring \
--with-mysqli \
--enable-mysqlnd \
--enable-pcntl \
--enable-pdo \
--with-pdo_firebird \
--with-pdo_mysql \
--with-pdo_sqlite \
--enable-phar \
--enable-posix \
--with-pspell \
--with-readline \
--enable-session \
--enable-shmop \
--with-snmp \
--enable-soap \
--enable-sockets \
--with-sodium \
--with-sqlite3 \
--enable-sysvmsg \
--enable-sysvsem \
--enable-sysvshm \
--with-tidy \
--enable-tokenizer \
--with-xsl \
--with-zip \
--enable-simplexml \
--with-libxml \
--enable-xml \
--enable-xmlreader \
--enable-xmlwriter \
--enable-opcache
make -j `grep processor /proc/cpuinfo | wc -l`
#(j옵션을 주어 컴파일 속도를 최적화 합니다.)

/bin/ld: ext/ldap/ldap.o: undefined reference to symbol 'ber_memfree'
#(make 중에 ldap 쪽에서 위와 같은 에러가 발생했습니다.)
#(아래처럼 Makefile을 수정할 필요가 있었습니다.)

vi Makefile
EXTRA_LIBS = -lcrypt -ltidy -lresolv -lcrypt -lreadline -lncurses -laspell -lpspell -lfbclient -lrt -lldap -llber -lstdc++ -lgmp -lbz2 -lutil -lrt -lm -ldl -lxml2 -lssl -lcrypto -lsqlite3 -lz -lcurl -lxml2 -lenchant -lgmodule-2.0 -lglib-2.0 -lffi -lssl -lcrypto -lz -lpng15 -ljpeg -lfreetype -licuio -licui18n -licuuc -licudata -lonig -lsqlite3 -lxml2 -lnetsnmp -lssl -lssl -lcrypto -lm -lxml2 -lsodium -lxml2 -lxml2 -lxml2 -lxslt -lz -ldl -lm -lxml2 -lexslt -lxslt -lz -lm -lgcrypt -ldl -lgpg-error -lxml2 -lzip -lz -lssl -lcrypto -lcrypt
#(위와 동일한 에러 발생 시 Makefile에 EXTRA_LIBS 쪽에 -llber 추가)

make -j `grep processor /proc/cpuinfo | wc -l`
make install

cp -avp php.ini-production /etc/php.ini


cat << EOF >> /etc/profile
export PKG_CONFIG_PATH=/usr/local/libzip/lib64/pkgconfig
PATH=$PATH:/usr/local/php/bin
export PATH
EOF

source /etc/profile

< imagick 모듈 추가 >
cd /usr/local/src
wget https://pecl.php.net/get/imagick-3.4.4.tgz
tar zxvf imagick-3.4.4.tgz
cd imagick-3.4.4
phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make

/usr/local/src/imagick-3.4.4/imagick_file.c:313:112: error: expected ??;??, ??,?? or ??)?? before ??TSRMLS_DC??
zend_bool php_imagick_stream_handler(php_imagick_object *intern, php_stream *stream, ImagickOperationType type TSRMLS_DC)
^
make: *** [imagick_file.lo] Error 1


(php8에서는 imagick이 정상적으로 설치가 되지않고 Error가 발생했습니다.
동일한 오류가 해외쪽에서도 있었는지 찾다보니 git에서 8버전에서 사용할 수 있는
imagick을 찾게 되었습니다.)

git clone https://github.com/Imagick/imagick.git
cd imagick
phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make

mkdir -p /etc/php.d/modules
cp -a /usr/local/src/imagick/modules/imagick.so /etc/php.d/modules/imagick.so
< opcache 모듈 설치 >

컴파일 시 추가했던 opcache가 자동으로 올라오지 않아 수동으로 추가해주었습니다.

cd /usr/local/src/php-8.0.1/ext/opcache
phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
cp -a /usr/local/src/php-8.0.1/ext/opcache/modules/opcache.so /etc/php.d/modules/opcache.so

(php.ini에 imagick과 opcache 모듈을 추가 해줍니다.)
cat << EOF >> /etc/php.ini
extension=/etc/php.d/modules/imagick.so
zend_extension=/etc/php.d/modules/opcache.so
EOF

마지막으로 httpd.conf에 아래 값을 추가 한 뒤 마무리합니다.

<IfModule dir_module>
DirectoryIndex index.html index.php
</IfModule>

AddType application/x-httpd-php .php .htm .html .inc
AddType application/x-httpd-php-source .phps


WordPress Install & TEST

cd /home/php
wget https://ko.wordpress.org/latest-ko_KR.tar.gz
tar zxvf latest-ko_KR.tar.gz
cd wordpress
cp -a wp-config-sample.php wp-config.php

vi wp-config.php

wp.config.php에서 위 mariadb에서 만들어준 DB와 계정 정보를 넣어줍니다.

/** The name of the database for WordPress */
define( ‘DB_NAME’, ‘wordpress’ );
/** MySQL database username */
define( ‘DB_USER’, ‘manvscloud’ );
/** MySQL database password */
define( ‘DB_PASSWORD’, ‘PW’ );
/** MySQL hostname */
define( ‘DB_HOST’, ‘127.0.0.1’ );
/** Database Charset to use in creating database tables. */
define( ‘DB_CHARSET’, ‘utf8’ );
/** The Database Collate type. Don’t change this if in doubt. */
define( ‘DB_COLLATE’, ” );

임시로 /home/php 사용자/그룹 권한을 apache로 한 뒤 Apache를 재시작합니다.
(테스트 후 사용자/그룹 권한을 변경하는 것을 권장합니다.)

chown -R apache:apache /home/php
apachectl rstart

[ 사이트 접속 해보기 ]

글쓰기 테스트 및 플러그인 설치/활성화까지 잘 되었습니다.
(플러그인 설치를 원활히 하려면 wp-config.php에 추가 옵션이 필요할 수 있습니다.)

PHP8에서 추가되거나 달라지는 부분은 추가 링크로 남기도록 하겠습니다.
https://www.php.net/releases/8.0/en.php
https://www.inflearn.com/course/php8-new-features#

PHP 8버전 컴파일은 성공적이었습니다.
마지막으로 PHP 8 컴파일 컨텐츠를 해볼 수 있도록 제안해주신 리눅서님에게
감사의 인사 올립니다. 많은 공부가 되었습니다.
https://linuxer.name/

긴 글 읽어주셔서 감사합니다.