Browsing Tag

Linux

NCP

[NCP] 네이버 클라우드에서 2TB 이상 파티션 사용하기 – Windows편

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

오늘은 네이버 클라우드에서 Server 사용 시 Windows 환경에서 2TB 이상 파티션을 사용하는 방법에 대해 알아보도록 하겠습니다.


Environment and Description

📢 사용된 OS : win-2016-64-en

Linux 편에서도 설명했듯 네이버 클라우드에서 스토리지를 추가하여 생성할 때 최대 볼륨 크기는 2000GB로 제한되어 있습니다.

Linux 환경에서는 LVM(Logical Volume Manager)을 이용하여 최대 용량을 4TB, 6TB까지도 늘려보았습니다. 그렇다면 Windows 환경에서는 어떻게 파티션 최대 용량을 늘릴 것인가에 대해서 알아봅시다.


Adding capacity using storage pools

우선 위 이미지와 같이 서버에 추가할 스토리지 2개를 생성합니다.
2000GB 용량으로 2개의 스토리지를 생성해주었습니다.

이후 서버에 접속하여 아래 이미지만 순서대로 따라 해주면됩니다.
TIP이라면 중간에 뭔가 잘 안된다 싶으면 F5를 눌러 최신화 해줍시다.
설정한 것이 즉각 최신화가 안돼서 적용하려면 새로고침이 필요하더라구요…

서버 관리자에서 File and Storage Services로 클릭해줍시다.
Storage Pools 입장!!
TASKS – New Storage Pool
Next를 눌러서 넘어갑시다.
이름 정해주고 Next
추가할 물리적 디스크를 선택하고 Next를 눌러줍니다.
VIRTUAL DISKS 쪽에서 TASKS – New Virtual DISK를 눌러줍니다.
Storage Pool 선택 OK
Next 클릭
동일하게 이름 정해주고 Next를 눌러줍시다.

이 부분이 중요한데 Simple이 우리가 아는 RAID 0, Mirror가 RAID 1, Parity가 RAID 5입니다.
RAID에 대한 부분은 따로 설명하지 않으니 RAID가 궁금하실 경우 검색해보시면 자료가 많으니 찾아보시기 바랍니다.

여기서 Thin으로 해줬습니다. Fixed를 해주니 이후에 추가 확장이 정상적으로 되지 않는 증상이 발견되어 Thin으로 선택해주었습니다. 용량이 적을 때는 Fixed로 해도 추가 확장이 잘 되는데 2TB만 넘어가면 추가 확장이 되지 않습니다. 그런데 Thin으로 해주면 이후 2TB가 넘어가도 추가 확장이 가능합니다.

원하는 가상 디스크 크기를 설정 후 Next를 눌러줍니다.
Create를 눌러 생성해줍시다.
이어서 볼륨 생성까지 하게되는데 바로 Next를 눌러주면 됩니다.
이 부분도 Next를 눌러주면 됩니다.
볼륨 사이즈 지정해주고 Next!
Drive letter 설정 후 Next
파일시스템 및 레이블 설정 후 Next
이제 Create만 눌러주면 정상적으로 모든 작업이 마무리됩니다.
방금 생성한 4TB짜리 D드라이브 입니다.

위 작업 후 추가적인 테스트도 진행하였습니다.

RAID 0, RAID 1, RAID 5만 있어서 RAID 10은 RAID 1로 묶어주고 다시 0으로 묶어주는 작업을 해야하나? 싶어서 Storage Pool에서 1로 묶은 뒤 추가적으로 0으로 묶어주려고 했는데 Storage Pool에서는 그렇게 되지 않더라구요.

그런데 이게 diskmgmt.msc (디스크 관리)에서도 Span(JBOD), Simple(RAID 0), Mirror(RAID 1), Parity(RAID 5) 기능이 있단 말이죠?
Storage Pool에서 RAID 1로 묶은 두 디스크가 diskmgmt.msc (디스크 관리)에서 0으로 묶을 수 있길래 재미삼아 한번 해봤는데…

되긴 됩니다.. 그런데 이게 정상적이지는 않아보였습니다.😑
디스크 관리에서 RAID 1 디스크 2개를 0으로 추가로 묶어줄 때 12시간이 소요됐습니다.
무려 테스트는 200GB 디스크 4개로 했는데 상당히 오랜 시간이 소요된 것입니다.

이게 과연 정상적일까…🙄
이렇게 써보신 경험이 있으시다면 댓글로 공유해주세요~


Volume Expansion

자 이제 위에서 구성한 Storage Pool에서 파티션 크기를 더 확장 해보겠습니다.
기존 4TB에서 6TB로 확장하기 위해 스토리지 하나를 더 생성해주었습니다.

디스크 생성 및 추가 후 Storage Pool에서 위 이미지와 같이 Add Physical Disk를 선택해줍니다. 추가할 Disk가 보이지 않는 다면 F5를 눌러 최신화 해줍시다.

Add Physical DIsk

Physical Disk가 정상적으로 추가되면 이제 위 이미지처럼 Virtual Disks에서 Extend Virtual Disk를 선택하여 가상 디스크를 확장해주도록 합시다.

확장할 최대 크기를 입력해줍니다.

[윈도우 키+ R]을 누르신 후 diskmgmt.msc를 실행하여 디스크 관리를 켜줍니다.

위 이미지처럼 기존 4TB 디스크에서 Extend Volume을 눌러 디스크를 확장해주도록 합시다.

추가한 용량을 선택해주고 Next를 눌러줍니다.

Finish를 눌러 마무리 해주면 아래 이미지와 같이 정상적으로 5.85TB까지 크기가 확장된 것을 확인하실 수 있습니다.

Disk 확장 마무리 확인

Benchmark performance testing

이 포스팅을 준비하면서 Storage Pool을 이용하여 RAID를 묶었을 때 성능 테스트가 궁금해서 벤치마크 성능 테스트도 함께 해보았습니다. 벤치마크 툴은 ATTO Disk Benchmark 를 사용하였습니다.

Raid 설정을 하지 않은 일반 DISK
디스크를 2개를 SIMPLE (RAID 0)로 묶었을 때
디스크를 3개를 SIMPLE (RAID 0)로 묶었을 때

수치를 보면 확실히 디스크 3개를 RAID 0 으로 묶었을 때가 가장 Write/Read 수치가 높게 나왔습니다. 그런데 이 과정에 재밌는 사실을 하나 알아냈는데 디스크 3개를 RAID 0으로 묶었을 때와 디스크 2개를 RAID 0 으로 묶은 뒤 이후에 추가로 디스크를 1개 더 추가 확장하였을 때 동일한 용량인데 다른 수치를 보였습니다.

디스크 3개를 RAID 0 으로 묶었을 때
: I/O Size 64MB 기준 Write, Read = 264.37, 257.55 MB/s

디스크 2개를 RAID 0 으로 묶고 이후 디스크 1개를 추가 확장했을 때
: I/O Size 64MB 기준 Write, Read = 176.12, 169.78 MB/s

디스크 2개를 RAID 0 으로 묶었을 때
: I/O Size 64MB 기준 Write, Read = 175.34, 169.54 MB/s

RAID를 하지 않았을 때
: I/O Size 64MB 기준 Write, Read = 86.10, 85.05 MB/s

위와 같은 수치가 나왔었습니다.

애초에 처음 RAID를 잡을 때 크게 묶지 않는다면 이후 디스크를 추가하는 부분은 수치가 변하지 않는?…


Note

윈도우 Storage pool 역시 백업을 스냅샷이 아닌 이미지 생성으로 진행해야합니다.

이후 서버에 문제가 생겼을 때 생성된 이미지로 서버를 재생성하면 구성된 Storage pool까지 전부 그대로 올라오는데 스냅샷은 그렇게 되지 않습니다.

단, Linux 편에서도 언급했듯 이미지 백업으로 서버를 생성하면 서버 생성 시 스토리지 종류를 SSD로 선택할 경우 나머지 볼륨들도 전부 SSD로 생성된다는 점!!

OS는 SSD 추가 스토리지를 HDD로 나누어야할 경우 동일하게 서버 생성 후 구성하여 데이터를 복사해줘야합니다.


Personal Comments

여기까지 네이버 클라우드 윈도우 환경에서 2000GB를 초과하는 파티션도 마무리했습니다.

Storage Pool을 이용해서 software RAID를 구성하고 파티션 크기를 확장해보았는데 나름 괜찮은 것같습니다. 원하시는 구성에 맞춰서 RAID 0, RAID 1, RAID5 설정을 하셔서 사용하면 좋을 것같습니다.

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

NCP

[NCP] 네이버 클라우드에서 2TB 초과하는 파티션 사용하기 – Linux편

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

오늘은 네이버 클라우드 Linux 환경에서 2TB 용량을 초과하는 파티션 사용법에 대해 포스팅하였습니다.

원래 Windows 부터 자료 다 준비해놨는데 포스팅 이미지들을 전부 회사에 두고온 관계로…
Linux편을 먼저 포스팅해보겠습니다.🙄

우선 테스트 환경와 어떻게 2TB를 초과하는 용량의 파티션을 생성할 것인가에 대해 알아보도록 합시다.


Environment and Description

📢 사용된 OS : centos-7.8-64

네이버 클라우드에서 스토리지를 추가하여 생성할 때 최대 볼륨 크기는 2000GB로 제한되어 있습니다.

그렇다면 어떻게 2000GB가 넘는 파티션을 생성할 것이냐?

우선 결론부터 말하자면 LVM(Logical Volume Manager)을 사용하여 파티션을 생성할 것입니다.

LVM에 대해 깊게 설명하는 포스팅은 아니니 간단하게 설명하자면 LVM을 이용한다면 여러 개의 물리적인 디스크 파티션을 논리적인 그룹으로 묶은 뒤 개별적인 논리 디스크로 할당하여 유연성있게 사용할 수 있습니다.

LVM에 대해 더 자세히 알고 싶으시다면 LVM에 대한 개념과 명령어에 대해 검색하여 확인 해보시기 바랍니다.


Create partitions using LVM

우선 위 이미지와 같이 서버에 추가할 스토리지 2개를 생성합니다.
2000GB 용량으로 2개의 스토리지를 생성해주었습니다.

[root@s17ab8051000 ~]# fdisk -l

Disk /dev/xvda: 53.7 GB, 53687091200 bytes, 104857600 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
Disk label type: dos
Disk identifier: 0x000ac8f2

    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1   *        2048     2099199     1048576   83  Linux
/dev/xvda2         2099200   104857599    51379200   83  Linux

Disk /dev/xvdb: 2147.5 GB, 2147483648000 bytes, 4194304000 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


Disk /dev/xvdc: 2147.5 GB, 2147483648000 bytes, 4194304000 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

서버 내에서 fdisk -l 명령어로 확인해보면 추가된 두개의 스토리지를 확인할 수 있습니다.

[root@s17ab8051000 ~]# fdisk /dev/xvdb

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-4194303999, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-4194303999, default 4194303999): 
Using default value 4194303999
Partition 1 of type Linux and of size 2 TiB is set

fdisk /dev/xvdb 를 이용하여 파티션을 생성해줍시다.

1. n을 눌러 새로 생성해줍니다.
2. p를 눌러 주 파티션을 생성해줍니다.
3. 파티션 넘버를 정해주는데 default가 1로 되어있어 그냥 엔터만 쳐도 됩니다.
4. First sector는 섹터 시작점 Last sector는 섹터가 끝나는 부분을 지정해주는 건데 그냥 엔터를 눌러주어 전체 용량 지정해줍시다.

Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): l

 0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris        
 1  FAT12           27  Hidden NTFS Win 82  Linux swap / So c1  DRDOS/sec (FAT-
 2  XENIX root      39  Plan 9          83  Linux           c4  DRDOS/sec (FAT-
 3  XENIX usr       3c  PartitionMagic  84  OS/2 hidden C:  c6  DRDOS/sec (FAT-
 4  FAT16 <32M      40  Venix 80286     85  Linux extended  c7  Syrinx         
 5  Extended        41  PPC PReP Boot   86  NTFS volume set da  Non-FS data    
 6  FAT16           42  SFS             87  NTFS volume set db  CP/M / CTOS / .
 7  HPFS/NTFS/exFAT 4d  QNX4.x          88  Linux plaintext de  Dell Utility   
 8  AIX             4e  QNX4.x 2nd part 8e  Linux LVM       df  BootIt         
 9  AIX bootable    4f  QNX4.x 3rd part 93  Amoeba          e1  DOS access     
 a  OS/2 Boot Manag 50  OnTrack DM      94  Amoeba BBT      e3  DOS R/O        
 b  W95 FAT32       51  OnTrack DM6 Aux 9f  BSD/OS          e4  SpeedStor      
 c  W95 FAT32 (LBA) 52  CP/M            a0  IBM Thinkpad hi eb  BeOS fs        
 e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a5  FreeBSD         ee  GPT            
 f  W95 Ext'd (LBA) 54  OnTrackDM6      a6  OpenBSD         ef  EFI (FAT-12/16/
10  OPUS            55  EZ-Drive        a7  NeXTSTEP        f0  Linux/PA-RISC b
11  Hidden FAT12    56  Golden Bow      a8  Darwin UFS      f1  SpeedStor      
12  Compaq diagnost 5c  Priam Edisk     a9  NetBSD          f4  SpeedStor      
14  Hidden FAT16 <3 61  SpeedStor       ab  Darwin boot     f2  DOS secondary  
16  Hidden FAT16    63  GNU HURD or Sys af  HFS / HFS+      fb  VMware VMFS    
17  Hidden HPFS/NTF 64  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE 
18  AST SmartSleep  65  Novell Netware  b8  BSDI swap       fd  Linux raid auto
1b  Hidden W95 FAT3 70  DiskSecure Mult bb  Boot Wizard hid fe  LANstep        
1c  Hidden W95 FAT3 75  PC/IX           be  Solaris boot    ff  BBT            
1e  Hidden W95 FAT1 80  Old Minix   
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'

Command (m for help): w

이어서 해당 파티션의 타입을 지정해주어야하는데 타입의 종류는 l(L)을 입력하여 타입에 대한 모든 Hex code를 볼 수 있습니다.
우리는 Linux LVM을 사용해야하니 8e를 사용 해줄 것입니다.

5. t를 입력하여 파티션 타입 지정
6. 8e 입력하여 Linux LVM로 지정해줍니다.
7. w (저장)

위 과정을 추가한 두 디스크 /dev/xvdb, /dev/xvdc 모두 설정해주어야 합니다.

[root@s17ab8051000 ~]# fdisk -l

Disk /dev/xvda: 53.7 GB, 53687091200 bytes, 104857600 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
Disk label type: dos
Disk identifier: 0x000ac8f2

    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1   *        2048     2099199     1048576   83  Linux
/dev/xvda2         2099200   104857599    51379200   83  Linux

Disk /dev/xvdb: 2147.5 GB, 2147483648000 bytes, 4194304000 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
Disk label type: dos
Disk identifier: 0x09ecabef

    Device Boot      Start         End      Blocks   Id  System
/dev/xvdb1            2048  4194303999  2097150976   8e  Linux LVM

Disk /dev/xvdc: 2147.5 GB, 2147483648000 bytes, 4194304000 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
Disk label type: dos
Disk identifier: 0x0a3c26f7

    Device Boot      Start         End      Blocks   Id  System
/dev/xvdc1            2048  4194303999  2097150976   8e  Linux LVM

두 스토리지 전부 정상적으로 생성했다면 /dev/xvdb1, /dev/xvdc1가 Linux LVM으로 잘 생성된 것을 확인할 수 있습니다.

[root@s17ab8051000 ~]# rpm -qa | grep lvm2
lvm2-libs-2.02.186-7.el7_8.2.x86_64
lvm2-2.02.186-7.el7_8.2.x86_64

이제 논리적 볼륨으로 관리해줄 것입니다.
lvm2가 설치되어 있어야하지만 네이버 클라우드에서는 이미 설치가 되어 있었습니다.

[root@s17ab8051000 ~]# pvcreate /dev/xvdb1
  Physical volume "/dev/xvdb1" successfully created.
[root@s17ab8051000 ~]# pvcreate /dev/xvdc1
  Physical volume "/dev/xvdc1" successfully created.

pvcreate 명령어를 이용하여 fdisk로 만든 파티션을 물리적 볼륨(PV)으로 생성해줍니다.

[root@s17ab8051000 ~]# pvdisplay
  "/dev/xvdb1" is a new physical volume of "1.95 TiB"
  --- NEW Physical volume ---
  PV Name               /dev/xvdb1
  VG Name               
  PV Size               1.95 TiB
  Allocatable           NO
  PE Size               0   
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               gcpy02-Fe7l-4Klb-pQed-z726-sgmY-JQXe6R
   
  "/dev/xvdc1" is a new physical volume of "1.95 TiB"
  --- NEW Physical volume ---
  PV Name               /dev/xvdc1
  VG Name               
  PV Size               1.95 TiB
  Allocatable           NO
  PE Size               0   
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               I6W7l7-Rxce-QllJ-n6nl-nULX-PZ3j-PQGJe3

pvdisplay 명령어를 이용하여 생성된 PV를 자세히 볼 수 있습니다. (pvs, pvscan 명령어를 사용해도 좋습니다.)

[root@s17ab8051000 ~]# vgcreate vg_data /dev/xvdb1 /dev/xvdc1
  Volume group "vg_data" successfully created

[root@s17ab8051000 ~]# vgdisplay
  --- Volume group ---
  VG Name               vg_data
  System ID             
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               <3.91 TiB
  PE Size               4.00 MiB
  Total PE              1023998
  Alloc PE / Size       0 / 0   
  Free  PE / Size       1023998 / <3.91 TiB
  VG UUID               Kl29bl-HIIm-NXxt-RPRI-1mfr-VMtO-0qOO7I

PV 생성 후에 VG, 즉 볼륨 그룹을 생성해주어야합니다.
vgcreate 명령어로 위와 같이 볼륨 그룹을 생성해줍시다.
vgcreate VG 이름 디바이스명1 디바이스명2 과같이 사용할 수 있습니다.

[root@s17ab8051000 ~]# lvcreate -l 100%FREE -n lv_data vg_data
  Logical volume "lv_data" created.

[root@s17ab8051000 ~]# lvdisplay
  --- Logical volume ---
  LV Path                /dev/vg_data/lv_data
  LV Name                lv_data
  VG Name                vg_data
  LV UUID                66UDwi-kBvC-lJFc-Nc0g-QcSA-dxJL-0eYTUG
  LV Write Access        read/write
  LV Creation host, time s17ab8051000, 2021-07-18 15:30:36 +0900
  LV Status              available
  # open                 0
  LV Size                <3.91 TiB
  Current LE             1023998
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:0

VG으로 물리적 볼륨을 하나로 묶어주었습니다.
생성된 VG에서 여러개의 LV로 또는 하나의 LV로 생성하실 수 있습니다.
lvcreate로 논리적 볼륨(LV)를 생성해줄 것입니다.
-l 옵션은 PE 단위이며 -L 옵션은 MB, GB, TB 단위입니다.
(사용할 수 있는 PE와 용량은 vgdisplay 명령어에서 Free PE / Size 를 확인하면 볼 수 있습니다.)

lvcreate -l 100%FREE 를 주고 -n 옵션으로 lv의 이름을 지정해줬습니다 이후 위에서 생성했던 vg의 이름을 써줍니다.

[root@s17ab8051000 ~]# mkfs.xfs /dev/vg_data/lv_data
meta-data=/dev/vg_data/lv_data   isize=512    agcount=4, agsize=262143488 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=1048573952, imaxpct=5
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=511999, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

이제 마지막으로 파일시스템 작업과 마운트 작업만 해주면 끝입니다.
저는 xfs 파일시스템으로 포맷해줬는데 이 부분은 원하시는 파일시스템으로 포맷해주시면 됩니다.

[root@s17ab8051000 ~]# mkdir /data
[root@s17ab8051000 ~]# mount /dev/vg_data/lv_data /data
[root@s17ab8051000 ~]# df -h /data
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/vg_data-lv_data  4.0T   33M  4.0T   1% /data

위와 같이 생성한 디렉토리에 마운트까지 정상적으로 완료되었습니다.
하지만 최종적으로 부팅 후에도 정상적으로 마운트되려면 /etc/fstab 파일을 수정해주어야합니다.

[root@s17ab8051000 ~]# blkid /dev/vg_data/lv_data
/dev/vg_data/lv_data: UUID="4240c1b1-ac89-477c-933b-eff8db839adf" TYPE="xfs" 

blkid 명령어로 UUID를 확인하고 /etc/fstab 파일에 아래와 같이 추가해주었습니다.

#
# /etc/fstab
# Created by anaconda on Mon Aug 31 14:44:01 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=0692fdb8-bb3c-4094-83f0-fe95a339b8c1 /                       xfs     defaults        0 0
UUID=f95bed0a-11af-4b2c-bfcc-4afb91a68fc1 /boot                   xfs     defaults        0 0
UUID=4240c1b1-ac89-477c-933b-eff8db839adf /data                   xfs     defaults        0 0

네이버 클라우드에서 2TB가 초과되는 파티션을 사용하는 것 생각보다 쉽지 않나요?

그럼 이제 이렇게 논리적으로 생성한 볼륨을 확장하는 방법도 알아봅시다.
4TB의 용량도 다 써버려서 확장이 필요할 때 이미 생성된 LV는 추가적인 확장이 가능할까요?


Volume Expansion

LV 확장은 충분히 가능합니다. 아래 예시로 준비하였습니다.

먼저 2000GB 크기의 스토리지를 하나 더 추가 생성하였습니다.

[root@s17ab8051000 ~]# fdisk /dev/xvdd
Welcome to fdisk (util-linux 2.23.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
Building a new DOS disklabel with disk identifier 0x5840d763.

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 
First sector (2048-4194303999, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-4194303999, default 4194303999): 
Using default value 4194303999
Partition 1 of type Linux and of size 2 TiB is set

Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

위에서 배운 그대로 fdisk를 이용하여 파티션을 생성해줍니다.

[root@s17ab8051000 ~]# pvcreate /dev/xvdd1
  Physical volume "/dev/xvdd1" successfully created.

[root@s17ab8051000 ~]# vgdisplay
  --- Volume group ---
  VG Name               vg_data
  System ID             
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  2
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               <3.91 TiB
  PE Size               4.00 MiB
  Total PE              1023998
  Alloc PE / Size       1023998 / <3.91 TiB
  Free  PE / Size       0 / 0   
  VG UUID               Kl29bl-HIIm-NXxt-RPRI-1mfr-VMtO-0qOO7I
   
[root@s17ab8051000 ~]# 
[root@s17ab8051000 ~]# vgextend vg_data /dev/xvdd1
  Volume group "vg_data" successfully extended

자 여기서부터가 중요한데 pvcreate를 이용하여 PV를 생성해주는 것까지는 동일합니다.
하지만 이번엔 볼륨 그룹을 따로 생성해주지 않았습니다.
볼륨 그룹을 따로 생성할 수도 있겠지만 vgextend를 이용하여 기존 볼륨 그룹을 확장하는 방식으로 해보았습니다.

[root@s17ab8051000 ~]# vgdisplay
  --- Volume group ---
  VG Name               vg_data
  System ID             
  Format                lvm2
  Metadata Areas        3
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                3
  Act PV                3
  VG Size               <5.86 TiB
  PE Size               4.00 MiB
  Total PE              1535997
  Alloc PE / Size       1023998 / <3.91 TiB
  Free  PE / Size       511999 / 1.95 TiB
  VG UUID               Kl29bl-HIIm-NXxt-RPRI-1mfr-VMtO-0qOO7I
   

[root@s17ab8051000 ~]# lvextend -l +511999 /dev/vg_data/lv_data
  Size of logical volume vg_data/lv_data changed from <3.91 TiB (1023998 extents) to <5.86 TiB (1535997 extents).
  Logical volume vg_data/lv_data successfully resized.

vgdisplay를 이용해서 보면 정상적으로 VG가 확장되어 Free PE / Size가 추가적으로 여유가 생긴 것을 확인할 수 있습니다.

여기서 lvextend 명령어를 이용해줍시다!
lvextend를 이용하면 논리적 볼륨을 확장할 수 있습니다.
이번엔 -l 명령어로 PE를 지정해서 줘봅시다. (1PE 당 4MB의 용량이라고 합니다.)

[root@s17ab8051000 ~]# lvscan
  ACTIVE            '/dev/vg_data/lv_data' [<5.86 TiB] inherit
[root@s17ab8051000 ~]# df -h /data
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/vg_data-lv_data  4.0T   33M  4.0T   1% /data

끝이 아닙니다.
LV는 확장되었지만 df 명령어로 보면 그대로 전체 크기가 4T로 머물러 있을 것입니다.

왜냐? 파일시스템을 확장해주지 않았으니까…

[root@s17ab8051000 ~]# xfs_growfs -d /data
meta-data=/dev/mapper/vg_data-lv_data isize=512    agcount=4, agsize=262143488 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=1048573952, imaxpct=5
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=511999, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 1048573952 to 1572860928
[root@s17ab8051000 ~]# 
[root@s17ab8051000 ~]# df -h /data
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/vg_data-lv_data  5.9T   33M  5.9T   1% /data

xfs_growfs 명령어로 위와 같이 파일시스템을 확장해줄 수 있습니다.
※ 파일시스템이 EXT4일 경우 resize2fs 명령어를 사용할 수 있습니다.

파일시스템 확장 후 df 명령어로 다시 확인 해보면 정상적으로 6T까지 용량이 늘어난 것을 볼 수 있습니다.


Note

이렇게 스토리지 LVM을 이용하여 파티션을 구성했을 경우 백업을 스냅샷 백업이 아닌 이미지 백업으로 해야합니다.

이후 서버에 문제가 생겼을 때 생성된 이미지로 서버를 재생성하면 구성된 LVM까지 전부 다 그대로 올라오는데 스냅샷은 그렇게 할 수 없습니다.
스토리지 여러개를 하나로 묶어 놓았는데 스냅샷으로 백업해버리면 스냅샷으로 볼륨 생성 후 이걸 다시 묶어주고 파일시스템을 포맷하면 데이터가 살아있지 못하죠..

단 이미지 백업으로 서버를 생성하면 서버 생성 시 스토리지 종류를 SSD로 선택할 경우 나머지 볼륨들도 전부 SSD로 생성된다는 점이죠…

나머지 볼륨들을 다시 HDD로 변경하려면 스토리지를 HDD로 생성 하고 LVM으로 PV,VG, LV전부 구성 해준 뒤 데이터를 복사해줘야합니다…😥


Personal Comments

지금까지 네이버 클라우드 리눅스 환경에서 2000GB를 초과하는 파티션을 만들어보았습니다.
오늘 설명드린 LVM을 이용한 파티션 생성 및 확장 뿐만이 아니라 축소, 스냅샷 등 다양하게 사용할 수 있으니 관심있으시면 다양하게 써보시면 좋을 것같습니다.

Windows편도 금방 포스팅하도록 하겠습니다.

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

IT/Linux/Kubernetes

Rocky Linux 8.4 GA (Green Obsidian) 등장!

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

오늘은 좋은 소식이 있어 포스팅을 하게 되었습니다. 2021년 06월 21일 Rocky Linux 8.4 GA가 출시되었습니다. 이전 RC와 GA는 다음 과 같은 차이가 있습니다.

RC(Release Candidate) 즉 베타 버전으로 버그가 발생하지 않는 이상 출시 전 상태라고 보시면 되고 GA(General Availability)은 웹이나 물리적인 환경에서 사용할 수 있도록 출시된 것이라 보면되는데 그렇기때문에 RC는 일반 물리적인 장비에 설치가 되지않는 반면 GA는 설치가 잘 되었습니다.(VirutalBox에서는 RC 설치됨, 다만 서비스 용도로 사용하기 부적절)

엔지니어로서 이런 운영체제가 생기거나 버전업이되거나 할 때마다 설렙니다.
(물론 너무 자주 버전이 변경되면 조금…😐)

NAME="Rocky Linux"
VERSION="8.4 (Green Obsidian)"
ID="rocky"
ID_LIKE="rhel fedora"
VERSION_ID="8.4"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Rocky Linux 8.4 (Green Obsidian)"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:rocky:rocky:8.4:GA"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
ROCKY_SUPPORT_PRODUCT="Rocky Linux"
ROCKY_SUPPORT_PRODUCT_VERSION="8"
Rocky Linux release 8.4 (Green Obsidian)
Rocky Linux release 8.4 (Green Obsidian)
Rocky Linux release 8.4 (Green Obsidian)
//appstream 기준
httpd.x86_64                                                                              2.4.37-39.module+el8.4.0+571+fd70afb1  
php.x86_64                                                                                7.2.24-1.module+el8.4.0+413+c9202dda  
mysql.x86_64                                                                               8.0.21-1.module+el8.3.0+242+87d3366a   
mariadb.x86_64                                                                            3:10.3.28-1.module+el8.4.0+427+adf35707 
postgresql.x86_64                                                                             10.17-1.module+el8.4.0+548+9eccbe3f  
redis.x86_64                                                                               5.0.3-2.module+el8.4.0+393+5af13779 
openssl.x86_64                                                                                       1:1.1.1g-15.el8_3 

ROCKY LINUX 8.4 GA

GREEN OBSIDIAN 이라는 이름으로 출시된 ROCKY LINUX 8.4는 출시된지 며칠밖에 지나지않아 물론 어느정도의 버그가 발생할 수 있다는 것도 생각해야합니다.

설치 과정은 Rocky Linux 8.3 RC 버전과 동일합니다.

당장 서비스에 사용하기 전에 여러가지 테스트를 해보는 것만큼 좋은 것이 없습니다.
그렇기때문에 현재 물리 서버에 ROCKY LINUX 8.4 GA를 설치 후 여러가지 환경 테스트와 기존 CentOS 7에서 서비스 하던 것들을 이전 작업을 진행하여 ROCKY LINUX 8.4에서 이상없이 정상적인 운영이 되는지 이상 증상이 발생하지 않는지 검토할 준비가 되어있습니다.

현재 기본적인 환경 테스트는 거의 마무리가 다 되어가고 곧 이전 작업 및 서비스 테스트까지 완료될 예정입니다.

테스트가 끝나면 실제 서비스 사용이나 이전도 고려해볼 수 있으니 문서화 해야겠습니다.

또한 Rocky Linux는 클라우드 환경에서도 사용될 예정입니다.
Cloud Offerings으로 이미 AWS와 GCP가 공식 문서에 올라왔으며 네이버 클라우드 역시 현재 후원 및 파트너로 존재하니 클라우드에서도 Rocky Linux를 사용하게 될 날이 얼마남지 않은듯 합니다.

또한 컨테이너 이미지도 준비 중인 것으로 보입니다.

아직 Docker Hub에 Official Images로는 없는 상태지만 곧 올라올 것같네요.


Personal Comments

모든 테스트가 끝나면 문서화 후 공유하기 좋은 내용들은 추가로 공유하도록 하겠습니다.
요즘엔 할 것이 많네요. 자고 일어나면 늘 새로운 것들이 반기는듯한?…
할 것이 많다는 것은 좋은 것같습니다.

내일이나 모레 중으로 네이버 클라우드의 Container Registry에 대한 포스팅이 올라갈 예정입니다. 현재 임시글 작성은 완료된 상태라 곧 포스팅됩니다.

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

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의 정식 출시를 응원하며 글을 마무리하도록 하겠습니다.

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

Dev

[Dev] 도커를 이용한 jupyter notebook Install & pandas test

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

최근에 슬슬 개발 언어를 배워볼 필요성을 느끼게 되었습니다.
제가 배워보기로 한 언어는 Python입니다.

Python이 배우기 쉬운 언어라 선택하기보다 제가 만들고 싶은 것도 있고 해보고 싶은 작업에 Python이 필요로 하기때문에 선택하게 되었습니다.


Python을 배워 데이터 분석과 Python용 AWS SDK인 boto3에 활용할 예정이며
언어를 배우기 앞서 웹 브라우저를 통해 코드 작성 후 실행을 해볼 수 있도록
“JUPYTER NOTEBOOK”을 설치할 것입니다.


ENV & BASE INSTALL

우선 고정적인 Python 버전과 변경된 Python 버전으로 인해 다른 시스템에 영향이 가는 것을 원하지 않아 독립된 가상 환경이 필요했습니다.

# OS : CentOS7
# Virtualization approach : Docker
# Python : 3.8.6
# Jupyter : 6.2.0

pyenv, virtualenv, anaconda, docker, kubernetes 등 다양한 선택지가 있었으나
저는 제가 조금 더 익숙한 docker를 이용하여 설치를 하였습니다.

아래 기본적인 설정과 docker 설치를 남겨놓았으나 이 포스팅은 Jupyter 설치가 메인이라 docker 설치 방법에 대한 설명을 따로 하지않도록 하겠습니다.

setenforce 0

sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

[root@localhost jupyter]# sestatus | grep config
Mode from config file: disabled

yum update -y && yum install -y yum-utils

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

yum install -y docker-ce

curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

cd /usr/local/bin

chmod +x docker-compose

base=https://github.com/docker/machine/releases/download/v0.16.0 && curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine && sudo install /tmp/docker-machine /usr/local/bin/docker-machine

systemctl enable docker
systemctl start docker

Jupyter NoteBook Install

docker와 docker-compose 설치 및 실행을 끝마치고
vi docker-compose.yaml 를 하여 아래와 같은 .yaml 파일을 생성합니다.

version:                "3"
services:
  datascience-notebook:
      image:            jupyter/datascience-notebook
      volumes:
        - /docker/jupyter:/home/jovyan/work
      ports:
        - 8888:8888
      container_name:   jupyter-container

위 사이트에서 처럼 원하시는 옵션에 맞게 사용자 지정하여 파일을 생성하셔도 좋습니다.

이후 docker-compose up -d 명령어를 이용하여 실행할 수 있습니다.
-d 옵션을 줘야 백그라운드로 실행이 됩니다.

jupyter의 경우 실행 시 토큰 값을 알아야 접속이 가능합니다.
(옵션에서 토큰or패스워드 값을 제거할 수도 있습니다.)

백그라운드로 실행했을 때는 docker-compose logs 명령어를 이용하여 확인이 가능합니다.

정상적으로 접근이 되지않고 302 에러가 발생할 경우 방화벽 문제가 있을 수 있습니다.
방화벽을 확인해보시기 바랍니다.

[root@localhost jupyter]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1ccb4d9ba04 jupyter/datascience-notebook “tini -g — start-no…” About an hour ago Up 56 minutes 0.0.0.0:8888->8888/tcp jupyter-container

docker ps 명령어로 실행된 docker 컨테이너를 확인 할 수 있으며
docker exec -it f1ccb4d9ba04 /bin/bash (docker exec -it CONTAINER ID /bin/bash) 를 이용할 경우
컨테이너 내부로 접속이 가능합니다.

  • docker-compose 재시작 시 자동 실행 등록

vi /etc/systemd/system/docker-compose.service

[Unit]
Description=Docker Compose Application Service
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/develop/docker
ExecStart=/usr/local/bin/docker-compose up -d
ExecStop=/usr/local/bin/docker-compose down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

systemctl daemon-reload
systemctl enable docker-compose


pandas 라이브러리 테스트

마지막으로 생성한 jupyter notebook을 이용하여 python의 pandas 라이브러리를 테스트 해보겠습니다.

[New]에서 Python3을 선택합니다.
import pandas as pd

df = pd.DataFrame(
[[30, 173, 61],
[27, 181, 79],
[26, 158, 45]],
index=[1, 2, 3],
columns=['Age', 'Height', 'Weight'])

df

코드는 간단하게 테스트용으로 사용하였습니다.

pandas 라이브러리 테스트까지 정상적으로 마무리되었습니다.
지금부터라도 Python 공부를 해봐야겠습니다.


참고 사이트

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

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/

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

IT/Linux/Kubernetes

KUBERNETES 1.19 설치 및 APM + WORDPRESS 연동 – 2부

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

1부 “VirtualBox를 이용한 Kubernetes 1.19 설치” 편에 이어
2부에서는 설치된 Kubernetes를 이용하여 APM + WordPress 연동을 작성하겠습니다.

1부 “VirtualBox를 이용한 Kubernetes 1.19 설치”를 못보신 분들을 위해
해당 포스트 하단에 추가로 링크를 추가해두었습니다.

APM + WordPress를 연동하여 wordpress 웹 서비스를 운영할 수 있도록 해보겠습니다.

PV, PVC, Service & Pod Deploy

| PV

1. vi pv_01.yaml

kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv0001
  labels:
    type: local
spec:
  capacity:
    storage: 25Gi
  accessModes:
    - ReadWriteOnce
  hostPath:

    path: "/data001/pv0001"

2. vi pv_02.yaml

kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv0002
  labels:
    type: local
spec:
  capacity:
    storage: 25Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/data001/pv0002"

위 .yaml 파일을 만든 뒤 아래 명령어를 이용하여 퍼시스턴트 볼륨을 생성하고
정상적으로 생성되었는지 확인 해봅니다.

 kubectl create -f pv_01.yaml
 kubectl create -f pv_02.yaml
 kubectl get pv

| Mysql, PVC + Services + Pod

  • vi mysql-deployment.yaml
apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pvc

| WordPress, PVC + Services + Pod

  • vi wordpress-deployment.yaml
apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: LoadBalancer
  externalIPs:
  - 192.169.0.31
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pvc
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:4.8-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        ports:
        - containerPort: 80
          name: wordpress
        volumeMounts:
        - name: wordpress-persistent-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-persistent-storage
        persistentVolumeClaim:
          claimName: wp-pvc

위 파일은 PVC와 Pod, Services .yaml 파일입니다.
따로 분리하여 만들어줄 수도 있고, 위 방법과 같이 합쳐서 한 파일로 만들 수도 있습니다.

| Add Secret Generator

  • vi kustomization.yaml
secretGenerator:
- name: mysql-pass
  literals:
  - password=rlatngus1!
resources:
  - mysql-deployment.yaml
  - wordpress-deployment.yaml
  • kubectl apply -k ./

| Confirm Settings

지금까지 설정한 것들을 아래의 방법으로 모두 확인해보시기 바랍니다.
위 wordpress-deployment.yaml에서 External-IP를 Kube-Node1의 IP로 설정해두었습니다.

  • kubectl get secrets
  • kubectl get pvc
  • kubectl get pods
  • kubectl get services

Check Service (192.168.0.31:80)

Kube-Node1 IP인 192.168.0.31로 80포트를 타고 wordpress가 실행되었습니다.
정상적으로 운영되는 것을 웹 페이지에서 볼 수 있었습니다.

C o m m a n d

1 kubectl get svc
2 kubectl get nodes
3 kubectl get pods
–all-namespaces
-o wide
4 kubectl delete pod [pod이름]
namespace가 default가 아닌 다른 것일 때 ex) -n kube-system
5 kubectl describe pod [pod이름]
6 kubectl get events
7 kubectl get pv
8 kubectl get pvc
9 kubectl edit svc [service이름]
10 kubectl create -f [파일] ex) mysql.yaml

마지막으로 자주 쓰이게 됐던 명령어들을 10가지 뽑아 정리하였습니다.
이 포스팅이 실습에 많은 도움이 되셨길 바라며 이론적인 부분은 따로 찾아보시기 바랍니다.

1,2부에 걸쳐 긴 글 읽어주셔서 감사합니다.

IT/Linux/Kubernetes

Kubernetes 1.19 설치 및 APM + WordPress 연동 – 1부

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

오늘은 Kubernetes 1.19 설치 후 APM + WordPress를 연동하여
wordpress 웹 서비스를 운영하는 것이 목표입니다.

1부에서는 VirtualBox를 이용한 Kubernetes 1.19 설치,
2부에서는 설치된 Kubernetes를 이용하여 APM + WordPress 연동을 작성하겠습니다.

설치 환경은 아래와 같습니다.

Environment

  • VirtualBox [각 VM 정보]
    CentOS 7.8 2003 (core) + 3.10.0-1127.19.1.el7.x86_64
    MEMORY : 4G
    CPU : 2
    HDD : 50G
    네트워크 방식 : 어댑터에 브리지

“테스트하는데 저렇게 많은 메모리와 많은 node를 생성할 필요는 없습니다.
그냥 제 노트북 스펙이 괴물이라 퍼줬습니다.”


최소 2G 메모리면 충분히 설치가 가능합니다.

Kubernetes Install & Environment Setup

  • Master – 1
    Kubernetes 설치를 위해서는 기본적인 설치 환경을 만들어주어야 합니다.

    VirtualBox를 이용하여 CentOS 7를 설치해 kube-master를 생성해주고
    Master에서 아래 환경들을 구성합니다.

1 setenforce 0
2 sed -i ‘s/^SELINUX=enforcing$/SELINUX=permissive/’ /etc/selinux/config
3 sestatus
4 systemctl stop firewalld && systemctl disable firewalld
5 systemctl stop NetworkManager && systemctl disable NetworkManager
6 swapoff -a && sed -i ‘/ swap / s/^/#/’ /etc/fstab
7 cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
8 sysctl –system
9 cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
10 yum -y update
11 cat << EOF >> /etc/hosts
192.168.0.30 kube-master
192.168.0.31 kube-node1
192.168.0.32 kube-node2
192.168.0.33 kube-node3
EOF
12 cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.30 kube-master
192.168.0.31 kube-node1
192.168.0.32 kube-node2
192.168.0.33 kube-node3
13 yum install -y yum-utils device-mapper-persistent-data lvm2
14 yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo
15 yum update -y && yum install -y docker-ce
16 mkdir /etc/docker
17 cat > /etc/docker/daemon.json <<EOF
{
“exec-opts”: [“native.cgroupdriver=systemd”],
“log-driver”: “json-file”,
“log-opts”: {
“max-size”: “100m”
},
“storage-driver”: “overlay2”,
“storage-opts”: [
“overlay2.override_kernel_check=true”
]
}
EOF
18 mkdir -p /etc/systemd/system/docker.service.d
19 yum install -y kubelet kubeadm kubectl –disableexcludes=kubernetes

여기까지 구성하셨다면 기본적인 노드 복제 전 모든 설정들이 구성된 것입니다.
다음 작업을 진행하기 전에 스냅샷을 생성하시기 바랍니다.

이 스냅샷은 앞으로 당신의 쿠버네티스 모험으로부터 많은 도움을 줄 것입니다.

이제 설정을 마친 Kube-Master를 아래와 같은 방법으로 Kube-Node1,2,3으로 복제할 것입니다.

모든 Kube-Node 복제를 완료하셨다면 이제 아래 작업으로 넘어가셔도 좋습니다.

  • Node – 1
    Master를 복제하여 Node를 만들었기때문에 Node들은 Master와 동일한 IP를 갖고있습니다.
    Node 복제가 완료되면 가장 먼저 IP 변경과 hostname 변경을 해주는 것이 우선입니다.

1 /etc/sysconfig/network-scripts/ifcfg-enp0s3
IPADDR=192.168.0.
2 systemctl restart network
3 hostnamectl set-hostname kube-node

  • Master – 2
    Node의 네트워크 설정이 완료되면 다시 Master로 돌아와서 설정을 마저합니다.
    아래 설정 중에 kubeadm join 값을 반드시 저장해두시기 바랍니다.

20 systemctl daemon-reload
21 iptables -nL
22 systemctl enable –now docker
23 docker run hello-world
24 systemctl enable –now kubelet

25 kubeadm init –pod-network-cidr=20.96.0.0/12

# kubeadm join value 값을 따로 저장해두자.
# –token 7ovjlh.znruevaiqj9cbrk8 \ –discovery-token-ca-cert-hash sha256:77ef7 – 이하 생략

26 mkdir -p $HOME/.kube
27 cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
28 chown $(id -u):$(id -g) $HOME/.kube/config
29 yum install bash-completion -y
30 source <(kubectl completion bash)
31 echo “source <(kubectl completion bash)” >> ~/.bashrc

  • Node – 2
    Master-2 의 작업이 모두 완료되면 Node로 돌아와 아래와 같은 작업을 해줍니다.
    Master에서 저장해둔 본인의 kubeadm join 값을 아래에 추가하여 붙여줍니다.

4 systemctl daemon-reload
5 systemctl enable –now docker
6 systemctl enable –now kubelet
7 kubeadm join 192.168.0.30:6443 –token 7ovjlh.znruevaiqj9cbrk8 \
–discovery-token-ca-cert-hash sha256:77ef7c8c7325d309fa91cab608ce0eb94f30f300bd053db4c08341bf083ef53d

  • Master – 3
    이제 99% 설치가 완료됐다고 보시면 됩니다.
    kubectl get nodes를 하여 Master에서 각 Node들의 상태를 확인해보시기 바랍니다.

    STATUS 값이 READY 상태여야합니다.

32 kubectl get nodes

33 kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
34 kubectl get pods –all-namespaces

calico도 설치해줍니다.
calico는 컨테이너 기반에서 사용되는 네트워크 플러그인 중에 하나입니다.

calico가 정상적으로 Running 중이십니까?
여기까지 성공하셨다면 Kubernetes 1.19 설치가 정상적으로 완료되었습니다.

많은 도움이 되셨길 바라며,
함께 Kubernetes 자격증 도전중인 용사님들 화이팅입니다!

2부에 이어서 설치된 Kubernetes로 APM + WordPress 연동하여
서비스를 운영해보도록 하겠습니다.

읽어주셔서 감사합니다.