Notice/News

[Notice] 포스팅 일정 공지

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

2021-08-01까지 CKA(Certified Kubernetes Administrator) 시험에 집중하기 위해 블로그 추가 포스팅은 시험 이후 업로드될 예정입니다.

기간 : ~ 2021-08-01

매번 포스팅을 읽어주셔서 다시 한 번 감사의 인사드리며 시험 이후 후기 포스팅으로 찾아뵙겠습니다.

요즘 날씨가 많이 더워졌습니다.
무더위에 건강 잘 챙기시기 바랍니다.

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

What is HTTP/2(h2)? & CentOS6 HTTP/2

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

오늘은 CentOS 6에서 HTTP/2를 적용해보려 합니다.
CentOS 6은 2020년 11월 30일 이미 지원이 중단된 OS지만 아직 쓰고 계시는 사용자들이 많아 CentOS 6부터 적용 방법을 작성하기로 했습니다.


WHAT IS HTTP/2(H2)?

현재 HTTP/3 까지 출시되었으나 아직까지 많은 유저들은 1999년에 출시된 HTTP1.1을 가장 많이 사용하고 있습니다.
최근들어 HTTP/2를 적용하는 분들이 늘어나고 있어 HTTP/2에 대해 소개를 해드리고자 합니다.

우선 HTTP/2는 HTTP/1.1을 대체하는 것이 아닌 확장한 것인데 HTTP 메소드, 상태 코드, URI, 헤더 필드를 사용하여 동일하게 유지되고 있습니다.

HTTP/1.1로 시작하여 클라이언트가 HTTP/2를 지원하면 연결이 업그레이드 되는 방식입니다.

https://blog.knoldus.com/still-not-switch-to-http-2/

HTTP1.1은 연결 시 하나의 요청과 응답만 처리하기에 동시 데이터 전송이나 여러개의 리소스를 처리하는데에 속도와 성능이 떨어집니다.(전체 용량에 도달하기 전 여러 번의 소규모 전송으로 인한 지연 발생) 또한 서버와 클라이언트 간에 추가 요청이나 메타데이터 교환으로 반복적인 헤더와 쿠키 전송으로 응답 속도가 느려지는 현상이 나타납니다.

HTTP/2를 사용하게되면 이러한 문제를 해결할 수 있습니다. 클라이언트가 단일 TCP 연결을 통해 다수의 모든 요청을 동시에 보낼 수 있게 됩니다.
다만 무조건적으로 HTTP/2가 좋은 것만은 아니기에 내가 운영하는 서비스가 HTTP/2를 사용하기에 적합한지 판단이 필요합니다.

HTTP/2를 사용하게될 경우 단일 연결을 사용하여 동시 요청을 보내게 됩니다. 이는 예측할 수 없는 스파이크가 발생할 수 있는 원인이 될 수 있습니다. 게다가 HTTP/2 Server Push 기법을 이용하여 클라이언트가 요청하기 전에 서버가 클라이언트로 리소스를 보낼 수 있습니다. 이는 리소스를 선점적으로 로드하는데 도움이 되지만 이 또한 재방문자가 캐시된 파일 복사본이 있을 수 있으며 이 경우 서버에서 리소스를 푸시하지 않도록 Push Cache를 인식하도록 해주어야 합니다.(Cache-Control max-age 등 헤더 적용)

HTTP/2 사용은 응답 시간이 중요하지 않은 애플리케이션, 제한된 IoT 장치나 안정적인 연결이 필요한 곳 그리고 WebSockets, Server-Sent Events (SSE), Pub/Sub 메시징과 같이 적절한 기술이 사용되는 경우 등이 적합하다고 볼 수 있겠습니다.

HTTP/2를 적용하기 위해서는 조건이 있습니다.
만약 Apache를 사용할 것이라면 Apache 2.4.17버전 이상이 이어야하며 openssl 버전도 1.0.2 이상이 되어야합니다. PHP의 경우 libcurl 사용 즉, cURL을 이용하여 HTTP/2 POST를 요청하기 위해서는cURL 7.43 이상, PHP 버전도 5.5.24 이상의 환경이 필요합니다.

오늘은 간단하게 CentOS6에서 Apache로 http2 사용하기를 준비했습니다.


Using HTTP/2 on CentOS 6

mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo_org
vi /etc/yum.repos.d/CentOS-Base.repo

우선 CentOS6은 지원 중단으로 Base repo를 아래와 같이 변경해주었습니다.

# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the 
# remarked out baseurl= line instead.
#
#

[base]
name=CentOS-$releasever - Base
release=$releasever&arch=$basearch&repo=os&infra=$infra
baseurl=https://vault.centos.org/6.10/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

#released updates 
[updates]
name=CentOS-$releasever - Updates
release=$releasever&arch=$basearch&repo=updates&infra=$infra
baseurl=https://vault.centos.org/6.10/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
release=$releasever&arch=$basearch&repo=extras&infra=$infra
baseurl=https://vault.centos.org/6.10/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
release=$releasever&arch=$basearch&repo=centosplus&infra=$infra
baseurl=https://vault.centos.org/6.10/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib
release=$releasever&arch=$basearch&repo=contrib&infra=$infra
baseurl=https://vault.centos.org/6.10/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

만약 위와 같이 Base repo를 변경했는데도 정상적으로 yum 설치가 되지 않는다면
지원이 중단된 다른 repo가 있는지 확인해보신 후 중단된 repo를 제거 및 yum clean all 후 재진행 해보시기 바라며 그 후에도 되지않는다면 /etc/resolv.conf 에 nameserver가 정상적으로 등록되어 있는지 확인해보시기 바랍니다.

[root@manvscloud ~]# yum update -y
[root@manvscloud ~]# yum install wget perl gcc zlib-devel epel-release -y

위는 필수 설치 패키지 입니다.

기존에 운영하고 계시던 서비스가 존재한다면 yum update 전에 update 시 예외처리가 필요한 패키지들을 반드시 exclude해주시기 바랍니다.

yum update –exclude= 방식으로 exclude할 수 있으며 /etc/yum.conf에 exclude 설정을 해줄 수도 있습니다.


Install openssl and upgrade version

<OpenSSL Site>

openssl부터 설치해보도록 합시다.
CentOS 6은 기본적으로 1.0.1버전의 openssl이 설치되는데 1.0.2를 설치해주기 위해 컴파일 작업을 진행할 것입니다.

// 컴파일 설치 진행
[root@manvscloud ~]# cd /usr/local/src
[root@manvscloud src]# wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2u.tar.gz
[root@manvscloud src]# tar zxvf openssl-1.0.2u.tar.gz
[root@manvscloud src]# cd openssl-1.0.2u
[root@manvscloud openssl-1.0.2u]# ./config --prefix=/usr/local/openssl shared zlib
[root@manvscloud openssl-1.0.2u]# make
[root@manvscloud openssl-1.0.2u]# make install

// ldconfig 및 버전 확인
[root@manvscloud openssl-1.0.2u]# echo "/usr/local/openssl/lib" >  /etc/ld.so.conf.d/openssl.conf
[root@manvscloud openssl-1.0.2u]# cat /etc/ld.so.conf.d/openssl.conf 
/usr/local/openssl/lib
[root@manvscloud openssl-1.0.2u]# ldconfig
[root@manvscloud openssl-1.0.2u]# mv /usr/bin/openssl /usr/bin/openssl-1.0.1
[root@manvscloud openssl-1.0.2u]# ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
[root@manvscloud openssl-1.0.2u]# openssl version
OpenSSL 1.0.2u  20 Dec 2019

// 기존 certs 복사 
[root@manvscloud certs]# cp -avp /etc/pki/tls/certs /usr/local/openssl/ssl/
`/etc/pki/tls/certs/ca-bundle.crt' -> `/usr/local/openssl/ssl/certs/ca-bundle.crt'
`/etc/pki/tls/certs/Makefile' -> `/usr/local/openssl/ssl/certs/Makefile'
`/etc/pki/tls/certs/renew-dummy-cert' -> `/usr/local/openssl/ssl/certs/renew-dummy-cert'
`/etc/pki/tls/certs/ca-bundle.trust.crt' -> `/usr/local/openssl/ssl/certs/ca-bundle.trust.crt'
`/etc/pki/tls/certs/make-dummy-cert' -> `/usr/local/openssl/ssl/certs/make-dummy-cert'

위와 같이 진행해준다면 openssl 버전이 1.0.2로 설치가 된 것입니다!


Apache + apr, apr-util, pcre

yum install -y nghttp2 libnghttp2 libnghttp2-devel gcc-c++ libstdc++-devel expat-devel pcre-devel

이제 HTTP/2 적용을 위한 Apache를 설치해봅시다.

apache 2.4 버전부터는 apr과 apr-util도 설치해주어야하는데 우선 apr 설치 과정입니다.

[root@manvscloud ~]# cd /usr/local/src
[root@manvscloud src]# wget http://mirror.apache-kr.org/apache/apr/apr-1.6.5.tar.gz
[root@manvscloud src]# tar zxvf apr-1.6.5.tar.gz 
[root@manvscloud src]# cd apr-1.6.5
[root@manvscloud apr-1.6.5]# ./configure --prefix=/usr/local/apr
[root@manvscloud apr-1.6.5]# cp -arp libtool libtoolT
[root@manvscloud apr-1.6.5]# make
[root@manvscloud apr-1.6.5]# make install

아래는 apr-util 과정입니다.

[root@manvscloud ~]# cd /usr/local/src
[root@manvscloud src]# wget http://mirror.apache-kr.org/apache/apr/apr-util-1.6.1.tar.gz
[root@manvscloud src]# tar zxvf apr-util-1.6.1.tar.gz 
[root@manvscloud src]# cd apr-util-1.6.1
[root@manvscloud apr-util-1.6.1]# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
[root@manvscloud apr-util-1.6.1]# make
[root@manvscloud apr-util-1.6.1]# make install

pcre도 설치해줄 건데 이후 modsecurity를 사용하기 위해서도 pcre가 필요합니다.

[root@manvscloud ~]# cd /usr/local/src
[root@manvscloud src]# wget https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz
[root@manvscloud src]# tar zxvf pcre-8.43.tar.gz 
[root@manvscloud src]# cd pcre-8.43
[root@manvscloud pcre-8.43]# ./configure --prefix=/usr/local/pcre
[root@manvscloud pcre-8.43]# make
[root@manvscloud pcre-8.43]# make install

Apache 2.4버전을 컴파일할 모든 준비가 되었습니다.
우선 아래 옵션을 보시면 event방식으로 설치했습니다.

[root@manvscloud ~]# cd /usr/local/src
[root@manvscloud src]# wget http://archive.apache.org/dist/httpd/httpd-2.4.48.tar.gz
[root@manvscloud src]# tar zxvf httpd-2.4.48.tar.gz 
[root@manvscloud src]# cd httpd-2.4.48
[root@manvscloud httpd-2.4.48]# ./configure --prefix=/usr/local/apache \
--enable-mods-shared=all --enable-http2 \
--enable-ext-filter --enable-ssl --with-ssl=/usr/local/openssl \
--enable-so --enable-cache --enable-proxy \
--enable-deflate --enable-suexec --enable-file-cache \
--with-mpm=event --with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr-util \
--with-pcre=/usr/local/pcre/bin/pcre-config \
--enable-modules=all --enable-module=shared
[root@manvscloud httpd-2.4.48]# make
[root@manvscloud httpd-2.4.48]# make install

(event 방식으로 설치 시 event + fcgi proxy + php-fpm 구조가 일반적입니다.)
왜 event 방식으로 설치했느냐?

prefork 방식은 http/2를 지원하지 않습니다.
prefork 방식이 지원되지 않는 이유는 무엇인가?에대한 질문에 대답은 간단합니다.
HTTP/2는 클라이언트가 단일 TCP 연결을 통해 서버에서는 다수의 모든 요청 즉, 동시 요청을 보내야합니다.

prefork의 단일 스레드 요구 사항을 HTTP/2에 매핑하는 것이 불가능한 것입니다.
처리 모델의 충돌이라고 볼 수있죠. (worker와 event는 다중 스레드 지원)

[root@manvscloud ~]# echo "PATH=$PATH:$HOME/bin:/usr/local/apache/bin" >> /etc/profile
[root@manvscloud ~]# echo "export PATH"  >> /etc/profile
[root@manvscloud ~]# tail -n 2 /etc/profile
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin:/usr/local/apache/bin
export PATH
[root@manvscloud ~]# source /etc/profile

/usr/local/apache/bin 아래 명령어들을 편하게 사용할 수 있게 위와 같이 등록해주었습니다.
이제 apache에서 모듈을 추가해줍시다.

// 모듈 확인
[root@manvscloud ~]# apachectl -M | grep http2

//http2 모듈 확인
[root@manvscloud ~]# cat -n /usr/local/apache/conf/httpd.conf | grep http2
   144	#LoadModule http2_module modules/mod_http2.so

//주석 제거
[root@manvscloud ~]# sed -i '144s/#LoadModule/LoadModule/g' /usr/local/apache/conf/httpd.conf

//모듈 적용 확인
[root@manvscloud ~]# apachectl -M | grep http2
 http2_module (shared)

// Protocols 추가
[root@manvscloud ~]# cat << EOF >> /usr/local/apache/conf/httpd.conf 
> <IfModule http2_module>
>         ProtocolsHonorOrder On
>         Protocols h2 h2c http/1.1
> </IfModule>
> EOF

위 작업 후 apachectl start를 하여 apache를 실행해주고 웹사이트가 정상적으로 잘 출력되는지 확인해보시기 바랍니다. Apache가 정상적으로 실행됐는데 페이지 출력이 안되면 iptables가 실행되어있지 않은지? 상단 방화벽 등 어딘가에 막히는 것이 없는지 확인해보시고 그래도 출력이 안되신다면 /usr/local/apache/logs 아래 생성된 로그를 참고하여 해결이 필요합니다.

HTTP2.Pro에서 HTTP/2가 잘 적용되었는지 확인해보니 잘 적용되었다고 나오는군요.
해당 사이트는 아래 링크를 통해 바로 접속이 가능합니다.


Nginx

[root@manvscloud ~]# yum list nginx
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * epel: d2lzkl7pfhq30w.cloudfront.net
Available Packages
nginx.x86_64                                                                                                                         1.10.3-1.el6                                                                                                                         epel

[root@manvscloud ~]# nginx -V
nginx version: nginx/1.10.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=' -Wl,-E'

CentOS 6에서 Nginx는 epel에서 1.10.3으로 주네요.
openssl 버전만 맞춰준 뒤에 yum 설치만 해도 됩니다. nginx -V 옵션으로 보면 –with-http_v2_module 옵션이 보이시나요?

단 Nginx에서 http2 적용 테스트 시 주의할 점이 있다면 아래와 같이 HTTPS(443) SSL 설정을 해줍시다.
listen 80 http2 default_server; 으로 설정할 경우 사이트 접속이 안되고 다운로드가 됩니다.🤣

server {
    listen       443 ssl http2 default_server;
    listen       [::]:443 ssl http2 default_server;
.
. 생략
.
}

CentOS 6에서 Nginx는 크게 어려움이 없을 것으로 보입니다.


Et cetera

나머지는 도움될만한 내용만한 자료만 첨부해두도록 하겠습니다.

cURL은 위 링크를 참고하면 HTTP/2 적용을 위해 cURL을 설치하는 과정이 나와있습니다.
물론 무작정 영상 그대로 따라하기보다 영상에서 주는 옵션을 보며 해당 옵션과 경로가 나의 환경에 맞는지 검토하는 것은 필수입니다.

마지막으로 Tomcat은 className을 org.apache.coyote.http2.Http2Protocol로 설정해주어야합니다.

<Connector port="8080" protocol="HTTP/1.1">
.
. //생략
.
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
.
. //생략
.
</Connector>

Tomcat 역시 버전만 맞춰주면 크게 어려울 것 없어보입니다. 😎


Personal Comments

지금까지 CentOS 6에 HTTP/2를 적용에 대해 알아보았습니다.
앞으로 CentOS 7, Rocky 8, Naver Cloud Platform Load Balancer, AWS ELB 등에서 HTTP/2를 적용하는 방법에 대해서도 추가적으로 포스팅 될 예정입니다.

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

IT/Linux/Kubernetes

[K8S] Study the Kubernetes command in preparation for the CKA

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

요즘 CKA 자격증 준비로 꾸준히 Kubernetes 공부를 하고 있습니다.
CKA 시험은 아무래도 실습 시험이다보니 꾸준히 실습 환경에서 다양한 연습을 필요로 합니다.

오늘은 제가 요즘 공부하고 있는 Kubernetes의 명령어들과 CKA 공부법 및 링크(Docs) 모음을 공유하고자 합니다.


Kubectl 명령어

kubernetes에서 클러스터에 명령을 내리기 위해서는 우선적으로 kubectl 명령어가 익숙해져야합니다. 자주 사용되는 kubectl 명령어에 대해 간단히 알아보도록 하겠습니다.

그런데… 명령어가 아~~~주 많습니다. create 명령어를 공부하기 위해 docs에 들어가서 create페이지를 들어가면 아래 명령어처럼 별거 아닌듯이 나와있지만 스크롤을 아무리 내려도 create가 끝나지 않을 것입니다.

$ kubectl create -f FILENAME

좌측 카테고리를 다시 한 번 봤는데 숨겨진 리스트들이 나오더군요…

처음부터 다~ 외우지 않아도 됩니다.
자주 사용하다보면 자주 사용하는 것들은 손이 익히게 되는 것이니까요?

CKA 시험도 kubernetes.io docs를 볼 수 있게 해주기 때문에 명령어를 한번씩 사용해보고 특정 상황에 맞게 필요한 명령어를 찾아서 사용할 수만 있다면 크게 문제 없을 것이라 생각됩니다.

The most basic commands for importing workloads 📢
  • create
  • get
  • run
  • expose
  • delete
APP MANAGEMENT 🔨
  • apply
  • annotate
  • autoscale
  • debug
  • diff
  • edit
  • kustomize
  • label
  • patch
  • replace
  • rollout
  • scale
  • set
  • wait
WORKING WITH APPS 🚢
  • attach
  • auth
  • cp
  • describe
  • exec
  • logs
  • port-forward
  • proxy
  • top
CLUSTER MANAGEMENT 💻
  • api-versions
  • certificate
  • cluster-info
  • cordon
  • drain
  • taint
  • uncordon
KUBECTL SETTINGS AND USAGE 🔎
  • alpha
  • api-resources
  • completion
  • config
  • explain
  • options
  • plugin
  • version

CKA(Certified Kubernetes Administrator)를 제대로 준비하자!

우선 CKA를 준비하는 지금 docs에서 yaml 파일을 구해서 쓴다기보다 명령어를 이용하여 yaml 파일을 생성하는 연습을 하고 있습니다. 예를 들어봅시다.

네임스페이스는 manvscloud이고 레이블은 name=kim을 사용해야하는 1.12버전의 nginx를 생성조건에 맞게 명령어를 써본다면 아래와 같이 쓸 수 있습니다.

root@cka-k8s-master:/home/k8s# kubectl run nginx --image=nginx:1.12 --labels=name=kim --namespace=manvscloud --dry-run=client -o yaml > nginx.yaml

생성된 yaml 파일을 보면 아래와 같이 생성되어 있습니다.

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    name: kim
  name: nginx
  namespace: manvscloud
spec:
  containers:
  - image: nginx:1.12
    name: nginx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

명령어로 yaml 생성에 익숙해진다면 yaml 파일을 생성하지 않고 옵션에 맞게 pod를 생성하는 것도 해봅니다.

root@cka-k8s-master:/home/k8s# kubectl run nginx --image=nginx:1.12 --labels=name=kim --namespace=manvscloud --dry-run=client -o yaml | kubectl create -n manvscloud -f -

이런 방법으로 연습을 해주면 명령어 옵션도 빠르게 익힐 수 있고 이후 yaml에 익숙하지 않더라도 어떠한 옵션을 넣어야하는데 어디에 넣어야할지 모를 때 명령어로 원하는 옵션을 주고 yaml 파일로 뽑아서 확인도 해볼 수 있을 것같습니다.


또 다른 주제로 Multi-container pod 환경에서 확인 방법에 대해서도 적응했습니다.
우선 예시로 Multi-container pod 하나를 생성하겠습니다.

vi multicon.yaml

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: multi-con
  name: multi-con
spec:
  containers:
  - image: nginx
    name: nginx-con
  - image: redis
    name: redis-con
  - image: mongo
    name: mongo-con
  restartPolicy: Always

하나의 pod 내에 3개의 컨테이너 이미지가 존재하는 것입니다.

root@cka-k8s-master:/home/k8s# kubectl get pod --show-labels
NAME        READY   STATUS    RESTARTS   AGE   LABELS
multi-con   3/3     Running   0          17m   run=multi-con

아래 명령어들로 컨테이너 이미지 목록을 볼 수 있습니다.

root@cka-k8s-master:/home/k8s# kubectl describe pod | grep Image
    Image:          nginx
    Image ID:       docker-pullable://nginx@sha256:353c20f74d9b6aee359f30e8e4f69c3d7eaea2f610681c4a95849a2fd7c497f9
    Image:          redis
    Image ID:       docker-pullable://redis@sha256:b6a9fc3535388a6fc04f3bdb83fb4d9d0b4ffd85e7609a6ff2f0f731427823e3
    Image:          mongo
    Image ID:       docker-pullable://mongo@sha256:fe44eb6a2ea2bb1548718ec05eb9cb165f1bded37595ebea507bddc413ab99ae

// 레이블이 run=multi-con으로 필터링된 컨테이너 이미지 목록
root@cka-k8s-master:/home/k8s# kubectl get pods --all-namespaces -o=jsonpath="{.items[*].spec.containers[*].image}" -l run=multi-con
nginx redis mongo

그렇다면 하나의 pod안에 다수의 컨테이너가 있다면 어떻게 다를까요?
-c 옵션으로 pod 내에 컨테이너를 지정하여 명령어를 사용하거나 해당 컨테이너로 접속이 가능합니다.

// nginx-con 컨테이너 내에 nginx.conf 파일 여부 확인
root@cka-k8s-master:/home/k8s# kubectl exec multi-con -c nginx-con -- ls -l /etc/nginx/nginx.conf
-rw-r--r-- 1 root root 648 Jul  6 15:11 /etc/nginx/nginx.conf

//mongo-con 컨테이너 접속
root@cka-k8s-master:/home/k8s# kubectl exec -it multi-con -c mongo-con -- /bin/bash
root@multi-con:/#

생각보다 간단하지만 이런 케이스를 경험해보지 않는다면 당황할 수 있으니 어떠한 케이스라도 한번씩 다 해보는 게 중요하다고 봅니다.
(이해하지 못하고 무작정 외우는 건 제가 선호하는 타입이 아니라서…)


마지막으로 하나를 더 알아보겠습니다.

이번에는 마스터의 kubectl, kubelet, kubeadm의 버전을 업그레이드 할 것입니다.
단, 작업 전 예약 불가능으로 설정할 것이며 작업 후 예약 가능하도록 설정해줄 것입니다.
또한 업그레이드 하기 전 유지 관리를 위해 마스터를 drain 해줄 것입니다.

작업 전 master에서 kubernetes 패키지를 확인해보니 현재 kubectl, kubelet, kubeadm 버전은 1.21.1이네요. 해당 버전을 1.21.2로 업그레이드 하겠습니다.

[root@manvscloud-k8s-m ~ (kube:default)]# dpkg -l | grep kube
hi  kubeadm                              1.21.1-00                         amd64        Kubernetes Cluster Bootstrapping Tool
hi  kubectl                              1.21.1-00                         amd64        Kubernetes Command Line Tool
hi  kubelet                              1.21.1-00                         amd64        Kubernetes Node Agent
ii  kubernetes-cni                       0.8.7-00                          amd64        Kubernetes CNI

업그레이드 전 조건이 있으니 우리는 kubectl 명령어 중 cordon, uncordon, drain 을 사용하게 됩니다.

// 아래와 같이 명령어를 사용해주면 해당 노드는 스케줄이 불가능하게 표시됩니다.
[root@manvscloud-k8s-m ~ (kube:default)]# kubectl cordon manvscloud-k8s-m
node/manvscloud-k8s-m cordoned

// 이제 drain을 해주는데 이는 유지 관리를 위해 지정된 노드에 있는 pod들을 다른곳으로 이동시키는 명령어입니다. 자세한 옵션은 kubectl docs를 참고해주세요.
[root@manvscloud-k8s-m ~ (kube:default)]# kubectl drain manvscloud-k8s-m --delete-local-data --ignore-daemonsets --force
Flag --delete-local-data has been deprecated, This option is deprecated and will be deleted. Use --delete-emptydir-data.
node/manvscloud-k8s-m already cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-xqbt6, kube-system/kube-proxy-jqvxn
evicting pod kube-system/coredns-558bd4d5db-gv4dn
evicting pod kube-system/calico-kube-controllers-78d6f96c7b-5nnlh
evicting pod kube-system/coredns-558bd4d5db-62njr
pod/calico-kube-controllers-78d6f96c7b-5nnlh evicted
pod/coredns-558bd4d5db-gv4dn evicted
pod/coredns-558bd4d5db-62njr evicted
node/manvscloud-k8s-m evicted

// 이제 1.21.2 버전을 설치해줍시다.
[root@manvscloud-k8s-m ~ (kube:default)]# apt-get install kubeadm=1.21.2-00 kubelet=1.21.2-00 kubectl=1.21.2-00

--- 설치 내용 생략 ---

// 이후 daemon-reload와 kubelet을 재시작 해줍니다.
[root@manvscloud-k8s-m ~ (kube:default)]# systemctl daemon-reload
[root@manvscloud-k8s-m ~ (kube:default)]# systemctl restart kubelet

kubectl, kubelet, kubeadm의 버전이 1.21.2 버전으로 설치되었습니다.

[root@manvscloud-k8s-m ~ (kube:default)]# dpkg -l | grep kube
ii  kubeadm                              1.21.2-00                         amd64        Kubernetes Cluster Bootstrapping Tool
ii  kubectl                              1.21.2-00                         amd64        Kubernetes Command Line Tool
ii  kubelet                              1.21.2-00                         amd64        Kubernetes Node Agent
ii  kubernetes-cni                       0.8.7-00                          amd64        Kubernetes CNI

이제 마스터 노드가 정상적으로 스케줄 예약이 가능하도록 uncordon 해줍니다.

[root@manvscloud-k8s-m ~ (kube:default)]# kubectl uncordon manvscloud-k8s-m
node/manvscloud-k8s-m uncordoned

kubectl get nodes로 마스터 노드 버전을 보시면 마스터 노드의 버전이 1.21.2로 올라 가있는 것을 보실 수 있습니다.

[root@manvscloud-k8s-m ~ (kube:default)]# kubectl get nodes
NAME                STATUS   ROLES                  AGE   VERSION
manvscloud-k8s-m    Ready    control-plane,master   23d   v1.21.2
manvscloud-k8s-w1   Ready    <none>                 23d   v1.21.1
manvscloud-k8s-w2   Ready    <none>                 23d   v1.21.1
manvscloud-k8s-w3   Ready    <none>                 23d   v1.21.1

CKA(Certified Kubernetes Administrator) 공부 시 참고한 링크 모음


Personal Comments

지금까지 CKA 시험에 대비한 kubectl 명령어에 대해 간단하게 알아보았습니다.
다음 포스팅은 etcdctl 명령어로 CKA 공부를 이어서 진행해보도록 하겠습니다.

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

IT/Linux/Kubernetes

[K8S] CKA(Certified Kubernetes Administrator) Study 참고 링크 모음

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

해당 포스팅은 CKA(Certified Kubernetes Administrator)를 공부하며 참고했던 링크들의 모아둔 글입니다.

이 포스팅은 CKA 시험 합격 포스팅이 올라오기 전까지 주기적으로 업데이트 됩니다.


※ A collection of links that have been referenced

🎹 kubectl Commands Reference Docs


Personal Comments

이 포스팅은 주기적으로 업데이트되니 확인하실 때마다 링크가 추가될 수 있습니다.

읽어주셔서 감사합니다.

AWS

[AWS] RDS Log Generation (General, slow query, audit logs)

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

오늘은 오랜만에 AWS에 대한 포스팅입니다.
최근 ISMS-P를 준비가 필요하여 RDS에서 로그를 남기는 방법에 대한 질문을 받은 적이 있어 이를 블로그로도 공유하고자 올립니다.


RDS Log

RDS 생성 또는 수정시 체크할 수 있는 로그 내보내기 옵션입니다.
생각보다 이 기능이 로그를 생성하는 옵션인 것으로 아시는 분들이 있었습니다.
위 내보내기를 전부 체크하여도 에러 로그만 생성되고 나머지 로그가 생성이 되지 않는 것을 확인할 수 있습니다. (에러 로그는 Default가 생성이라 따로 설정하지 않아도 생성됩니다.)

이 기능은 말 그대로 로그를 CloudWatch Logs로 게시할 수 있도록 내보내는 옵션이며
로그를 생성하는 옵션은 따로 존재합니다.

일반 로그와 느린 쿼리 로그를 생성하기 위해서는 아래 첨부된 이미지와 같이 파라미터 그룹 수정이 필요합니다.

일반 로그는 general_log를 검색하면 나오고 슬로우 쿼리는 slow_query_log라고 검색하면 나옵니다.

두 값을 1로 변경 해줍시다. (1로 설정해야 로그가 생성됩니다.)

현재 운영중인 RDS 인스턴스의 파라미터 그룹이 default 파라미터로 설정되어 있다면 사용자 지정 파라미터 그룹을 생성하여 파라미터 수정 및 파라미터 그룹 수정을 진행합니다.
(RDS 인스턴스 [수정]을 이용하여 파라미터 그룹을 변경할 수 있습니다.)

여기서 중요한 점은 또 Down Time의 여부겠죠.
파라미터 그룹을 변경하게 될 경우 또는 파라미터 값을 수정하게 될 경우 재부팅이 필요하여 Down Time이 발생하게 될까요?

정답은 아래와 같습니다.

그렇다면 동적 파라미터와 정적 파라미터를 어떻게 구분하느냐?

파라미터 그룹 내에 파라미터들을 보면 [적용 유형]이 있습니다.
Dynamic이 동적 파라미터, Static이 정적 파라미터로 수정이 필요한 파라미터를 검색하여
해당하는 파라미터의 값이 수정될 경우 재부팅이 필요한가?를 알 수 있으니 이를 확인하여 적절한 시간에 작업을 진행할 수 있습니다.


RDS Audit Log

파라미터 그룹까지 설정하였습니다. 하지만 파라미터 그룹에서 감사 로그는 찾을 수 없습니다. 그 이유로 감사 로그는 파라미터 그룹이 아닌 옵션 그룹에서 설정이 필요하기 때문입니다.

옵션 그룹에서 감사 로그를 설정 해주려면 default 옵션 그룹에서 새로 생성한 옵션 그룹으로 변경이 필요합니다.

새로 생성한 옵션 그룹에서 위와 같이 MARIADB_AUDIT_PLUGIN 옵션을 추가하여 설정할 수 있습니다. 크게 사용하실만한 옵션에 대해서만 간단하게 설명하자면 다음과 같습니다.

  • SERVER_AUDIT_FILE_ROTATE_SIZE : 로그 파일 용량 크기를 제한합니다. (1–1000000000)
    최대 1GB까지 설정 가능하며 Default 값은 1000000 입니다.
  • SERVER_AUDIT_FILE_ROTATIONS : 로그 파일의 로테이션 수를 설정합니다. (0-100)
    최대 100개의 파일까지 생성가능하며 Default값은 9입니다.
  • SERVER_AUDIT_EVENTS : 특정 이벤트 유형으로 제한하여 로그를 남깁니다.
    이를 설정하지 않을 경우 모든 이벤트 유형을 남기게 됩니다.
    Default 값은 CONNECT, QUERY 입니다.
  • SERVER_AUDIT_INCL_USERS : SERVER_AUDIT_EXCL_USERS보다 우선 순위가 높으며 기록할 사용자를 추가합니다. 또한 값이 없을 경우 로깅에 모든 사용자를 로깅합니다.(SERVER_AUDIT_INCL_USERS 값에 admin을 추가하고 SERVER_AUDIT_EXCL_USERS 값이 비어있다면 admin 계정에 대한 로그만 남깁니다.)
  • SERVER_AUDIT_EXCL_USERS : 값에 사용자를 추가할 경우 해당 사용자를 로그에 기록이 남지않습니다. (로그 예외 처리 계정 추가라고 보면 이해가 쉽습니다.)
    값이 없을 경우 로깅에 예외 처리할 사용자가 없다라는 의미가 됩니다.
  • SERVER_AUDIT_QUERY_LOG_LIMIT : 쿼리 문자열 길이를 제한합니다. (0–2147483647)
    Default값은 1024입니다.

옵션 변경 및 옵션 그룹 변경이 완료되었다면 RDS 로그에서 아래 이미지와 같이 Audit.log가 생성되는 것을 확인할 수 있습니다.

Cloudwatch logs로 내보내기 설정을 하게될 경우 CloudWatch 로그 이벤트에서도 로그를 자세히 확인할 수 있습니다.
DB에서 show databases 및 show tables를 입력해보았는데 Audit 로그에 그대로 남았습니다.


Aurora DB, Using advanced auditing

Aurora MySQL에서는 RDS MySQL과 다르게 고급 감사를 사용할 수 있습니다.
설정 방법은 크게 어렵지 않아 어떠한 고급 감사 기능이 있는지 링크만 남겨두도록 하겠습니다.


Personal Comments

오늘은 오랜만에 AWS의 RDS 로그 생성 방법에 대해 알아보았습니다.

아무래도 감사 로그를 남기는 부분은 ISMS-P를 준비하실 때 필요한 부분이니 이 부분은 어느정도 도움이 되시리라 생각합니다.

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

Certificate

CKA(Certified Kubernetes Administrator) 시험 일정

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

드디어 미루어왔던 CKA(Certified Kubernetes Administrator) 시험 일정이 정해졌습니다.
2021-07-31 18:15~20:15에 시험이 예정되었습니다.

현재 DKOS에서 Kubernetes를 꾸준히 공부하고 있습니다.
다른 일정들도 많지만 이번달 말까지는 쿠버네티스 학습에 조금 더 비중을 두려고 합니다.

시험 합격 후 공부법과 시험을 어떻게 준비할 것인가에 대해 자세히 후기를 남기도록 하겠습니다.

NCP

[NCP] Container Registry에서 이미지를 가져오기 & 로드밸런서 연결

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

오늘은 Naver Cloud Platform에서 Container Registry에서 이미지를 가져오는 방법과 Load Balancer에 연결하는 방법을 알아보도록 하겠습니다.


CONTAINER REGISTRY에서 이미지를 가져오기

아직 Container Registry를 생성해본 적이 없으시다면 위 [NAVER CLOUD KUBERNETES – CONTAINER REGISTRY로 컨테이너 이미지를 관리]를 먼저 보고 오시기 바랍니다.

위 포스팅에서는 push를 해보았습니다. 오늘은 pull을 해볼 시간입니다.

우선 테스트용으로 하고 계시다면 이전에 했던 docker image를 전부 지우고 한 번 해보도록합시다.

[root@kubernetes-server-kr2 ~]# docker rm `docker ps -a -q`
[root@kubernetes-server-kr2 ~]# docker rmi -f `docker images -q`

docker login을 해줍시다.

[root@kubernetes-server-kr2 ~]# docker login <CONTAINER REGISTRY에 나와있는 엔드포인트>
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

docker pull 엔드포인트/이미지:버전 명령어로 docker 이미지를 가져올 수 있습니다.

[root@kubernetes-server-kr2 ~]# docker pull manvscloud-k8s-cr.kr.ncr.ntruss.com/manvscloud-apache:1.0
1.0: Pulling from manvscloud-apache
2d473b07cdd5: Pull complete 
444a3233aeea: Pull complete 
Digest: sha256:b2e60515712f6c5d4f155e9d234299fa82640d8dc7766405fe997c1b80658c07
Status: Downloaded newer image for manvscloud-k8s-cr.kr.ncr.ntruss.com/manvscloud-apache:1.0
manvscloud-k8s-cr.kr.ncr.ntruss.com/manvscloud-apache:1.0

또한 k8s에서 secret을 이용한다면 패스워드, OAuth 토큰, ssh 키와 같은 정보를 저장 및 관리할 수 있는데 이를 이용하여 pod를 생성해보도록 합시다.

[root@kubernetes-server-kr2 ~]# kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-p5mq2   kubernetes.io/service-account-token   3      11d

kubectl create secret docker-registry “secret 이름” –docker-server=레지스트리-엔드포인트 –docker-username=Access-Key-ID –docker-password=Secret-Key –docker-email=계정으로 아래와 같이 secret을 만들 수 있습니다.

[root@kubernetes-server-kr2 ~]# kubectl create secret docker-registry manvscloud-sec --docker-server=레지스트리-엔드포인트 --docker-username=Access-Key-ID --docker-password=Secret-Key --docker-email=계정

[root@kubernetes-server-kr2 ~]# kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-p5mq2   kubernetes.io/service-account-token   3      11d
manvscloud-sec        kubernetes.io/dockerconfigjson        1      19s

이제 yaml 파일을 생성하여 위에서 생성한 secret을 이용하여 이미지를 pull 및 pod 생성을 해봅시다.

vi apache.yaml

apiVersion: v1
kind: Pod
metadata:
 name: manvscloud-apache
 namespace: default
spec:
 containers:
 - name: manvscloud-apache
   image: manvscloud-k8s-cr.kr.ncr.ntruss.com/manvscloud-apache:1.0
 imagePullSecrets:
 - name: manvscloud-sec
[root@kubernetes-server-kr2 ~]# kubectl create -f apache.yaml 
pod/manvscloud-apache created

[root@kubernetes-server-kr2 ~]# kubectl get pods
NAME                                 READY   STATUS    RESTARTS   AGE
manvscloud-apache                    1/1     Running   0          4s

CONTAINER REGISTRY에 있는 이미지를 잘 가져와 pod가 생성되었습니다.
이렇게 CONTAINER REGISTRY를 이용하여 이미지 배포 관리가 쉽게 가능합시다.

또한 CONTAINER REGISTRY에서 Configuration을 클릭하여 Public Endpoint를 활성화/비활성화 선택이 가능합니다. 네이버 클라우드 내부에서만 사용할 것이라면 비활성화 하는 것이 좋습니다.


로드밸런서 연결

네이버 클라우드 Kubernetes Service를 사용중이라면 서비스 생성 시에 type을 LoadBalancer로 지정할 경우 네이버 클라우드 콘솔 내에 로드밸런서 인스턴스가 자동으로 생성됩니다.

로드밸런서 설정의 경우 어노테이션으로 설정할 수 있습니다.

"metadata": {
  "annotations": {
    "key1" : "value1",
    "key2" : "value2"
  }
}
https://guide.ncloud-docs.com/docs/nks-nks-1-8

실습을 통해 직접 로드밸런서를 생성해봅시다.
이번 실습에서는 어노테이션을 이용하여 추가적인 설정은 하지 않았습니다.
간단하게 로드밸런서 연결만 따라할 수 있도록 해두었습니다.

vi manvscloud-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
 name: apache-deployment
spec:
 replicas: 3
 selector:
   matchLabels:
     app: apache
 template:
   metadata:
     labels:
       app: apache
   spec:
     containers:
     - name: apache
       image: manvscloud-k8s-cr.kr.ncr.ntruss.com/manvscloud-apache:1.0
       ports:
       - containerPort: 80
     imagePullSecrets:
     - name: manvscloud-sec

아래와 같이 kubectl get pods –show-labels 했을 때 LABELS이 붙어있을 것입니다.
replicas, label 등은 따로 쿠버네티스에 대한 공부가 필요하니 이러한 설정에 이해가 어려우신 분들은 우선 kubernetes에 대한 공부를 우선적으로 간단하게나마 하시는 것을 권장드립니다.

[root@kubernetes-server-kr2 ~]# kubectl get pods --show-labels
NAME                                 READY   STATUS    RESTARTS   AGE   LABELS
apache-deployment-75895cbcbb-6dlvz   1/1     Running   0          14s   app=apache,pod-template-hash=75895cbcbb
apache-deployment-75895cbcbb-l7q4d   1/1     Running   0          14s   app=apache,pod-template-hash=75895cbcbb
apache-deployment-75895cbcbb-vcvpq   1/1     Running   0          14s   app=apache,pod-template-hash=75895cbcbb

[root@kubernetes-server-kr2 ~]# for pod in $(kubectl get pod -l app=apache |awk 'NR>1 {print $1}'); do kubectl exec $pod -- /bin/sh -c "hostname > /var/www/html/index.html; echo '안녕하세요. ManVSCloud입니다.' >> /var/www/html/index.html"; done

각 pod 내 index.html 파일을 수정해주었습니다.
로드밸런서를 연결하여 접속하기 위해 LoadBalancer를 생성해봅시다.

아래와 같이 Serivces yaml을 생성합니다.

vi lb.yaml

kind: Service
apiVersion: v1
metadata:
 name: lb-service
spec:
 ports:
   - port: 80
     targetPort: 80
 selector:
   app: apache
 type: LoadBalancer
[root@kubernetes-server-kr2 ~]# kubectl create -f lb.yaml 
service/lb-service created

kubectl get services 명령어로 확인해보면 EXTERNAL-IP가 NCP 내 LB로 되어있는 것을 확인할 수 있습니다.

[root@kubernetes-server-kr2 ~]# kubectl get services
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP                                                        PORT(S)        AGE
kubernetes   ClusterIP      198.19.128.1    <none>                                                             443/TCP        11d
lb-service   LoadBalancer   198.19.208.51   default-lb-service-821a9-7191539-4b535e410da7.kr.lb.naverncp.com   80:31033/TCP   5m33s

콘솔을 보면 따로 Load Balancer를 생성해주지 않았는데 따로 콘솔상에서 생성되어 있는 것을 확인할 수 있습니다. 삭제도 마찬가지입니다.
kubectl delete svc lb-service를 해주면 콘솔상에서도 자동 제거가 됩니다.

생성된 LB의 접속 정보를 이용하여 웹에서 접속해보면 위에서 추가해준 index.html의 값이 나오고 있습니다.

로드밸런싱 알고리즘은 기본값인 Round Robin으로 설정되어 있으며 Least Connection과 Source IP Hash로도 변경이 가능합니다.


Personal Comments

오늘은 CONTAINER REGISTRY에서 이미지를 가져오는 방법과 로드밸런싱 연동 방법을 알아보았습니다.

참고로 실습 과정을 따라해보실 경우 .yaml 파일을 그대로 복사하지 마시고 엔드포인트를 잘 수정하여 사용하시기 바랍니다.

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

함께 보며 공부하기 좋은 자료

Notice/News

[NOTICE] 포스팅 일정 공지 (2021-07-02)

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

매번 포스팅을 읽어주셔서 매번 감사합니다.
다름이 아니라 이번 주 포스팅 일정에 대한 내용으로 공지 안내드립니다.

1주일에 2개의 포스팅을 목표로 하고있으나
이번 주는 회사 업무 및 추가적인 스케줄로 인해 이번 주 일요일에 업로드 될 예정입니다.

다시 한 번 감사의 인사 올립니다.