ORACLE DB dump backup and recovery (export / import)

오라클에서 데이터베이스나 스키마 별로 데이터를 저장, 백업하거나

다시 복구해야할때, DB Dump를 떠논다고 말한다.

Dump는 간단한 명령어로 쉽게 떠지지만,

 

반드시 Dump를 저장할 디렉토리를 만들어 지정해줘야한다.

 

1. 오라클시스템상 디렉토리 만들기.

CREATE DIRECTORY datadump AS 'C:\dump';
GRANT READ, WRITE ON DIRECTORY datadump TO SYSTEM;
GRANT CREATE ANY DIRECTORY TO SYSTEM;

SELECT * FROM DBA_DIRECTORIES;

1. C밑에 물리적인 폴더를 생성하고, (dump라는 이름으로 생성했다)

이후 “CREATE DIRECTORY datadump AS ‘C:\dump'”를 수행하여

데이터 베이스 상에 논리적 디렉토리를 지정해준다. (datadump라는 폴더를 만들었다.)

 

2. 이후 읽고 쓰기 권한을 부여해주어야 한다.

GRANT READ, WRITE ON DIRECTORY datadump TO SYSTEM
;
GRANT CREATE ANY DIRECTORY TO SYSTEM;

 

3. 확인

SELECT * FROM DBA_DIRECTORIES; 를 수행하면 만들어졌음을 확인할수있다.

 

 

로컬이라면, CMD에서 sqlplus 명령어로 dba로 접속하여 진행해도 무방하다.

cmd> sqlplus / as sysdba

 

2.  export / emport 시작

CMD창에서 반출 명령어를 입력한다. (접속 스키마 id/pw , ip:포트, db풀, 만든 directory정보 확인)

-- expdp 반출
--db full
expdp userid=ECUBE2/ECUBE2@//127.0.0.1:1521/OBZMETA dumpfile= OBZMETA.dmp directory=datadump  full=y logfile=fullexp.log

*localhost 경우 @//127.0.0.1:1521/OBZMETA 생략 가능
--schema (ECUBE2, ECUBEEBM2)
expdp userid=ECUBE2/ECUBE2@//127.0.0.1:1521/OBZMETA  dumpfile=ECUBE2.dmp directory=datadump  schemas=ECUBE2 logfile=fullimp.log

expdp userid=ECUBEEBM2/ECUBEEBM2@//127.0.0.1:1521/OBZMETA  dumpfile=ECUBEEBM2.dmp directory=datadump  schemas=ECUBEEBM2 logfile=fullimp.log
--반입
--db full
expdp userid=ECUBE2/ECUBE2@//127.0.0.1:1521/OBZMETA dumpfile= OBZMETA.dmp directory=datadump  full=y logfile=fullexp.log


--schema (ECUBE2, ECUBEEBM2)
impdp userid=ECUBE2/ECUBE2@//127.0.0.1:1521/OBZMETA  dumpfile=ECUBE2.dmp directory=datadump  schemas=ECUBE2 logfile=fullimp.log

impdp userid=ECUBEEBM2/ECUBEEBM2@//127.0.0.1:1521/OBZMETA  dumpfile=ECUBEEBM2.dmp directory=datadump  schemas=ECUBEEBM2 logfile=fullimp.log

 

Understanding the task scheduler (Schtasks) cmd input method

작업스케줄러(schtasks)를 cmd로 입력하는 방법

Microsoft Docs Windows 2008 server , Windows command help, etc / schtasks

▣ 시간 단위 작업

30분마다 실행되는 작업

schtasks /create /tn “back up” /tr \\data\task01.bat /sc minute /mo 30

참고 : /sc minute인 경우 /mo의 유효값은 1-1439분이다.

매일 오전 9시부터 18시이전까지 60분마다 실행되는 작업

schtasks /create /tn “back up” /tr task01.bat /sc minute /mo 60 /st 09:00 /et 18:00 /k

참고 : /k는 /et 또는 /du 시간이 되면 작업을 중지한다.

/k는 onstart, onlogon, onidle, onevent는 해당되지 않는다.

2018년 6월 1일부터 12시간단위마다 실행되는 작업

schtasks /create /tn check /tr %userprofile%\desktop\schedule.txt /sc hourly /mo 12 /sd 2018/06/01

참고 : /sc hourly인 경우 /mo의 유효값은 1-23시간이다.

/sd : startdate는 yyyy/mm/dd의 한국 날짜 형식이다.

매 시간 50분에 실행되는 작업

schtasks /create /tn “My Schedule” /tr MySchedule.txt /sc hourly /st 00:50

참고 : /hourly에서 /mo가 생략 되면 기본값은 1이다.

명령입력 현재시간이 00:53분이었다면 다음날에 00:50에 명령이 실행된다.

3시간 간격으로 자정부터 10시간 동안 반복 작업

schtasks /create /tn “My Program” /tr “C:\Program\MyProgram.exe” /sc hourly /mo 3 /st 00:00 /du 0010:00

참고 : 오전 12시, 오전 3시, 오전 6시 , 오전9시에 실행된다. 지속시간이 10시간이므로 오후 12시에는

실행되지 않고 다음날 오전 12시에 실행된다.

/k를 사용하여 작업시간 이후에 중지 할 수 있으나 지속시간이 길지 않으면 굳이 중지할 필요가 없다.

 

 

▣ 일 단위 작업

매일 오전 9시에 2020년 12월 31일까지 실행되는 작업

schtasks /create /tn “My Program” /tr C:\Program\MyProgram.exe /sc daily /st 09:00 /ed 2020/12/31

참고 : /sc daily인 경우 /mo가 생략되면 기본값은 1이다. /sc daily에서 /mo의 유효값은 1-365일이다.

2018년 6월 1일부터 5일마다 오후 6시에 실행되는 작업

schtasks /create /tn “My Program” /tr C:\Program\MyProgram.exe /sc daily /mo 5 /sd 2018/06/01 /st 18:00

사용자가 로그온 되어 있을때 10일마다 실행되는 대화형 작업

schtasks /create /tn “My Script” /tr MyScript.vbs /sc daily /mo 10 /it

참고 : “다음 사용자계정으로 실행”되는 (RU)계정으로 로그온 되어 있는 있을때만 실행 (/it)

 

 

▣ 주 단위 작업

6주마다 실행되는 작업

schtasks /create /tn “My Program” /tr c:\programs\myprogram.exe /sc weekly /mo 6 /s Server03 /u Administrator1

참고 : /sc weekly /mo의 기본값은 1(주)이다. /sc weekly에서 /mo의 유효값은 1-52주이다.

/d day 매개변수가 생략되면 월요일부터 실행

/s 연결할 원격시스템 지정

/u 사용자의 관리자계정 권한을 지닌 Adiministrator1 계정으로 지정

격주마다 월요일에 실행되는 작업

schtasks /create /tn “My prog” /tr c:\prg\myprog.exe /sc weekly /mo 2 /d MON

참고 : /mo 2 격주 간격

/sc weekly /d 매개변수의 유효값은 MON, TUE, WED, THU, FRI, SAT, SUN

 

 

▣ 월 단위 작업

매달 1일에 실행되는 작업

schtasks /create /tn “My Prg” /tr myprg.exe /sc monthly

참고 : /sc monthly 에서 /d 매개변수의 유효값은 1-31일이다. /d 매개변수가 생략되면 기본값 1이 적용된다.

/sc monthly에서 /mo 매개변수의 유효값은 1-12 또는 First, Second, Third, Fourth, Last, Lastday이다.

/mo 매개변수가 생략되면 기본값 1이 적용된다.

3개월마다 1번씩 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc monthly /mo 3

참고 : 3월 ,6월, 9월, 12월 에 1번씩 1일에 작업실행

/d 매개변수가 생략되었으므로 기본값 1일이 적용된다.

격월의 25일에 09:00시간에 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc monthly /mo 2 /d 25 /st 09:00 /sd 2018/06/01 /ed 2025/05/31

참고 : /sc monthly에서 /mo 매개변수가 2이므로 격월로 작업실행

/d 25 25일에 작업 실행

/sd는 start date, /ed는 end date를 지정

/et가 생략되면 시작시간과 상관없이 00:00이 기본값이다.

 

 

▣ 요일 단위 작업

매주 월요일부터 금요일에 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc weekly /d MON,TUE,WED,THU,FRI

매주 금요일에 실행 되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc weekly /d FRI

참고 : /se weekly에서 /mo는 작업을 실행할 간격(주)이며 생략되면 기본값 1이므로 매주 작업 실행

/d *(와일드카드) 는 일일작업실행의 의미와 같다.

4주마다 월요일과 금요일에 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc weekly /mo 4 /d MON,FRI

 

 

▣ 한달 중 특정 주 단위 작업

매월 셋째주 월요일에 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc monthly /mo Third /d MON

참고 : /sc monthly에서 /mo 매개변수를 1~12 또는 First, Second, Third, Fourth를 선택할 수 있다.

예를 들어 /mo 2 이면 격월이란 의미로 2,4,6,8,10,12월에 해당되고 /d 매개변수는 1~31일까지

지정이 가능하다.

반면에 /mo SECOND로 지정하면 둘째주라는 의미이며 /d 매개변수는 MON, TUE, WED, THU,

FRI, SAT, SUN로 지정이 가능하다.

/sc /monthly /mo last /d sat : 매월 마지막 토요일

– /mo last 에는 /d 매개변수가 반드시 필요하며 /d 매개변수에는 1~31이 아닌 MON, TUE, WED,

THU, FRI, SAT, SUN로 지정해야 한다.

/sc /monthly /mo lastday /m Jan, Feb 1월 2월 마지막 일

– /mo lastday에는 /m 매개변수가 반드시 필요하며 유효값에는 JAN, FEB, MAR, APR, MAY,

JUN, JUL, AUG, SEP, OCT, NOV, DEC. 와일드카드 “*”가 있다.

1월과 7월의 첫번째 월요일에 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc monthly /mo FIRST /d MON /m JAN,JUL

참고 : /sc monthly에서 /m이 생략되면 매월 실행

 

 

▣ 특정 일 단위 작업

매월 1일에 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc monthly

참고 : /sc monthly에서 /m이 없으면 매월 실행, /d가 없으면 기본값은 1이다.

6월 1일과 7월 1일 오후 6시에 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc monthly /d 1 /m JUN,JUL /st 18:00

매월 말일에 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc monthly /mo lastday /m *

참고 : /sc monthly /mo lastday에서는 반드시 /m 매개변수가 필요하다.

5,6,7월의 마지막 일 18:00에 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc monthly /mo lastday /m MAY,JUN, JUL /st 18:00

 

 

▣ 한번만 필요한 작업

한번 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc once /sd 2018/06/01 /st 00:00

참고 : 한번만 실행되는 작업의 /sc 매개변수는 once이다.

/sd 매개변수는 선택사항이며 /st 매개변수는 필수사항이다.

 

 

▣ 시스템이 시작될 때 작업

시스템이 시작 될때 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc onstart /sd 2018/05/13

참고 : 시스템이 시작할 때 실행되는 작업의 /sc 매개변수는 onstart이다.

/sd 매개변수는 선택사항이며 기본값은 현재 날짜이다.

 

 

▣ 로그온 할 때 작업

로그온 할 때 실행 되는 작업

schtasks /create /tn “Virus Check3” /tr “cmd /k cd \”c:\Program Files\Windows Defender\” & MpCmdRun.exe -Scan -scantype 2″ /sc onlogon

참고 : 로그온 할 때 실행되는 작업의 /sc 매개변수는 onlogon이다.

/sd 매개변수는 선택사항이며 기본값은 현재 날짜이다.

/s 매개변수는 연결할 원격시스템이며 생략되면 로컬시스템이 기본값이다.

 

 

▣ 시스템이 유휴상태일 때 작업

시스템이 유휴상태일 때 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc onidle /i 10

참고 : 시스템이 유휴상태(사용자 사용이 없는 상태)

/i 매개변수는 유휴상태 대기 시간을 설정하며 유효값은 1~999분이다.

위 구문은 사용자입력이 10분동안 없으면 작업이 실행된다.

 

 

▣ 시스템 이벤트가 게시될 때 작업

특정 이벤트가 채널에 게시될때 마다 실행되는 작업

schtasks /create /tn “Event Check” /tr “Msg Admin01 계정이 변경되었습니다.” /sc onevent /ec Security /MO “*[System[Provider[@Name=’Microsoft-Windows-Security-Auditing’] and EventID=4738]]”

참고 : /sc onevent 에서 /ec는 event channel이며 유효값은 Application, Security, Setup, System 이다.

이벤트 쿼리 스트링에서는 반드시 대문자, 소문자 구별을 해야 한다.

이벤트 쿼리 스트링부분은 다음과 같이 간략하게 줄일 수 있다.

/MO *[System/EventID=4738]

 

 

▣ 지금 작업

지금부터 몇분 후에 한번 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc once /st 14:18 /sd 2018/05/13

참고 : 지금실행이라는 옵션은 없지만 현재시간으로부터 몇분 후에 한번 실행되는 작업을 만들 수 있다.

/st 매개변수는 필수사항이고 /sd 매개변수는 선택사항이다.

 

 

▣ 다른 권한으로 작업

로컬시스템에서 관리자권한으로 실행되는 작업

schtasks /create /tn “My Prg” /tr myprg.exe /sc weekly /d FRI /ru Admin01

참고 : 관리자권한(Admin01)으로 실행되는 작업을 만드려면 /ru 매개변수가 필요하다.

만약 명령을 입력하는 현재의 계정이 표준계정이라면 암호를 입력하는 메시지가 표시되며

암호를 입력해야만 한다.

이러한 암호는 /rp 매개변수로 처음부터 입력할 수 있으며 선택사항이다.

입력하는 계정이 관리자 계정에서는 암호가 필요하지 않다.

원격 시스템에서 다른 권한으로 3일마다 실행되는 작업

schtasks /create /tn “My Prg” /tr myprg.exe /sc daily /mo 3 /s office04 /u office04\Admin01 /ru Domain01\UserAcnt03

Type the password for office04\Admin01:********

Please enter the run as password for Domain01\UserAcnt03: ********

SUCCESS: The scheduled task “My Prg” has successfully been created.

참고 : /s 매개변수는 원격시스템이며

/u 매개변수는 원격시스템에서 작업권한이 있는 계정을 지정 – 작업예약 계정

/ru 작업을 실행할 때 사용되는 계정 지정 – 작업실행 계정

/ru 매개변수가 생략되면 /u 매개변수의 계정으로 실행

특정 사용자가 로그온 되어 있는 경우에만 매주 월요일 오후 5시에 실행되는 작업

schtasks /create /tn “My Prg” /tr myprg.exe /sc weekly /d MON /st 17:00 /s System10 /u Domain3\Admin03 /ru System10\Admin01 /it

참고 : System10\Admin01계정이 로그온되어 있는 경우에만 매주 금요일 오전 4시에 작업을 실행.

/it 매개변수는 System10\Admin01계정이 로그온되어 있는 경우에만 작업이 실행되는 옵션이다.

interactive전용(/it)속성이 있는 작업을 식별하려면 상세 쿼리(/Query/v)를 사용. /it 옵션이 포함된

작업의 상세 조회 표시에서 로그온 모드 필드의 값은 대화형만 가진다.

schtasks /query /v

시스템 권한으로 매월 7일에 실행되는 작업

schtasks /create /tn “My Prg” /tr c:\prg\myprg.exe /sc monthly /d 7 /ru System

참고 : /ru System(또는/ru “”)매개 변수(시스템보안 컨텍스트)가 필요하며 /rp 매개 변수가 유효하지 않는다.

/ru시스템 작업에서 암호를 사용하지 않으므로 /rp 매개 변수를 생략한다.

시스템 계정에 대화형 로그온 권한이 없으므로 사용자는 시스템 사용 권한으로 실행되는 프로그램

또는 작업을 보거나 상호 작용할 수 없다.

/ru 매개 변수는 작업을 예약하는 데 사용되는 권한이 아니라 작업이 실행되는 사용 권한을 결정.

/ru 매개 변수 값에 관계 없이 관리자(administrator)만 작업을 예약할 수 있다.

시스템 권한으로 실행되는 작업을 식별하려면 세부 쿼리(/query/v)를 사용.

시스템 실행 작업의 상세 조회 표시에서 “다음 계정으로 실행” 필드의 값은

NTAUTHORITY\SYSTEM이고 로그온 모드 필드의 값은 백그라운드 값이다.

원격 컴퓨터에서 시스템권한으로 매일 아침 8시에 실행되는 작업

schtasks /create /tn “My Prg” /tr myprg.exe /sc daily /st 08:00 /s computer01 /u Admin01 /ru System

참고 : /tr 매개 변수를 사용하여 myprg프로그램의 원격 복사본을 지정.

/sc 매개 변수를 사용하여 일일 작업을 지정하고 /mo 매개 변수를 생략하여 기본 값이 1(매일)으로

구성한다.

/u 매개 변수를 사용하여 원격 시스템에서 작업을 예약할 수 있는 권한이 있는 계정을 지정.

/ru 매개 변수를 사용하여 시스템 계정에서 작업을 실행하도록 지정.

/ru 매개 변수가 없으면 /u 에서 지정한 계정 권한으로 작업이 실행된다.

2개 이상의 프로그램이 실행되는 작업

schtasks /create /tn “security check” /tr c:\secuchk.bat /sc onlogon /ru Domain3\Admin01

참고 : 기본적으로 /tr 에서는 하나의 프로그램만 실행된다.

2개 이상의 프로그램을 실행하는 작업을 하려면 메모장에 프로그램을 나열하고 배치파일

(secuchk.bat)로 저장

예 : c:\Windows\System32\wf.msc

c:\Windows\Sytem32\secpol.msc

로그온 할때마다 관리자계정 권한으로 방화벽과 로컬보안정책이 동시에 실행된다.

원격 시스템에서 15일마다 실행되는 작업

schtasks /create /tn “My Prg” /tr “c:\program files\programs\myprg.exe” /sc daily /mo 15 /s server01

참고 : 로컬 현재 사용자는 원격 시스템의 관리자이므로 작업 예약에 대한 대체 권한을 제공하는

/u 매개 변수는 필요하지 않는다.

원격 컴퓨터에서 작업을 예약할 때는 모든 매개 변수가 원격 컴퓨터를 참조한다. /tr r매개 변수로

지정된 실행 파일은 원격 시스템에 있는 실행파일의 복사본을 참조한다.

참고 : 원격 시스템에서 실행되도록 작업을 예약하려면 다음 조건을 충족해야 한다.

◈ 작업을 예약할 수 있는 권한이 있어야 한다. 따라서 원격 시스템의 관리자 그룹에 속한 계정으로

로컬 시스템에서 로그온 하거나 원격 시스템의 관리자 자격 증명을 제공하려면 /u 매개 변수를

사용해야 한다.

◈ 로컬 및 원격 컴퓨터가 동일한 도메인에 있거나 원격 컴퓨터 도메인이 신뢰하는 도메인에

있는 경우에만 /u 매개 변수를 사용할 수 있다. 그렇지 않으면 원격 시스템이 지정된 사용자 계정을

인증할 수 없고 해당 계정이 관리자 그룹의 구성원인지 확인할 수 없다.

◈ 원격 컴퓨터에서 실행할 수 있는 충분한 권한이 있어야 한다. 기본적으로 작업은 로컬 컴퓨터의

현재 사용자 권한으로 실행되거나 /u 매개 변수를 사용하는 경우 /u 매개 변수로 지정된 계정의

사용 권한으로 실행된다. 그러나 /ru 매개 변수를 사용하여 다른 사용자 계정이나 시스템 사용

권한으로 작업을 실행할 수도 있다.

사용자가 원격 컴퓨터에서 3시간 마다 명령을 예약하는 경우

schtasks /create /tn “My Prg” /tr “c:\program files\programs\myprg.exe” /sc hourly /mo 3 /s server01 /u Domain1\admin01 /p N28$sp4X /ru server01\user04 /rp MyPw!9aD

참고 : 작업을 예약하려면 관리자 권한이 필요하므로 명령은 /u및 /p매개 변수를 사용하여 사용자의 관리자 계정 (Reskits도메인의 관리자 11)의 자격 증명을 제공한다. 기본적으로 이러한 권한은 작업를 실행하는 데도 사용된다.

그러나 작업을 실행하는 데 관리자 권한이 필요하지 않으므로 명령에는 /u및 /rp매개 변수가 포함되어 기본 값을 재정의하고 원격 시스템에서 사용자의 비 관리자 계정 권한으로 작업을 실행한다.

사용자가 원격 컴퓨터에서 매월 마지막 일에 명령을 예약하는 경우

schtasks /create /tn “My Prg” /tr “c:\program files\programs\myprg.exe” /sc monthly /mo LASTDAY /m * /s server2 /u business1\admin01

참고 : 로컬 현재 사용자(user01)는 원격 시스템의 관리자가 아니므로 명령은 /u 매개 변수를

사용하여 사용자의 관리자 계정(business도메인의 관리자 11)의 자격 증명을 제공하여 작업을 예약한다.

관리자 계정 권한은 작업을 예약하고 작업을 실행하는데 사용된다.

명령에 /p (비밀 번호)매개 변수가 포함되어 있지 않기 때문에 schtasks는 비밀 번호를 묻는 메시지를 표시한다.

그런 다음 성공 메시지와 경고를 표시한다.

다른 도메인 내 iframe의 세션이 유지가 안될때 ( Same Site )

문 제

A.com 내에 내가만든 B.com/B.jsp 을 iframe 으로 걸었다.

내가 만든 B.com/B.jsp 내의 세션값을 뽑아도 계속 null인 상황이다.

줄곧 크롬으로 테스트 했던터라 IE로 하니까 또 잘된다.

확인한 부분을 정리하면 이렇다.

1. 크롬 개발자 도구로 Response Headers 를 확인 보았다.

2. Set-Cookie 값안에 JSESSIONID 값이 만들어 지는데, 이값이 호출때마다 변경 된다.

자세히 보면 오른쪽에 노란색 느낌표가 떠있고, 마우스를 가져가면, SameSite 관련 부연설명이 나온다.

웹 search를 해보면 SameSite관련 이슈로 A.com -> B.com POST 방식으로

리다이렉트 했을때 기존에 읽어지던 쿠키값을 읽을수 없는케이스가 제일 많은듯 했다.

3. iframe을 걸어놓은 B.com/B.jsp 에서는 session.getAttribute를 통해서 값이 꺼내지지만,

   java servlet 레벨에서 아래와 같이 뽑아도 null 값만 나오게 된다.

request.getSession().getAttribute("String");

원인 – Chrome 80 쿠키 SameSite 정책이 변경 되었다.

– 도메인이 서로 다른 사이트 간 이동을 하는 경우 쿠키 전달 불가

– 기본 SameSite를 Lax로 변경

( 2020년 2월4일 크롬 80버전 부터 변경 !! )

SamteSite 쿠키에 대해

SameSite 쿠키의 정책으로 None, Lax, Strict 세 가지 종류를 선택할 수 있고

동작하는 방식이 다르다고 할수 있다.

None: 

– SameSite 가 탄생하기 전 쿠키와 동작하는 방식

– None으로 설정된 쿠키의 경우 크로스 사이트 요청의 경우에도 항상 전송

– SameSite를 None으로 설정할 경우 쿠키에 암호화된 HTTPS 연결이 필요함을 나타내는

   Secure 속성을 같이 설정해주어야 한다.
– HTTPS 일때만 사용 가능.

Lax: 

Strict에 비해 상대적으로 느슨한 정책입니다. Lax로 설정된 경우, 대체로 서드 파티 쿠키는 전송되지 않지만, 몇 가지 예외적인 요청에는 전송 된다.

Strict: 

– 가장 보수적인 정책.

– Strict로 설정된 쿠키는 크로스 사이트 요청에는 항상 전송않음.

– 즉, 서드 파티 쿠키는 전송되지 않고, 퍼스트 파티 쿠키만 전송 된다

해 결

결론은 크롬의 쿠키 보안정책이 바뀌어서,

기본이 SameSite의 레벨이 NONE에서 LAX 올라갔으니, 다시 NONE으로 내려주면 된다는 것이다.

중요한점은 HTTPS 일때 사용가능하다.

SameSite 설정시에 None 옵션과 Secure를 함께 주도록되어있는데,

이때 Https일때만 사용이 가능하다고 한다.

즉 B.com 의 도메인은 https 호출이 가능해야 한다.

A.com 의 설정을 건드릴 필요없이 iframe이 걸리는 B.com 쪽에 서버 설정을 수정해야 했다.

나는 앞단에 Apache 서버가 있고, WAS 가 따로 있는 상황이었다.

이럴경우는 apache 웹서버에서 설정을 해줄수 있다.

Apache_HOME / conf / httpd.conf

<IfModule headers_module>
        Header edit Set-Cookie ^(.*)$ $1;SameSite=None;Secure;
</IfModule>

값을 넣어주고 apache 재기동을 했다.

다음부터는 호출시 B.com/b.jsp에서도 세션값에서 정상적으로 값이 꺼내지고

Set-Cookie 값안에 JSESSIONID 값 자체가 유지되는 것을 확인 할수 있었다.

구글 공지

https://blog.chromium.org/2019/10/developers-get-ready-for-new.html

참고자료

https://web.dev/samesite-cookies-explained/

https://chromestatus.com/feature/5088147346030592

http://www.gnujava.com/board/article_view.jsp?board_no=37&article_no=8583

https://velog.io/@jsj3282/%EA%B5%AC%EA%B8%80-Chrome-SameSite-%EC%9D%B4%EC%8A%88

[Kubernetes] Understanding how the Calico CNI works

[Kubernetes] Calico CNI 동작원리 이해하기

  • Calico란, 컨테이너, 가상 머신 및 기본 호스트 기반 워크로드를 위한 오픈 소스 네트워킹 및 네트워크 보안 솔루션이다.
  • Kubernetes, OpenShift, Mirantis Kubernetes Engine(MKE), OpenStack 및 베어메탈 서비스를 포함한 광범위한 플랫폼 지원한다.
  • Calico의 eBPF 데이터 플레인을 사용하든 Linux의 표준 네트워킹 파이프라인을 사용하든 Calico는 진정한 클라우드 네이티브 확장성과 함께 놀랍도록 빠른 성능을 제공한다.
  • Calico는 공용 클라우드나 온프레미스, 단일 노드 또는 수천 개의 노드 클러스터에서 실행되는지 여부에 관계없이 개발자와 클러스터 운영자에게 일관된 경험과 기능 세트를 제공한다.

구성 요소 아키텍처(링크)

    • BGP(Border Gateway Protocol): AS 사이에서 이용되는 라우팅 프로토콜. 대규모 네트워크(수천만의 경로 수)에 대응하도록 설계됐다. 그래서 BGP로 동작하는 라우터는 비교적 고가인 제품이 많다.
    • AS(Autonomous System): 하나의 정책을 바탕으로 관리되는 네트워크(자율 시스템)를 말한다. ISP, 엔터프라이즈 기업, 공공기관 같은 조직이 이에 해당하며 인터넷은 이러한 자율 시스템의 집합체이다.여러가지 구성 요소가 많지만, 일단 눈여겨 볼 내용은 Calico가 사용하는 Datastore[1]와 마스터 노드를 포함한 모든 노드들에 존재하는 Calico Pods[2]
      • Felix (필릭스) : 인터페이스 관리, 라우팅 정보 관리, ACL 관리, 상태 체크
      • BIRD (버드): BGP Peer 에 라우팅 정보 전파 및 수신, BGP RR(Route Reflector)
      • Confd : calico global 설정과 BGP 설정 변경 시(트리거) BIRD 에 적용해줌
      • Datastore plugin : calico 설정 정보를 저장하는 곳 – k8s API datastore(kdd) 혹은 etcd 중 선택
      • Calico IPAM plugin : 클러스터 내에서 파드에 할당할 IP 대역
      • calico-kube-controllers : calico 동작 관련 감시(watch)
      • calicoctl : calico 오브젝트를 CRUD 할 수 있다, 즉 datastore 접근 가능

구성 요소 확인하기

  • 데몬셋으로 각 노드에 calico-node 파드가 동작하여, 해당 파드에 birdfelixconfd 등이 동작 + Calico 컨트롤러 파드는 디플로이먼트로 생성
    • Calico의 특징은 BGP를 이용해 각 노드에 할당된 Pod 대역의 정보를 전달한다. 즉, 쿠버네티스 서버뿐만 아니라 물리적인 라우터와도 연동이 가능 하다는 뜻이다. (Flannel의 경우 해당 구성 불가)
    • Calico Pod 안에서 Bird라고 하는 오픈소스 라우팅 데몬 프로그램이 프로세스로 동작하여 각 Node의 Pod 정보가 전파되는 것이다.
    • 이후 Felix라는 컴포넌트가 리눅스 라우터의 라우팅 테이블 및 iptables rule에 전달 받은 정보를 주입하는 형태이다.
    • confd는 변경되는 값을 계속 반영할 수 있도록 트리거 하는 역할이다.

Calico 기본 통신 과정 확인하기

calicoctl 설치

  • 리소스 관리를 위해 Calico CLI를 설치 및 구성

마스터 노드 확인

  • Calico CNI 설치시, 데몬셋이므로 모든 노드에 칼리코 파드가 하나씩 존재하게 된다. (calico-node-*)
  • 칼리코 컨트롤러가 하나 존재하는 것을 확인할 수 있다.
  • calicoctl ipm show 명령어를 통해, IAPM 정보를 확인할 수 있다. 아래 스크린샷에서는 172.16.0.0/16 대역을 해당 쿠버네티스 클러스터에서 사용할 수 있다는 내용을 알 수 있다.

    • IPAM(IP Address Management): 풍부한 사용자 환경을 통해 IP 주소 인프라의 엔드 투 엔드 계획, 배포, 관리 및 모니터링을 지원하는 통합 도구 모음이다.
      IPAM은 네트워크상의 IP 주소 인프라 서버 및 DNS(도메인 이름 시스템) 서버를 자동으로 검색하여 중앙 인터페이스에서 이들 서버를 관리할 수 있다.
    • 옵션을 통해 아래와 같이 특정한 노드에 할당 가능한 대역대를 확인할 수도 있음(Block는 각 노드에 할당된 Pod CIDR 정보를 나타냄)
  • calicoctl node 정보 확인
  • ippool 정보 확인
  • 파드와 서비스 사용 네트워크 대역 정보 확인

실습 1.

동일 노드 내 파드 간 통신

  • 결론: 동일 노드 내의 파드 간 통신은 내부에서 직접 통신됨

파드 생성 전 노드(k8s-w1)의 기본 상태

노드(k8s-w1)에 파드 2개 생성

  • 아래 내용으로 node1-pod2.yaml 파일 작성 후 파드 생성
  • 파드 생성 전후의 변화를 관찰하기 위해 터미널 하단 추가 탭에watch calicoctl get workloadEndpoint 명령어를 사용하여 모니터링
    • calicoctl 명령어로 endpoint 확인: veth 정보도 확인할 수 있음

생성된 파드 정보 확인

네트워크 인터페이스 정보 확인(k8s-w1)

  • calice#~ 두개 추가된 것을 확인할 수 있음
  • 각각 net ns 0,1로 호스트와 구별되는 것을 확인할 수 있음

네트워크 네임스페이스 확인

  • 아래 2개 PAUSE 컨테이너가 각각 파드별로 생성된 것을 확인할 수 있음
  • 바로 위 스크린샷인 link-netnsid 0, link-netnsid 1과 매칭됨

라우팅 테이블 확인

  • 파드의 IP/32bit 호스트 라우팅 대역이 라우팅 테이블에 추가된 것을 확인할 수 있음

파드간 통신 실행 이해

  • (위) 마스터 노드에서 Pod1 Shell에 접근하여 Pod2로 Ping 테스트
  • (아래) 워커 노드(k8s-w1)에서 iptables 필터 테이블에 FORWARD 리스트 중 cali-FORWARD 룰 정보를 필터링해서 watch로 확인
  • 테스트 결과 아래 이미지와 같이 Host iptables에서 FOWRARD라는 테이블의 허용 조건에 따라 정상적으로 통신이 가능한 것을 확인할 수 있다.

파드에서 외부(인터넷)로의 통신

  • 결론: 파드에서 외부(인터넷) 통신 시에는 해당 노드의 네트워크 인터페이스 IP 주소로 MASQUERADE(출발지 IP가 변경) 되어서 외부에 연결됨

파드 배포 전 calico 설정 정보 확인 & 노드에 iptables 확인

  • 마스터 노드에서 아래 내용 확인: natOutgoing의 기본값이 true로 설정되어 있는 것을 확인 할 수 있다. 즉 이 노드에서 외부로 통신할 때 NAT의 MASQUERADE를 사용하겠다는 의미이다.

    NAT – MASQUERADE : 조건에 일치하는 패킷의 출발지 주소를 변환하는 것. 내부에서 전달되는 요청의 출발지 주소를 조건에 지정된 인터페이스의 IP로 변환한다.

  • 워커 노드(k8s-w1)에서도 외부로 통신시 MASQUERADE 동작 Rule이 존재하는 것을 확인할 수 있다.

마스터 노드에서 워커 노드(k8s-w1)에 아래 내용의 파드 1개 생성

외부 통신 가능 여부 확인

  • 통신 전, 워커 노드(k8s-w1)에 iptables NAT MASQUERADE 모니터링을 활성화 하면 외부 통신시 pkts값이 증가하는지 확인할 수 있다.
  • (위) 마스터 노드에서 Pod1 Shell 실행 후, 8.8.8.8로의 통신 성공
  • (아래) pkts 값이 이전 이미지와 다르게 증가한 것을 확인할 수 있다.

다른 노드에서 파드 간 통신

  • 결론: 다른 노드 환경에서 파드 간 통신시에는 IPIP터널(기본값) 모드를 통해서 이루어진다.
    • 각 노드에 파드 네트워크 대역은 Bird에 의해서 BGP로 광고 전파/전달 되며, Felix에 의해서 호스트의 라우팅 테이블에 자동으로 추가/삭제 된다.
    • 다른 노드 간의 파드 통신은 tunl0 인터페이스를 통해 IP 헤더에 감싸져서 상대측 노드로 도달 후 tunl0 인터페이스에서 Outer 헤더를 제거하고 내부 파드와 통신한다.

파드 배포 전, 노드에서 BGP에 의해 전달 받은 정보가 호스트 라우팅 테이블에 존재하는지 확인

  • 아래 명령어를 통해 나머지 노드들의 파드 대역을 자신의 호스트 라우팅 테이블에 가지고 있고, 해당 경로는 tunl0 인터페이스로 보내게 된다는 사실을 알 수 있다.

워커 노드(k8s-w1, w2)의 tunl0 정보 확인

  • 터널 인터페이스가 IP에 할당되어 있음
  • MTU는 1480 (칼리코 사용 시 파드의 인터페이스도 기본 MTU 1480 사용)
  • 현재 TX/RX 카운트는 0 –> 잠시 후, 오버레이 통신시 카운트 값이 증가할 것

마스터 노드에서 워커 노드(k8s-w1, w2) 대상으로 각각 파드 1개씩 생성

  • calicoctl 명령어를 이용하여 생성된 파드의 엔드포인트 확인

각 노드에서 파드 간 통신을 처리하는 라우팅 정보 확인

  • k8s-w1(172.16.158.4/32) 노드에서 w2(172.16.184.0) 노드 대역에 통신하려면 192.168.10.102를 거쳐야 한다는 것을 확인할 수 있다.
  • 반대로 w2(172.16.184.1/32) 노드에서 w1(172.16.158.0) 노드 대역에 통신하려면 192.168.10.101를 거쳐야 한다.

다른 노드 파드 간 통신이 어떻게 실행되는지 확인 ⇒ IPIP

  • (상) Pod2가 속한 노드(k8s-w2)에 tunl0 인터페이스 TX/RX 패킷 카운트 모니터링 세팅
  • (중) 마스터 노드에서 Pod1 Shell 접속 후, Pod2로 Ping 통신 테스트 준비
  • (하) Pod1이 속한 노드(k8s-w1)에서 패킷 덤프 세팅: tunl0 – 터널 인터페이스에 파드간 IP 패킷 정보를 확인할 수 있음
  • 결과
    • (중) Pod1 –> Pod2로 정상 통신 확인
    • (상) tunl0 인터페이스의 TX/RX 패킷 카운트가 각각 10개로 증가
    • (하) 실제 통신을 하게 되는 파드 간 IP 패킷 정보 확인
  • 실제로 오버레이 통신을 하고 있는지 확인하기 위해 패킷덤프 명령어를 아래와 같이 수정하여 Ping 통신을 다시 하였고, 결과적으로 IP Outer(파란색 박스) 헤더 정보 안쪽에 Inner(빨간색 박스) 헤더가 1개 더 있음을 확인할 수 있다.

Calico 네트워크 모드

Calico Mode 요약

  • 칼리코는 다양한 네트워크 통신 방법을 제공한다.

IPIP 모드

  • 파드 간 통신이 노드와 노드 구간에서는 IPIP 인캡슐레이션을 통해 이루어진다.
  • 단, Azure 네트워크에서는 IPIP 통신이 불가능하기 때문에 대신 VXLAN 모드를 사용한다고 한다.

Direct 모드

  • 파드 통신 패킷이 출발지 노드의 라우팅 정보를 보고 목적지 노드로 원본 패킷 그대로 전달된다.
  • 단, 클라우드 사업자 네트워크 사용 시, NIC에 매칭되지 않는 IP 패킷은 차단되니 NIC의 Source/Destination Check 기능을 Disable해야 정상 통신 가능 (AWS 문서 링크)

BGP 연동

  • Kubernetes 클러스터 내부 네트워크와 IDC 내부망 네트워크 간 직접 라우팅도 가능

VXLAN 모드

  • 파드 간 통신이 노드와 노드 구간에서는 VXLAN 인캡슐레이션을 통해서 이루어진다.
  • 다른 노드 간의 파드 통신은 vxlan 인터페이스를 통해 L2 프레임이 UDP – VXLAN에 감싸져 상대 노드로 도달 후 vxlan 인터페이스에서 Outer헤더를 제거하고 내부의 파드와 통신하게 된다.
  • BGP 미사용, VXLAN L3 라우팅을 통해서 동작한다.
  • UDP를 사용하므로 Azure 네트워크에서도 사용 가능하다.

Pod 패킷 암호화(네트워크 레벨)

  • Calico의 다양한 네트워크 모드 환경 위에서 WireGuard 터널을 자동 생성 및 파드 트래픽을 암호화하여 노드 간 전달한다.
  • Yaml 파일에 간단하게 추가하는 것만으로도 네트워크 레벨의 패킷 암호화를 설정할 수 있다.
  • WireGuard는 구닥다리 IPsec 및 OpenVPN의 대항마로 등장한 open source VPN project이며 작년, Linux 5.6 커널에 WireGuard 1.0.0 기본 패키지로 탑재되었다.
  • 정말 간결한 코드 구조와 빠른 성능 (모든 것이 kernel에서 동작하고, 주요 암호 알고리즘에 대해서 병렬처리하므로써 빠른 속도를 자랑함)

실습 2. WireGuard

WireGuard 설정

  • 모든 노드에 WireGuard를 설치(apt install wireguard -y)하고, Enabled 설정
  • 현재 노드에 존재하는 Wireguard 퍼블릭 키 확인
  • wireguard.cali 인터페이스 정보 확인
  • wg로 시작하는 명령어를 사용하여 wireguard.cali 설정 확인: 노드 별로 각각의 상대방 Peer의 IP와 퍼블릭 키를 확인할 수 있음

동작 확인

  • 아래 내용으로 파드 생성
  • (상) 파드가 생성된 노드의 eth0(enp0s8)에서 패킷 덤프 모니터링 세팅
  • (하) 생성한 파드 Shell 접속 후 Ping 통신 준비
  • (하) Pod2 IP 확인
  • (중) Pod1 –> Pod2 Ping 정상 통신
  • (상) 51820 포트 패킷 덤프 내용 확인

3-Tier container environment configuration using Kubernetes (NginX/Tomcat/MySQL)

쿠버네티스를 활용한 3-Tier 컨테이너 환경 구성을 해보고자 한다. 구성은 도커와 동일하게 아래와 같이 간다.

3-Tier container environment configuration using Docker(NginX/Tomcat/MySQL)

이번에는 구성 시에 1-Container에 WEB/WAS/DB Pod를 각각 띄울 예정이다.

동일한 컨테이너에서 기동하기 때문에 서로에 대한 IP는 변하지 않을 것이고 IP Address는 localhost로 설정해주어야 한다.

그렇기 때문에!!

– WEB-WAS 사이의 연동 설정에서 IP를 localhost로 변경

– WAS-DB 사이의 연동 설정(어플리케이션 부분)에서 DB IP를 localhost로 변경

해주어야한다.. 그렇다면 이미지 부터 다시 말아보자.

1. WEB 구성

1-1. NginX의 WAS 연동 설정 파일에서 IP Address를 localhost로 변경 후 다시 이미지 생성

> $ vi /root/nginx-for-petclinic/nginx/conf

17 http {
18     upstream was-list {
19         #server tomcat-petclinic:8080;
20         server localhost:8080;
21     }
22
23     include       mime.types;
24     default_type  application/octet-stream;

1-2. Dockerfile을 이용하여 이미지 생성

root@master:~/nginx-for-petclinic# pwd
/root/nginx-for-petclinic
root@master:~/nginx-for-petclinic# docker build -t nginx-petclinic:2.0 .

# 이미지 생성 후, 확인

root@master:~/nginx-for-petclinic# docker images
REPOSITORY                               TAG       IMAGE ID       CREATED         SIZE
nginx-petclinic                          2.0       1f34b3ccac6d   5 seconds ago   133MB

1-3. 이미지를 Dockerhub에 저장

> 내가 생성한 이미지를 이따 yaml파일에서 로드할  수 있도록..

root@master:~# docker tag nginx-petclinic:2.0 ghkd5216/nginx-petclinic:2.0
root@master:~# docker push ghkd5216/nginx-petclinic:2.0

The push refers to repository [docker.io/ghkd5216/nginx-petclinic]
52efdeec58ec: Pushed
201e7ba1790a: Pushed
9959a332cf6e: Layer already exists
f7e00b807643: Layer already exists
f8e880dfc4ef: Layer already exists
788e89a4d186: Layer already exists
43f4e41372e4: Layer already exists
e81bff2725db: Layer already exists
2.0: digest: sha256:15cf195c6e6575d744fa0eb07b429d0db3d99f61

2. WAS 구성

2-1. WAS에서는 AP쪽에 DB 설정이 있기 때문에 소스 빌드 및 해당 소스가 디플로이된 이미지를 다시 생성해야 한다.

> $vi /root/spring-framework-for-petclinic/pom.xml

> 515번 라인과 같이 localhost로 변경해주면 된다.

509             <id>MySQL</id>
510             <properties>
511                 <db.script>mysql</db.script>
512                 <jpa.database>MYSQL</jpa.database>
513                 <jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
514                 <!–<jdbc.url>jdbc:mysql://mysql-petclinic:3306/petclinic?useUnicode=true</jdbc.url>–>
515                 <jdbc.url>jdbc:mysql://localhost:3306/petclinic?useUnicode=true</jdbc.url>
516                 <jdbc.username>root</jdbc.username>
517                 <jdbc.password>petclinic</jdbc.password>
518             </properties>

2-2. 소스 빌드를 위한 자바 변경

> 자바 버전이 1.8이 되도록 수정

root@master:~/spring-framework-for-petclinic# sudo update-java-alternatives –jre-headless –jre –set java-1.8.0-openjdk-amd64

root@master:~/spring-framework-for-petclinic# java -version
openjdk version “1.8.0_292”
OpenJDK Runtime Environment (build 1.8.0_292-8u292-b10-0ubuntu1~20.04-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)

2-3. 소스 빌드

> 소스를 빌드하고 나면, 현 디렉토리에 target 안에 petclinic.war라는 소스 파일이 빌드되어 있을 것이다.

root@master:~/spring-framework-for-petclinic# mvn clean package -Dmaven.test.skip=true -P MySQL

…(중략)

[INFO] ————————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————————
[INFO] Total time:  13.144 s
[INFO] Finished at: 2021-11-16T18:04:01+09:00
[INFO] ————————————————————————

2-4. WAS 이미지 생성

> 이제 만든 소스를 활용하여 tomcat 이미지를 만들어보도록 하자.

우선 이미지 생성을 위해 Dockerfile을 생성하고 위에서 만들었던 petclinic.war 파일을 Dockerfile 디렉토리에 위치시킨다.

root@master:/home/dockerfile/petclinic# pwd
/home/dockerfile/petclinic
root@master:/home/dockerfile/petclinic# ls -arlt
total 40644
drwxr-xr-x 5 root root     4096 11월  7 14:06 ..
-rw-r–r– 1 root root 41605349 11월  7 14:06 petclinic.war
-rw-r–r– 1 root root       64 11월  7 14:06 Dockerfile
drwxr-xr-x 2 root root     4096 11월  7 14:06 .

==================================================
하기는 Dockerfile 내용이다.
==================================================
root@master:/home/dockerfile/petclinic# cat Dockerfile
From tomcat:8-jre8
ADD petclinic.war /usr/local/tomcat/webapps/

위와 같이 준비가 되었다면 이제 해당 위치에서 이미지 빌드를 하면 된다.

커맨드는 아래와 같다.

root@master:/home/dockerfile/petclinic# docker build -t tomcat-petclinic:2.0 .
Sending build context to Docker daemon  41.61MB
Step 1/2 : From tomcat:8-jre8
—> cff25871f024
Step 2/2 : ADD petclinic.war /usr/local/tomcat/webapps/
—> 1c6d007012d5
Successfully built 1c6d007012d5
Successfully tagged tomcat-petclinic:2.0

2-5. 이미지를 Dockerhub에 저장

> 내가 생성한 이미지를 이따 yaml파일에서 로드할  수 있도록..

root@master:~# docker tag tomcat-petclinic:2.0 ghkd5216/tomcat-petclinic:2.0
root@master:~# docker push ghkd5216/tomcat-petclinic:2.0
The push refers to repository [docker.io/ghkd5216/tomcat-petclinic]
3fe16f1fe077: Pushed
7a1149e8d0d8: Layer already exists
f3d15ade5c54: Layer already exists
80ac7083a323: Layer already exists
01de28a83f3f: Layer already exists
74a293db1084: Layer already exists
68c1e7509c65: Layer already exists
6ccd0e6bdf7a: Layer already exists
9f9f651e9303: Layer already exists
0b3c02b5d746: Layer already exists
62a747bf1719: Layer already exists
2.0: digest: sha256:7ee8909691df00b211aa42f1605062019422b0d93d52053d4ad01034390e04a7 size: 2631

3. YAML 파일 생성

이제 이미지도 준비되었고, yaml 파일만 생성하여 기동해보면 된다.
도커와는 다르게 쿠버네티스의 경우에는 쿠버네티스 클러스터 내에서 동작하기 때문에 생성된 컨테이너의 IP 또한 클러스터 내의 CNI 네트워크 대역으로 할당된다.

그렇기 때문에 외부에서 해당 컨테이너에 접근하여 서비스를 호출하려면 Service를 통해 가능하다. AWS나 GCP같은 Public Cloud의 경우에는 Service에서 LoadBalnancer를 제공하여 외부로 노출할 IP를 할당 받지만, 우리가 테스트하는 방식과 같이 Baremetal(On-Premise) 환경에서는 LoadBalancer 기능이 없다. 그래서 LoadBalancer타입을 지원하게끔 하기 위해 MetalLB라는 놈을 사용해주어야 한다.

먼저 metalb을 설치해보면 아래와 같다.

root@master:~/yaml# kubectl apply -f  https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml

=================================
metallb.yaml 파일을 이용하여 파드와 기타 등등의 서비스를 실행한다.
이후, metallb-system 네임스페이스에 있는 리소스들을 조회해본다.
=================================

root@master:~/yaml# kc get all -n metallb-system

NAME                              READY   STATUS    RESTARTS   AGE
pod/controller-675d6c9976-d5k57   1/1     Running   0          9s
pod/speaker-h4l8n                 1/1     Running   0          9s
pod/speaker-rm54l                 1/1     Running   0          9s

NAME                     DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                 AGE
daemonset.apps/speaker   2         2         2       2            2           beta.kubernetes.io/os=linux   9s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/controller   1/1     1            1           9s

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/controller-675d6c9976   1         1         1       9s

이제 3-Tier환경의 컨테이너를 생성할 차례다.

yaml 파일의 경우 아래와 같다.

모든 항목들을 세세히 설명할 수는 없고 하나씩 찾아보면 기본적인 설정(포트/환경변수)만 되어있음을 볼 수 있다.

이 글에서는 가볍게 구성해보는 것이기 때문에 다음 글에서 좀 더 yaml 문법이나 파라미터 값을 공부해보아야 겠다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: petclinic-deployment
  namespace: default
  labels:
    app: petclinic-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
       app: petclinic-app
  template:
    metadata:
      labels:
        app: petclinic-app
    spec:
      containers:
      - image: mysql:5.7.8
        imagePullPolicy: Always
        name: mysql-petclinic
        ports:
        - containerPort: 3306
          protocol: TCP
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: petclinic
        - name: MYSQL_DATABASE
          value: petclinic
      - image: docker.io/ghkd5216/nginx-petclinic:2.0
        imagePullPolicy: Always
        name: nginx-petclinic
        ports:
        - containerPort: 80
          protocol: TCP
      - image: docker.io/ghkd5216/tomcat-petclinic:2.0
        imagePullPolicy: Always
        name: tomcat-petclinic
        env:
        - name: JAVA_OPTS
          value: "-Xms512m -Xmx512m"
        ports:
        - containerPort: 8080
          protocol: TCP
      restartPolicy: Always

---

apiVersion: v1
kind: Service
metadata:
  name: petclinic-svc
spec:
  type: LoadBalancer
  selector:
    app: petclinic-app
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80


---

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.1.240-192.168.1.250

> 제일 하단에 metallb 관련 설정을 보면 addresses 범위 안에서 외부로 노출할 ExternalIP 대역을 설정할 수 있다.

이제 만든 yaml 파일을 실행하여 보자!!

4. Kubernetes를 통한 컨테이너 배포

root@master:~/yaml# kc apply -f petclinic-app.yaml
deployment.apps/petclinic-deployment created
service/petclinic-svc created
configmap/config created

root@master:~/yaml# kc get all
NAME                                        READY   STATUS    RESTARTS   AGE
pod/petclinic-deployment-86dc87794d-j69mm   3/3     Running   0          24s

NAME                    TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)        AGE
service/kubernetes      ClusterIP      10.96.0.1        <none>           443/TCP        13d
service/petclinic-svc   LoadBalancer   10.109.251.153   192.168.56.240   80:30560/TCP   24s

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/petclinic-deployment   1/1     1            1           24s

NAME                                              DESIRED   CURRENT   READY   AGE
replicaset.apps/petclinic-deployment-86dc87794d   1         1         1       24s

> 위와 같이 LoadBalancer 타입의 Service가 생성되어 External-IP를 할당하여 외부로 노출하는 것을 볼 수 있다.

이제 모든 준비가 끝났다.

실제로 외부의 웹 브라우저에서 클라이언트 입장으로 서비스를 호출해보자. 호출 url은 EXTERNAL_IP:[LB PORT]/petclinic 이다.

나의 경우에는 http://192.168.56.240:80/petclinic/으로 호출하면 된다.

5. 서비스 호출

 

 

> 외부 노출 IP로 정상적으로 접근 가능하다. 몇 가지 업무 테스트를 해보면,

 

 

정상적으로 데이터가 DB에 저장되는 것을 볼 수 있다.

3-Tier container environment configuration using Docker(NginX/Tomcat/MySQL)

이번 글에서는 Docker를 사용하여 간단한 3-Tier 컨테이너 환경을 구성해보고자 한다.

– WEB = NginX

– WAS = Tomcat

– DB = MySQL

구성은 WAS -> WEB -> DB 순으로 하도록 한다.

우선,  WAS 부터 구성해보도록 하자.

1. WAS 구성

1-1. Github에 올라가 있는 어플리케이션 소스 다운로드

> 소스를 다운받을 디렉토리 생성 후 Git 저장소에서 소스를 Pull 한다.

root@master:~# mkdir -p /home/src
root@master:~# cd /home/src
root@master:/home/src#

root@master:/home/src# git clone https://github.com/Hwang-sangyeon/spring-framework-for-petclinic.git
Cloning into ‘spring-framework-for-petclinic’…
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 4 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 1.89 MiB | 4.96 MiB/s, done.

1-2. JDK와 Maven 설치

> 소스를 컴파일 하기 위해 OpenJDK와 Maven을 설치한다.

root@master:~# sudo apt-get install openjdk-8-jdk maven

(중략)

update-alternatives: using /usr/lib/jvm/java-11-openjdk-amd64/bin/unpack200 to provide /usr/bin/unpack200 (unpack200) in auto mode
update-alternatives: using /usr/lib/jvm/java-11-openjdk-amd64/lib/jexec to provide /usr/bin/jexec (jexec) in auto mode
Setting up libxdmcp-dev:amd64 (1:1.1.3-0ubuntu1) …
Setting up x11proto-core-dev (2019.2-1ubuntu1) …
Setting up libxcb1-dev:amd64 (1.14-2) …
Setting up libx11-dev:amd64 (2:1.6.9-2ubuntu1.2) …
Setting up libxt-dev:amd64 (1:1.1.5-1) …

1-3. JAVA_HOME 설정

> 현재 java -version으로 버전 확인 시 설치한 자바로 설정되어 있지 않기 때문에 아래와 같이 변경이 필요하다.

root@master:/home/src# sudo update-java-alternatives –list
java-1.11.0-openjdk-amd64      1111       /usr/lib/jvm/java-1.11.0-openjdk-amd64
java-1.8.0-openjdk-amd64       1081       /usr/lib/jvm/java-1.8.0-openjdk-amd64
root@master:/home/src#
root@master:/home/src#
root@master:~# sudo update-java-alternatives –jre-headless –jre –set java-1.8.0-openjdk-amd64

root@master:/home/src# java -version
openjdk version “1.8.0_292”
OpenJDK Runtime Environment (build 1.8.0_292-8u292-b10-0ubuntu1~20.04-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)

1-4. 소스 Build

> 이제 소스와 컴파일 할 JDK와 maven도 준비되었기 때문에 Compile을 해보도록 하자

소스 경로에 들어가 압축을 풀고 아래와 같이 빌드를 진행해준다.

빌드 전에 잠시 소스 수정이 필요하다.
pom.xml에 mysql 연동 부분에 localhost:3306을 mysql-petclinic:3306으로 수정하자.
was와 db가 다른 컨테이너로 기동되기 때문에 localhost를 인식할 수 없다.
그러나 mysql-petclinic은 컨테이너 명으로 link가 걸려 통신이 가능하다..

root@master:/home/src/spring-framework-for-petclinic/spring-framework-for-petclinic# mvn clean package -Dmaven.test.skip=true -P MySQL

…(중략)

[INFO] ————————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————————
[INFO] Total time:  16.802 s
[INFO] Finished at: 2021-11-07T13:54:37+09:00
[INFO] ————————————————————————

=========================================================================
빌드를 하고 나면, 소스 경로 하위의 target 디렉토리에 petclinic.war 소스 파일이 생성된다.

root@master:/home/src/spring-framework-for-petclinic/spring-framework-for-petclinic/target# ls -arlt|grep petclinic.war
-rw-r–r– 1 root root 41605349 11월  7 13:54 petclinic.war

1-5. WAS 이미지 생성

> 이제 만든 소스를 활용하여 tomcat 이미지를 만들어보도록 하자.

우선 이미지 생성을 위해 Dockerfile을 생성하고 이전에 만들었던 petclinic.war 파일을 같은 디렉토리에 위치시킨다.

root@master:/home/dockerfile/petclinic# pwd
/home/dockerfile/petclinic
root@master:/home/dockerfile/petclinic# ls -arlt
total 40644
drwxr-xr-x 5 root root     4096 11월  7 14:06 ..
-rw-r–r– 1 root root 41605349 11월  7 14:06 petclinic.war
-rw-r–r– 1 root root       64 11월  7 14:06 Dockerfile
drwxr-xr-x 2 root root     4096 11월  7 14:06 .

하기는 Dockerfile 내용이다.
root@master:/home/dockerfile/petclinic# cat Dockerfile
From tomcat:8-jre8
ADD petclinic.war /usr/local/tomcat/webapps/

위와 같이 준비가 되었다면 이제 해당 위치에서 이미지 빌드를 하면 된다.

커맨드는 아래와 같다.

root@master:~/docker/tomcat-test# docker build -t tomcat-petclinic .
Sending build context to Docker daemon  41.61MB
Step 1/2 : From tomcat:8-jre8
8-jre8: Pulling from library/tomcat
bb7d5a84853b: Pull complete
f02b617c6a8c: Pull complete
d32e17419b7e: Pull complete
ab18cfab55f9: Pull complete
793716e93ecb: Pull complete
3b9b14f7678b: Pull complete
4dc2d594b57d: Pull complete
3f275ee15a3d: Pull complete
15b0db619216: Pull complete
c0aa838e7a3a: Pull complete
Digest: sha256:47165dabe7c092c61ef2726a7fdc70dda0ce9dea07ca68bda0aea6ecfaba2873
Status: Downloaded newer image for tomcat:8-jre8
—> cff25871f024
Step 2/2 : ADD petclinic.war /usr/local/tomcat/webapps/
—> f27039d77fc4
Successfully built f27039d77fc4
Successfully tagged tomcat-petclinic:latest

2. WEB 구성

2-1. NginX 리소스 다운로드

> Git에 올라가 있는 NginX 리소스를 다운받는다.

root@master:/home/src# git clone https://github.com/Hwang-sangyeon/nginx-for-petclinic.git
Cloning into ‘nginx-for-petclinic’…

리소스 다운로드 후,

nginx.conf 파일에서 was 연동 포트 확인 및 nginx listen-port를 확인한다.

2-2. 이미지 생성

> Dockerfile이 있는 디렉토리에서 이미지를 빌드한다.

root@master:/home/src/nginx-for-petclinic/nginx-for-petclinic# docker build -t nginx-petclinic .
Sending build context to Docker daemon  6.656kB

2-3. WEB/WAS 이미지 확인

root@master:/home/src/nginx-for-petclinic/nginx-for-petclinic# docker images|grep petclinic
nginx-petclinic                          latest    952aff9083ee   19 seconds ago   133MB
tomcat-petclinic                         latest    39e56a91e5e7   9 minutes ago    334MB

3. 컨테이너 기동

이제부터는 필요한 이미지가 준비되었기 때문에 WEB/WAS/DB 컨테이너를 기동하여 3-Tier를 구성을 해보려고 한다.

여기서 중요한 점은 WAS가 기동되기 전에 (소스 빌드) DB가 먼저 떠있어야 하기 때문에 DB 컨테이너를 반드시 먼저 기동시켜야 한다는 것이다.

3-1. DB 컨테이너 기동

> mysql-petclinic 컨테이너 명으로 mysql 이미지를 바로 받아 컨테이너를 실행한다.

docker run --name mysql-petclinic -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8

Initializing database 이후 docker container ps로 확인

root@master:~# docker container ps | grep mysql
d286f5c59a6c   mysql:5.7.8            “/entrypoint.sh mysq…”   57 seconds ago      Up 56 seconds      0.0.0.0:3306->3306/tcp, :::3306->3306/tcp   mysql-petclinic

3-2. WAS 컨테이너 기동

docker run -it --rm -p 8080:8080 --name tomcat-petclinic --link mysql-petclinic:mysql-petclinic tomcat-petclinic

> tomcat 컨테이너에서 mysql 컨테이너의 ip로 접속할 수 있겠지만, static ip가 아니기 때문에 mysql 컨테이너의 이름으로 접속을 해야 할 필요가 있다. 이럴 경우 link 옵션을 통해 컨테이너를 구동하면 tomcat 컨테이너에서 mysql 컨테이너로 이름으로 접속할 수 있다. link 옵션으로 구동하면 톰캣 컨테이너 안의 /etc/hosts에 링크된 mysql 컨테이너 hostname과 ip가 들어간다.

3-3. WEB 컨테이너 기동

docker run -it --rm -p 80:80 --name nginx-petclinic --link tomcat-petclinic:tomcat-petclinic nginx-petclinic

4. 서비스 호출

 

192.168.56.200은 VM의 IP

 

이상 도커를 활용하여 3-Tier 컨테이너 환경을 구성해보았다..

DiskPart command concept and how to use.

Diskpart 개념과 사용 방법 안내

Windows OS에서 디스크 파티션을 조작할려면 [컴퓨터 관리]에 있는 [저장소] → [디스크 관리]를 사용하는 것이 일반적일 것입니다. 하지만 diskpart.exe라는 명령어를 이용해서도 똑같은 작업을 할 수 있습니다.

※ Diskpart는 파티션 작업 명령으로 데이터가 삭제되므로 중요 데이터 백업 및 확인후 사용토록 주의하시기 바랍니다.

Diskpart 란?

– Windows98이나 Windows ME에서 사용하던 Fdisk를 대체하는 파티션 툴로 동적 디스크를 지원하고, 디스크 관리 스냅인에서 지원하는 것보다 더 많은 작업을 수행할 수 있습니다. 디스크 관리 스냅인은 사용자가 실수로 데이터 손실을 초래할 수 있는 작업을 수행하지 못하도록 하지만, Diskpart를 사용하면 파티션과 볼륨을 명시적으로 제어할 수 있으며, 이런 기능 때문에 신중히 사용해 주셔야 합니다.

– 윈도우 XP, 2000, Vista, 7 이상 OS에서 사용 가능합니다. (위치 : C:\Windows\****32 폴더내 있습니다.)

Diskpart 사용 방법

1] Diskpart 모드 진입하기

  • 1. **** 모드로 CMD 콘솔 실행합니다.
  • 방법 : 시작 > 프로그램 및 파일 검색(또는 Windows 검색) 창에 ‘CMD’ 입력 > CMD 항목에 마우스 오른쪽 버튼 클릭 후 ‘**** 권한으로 실행’ 선택

    시작을 눌러 검색창에 cmd 입력하여 검색후 마우스 오른쪽 버튼을 눌러 **** 권한으로 실행을 클릭하는 예시 화면

  •  
  • 2. diskpart 입력 후 엔터를 칩니다.

    diskpart 입력하고 엔터 치는 창

  •  
  • 3. DISKPART> 프롬프트 발생하면 이후 사용 가능합니다.

    diskpart 명령프롬프트 떠 있는 창

2] 디스크 초기화하기

Diskpart 모드 진입 상태에서 명령어를 이용하여 하드디스크의 파티션을 모두 초기화합니다.

  •  
  • 1. list disk : 디스크목록 보기
  •  
  • 2. select disk 1 : 초기화할 disk를 선택합니다. (“sel disk 1” 와 동일)
  •  
  • 3. list partition : 파티션정보 확인 (“list part” 와 동일)
  •  
  • 4. clean : 선택된 디스크의 파티션정보를 전부 초기화
  •  
  • 5. list partition : 파티션 정보 사라짐 확인
  • 위 5가지 목록에 대하여 명령어를 입력하고 진행한 화면창

  • ※ 여기서 포커스란 개념이 나옵니다. select 명령을 이용해 작업하고자 하는 객체에 포커스를 주어야 합니다. select disk 1 이라고 주고 list disk 하자 disk 1 옆에 * 가 붙었습니다. 앞으로 disk 1 이 작업대상이 된 겁니다. (select disk=1이라고 해도 됩니다.)

3] 디스크 파티션 분할하기

하드디스크의 파티션을 분할(주, 확장, 논리) 합니다.

  •  
  • 1. list disk : 디스크 목록 보기
  •  
  • 2. select disk 1 : 초기화할 disk를 선택합니다.
  •  
  • 3. list partition : 파티션 정보 확인
  •  
  • 4. create partition primary size = 120000 : 주파티션을 120GB만큼 생성하는 명령어
  •  
  • 5. create partition extended : 확장파티션 생성
  •  
  • 6. create partition logical : 논리파티션 생성
  • 위의 6가지 항목을 차례대로 명령어 입력해서 진행한 창

※ create partition primary size = 120000

120000M 크기(size=120000)의 주파티션(primary partition)을 만들라(create)는 명령입니다. size 지정을 안하게 되면 이용가능한 모든 용량을 잡습니다. 파티션을 1개만 잡을 때 또는 마지막 파티션을 잡을 때는 size 옵션을 생략하면 됩니다. 주파티션은 4개까지 만들 수 있고, 그 이상을 만들려면 주파티션 1개 대신 확장파티션을 잡아야 합니다. 즉, 최대 주파티션 3개 확장파티션 1개가 됩니다. 확장파티션은 디스크당 1개만 만들 수 있습니다. 확장파티션에서 원하는 개수만큼 논리드라이브를 만듭니다.

※ 확장 파티션 설정

create partition extended : 확장파티션(extended partition)을 만들라(create)는 의미입니다. size 지정이 없으면 disk의 남은 용량을 전부 이용합니다. 확장 파티션에서는 반드시 1개 이상의 논리드라이브를 지정해 주어야 합니다. create partition logical size = 250 라고 하면 250메가의 논리드라이브(partition logical)가 생성되고, create partition logical size = 100 하면 100메가의 논리드라이브(partition ligical)가 추가 생성됩니다. create partition logical 이라고만 하면 나머지 용량을 모두 잡습니다. list partition을 입력하면 선택한 디스크의 파티션 정보를 볼 수 있습니다.

디스크관리의 디스크1의파티션에 포맷과 드라이브 문자 할당이 안되어있는 화면
※ create partition 이후 디스크 관리에서 디스크1의 파티션에 포맷과 드라이브 문자 할당이 안 되어 있습니다.

4] 파티션 포맷하기

분할된 파티션을 포맷합니다.

  •  
  • 1. format fs=ntfs quick : 현재 선택되어 있는 파티션을 ntfs로 빠른 포맷한다.
  •  
  • 2. list partition : 파티션 선택 확인
  •  
  • 3. select partition 1 : 포맷할 파티션 선택
  •  
  • 4. format fs=ntfs quick : 선택한 파티션을 ntfs로 빠른 포맷합니다.
    ※ 참고로 fs=fat32로 하면 FAT32로 포맷합니다. (단, 30GB 이하일 경우에만 진행해야 합니다.)

    위 4번항목에 대한 명령어를 모두 입력한 상태창

  •  
  • 5. 디스크 관리에서 포맷 완료는 확인되나, 아직 드라이브 문자 할당은 안된 상태로 보이게 됩니다.

    디스크관리에서 포맷완료는 했으나 드라이브 할당이 안된 상태창

5] 파티션[드라이브] 문자 할당

분할된 파티션에 드라이브명을 할당합니다.

  •  
  • 1. assign letter=x : 선택되어 있는 파티션에 X 드라이브명 할당
  •  
  • 2. list partition : 선택된 파티션을 확인

    위 2가지 항목에 대한 명령어 실행 화면창

  •  
  • 3. select partition 2 : 문자를 할당할 파티션을 선택
  •  
  • 4. assign letter=Z : 선택되어있는 파티션에 Z드라이브명 할당

    select partition 2 입력하고 list patition입력후 assign letter=Z 명령어 입력창

  •  
  • 5. 디스크1의 파티션에 드라이브명이 할당된 것을 확인할 수 있습니다.

    디스크1의 파티션에 드라이브명이 x와 z로 할당된 상태창

  • ※ assign letter=X 명령어에서, letter=X 옵션을 안쓰면 차례로 미사용 문자가 할당됩니다. list volume을 입력하면 선택한 디스크의 볼륨(드라이브명)을 확인할 수 있습니다.

6] 파티션 삭제하기

분할된 파티션을 삭제합니다.

  •  
  • 1. 파티션 4,5,6(볼륨 3,4,5)에 각각 X:, Y:, Z: 가 할당된 파티션입니다.

    파티션 4,5,6에 각각 X:, Y:, Z: 할당된 파티션 창

  •  
  • 2. 파티션을 삭제합니다. 볼륨으로 지정하는 경우 드라이브명이 지정되어 있다면, 드라이브명을 쓸 수 있습니다. 볼륨 번호랑 파티션 번호가 다르니 혼동하지 않도록 주의하세요.
  • select volume z 볼륨 z에 포커스를 맞춥니다. (select volume=z 도 같음 “=” 생략 가능)
  • delete partition 파티션을 삭제합니다. 마찬가지로 볼륨 y(파티션 5), 볼륨 3 (볼륨 x, 파티션 4)를 삭제합니다.

    select volume z입력후 delete partition후 select partition y입력후 select partition 5 입력 delete partition입력후 select volume 3입력후 delete partition 입력 확인창

    select partition 3입력후 delete partition에서 delete partition override입력후 확인

  •  
  • ※ 파티션 3번의 확장파티션에 포커스를 주고 삭제하려는데 잘 안될수 있습니다. 이럴 때 위 그림의 입력 내용처럼 delete partition override 라고 override 옵션을 주면 됩니다.(히든 영역 삭제 가능)
  • ※ 브랜드 PC에서 별도 영역으로 구성한 파티션, 즉 [OEM 파티션]을 삭제할 때도 대상 파티션에 포커스를 주고, delete partition override 로 삭제합니다. 삼성 PC에서는 복원영역이 OEM 파티션 영역입니다.

    oem파티션 영역을 표시한 디스크관리 창

7] Diskpart 나가기

diskpart를 종료하는 방법은, exit를 입력합니다.

exit명령어로 나가기 실행

Synology RAID Volume 단일 Volume으로 변경하기

시놀로지는 볼륨 관리를 위해 md라고 불리는 software raid를 사용합니다.
raid를 관리하기 위해 사용하는 명령어가 mdadm 입니다.

보통은, /dev/md0가 OS 파티션, /dev/md1이 swap 파티션, 그리고 사용자가 사용하는 첫번째 볼륨 파티션이 /dev/md2로 생성되는데요..

“cat /proc/mdstat” 명령을 치시면 현재 사용하고 있는 md raid 정보가 출력됩니다.

?? ??2.png

이중 md 구성 별 blocks 수를 대략 비교 해보며 Disk Size 별로 어떤 Volume 인지 확인합니다.

mdadm –grow –raid-devices=1 –force /dev/[md2] <— 분리 하고자 하는 md 번호

상기 명령을 통해 원하는 Volume Raid를 분리 할 수 있습니다.

[Tomcat] 리눅스의 톰캣 로그에서 한글깨지는 문제 해결방법

리눅스의 톰캣 로그에서 한글이 깨져나오네요.

톰캣의 인코딩에 문제가 생겨서 그러겠죠?

[톰캣설치 폴더 > bin] 디렉토리로 가면 catalina.sh 파일이 있습니다.

그 파일을 편집기로 여시구요.

-Djava.io.tmpdir=”$CATALINA_TMPDIR” \
이 부분 찾아서 그 아래에 아래 소스를 모두 추가합니다.

-Djava.io.tmpdir=”$CATALINA_TMPDIR” \
-Dfile.encoding=”utf-8″\

수정한 파일을 저장하고, 톰캣을 재시작하면 아래처럼 로그에 한글이 잘 나옵니다.

Kubernetes Monitoring : HPA (Horizontal Pod Autoscaler)

Overview

쿠버네티스 클러스터에서 hpa를 적용해 시스템 부하상태에 따라 pod을 autoScaling시키는 실습을 진행하겠습니다.

참고 링크 : Kubernetes.io/Horizontal Pod Autoscaler

Prerequisites

먼저 쿠버네티스 클러스터를 생성해주세요.

참고링크 : 호롤리한하루/Install Kubernetes on CentOS/RHEL

본 실습에서 사용한 spec :
OS : CentOS v7.6
Arch : x86

Kubernetes : v1.16.2
Master : 4cpu, ram16G (1개)
Node : 4cpu, ram16G (2개)

Step

그림1

1. Metrics-Server 배포

먼저 top명령어를 입력해봅시다.

$ kubectl top node

Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)

현재는 에러메세지가 뜹니다.
이유는 노드의 system metric들을 수집하는 서비스가 없기 때문입니다.

system metric을 수집하는 Metrics-Server를 배포해주도록 합시다.

$ git clone https://github.com/kubernetes-sigs/metrics-server.git
$ cd metrics-server

쿠버네티스에서 공식으로 서포트하고있는 add-on 컴포넌트인 metrics-server를 클론받고, 배포하기 이전에 yaml파일을 수정해주어야합니다.
클러스터 내에서 사용하는 인증서가 신뢰되지 않은 경우와 호스트 이름을 찾지 못하는 경우를 방지하기 위함입니다

$ vim deploy/kubernetes/metrics-server-deployment.yaml

image
위 그림과 같이 argument들을 수정해줍니다.

args:
  - --kubelet-insecure-tls
  - --kubelet-preferred-address-types=InternalIP
  - --cert-dir=/tmp
  - --secure-port=4443

그리고 나서 metrics-server를 배포하면 :

$ kubectl apply -f deploy/kubernetes/

clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
serviceaccount/metrics-server created
deployment.apps/metrics-server created
service/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created

중간에 metrics.k8s.io라는 API가 생성되어 Api server에 등록된 것을 확인할 수 있습니다.

이제 top명령어를 사용할 수 있게 됩니다.

$ kubectl top nodes

NAME       CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
kube-m     248m         6%     1656Mi          10%
kube-n01   112m         2%     760Mi           4%
kube-n02   112m         2%     724Mi           4%

각 노드의 cpu와 memory사용량을 확인할 수 있습니다.

2. 부하테스트를 위한 이미지 작성

이제 시스템의 부하테스트를 위한 이미지를 작성해보겠습니다.

$ mkdir php
cd php

스크립트 작성 :

$ vim index.php

<?php
  $x = 0.0001;
  for ($i = 0; $i <= 1000000; $i++) {
    $x += sqrt($x);
  }
  echo "OK!";
?>

스크립트를 포함하는 도커 이미지 작성 :

$ vim Dockerfile

FROM php:5-apache
ADD index.php /var/www/html/index.php
RUN chmod a+rx index.php

도커 이미지 빌드 :

$ docker build --tag {docker id : totoli78}/php-apache .

$ docker images |grep php

totoli78/php-apache                    latest              39e1797ad29c        23 seconds ago      355MB

생성한 이미지를 본인의 docker hub에 push해줍니다.

$ docker login
...
Login Succeeded

$ docker push totoli78/php-apache

부하테스트를 위해 쿠버네티스 클러스터에 pod으로 배포해줍니다.

$ vim hpa-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-apache
spec:
  selector:
    matchLabels:
      run: php-apache
  replicas: 1
  template:
    metadata:
      labels:
        run: php-apache
    spec:
      containers:
      - name: php-apache
        image: totoli78/php-apache
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 500m
          requests:
            cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
  name: php-apache
  labels:
    run: php-apache
spec:
  ports:
  - port: 80
  selector:
    run: php-apache

yaml을 작성한 뒤에는 배포!

$ kubectl apply -f hpa-test.yaml

deployment.apps/php-apache created
service/php-apache created

3. HPA 배포

이제 오토스케일러를 생성해주면 됩니다.

$ vim autoscaler.yaml

위에서 만든 부하테스트용 pod인 php-apache의 평균 cpu사용량을 50%로 맞추기 위해 레플리카의 개수를 늘리고 줄입니다. (1개~10개)

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 50
$ kubectl apply -f autoscaler.yaml
horizontalpodautoscaler.autoscaling/php-apache created

hpa커맨드를 통해 현재 hpa에 감지되는 시스템 부하정도와 관리하는 pod의 개수를 확인할 수 있습니다.

$ kubectl get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         10        1          18s

아직은 서버로 어떠한 요청도 하지 않았기 때문에, 현재 cpu소비량은 0%임을 알 수 있습니다. (TARGET은 deployment에 의해 제어되는 pod들의 평균을 뜻합니다.)

부하테스트

부하가 증가함에 따라 오토스케일러가 어떻게 반응하는지 살펴보겠습니다.

창을 하나 더 띄워서 php-apache 서비스에 무한루프 쿼리를 전송합니다.

$ kubectl run -it --rm load-generator --image=busybox /bin/sh

If you don't see a command prompt, try pressing enter.
/ #
/ # while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!...

1~2분 지난 뒤에 hpa커맨드로 부하상태를 살펴보면 TARGET의 수치가 높아진 것을 확인할 수 있습니다.

$ kubectl get hpa

NAME         REFERENCE               TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   248%/50%   1         10        1          9m7s

그리고 deployment 컨트롤러를 확인해보면 pod의 replica수가 5개까지 늘어난 것을 확인할 수 있습니다.

$ kubectl get deploy php-apache

NAME         READY   UP-TO-DATE   AVAILABLE   AGE
php-apache   5/5     5            5           12m

busybox컨테이너를 띄운 터미널에서 Ctrl+C로 부하 발생을 중단시키고, 몇 분 후에 결과를 확인합니다.

$ kubectl get hpa

NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         10        5          11m

cpu의 사용량이 0%까지 떨어졌고, deployment의 pod replica수도 1개로 줄어든 것을 확인할 수 있습니다.

$ kubectl get deploy php-apache

NAME         READY   UP-TO-DATE   AVAILABLE   AGE
php-apache   1/1     1            1           19m

replica autoscaling은 몇 분 정도 소요됩니다. (체감상 3~5분)