블로그 이미지
redkite

카테고리

분류 전체보기 (291)
00.SI프로젝트 산출물 (0)
00.센터 운영 문서 (0)
01.DBMS ============.. (0)
01.오라클 (117)
01.MS-SQL (15)
01.MySQL (30)
01.PostgreSql (0)
01.DB튜닝 (28)
====================.. (0)
02.SERVER ==========.. (0)
02.서버-공통 (11)
02.서버-Linux (58)
02.서버-Unix (12)
02.서버-Windows (2)
====================.. (0)
03.APPLICATION =====.. (11)
====================.. (0)
04.ETC =============.. (0)
04.보안 (5)
====================.. (0)
05.개인자료 (1)
06.캠핑관련 (0)
07.OA관련 (1)
Total
Today
Yesterday

달력

« » 2024.5
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

공지사항

최근에 올라온 글

'02.서버-Linux'에 해당되는 글 58건

  1. 2013.05.08 [리눅스]CentOS virbr0 NAT disable
  2. 2013.04.23 [리눅스]Find perm 옵션
  3. 2013.03.29 [리눅스]멀티 환경변수 case 문 이용
  4. 2013.03.28 [리눅스]RPM Failed dependencies
  5. 2013.03.25 [리눅스]NDD & TCPDUMP
  6. 2013.03.18 [리눅스]SoftWare RAID10
  7. 2013.03.18 [리눅스]LVM with Software RAID
  8. 2013.03.08 [리눅스]패스워드 쉽게 변경하기(실수하지 않게)
  9. 2013.02.18 [리눅스]Handy Tools for Linux admins
  10. 2013.02.07 [트러블슈팅]KERNEL: assertion (!sk->sk_forward_alloc) failed at net/core/stream.c (279) and net/ipv4/af_inet.c (148)
  11. 2013.02.07 [리눅스]Fix the "Bind to port 22 on 0.0.0.0 failed : Address already in use" error
  12. 2013.01.24 [리눅스]for문 스크립트
  13. 2013.01.04 [리눅스]SWAP 파일 추가
  14. 2012.12.19 [리눅스]아파치 2.4.2 버전 컴파일
  15. 2012.12.19 [리눅스]I/O Error 대처법
  16. 2012.12.19 [리눅스]fstab 마운트 설정 관련
  17. 2012.12.19 [리눅스]LVS(Linux Virtual Server)에 대하여
  18. 2012.12.19 [리눅스]아파치 퍼포먼스 튜닝
  19. 2012.12.19 [리눅스]Find 명령어 완정 정복 가이드
  20. 2012.12.19 [리눅스]루트 패스워드 분실 시
  21. 2012.12.19 [리눅스]커널값 변경
  22. 2012.12.19 [리눅스]VIP 셋팅 방법
  23. 2012.12.19 [리눅스]RawDevice 설정
  24. 2012.12.19 [리눅스]fstab 오류 발생 처리
  25. 2012.12.19 [리눅스]패스워드 정책 설정
  26. 2012.12.19 [리눅스]DD 가상파일 생성
  27. 2012.12.19 [리눅스]메일 관리
  28. 2012.12.19 [리눅스]lsyncd – 실시간 파일 동기화
  29. 2012.12.19 [리눅스]패스워드 만료일자 변경
  30. 2012.12.19 [리눅스]부트영역 복구하기

virbr0 NAT 인터페이스 disable 시키기

왜 disable 시킬까?

 

by Vivek Gite · 0 comments

This entry is part 9 of 12 in the series Redhat KVM Virtulization

 

virtual network (virbr0)는 guest들이 네트웍 서비스에 접근하는 것을 허락하기위해서  Network address translation (NAT) 를 위해 사용된다. 하지만 NAT는 늦고 데스크탑 설치를 위해서 권장된다. 이 Network address translation (NAT)를 disable시키기 위해서는 아래와 같이 설정한다.

현재 설정상태 보기

아래와 같이 명령한다:

#ifconfig

 

결과 예제:

virbr0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0 inet6 addr: fe80::200:ff:fe00:0/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:39 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:7921 (7.7 KiB)

 

또는 아래의 명령을 이용해라:

 

# virsh net-list

 

결과 예제:

Name State Autostart ----------------------------------------- default active yes

 

 

virbr0를 disable 시키는 방법:

# ifconfig

# virsh net-destroy default
# virsh net-undefine default
# service libvirtd restart

'02.서버-Linux' 카테고리의 다른 글

[리눅스]Find perm 옵션  (0) 2013.04.23
[리눅스]멀티 환경변수 case 문 이용  (0) 2013.03.29
[리눅스]RPM Failed dependencies  (0) 2013.03.28
[리눅스]NDD & TCPDUMP  (0) 2013.03.25
[리눅스]SoftWare RAID10  (0) 2013.03.18
Posted by redkite
, |

find 의 -perm 옵션은 보통 3가지 mode 를 사용합니다.

  1. -perm mode
  2. -perm -mode
  3. -perm /mode

mode 는 정확하게 mode 가 매치되는 것만

-mode 는 mode 를 포함하고, 추가적인 퍼미션이 있는 것만

/mode 는 mode 에서 한개 bit라도 매치되는 것이 있으면

아래의 예들을 실행해 보시면 이해에 도움이 되실 겁니다.

하나의 임시 디렉토리 속에 아래 명령으로 모든 가능한 퍼미션을 만들고 테스트 해보세요.

for i in $(seq 0 7); do for j in $(seq 0 7); do for k in $(seq 0 7); do  touch ${i}${j}${k}; chmod ${i}${j}${k} ${i}${j}${k}; done; done; done

아래는 서로 결과가 같고, 퍼미션이 0700인 것만 찾습니다.

find . -perm u+rwx

find . -perm u=rwx

find . -perm 0700

find . -perm 700

아래는 서로 결과가 같고, 퍼미션이 0020인 것만 찾습니다.

find . -perm g+w

find . -perm g=w

find . -perm 0020

find . -perm 020

find . -perm 20

아래는 서로 결과가 같고, 퍼미션이 0500 보다 더 많이 허용된 것을 찾습니다.

find . -perm -u+rx

find . -perm -u=rx

find . -perm -0500

find . -perm -500

아래는 서로 결과가 같고, 퍼미션 0771 의 각 권한(rwxrwxrwx) 중 한 개 이상의 권한이 같은 것을 찾습니다.

find . -perm /u+rwx,g+rwx,o+x

find . -perm /u=rwx,g=rwx,o=x

find . -perm /u=rwx,g=rwx,o+x

find . -perm /0771

find . -perm /771

아래와 같이 !을 붙일 때 찾을 수 있는 퍼미션의 예상은

find . ! -perm /u+rwx,g+rwx,o+x -ls

-------rw-

--------w-

----------

-------r--

입니다.

참조하세요 ^^

추가질문에 대한 답변

-perm -2 -o -perm -20

-o 는 or 의 의미입니다.

-perm -2 또는 -perm -20 입니다.

other 가 writable 이상이거나 또는 group 이 writable 이상인 것을 의미합니다.

즉, other 또는 group 에 실행권한이 있는 파일을 의미합니다.

같은 의미지만 반대로 이야기 하면, 실행권한이 user 에게만 있거나 아예 없는 파일을 제외한 파일을 의미합니다.

만약,

find ../ ! -user mylin \( -perm 2 -o -perm -20 \) -exec {} \; 이라면

상위 디렉토리의 하위로 소유자가 user가 아니고 other나 group 에 실행권한이 있는 파일을 찾아서 실행한다

는 의미가 됩니다.

 

'02.서버-Linux' 카테고리의 다른 글

[리눅스]CentOS virbr0 NAT disable  (0) 2013.05.08
[리눅스]멀티 환경변수 case 문 이용  (0) 2013.03.29
[리눅스]RPM Failed dependencies  (0) 2013.03.28
[리눅스]NDD & TCPDUMP  (0) 2013.03.25
[리눅스]SoftWare RAID10  (0) 2013.03.18
Posted by redkite
, |

# .bash_profile


# Get the aliases and functions

if [ -f ~/.bashrc ]; then

. ~/.bashrc

fi


# User specific environment and startup programs


PATH=$PATH:$HOME/bin


export PATH

unset USERNAME


# User specific environment and startup programs

export ORACLE_BASE=/oracle/app/oracle

export ORACLE_HOME=$ORACLE_BASE/product/1020/db_1

export ORA_CRS_HOME=$ORACLE_BASE/product/1020/crs_1

export ORACLE_PATH=$ORACLE_BASE/common/oracle/sq1:.:$ORACLE_HOME/rdbms/admin


# Each RAC node must have a unique ORACLE_SID. (i.e. orcl1, orcl2, ...)

#export ORACLE_SID=OTPDB


export PATH=.:${PATH}:$HOME/bin:$ORACLE_HOME/bin:$ORA_CRS_HOME/bin

export PATH=${PATH}:/usr/bin:/bin:/usr/bin/X11:/usr/local/bin

export PATH=${PATH}:$ORACLE_BASE/common/oracle/bin

export ORACLE_TERM=xterm

export TNS_ADMIN=$ORACLE_HOME/network/admin

export ORA_NLS10=$ORACLE_HOME/nls/data

export LD_LIBRARY_PATH=$ORACLE_HOME/lib

export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$ORACLE_HOME/oracm/lib

export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/lib/usr/lib:/usr/local/lib

export CLASSPATH=$ORACLE_HOME/JRE

export CLASSPATH=${CLASSPATH}:$ORACLE_HOME/jlib

export CLASSPATH=${CLASSPATH}:$ORACLE_HOME/rdbms/jlib

export CLASSPATH=${CLASSPATH}:$ORACLE_HOME/network/jlib

export THREADS_FLAG=native

export TEMP=/tmp

export TMPDIR=/tmp

export DISPLAY=172.16.2.235:0.0

export ORACLE_OWNER=oracle

#export NLS_LANG=AMERICAN_AMERICA.KO16KSC5601

#export NLS_LANG=AMERICAN_AMERICA.US7ASCII

#export NLS_LANG=KOREAN_KOREA.KO16KSC5601

#export LANG=C


# prompt

PS1='[${ORACLE_SID}]'`hostname`':$PWD> '

# alias set

alias dba='sqlplus "/as sysdba"'

alias crs='/oracle/app/oracle/product/crs/bin/crs_stat -t'

umask 022

set -o vi

stty erase 

export EDITOR=vi





#ORACLE_SID


echo "Choose ORACLE_SID (ORACLE Database Name)"


echo


echo "1) TEST OTPDB"


echo "2) TEST RADB"


echo


echo "[1번이나 2번을 선택해주세요]"


 


read insNumber


case ${insNumber} in


     1)


       export ORACLE_SID=OTPDB

       export NLS_LANG=AMERICAN_AMERICA.US7ASCII


       ;;


     2)


       export ORACLE_SID=TESTRA

       export NLS_LANG=AMERICAN_AMERICA.KO16KSC5601


       ;;


     *)


       echo "Not Choosed ORACLE_SID"


       ;;


esac

'02.서버-Linux' 카테고리의 다른 글

[리눅스]CentOS virbr0 NAT disable  (0) 2013.05.08
[리눅스]Find perm 옵션  (0) 2013.04.23
[리눅스]RPM Failed dependencies  (0) 2013.03.28
[리눅스]NDD & TCPDUMP  (0) 2013.03.25
[리눅스]SoftWare RAID10  (0) 2013.03.18
Posted by redkite
, |

[root@dev-ra-dbms ~]# rpm -Uvh --nodeps unixODBC-devel-2.2.11-10.el5.i386.rpm


 

경고: unixODBC-devel-2.2.11-10.el5.i386.rpm: Header V3 DSA signature: NOKEY, key ID 37017186

준비 중...                  ########################################### [100%]

   1:unixODBC-devel         ########################################### [100%]

'02.서버-Linux' 카테고리의 다른 글

[리눅스]Find perm 옵션  (0) 2013.04.23
[리눅스]멀티 환경변수 case 문 이용  (0) 2013.03.29
[리눅스]NDD & TCPDUMP  (0) 2013.03.25
[리눅스]SoftWare RAID10  (0) 2013.03.18
[리눅스]LVM with Software RAID  (0) 2013.03.18
Posted by redkite
, |

Auto Negotiation OFF시 스피드와 Duplex 모드를 동시에 같이 셋팅 해 주어야 함.

Auto Negotitation Diable 시키는 방법 (일시적)

# ethtool -s eth0 autoneg off

스피드와 duplex를 같이 셋팅하지 않고 위와 같이 명령 내리면, 드라이버가 자동으로 다시 Auto Negotiation을 Enable 시켜 버림.

Auto Negotitation Diable 시키는 방법 (NIC을 죽었다 살리면 다시 auto로 바뀜)

# ethtool -s ethx autoneg off speed 1000 duplex full

ethx에서 x는 이더넷 디바이스 숫자를 의미함. 1Gbps 스피드에 Duplex Mode가 Full-Duplex로 맞춰 주는 것을 의미

Auto Negotitation Diable 시키는 방법 (NIC을 죽었다 살려도 고정으로 하게 하는 방법)

# vi /etc/sysconfig/network-scripts/ifcfg-ethx
ETHTOOL_OPTS="speed 100 duplex full autoneg off"

ifcfg-ethx에서 x는 이더넷 디바이스 숫자를 의미함. ifcfg-ethx를 vi 에디터를 통해 열고, ETHTOOL_OPTS... 이하 문구를 넣어 주면 NIC을 죽였다 살렸을 때도 고정 시킬 수 있음.

몇몇 카드는 ethtool로 동작 하지 않을 때가 있는데, 이럴 때는 mii-tool 유틸리티를 이용한다.

# ethtool eth0 => eth0 상태 보기
Settings for eth0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full

Advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 1
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: puag
Wake-on: g
Link detected: yes


# mii-tool -v eth0 => eth0 상태 보기
eth1: no autonegotiation, 10baseT-HD, link ok

# mii-tool -F 100BaseTx-FD eth0 => eth0 상태 변경(100BaseTx-HD 등...)
불행하게도 위 옵션도 부팅 되면, 모두 풀려 버려, auto negotiation으로 변경 되어 버린다. 부팅 될 때도 수동으로 동작하게 하려면, /etc/rc.local 파일에 
ethtool 문구나 mii-tool 문구를 넣어 준다.

#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

ethtool -s eth0 speed 100 duplex full autoneg off
mii-tool -F 100baseTx-FD eth1
touch /var/lock/subsys/local


==============================================================================================
Linux

1. 연결상태 확인

mii-tool을 옵션없이 실행하면 랜카드의 속도, duplex 모드, 연경 상태를 보여주며 
-v 옵션을 추가하면 보다 상새한 MII 상태를 볼 수 있다. 
root 권한으로 실행해야 합니다.

--------------------------------------------------------------------------------------- 
# mii-tool 
eth0: negotiated 100baseTx-FD, link ok ( 100MB, Full Duplex로 autonegotiation됨 ) 
eth1: no link             ( 연결되어 있지 않음 ) 
# mii-tool -v 
eth0: negotiated 100baseTx-FD, link ok 
 product info: Intel 82555 rev 4 
 basic mode:  autonegotiation enabled 
 basic status: autonegotiation complete, link ok 
 capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD 
 advertising: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD flow-control 
 link partner: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD 
eth1: no link 
 product info: Intel 82555 rev 4 
 basic mode:  autonegotiation enabled 
 basic status: no link 
 capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD 
 advertising: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD flow-control 
---------------------------------------------------------------------------------------

-w 옵션을 사용하면 실시간으로 연결 상태를 확인할 수 있다. 
만약 갑자기 no link라고 나온다면 회선에 문제가 생겼거나 연결된 장비간의 회선속도나 
duplex 모드가 맞지 않은 경우이다.

--------------------------------------------------------------------------------------- 
# mii-tool -w 
08:58:00 eth0: negotiated 100baseTx-FD, link ok 
08:58:00 eth1: no link 
21:23:11 eth0: no link (연결이 끊긴 상태에서) 
21:23:15 eth0: negotiated 100baseTx-FD, link ok (다시 연결됨) 
---------------------------------------------------------------------------------------

2. 속도 변경

autonegotiation으로 두 장비간의 연결 속도와 duplex 모드를 자동으로 맞추게되지만 
제대로 되지 않아 충돌(Late Collision)이 많이 발생하는 경우나 원하는 속도로 변경을 
해야할 때 mii-tool은 유용하게 쓰일 수 있다. 다음은 100MB, Full duplex 모드로 변경 
하는 예이다.

--------------------------------------------------------------------------------------- 
# mii-tool -F 100baseTx-FD eth0 
---------------------------------------------------------------------------------------

원래 autonegotiation로 restart하려면 -r 옵션을 사용하면 된다.


Solaris

다음 절차는 네트워크 인터페이스 카드가 자동 협상(autonegotiation)이 설정(ON)되어
있는 상태에서 실행하고 있는 경우 100 MB full duplex 또는  원하는 속도와 모드로
강제 설정하는 방법입니다.

1. 서버에서 확인한 결과, 자동 협상(autonegotiation)이 설정(ON)되어 있다면 100fdx
및 100hdx 옵션 모두가 1(ON)을 여러 번 반환하고 10fdx 및 10hdx도 1을 반환합니다. 
따라서 100fdx 또는 1000fdx 변수를 1(ON)로 설정한 경우 다른 설정값은 여전히 활성화된
상태입니다. /etc/rc2.d/S99.. 스크립트가 수행하는 것처럼 다른 모든 옵션을 0으로 
설정해야 합니다. 예를 들어 hme 카드의 경우 명령행에서 다음과 같은 순서대로 옵션을
설정해야 합니다.

ndd -set /dev/hme instance 0 
ndd -set /dev/hme adv_autoneg_cap 0 
ndd -set /dev/hme adv_100T4_cap 0 
ndd -set /dev/hme adv_100fdx_cap 1 
ndd -set /dev/hme adv_100hdx_cap 0 
ndd -set /dev/hme adv_10fdx_cap 0 
ndd -set /dev/hme adv_10hdx_cap 0

------------------------------------

ifconfig -a로 LAN Card 확인


- NETWORK Parameter 확인. 
==================================== 
ndd -get /dev/eri adv_autoneg_cap 
ndd -get /dev/eri adv_100T4_cap 
ndd -get /dev/eri adv_100fdx_cap 
ndd -get /dev/eri adv_100hdx_cap 
ndd -get /dev/eri adv_10fdx_cap 
ndd -get /dev/eri adv_10hdx_cap 
============================== 
- 수동으로 설정 파일 수정. 
@doc[/etc/rc2.d]#vi S97fdx 
ndd -set /dev/eri adv_autoneg_cap 0 
ndd -set /dev/eri adv_100T4_cap 0 
ndd -set /dev/eri adv_100fdx_cap 1 
ndd -set /dev/eri adv_100hdx_cap 0 
ndd -set /dev/eri adv_10fdx_cap 0 
ndd -set /dev/eri adv_10hdx_cap 0

------------------------------------

2. 스위치 측에서 확실한 값을 반환하는 유일한 옵션은 lp_autoneg_cap입니다. 그 외의
모든 옵션의 대부분은 언제나 0을 반환합니다. 예를 들어 아래 모든 옵션은 0을 반환
합니다.

ndd -set /dev/hme instance 0 ndd /dev/hme lp_100fdx_cap ndd /dev/hme lp_100hdx_cap ndd /dev/hme lp_10fdx_cap ndd /dev/hme lp_10fdx_cap

어느 정도 도움이 되는 유일한 옵션은 다음과 같습니다.

ndd /dev/hme lp_autoneg_cap

3. 그러므로 인터페이스 카드와 스위치를 설정한 후 사용할 수 있는 최상의 옵션은 
다음과 같습니다.

ndd /dev/hme link_speed (100MB의 경우 1, 10MB의 경우 0) ndd /dev/hme link_mode (full duplex의 경우 1, half duplex의 경우 0)

위 옵션은 통신할 때 사용하고 있는 인터페이스 및 스위치의 속도와 모드를 나타냅니다.


적용 대상:    네트워크 - OS/네트워크 구성, AFO Vertical Team Docs/LAN/WAN/Datacomms 
첨부:         (없음)

4. 솔라리스에서 회선이 연결됐는지 확인하는 방법

  while 1
  ? ndd -get /dev/hme link_status
  ? sleep 1
  ? end
5. 패킷 모니터링을 위한 트래픽 덤프 툴 tcpdump
  
  1) eth0 인터페이스로 오고가는 트래픽 정보를 보여줌(-i eth0 옵션없으면 eth0임)
  
  tcpdump
  
  2) 192.128.1.1 host로 오고가는 또는 제외한 트래픽

  tcpdump host 192.128.1.1
  tcpdump src host 192.128.1.1
  tcpdump dst host 192.128.1.1
  tcpdump not host 192.128.1.1

  3) 192.128.1.1과 192.128.1.2 사이를 오고가는 트래픽만

  tcpdump host 192.128.1.1 and 192.128.1.2

  4) ICMP, ARP, UDP 프로토콜만, ICMP 프로토콜 20개만

  tcpdump icmp -i eth0
  tcpdump arp
  tcpdump udp
  tcpdump icmp -c 20

  5) 웹 포트로 오고가는 패킷만

  tcpdump port 80

  6) dhcp 패킷 확인할 때

  # tcpdump -v -s 1500 port 67 or port 68
  tcpdump: listening on eth0
  01:17:16.803166 0.0.0.0.bootpc > 255.255.255.255.bootps: [udp sum ok]
  xid:0x29b28363 vend-rfc1048 DHCP:REQUEST RQ:truefeel
  PR:SM+BR+TZ+DG+DN+NS+HN+YD+YS+NTP [tos 0x10] (ttl 16, id 0, len 328)
  01:17:16.806441 192.168.1.254.bootps > 255.255.255.255.bootpc:

Posted by redkite
, |

fdisk on all device and create Software RAID partition same size (E.g. 500GB). For RAID 10 you need to 4 disks. I'm assuming that server is booting from ssd or ide disk called /dev/sda

Code:

fdisk /dev/sdb
fdisk /dev/sdc
fdisk /dev/sdd
fdisk /dev/sde

At this point you may need to reboot the system so that kernel will update and sync table. Once rebooted type the following command to create the mdadm RAID set using 4 paritions:

Code:

mdadm --create /dev/md0 -v --raid-devices=4  --level=raid10 /dev/sdb1 /dev/sdc1 /dev/sde1 /dev/sde1

Watch raid building process

Code:

watch cat /proc/mdstat

Once completed format and use /dev/md0:

Code:

fdisk /dev/md0

Format as ext3 or ext4

Code:

mkfs.ext3 /dev/md0p1

OR

Code:

mkfs.ext4 /dev/md0p1

Mount it:

Code:

mkdir /data
mount /dev/md0p1 /data
Posted by redkite
, |

What is RAID and LVM

RAID is usually defined as Redundant Array of Inexpensive disks. It is normally used to spread data among several physical hard drives with enough redundancy that should any drive fail the data will still be intact. Once created a RAID array appears to be one device which can be used pretty much like a regular partition. There are several kinds of RAID but I will only refer to the two most common here.

The first is RAID-1 which is also known as mirroring. With RAID-1 it's basically done with two essentially identical drives, each with a complete set of data. The second, the one I will mostly refer to in this guide is RAID-5 which is set up using three or more drives with the data spread in a way that any one drive failing will not result in data loss. The Red Hat website has a great overview of the RAID Levels.

There is one limitation with Linux Software RAID that a /boot partition can only reside on a RAID-1 array.

Linux supports both several hardware RAID devices but also software RAID which allows you to use any IDE or SCSI drives as the physical devices. In all cases I'll refer to software RAID.

LVM stands for Logical Volume Manager and is a way of grouping drives and/or partition in a way where instead of dealing with hard and fast physical partitions the data is managed in a virtual basis where the virtual partitions can be resized. The Red Hat website has a great overview of the Logical Volume Manager.

There is one limitation that a LVM cannot be used for the /boot.


Initial set of a RAID-5 array
I recommend you experiment with setting up and managing RAID and LVM systems before using it on an important filesystem. One way I was able to do it was to take old hard drive and create a bunch of partitions on it (8 or so should be enough) and try combining them into RAID arrays. In my testing I created two RAID-5 arrays each with 3 partitions. You can then manually fail and hot remove the partitions from the array and then add them back to see how the recovery process works. You'll get a warning about the partitions sharing a physical disc but you can ignore that since it's only for experimentation.

In my case I have two systems with RAID arrays, one with two 73G SCSI drives running RAID-1 (mirroring) and my other test system is configured with three 120G IDE drives running RAID-5. In most cases I will refer to my RAID-5 configuration as that will be more typical.

I have an extra IDE controller in my system to allow me to support the use of more than 4 IDE devices which caused a very odd drive assignment. The order doesn't seem to bother the Linux kernel so it doesn't bother me. My basic configuration is as follows:

hda 120G drive
hdb 120G drive
hde 60G boot drive not on RAID array
hdf 120G drive
hdg CD-ROM drive
The first step is to create the physical partitions on each drive that will be part of the RAID array. In my case I want to use each 120G drive in the array in it's entirety. All the drives are partitioned identically so for example, this is how hda is partitioned:
Disk /dev/hda: 120.0 GB, 120034123776 bytes
16 heads, 63 sectors/track, 232581 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1      232581   117220792+  fd  Linux raid autodetect
So now with all three drives with a partitioned with id fd Linux raid autodetect you can go ahead and combine the partitions into a RAID array:
# /sbin/mdadm --create --verbose /dev/md0 --level=5 --raid-devices=3 \
	/dev/hdb1 /dev/hda1 /dev/hdf1
Wow, that was easy. That created a special device /dev/md0 which can be used instead of a physical partition. You can check on the status of that RAID array with the mdadm command:
# /sbin/mdadm --detail /dev/md0
        Version : 00.90.01
  Creation Time : Wed May 11 20:00:18 2005
     Raid Level : raid5
     Array Size : 234436352 (223.58 GiB 240.06 GB)
    Device Size : 117218176 (111.79 GiB 120.03 GB)
   Raid Devices : 3
  Total Devices : 3
Preferred Minor : 0
    Persistence : Superblock is persistent

    Update Time : Fri Jun 10 04:13:11 2005
          State : clean
 Active Devices : 3
Working Devices : 3
 Failed Devices : 0
  Spare Devices : 0

         Layout : left-symmetric
     Chunk Size : 64K

           UUID : 36161bdd:a9018a79:60e0757a:e27bb7ca
         Events : 0.10670

    Number   Major   Minor   RaidDevice State
       0       3        1        0      active sync   /dev/hda1
       1       3       65        1      active sync   /dev/hdb1
       2      33       65        2      active sync   /dev/hdf1
The important lines to see are the State line which should say clean otherwise there might be a problem. At the bottom you should make sure that the State column always says active sync which says each device is actively in the array. You could potentially have a spare device that's on-hand should any drive should fail. If you have a spare you'll see it listed as such here.

One thing you'll see above if you're paying attention is the fact that the size of the array is 240G but I have three 120G drives as part of the array. That's because the extra space is used as extra parity data that is needed to survive the failure of one of the drives.


Initial set of LVM on top of RAID
Now that we have /dev/md0 device you can create a Logical Volume on top of it. Why would you want to do that? If I were to build an ext3 filesystem on top of the RAID device and someday wanted to increase it's capacity I wouldn't be able to do that without backing up the data, building a new RAID array and restoring my data. Using LVM allows me to expand (or contract) the size of the filesystem without disturbing the existing data.

Anyway, here are the steps to then add this RAID array to the LVM system. The first command pvcreate will "initialize a disk or partition for use by LVM". The second command vgcreate will then create the Volume Group, in my case I called it lvm-raid:

# pvcreate /dev/md0
# vgcreate lvm-raid /dev/md0
The default value for the physical extent size can be too low for a large RAID array. In those cases you'll need to specify the -s option with a larger than default physical extent size. The default is only 4MB as of the version in Fedora Core 5. The maximum number of physical extents is approximately 65k so take your maximum volume size and divide it by 65k then round it to the next nice round number. For example, to successfully create a 550G RAID let's figure that's approximately 550,000 megabytes and divide by 65,000 which gives you roughly 8.46. Round it up to the next nice round number and use 16M (for 16 megabytes) as the physical extent size and you'll be fine:
# vgcreate -s 16M <volume group name>
Ok, you've created a blank receptacle but now you have to tell how many Physical Extents from the physical device (/dev/md0 in this case) will be allocated to this Volume Group. In my case I wanted all the data from /dev/md0 to be allocated to this Volume Group. If later I wanted to add additional space I would create a new RAID array and add that physical device to this Volume Group.

To find out how many PEs are available to me use the vgdisplay command to find out how many are available and now I can create a Logical Volume using all (or some) of the space in the Volume Group. In my case I call the Logical Volume lvm0.

# vgdisplay lvm-raid
	.
	.
   Free  PE / Size       57235 / 223.57 GB
# lvcreate -l 57235 lvm-raid -n lvm0
In the end you will have a device you can use very much like a plain 'ol partition called /dev/lvm-raid/lvm0. You can now check on the status of the Logical Volume with the lvdisplay command. The device can then be used to to create a filesystem on.
# lvdisplay /dev/lvm-raid/lvm0 
  --- Logical volume ---
  LV Name                /dev/lvm-raid/lvm0
  VG Name                lvm-raid
  LV UUID                FFX673-dGlX-tsEL-6UXl-1hLs-6b3Y-rkO9O2
  LV Write Access        read/write
  LV Status              available
  # open                 1
  LV Size                223.57 GB
  Current LE             57235
  Segments               1
  Allocation             inherit
  Read ahead sectors     0
  Block device           253:2
# mkfs.ext3 /dev/lvm-raid/lvm0
	.
	.
# mount /dev/lvm-raid/lvm0 /mnt
# df -h /mnt
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/lvm--raid-lvm0
                       224G   93M  224G   1% /mnt

Handling a Drive Failure
As everything eventually does break (some sooner than others) a drive in the array will fail. It is a very good idea to run smartd on all drives in your array (and probably ALL drives period) to be notified of a failure or a pending failure as soon as possible. You can also manually fail a partition, meaning to take it out of the RAID array, with the following command:
# /sbin/mdadm /dev/md0 -f /dev/hdb1
mdadm: set /dev/hdb1 faulty in /dev/md0

Once the system has determined a drive has failed or is otherwise missing (you can shut down and pull out a drive and reboot to similate a drive failure or use the command to manually fail a drive above it will show something like this in mdadm:

# /sbin/mdadm --detail /dev/md0
     Update Time : Wed Jun 15 11:30:59 2005
           State : clean, degraded
  Active Devices : 2
 Working Devices : 2
  Failed Devices : 1
   Spare Devices : 0
	.
	.
     Number   Major   Minor   RaidDevice State
        0       3        1        0      active sync   /dev/hda1
        1       0        0        -      removed
        2      33       65        2      active sync   /dev/hdf1
You'll notice in this case I had /dev/hdb fail. I replaced it with a new drive with the same capacity and was able to add it back to the array. The first step is to partition the new drive just like when first creating the array. Then you can simply add the partition back to the array and watch the status as the data is rebuilt onto the newly replace drive.
# /sbin/mdadm /dev/md0 -a /dev/hdb1
# /sbin/mdadm --detail /dev/md0
     Update Time : Wed Jun 15 12:11:23 2005
           State : clean, degraded, recovering
  Active Devices : 2
 Working Devices : 3
  Failed Devices : 0
   Spare Devices : 1

          Layout : left-symmetric
      Chunk Size : 64K

  Rebuild Status : 2% complete
	.
	.
During the rebuild process the system performance may be somewhat impacted but the data should remain in-tact.
Posted by redkite
, |

리눅스에서 패스워드를 변경할 때 일반적으로 passwd 명령어를 입력한 후 새로운 패스워드를 두번 입력하는 방식을 사용하실 텐데요


자동화 스크립트 안에서는 이런 식의 대화형 쉘이 등장하면 골치 아프겠죠? 그래서 존재하는 옵션이 바로 Standard Input 입니다. 단 root 계정에서만 이 옵션을 사용할 수 있습니다.

passwd --stdin 계정

아래는 root 패스워드를 12345!@#$% 로 변경하는 모습입니다.


패스워드를 두번 입력 안해서 덜 귀찮고, 입력하는 패스워드가 눈에 보이기 때문에 실수 안해서 좋습니다. 뭐 보안상 취약하다고 할 수도 있겠지만요...

이제 한 걸음 더 나아가, 위 작업을 한줄로 처리하려면 어떻게 할까요? 바로 echo와 파이프 | 를 이용하는 것입니다.

echo '패스워드' | passwd --stdin 계정

아래는 한줄로 root 패스워드를 12345!@#$% 로 변경하는 모습입니다.


이처럼 echo와 passwd 명령어의 --stdin 옵션을 사용하면 패스워드 변경을 한줄로 처리할 수 있어, 자동화 스크립트에서 유용하게 활용할 수 있습니다. 이상입니다.

Posted by redkite
, |
  • PasteDB.com : Pastebin clone : http://www.pastedb.com
    When working with code, bash scripts, etc.. you'll eventually need to share some with another human. The easiest way to do this is to find a good pastebin type site.
  • StrongerPassword.com : Strong password generator : http://www.strongerpassword.com
    When setting up users, you find yourself gazing around the room trying to think of a good password to hand out. Make it easy by using a website that can generate strong passwords on the fly. Add capital letters, integers, symbols..
  • WhatsIP.net : What is my ip address : http://whatsip.net
    When speaking to someone who is possibly blocked by a firewall, you'll need to know their IP address. This is a nice site that you can send a client to. Easy to remember, short and not overpacked with ads.
  • Check-Pagerank.org : Check Google Pagerank : http://www.check-pagerank.org
    This isn't really a 'Linux admin' tool, but if you're into Linux, you're likely a lot of things.. webmaster included. This site will help you to keep an eye on your website(s) pageranks.
Posted by redkite
, |
 

# dmesg
KERNEL: assertion (!sk->sk_forward_alloc) failed at net/core/stream.c (279)
KERNEL: assertion (!sk->sk_forward_alloc) failed at net/ipv4/af_inet.c (148)
# uname -r
2.6.14.1
http://lkml.org/lkml/2006/2/8/300
e1000? and 2.6.14 related
I had this messages on 2.6.14.2 and now I have it on 2.6.15.3.
For what it's worth I had these messages for a while and they got
fixed 2 or 3 weeks ago from memory in Dave's 2.6.16 net tree or net2.6
tree.
Is it possible for you to download 2.6.16-rc2 or similar and see if it
goes away?
금일 커널 stable 버전은 2.6.23
2.6.17 이상을 쓰면 좋겠군요. 얼마나 크게 문제가 되는지는 모르겠지만 말입니다.
http://www.mail-archive.com/netdev@vger.kernel.org/msg06380.html
http://bugzilla.kernel.org/show_bug.cgi?id=5946
Please retest with 2.6.17-rc1. Davem and Hubert found several errors in e1000
driver. One of them would have caused this error.
This patch is already in 2.6.16 and later
http://www.mail-archive.com/netdev@vger.kernel.org/msg09795.html
E1000 has some TSO bug most likely, try reproducing with
"ethtool -K eth0 tso off", replacing "eth0" with your actual
e1000 interface name(s).
Can someone explain to me the
possible relation of e1000 (and maybe TSO) and sk->sk_forward_alloc?
http://kerneltrap.org/node/397
tcp segmentation offload (or TCP Large Send)
e1000 support for TSO under Linux
os - network - e1000 - tso bug - dmesg - warn? or error? or critical?
http://www.fi.muni.cz/~kas/blog/index.cgi/2005/09/index.html
Surprisingly enough, the tests without TSO were faster than with it enabled.

Posted by redkite
, |

 

Posted on March 30, 2006

The error when starting and restarting sshd :
Mar 30 23:35:11 x sshd[9151]: Server listening on :: port 22.
Mar 30 23:35:11 x sshd[9151]: error: Bind to port 22 on 0.0.0.0 failed: Address already in use.
Mar 30 23:38:07 x sshd[9151]: Received signal 15; terminating.
Mar 30 23:38:07 x sshd[1977]: Server listening on :: port 22.
Mar 30 23:38:07 x sshd[1977]: error: Bind to port 22 on 0.0.0.0 failed: Address already in use.

A successful connection made to the server despite the issue :
Mar 30 23:40:46 x sshd[2421]: Accepted publickey for root from ::ffff:xxx.xxx.xxx.xxx port 13586 ssh2

The fix : disable IPv6 :
echo "alias net-pf-10 off" >> /etc/modprobe.conf
restart the machine

Restarting the machine with IPv6 disabled :
Mar 30 23:47:57 x sshd[1957]: Server listening on 0.0.0.0 port 22.
Mar 30 23:48:46 x sshd[2470]: Accepted publickey for root from xxx.xxx.xxx.xxx port 13600 ssh2

Posted by redkite
, |
#!/bin/bash

list=$(cat /root/target.txt | xargs ls -d |awk '{print $1}')
copy=$(cat /root/target.txt | awk '{print $1}')
bkdir=/root/test2

for et in ${list}
do
cp -r $et $bkdir
done

#!/bin/bash


list=$(ls /root/filemv/1/ | awk '{print $1}')


for fhs in ${list}

do

mv /root/filemv/1/$fhs /root/filemv/2/

done

 

====================================================

 

#!/bin/bash


list=$(cat /usr/filelist.txt)


for fhs in ${list}

do

sort /usr/$fhs |uniq > /usr/$fhs.sql

done

 

 

====================================================

 

 


#!/bin/bash


count=$1

seq=1

count=$((count + 1))


while [ $count -gt $seq ]

do

        touch ./1/$seq

        seq=$((seq + 1))

done



1. 반복 명령

 1) for 명령

  - for 반복문을 사용하면, 일련의 파일이나 사용자에 대해 동일한 명령들을 반복하여 
    실행시킬 수 있다

  - for 명령 다음에는 사용자 정의 변수가 나오고, 이어서 키워드 in과 단어를 나열한다

  - 일단 변수에 단어가 대입되면 반복문의 본문에 해당하는 do와 done 사이의 명령들이 실행된다

  - 형식

   for 변수 in 단어목록
   do 
    명령(들)
   done


   $ cat mylist 
   aaa
   bbb
   ccc

   $ cat test
   
   for person in $(cat mylist)
  
    > 명령 치환을 수행하면 파일 mylist의 내용이 단어 목록이 된다

    > 반복문이 처음 수행될 때, 변수 person에는 aaa가 저장되며 다음으로 bbb가 저장된다

   do 
    mail $person < letter
    echo $person was sent a letter.
   done
   echo "The letter has been sent."


 2) 단어 목록에서의 $*와 $@ 변수

  - $*는 하나의 문자열로 취급하고, $@는 단어별로 다른 문자열로 취급한다

   $ cat test

   for name in $*
   do 
    echo Hi $name 
   done

    > $*와 $@는 모든 위치 매개변수들의 값으로 전개된다

   $ ./test aaa bbb ccc
   Hi aaa
   Hi bbb
   Hi ccc


   $ cat test1

   for file
   do 
    if [ -f $file -a ! -x $file ]
    then 
     chmod +x $file
     echo $file now has execute permission
    fi
   done

   $ ./test1 *

    > for 문에 단어 목록을 따로 지정하지 않으면 반복문은 위치 매개변수들을 차례로 처리한다

    > for file in $*와 같은 의미이다


 3) while 명령

  - while 명령은 다음에 따라오는 명령을 평가해서, 종료 상태가 0이면 반복문 본문(do와 done사이)의 
     명령들을 수행시킨다

  - 키워드 done에 다다르면, 프로그램의 제어는 다시 반복문의 시작부분으로 옮겨져서 명령의 
     종료상태를 다시 검사한다

  - while 문에 의해 명령의 종료 상태가 0이 아닌 값으로 바뀔 때까지 반복문이 계속되며, 
     종료 상태가 0이 아닌 값인 경우에는 프로그램의 제어 done 다음으로 옮겨져서 계속 실행된다

  - 형식

   while 명령
   do
    명령(들)
   done

   
   $ cat test

   num=0
   while (( $num < 10 ))

    > let 명령은 수식을 평가하여, 종료 상태가 0이면 조건을 참으로 간주한다

   do 
    echo -n "$num "
    let num+=1
   done
   echo -e "\nAfter loop exits, continue running here"

   $ ./test
   0 1 2 3 4 5 6 7 8 9
   After loop exits, continue running here  


 4) until 명령

  - until 명령은 while 명령과 유사하게 사용된다 
  
  - 하지만 until 다음에 나오는 명령이 실패해야 반복문이 실행된다는 점이 다르다

  - 명령의 종료 상태가 0이 아닌 경우에 반복문이 수행된다

  - 형식

   until 명령
   do
    명령(들)
   done


 5) select 명령과 메뉴

  - 배시 쉘에서는 메뉴 생성을 위해 select라는 새로운 반복문을 제공한다

  - 숫자(일련번호)를 선택 항목으로 사용하는 메뉴를 표준 오류로 출력하면
    프롬프트 PS3을 이용해 사용자의 입력을 기다린다

  - PS3의 기본값은 #?이다 
  
  - 사용자는 메뉴 항목에 나타나는 숫자들 중 하나를 선택하여야한다

  - 사용자가 입력한 값은 배시 쉘의 내장 변수인 REPLY에 저장되며, 저장된 숫자는 선택항목의
    결정에 사용한다 
   
  - 변수 LINES와 COLUMNS는 메뉴 항목을 표시할 때, 출력 모양을 설정하기 위해서 사용한다

  - 메뉴가 표준 오류로 출력될 때는 각 항목 앞에 일련 번호와 닫는 기호())가 붙는다

  - PS3 프롬프트는 메뉴의 맨 아래에 출력된다

  - select는 반복문 명령이므로 break 명령을 사용하여 반복문을 빠져나가거나, exit 명령을 사용하여 
    스크립트 전체를 종료할 수 있다

  - 형식

   select var in wordlist
   do
    명령(들)
   done


   $ cat test 
   PS3="Select a program to execute: " 
   select program in 'ls -F' pwd date
   do 
    $program 
   done

   $ ./test
   1) ls -f 
   2) pwd
   3) date
   select a program to execute: 2
   /home/ellie

    > PS3 변수에 메뉴 목록의 맨 아래에 표시할 프롬프트를 지정한다

    > 프롬프트를 출력한 후에는 사용자의 입력을 기다리며, 이 프롬프트의 기본값은 $#이다

    > select 반복문은 program 이라는 변수와 세개의 단어 목록으로 구성된다

    > 메뉴 항목으로는 어떤 단어든지 사용할 수 있다


 6) 반복문 제어 명령  

  - 특별한 상황이 발생하면, 반복문을 탈출하거나, 반복문의 시작 부분으로 되돌아가야 하는 경우에 사용한다

  - shift 명령

   -> shift 명령은 매개변수 목록의 순서에서, 지정한 횟수만큼 왼쪽으로 이동 시킨다 
   
   -> 매개 변수를 지정하지 않고 shift 명령을 사용한 경우에는 매개변수 목록의 자리를 
      왼쪽으로 한번만 이동시키며 이동되면 영구히 제거 된다

   -> 형식

    shift [n]


    $ cat test

    set aaa bbb ccc ddd
   
    shift

    echo $*

    shift 2

    echo $*

    
    $ ./test

    bbb ccc ddd
  
    ddd


  - break

   -> 내장 명령 break는 반복문을 즉시 탈출하고자 하는 경우에 사용한다 
      (프로그램은 계속진행되며 프로그램을 종료에는 exit 명령을 사용한다)

   -> break 명령이 실행되면 프로그램의 제어는 곧 바로 done 다음으로 이동한다

   -> 여러 반복문이 중첩되어 있을 때는 break를 사용한 반복문에서만 빠져나온다

   -> 중첩 반복문 구조에서 특정 반복문을 빠져 나오고자 할 때는 break 명령에 
      탈출하고자 하는 외부 반복문을 지정하기 위해 정수 매개 변수를 사용할 수 있다

   -> break는 무한 반복문의 탈출에 유용하게 사용할 수 있다

   -> 형식

    break [n]


    $ cat test

    while true; do 
     
     echo Are you ready to move on\?
     read answer

     if [[ "$answer" == [Yy] ]]
     then

      break               ------------------+
                                            |
     else                                   |
                                            |
      .... commands ....                    |
                                            |
     fi                                     |
                                            |
    done                                    |
                                            |
    print "Here we are"   <-----------------+


  - continue 명령

   -> continue 명령은 지정한 조건이 참이면 제어를 반복문의 시작 부분으로 되돌린다

   -> continue 아래의 명령들은 모두 무시하게되며, 중첩된 반복문의 경우, continue 명령은
        제어를 가장 아래쪽의 반복문으로 넘겨준다

   -> 형식

    continue [n]


    $ cat test

    for name in $(cat mail_list)   <-----------+
    do                                         |
     if [[ $name == richard ]] ; then          |
      continue                     ------------+
     else
      mail $name < memo
     fi
    done


  - 중첩 반복문의 제어

   -> 중첩 반복문을 사용하는 경우, break나 continue 명령들에 정수 매개변수를 주면 반복문들 
      사이의 이동이 가능하다


    $ cat test

    for month in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec <-------+
                                                                         |
    do                                                                   |
                                                                         |
     for week in 1 2 3 4         <----------------------------------+    |
                                                                    |    |
     do                                                             |    |
                                                                    |    |
      echo -n "Processing the month of $month. OK? "                |    |
                                                                    |    |
      read ans                                                      |    |
                                                                    |    |
      if [ "$ans" = n -o -z "$ans" ]                                |    |
                                                                    |    |
      then                                                          |    |
                                                                    |    |
       continue 2                       ----------------------------|----+ 
                                                                    |
      else                                                          |
                                                                    |
       echo -n "Process week $week of $month? "                     |
                                                                    |
       read ans                                                     |
       if [ "$ans" = n -o -z "$ans" ]                               |
                                                                    |
       then                                                         |
                                                                    |
       continue                        -----------------------------+

       else

       echo "Now processing week $week of $month. "

       sleep 1

       echo "Done processing..."

       fi

      fi
   
     done

    done


  - I/O 리다이렉션과 자식 쉘

   -> 파이프(pipe)나 리다이렉션을 이용하면 파일에서 반복문으로 입력을 전환할 수 있다

   -> 같은 방법으로 출력 역시 반복문에서 파일로 지정할 수 있다

   -> 입출력(I/O) 리다이렉션이나 파이프를 처리하기 위해서는 자식 쉘을 실행시켜야 한다

   -> 반복문 내에서 정의한 변수들은 스크립트의 나머지 부분을 참조할 수 없다

   -> 반복문의 출력을 유닉스/리눅스 명령으로 파이프하기

       > 출력은 파이프를 이용하여 다른 명령의 입력으로 사용될수 있으며, 리다이렉션을 이용해 
          파일로 보낼 수도 있다

    $ cat test

    for i in 7 9 2 3 4 5 
    do 
     echo $i
    done | sort -n

     >> 결과는 sort -n에게 넘겨져 정렬된다


  - 백그라운드에서 반복문 사용

   $ cat test

   for person in aaa bbb ccc ddd

   do 
   
    mail $person < memo

   done &

    > 키워드 done 다음의 &는 반복문을 백그라운드에서 처리하도록 한다

    > 반복문이 실행되는 동안에도 프로그램은 계속 진행된다


  - IFS 와 반복문

   -> 쉘의 내부 필드 구분자(IFS)는 스페이스, 탭, 및 개행문자로 설정되어 있다

   -> IFS는 단어(token)의 구분에 사용된다


2. 함수

 - 함수는 명령이나 명령 집합에 대한 이름으로 효율성을 높이거나, 프로그램의 모듈화를 위해 사용한다

 - 함수는 현재 쉘 내에서 실행되며 자식 프로세스를 생성하지 않고 함수를 실행 시킨다

 - 함수는 다른 파일에 저장하여 두었다가 필요할 때 스크립트에서 호출하여 사용할 수 있다

  1. 쉘에서는 사용자의 입력이 내장 명령인지, 함수인지, 아니면 디스크에서 찾아야하는 실행 
     프로그램(혹은 스크립트)인지 판단하는 과정을 거쳐 별명인지를 우선 판단하고, 다음으로 
     함수인지 검사한 다음, 내장 명령인지 확인한다. 마지막으로 실행 프로그램인지 확인한다

  2. 함수는 사용하기 전에 정의해야 한다

  3. 함수는 현재 환경 하에서 실행되며 호출한 스크립트와 변수를 공유할 뿐만 아니라, 매개변수 역시 
     위치 매개변수로 지정하여 함수에 전달할 수 있다. local 함수를 사용하여 지역변수를 함수 내에서 
     생성하여 사용할 수 있다

  4. 만약 함수 안에서 exit 명령을 실행하면 스크립트 자체가 종료된다. 함수가 종료한 후, 복귀 지점은 
     스크립트에서 함수를 호출한 곳이 된다

  5. 함수 내에서 사용한 return 문은 가장 최근에 실행된 명령의 종료 상태값이나, 지정한 매개 변수값을 
     반환한다

  6. 내장 명령 export -f 를 사용하면 함수를 자식 쉘에 익스포트 할 수 있다

  7. declare -f 명령을 사용해서 함수와 그 정의를 출력할 수 있다 
     declare -F 명령을 사용하면 함수의 이름만 출력한다

  8. 트랩(trap)은 변수처럼 함수 간에도 전역이며 함수에서 정의한 경우에도 호출한 스크립트와 공유한다

  9. 함수가 다른 파일에 저장되어 있다면 마침표(. 혹은 source) 명령을 사용하여 현재 스크립트에
     들일 수 있다

  10. 함수는 자신을 호출할 수 있으며 재귀 호출의 횟수에는 제한이 없다

 - 형식

  function 함수이름 { 명령(들) ; 명령(들); }


 - 함수 설정 해제

  -> unset 명령을 사용하면 함수를 메모리에서 제거할 수 있다

  -> 형식

   unset -f function_name


 - 함수의 익스포트(export)

  -> 함수를 자식 쉘들에게 익스포트할 수 있다

  -> 형식

   export -f function_name


 - 함수 매개변수와 반환값

  -> 매개변수

   => 매개변수의 전달은 위치 매개변수를 사용하여 함수로 넘겨줄 수 있다

   => 함수에서 사용하는 위치 매개변수는 통용범위(scope)가 함수 내로 한정된다

   => 함수의 매개변수는 함수 밖에서 사용 중인 다른 위치 매개변수에게는 아무런 영향을 미치지 않는다


  -> 내장 명령 local

   => 내장 명령 local을 사용하면 현재 함수에게만 유효한 지역 변수를 생성시킬 수 있다


  -> return 내장 명령

   => return 명령은 함수를 종료한 후, 제어를 함수를 호출한 곳으로 되돌려준다

   => return 명령에 아무런 매개변수도 지정하지 않은 경우, 함수의 반환값은 스크립트 안에서
       최근에 사용된 명령의 종료 상태가 된다

   => 유닉스 명령의 출력을 가져올 때와 동일하게 함수 전체를 괄호 안에 넣고 괄호 앞에 달러기호($)를
       사용하면 출력을 특정 변수에 저장할 수 있다


 - 함수와 source(dot) 명령

  -> 저장함수

   => 함수를 종종 .profile에 정의하여 사용자가 로그인함과 동시에 정의되도록 한다

   => 함수는 익스포트(export)할 수 있을 뿐만 아니라, 다른 파일에 저장할 수도 있다.

   => 저장해둔 함수가 필요한 경우에는 마침표(. 혹은 source) 명령과 파일명을 입력하면,
       함수의 정의가 활성화 된다

   
   $ cat test

   function go () { 
    cd $HOME/bin/prog
    PS1=''pwd' > '
    ls
   }

   function greetings () { echo "Hi $1! Welcome to my world." ; }

   
   $ source test

    > 마침표(. 혹은 source) 명령으로 test  파일의 내용을 쉘 메모리로 
      불러와 두 함수가 현재 쉘에서 정의된다

   $ greetings aaa
   Hi aaa! Welcome to my world.

Posted by redkite
, |

파일/장치를 스왑으로 설정하는 명령어이다.

사용법 : swapon [옵션] [장치명]

-a : /etc/fstab 에 sw'' 스왑 장치로 표기된 모든 장치를 스왑으로 설정한다.

-p 우선권 : swapon에서 사용될 우선권을 설정한다. 우선권은 0 ~ 32767 사이의 값이다. pri=value 이라는 항목을 /etc/fstab 의 옵션 필드에 써 넣으면 swapon -a할 때 이용된다.
swapon은 파일 혹은 apth로 분류되는 블록 디바이스로의 스왑 영역을 설정한다.

512M의 스왑파일 만들기

# dd if=/dev/zero of=/swap bs=1024 count=524288

# mkswap /swap 524288

# sync

# swapon /swap

 

free명령으로 작성된 스왑파일을 확인한다.

# free
스왑을 해제하려면 swapoff 명령을 사용하면 된다.

# swapoff /swap

# free

Posted by redkite
, |

## 이벤트 방식으로 올릴경우

./configure --prefix=/usr/local/apache2.4.2 --enable-rewrite --enable-speling --with-mpm=event --enable-cache --enable-deflate --enable-unique-id --enable-file-cache --enable-mem-cache --enable-disk-cache --enable-charset-lite --enable-mods-shared=most --enable-nonportable-atomics --disable-distcache--with-included-apr --with-included-apr-util

./configure --prefix=/usr/local/apache2.4.2 --enable-rewrite --enable-speling --enable-mpms-shared=all --enable-cache --enable-deflate --enable-unique-id --enable-file-cache --enable-mem-cache --enable-disk-cache --enable-charset-lite --enable-mods-shared=most --enable-nonportable-atomics --disable-distcache--with-included-apr --with-included-apr-util

Posted by redkite
, |

0028. [리눅스]I/O error 대처법

일반적으로 리눅스 운영체제를 사용하는 곳 중에서 정기적인 리부팅 및 시스템을 관리를 하지 않는 곳에서는 가끔씩 파일시스템 에러가 발생을 한다.

이러한 파일 시스템 에러는 자칫하면 리눅스 운영체제 자체를 사용 할수 없는 경우가 있으므로 상당히 조심스럽게 접근을 해야 한다. 어떨 경우에는 백업이 되어 있다면 재설치 하는게 더 안정적인 서비스가 될수도 있다.



I/O에서 에러가 나면서 파일 시스템에 문제가 있어 부팅이 안되고 있다, 대부분 이럴 경우 2가지 유형이 있는데 운영체제 파일 시스템이 손상이 가서 나타나는 현상과 또한가지 하드디스크의 베드섹터가 생겼을때에도 나타날수 있는 현상이다.



부팅후에 중간 단계에서 / 파티션의 파일 시스템이 에러가 나면서 FSCK 명령어로 수동으로 체크하라는 메세지를 보여 주고 있다.

이럴 경우 root 패스워드를 입력을 하고 fsck 명령어를 통하여 파일 시스템을 체크를 한다. 일종의 디스크 조각모음 같은 형태라고 보면 되겠다. i-node 값들이 손상되었을때 복구해 주는 명령이기도 하다.,

기본적으로는 윈도우는 FAT32 나 NTFS 파일 시스템을 사용하지만 리눅스는 EXT2, EXT3 등의 파일 시스템을 사용을 한다.
지금 대부분 리눅스 배포판 운영체제는 EXT3 파일 시스템을 채택하고 있다.



이렇듯 FSCK 명령어로 파일 시스템을 체크하고 있다. 이럴경우 대부분 복구가 되어 부팅이 가능하지만 최악의 경우 부팅이 안되는 경우도 있다.

이럴때에는 복구설치를 하던지 재설치를 하는것이 오히려 더 빠른 장애처리가 될 것이다.


[정기적인 리부팅은 시스템 리소스 초기화 기능]

이러한 파일시스템 체크 및 시스템 리소스등을 체크 하려면 정기적인 리부팅을 한번씩 해 주는것이 좋다. 그렇게 함으로 인하여 어떠한 에러사항이 있는지 체크도 가능하고 리소스 고갈로 인한 서버가 다운 되는 현상을 막을 수 있다. 그것은 재부팅 되면서 각종 데몬이나 컨넥션등이 초기화가 되기 때문이다..정확하게 말해서는 컨넥션이 끊어지는 것이다

Posted by redkite
, |
  1. 부팅시 hdb 또는 윈도우 파티션 자동 마운트하기
    mount
    하려는 device /dev/hda5 경우

    1. mount
    directory 생성 (/home/win)

    2. /etc/fstab
    다음 항목 추가

    /dev/hda5 /home/win vfat user,rw,noauto,noexec,iocharset=cp949 0 0

    3. mount /dev/hda5

    4. noauto option
    빼면 system booting 시에 마운트됨

    ====================
    user (
    일반사용자 계정으로도 mount 가능; nouser=root 허용)
    rw (
    읽기 쓰기 허용 ; ro=읽기전용)
    noexec (
    실행허용안함; exec=실행허용)
    iocharset=cp949 (
    한글 파일명을 사용하기 위해 지정)
    마지막 0 0 dump fsck 사용 옵션. (dump, fsck 하지 않음)


    /etc/fstab
    등록하는 방법에는 file system, directory, type, option, freq, pass순으로 관리자가 한줄한줄 직접 에디터 상에서 입력하는 방법도 있지만 이는 불편함으로 다음과 같은 방법을 사용할 수도 있다. 일반적으로 시스템 가동중에 mount 명령을 이용하여 마운트를 실행한 현상태의 마운트상태가 재부팅 시에도 유지되기를 바라는 경우가 대부분일 것이다. 다음은 그런 경우를 위한 방법이다.

    # mv /etc/fstab /etc/fstab.old

    # mount -p > /etc/fstab

    # rm /etc/fstab.old

    mount
    명령에 -p 옵션을 주게 되면 현재의 마운트 상황을 /etc/fstab 포맷으로 보여주기 때문에 이를 이용하여 /etc/fstab 만들어주면 된다.

    /dev/dataVG/data1 /data ext3 defaults,noatime 1 2











    2. fstab
    일반

    fstab
    필드 구성 | LINUX 2005/05/26 03:51
    http://blog.naver.com/boxcj/140013292351
    /dev/hda1 /root ext3 default 1 2
    파일시스템명시 | 파일위치 | 종류 | 마운트 옵션 | 덤프인자 | 체크시퀸스 번호

    fstab
    6개의 필드로 구성되어 있다.

    1.
    파일시스템 명시 : 블럭장치나 마운트될 파일시스템을 명시한다.
    -
    파일시스템은 디바이스 명을 입력한다.

    2.
    파일위치 : 마운트하는 지점을 명시한다.

    3.
    종류: 파일시스템의 종류를 나타낸다
    - dos
    - ext2
    - ext3
    - nfs
    - swap
    -vfat (
    윈도우 일반..확인요?)
    -


    4.
    마운트옵션: 파일시스템의 마운트 옵션을 나타낸다
    - default :
    모든것
    - noquota :
    쿼터 사용안함
    - nosuid : SUID
    접근 불가능
    - quota :
    쿼터 사용
    - ro :
    읽기 가능
    - rw :
    읽기 쓰기 가능
    - suid: SUID
    접근 가능

    5.
    덤프인자 : 파일시스템이 덤프될 필요가 있는지를 설정한다.
    - 0 :
    덤프될 필요없음
    - 1 :
    덤프 필요합

    6.
    체크시퀸스 번호 : fsck 의해 수행되는 무결성 검사를 위한 파일시스템 우선순위를 결정한다.
    - 0 :
    체크 안함
    - 1 :
    우선적으로 체크
    - 2 : 1
    번이 끝난 체크
    --------------------------------------------------------------------
    LABEL=/ / ext3 defaults 1 1
    none /dev/pts devpts gid=5,mode=620 0 0
    LABEL=/home /home ext3 defaults 1 2
    none /proc proc defaults 0 0
    none /dev/shm tmpfs defaults 0 0
    /dev/hda2 swap swap defaults 0 0
    /dev/cdrom /mnt/cdrom udf,iso9660 iocharset=cp949,noauto,user,exec,kudzu,ro 0 0
    --------------------------------------------------------------------

 

 

/etc/fstab 파일은 리눅스 시스템이 자동으로 마운트하기 위한 정보를 담고 있다.

아래처럼 6가지 정보를 입력하는데,

<file system> <mount point> <type> <options> <dump> <pass>

항목은 또는 스페이스 등의 공백으로 구분한다.

 

1.

file system: 파일시스템이 있는 장치나 파티션. 전에는/dev/sda1 이런 방식을 쓰는데 이제는 UUID 사용하는 것이 기본이다.

UUID 알아내는 방법은 터미널에서 다음의 명령으로 간단히 알아낼 있다.

sudo blkid

다음과 같이 장치/파티션, UUID, 파일시스템 타입을 눈에 있다.

/dev/sda1: UUID="b3450059-0c0a-4342-a3c4-52c1871fd2b4″ TYPE="ext3″

/dev/sda2: UUID="3cf235dd-9306-42ef-83bc-fb7e1d7c612d" TYPE="ext4″

/dev/sdc3: UUID="C2D0FC6AD0FC6657″ LABEL="500Data" TYPE="ntfs"

ls -l /dev/disk/by-uuid

명령도 UUID 있지만 파일 시스템은 안나온다.

여기서는 ntfs타입인 /dev/sdc3 마운트하는 것으로 예를 들겠다.

UUID="C2D0FC6AD0FC6657″ <mount point> <type> <options>

 

<

<dump> <pass>

이제 나머지 5 값도 찾아보자.

 

2.

mount point 대상 파티션을 어디에 마운트할 것인가 경로를 지정하는 것이다. 자기가 하고싶은데에 하면 그만이지만 보통 /mnt /media 사용한다. 여기에서는 /media 이용할 것이다. 다음의 명령어로 /media 폴더로 이동한다.

cd /media

여기에 마운트 디렉토리를 만든다. sdc3파티션은 유틸리티와 드라마 등이 있으니 그냥 Data라는 이름으로 만들겠다. /media 디렉토리에 폴더를 만들기 위해서는 root 권한이 필요하다. 따라서 우분투 사용자라면

sudo mkdir Data

, 이제 mout point /medai/Data 정해졌다.

UUID="C2D0FC6AD0FC6657″ /medai/Data <type> <options> <dump> <pass>

 

3. type

마운트하려는 파티션의 포맷 타입을 지정해준다.

ntfs 경우는 ntfs-3g, fat 경우는 vfat이다. 물론 ext3으로 포맷된 파티션이라면 ext3라고 해주면 된다.

  • auto
  • vfat – used for FAT partitions.
  • ntfs, ntfs-3g – used for ntfs partitions.
  • ext2, ext3, jfs, reiserfs, etc.
  • udf,iso9660 – for CD/DVD.swap.

파일시스템에 맞게 입력해주면 된다.

 

UUID="C2D0FC6AD0FC6657″ /medai/Data ntfs-3g <options> <dump> <pass>

 

4. options

옵션은 파일 시스템과 관련있다. defaults rw, suid, dev, exec, auto, nouser, async 등의 속성을 갖는다.

대표적인 옵션들은 아래에 있고 많은 정보를 원하는 분은 man mount 보시면 된다.

  • sync/async – All I/O to the file system should be done (a)synchronously.
  • auto – The filesystem can be mounted automatically (at bootup, or when mount is passed the -a option). This is really unnecessary as this is the default action of mount -a anyway.
  • noauto – The filesystem will NOT be automatically mounted at startup, or when mount passed -a. You must explicitly mount the filesystem.
  • dev/nodev – Interpret/Do not interpret character or block special devices on the file system.
  • exec / noexec – Permit/Prevent the execution of binaries from the filesystem.
  • suid/nosuid – Permit/Block the operation of suid, and sgid bits.
  • ro – Mount read-only.
  • rw – Mount read-write.
  • user – Permit any user to mount the filesystem. This automatically implies noexec, nosuid,nodev unless overridden.
  • nouser – Only permit root to mount the filesystem. This is also a default setting.
  • defaults – Use default settings. Equivalent to rw, suid, dev, exec, auto, nouser, async.
  • _netdev – this is a network device, mount it after bringing up the network. Only valid with fstype nfs.

나는 rw,nosuid,nodev,allow_other 속성을 주었다.

UUID="C2D0FC6AD0FC6657″ /medai/Data ntfs-3g rw,nosuid,nodev,allow_other <dump> <pass>

5. dump

dump 백업 유틸리티인데 이걸로 백업을 하느냐 여부를 결정한다.

(우분투 9.10에는 dump 설치가 안되어 있더군;;; dump 설치하고 manpage 보니 ext2/3 filesystem backup이라고 나오는데 ext4 ntfs같은 것은 덤프를 못하는 것인가…?)

UUID="C2D0FC6AD0FC6657″ /medai/Data ntfs-3g rw,nosuid,nodev,allow_other 0 <pass>

 

6. pass

pass fsck라는 유틸리티가 파일시스템을 체크하는 순서를 지정하는 것으로

  • 0 안하는 것이고,
  • 1이면 먼저
  • 2 나중에

1 /(root) 사용하고 나머지는 2 사용하는 것이 보통이다. 나는 문서나 유틸리티만 모아두는 파티션은 체크를 안한다. 0으로 해주면 된다.

 

UUID="C2D0FC6AD0FC6657″ /medai/Data ntfs-3g rw,nosuid,nodev,allow_other 0 0

 

드디어 .

이제 /etc/fstab 있는 파일시스템을 모두 마운트해서 사용해보자~

Posted by redkite
, |

0066. LVS에 대하여

Linux Virtual Server 자습서

Horms (Simon Horman) – horms@valinux.co.jp

VA Linux Systems Japan 주식 회사 – www.valinux.co.jp

2003 년 7 월 (2004 년 3 월 개정)

http://www.ultramonkey.org/

요약

Linux Virtual Server (LVS) 프로젝트는 레이어 4 스위칭을 이용하여 Web 서버나 메일 서버와 같은 네트워크 서비스의 부하 분산을 가능하게합니다. 이것은 매우 빠른 속도로 이러한 서비스는 수만에서 수십만의 동시 접속에까지 확장해 서비스를 제공할 수 있습니다. 이 연습의 목적은 LVS의 다양한 기능을 이용하여 인터넷 서비스 부하 분산을하는 방법과 heartbeat 및 keepalived 같은 도구를 사용하여 고가용성을 실현하는 방법을 보여줍니다. 또한 고가 용성 환경에서 활성 연결을 유지하거나 활성 피드백을 활용하여 부하를보다 효과적으로 분산시킬 등 최근 개발 테마가있는 고급 항목도 다룹니다.

시작하기

Linux Virtual Server (LVS) 프로젝트는 Linux 커널 레이어 4 스위칭을 구현합니다. 이것은 TCP와 UDP 세션 부하를 여러 실제 서버에 분산 수 있습니다. 즉, 인터넷 서비스를 하나 이상의 호스트로 확장할 수 있도록합니다. 이것은 전자 메일에서 X Window System까지 대부분의 서비스에서 사용할 수 있지만, World Wide Web에 HTTP 및 HTTPS 트래픽을 이용하는 것이 가장 일반적이라고 생각됩니다.

LVS 자체는 Linux에서 작동하지만, 모두가 사용하는 OS에 관계없이 최종 사용자가 실제 서버에 대한 연결을 균형있게 조정할 수 있습니다. 연결이 TCP 또는 UDP 중 하나를 사용하기만하면 LVS를 사용할 수 있습니다.

LVS는 매우 고성능, 최대 10 만 개의 동시 연결을 처리할 수 있습니다. 포화 100M 비트 ethernet 링크를 저렴한 상용 하드웨어를 사용하여 쉽게 부하 분산시킬 수 있습니다. 또한보다 고성능 상용 하드웨어를 사용하면 포화 1G 비트 이상의 링크를 부하 분산시킬 수 있습니다.

LVS의 기본

이 섹션에서는 LVS의 구조, LVS를 구해서 설치하는 방법, 주요 동작 모드의 설정 방법 등 기본적인 정보를 제공합니다. 이 정보에서 TCP와 UDP 서비스의 부하를 분산하도록 LVS를 설정할 수 있습니다.

용어

Linux Director : Linux와 LVS가 설치된 호스트. 최종 사용자의 패킷을 받아 실제 서버로 전송한다.

최종 사용자 : 연결의 기점이되는 호스트.

실제 서버 : 연결 종점이되는 호스트. Apache 등 어떤 데몬을 실행하고있다.

단일 호스트가 위의 중 여러 역할을 동시에 할 수있다.

가상 IP 주소 (VIP) : Linux Director가 취급하는 서비스에 할당된 IP 주소입니다.

실제 IP 주소 (RIP) : 실제 서버의 IP 주소입니다.

레이어 4 스위칭

그림 1 : LVS NAT

레이어 4 스위치는 들어오는 TCP / IP 연결 및 UDP / IP 데이터 그램을 실제 서버에 다중화하는 방식으로 작동합니다. 패킷은 Linux Director를 대신해서 어떤 실제 서버로 전송 여부를 결정합니다. 이것이 결정되면 동일한 연결의 나머지 패킷이 동일한 실제 서버에 보내집니다. 이렇게 연결의 무결성이 유지됩니다.

패킷 전송

Linux Virtual Server는 NAT (Network Address Translation), IP-IP 캡슐화 (터널링), 직접 라우팅 세 가지 방식으로 패킷을 전송할 수 있습니다.

NAT (Network Address Translation) : 원본 / 대상 포트, 패킷의 주소를 조작하는 방법입니다. 이것이 가장 일반적으로 사용되는 것이 IP 마스 커 레이드입니다. IP 마스 커 레이드는 RFC 1918 [2] 사설 네트워크에서 인터넷에 액세스할 수 있도록하는 데 자주 사용되는 방법입니다. 레이어 4 스위칭에서는 최종 사용자가 패킷을 받으면 대상 포트와 IP 주소가 선택된 실제 서버 것에 다시 작성됩니다. 회신 패킷 Linux Director를 지날 때 매핑이 해제되므로 최종 사용자는 예상대로 소스로부터 응답을받을 수 있습니다.
직접 라우팅 : 최종 사용자의 패킷을 직접 실제 서버로 전송하는 방법입니다. IP 패킷은 변경되지 않기 때문에 실제 서버가 가상 서버의 IP 주소에 대한 트래픽을 허용하도록 설정해야합니다. 이를 위해서는 더미 인터페이스를 사용하거나 가상 서버의 IP 주소로 트래픽을 로컬 포트​​로 리디렉션 패킷 필터링합니다. 실제 서버는 사용자에게 직접 응답을 보낼 수 있습니다. 즉, Linux Director를 리턴 경로에 상주할 수 없습니다.
IP-IP 캡슐화 (터널링) : 해당 IP 주소로 패킷을 동일한 네트워 크나 다른 네트워크에있는 다른 주소로 리디렉션할 수 있도록합니다. 레이어 4 스위치에서는이 동작을 직접 라우팅과 유사하지만 패킷을 전송할 때 그냥 ethernet 프레임을 조작하는 것이 아니라, IP 패킷에 캡슐 화하는 점이 다릅니다. 터널링의 주요 장점은 실제 서버가 다른 네트워크에있어도 상관 없다는 것입니다.
그림 2 : LVS 직접 라우팅

가상 서비스

Linux Director는 가상 서비스는 IP 주소와 포트 및 프로토콜 또는 방화벽 마크 정의됩니다. 가상 서비스에는 옵션 지속성 시간을 연결할 수 있습니다. 이것이 설정되고 제한 시간이 경과하기 전에 동일한 IP 주소에서 연결을 수신하면 연결이 원래 연결과 동일한 실제 서버로 전송됩니다.

IP 주소와 포트 및 프로토콜 : 가상 서버는 다음과 같이 지정합니다.
IP 주소 : 최종 사용자가 서비스에 액세스하는 데 사용하는 IP 주소
포트 : 최종 사용자의 연결 포트
프로토콜 : UDP 또는 TCP
방화벽 마크 : 패킷은 ipchains 또는 iptables를 사용하여 32 비트 부호없는 값으로 표시됩니다. Linux Virtual Server는이 마크를 이용하여 가상 서비스로 발송 전달된 패킷을 나열하고 적절하게 라우팅합니다. 이것은 동일한 실제 서버에서 운영하는 IP 기반 가상 서비스가 대량으로 필요하거나 다른 포트 사이에 지속성을 그룹화할 때 유용합니다. 예를 들어 특정 최종 사용자가 HTTP 및 HTTPS에서 동일한 실제 서버에 전송되도록하고 싶은 경우 등입니다.
예약

가상 서비스는 들어오는 연결을 실제 서버에 할당하는 데 사용되는 스케줄링 알고리즘이 할당됩니다. LVS는 스케줄러가 다른 커널 모듈로 구현되어 있습니다. 따라서 LVS 코드를 변경하지 않고도 새로운 스케줄러를 구현할 수 있습니다.

스케줄링 알고리즘은 용도에 따라 여러 가지가 있습니다. 가장 간단한 것은 라운드 로빈과 최소 연결입니다. 라운드 로빈은 각 실제 서버에 순차적으로 연결을 할당합니다. 최소 연결은 가장 연결이 적은 실제 서버에 연결을 할당합니다. 모두 간단한 구조로 작동합니다. 이 스케줄러는 부하에 따라 할당하는 변종도 이러한에서는 실제 서버 부하에 비례하여 연결을 할당합니다. 보다 스펙이 높은 실제 서버에 부하를 많이 설정 해두면 더 많은 연결을 할당하는 구조입니다.

특별한 용도에 대응한 더욱 복잡한 스케줄링 알고리즘도 있습니다. 예를 들어, 같은 IP 주소 요청이 동일한 실제 서버에 전송되도록하는 것은 투명한 프록시로드 균형 조정 LVS를 사용할 때 유용합니다.

LVS 설치

SuSE 등 일부 배포판은 LVS가 컴파일된 커널을 제공합니다. 이 경우 필요한 작업이 제공되고있다 ipvsadm 패키지를 설치하는 것입니다. 본고의 집필 시점에서는 Ultra Monkey은 Debian Sid (불안정 버전), Woody (안정 / 3.0), 그리고 Red Hat 7.3 및 8.0용으로 빌드된 패키지를 준비하고 있습니다. 이러한 패키지를 구해서 설치에 대한 자세한 정보는 www.ultramonkey.org를 참조하십시오. 나중에 소스에서 LVS를 설치하는 방법을 설명합니다. 이것은 LVS의 구조를 이해하는데도 도움이됩니다.

이전 버전의 LVS는 Linux 2.2 시리즈 커널에서 실행했습니다. 이 구현은 커널 소스에 많은 패치를해야했습니다. 따라서 각 버전의 LVS는 커널 버전에 밀접하게 관련이있는 것입니다. 2.4 커널의 일부인 netfilter 패킷 필터링 아키텍처 [4], LVS를 일련의 커널 모듈로 거의 단독으로 구현하는 것이 가능합니다. 이 결과, LVS가 개별 커널 릴리즈에 고정되어 버리는 일이 없습니다. LVS는 커널에 직접 컴파 일할 수 있지만, 여기에서는보다 쉽고 유연한, LVS를 모듈로 사용하는 방법을 다룹니다.

커널 받기 및 압축 풀기
모든 경우에 가장 쉬운 방법은 신선한 커널을 사용하는 것입니다. 이것은 www.kernel.org에서 구할 수 있습니다. 이 예제에서 사용하는 것은 2.4.20 커널입니다.다음 명령을 실행하여 커널을 linux-2.4.20 디렉토리에 압축을 풉니다.

tar-jxvf linux-2.4.20.tar.bz2
LVS 받기 및 압축 풀기
LVS는 www.linuxvirtualserver.org에서 구할 수 있습니다. 이 예제에서는 1.0.9을 사용합니다. 다음 명령을 실행하여 ipvs-1.0.9 디렉토리에 압축을 풉니다.

tar-zxvf ipvs-1.0.9.tar.gz
LVS 패치를 커널에 적용
LVS 모듈을 컴파일하려면, 2 개의 작은 커널 패치가 필요합니다. 이 패치를 적용하려면 다음 명령을 사용합니다.

cd linux-2.4.20 /
patch-pq <.. / ipvs-1.0.9/linuxkernel_ksyms_c.diff
patch-pq <.. / ipvs-1.0.9/linuxnet_netsyms_c.diff
인터페이스를 숨길 수 있도록 3 번째 패치를 적용합니다. 숨어 인터페이스는 ARP 요청에 응답하지 않고, LVS 직접 라우팅과 함께 실제 서버에서 사용됩니다.

patch-pq <.. / ipvs-1.0.9/contrib/patches/hidden-2.4.20pre10-1.diff
커널 구성
먼저 트리가 깨끗하다 확인합니다.

make mrproper
그러면 커널을 구성하고 있습니다. make menuconfig, make xconfig, make config 등 다양한 방법이 있지만 어느 방법이든 최소한 다음 옵션을 포함하여 netfilter 지원하도록 컴파일하도록주의하십시오. 이 옵션은 가능한 모듈로 빌드하는 것이 좋습니다.

Networking options —>
Network packet filtering (replaces ipchains)
<m> IP : tunnelling
IP : Netfilter Configuration —>
<m> Connection tracking (required for masq / NAT)
<m> FTP protocol support
<m> IP tables support (required for filtering / masq / NAT)
<m> Packet filtering
<m> REJECT target support
<m> Full NAT
<m> MASQUERADE target support
<m> REDIRECT target support
<m> NAT of local connections (READ HELP) (NEW)
<m> Packet mangling
<m> MARK target support
<m> LOG target support
커널 빌드와 설치
커널을 다시 구성했으면 빌드 종속성을 다시 구축해야합니다.

make dep
이것이 끝나면 다음 명령을 사용하여 커널과 모듈을 빌드합니다.

make bzImage modules
빌드된 모듈과 커널을 설치하려면 다음 명령을 실행합니다. 이렇게하면 / lib/modules/2.4.20 / 모듈이 설치된 / boot/vmlinuz-2.4.20 커널이 설치됩니다.

make install modules_install
부트 로더 업데이​​트
부트 로더 grub을 사용하는 경우 / etc / grub.conf에 새 항목을 추가할 필요가 있습니다.여기서는 / boot 파티션을 / dev/hda3는 것을 전제로 설명합니다. / etc / grub.conf의 기존 항목을 참고하십시오.

title 2.4.20 LVS
root (hd0, 0)
kernel / vmlinuz-2.4.20 ro root = / dev/hda3
부트 로더가 lilo의 경우 / etc / lilo.conf에 새 항목을 추가합니다. 여기서는 루트 파티션이 / dev/hda2 것을 전제로 설명합니다. / etc / lilo.conf에있는 기존 항목을 참고하십시오.

image = / boot/vmlinuz-2.4.20

label = 2.4.20-lvs
read-only
root = / dev/hda2
/ etc / lilo.conf가 업데이트되면 lilo를 실행합니다.

lilo
Added Linux-LVS *
Added Linux
Added LinuxOLD
시스템을 다시 시작합니다.
부트 로더 프롬프트에서 새로 만든 커널이 부팅되는지 확인합니다.

LVS 빌드 및 설치
LVS를 구축하기위한 명령은 ipvs-1.0.9/ipvs / 디렉토리에서 실행합니다. 빌드 및 설치에 사용하는 명령은 다음과 같습니다. 커널을 빌드한 / kernel/source/linux-2.4.20를 루트 디렉토리로 사용하십시오.

make KERNELSOURCE = / kernel/source/linux-2.4.20 all
make KERNELSOURCE = / kernel/source/linux-2.4.20 modules_install
Ipvsadm 빌드 및 설치
Ipvsadm는 LVS 설정하는 데 사용하는 사용자 공간 도구입니다. 소스 ipvs-1.0.9/ipvs/ipvsadm / 디렉토리에 있습니다. 빌드 및 설치하려면 다음 명령을 사용합니다.

make all
make install
LVS NAT

LVS NAT는 LVS 설정 아마 가장 간단한 방법입니다. 실제 서버에서 패킷을 Linux Director가 수신 대상 IP 주소가 실제 서버의 것으로 다시 작성됩니다. 실제 서버의 응답 패킷의 원본 IP 주소는 실제 서버 것에서 VIP의 것으로 바뀝니다.

그림 3 : LVS NAT의 예

Linux Director

IP 전달 기능을 활성화합니다. 이것은 다음 줄을 / etc / sysctl.conf에 추가하여 sysctl-p를 실행하여합니다.
net.ipv4.ip_forward = 1
eth0 : 0 172.17.60.201를 설정합니다. 이것은 시스템의 네트워크 설정의 일부로하는 것이 가장 좋지만, 수동 수도 있습니다.
ifconfig eth0 : 0 172.17.60.201 netmask 255.255.0.0 broadcast 172.17.255.255
LVS 설정
ipvsadm-A-t 172.17.60.201:80
ipvsadm-a-t 172.17.60.201:80-r 192.168.6.4:80-m
ipvsadm-a-t 172.17.60.201:80-r 192.168.6.5:80-m
실제 서버

회신 패킷 Linux Director를 통해 라우팅되어 있는지 확인하십시오. 일반적으로 서버 네트워크의 VIP를 기본 게이트웨이 설정하여 수행합니다.
원하는대로 데몬이 포트 80을 수신하고 최종 사용자의 연결을 처리할 수 있는지 확인하십시오.
테스트 및 디버깅

테스트 서버 네트워크 외부에서 172.17.60.201:80에 연결합니다.

Linux Director와 실제 서버에서 패킷 추적 도구를 실행하면 디버깅에 매우 유용합니다.연결 경로를 추적하고 모든 단계에서 패킷이 사라지고 있는지 판단하면 설정에 대한 많은 문제를 해결할 수 있습니다. 여기에서는 예로 Tcpdump를 사용하는 방법을 소개하지만, 다양한 OS를위한 여러 가지 도구가 존재합니다.

다음 추적은 최종 사용자 10.2.3.4가 VIP 172.17.60.201 연결을 시작하고이 연결을 실제 서버 192.168.6.5로 전송됩니다. Linux Director가 패킷을 받아 실제 서버로 전송하고 그 반대를하고있는 것을 알 수 있습니다. 실제 서버에 전송된 패킷이 원본 주소로 최종 사용자의 IP 주소를 가지고있는 것에 주목하십시오. Linux Director 변경하는 것은 패킷의 대상 IP 주소입니다. 마찬가지로 실제 서버의 응답에 대상으로 최종 사용자의 주소가 지정되어 있습니다. Linux Director 회신 패킷의 원본 IP 주소만을 VIP되도록 다시 작성합니다.

tcpdump-n-i any port 80
12:40:40.965499 10.2.3.4.34802> 172.17.60.201.80 :
S 2555236140:2555236140 (0) win 5840
<mss 1460,sackOK,timestamp 16690997 0,nop,wscale 0>
12:40:40.967645 10.2.3.4.34802> 192.168.6.5.80 :
S 2555236140:2555236140 (0) win 5840
<mss 1460,sackOK,timestamp 16690997 0,nop,wscale 0>
12:40:40.966976 192.168.6.5.80> 10.2.3.4.34802 :
S 2733565972:2733565972 (0) ack 2555236141 win 5792
<mss 1460,sackOK,timestamp 128711091 16690997,nop,wscale 0> (DF)
12:40:40.968653 172.17.60.201.80> 10.2.3.4.34802 :
S 2733565972:2733565972 (0) ack 2555236141 win 5792
<mss 1460,sackOK,timestamp 128711091 16690997,nop,wscale 0> (DF)
12:40:40.971241 10.2.3.4.34802> 172.17.60.201.80 :
. ack 1 win 5840 <nop,nop,timestamp 16690998 128711091>
12:40:40.971387 10.2.3.4.34802> 192.168.6.5.80 :
. ack 1 win 5840 <nop,nop,timestamp 16690998 128711091>
ctrl-c
활성 연결 수를 표시하려면 ipvsadm-L-n을 사용합니다.

ipvsadm-L-n
IP Virtual Server version 1.0.9 (size = 4096)
Prot LocalAddress : Port Scheduler Flags
-> RemoteAddress : Port Forward Weight ActiveConn InActConn
TCP 172.17.60.201:80 rr
-> 192.168.6.5:80 Masq 1 7 3
-> 192.168.6.4:80 Masq 1 8 4
ipvsadm-L-stats는 초당 전송 및 수신되는 패킷의 수와 바이트 수를 표시합니다.

ipvsadm-L-n – stats
IP Virtual Server version 1.0.9 (size = 4096)
Prot LocalAddress : Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress : Port
TCP 172.17.60.201:80 114 1716 1153 193740 112940
-> 192.168.6.5:80 57 821 567 9464 2 55842
-> 192.168.6.4:80 57 895 586 9909 8 57098
ipvsadm-L-rate는 송수신되는 패킷의 수를 표시합니다.

ipvsadm-L-n – rate
IP Virtual Server version 1.0.9 (size = 4096)
Prot LocalAddress : Port CPS InPPS OutPPS InBPS OutBPS
-> RemoteAddress : Port
TCP 172.17.60.201:80 56 275 275 1873 9 41283
-> 192.168.6.5:80 28 137 137 9344 20634
-> 192.168.6.4:80 28 138 137 9395 20649
ipvsadm-L-zero는 모든 통계 값을 제로로합니다.

LVS 직접 라우팅

그림 4 : LVS 직접 라우팅 예제

LVS 직접 라우팅은 패킷을 변경하지 않고 실제 서버의 MAC 주소로 전달하는 방식으로 작동합니다. 패킷이 변경되지 않기 때문에, VIP 향하는 트래픽을 받아 실제 서버를 설정해야합니다. 이것은 숨겨진 인터페이스를 사용하여 구현되는 것이 일반적입니다.

Linux Director는 들어오는 패킷을 변경하지 않기 때문에, 응답 패킷이 Linux Director를 거칠 필요가 없습니다. 이 덕분에 더 높은 처리량을 제공합니다. 또한 회신 패킷 Linux Director를 통하지 않고 직접 최종 사용자에게 보내지기 때문에 동일한 로컬 네트워크의 최종 사용자에게 서비스의 부하를 분산하는 것이 쉽습니다.

Linux Director

IP 전달 기능을 활성화합니다. 이것은 다음 줄을 / etc / sysctl.conf에 추가하여 sysctl-p를 실행합니다.
net.ipv4.ip_forward = 1
eth0 : 0 172.17.60.201를 설정합니다. 이것은 시스템의 네트워크 설정의 일부로하는 것이 가장 좋지만, 수동 수도 있습니다.
ifconfig eth0 : 0 172.17.60.201 netmask 255.255.0.0 broadcast 172.17.255.255
LVS 설정
ipvsadm-A-t 172.17.60.201:80
ipvsadm-a-t 172.17.60.201:80-r 172.17.60.199:80-g
ipvsadm-a-t 172.17.60.201:80-r 172.17.60.200:80-g
실제 서버는 응답 패킷을 직접 사용자에게 보낼 수 있습니다. Linux Director가 패킷을 변경할 필요가 없습니다. 즉, Linux Director가 실제 서버의 게이트웨이되지 않아도됩니다.
그러나 경우에 따라서는 (Linux Director는 정말 실제 서버의 네트워크 게이트웨 이인 경우) 실제 서버에서 응답 패킷을 Linux Director를 통해 라우팅하는 것이 바람직하다 수 있습니다. 이러한 패킷의 소스 주소는 VIP입니다. 그러나이 VIP는 Linux Director 인터페이스에 속해 있기 때문에, Linux Director는 패킷이 위조되고있는 것으로 간주하고이를 무시하고 버립니다.

이 문제를 해결하는 방법은 여러 가지가 있습니다. 가장 좋은 방법은 Julian Anastasov 제공 커널 패치를 적용하는 것입니다. 이 패치는 인터페이스별로 패킷 삭제 동작을 무효로 할 수있다 proc 항목을 추가합니다. 이 패치는 http://www.ssi.bg/ ~ ja / # lvsgw에서 구할 수 있습니다.

실제 서버

위의 패치를 커널에 적용하지 않는 경우 응답 패킷이 Linux Director를 통해 라우팅되지 않았는지 확인합니다.
최종 사용자의 연결을 처리하는 데몬이 포트 80에서 수신을하고 있는지 확인합니다.
루프백 인터페이스에 172.17.60.201를 설정합니다. 이것은 시스템의 네트워크 설정의 일부로하는 것이 가장 좋지만, 수동 수도 있습니다. Linux에서 다음 명령을 사용하여합니다.
ifconfig lo : 0 172.17.60.201 netmask 255.255.255.255
172.17.60.201이 속한 네트워크의 실제 서브넷 마스크 관계없이 네트 마스크는 255.255.255.255이어야합니다. 이것은 루프백 인터페이스는 넷마 스크가 포함하는 모든 주소가 인터페이스에 바인딩되어 있기 때문입니다. 일반적인 경우는 127.0.0.1 네트 마스크 255.0.0.0로 설정된 루프백 인터페이스가 127.0.0.0 / 8 모든 트래픽을 허용하는 것입니다. 따라서 여기에서는 lo : 0 만 172.17.60.201로 향하는 패킷을받을 수 있도록하고 싶기 때문에, 네트 마스크가 255.255.255.255 여야가 있습니다.

루프백을 숨깁니다. Linux 실제 서버에서 루프백 인터페이스를 숨기고, VIP의 ARP 요청에 응답하지 않도록해야합니다. 이것은 "LVS 설치"섹션에서 소개한 숨어 인터페이스 패치를 적용하여 수 있습니다. 패치를 사용하려면 다음 행을 / etc / sysctl.conf에 추가하고 sysctl-p를 실행합니다.
# 숨겨진 장치를 활성화하는
net.ipv4.conf.all.hidden = 1
# 루프백 인터페이스 숨기기
net.ipv4.conf.lo.hidden = 1
테스트 및 디버깅

테스트는 모든 네트워크에서 172.17.60.201:80에 연결하여 수행할 수 있습니다.

디버깅은 LVS NAT와 마찬가지로 ipvadm 및 패킷 추적을 사용하여 수행할 수 있습니다.그러나 패킷이 전송될 때, 주소 변환이되지 않는 것에 주의해주세요. 또한 회신 패킷이 LVS에 의해 처리되지 않는 경우에도주의가 필요합니다. 실제 서버에서 최종 사용자에게 직접 전송됩니다. 따라서 송신 패킷과 바이트는 제로가됩니다.

LVS 터널

그림 5 : LVS 터널 예 : LVS 직접 라우팅 예제와 동일한 토폴로지

LVS 터널링은 직접 라우팅과 거의 같은 구조입니다. 주요 차이점은 단순히 새로운 ethernet 프레임을 보내는 것이 아니라 IP 캡슐화된 IP를 사용하여 패킷이 실제 서버에 전송되는 것입니다. 이 최대의 장점은 실제 서버가 Linux Director는 다른 네트워크에있어도 상관 없다는 것입니다.

Linux Director

IP 전달 기능을 활성화합니다. 이것은 다음 줄을 / etc / sysctl.conf에 추가하여 sysctl-p를 실행합니다.
net.ipv4.ip_forward = 1
eth0 : 0 172.17.60.201를 설정합니다. 이 경우에도 시스템의 네트워크 설정의 일부로하는 것이 가장 좋지만, 수동 수도 있습니다.
ifconfig eth0 : 0 172.17.60.201 netmask 255.255.0.0 broadcast 172.17.255.255
LVS 설정
ipvsadm-A-t 172.17.60.201:80
ipvsadm-a-t 172.17.60.201:80-r 172.17.60.199:80-i
ipvsadm-a-t 172.17.60.201:80-r 172.17.60.200:80-i
Linux Director를 실제 서버의 게이트웨이 라우터로 사용하려면 (그 필요는 없지만), 커널에 패치를 적용하는 방법을 "직접 라우팅"섹션에서 확인하십시오.
실제 서버

"직접 라우팅 '섹션에서 소개 패치를 커널에 적용하지 않는 경우 응답 패킷이 Linux Director를 통해 라우팅되지 않았는지 확인합니다.

원하는 데몬이 포트 80에서 실행되고 최종 사용자의 연결을 받아들일 수 있는지 확인하십시오.
tunl0에 172.17.60.201를 설정합니다. 이 경우에도 시스템의 네트워크 설정의 일부로하는 것이 가장 좋지만, 수동 수도 있습니다.
ifconfig tunl0 172.17.60.201 netmask 255.255.255.255
포워딩을 사용하여 루프백을 숨깁니다. 이것은 / etc / sysctl.conf에 다음 줄을 추가하고 sysctl-p를 실행하여 수행할 수 있습니다.
net.ipv4.ip_forward = 1
# 숨겨진 장치를 활성화하는
net.ipv4.conf.all.hidden = 1
# tunl0 인터페이스 숨기기
net.ipv4.conf.tunl0.hidden = 1
테스트 및 디버깅

테스트는 모든 네트워크에서 172.17.60.201:80에 연결하여 수행할 수 있습니다. 디버깅 LVS 직접 라우팅과 비슷합니다.

고가 용성

LVS는 네트워크 서비스의 부하 분산을 효율적으로하기위한 방법입니다. 일반적으로 여러 서버 (최종 사용자보고) 하나의 서버인 것처럼 작동하는 것을 의미합니다. 불행히도, 시스템의 서버의 수가 증가하면 증가할수록, 그 중 하나에 오류가 일어날 가능성도 높아집니다. 따라서 높은 가용성을 실현하는 기술을 이용하여 1 대의 서버에 장애가 발생해도 가상 서비스가 유지되도록하는 것이 중요합니다.

Heartbeat

Heartbeat는 한 쌍의 Linux Director를 모니터링하는 데 사용되는 모든 시간에 반면에 VIP가 할당된 것을 보장합니다. 이것은 각 호스트가 정기적으로 heartbeat 메시지를 전송하여 작동합니다. 정해진 시간에 heartbeat 메시지가 수신되지 않으면 해당 호스트가 실패로 간주됩니다. 이 경우 리소스를 인계 수 있습니다. Heartbeat는 모듈식 설계가되어 있으며, 모든 리소스를 정의할 수 있습니다.

설명의 형편상 여기서는 IP 주소 리소스합니다. 페일오버가 발생하면 IP 주소 인계라는 방법으로 IP 주소를 검색합니다. 이것은 새로 활성화된 Linux Director가 gratuitous ARP 패킷을 VIP로 전송하여 수행됩니다. 네트워크의 모든 호스트는이 ARP 패킷을 받고 다음 패킷을 새 Linux Director의 VIP로 발송 보냅니다.

Heartbeat는 www.linux-ha.org에서 구할 수 있습니다. 제공되는 패키지를 사용하여 설치하거나 다음 명령을 사용하여 소스에서 빌드합니다.

. / ConfigureMe build
make
make install
예제 구성

그림 6 : Heartbeat 예제

/ etc / ha.d에있는 3 개의 파일을 사용하여 설정합니다.

ha.cf : 통신에 사용 인터페이스, 메시지 전송 빈도 로깅 위치 등 heartbeat의 기본 매개 변수를 설정합니다.

오라클의 공유 메모리는 커널 작업을 수반하지 않으며 프로세스 간의 데이터 복제 작업이 불필요 하기 때문에 , IPC(inter-Process Communication)를 위한 가장 빠른 방법을 선호 되고 있습니다.
오라클은 인스턴스 구조를 보면 SGA(System Global Area)와 백 그라운드 프로세스로 구성 되어 있습니다. 여기에서 SGA는 Shared Pool, Database Buffer Cache, Redo Log Buffer 등의 저장에 활용되므로 SGA 크기에 따라 오라클 성능이 크게 달라집니다.

그럼 오라클을 설치하기 전에 Linux에서 사용하는 커널 매개변수와 Shell Limit에 대해서 알아 보도록 하겠습니다.


1. Linux 커널 매개변수의 설정

다른 UNIX 시스템과 달리, Linux 운영체제에서는 시스템이 실행 중인 상태에서 대부분의 커널 매개변수를 수정할 수 있습니다. 커널 매개변수를 변경한 뒤에 시스템을 리부팅할 필요도 없습니다. Oracle Database 10g가 요구하는 커널 매개변수 설정할 수 있으나 시스템에 이미 커널 메게변수가 높은 수치로 설정 되어있을 경우에는 변경 하지 마시기 바랍니다.

[ 매개변수 - kernel.shmmax ]
SHMMAX 매개변수는 공유 메모리 세그먼트의 최대 크기(바이트 단위)를 정의하는데 사용됩니다. 오라클 SGA 메모리로 구성되며, SHMMAX가 올바르게 설정되지 않을 경우 SGA의 크기가 제약될 수도 있습니다. 따라서 SGA의 크기보다 작지 않도록 SHMMAX를 설정합니다.
총 10GB의 메모리에서 오라클이 사용할 수 있는 최대 한도를 정의 하는 것을 의미 합니다.
먄약 SHMMAX 매개변수가 잘못 설정될 경우에는 아래와 같은 오라클 에러 메시지가 발생 됩니다.

ORA-27123: unable to attach to shared memory segment

기본적으로 SHMMAX 기본 값은 32MB 입니다. SGA로 사용하기에는 너무 적은 공간이기 때문에 적당한 크기로 변경 해야 합니다.
[2010-12-09 03:26:18]-[root@calmmass:/proc/sys/kernel]
# cat /proc/sys/kernel/shmmax |sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta'
33.554.432

[ 매개변수 - kernel.shmall ] SHMALL 커널 매개변수는 특정 시점에 시스템에서 사용 가능한 공유 메모리의 최대 크기(페이지 단위)를 설정하는데 사용됩니다. 따라서 이 매개변수는 최소한 아래 값보다 커야 합니다.
ceil(SHMAX/PAGE_SIZE)
우선 페이지 사이즈를 확인 해보겠습니다. Red Hat Linux의 페이지 사이즈는 기본적으로 4,096 바이트 입니다.
[2010-12-09 02:51:29]-[root@calmmass:~]
# getconf PAGESIZE |sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta'
4.096

SHMALL의 디폴트 사이즈는 아래와 같습니다. sed를 이용해서 3자리로 구분한 결과 2MB를 사용합니다.
# cat /proc/sys/kernel/shmall |sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta'
2.097.152

[ 매개변수 - kernel.shmmni ] SHMMNI는 공유 메모리 식별자의 개수를 의미 하며 권장 값은 100 이상 으로 설정하셔야 합니다. 아래와 같이 확인 하시기 바랍니다.
[2010-12-09 03:26:07]-[root@calmmass:/proc/sys/kernel]
# cat shmmni
4096

[ 매개변수 - kernel.sem ] 세마포어(Semaphore)란 공유 리소스의 사용 과정에서 프로세스(프로세스 내 쓰레드) 간의 동기화를 위해 사용되는 일종의 카운터(counter) 입니다. 애플리케이션의 세마포어를 이용하면, 운영 체제는 SET를 통해 세마포어를 지원하게 됩니다.
그럼 세마포어 설정 값을 먼저 확인 해보겠습니다.
[2010-12-09 03:39:32]-[root@calmmass:/proc/sys/kernel]
# ipcs -lm
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 32768
max total shared memory (kbytes) = 8388608
min seg size (bytes) = 1

SEM 매개변수는 세마포어 최대값을 조정 가능하며 의미는 아래와 같습니다.
의미 : {배열당 최대 SEM 수}{최대SEM시스템넓이}{SEMOP호출당최대OP수}{최대배열수}
[2010-12-09 03:37:24]-[root@calmmass:/proc/sys/kernel]
# cat /proc/sys/kernel/sem |sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta'
250 32.000 32 128
1 2 3 4 (필드 라고 정의 하겠습니다.)
1 필드 값(250) : SEMMSL 매개변수는 세미포어 set 당 세마포어의 최대 개수를 정의합니다. 오라클을 예로 init[SID].ora 파일(pfile, spfile 동일)의 PROCESS 인스턴스 매개변수의 (전체 데이터베이스 중) 최대값에 10을 더한 값을 사용할 것을 권장하고 있습니다. 그래서 100이상의 값을 정의하는 것을 권장 합니다.

2 필드 값(32.000) : SEMMNI 매개변수는 전체 Linux 시스템의 세마포어 set의 개수를 정의 합니다. 오라클에서는 100이상의 값을 정의하는 것을 권장합니다.

3 필드 값(32) : SEMMNS 매개변수는 전체 Linux 시스템의 ("세마포어 set"이 아닌) 세마포어의 최대 개수를 정의 합니다. 오라클은 인스턴스 매개변수의 값을 모두 더한 뒤, 가장 큰 Processes값을 두 차례 더하고, 마지막으로 각 데이터베이스 별로 10을 더한 값을 SEMMNS를 설정하도록 권장 합니다.

4. 필드 값(128) : SEMOPM 매개변수는 semop 시스템 호출(system call) 별로 수행될 수 있는 세마포어 작업의 수를 설정하는데 사용됩니다.SEMOPM을 SEMMSL과 동일하게 설정하는 것을 권장합니다. 오라클에서는 100이상의 값으로 설정할 것을 권장 하고 있습니다.


[ 매개변수 - fs.file-max ] Red Hat Linux 서버를 구성하는 과정에서, 사용 가능한 파일 핸들(file handle)의 수가 충분한지 확인하는 것을 매우 중요합니다. 파일 핸들의 최대 개수 설정에 따라 Linux 시스템에서 동시에 오픈할 수 있는 파일의 수가 달라지게 됩니다.
오라클은 전체 시스템의 파일 핸들 수를 최소 65536개 이상으로 설정 할 것을 권장 하고 있습니다.
전체 시스템에서 사용 가능한 파일 핸들의 최대 값을 확인 해보겠습니다.
[2010-12-09 04:06:03]-[root@calmmass:/proc/sys/fs]
# cat /proc/sys/fs/file-max |sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta'
104.857

[ 매개변수 - net.Ipv4.Ip_local_port_range ] 이부분은 새 접속에서 사용할 수 있는 포트의 사용 가능 범위를 확장하는 의미를 가지고 있습니다.
시스템에서 사용하는 포트번호는 /etc/services 파일에 구성 되어있습니다.
[2010-12-09 04:06:24]-[root@calmmass:/proc/sys/fs]
# tail /etc/services
binkp 24554/udp # Binkley
asp 27374/tcp # Address Search Protocol
asp 27374/udp # Address Search Protocol
.. 생략 ..

매개변수의 값을 확인 해보겠습니다. 오라클은 1024 ~ 65000까지 허용하도록 권장 합니다.
[2010-12-09 04:14:10]-[root@calmmass:/proc/sys/net/ipv4]
# cat /proc/sys/net/ipv4/ip_local_port_range |sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta'
32.768 61.000

[ 매개변수 - net.core.rmem_default, net.core.rmem_max ] 일반적인 경우의 대용량 Serving을 위한 설정 합니다. 오라클은 기본적으로 대용량 데이터베이스를 기준으로 하기 때문에 기본 설정 된 값을 변경해야 합니다. 아래와 같은 경우에는 기본 설정 값입니다.
[2010-12-09 04:18:03]-[root@calmmass:/proc/sys/net/core]
# cat /proc/sys/net/core/rmem_default |sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta'
65.535
[2010-12-09 04:18:29]-[root@calmmass:/proc/sys/net/core]
# cat /proc/sys/net/core/rmem_max |sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta'
131.071

[ 매개변수 - net.core.wmem_default, net.core.wmem_max] 소켓 출력 큐의 기본 값과 최대 값을 조정하기 위한 매개변수 입니다. 일반적인 경우의 대용량 Serving을 위한 설정이므로 역시 rmem_default, rmem_max의 값과 동일하게 구성해는 것이 바랍직 합니다. 기본적으로 설정 되어있는 값을 확인 해보겠습니다.
# cat /proc/sys/net/core/wmem_default |sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta'
65.535
[2010-12-09 04:23:05]-[root@calmmass:/proc/sys/net/core]
# cat /proc/sys/net/core/wmem_max |sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/;ta'
131.071

[ 커널 매개변수 반영 ]
이상으로 매개변수의 용도와 설정값을 확인 하는 방법을 실습 했습니다.
이번에는 커널 매개변수를 오라클 기준으로 변경해서 반영 해보도록 하겠습니다. 기본적으로는 위에 나와있는 설정 파일에 값을 변경 해도 되며, sysctl -w [매개변수명]=value 명령어를 이용 할 수 있습니다. 하지만 이번 문서에서는 리눅스의 장점을 살려 환경설정 파일로 매개변수를 반영 하겠습니다.

오라클(
바로가기) 설치 메뉴얼에는 아래와 같이 설정 하길 권장합니다.
cat >> /etc/sysctl.conf <<EOF
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000
EOF
/sbin/sysctl -p

파라매터를 더 추가해보겠습니다. (강추 입니다.)
kernel.shmmax=536870912
kernel.shmmni=4096
kernel.shmall=2097152
kernel.sem=250 32000 100 128
fs.file-max=65536
net.ipv4.ip_local_port_range=1024 65000
net.core.rmem_default=262144
net.core.rmem_max=262144
net.core.wmem_default=262144
net.core.wmem_max=262144


2. Shell Limit 설정

오라클은 Linux 계정 별로 실행되는 프로세스와 열린 파일의 수를 제한하는 것을 권장합니다. 이를 위해, root 계정에서 아래 내용을 /etc/security/limits.conf 설정파일에 oracle10g 라는 특정 프로그램을 제어하는 방법을 설명 하겠습니다.

[참고] /lib/security/pam_limits.so 모듈이 사용할 설정 파일이 /etc/security/limits.conf 파일 입니다. 그중에서 각각 설정에 대해서 아래와 같이 정리 하였습니다.
domain : 제한을 할 대상으로써 사용자 이름이나 그룹 이름, 그리고 와일드 문자를 사용할 수 있습니다.
type : 강하게 제한할 것인지 아니면 어느 정도 여유를 줄 것인지 결정을 합니다.(soft, hard)
item : 제한을 할 항목입니다.
- core : core 파일 사이즈(KB)
- data : 최대 데이터 크기(KB)
- fsize : 최대 파일 사이즈(KB)
- memlock : 최대 locked-in-memory 주소 공간(KB)
- nofile : 한번에 열 수 있는 최대 파일 수
- rss : 최대 resident set size(KB)
- stack : 최대 스택 사이즈(KB)
- cpu : 최대 CPU 점유 시간(MIN)
- nproc : 최대 프로세스 개수
- as : 주소 공간 제한
- maxlogins : 동시 로그인 최대 수
- priority : 사용자 프로세스가 실행되는 우선 순위

[참고] ulimit를 이용하여 리소스를 제한하는 방법입니다. ulimit는 PAM과는 조금 다르게 root계정까지도 제한을 할 수 있습니다. 여기에서 제한에는 두가지 종류가 있습니다.
Soft Limit : 새로운 프로그램이 생성되면 디폴트로 적용되는 제한
Hard Limit : Soft Limit에서 최대 늘릴 수 있는 제한
단, Hard Limit는 root 유저에 의해 조정 가능하지만 무한히 늘리 수 없기 때문에 커널에서 해당 설정 값을 조정 후 늘릴 수 있습니다.


[ oracle10g soft nproc 2047 ]
oracle10g 라는 프로그램이 처음 수행시 기본값으로 사용하는 프로세스는 최대 2047로 제한한다는 의미 입니다.
[ oracle10g hard nproc 16384 ] oracld10g 라는 프로그램이 수행시 사용하는 프로세스는 최대 16384로 제한 한다는 의미 입니다.
[ oracle10g soft nofile 1024 ] oracle10g 라는 프로그램이 처음 수행시 기본값으로 사용하는 파일은 최대 1024로 제한 한다는 의미입니다.
[ oracle10g hard nofile 65536 ] oracle10g 라는 프로그램이 수행시 사용하는 파일은 최대 65536으로 제한 한다는 의미 입니다.


[의문점] 어떤 방식으로 해야 이상적인 설정 일까요?
이상적인 설정은 실제로 oracle database가 가동 되고 나서 개수 제한으로 에러가 발생 하지 않게 하는 것이 가장 이상적인 설정이라고 볼 수 있습니다. 그래서 최대한 해당 프로세스의 개수가 어느정도인지 파일의 개수는 평균적으로 어느정도 사용하는지 파악후 설정 해주는것이 바람직합니다.

그럼 특정 프로그램이 사용하는 프로세스의 개수를 테스트 해보도록 하겠습니다.
[2010-12-09 05:38:43]-[root@calmmass:/proc/sys/net/core]
# lsof -p 3094 |wc -l
1370

열려있는 파일 개수 확인 하는 방법
[2010-12-09 05:39:01]-[root@calmmass:/proc/sys/net/core]
# sysctl -a |grep file
fs.file-max = 104857
fs.file-nr = 1995 472 104857

마지막으로 /etc/security/limits.conf 리소스 제한 설정파일에 oracle 설치시 필요한 설정 내역은 아래와 같습니다.
oracle10g soft nproc 2047
oracle10g hard nproc 16384
oracle10g soft nofile 1024
oracle10g hard nofile 65536



Oracle을 각 OS별 설치하면서 느낀 점은 위와 같은 설정 내역이 조금씩 다르다는 점입니다.
그렇다면 이러한 설정 내역을 모두 외우는 것은 무의미하고 어떤 작업에 의해서 설정을 해야 하는지를 먼저 파악하는 것이 우선이라고 생각 했습니다.
각 설정 파일의 역활과 오라클이 구동 되었을때 사용하는 용도를 보면 조금 접근하기기 편하지 않을까 생각 해봅니다.

Posted by redkite
, |

0027. Apache Performace Turning

아파치 서버 성능 개선을 설정 가이드

Woon San Ko

0.8

Revision History
Revision 0.8 2007.4.13 Woonsan
Ko
신규 작성

아파치 서버는 많은 부하가 발생하는 상황에서도 매우 훌륭하게 처리하는 서버이긴 하지만, 모든 것을 스스로 자동으로 최적화할 수는 없다. 이 글에서는, 어떻게 하면 아파치 서버를 최적의 상태로 설정하는가를 다룬다.

우리가 보다 나은 성능을 위해 제일 먼저 접근할 수 있는 것은, 아파치를 소스로부터 다시 빌드하는 일이다. 아파치에 어떤 모듈들을 포함시킬지, 또 그 모듈들을 동적으로 로드할지 아니면 정적으로 로드하게 할지 등을 잘 선택해야 한다. 이는 성능 뿐만 아니라 보안에 있어서도 매우 중요한 사항이다. 완전히 정적으로 모듈들을 로드하는 아파치 서버는 mod_so를 필요로 하지 않으며, 이는 운영에 있어서 약간의 성능 개선 효과를 가져온다. 그리고 플랫폼에 맞는 최적화 옵션들을 사용하여 성능을 개선할 수 있다.

아파치 2.0의 주요 목표 중 하나는, 아파치 1.3 보다 성능을 개선하고, 핵심 엔진을 완벽한 멀티쓰레드로 구현하여 대규모 사이트에 가용성을 보장하는 것이다.

아파치 2.0은 이를 위해 병렬처리모듈 (Multi Processing Module; MPMs) 을 제공한다. 유닉스 계열 서버들에서는 세 가지의 다른 옵션들을 적용하여 매우 다른 방식의 병렬처리 모드를 선택할 수 있다. MPM은 오직 빌드 시에만 적용된다. 그러므로 이것이 바로 우리가 제일 먼저 아파치를 다시 빌드하는 것에서 출발해야 하는 이유이다.

아파치는 성능, 처리 시의 서버의 동작, HTTP 그리고 네트워크 프로토콜 수준의 통제를 가능하게 하는 여러 가지 지시어들을 제공한다. 또한 기타 아파치 환경 설정들도 서버의 성능에 지대한 영향을 끼칠 수 있다. 시스템 관리자는 이러한 여러 측면들을 숙지해야만 보다 나은 성능을 얻을 수 있다.

성능은 보통 하나의 자원을 다른 자원에 대해 트레이드 오프하는 일이다. 예를 들어, CPU 시간 대 메모리, 메모리 대 대역폭, 또는 대역폭 대 CPU 시간 등. 우리가 만일 올바른 설정을 결정할 수 없다면, 거의 대부분 보다 나은 성능을 기대하기 어렵게 된다. 우리가 만일 서로 다른 자원들 간의 균형을 잘못 맞추게 되면, 종종 성능을 개선하려고 한 시도 자체가 오히려 성능을 떨어뜨리는 경우도 많다. 아파치 서버의 성능이 나아졌는지를 알아낼 수 있는 유일한 방법은 벤치마킹을 해 보는 것이다. 그렇기 때문에 아파치 서버는 벤치마킹 유틸리티 도구인 ab 프로그램을 함께 제공하고 있다. 이 ab 도구에 대해서는 이 글의 후반부에서 다룰 것이다.

아파치 서버는 또한, 아파치 서버를 중간 프록시로 설정함으로써 ("Reverse-proxy"), 다른 웹 서버들의 성능을 개선하는 데에 사용될 수도 있다. 프록시가 캐시 응답을 수행하게 설정함으로써, 대상 서버의 부하를 줄일 수 있다.

성능 개선에 있어서, 궁극적으로, 더이상 어떠한 성능 튜닝 작업을 하더라도 그 효과가 더 이상 없는 경우까지 도달할 수 있다. 이러한 지점에 이르면, 두 가지 가능한 대안이 있다. 하나는 보다 강력한 하드웨어로 이전하는 것이며, 또 다른 하나는 (보다 재밌는 방법인데) 보다 저급의 하드웨어들을 엮어서 클러스터를 구성하는 것이다. 아파치의 URL 재작성 기능과 프록시 기능을 함께 사용하게 되면, 매우 적은 노력으로 그러한 클러스터를 구성할 수 있다.

1. 아파치 서버 성능 관련 지시어

아파치는 서버의 성능과 직접적으로 관련된 여러 지시어들을 제공한다. 이 지시어들은 다음과 같이 프로세스, 네트워크, 그리고 HTTP 제어 수준과 같은 세 가지 주요 그룹들로 분화된다.

  • 아파치 서버가 시작될 때 프로세스와 쓰레드의 개수를 제어하는 지시어들과 아파치 서버가 풀을 어떻게 증가시키고 감소시키는지에 대한 지시어들. 아파치 2.0에서는, 이러한 사항들이 MPM에 의해서 제공되므로, 사용 가능한 지시어들과 기본 값들은 우리가 어떤 MPM을 사용하는가에 따라 달라진다. 이 지시어들은 다시 프로세스 관리와 쓰레드 관리라는 두 가지 그룹으로 나뉜다.

  • 네트워크 수준에서 아파치의 행위를 변경할 수 있는 지시어들. 이 지시어들은 수신되는 요청의 큐의 크기, 대기 프로세스 또는 대기 쓰레드에 요청을 할당하기 위한 락킹 메커니즘, 그리고 클라이언트에 정보를 보내기 위한 버퍼의 크기를 설정하는 데에 사용된다.

  • HTTP 프로토콜 수준에서 아파치의 행위를 변경할 수 있는 지시어들. 이 지시어들은 아파치가 클라이언트와의 연결을 어떻게 제어할지를 설정할 수 있게 한다. 이 지시어들에는 Timeout 값과 HTTP/1.1의 keepalive 설정을 포함한다. 또한 아파치 서버가 클라이언트로부터 데 한번에 얼마 만큼의 데이터를 받게끔 제한을 가할 수 있는 설정들도 포함한다.

1.1. MPM 설정

아파치 2.0의 가장 주요한 개선 사항은 바로 MPM의 도입이다. MPM은 아파치 2.0이 모든 플랫폼에서 완벽한 멀티 쓰레드 서버로서 동작할 수 있게끔 할 뿐만 아니라, 특정 서버 환경에서 가장 적절한 프로세스 모델을 선택하여 사용할 수 있도록 한다. MPM 아키텍처는 개방적으로 설계되어, 관심있는 사람이라면 누구나 자신의 프로세스 모델을 설계하고 구현하여 아파치 핵심 엔진에 결합할 수 있다. 심지어 TCP/IP 방식이 아닌 다른 통신 방법을 사용하는 MPM을 개발할 수도 있다.

MPM의 실제적인 선택은, --with-mpm 옵션에 의해, 아파치를 빌드할 때에 이루어지게 된다. 서로 다른 MPM들에 대한 설계 철학의 차이점들과 유사점들을 이해하는 것은 매우 유익하다. 이 장에서는 MPM과 관련된 각 설정들을 살펴 본다.

1.1.1. MPM 프로세스 모델

각각의 모든 MPM들이 서로 다르긴 하지만, 그들 모두 세 가지 그룹으로 분류될 수 있는데, 그 분류 기준은 프로세스 기반인가, 쓰레드 기반인가, 아니면 이 두 가지를 섞은 것인가이다.

1.1.1.1. Process-Only

Process-Only 서버는 서버 프로세스의 풀을 관리하면서, 필요에 따라 새로운 프로세스들을 생성하는 것이다. 이에는 두 가지 변형이 있는데, 하나는 필요할 때마다 새로운 프로세스를 생성 (fork) 하는 형태이고, 다른 하나는 미리 프로세스를 생성해 놓고 (prefork), 그 프로세스들을 풀에 넣어 두었다가 사용하는 방식이다.

아파치 1.3과 아파치 2.0의 prefork MPM은 모두 pre-forking 서버들이다. prefork MPM은 안정성과 아파치 1.3과 그 이전 버전들과의 호환성을 위해 제공된다.

1.1.1.2. Thread-Only

fork 시스템 호출을 지원하지 않는 플랫폼들은, 모든 쓰레드들이 단일 프로세스 내에서 동작하는 순수한 멀티 쓰레드 프로세스 모델을 사용한다. 이러한 플랫폼들로는, Windows, Netware, 그리고 BeOS가 있다.

beos MPM과 netware MPM은 동적인 쓰레드 풀을 관리하여, 클라이언트 요구에 따라 그 풀을 증가시키거나 감소시킨다. 이 MPM들은 본질적으로 prefork MPM이 동작하는 방식과 동일한 방식이라고 볼 수 있는데, 이들은 다만 프로세스들 대신에 쓰레드가 사용한다는 점이다.

winnt MPM은 가장 제한적이다. 이 MPM은 단일 프로세스 내에서 고정적인 개수의 쓰레드들을 동작시키며, 서버 생명 주기 동안에 쓰레드 풀이 증가하거나 감소하지 않는다. 쓰레드들은 최대 요청 처리 개수에 도달한 경우에 종료되고 재시작될 수 있다. 하지만 전체 쓰레드 개수는 변하지 않는다. 물론, 이러한 점은 환경 설정을 매우 쉽게 만든다. 즉, MaxRequestsPerChildThreadsPerChild 라는 두 가지 지시어들만 신경 쓰면 되기 때문이다.

1.1.1.3. Hybrid (Multiprocess/Multithreaded)

Hybrid 서버들은 프로세스 기반 모델과 쓰레드 기반 모델의 혼합 형태를 사용한다. 즉, 각 프로세스는 여러 쓰레드를 실행시킨다. 이러한 MPM 설정을 사용하는 것은 결국 프로세스 관리 지시어들과 쓰레드 관리 지시어들을 모두 사용해야 함을 의미한다. 또한, MPM의 구현 알고리즘에 따라 서로 다른 지시어들 사이의 상호 관련성이 달라질 수도 있다.

worker MPM은 프로세스의 동적 풀을 관리하는데, 각 프로세스는 고정된 개수의 쓰레드들을 포함한다. 모든 프로세스들의 모든 쓰레드들은 서버로부터 받은 클라이언트 요청에 응답할 수 있다. 이 설정은 아파치 2.0 유닉스 계열 서버들에서 가능한 주요 설정이다.

perchild MPM은 프로세스들의 정적인 풀을 관리하는데, 각 프로세스는 동적으로 변동 가능한 쓰레드들을 관리한다. 다른 MPM들과는 달리, 유독 perchild는 프로세스들이 다른 서버 설정들(예를 들면, 가상 호스트 설정)과 연관된다. 하나의 프로세스를 특정 가상 호스트와 연관시키게 되면, perchild는 각 가상 호스트가 자신만의 쓰레드 풀을 관리할 수 있도록 허용하여, 그 가상 호스트의 요청에 따라 쓰레드 풀을 증가시키거나 감소시키게 된다. perchild의 또 다른 독보적인 특성은 각 프로세스가 서로 다른 사용자나 그룹으로 실행할 수 있다는 점이다.

mpmt_os2 MPM은 OS/2 플랫폼에서 적용 가능하다. 동작 수행에 있어서는, 대부분 worker MPM과 동일하다.

1.2. 프로세스 관리 지시어

아파치는 프로세스 관리와 관련한 일곱 가지의 지시어들을 제공한다. 이들은 사용하는 MPM에 의존적이며, process-only 모델과 hybrid 모델에서 적용 가능하다.

Table 1. 프로세스 관리 지시어

지시어 환경 기본값 영향 지시어
설명
ServerLimit <number> 1.3/prefork, worker, perchild 1.3/prefork: 256, worker: 16, perchild: 8 1.3/prefork: MaxClients, worker: MaxClients, perchild: NumServers

ServerLimit 지시어는 유닉스 계열 아파치 서버에 의해 생성되는 서버 프로세스의 최대 개수를 제약함. 사용되는 프로세스 모델에 따라, 결과가 달라짐. ServerLimit 지시어의 목표는 모든 병렬 프로세스 서버들에 통일된 제한 사항을 가지는 것임. ThreadLimit과 함께 사용되는 경우에는, ServerLimit이 스코어보드 개수를 정의할 수도 있다. 이 지시어가 변경된 후 적용되려면, 서버가 재시작해야 함.

참고사항

ServerLimit 값은 CFLAGS 를 정의하여 컴파일 시에 설정할 수도 있다. 예) -DDEFAULT_SERVER_LIMIT=512. 하지만, 기본 최대값인 2000을 초과할 수는 없다. 이 기본 최대값은 빌드시에 -DMAX_SERVER_LIMIT=1000와 같이 오버라이드 가능함.

StartServers <number> 1.3/prefork, worker, mpmt_os2 1.3/prefork: 5, worker: 3, perchild: 2

프로세스들의 동적인 풀을 허용하는 프로세스 모델에서, 이 지시어는 아파치 서버가 시작될 때 생성해야 할 자식 프로세스들의 개수를 결정.

참고사항

MinSpareServers (1.3/prefork) 값이 만일 더 큰 경우에는 아파치 서버가 그 차이를 즉시 더 생성하게 된다. 프로세스 풀의 크기는 또한 MaxSpareServers (1.3/prefork) 값과 MaxRequestsPerChild (모든 MPM) 에 의해서도 영향 받는다.

NumServers <number> perchild

고정 불변의 프로세스 풀을 생성하는 프로세스 모델에서, NumServers 지시어는 생성되는 프로세스 개수를 결정. 현재 이 지시어는 perchild MPM에만 적용됨. perchild MPM은 StartServersMaxClients 지시어들 대신에 이 지시어를 사용한다. 이는 생성되는 프로세스가 불멸한다는 것을 의미하진 않는다. 만일 MaxRequestsPerChild 값이 0이 아니면, 각 자식 프로세스는 자신의 최대 요청 개수를 초과하게 되면 새로운 프로세스로 대체된다. 따라서, 프로세스의 총 개수는 항상 일정하다. 가상 호스트가 없는 상황에서 이 지시어에 해당하는 기본 값은 2이다. 하지만, 실제 운영할 때에는 이 값을 증가시켜야 할 때가 있을 것이다.

참고사항

perchild는 (반드시 그럴 필요는 없지만) 기본적으로 가상 호스트들과 함께 사용하기 위해 고안된 것이다. 그러므로 서버의 개수는 서버의 모든 가상 호스트들을 처리할 수 있을 정도로 충분히 있어야 한다. 이는 ServerLimit 지시어에 의해 제약되며, -DDEFAULT_NUM_DAEMON 과 같이 컴파일 시에도 설정될 수 있다.

perchild 프로세스를 가상 호스트들에 할당하기 위해서는, ChildPerUserID 지시어를 1에서 NumServers 지시어 값에 이르는 각각의 프로세스 번호에 설정하여, 프로세스에게 사용자와 그룹을 설정해 줄 수 있다. 그리고 나서 AssignUserID 지시어를 <VirtualHostgt; 컨테이너 내에서 설정하여 해당 가상 호스트가 하나의 프로세스와 연관될 수 있다.

MinSpareServers <number> 1.3/prefork

이는 한번에 가능한 아파치 프로세스의 최소 개수를 설정한다. 만일 프로세스들이 클라이언트 요청 처리에 바쁜 상황이 되면, 아파치는 새로운 프로세스들을 생성하여 서버의 풀의 크기를 최소 값으로 유지하게 된다. 필요에 따른 서버의 시작에 관한 아파치의 알고리즘으로 인하여, 이 값을 증가시키는 것은 동시에 많은 요청들을 동시에 처리해야 하는 상황에서만 의미가 있다. 즉 날마다 수백만의 히트를 기록하는 사이트들에서는 다음과 같은 설정이 적절하다.

MinSpareServers 32

참고사항

이 값은 -DDEFAULT_MIN_FREE_DAEMON=32 와 같이 컴파일 시에 설정할 수도 있다.

MaxSpareServers <number> 1.3/prefork

이 지시어는 한번에 IDLE 상태로 될 수 있는 최대 아파치 프로세스 개수를 설정한다. 만일 피크 시간에 많은 프로세스들이 시작되고 급격히 요청들의 빈도가 사라지게 되는 경우에는, 이 지시어의 설정이 너무 많은 프로세스들이 영속적으로 남아 있는 문제를 해결해 주게 된다. 이 값은 MinSpareServers 값 이상이어야 한다. 하루에 수백만 이상의 방문이 이루어지는 사이트에서는 다음과 같은 값을 설정하는 것이 타당할 수 있다. (하지만 worker MPM을 고려해 보아야 한다.

MaxSpareServers 64

MaxSpareServersMinSpareServers는 지금보다 예전에 매우 중요한 것이었다. 버전 1.3 이후로, 아파치는 들어오는 요청들을 1부터 최대 32개의 새로운 프로세스들을 생성하는 대응 알고리즘을 가지고 있다. 그 이유는, 아파치가, 반드시 필요하지 않는 한, 한꺼번에 너무 많은 프로세스를 시작하지 않도록 하는 데에 있다.

이러한 전략은 아파치가 서버 풀을 동적으로 관리하는 효과를 가져오게 된다. 다음은, 이 설정들에 대한 기본 값들이다.

  • StartServers: 5

  • MinSpareServers: 5

  • MaxSpareServers: 10

참고사항

이 지시어는 -DDEFAULT_MAX_FREE_DAEMON=64 와 같이 CFLAGS를 설정함으로써 컴파일 시에 설정 가능하다.

MaxRequestsPerChild <requests> 1.3, 모든 MPM

MaxRequestsPerChild 지시어는 특정 아파치 프로세스가 처리해야 하는 요청의 최대 개수를 설정한다. 이 설정의 주 목표는 메모리 릭을 방지하는 것이다. 만일 다음과 같이 설정하게 되면, 프로세스들은 영원히 종료하지 않게 된다.

MaxRequestsPerChild 0

참고로, beos MPM을 제외한 다른 모든 MPM들의 기본 값은 10000이다.

한편, 이 값이 너무 작게 되면, 성능 상의 문제를 일으킬 수 있다. 즉, 아파치가 너무 자주 프로세스를 시작시키고 종료시켜야 하기 때문이다. 유닉스 계열 시스템에서 바람직한 값은 1000~10000이며, winnt MPM에서는 1000~100000이다.

이 지시어에 설정된 값에 따른 그 결과는, 프로세스 모델에 따라 매우 다르게 나타날 수 있다. 1.3/prefork와 같은 순수한 프로세스 모듈에서는, 이 값이 각 프로세스의 생명 주기를 결정한다. 순수한 쓰레드 모델에서는, 이 값이 전체 서버 프로세스의 생명 주기를 결정한다. 왜냐하면 순수한 쓰레드 모델에서는 오직 하나의 프로세스만을 재시작하기 때문이다. 이 값을 100으로 설정하게 되면, 하나의 prefork MPM 프로세스는 100*StartServers ~ 100*MaxClients 개수의 요청들을 처리하게 된다. 그러나, 이것이 winnt MPM에 있어서 모든 쓰레드들의 완전한 재시작을 의미하지는 않는다.

참고사항

이 설정 값은 컴파일 시에 CFLAGS-DDEFAULT_MAX_REQUESTS_PERCHILD=10000와 같이 설정할 수도 있다. beos MPM은 특별한 경우인데, MaxRequestsPerThread 옵션을 제공한다. 이 값은 컴파일 시에 -DDEFAULT_MAX_REQUESTS_PER_THREAD=10000와 같이 설정될 수 있다.

MaxClients <connections> 1.3/prefork, worker

이 지시어는 아파치 서버가 전체적으로 처리해야 하는 클라이언트의 총 개수를 설정한다. 모든 프로세스가 모두 Busy 상태에 있을 때 (worker MPM인 경우는 모든 프로세스들의 모든 쓰레드들이 Busy 상태에 있을 때), 연결을 시도하려고 하는 클라이언트들은 ServerUnavailable 응답을 받게 된다. 그렇기 때문에 이런 경우 이 값은 아래와 같이 너무 작게 설정되어서는 안된다.

MaxClients 100

이 제한 설정은 worker MPM과 1.3/prefork MPM에서 설정 가능하지만, 서로 동작하는 방식은 다르다. 1.3/prefork의 경우에는, 이 값은 전체 프로세스의 개수에 대한 제한이 되며, 이 개수는 연결하려는 클라이언트들의 총 개수를 제한하게 된다. worker MPM의 경우에는, 클라이언트의 총 연결 개수는 프로세스 개수와 프로세스 당 쓰레드 개수 (ThreadsPerChild) 를 곱하여 계산된다. 따라서 MaxClientsThreadsPerChild와 곱해져야 한다. MaxCleintsServerLimit 값보다 더 크지 않아야 한다.

한편 MaxClients를 작은 값으로 설정하게 되면, 일부 클라이언트들이 연결할 수 없는 상황이 있을 수 있긴 하지만, 클라이언트 요청의 턴어라운드를 증가시키는 효과를 가져올 수 있다. 따라서, 이 지시어는 양날의 도구라고 볼 수 있으며, 서버가 성능 튜닝이 되어야 하는지, 업그레이드 되어야 하는지, 아니면 클러스터 되어야 하는지를 알려 줄 수 있다. 이런 맥락과 맞닿는 부분이 바로 요청들의 대기 큐인데, 이는 후에 다루어질 ListenBacklog를 통해 설정될 수 있다.


1.3. 쓰레드 관리 지시어

아파치는 여섯 가지의 쓰레드 관리와 관련한 지시어들을 제공한다. 다섯 가지는 프로세스 관리 지시어들과 유사한 방식이며, 나머지 하나인 MaxThreadsPerChildThreadsPerChild의 변형된 형태라고 볼 수 있다.

Table 2. 쓰레드 관리 지시어

지시어 환경 설명
ThreadLimit <number>

worker,

perchild

ThreadLimit 지시어는 병렬 프로세스들에 의해 생성되는 서버 쓰레드들의 최대 개수를 설정한다. 사용되는 프로세스 모델에 따라, 이 지시어는 다른 의미를 가질 수 있다. ThreadLimit의 목적은 모든 병렬 프로세스 서버들에서 단일한 쓰레드 제한 사항을 두기 위함이다. ServerLimit과 함께, ThreadLimit은 스코어보드 개수를 정의하므로, 서버가 재시작될 때 다시 읽혀지지 않고 원래의 값을 유지한다. 이 값의 변경 사항은 서버가 재시작되어야 적용된다. 이 지시어의 기본 값은 64이다.

ThreadLimit 64

ThreadLimit은 모든 프로세스들의 전체 쓰레드 개수를 제한한다. 이 값은 MPM에 따라서 다르게 적용될 수 있다. worker MPM에서는 이 값이 MaxClients를 제한하며, 또한 ServerLimit * ThreadsPerServer를 제한한다. perchild MPM에서는, 이 값이 NumServers * MaxThreadsPerServer 값을 제한하게 된다.

참고사항

이 값은 CFLAGS 값에 -DDEFAULT_THREAD_LIMIT=512 와 같이 설정함으로써 컴파일 시에 설정될 수도 있다. 하지만, 기본적으로 제공되는 최대값을 초과할 순 없는데, 그 최대 값은 기본적으로 20000이다. 이 값을 오버라이드하고 싶다면, -DMAX_THREAD_LIMIT=50000와 같이 사용하라.

StartThreads <number>

perchild,

netware,

beos

프로세스 당 동적인 크기의 쓰레드들을 관리할 수 있도록 제공하는 프로세스 모델에서는, StartThreads 값은 아파치가 시작될 때 생성해야 할 자식 프로세스들의 개수를 결정한다. 이 값의 기본 값은 다음과 같다.

  • perchild: 5

  • netware: 25

  • beos: 10

perchild MPM의 경우에는 이 값은 서버 당 설정되는 것으로서, 전체 쓰레드 개수는 StartThreads * NumServers가 된다. 단일 프로세스 모델인 netwarebeos MPM인 경우에는, 이 값이 서버가 시작될 때의 전체 쓰레드 개수가 된다.

참고사항

이 값은 CFLAGS-DDEFAULT_START_THREADS=20와 같이 설정함으로써 컴파일 시에 설정 가능하다. netware MPM은 이 값이 기본적으로 25로 설정된 DEFAULT_THREADS_PER_CHILD로 설정되어 있다.

MinSpareThreads <number>

worker,

perchild,

mpmt_os2,

netware,

beos

이 지시어는 언제든지 항상 가용한 최소 개수의 아파치 쓰레드 개수를 설정한다. 클라이언트 요청들로부터 쓰레드들이 Busy 상태에 이르면, 아파치는 새로운 쓰레드들을 생성하여 풀을 관리한다. 이 값의 기본 값은 5이다.

MinSpareThreads 5

perchild MPM이 아닌 다른 모든 MPM들에서는, 이 값이 전 서버에 해당하는 설정이 되지만, perchild MPM에서는, 이 값이 자식 프로세스 당 여분 쓰레드 개수를 설정하는 의미가 된다. NumServers가 10이고, MinSpareThreads가 5인 경우, 여분 쓰레드 개수는 50이 된다.

참고사항

이 값은 유닉스 계열, 윈도우, OS/2 서버들에서 컴파일 시에 CFLAGS-DDEFAULT_MIN_SPARE_THREADS=10와 같이 설정할 수 있다. 윈도우에서는, DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD 값으로 설정된다.

Netware와 BeOS에서는, 지시어는 같지만, 컴파일 시의 옵션은 좀 다르다. -DDEFAULT_MIN_FREE_THREADS=10와 같이 사용하여 오버라이드 가능하다. 이 두 가지 플랫폼에서 기본 값은 10이다.

MaxSpareThreads <number>

worker,

perchild,

mpmt_os2,

netware,

beos

이 지시어는 Idle 상태의 쓰레드들의 최대 개수를 설정한다. 피크 시에 많은 쓰레드가 생성되고 난 뒤, 이 지시어는 초과된 쓰레드들이 더이상 동작하지 않도록 한다. 이 값은 MinSpareServers 값 이상이어야 의미가 있다.

perchild MPM이 아닌 모든 MPM들에서, 이 값은 전 서버에 걸쳐 유휴 쓰레드의 최대 개수를 설정한다. perchild MPM의 경우에는, 이 값이 자식 프로세스 당 유휴 쓰레드의 개수를 설정한다. 만일 NumServers가 10이고 MaxSpareThreads가 10인 경우, 전체 유휴 쓰레드의 개수는 100이 된다.

참고사항

이 값은 perchildmpmt_os2 MPM에서 CFLAGS-DDEFAULT_MIN_SPARE_THREADS=10와 같이 설정하여 컴파일 시에 설정 가능하다. 이는 또한 윈도우 환경에서도 적용 가능한데, DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD에 의해 설정된다.

Netware와 BeOS에서는 -DDEFAULT_MAX_FREE_THREADS=10를 사용하여 오버라이드 가능하다. 이 값의 기본 값은 NtWare에서 100이며, BeOS에서는 HARD_THREAD_LIMIT 의 값이 50으로 기본 설정되어 있다.

ThreadsPerChild <number>

worker,

winnt

프로세스 당 고정된 쓰레드 개수를 설정하는 프로세스 모델에서는, ThreadsPerChild가 아파치가 시작될 때 생성하는 쓰레드의 개수를 결정한다. 이에 대한 기본 값들은 다음과 같다.

  • worker: 25

  • winnt: 50

위 두 가지 MPM에서는, 이 값들을 어떻게 사용하는가에 따라 의미가 크게 달라진다. worker MPM에서는, 이 값이 얼마나 많은 동시 연결이, 또 다른 프로세스가 시작되기 전에 처리될 수 있는지를 결정한다. 프로세스의 개수는 동적이지만, 각 프로세스의 쓰레드 개수는 ThreadsPerChild로 설정된 개수로 고정된다. 유휴 쓰레드들의 최대 개수와 최소 개수는 이 숫자와 곱해져야 한다.

참고사항

worker MPM에서 이 값은 CFLAGS-DDEFAULT_THREADS_PER_CHILD=100와 같이 설정함으로써 컴파일 시에 설정될 수 있다. 이는 또한 Netware에서도 적용되는데, DEFAULT_START_THREADS의 기본 값으로 사용되어, StartThreads에 적용된다.

윈도우 환경에서는, ThreadsPerChild가 서버가 처리할 수 있는 전체 동시 연결 개수를 설정한다. 즉, 풀은 늘어나거나 줄어들지 않는다. 기본 값은 50이다.

ThreadsPerChild 50

윈도우 환경에서는, 자식 프로세스가 오직 하나이므로, 이 연결 개수에 대한 제한 값은 서버 전체로서 계산된다. 매우 Busy한 사이트에서는, 이 값은 최대 1024로 증가시킬 수 있다.

ThreadsPerChild 1024

윈도우 환경에서, 이 값은 또한 StartThreads 값이기도 하다. 이 값은 -DSTART_THREADS=1024와 같이 설정하여 컴파일 시에 설정할 수도 있다. 이 값은 HARD_THREAD_LIMIT 값을 초과할 수 없으며, HARD_THREAD_LIMIT는 1920으로 미리 설정되어 있다.

MaxThreadsPerChild <number>

perchild

쓰레드들의 동적 풀을 관리하는 프로세스 모델에서는, 이 지시어가 생성될 수 있는 최대의 쓰레드 개수를 결정한다. 현재 이 설정은 오직 perchild MPM에서만 적용 가능하다. 이 설정의 기본 값은 ThreadLimit 값과 동일하며, ThreadLimit 값을 초과할 수 없다.

MaxThreadsPerChild 10

ThreadLimit과는 달리, MaxThreadsPerChild는 변경될 수 있으며, 서버가 재시작될 때 새로운 값이 읽혀 적용될 수 있다. 그러므로, 이 값은 ThreadLimit 값보다 작게 설정될 수 있어서 나중에 아파치를 완전히 종료시키지 않고도 값을 올려서 적용할 수도 있다.

참고사항

이 값은 -DDEFAULT_MAX_THREADS_PER_CHILD=10 과 같이 컴파일 시에 설정될 수 있으며, MAX_THREAD_LIMIT 값을 초과할 수 없다. MAX_THREAD_LIMIT 값은 ThreadLimit 값의 가장 높은 가능한 값을 설정한다.

MaxRequestsPerChild <number>

beos

이 지시어는 단일 쓰레드의 최대 요청 처리 개수를 설정한다. 이는 beos MPM에서만 적용 가능하며, 위에서 언급된 MaxRequestsPerChild와 유사하다. 기본 값은 10000으로 다음과 같이 명시적으로 선언될 수 있다.

MaxRequestsPerChild 10000

참고사항

이 설정은 -DDEFAULT_MAX_REQUESTS_PER_THREAD=10000 와 같이 컴파일 시에 설정될 수 있으며, HARD_THREAD_LIMIT 값을 초과할 수 없다.


1.4. 네트워크 및 IP 관련 성능 지시어

HTTP는 TCP와 IP 네트워크 프로토콜 기반 위에 서 있다. 우리는 또한 운영체계의 네트워크 연결 처리 측면에서 제어할 수 있다. 아파치 2.0에서는 서로 다른 쓰레드들과 프로세스들이 네트워크 연결을 받아들이는 방식을 변경할 수도 있다.

Table 3. 네트워크 및 IP 관련 성능 지시어

지시어 설명
ListenBacklog <length>

클라이언트 연결 요청은, 아파치 프로세스 또는 쓰레드가 서비스할 수 있을 때까지 큐 내에 들어가게 된다. 이 큐의 최대 길이는 ListenBacklog 값에 의해 통제되며, 이의 기본 값은 511이다. 다음과 같이 변경할 수 있다.

ListenBacklog 1023

하지만, 이 값을 변경할 이유는 별로 없다. 만일 아파치가 요청 처리를 신속하게 수행하지 못하게 되어 이 큐가 넘치게 되는 상황이라면, 이 큐의 크기를 증가시키는 것보다는, 다른 곳에서 성능 개선을 하는 것이 보다 낫기 때문이다. 또한 많은 운영체계들은 이 값은 시스템 자체에서 제한시키고 있기도 하다.

이 값은 CFLAGS-DDEFAULT_LISTENBACKLOG=1023와 같이 설정하여 컴파일 시에 설정할 수 있다.

AcceptMutex <type>

웹서버 성능의 핵심 측면 중의 하나는 바로 네트워크 요청이 들어 왔을 때에, 대기하고 있던 프로세스나 쓰레드에 어떻게 할당해 주는가하는 방식이다. 어떤 경우에든, 아파치는 새로운 연결을 대기하고 있는 많은 쓰레드나 프로세스들을 가지고 있을 것이다. 이 경우 아파치는 서로 다른 쓰레드들이나 프로세스들이 어떻게 조정하여 연결을 취할 것인가하는 메커니즘을 가지고 있어야 한다. 이 메커니즘은 바로 상호 배타적 락킹 (Mutually Exclusively Lock), 즉 mutex에 의해 결정된다.

아파치는 네 가지의 서로 다른 mutex를 지원한다. 아파치 1.3에서는, 어떤 타입이 사용될지가 컴파일 시에 결정되고 변경될 수 없었다. CFLAGS 변수를 사용하여 오버라이드할 수만 있었다. 아파치 2.0에서는, 컴파일 시 뿐만 아니라, 서버 수준에서 설정 파일 내의 AcceptMutex 지시어를 사용하여 설정을 변경할 수 있다. 가용한 락킹 타입들은 플랫폼에 따라 다르긴 하지만, 아래 표에 나열된 것들 중 한 개 이상을 포함한다.

Table 4. AcceptMutex 지시어 설정 옵션

AcceptMutex CFLAGS 의미
flock -DUSE_FLOCK_SERIALIZED_ACCEPT flock 시스템 호출을 사용하며, LockFile에 정의된 락 파일을 사용
fcntl -DUSE_FCNTL_SERIALIZED_ACCEPT fcntl 시스템 호출을 사용하며, LockFile에 정의된 락 파일을 사용
sysvsem -DUSE_SYSVSEM_SERIALIZED_ACCEPT System V 세마포어 사용
posixsem -DUSE_POSIXSEM_SERIALIZED_ACCEPT POSIX 호환 세마포어 사용
pthread -DUSE_PTHREAD_SERIALIZED_ACCEPT POSIX 쓰레드 mutex 락을 사용


1.5. HTTP 관련 성능 지시어

서버 풀을 제어하는 것과 더불어, 아파치는 TCP/IP와 HTTP 프로토콜 수준에서 성능 관련 이슈들을 제어할 수 있는 지시어들을 제공한다. 이들은 모두 플랫폼 독립적이기 때문에, 아파치가 동작하는 플랫폼에 관계 없이 사용 가능하다.

Table 5. HTTP 관련 성능 지시어

지시어 설명
KeepAlive <on|off>

영속 연결은 클라이언트가 하나의 동일한 연결을 사용하여 여러 요청을 보낼 수 있도록 허용한다. 이러한 아이디어에 기초한 것이 바로 HTTP/1.1이다. 클라이언트가 서버에 대한 연결을 계속 유지할 수 있게 허용함으로써 기존 클라이언트의 성능을 향상시킬 수 있다. 하지만 서버가 매우 바쁜 경우 다른 새로운 클라이언트를 서비스할 수 없는 상황이 발생할 수 있다.

기본 설정은 다음과 같다.

KeepAlive on

KeepAlive는 클라이언트와 서버 간에 매우 빠른 대화를 제공하는 것으로서, 클라이언트가 접속을 끊기 전까지 해당 서버 프로세스가 다른 요청을 처리할 수 없다는 비용이 초래된다. 이 문제를 해결하기 위해, 아파치는 두 가지 추가 지시어를 제공하여 영속적인 연결에 대한 생명주기를 관리할 수 있도록 한다.

KeepAliveTimeout <seconds>

이 지시어는 아파치 프로세스 (또는 쓰레드) 가 클라이언트가 또다른 HTTP 요청을 보내기 전까지 대기해야 하는 시간을 설정한다. 이 시간이 경과하기까지 새로운 요청을 보내지 않으면, 서버는 연결을 끊게 된다. 이 값은 상대적으로 작은 값으로 설정되어야 하며, 기본 값으로 15초로 설정되어 있다.

KeepAliveTimeout 15

이 값을 컴파일 시에 설정하고 싶다면, CFLAGS-DDEFAULT_KEEPALIVE_TIMEOUT=15 과 같이 설정하면 된다.

MaxKeepAliveRequests <number>

타임 아웃 값과는 관계 없이, 영속 연결은 또한 MaxKeepAliveRequests로 설정된 요청 개수에 도달하게 되면 자동으로 연결을 끊게 된다. 서버 성능을 관리하기 위해서, 이 값은 높은 값으로 유지해야 하며, 기본 값은 100으로 설정되어 있다.

MaxKeepAliveRequests 100

이 값을 0으로 설정하게 되면, 타임 아웃 시간을 초과하지 않고 클라이언트가 연결을 끊지 않는 이상, 이 영속 연결은 영원히 활성화된 상태로 남아 있게 된다. 이는 약간 위험하다. 왜냐하면 이는 서버가 서비스 거부 (Denial of Service; DOS) 공격으로부터 무력하게 되기 때문이다. 따라서, 이 값은 높게 설정하되, 유한한 값으로 설정하는 것이 바람직하다.

이 값을 컴파일 시에 설정하려면, CFLAGS 변수에 -DDEFAULT_KEEPALIVE=100와 같이 설정하면 된다.

TimeOut <seconds>

이 지시어는 비활성화된 연결에 대하여 얼마나 오랫동안 HTTP 연결을 유지하고 있을지를 설정하며, 다음과 같은 기준에 의해 결정된다.

  • 연결이 확립되고 GET 요청이 접수되기 전까지의 시간. 이는 KeepAliveTimeout가 사용되는 영속 연결에는 영향을 끼치지 않는다.

  • PUT 또는 POST 요청에서 데이터의 마지막 패킷이 도착한 이후의 시간

  • 서버가 더 기다릴 게 있는 경우에, 마지막 ACK가 수신된 이후의 시간

TimeOut의 기본 값은 5분으로 설정되어 있으며, 다음과 동일하다.

TimeOut 300

이 값을 컴파일 시에 설정하고 싶다면, CFLAGS 변수에 -DDEFAULT_TIMEOUT=60와 같이 추가하면 된다. 참고로 ProxyTimeOut 지시어는 TimeOut 값을 오버라이드한다.


1.6. HTTP 제한 지시어

위에서 언급된 프로토콜 관련 지시어들과 더불어, 아파치는 클라이언트에 의해 요청되는 HTTP 요청의 크기를 제한할 수 있는 네 가지의 지시어들을 제공한다. 이들은 기본적으로 클라이언트들이 서버의 자원들을 소진시켜 DOS 문제들이 발생하지 않도록 하며, 그러므로 서버 보안에도 관련된다.

Table 6. 네트워크 및 IP 관련 성능 지시어

지시어 설명
LimitRequestBody <bytes>

이 지시어는 HTTP 요청의 Body 크기 (PUT 또는 POST 메소드에 의해 전송) 를 제한한다. 기본 값은 0으로 설정되며, 이는 아무런 것도 제한하지 않게 된다. 최대 값은 2147483647 바이트, 즉 2 GB 이다. 클라이언트가 Body 제한 값을 초과하여 데이터를 보내게 되면, 서버는 그 요청을 서비스하지 않고 오류 메시지를 전달하게 된다.

LimitXMLRequestBody <bytes>

아파치 내에서 XML 처리를 유발하는 HTTP 요청들 (즉, 내부의 Expat 파서에 전달되는 요청들) 은 이 지시어를 통해 별도로 크기를 제한할 수 있다. 이에는 mod_dav에 의해 처리되는 WebDAV 요청이 포함된다. LimitRequestBody와 마찬가지로 LimitXMLRequestBody는 제한 바이트 크기를 설정한다. 예를 들어, 500 KB 제한 크기는 다음과 같이 설정된다.

LimitXMLRequestBody 512000

이의 기본 값은 1000000 바이트이다. 참고로 LimitRequestBody의 기본 값은 원래 무제한(0)이었던 것과 차이가 있다는 점이 주목할 만하다.

LimitRequestFields <number>

이 지시어는 클라이언트가 HTTP 요청에 포함할 수 있는 헤더의 개수를 제한하며, 기본 값은 100이다. 실제 환경에서 클라이언트가 보내는 헤더의 개수는 대략 20개 내외이다. 이 값을 50개로 줄이려면 다음과 같이 설정할 수 있다.

LimitRequestFields 50

이 값을 컴파일 시에 적용하고 싶다면, CFLAGS 변수에 -DDEFAULT_LIMIT_REQUEST_FIELDS=50와 같이 설정하면 된다.

LimitRequestFieldSize <length>

이 값은 클라이언트에 의해 전송되는 개별 HTTP 헤더의 크기를 제한하며, 이 크기에는 헤더의 이름의 크기까지 포함된다. 이의 기본 값은 동시에 최대값이기도 한데, 8190 바이트이다. 이 값을 만일 100으로 바꾸고 싶다면 다음과 같이 설정한다.

LimitRequestFieldSize 100

이 값을 컴파일 시에 설정하고 싶다면 CFLAGS-DDEFAULT_LIMIT_REQUEST_FIELDSIZE=100와 같이 설정하면 된다.

LimitRequestLine <bytes>

이 값은 HTTP 요청 자체의 최대 길이를 제한하며, HTTP 메소드, URL, 그리고 프로토콜까지를 모두 포함한다. 기본 제한 값은 8190 바이트이다. 만일 이 값을 500 바이트로 줄이고 싶다면 다음과 같이 설정한다.

LimitRequestLine 500

이 지시어의 효과는 클라이언트가 전송할 수 있는 URL의 크기를 제한하는 것이다. 그래서 서버에 오직 유효한 URL만을 클라이언트가 요청할 수 있도록 한다. 이에는 GET 요청에서의 QUERY_STRING도 포함한다. 이 값을 너무 작게 설정하게 되면, 클라이언트가 GET 메소드에 의한 HTML 폼 전송을 막을 수도 있다.

이 값을 컴파일 시에 적용하고 싶다면, CFLAGS 변수에 -DDEFAULT_LIMIT_REQUEST_LINE=500 와 같이 설정하면 된다.


2. 보다 나은 성능을 위한 아파치 서버 설정

아파치의 많은 설정들은 적절한 처리 비용이 고려되지 않으면 성능에 큰 영향을 끼칠 수 있다. 어떤 것들은 주의하지 않으면 성능을 떨어뜨릴 수도 있고, 어떤 것들은 특정 환경에서 성능을 향상시킬 수도 있다.

2.1. 성능에 영향을 끼치는 지시어들

어떻게 사용되는가에 따라 성능을 향상시키거나 떨어뜨릴 수 있는 많은 지시어들이 존재한다. 어떤 것들은 명확하기도 하지만, 또 어떤 것들은 덜 명확한 것들이 있다.

2.1.1. DNS 및 호스트명 Lookup

DNS를 사용하는 것은 어떤 것이든 아파치 성능에 영향을 준다. 특히 다음 두 가지 지시어의 사용은 가능한 한 피해야 한다.

Table 7. DNS 및 호스트명 Lookup

지시어 설명
HostNameLookups <on|off|double> 이는 아파치가 IP 주소 대신 호스트 이름을 로그에 정보로 기록하도록 한다. 하지만, 이 과정은, 아파치가 성능을 위해 DNS 캐시를 사용함에도 불구하고, 시간이 많이 소요되는 작업이다. Analog와 같은 로그 분석기는 나중에 통계를 산출할 때에 자체적인 DNS 이름을 찾을 수 있는 기능이 있으므로, 그러한 도구에 의존하는 것이 바람직하다.
UseCanonicalName <on|off|dns>

이는 아파치가, ServerNamePort 지시어를 사용하지 않고, 자신의 IP 주소로부터 서버 이름을 추출하게끔 설정할 수 있다. 이 옵션은 mod_vhost_alias 모듈을 사용하여 대규모의 가상 호스트를 운영하는 경우에 유용할 수 있다. mod_vhost_alias 모듈은 아파치에 의해 서비스되는 호스트 이름들에 대해서만 캐시를 하는 것이지, 전체 인터넷에 대해서 캐시를 제공하지는 않기 때문에, HostNameLookups 옵션은 사용할 필요가 거의 없으며, 가능한 피해야 한다.

또한, 전체로서 또는 부분으로서 호스트 이름을 사용하게 되면, 호스트 이름을 통해 IP 주소를 찾는다든가, IP 주소를 통해 호스트 이름을 찾는다든가 하는 식의 DNS Lookup이 발생할 수 있다. 또한 이 옵션은 mod_access 모듈의 allowdeny 지시어에 영향을 미치며, mod_proxy 모듈의 ProxyBlock, NoProxy, NoCache 지시어 등에도 영향을 끼치게 된다.


2.1.2. 심벌릭 링크와 권한 검사

아파치는 FollowSymLinks 옵션에 따라 심벌릭 링크를 따라가서 서비스를 할지 아니면 서비스를 거부할지 설정될 수 있다. 이 옵션이 켜 있지 않으면, 아파치는 파일을 읽거나 CGI 스크립트를 실행할 때마다, 상위 디렉터리 또는 해당 파일이 심벌릭 링크인지 확인하기 위하여, 루트 디렉터리로부터 하위 디렉터리까지 이르는 전체 경로를 검사하는 데에 별도의 시간을 소비하게 된다.

한편, 만일 심벌릭 링크가 SymLinksIfOwnerMatch에 의해 활성화된 경우에, 아파치는 오직 그 링크의 소유자가 서버 (또는 가상 호스트) 의 소유자와 같은 소유자인 경우에만 링크를 따라가게 된다. 이러한 경우, 아파치는 전체 경로를 검사함은 물론, 해당 링크의 소유자까지 검사하게 된다.

성능을 최대화하려면, 항상 FollowSymLinks 를 사용하고, SymLinksIfOwnerMatch를 사용하지 마라.

Options FollowSymLinks

하지만, 이 옵션들은 보안을 향상시키기 위해 존재하는 것들이다. 이 전략은 시스템 관리자가 성능보다는 보안이 더 걱정될 때 사용할 수 있다.

mod_autoindex 는 이 옵션을 준수하게 됨에 유의하기 바란다.

2.1.3. 동적 컨텐트의 캐시

일반적으로 아파치는 동적으로 생성되는 컨텐트들에 대해서는 프록시에게 문서를 캐시하라는 정보를 제공하지 않는다. mod_expires 모듈을 사용하게 되면, 문서에 대하여 만료 시간을 강제로 설정할 수 있으며, 그 시간이 매우 짧다 하더라도 서버의 부하를 줄일 수 있다.

ExpiresByType text/html 600

이 지시어는 주식 시황 페이지와 같이 매 십 분마다 갱신해야 하는 페이지들을 제공할 때에 적절할 수 있다. 해당 페이지가 매우 짧은 시간 안에 만료되어야 할지라도 만일 페이지가 빈번하게 접근되는 경우에는 클라이언트가 페이지에 직접 접근하지 않고 프록시를 대신 사용하게 할 수 있다.

그렇다 할지라도, 어떤 프록시들은 그들 스스로 동적 컨텐트라고 생각하는 것의 캐시를 아예 방지하는 경우도 있다. 그들을 속이고 싶다면, 다음과 같이 CGI 스크립트들을 보통의 HTML 페이지로 여기게 할 수 있다.

RewriteEngine on
RewriteRule ^(/pathtocgi/.*)\.html$ $1.cgi [T=application/x-httpd-cgi]

2.1.4. Negotiated Content의 캐시

HTTP/1.1 클라이언트들은 Content Negotiation을 통해 어떻게, 그리고 언제 이미 캐시된 문서들을 받을 수 있는가에 대한 정보를 알고 있다. 하지만 HTTP/1.0 프록시의 경우에는 이러한 정보를 알지 못하므로, 우리는 다음과 같이 그러한 경우에도 적용시킬 수 있다.

CacheNegotiateDocs

이 옵션은, 만일 우리가 다국어 지원 사이트를 사용하는 경우에는 예기치 않은 사이드 이펙트를 가져올 수 있는데, 클라이언트가 잘못된 페이지를 전송 받을 수 있기 때문이다. 따라서, 주의해서 사용해야 한다. HTTP/1.0 클라이언트의 수는 사실 매우 적을 뿐 아니라 계속 줄어들고 있기 때문에, 이 옵션 자체를 아예 무시할 수도 있다.

또한 Content Negotiation에서 고려해야 할 사항은 확장자가 없는 디렉터리 인덱스를 설정한 경우이다. 이런 경우에는, 설사 그런 파일을 사용하지 않는다 하더라도, 확장자가 포함된 모든 인덱스 파일들을 나열하는 것이 바람직하다.

DirectoryIndex index.html index.htm index.shtml index.cgi

만일 DirectoryIndex index 라고만 설정하게 되면, 아파치 서버는 MultiViews 옵션이 켜져 있을 때 다른 여러 인덱스 파일들을 사용할 수 있기 때문이다.

2.1.5. 로깅

디스크와 CPU 시간을 가장 많이 사용하는 것 중의 하나는 바로 로깅일 것이다. 만일 성능을 최대로 하고 싶다면 로그를 아무 것도 남기지 않으면 된다. 하지만 이는 좋은 방법이 아닌데, 오류 정보들까지도 남기지 않기 때문이다. 우리는 Access 로그를 남기지 않도록 설정할 수 있으며, 다음과 같이 로그 수준을 최소로 설정할 수도 있다.

LogLevel error

또 다른 접근 방법으로는 로그를 다른 서버에 남기도록 하는 것이 있을 수 있다. 웹 서버에서 접근 가능한 NFS 디렉터리나 시스템 로그 데몬을 통해 그렇게 할 수 있는데, 후자가 더 바람직하다. NFS는 성능이 좋지 않다고 알려져 있다. 또한 마운트된 디렉터리는 웹 서버의 모든 사용자들이 잠재적으로 접근할 수 있어서 보안 위험성이 있다.

2.1.6. 세션 추적 기능

어떤 종류의 세션 추적 기능이든 모두 시간을 소비하게 된다. 먼저, 아파치는 쿠키와 URL 요소들을 검사하고, 없어진 경우에는 설정을 해야 하며, 두번째로, 그런 유용한 추적 기능에 대해 어딘가에 로그를 남기게 되므로, 아파치에 추가적인 작업을 만드는 것이다.

중요한 것은, 절대 필요하지 않은 경우에는, mod_usertrack 모듈이나 mod_session 모듈을 아예 사용하지 않는 것이다. 사용한다 하더라도 Directory, Location, 또는 Files 과 같은 지시어들 내에 한정적으로 사용하는 것이다.

2.1.7. .htaccess 파일

AllowOverrideNone으로 설정되지 않은 경우에는, 아파치가 .htaccess 파일을 검사하게 된다. 아파치는 요청된 자원이 존재하는 각각의 모든 디렉터리들 (루트 디렉터리로부터 계층적 하위 디렉터리들 모두) 내에서 .htaccess 파일을 찾아 검사하게 된다. 이는 매우 시간을 소요하게 되는 것이므로, 다음과 같이 아파치가 URL 요청 시마다 매번 이 검사를 하지 않도록 하게 할 수 있다.

# AllowOverride is directory scope only, so we use the root directory
<Directory />
  AllowOverride None
</Directory>

.htaccess에 의한 설정은 서버를 보다 안전하게 보호할 수 있는 효과를 가져 올 수도 있다. 특정 위치에서 옵션을 오버라이드해야 하는 경우라 할지라도, 서버 수준의 설정에서 지시어를 사용하여 유사한 효과를 거둘 수 있다. 특정 디렉터리에서만 오버라이드하여 설정함으로써, 전체 경로들에 대해 검사하는 오버헤드를 막을 수 있다.

2.1.8. Extended Status

mod_status 모듈은 ExtendedStatus 지시어가 on 으로 설정된 경우, 확장된 상태 페이지를 생성해 준다. 하지만, 이는 아파치가 운영 체계 시스템에게 모든 클라이언트 요청 각각에 대해 시간 정보를 호출하도록 하기 때문에 성능을 저해할 수 있다.

시간 호출은 어떤 플랫폼에서든 매우 비싼 시스템 호출 중의 하나라고 볼 수 있다. 따라서 성능을 저해할 수 있으며, 가상 호스트 수준이 아니라, 서버 수준에 설정된 경우에 더욱 그러하다. 이 옵션을 활성화하지 않는 것이 바람직하다.

2.1.9. URL 재작성

mod_rewrite 모듈의 URL 재작성 기능을 사용하게 되면, 성능을 떨어뜨리게 된다. 특히 복잡한 재작성 규칙을 사용하는 경우에 더욱 그러하다. RewriteEngine 지시어는 디렉터리 별 또는 가상 호소트 별로 사용될 수 있어서, 규칙이 복잡하고 특정한 경우에만 적용해야 하는 경우 선택적으로 적용 가능하다.

또한, 어떤 규칙들은 내부적으로 HTTP 요청을 서버에 호출하도록 되어 있기 때문에 성능을 보다 더 떨어뜨릴 수 있다. [NS] 플래그 사용에 주의를 기울이고, -F-U 옵션을 사용하는 데에 주의를 기울여야 한다.

2.1.10. 사이즈가 큰 설정 파일

사이즈가 큰 설정 파일은 그 자체로 아파치를 굼뜨게 만들 수 있다. mod_rewrite 모듈과 같은 것들은 설정 파일의 라인 개수를 줄임으로써 성능 상의 효과를 볼 수 있다. mod_vhost_alias 모듈은 대규모의 가상 호스트들을 관리할 때에 유용하다.

2.1.11. CGI 성능 튜닝

CGI 스크립트로 사용되는 스크립트나 애플리케이션은 미리 성능을 고려하여 작성되어야 한다. 너무 많은 메모리나 CPU 시간을 사용하지 않아야 하며, 가능한 한 빨리 출력을 생성해야 하고, 가능한 한 결과를 캐시할 수 있어야 한다.

아울러 아파치는 다음과 같은 CGI 관련 지시어들을 제공한다.

  • RLimitCPU: CPU 시간을 얼마나 사용할 수 있는지를 제어

  • RLimitMEM: 메모리를 얼마나 할당할 수 있는지를 제어

  • RLimitNPROC: 얼마나 많은 CGI 인스턴스들이 동시에 수행될 수 있는지를 제어

아파치 2.0 서버에서는, mod_cgid 모듈에 의해 확립되는 CGI 데몬에 의해 생성되는 Listen 큐의 크기를, 컴파일 시에 CFLAGS 변수를 -DDEFAULT_CGID_LISTENBACKLOG=<queue size> 와 같이 제공함으로써 설정 가능하다. 기본 크기는 100이다.

2.2. 기타 성능 튜닝 지시어들

표준 아파치 실행 모듈의 기능은 아니지만, 아파치 및 써드파티 모듈들에는 몇 가지 서버 성능을 다양한 방식으로 향상시킬 수 있는 방법들이 포함되어 있다. 여기서는 mod_file_cache (예전에는 mod_mmap_static) 모듈과 mod_bandwidth 모듈을 다루기로 한다.

2.2.1. 캐싱 및 메모리맵

오늘날 웹 서버들이 제공하는 컨텐트들은 대부분 동적 컨텐트들인 경우가 많다. 그럼에도 불구하고, 여전히 정적인 컨텐트들에 대해 캐시를 사용하는 것은 성능을 매우 향상시킨다. 정적 컨텐트들을 캐시로부터 서비스하게 되면, 해당 컨텐트를 디스크로부터 두번 이상 읽을 필요가 없게 된다. 이는 해당 파일을 읽는 것만을 넘기는 것 뿐만 아니라, 디스크에 있는 파일들에 대한 다른 여러 가지 검사 작업이나 위치를 찾아내는 작업들이 그대로 넘겨질 수 있게 되는 것이다.

좀 더 생각해 보면, 동적인 웹 사이트에서 정적 구성 요소들을 여러 개의 분리된 파일들로 나눔으로써, 성능을 최적화 하는 것도 가능하다.

예를 들면, 웹 사이트의 상단 및 좌측 탐색 영역은 클라이언트 사이드에서 자바 스크립트를 사용하여 컨텐트를 변경할 수 있도록 변경할 수 있다. 실제 자바 스크립트는 정적일 것이다. mod_include모듈을 사용하는 기법을 쓰면, 이러한 정적 구성요소들과 다른 동적 구성요소들을 사용하여, 동적 컨텐트를 생성하는 효율성을 높일 수 있다. 대부분의 템플릿 기반 웹 서버 프레임워크들은 대부분이 정적 컨텐트인 프리젠테이션을 실제 동적인 컨텐트와 분리할 수 있게 함으로써, 이러한 목표를 달성하는 데에 도움을 주곤 한다.

우리는 정적 컨텐트들을 보다 효율적으로 다룰 수 있는 다음과 같은 네 가지 접근 방법을 가지고 있다.

  • 메모리 맵 파일을 공유 메모리에서 영속적인 상태로 두는 방법

    파일을 공유 메모리에 두게 되면, 모든 아파치 프로세스들로부터 접근 가능하다. 하지만, 프로세스에서 시스템 메모리를 소모하게 된다. 메모리와 처리 능력 간에 트레이드 오프를 해야 한다. 물리 메모리가 풍부한 웹 서버에서는 좋은 아이디어가 될 수 있다. 하지만 가상 메모리를 사용해야 하는 웹 서버에서는 물리 메모리가 충분하지 않기 때문에 이 방법을 사용하는 것은 좋지 않다. 이 기능은 mod_mmap_static (아파치 1.3) 모듈이나 mod_file_cache (아파치 2.0) 모듈의 MMapFile 지시어를 사용하여 설정하면 된다.

  • 파일 핸들을 하나 열고 유지하고, 그 파일이 디스크에서 영속적으로 사용 가능하도록 하는 방법

    이 방법은 파일을 메모리에 유지하지 않고, 파일 핸들이 열려진 상태로 유지하여, 즉각적으로 읽혀지고 클라이언트에 전달할 수 있는 방법으로 메모리 매핑의 한 변형이다. 아파치는 그 스스로 파일을 보내지는 않고, 파일 핸들을 운영체계에 전달하게 되면, 운영 체계는 해당 파일을 최적화된 방법으로 전송하게 된다. 대부분의 현대적 유닉스 시스템들에서는, sendfile 시스템 호출에 의해 가능하다. 캐시된 파일에 대해 파일 핸들이 하나씩 필요한 방법이다. 이는 커널 상에서 단일 프로세스 당 가용한 파일 핸들의 개수로 인해 문제가 발생할 수 있다. (커널의 제한 값은 변경될 수 있긴 하지만, 무한대로 증가시킬 수는 없다.)

  • 아파치 앞에 프록시를 두고, HTTP/1.1 캐시 헤더를 사용하여 캐시하도록 알려 주는 방법

    만일 정적 컨텐트의 전체 페이지들을 전송해야 하는 경우라면, 우리는 단지 mod_expiresmod_header 모듈을 사용하여 프록시가 해당 문서를 대신 캐시해 주도록 알려 줄 수 있다. 외부 프록시 서버가 없는 경우에는, 아파치를 하나 더 추가하여 프록시로 설정할 수 있다. Squid와 같은 전용 프록시 서버도 또한 사용될 수 있다. 하지만, 서버에서 부분적으로 정적 페이지들을 제공해야 하는 경우에는 이러한 옵션은 효과를 발휘할 수 없다.

  • 아파치를 정적 컨텐트를 효율적으로 서비스할 수 있는 다른 웹 서버와 함께 운영하는 방법

    약간 당황스럽게 들릴 수도 있겠지만, 어떤 상황에서는 아파치보다 성능이 좋은 다른 웹 서버가 존재할 수 있다. 아파치의 강력한 특징은 잘 모듈화되어 있다는 점과 동적 컨텐트들을 처리하는 효율성이다. 순수하게 정적인 컨텐트들을 위해서라면, 그런 목적의 효율성 높은 웹 서버들이 존재하는데, 다음과 같은 것들이다.

위와 같은 서버들을 프록시로서 아파치 서버 앞에 두거나 아파치와 정적 컨텐트들을 위한 웹 서버를 스위칭하는 로드밸런스 기능의 노드를 앞에 두거나할 수 있다. 이를 위해서는 정적 컨텐트와 동적 컨텐트를 URL로부터 판단할 수 있는 신뢰성 있는 방법이 필요하다. 가장 쉽게 구별할 수 있는 유형의 컨텐트는 이미지 파일들이다. 이들은 파일 확장자 이름에 따라 쉽게 구별된다. 만약 가능하다면, 두번째 웹서버를 별도의 물리적 하드웨어 박스에 두는 것도 보다 좋은 방법이 될 수 있다.

2.2.1.1. 메모리맵 파일

메모리 맵 파일은 MMapFile 지시어에 의해 설정되며, 이는 아파치 1.3에서는 mod_mmap_static 모듈에 의해, 아파치 2.0에서는 mod_file_cache 모듈에 의해 제공되는데, 어느 경우든 동일한 방식으로 적용 가능하다. 두 모듈은 각 아파치 버전에서 표준적으로 제공되긴 하나, 기본 옵션으로 함께 컴파일되어 활성화되지는 않는다. 주의할 점은 mod_file_cache 모듈은 아파치 2.0의 mod_cache 계열 모듈들과는 아무런 관련이 없다는 것이다. 아파치 2.0의 mod_cache 계열 모듈들은 아파치 2.0의 프록시 캐시 기능을 구현한 것들이다. 이에 대해서는 뒷 부분에 다루게 된다.

메모리 맵 파일들은 운영체계가 파일을 영속적으로 메모리에 저장할 수 있도록 제공하는 캐시 메커니즘이다. 메모리에 파일들을 저장함으로써, 아파치는 디스크로부터 읽어들이지 않고도, 그 파일들을 클라이언트에 신속하게 전달할 수 있다. 일례로, 인덱스 페이지와 배너 로고를 메모리 맵 파일에 두려면 다음과 같이 설정할 수 있다.

MMapFile /home/www/alpha-complex/index.html /home/www/alpha-complex/banner.gif

위 설정은 오직 정적 파일에 대해서만 캐시 처리를 하게 된다. 동적으로 생성되는 컨텐트나 CGI 스크립트들은 MMapFile 지시어로 설정할 수 없다. CGI 스크립트를 캐시하려면, FastCGI 모듈이나 mod_perl과 펄 스크립트를 위한 Apache::Registry를 사용해야 한다.

MMapFile은 문법 측면에서 융통성이 크지 않으며, 와일드카드들을 지원하지 않는다. MMapDirectory와 같은 형태의 지시어는 지원되지 않아 한번에 여러 파일들을 설정할 수 없다. 만일 전체 디렉터리들을 메모리 맵에 넣으려면, 파일들의 목록을 생성하여, 여러 라인의 MMapFile 지시어를 포함시켜야 한다. 다음은 그 예이다.

$ ls -1 /home/www/alpha-complex/*.html | perl -ne 'print "MMapFile $_"' > /usr/local/apache/conf/ac-cache.conf

위의 명령은 서버 루트 아래에 있는 모든 HTML 문서들을 캐시하게끔 유도한다. 위에서 생성된 파일을 Include 지시어를 사용하여 아파치 설정 파일에서 포함하면 된다. mod_file_cache 모듈을 사용한 좀 더 다른 솔루션은 해당 모듈의 매뉴얼 페이지를 참조하기 바란다.

주목해야 할 점은, 파일이 한번 매핑되고 나면, 그 파일이 변경된다 할지라도 그 파일은 다시 디스크로부터 읽혀지지 않는다는 것이다. 만약 특정 파일의 변경 상태를 반영 시키려면, 물리적으로 해당 파일을 삭제하고, 별도의 새 파일로 대체하거나 아파치를 재시작해야 한다. 이렇게 하지 않으면, 클라이언트 예전 컨텐트를 서비스 받는 문제가 발생하게 된다.

2.2.1.2. 캐시 파일

캐시 파일들은 오직 아파치 2.0의 mod_file_cache 모듈을 통해서만 사용 가능하다. 파일을 메모리에 캐시하는 대신에, 파일 핸들을 열려진 상태로 서버가 계속 유지하는 방식이다. 파일이 요청되면, 해당 핸들은 운영체계에 전달되고, sendfile 시스템 호출에 의해 전송된다. 이는 일반적으로 파일을 전송하는 데에 매우 빠른 방법인데, 이는 운영체계가, 사용자 공간이 아닌, 커널 수준 오퍼레이션으로서 복사를 수행하기 때문이다.

이 방식에서 '캐시된 파일'이라는 용어는 이런 관점에서 잘못된 용어일 수 있다. 즉, 사실 캐시된 것은 파일이 아니라, 파일에 대한 핸들을 캐시하는 것이다. 물론 만일 해당 파일이 최근에 읽혀졌고, 여전히 하드웨어나 파일 시스템에 의해 버퍼링되어 있는 경우도 있긴 하다. sendfile의 장점은, 이러한 모든 과정이 자동으로 처리되어 상세한 내용을 우리가 신경쓸 필요가 없다는 것이다.

파일을 캐시하기 위해서는 CacheFile 지시어를 사용해야 한다. MMapFile와 거의 유사한 방식으로 설정하지만, 그 결과는 다르다. 캐시하려고 하는 각 파일들에 대하여, 아파치는 읽기 전용 파일 핸들을 열어 유지하게 된다. 그리고 그 파일 요청이 왔을 때에, 그 파일 핸들을 운영체계에 전달한다. 다음은 설정 예제이다.

CacheFile /home/www/alpha-complex/index.html /home/www/alpha-complex/banner.gif

메모리 맵 파일 사용 예와 같이 이 방식도 동일한 제약사항들을 가지고 있다. 즉 파일의 변경 사항이 발생했을 때, 아파치가 그것을 알도록 할 수 없다는 점이다. 대신에, 우리는 그 파일을 삭제하고 다른 파일로 대체하거나, 아파치를 재시작함으로써 그런 목적을 달성할 수 있다. 이런 제약사항이 존재하는 이유는, 파일의 변경 상태를 검사하기 위해서는 파일 시스템 접근이 필요하게 되고, 이렇게 되면 애초의 캐시 목적과는 상충되기 때문이다.

2.2.2. 대역폭의 제한

mod_bandwidth 모듈은 아파치 미러 사이트에서 구할 수 있다. 또한 현재 버전은 http://www.cohprog.com/ 사이트에서 구할 수 있다. 이 모듈은 아파치 1.3 유닉스 서버에서 적용 가능하며, 아파치 2.0은 앞으로 지원될 예정이다. 이 모듈은 아파치가 원격 클라이언트의 도메인 주소 또는 IP 주소에 따라 1초 당 전송받는 데이터의 양이나 요청된 파일의 크기를 제한할 수 있게 한다.

또한 접속되는 클라이언트의 수에 따라 나누어 대역폭 제한을 설정할 수도 있다. 이는 이론적으로 모든 클라이언트들을 서비스할 수 있을 정도로 충분한 대역폭을 가지고 있지 않은 상황에서 클라이언트 연결들을 관리할 수 있는 수단을 제공하기도 한다. 대역폭의 제한은 디렉터리 별 또는 가상 호스트 별, 또는 이 두 가지를 혼용하여 설정할 수 있다. 예를 들어, 웹 사이트에서 안전성을 고려할 필요가 없는 부분들에 대해서는 대역폭을 제한 설정하고, 안전성이 고려되어야 하는 온라인 주문 시스템은 모든 대역폭을 항상 활용할 수 있도록 설정할 수 있다.

mod_bandwidth 모듈은 표준 배포 모듈에서 활성화되지 않으므로, 서버를 재빌드하거나, 별도 모듈을 배치함으로써 사용 가능하다. 설치되면, 대역폭 제한은 다음과 같이 활성화된다.

BandWidthModule on

가상 호스트 컨테이너들은 이 지시어를 상속받지 않는다. 반면 디렉터리 컨테이너들은 이 지시어를 상속받는다. 각 가상 호스트에 대역폭 제한을 설정하려면, 각 가상 호스트 컨테이너에 대역폭 제한을 따로 설정해야 한다.

대역폭의 결정은 단 한번 정확하게 수행되기 때문에, 다른 모듈들이 먼저 요청을 처리할 기회를 갖지 않도록 mod_bandwidth 모듈이 다른 모든 모듈들 보다 먼저 로드되어야 한다.

아파치 1.3에서는, mod_bandwidth 모듈에 대한 LoadModuleAddModule 지시어가 다른 것들 보다 먼저 나와야 한다는 것을 의미한다. configure 를 사용한다면, --permute-module=BEGIN:bandwidth가 추가되면 된다. 그렇게 하지 않은 경우는 httpd.conf 파일을 편집해야 한다.

TODO: 아파치 2.0에서 사용 가능하게 되면 아래 상세 내역 기술할 것.

2.2.2.1. 디렉터리 설정

mod_bandwidth 모듈이 동작하려면, 파일 시스템의 특정 공간에 임시 파일들을 저장할 수 있도록 설정해야 한다. 기본적으로 이 디렉터리는 /tmp/apachebw로 설정된다. 하지만, 이는 설정 파일에서 BandWidthDataDir 지시어를 통해 다음과 같이 변경할 수 있다.

BandWidthDataDir /var/run/apache/bandwidth

이 디렉터리는 미리 생성되어 있어야 하며 아파치에 의해 작성 권한이 있어야 한다. 또한 master 디렉터리와 link 디렉터리가 이 디렉터리 내에 하위 디렉터리로 생성되어 있어야 한다. 만일 link 디렉터리 내에 죽은 링크인 경우에는 (즉, 링크 대상이 옮겨졌거나 삭제된 컨텐트인 경우에는), 아파치가 재시작될 때, 이 모듈이 정상 동작하지 않을 수 있다. mod_bandwidth 모듈과 함께 제공되는 cleanlink.pl 스크립트는 이를 자동으로 처리해 주는데, apachectl 스크립트를 수정하여 이 스크립트를 호출하도록 하면 좋다.

2.2.2.2. 클라이언트에 따른 대역폭 제한

대역폭 제한 설정은 다음과 같이 설정될 수 있다.

<Directory />
  BandWidth localhost 0
  BandWidth friendly.com 4096
  BandWidth 192.168 512
  BandWidth all 2048
</Directory>
                                        

위 설정은, 값을 0으로 설정함으로써, 아파치가 로컬 요청들을 제한하지 않도록 한다. (CGI 스크립트에 의한 내부 호출 등과 같은 경우.) 그리고 내부 네트워크 클라이언트들은 초당 512 바이트로 제한하며, 선호되는 도메인은 초당 4Kb까지 허용한다. 기타 나머지(all 키워드)는 2Kb까지 허용된다. 이 순서는 중요하다. 가장 먼저 일치하는 패턴이 적용된다.

2.2.2.3. 파일 크기에 따른 대역폭 제한

대역폭 제한은 LargeFileLimit 지시어를 사용하여 파일 크기에 따라 설정될 수 있다. 이렇게 함으로써, 크기가 큰 파일들은 작은 파일들에 비해 보다 더 점차적으로 전송될 수 있게 할 수 있다. 크기가 큰 파일이 보통의 작은 정적 페이지와 동일한 방식으로 전송되어 문제가 되는 경우에 이러한 설정은 큰 가치를 줄 수 있다. LargeFileLimitBandWidth 지시어가 동일한 URL에 적용되는 경우에는, 그 둘 중에 가장 작은 것이 선택된다.

LargeFileLimit 지시어는 두 개의 매개변수를 취한다. 하나는 킬로바이트 단위의 파일 크기이고, 다른 하나는 전송률이다. 예는 다음과 같다.

<Directory /home/www/alpha-complex>
  LargeFileLimit 50   8092
  LargeFileLimit 1024 4096
  LargeFileLimit 2048 2048
</Directory>
                                        

위 설정은 50Kb 보다 작은 파일들은 대역폭 제한을 하지 않도록 한다. 그리고 50Kb 이상 1Mb 미만의 파일은 초당 4Kb로 제한하며, 2Mb 이상의 파일들은 초당 2Kb로 제한한다.

BandWidth 지시어와 마찬가지로 순서가 중요한데, 그 순서에 따라 처음 일치하는 패턴이 발견되었을 때, 그 제한 설정을 취하게 되므로, 반드시 위 지시어들은, 파일 크기가 작은 것에서 큰 것으로 순서를 유지하여 설정해야 한다.

복수의 클라이언트들이 동시에 접속하는 경우에는, mod_bandwidth 모듈은 또한 각 클라이언트 별로 사용 가능한 대역폭을 비율로 계산하여 할당한다. 만일 열 개의 클라이언트가 전체 대역폭 제한 값 초 당 4096 바이트로 설정된 곳에 동시에 접속하는 경우, 각 클라이언트는 초 당 410 바이트를 할당 받는다. 주의할 점은, 예를 들어, 비디오 자료 웹 사이트와 같은 곳에서는, 이 값을 너무 작게 설정하면 사용자의 경험에 큰 타격을 줄 수 있다는 것이다.

2.2.2.4. 최소 대역폭과 클라이언트들 간의 대역폭 분할

대역폭은 mod_bandwidth 모듈에 의해, 개별 클라이언트 대역폭 설정에 기반하여, 클라이언트들 간에 공유된다. 따라서, 두 클라이언트 모두 초 당 4Kb라는 대역폭 제한을 가지고 있는 경우에, mod_bandwidth 모듈은 이를 나누어, 각 클라이언트에게 초 당 2Kb라는 대역폭을 선사한다. 하지만, 할당된 대역폭은 MinBandWidth로 설정 가능한 최소 대역폭 이하로 떨어지지는 않게 된다. 이의 기본 값은 초 당 256 바이트이다.

MinBandWidth 256

MinBandWidth는 첫번째 매개변수로 도메인 이름이나 IP 주소를 취하는데, 이는 BandWidth 지시어와 동일하다. BandWidth와 마찬가지로 순서에 따라 적용된다.

<Directory />
  BandWidth    localhost 0
  BandWidth    friendly.com 4096
  MinBandWidth friendly.com 2096
  BandWidth    192.168 512
  BandWidth    all 2048
  MinBandWidth all 512
</Directory>
                                        

한편, 클라이언트 별 대역폭 할당은, 설정 값을 -1로 설정하게 되면, 클라이언트 별 대역폭 할당 기능을 완전히 비활성화시킬 수 있다. 이렇게 하게 되면, 설정된 값이 그대로 사용되어 각 클라이언트에 할당되며, 전체를 비율에 의해 재계산되어 할당되지 않게 된다. 아래 예와 같다.

MinBandWidth all -1

위와 같이 설정하는 경우, 만일 열 개의 클라이언트가 초 당 4096 바이트의 대역폭 제한으로 접속하는 경우에, mod_bandwidth 모듈은 모든 각각의 클라이언트들에게 초 당 4096 바이트의 대역폭을 선사하게 된다.

2.2.2.5. 전송 알고리즘

mod_bandwidth 모듈은 두 개의 다른 알고리즘에 의해 클라이언트에게 데이터를 전송할 수 있다. 보통은 데이터들을 1Kb 짜리 패킷들로 나눈 다음 그것들을 대역폭이 허용할 때에 전송하게 된다. 만일 가용한 대역폭이 겨우 512 바이트에 불과한 경우에는, 1Kb 짜리 패킷은 대략 2초 간격으로 보내진다.

이에 대한 다른 대안은 BandWidthPulse 지시어를 사용하는 것인데, 이 지시어는 마이크로 초(microseconds)를 매개변수로 취한다. 이 지시어가 활성화된 경우, mod_bandwidth 모듈은 패킷의 크기와 상관 없이 설정된 각 주기마다 패킷을 보내게 된다. 예를 들면, 다음과 같이 초 당 주기율을 설정할 수 있다.

BandWidthPulse 1000000

위의 설정은 클라이언트가 초 당 512 바이트의 대역폭을 할당 받은 경우, 512 바이트 짜리 패킷 하나가 초 당 한 번 전송되게 한다. 이 설정의 장점은, 부하가 매우 많고 패킷 간의 시간 차가 클 때에, 보다 부드러운 방식의 통신을 가능하게 한다는 것이다. 반면 단점은, 실제 데이터에 대한 전송 보다 네트워크 연결에 대한 대역폭이 상대적으로 커진다는 점이다.

3. 아파치 서버 성능 벤치마킹

아파치 서버 성능을 개선할 수 있도록 설정하는 것은 훌륭한 것이지만, 그러한 노력이 어떻게 서버 성능에 영향을 주었는지에 대한 증거가 없이는 설정의 변경이 유용한 결과를 가져 왔는지 알 도리가 없다. 어떤 경우는 성능을 개선하려고 한 설정의 변경이 오히려 더 성능을 떨어뜨리는 결과를 가져 오기도 한다.

확실하게 상황을 파악하기 위해, 우리는 서버 성능을 벤치마크할 수 있으며 통계를 산출할 수 있다. 아파치는 ab 유틸리티를 제공하여 이러한 목적을 달성할 수 있도록 한다. 이외에도 다른 외부 벤치마킹 서비스들을 활용하는 것에 대해서도 살펴 보기로 한다.

3.1. ab를 활용한 아파치 벤치마킹

아파치는 자체적으로 ab라는 벤치마크 도구를 제공한다. 이 도구는 단순한 HTTP 클라이언트로서, 우리가 정한 특정 기준들에 따라 대상 서버에 반복된 요청을 보낸다. 이런 관점에서 ab 도구는 ping이나 spray와 같은 스타일의 도구를 HTTP를 위해 만든 것이라고 볼 수 있다. 이 도구는 어떤 웹 서버라도 쉽게 벤치마크할 수 있으므로, 벤치마크 비교 테스트에서 이 도구를 사용할 수 있다.

이 도구는 많은 옵션들을 제공하지만, 기본적으로 ab 도구 사용 방법은 슬래시로 끝나는 호스트 이름만으로도 바로 사용할 수 있다. 끝에 슬래시를 붙이지 않으면, 경고 메시지를 출력한다.

$ ./ab www.alphacomplex.com/

또한 다음 명령 수행도 위의 결과와 동일하다.

$ ./ab http://www.alphacomplex.com:80/

위와 같이 수행하게 되면, 대상 서버에 포트 번호 80번으로 한 번의 요청을 수행하게 될 것이다. 이는 대상 서버가 접근 가능한지를 확인할 수 있는 간단한 방법이 될 수도 있을 것이다. 하지만, 통계적으로는 별 의미가 없다. 다음과 같이 -n 옵션을 지정하여 요청 회수를 지시할 수 있다.

$ ./ab -n 1000 www.alphacomplex.com/

위 명령은 대상 서버로 1000번의 요청을 한번에 하나씩 보내게 될 것이다. 동시에 복수의 요청들을 보내 서버가 얼마나 견뎌내는지를 알고 싶다면, -c 옵션을 사용할 수 있다. 아래 명령은 동시에 10개의 요청들을 보내게 된다.

$ ./ab -n 1000 -c 10 www.alphacomplex.com/

ab는 매 100개의 요청 시마다의 진척 상황을 출력해 줄 것이다. 요청이 모두 종료되면, 시간에 따른 누적 요청 비율을 보여주는 표를 출력한다.

기본적으로 abGET 요청을 사용하며, 사람이 읽을 수 있는 형태의 공백으로 구별된 표를 출력하는데, 이 두 가지는 모두 옵션으로 변경할 수 있다. 또한 쿠키, 인증, 그리고 프록시 우회와 같은 옵션들도 설정할 수 있다. 전체적으로 ab는 22개의 옵션들을 제공하는데, 이들에 대해 아래에서 설명한다.

3.1.1. 사용법 옵션

아래 옵션들은 ab에 대한 정보를 출력하며 테스트를 수행하지는 않는다.

Table 8. 사용법 옵션

옵션 의미
-h ab 도움말 표시
-V ab의 버전 출력

3.1.2. 연결 옵션

이 연결 옵션들은 ab가 어떻게 요청을 생성할 것인지를 결정한다.

Table 9. 연결 옵션

옵션 의미
-c requests 한번에 동시에 연결 및 관리해야 하는 요청의 개수
-n response 전체 요청의 개수
-t seconds 하나의 요청이 완료되기까지 대기하는 최대 시간
-k HTTP/1.1의 KeepAlive 연결을 사용

-c 옵션과 -k 옵션의 선택은 통계를 산출하는 데에 있어서 큰 차이를 가져온다. 즉, 개별 요청을 잘 처리하던 서버가 한번에 스무 개의 요청을 처리할 때에는 끔찍한 결과를 가져오는 경우가 있다. 잘못 작성된 CGI 애플리케이션 같은 것들이 이런 현상을 보일 수 있다. KeepAlive 옵션을 사용하면 ab가 연결을 유지하여, 매번 요청이 완료될 때마다 연결을 끊지 않고, 복수의 요청에서 계속 사용하게 된다.

3.1.3. 인증 및 프록시 옵션

인증 및 프록시 옵션은 인증과 프록시 설정을 가능하게 한다.

Table 10. 인증 및 프록시 옵션

옵션 의미
-A user:password 제공된 인증 유형을 사용하여 Authorization 헤더를 보냄
-X host:port host:port로 프록시를 사용함.
-P user:password (-X 옵션이 함께 사용되는 경우에만) Proxy-Authorization 헤더를 보냄.

쿠키 기반 인증을 사용하려면 -C/-H 옵션을 대신 사용해야 한다. 세션 쿠키를 사용하는 사이트를 벤치마크하려면, -v 4 옵션을 사용하여 연속적인 벤치마크에서 하나의 세션 쿠키를 사용할 수 있도록 한다.

Note

셸 스크립트나 펄 스크립트를 사용하여 Cookie 또는 Cookie2 헤더의 값을 추출하게 할 수도 있으며, 그것을 이어지는 ab 명령에 계속해서 전달할 수 있다. ab는 서버로부터 전달된 쿠키를 저장하거나 반환하지 않는다.

3.1.4. 요청 방법, 헤더, 바디 옵션

이 옵션들은 요청의 내용을 결정한다.

Table 11. 요청 방법, 헤더, 바디 옵션

옵션 의미
-C cookie 제공된 값으로 Set-Cookie 헤더를 보냄
-H header:value 제공된 값으로 임의의 헤더를 보냄
-i GET이 아니라 HEAD 요청을 보냄
-p file GET이 아니라, 제공된 파일을 사용하여 POST 요청을 보냄
-T mime/type POST 요청일 때 미디어 타입을 설정

쿠키에 대해서는, 설정 값이 서버가 받아들일 수 있는 스타일의 쿠키로 설정되어야 한다. 예를 들면 다음과 같다.

-C "Troubleshooter=Roy-G-BIV; path=/; expires=Fri, 01-Aug-03 09:05:02 GMT; domain=.alpha-complex.com"

주목할 점은 ab는 지정되지 않은 경우 경로나 도메인을 추론하지 않는다는 점이다. 즉, ab는 오직 우리가 지정한 것만을 전송한다. 전체 쿠키는 공백과 세미콜론을 포함하므로, 쌍따옴표로 둘러싸여야 한다. 기본적인 쿠키 값들은 아래와 같이 쌍따옴표를 생략할 수도 있다.

-C Troubleshooter=Roy-G-BIV

위는 아래와 동일하다.

-H "Set-Cookie: Troubleshooter=Roy-G-BIV"

가능한 쿠키 포맷에 대한 상세 내역에 대해서는, mod_userattack 모듈의 CookieStyle 지시어에 대한 설명과 옵션들에 대해 참조해 보기 바란다. 또한 우리는 Set-Cookie2 헤더를 전송할 수도 있는데, 이 때에는 -C 옵션보다는 -H 옵션을 사용하여야만 한다. 즉, -C 옵션은 오직 Set-Cookie 헤더만을 전송한다.

-C 옵션과 -H 옵션은 -i 옵션이나 -p 옵션을 사용할 수 있다. 하지만, -i 옵션과 -p 옵션은 상호 배타적이다. -T 옵션은 오직 -p 옵션이 설정된 경우에만 의미가 있다. 왜냐하면 Content-Type 요청 헤더가 오직 바디를 포함한 경우에만 적용 가능하기 때문이다. 이 헤더는 GET이나 HEAD 요청에서는 적용할 수 없다.

-v 옵션은 Verbosity 수준을 증가시키기 위해 사용할 수 있으며, 이를 통해 실제 요청된 내역을 확인할 수 있다. 이는 요청이 우리가 의도한 바대로 전송되는지를 확인할 수 있는 좋은 수단이 된다. -n 옵션이 생략되어야만, 단일 요청만으로 이런 확인 작업을 보다 용이하게 할 수 있을 것이다.

3.1.5. 통계 옵션

이 옵션들은 계산되고 출력되는 통계 관련 옵션들을 지정한다.

Table 12. 통계 옵션

옵션 의미
-d 누적 비율 대 시간표의 보고서 생성
-S mean 대신에 avg 컬럼을 생성하며, 연결 회수 표에서 표준편차(sd)를 생성

3.1.6. 출력 옵션

이 옵션들은 ab가 무엇을 출력하고 어떤 포맷으로 생성할 것인가를 지정한다.

Table 13. 출력 옵션

옵션 의미
-e csvfile 부가적으로 csvfile 파일에 CSV 포맷으로 비율 통계를 기록
-g gnuplotfile 부가적으로 gnuplotfile 파일에 GNUPlot 포맷의 누적 통계를 기록
-w 통계를 일반 텍스트 파일이 아닌 HTML 표 포맷으로 출력
-x table_attrs HTML 테이블 출력일 때 표의 속성들을 설정
-y tr_attrs HTML 테이블 출력일 때 표의 행에 대한 속성들을 설정
-v verbosity Verbosity 수준 설정

ab는 네 가지의 서로 다른 포맷으로 출력할 수 있다. -e 옵션은 완전한 누적 비율 표를 작성하는데, 모든 퍼센트 포인트를 기록한다.

-g 옵션은 GNUPlot 파일을 생성하며, 이 파일에는 각 개별 요청의 시작 시간과 성능 통계들을 포함한다. 다음은 그 예이다.

starttime   seconds ctime   dtime   ttime   wait
Fri Aug 1 04:07:54      200     1014713074914875        0       26      26      0
Fri Aug 1 04:07:54      200     1014713074942100        0       27      27      0
Fri Aug 1 04:07:54      200     1014713074969613        0       26      26      0
                                

이 파일은 GNUPlot 파일을 인식할 수 있는 어떤 애플리케이션에서도 사용될 수 있다. 또한 고정 길이 포맷을 인식할 수 있는 스프레드 시트 프로그램에서도 로드할 수 있을 것이다.

-w 옵션은 일반 텍스트 파일이 아니라, HTML 파일로 출력하게 한다. 또한 -x 옵션, -y 옵션, 그리고 -z 옵션은 표의 모양새를 지정한다. 다음은 그 예이다.

$ ./ab -n 1000 -w -x "cellspacing=2 cellpadding=1 bgcolor=black border=0" -y "valign=top" -z "bgcolor=white"

위의 명령은 다음과 같은 스타일의 HTML을 생성한다.

    <table cellspacing=2 cellpadding=1 bgcolor=black>
      <tr valign=top>
        <td bgcolor=white>
                                

-w 옵션을 사용하게 되면, 현재로서는, -e 옵션과 -g 옵션을 통해 파일을 생성하는 기능을 꺼버리게 된다. 이는 조만간 변경될 것이다.

Verbosity 수준은 1부터 4까지 설정할 수 있으며, 0으로 설정하게 되면, 1로 설정한 것과 동일하게 취급된다. 그리고 4보다 큰 값을 설정하게 되면, 4로 설정한 것과 동일하게 취급된다. Verbosity 수준은 다음과 같다.

Table 14. Verbosity 수준

수준 설명
1 일반적인 통계 출력. 개별 요청 별로 출력하지 않음.
2 전송된 요청들을 출력
3 요청들을 출력하되, LOG: 행들을 추가
4 요청과 응답을 출력

주의

Verbosity 수준이 높을 수록 ab의 성능은 떨어지게 되며, 결과에도 영향을 끼치게 된다. 하지만, 단일 요청을 테스트할 때에 Verbosity 수준을 4로 설정하는 것은 벤치마크 테스트 자체에 대한 중요하고 정확한 정보를 얻는데 매우 유용한 것이다.

3.2. 외부 벤치마킹 도구

많이 사용되는 벤치마크 도구들로는 다음과 같은 것들이 있다.

  • httpperf

    단일 파일에 대한 단순한 요청 테스트라든가 클라이언트 세션들을 시뮬레이션해 보는 데에 매우 유용한 도구임.

  • Apache Bench

    단순한 벤치마크 도구로서, 현재 설치된 아파치 서버에 대한 성능을 측정해 보는 데에 좋은 정보를 제공한다.

3.3. 벤치마킹 전략

ab나 외부 벤치마크 서비스를 사용하여 몇 개의 대표 URL들을 테스트하여 필요한 벤치마크 정보를 얻을 수 있다고 생각하는 것은 매우 쉽게 떠올릴 수 있는 것이다. 하지만 불행히도, 이러한 것은 실제 경우와는 많이 다르다. 다음과 같은 이유에서다.

  • 우리가 대표 URL들이라고 생각한 것들이 실제로는 아닌 경우들이 있다.

  • CGI나 서버 사이드 애플리케이션에 전달되는 매개변수들이 변하게 되면, 그에 따라 실제 성능이 크게 좌우되는 경우들이 있다.

  • 어디서 테스트했는가에 따라 서로 다른 결과를 얻기도 한다. 또 네트워크 환경에 의존하기도 한다.

  • 실제 운영 서버를 벤치마크하게 되면 완전히 다른 결과를 가져오기도 한다.

  • 한번에 단 하나의 URL을 테스트하는 것은 실제 사용 패턴을 대표할 수 없는 경우가 많다.

마지막 경우는 좀더 설명될 필요가 있는데, ab와 같은 도구는 한번에 오직 하나의 URL만을 테스트할 수 있다. 그 URL이 우리가 테스트하고자 하는 JSP나 EJB 애플리케이션인 경우에, 여러 동시 연결 테스트를 수행하더라도, 꽤 만족스러운 결과를 얻을 수도 있다. 하지만 이는 잘못된 판단으로 판명되는 경우가 있다.

만일 우리가 동시에 여러 개의 ab 인스턴스를 동작시키게 되면, 동일한 애플리케이션에 대해서도 완전히 다른 결과를 얻을 수도 있다. 서버가 매우 느려질 수 있는 것이다. 이러한 이유는 많은 것들이 존재하지만, 전형적인 이유 중의 하나는 대규모 애플리케이션의 각 부분이 데이터베이스 연결을 필요로 하고, 각각 자원들을 필요로 하며, 또 각각 로깅 기능 등등이 필요하기 때문이다. 각 기능들을 한번에 하나씩 테스트하게 되면 서버를 전체적으로 한번 사용하는 것이기는 하다.

하지만, 그 기능들을 한번에 전체적으로 동시에 테스트하게 되면, 갑자기 메모리가 충분치 않아질 수도 있고, 데이터베이스가 열려진 연결의 최대치를 초과해 버릴 수도 있는 것이다.

결론적으로, 우리는 우리 서버에 대해 어떻게 벤치마크해야 할 것인가에 대해 더 계획을 세워야 한다는 것이다. 단순히 URL에 대해 ab 도구를 사용하여 단순한 테스트 결과를 얻는 것은 전체를 대표하지 못하며, 통계가 우리를 잘못된 판단으로 이끌 수 있는 것이다.

4. 성능 체크리스트

아래는 시스템 관리자가 동시 연결 요청들을 처리하는 데에 있어서 가장 높은 수준의 성능을 보장하기 위해 확인해 볼 수 있는 아이디어들과 기법들에 대한 간단한 목록이다.

  • 서버에 빠른 SCSI 디스크를 단 RAID 0를 사용한다.

  • 리눅스 플랫폼이라면, 하드 디스크 상호작용에 대해 hdparm 유틸리티를 사용하여 정교한 튜닝을 한다. (예를 들면, DMS 설정, Read-ahead, 그리고 Multiple-write 등)

  • 대규모의 정적 컨텐트들이 존재한다면, Tux나 kHTTPd와 같은 Non-forking 커널 공간 웹 서버들을 사용한다.

  • 모든 불필요한 로깅을 비활성화 시킨다. 예를 들면 LogLevelerror로 설정한다.

  • 로깅을 비활성화하기 전에 서버는 잘 테스트되어야 한다.

  • HARD_SERVER_LIMIT/HARD_THREAD_LIMIT/MAX_SERVER_LIMIT/MAX_THREAD_LIMIT 값이 적절한지를 확인한다.

  • 서버를 웹 서버 기능만 수행하게 한다. 다른 불필요한 애플리케이션들과 프로세스들을 비활성화 시킨다.

  • 불필요한 모듈들이 포함되지 않도록 한다.

  • 아파치를 완전히 정적 서버로 빌드하고, mod_so를 제거한다.

  • ExpiryCache-Control 헤더를 설정하여 가능한 캐시로부터 전송될 수 있도록 한다.

  • KeepAlive 값을 5초 이내로 설정하여, 가능한 한, 아파치가 기존 연결이 아니라 새로운 연결에 대해 응답할 수 있도록 한다.

  • 애플리케이션들을 영속적으로 만든다. (예를 들면 mod_fastcgi를 사용하는 방식) 그리고 가능한 한, 정적 페이지로 바꾼다. 데이터베이스를 변경하지 않는 간단한 데이터베이스 검색은 정적인 페이지로 교체할 수 있다.

  • mod_mmap_static (아파치 1.3) 이나 mod_file_cache (아파치 2.0) 모듈을 사용하여 빈번하게 접근되는 파일들을 메모리나 파일 핸들로부터 전송될 수 있도록 한다.

  • DNS Lookup과 같이 중복적인 작업을 하지 않도록 한다.

  • 커널의 네트워크와 프로세스 관련 매개변수들을 튜닝하여 아파치의 기대되는 부하를 처리할 수 있도록 한다.

  • 가능한 한, SSL을 사용하지 않는다. SSL은 서버에 처리 부하를 준다. 안전한 트랜잭션은 별도 서버로 이전하는 것을 검토해 보라.

  • 부하 분산을 위해 서버 클러스터를 구축하는 것을 검토해 보라.

참고 문헌

도서 또는 웹 문서들

[Wainwright02] Peter Wainwright. Copyright © 2002 Wrox Press. Wrox Press. Professional Apache 2.0.

 

Posted by redkite
, |

0013. FIND 명령어 완전 정복

Linux find 명령어 완전 정복 가이드

저자 - Sheryl Calish

가장 강력하면서도 한편으로는 혼란스러운 유비쿼터스 명령어인 find 명령어에 대한 개요.

게시일 : 2008년 7월

Linux find 명령어는 모든 Linux 명령어 가운데 가장 유용하면서도 혼란스러운 명령어 가운데 하나입니다. 다른 Linux 명령어의 표준 구문과 다른 구문을 가지고 있다는 점에서 어렵습니다. 하지만, 파일명, 파일 유형, 사용자, 더 나아가 타임 스탬프 별로 파일을 찾을 수 있다는 점에서 강력한 명령어이기도 합니다. find 명령어를 사용하면 이러한 속성을 자유롭게 조합해 파일의 위치를 찾을 수 있을 뿐만 아니라, 찾은 파일에 대해 연산을 수행할 수 있습니다.

본 글의 목적은 find 명령어와 그 잠재적 이점을 개략적으로 설명함으로써 find 명령어를 손쉽게 학습 및 사용할 수 있도록 돕는 것입니다. 동시에, find 명령어의 특성 중 가장 강력하면서도 한편으로는 혼란스러운 측면에 대한 개요 및 참조를 제공할 것입니다.

[주: 여기에서 사용된 find 명령어는 GNU 버전이기 때문에 일부 세부 내용은 다른 버전의 find 명령어와 다를 수 있습니다.]

기본 형식

먼저, find 명령어의 기본 구조부터 살펴보겠습니다:

find start_directory test options criteria_to_match

action_to_perform_on_results

아래 명령어에서 find는 이름에 "java" 확장자를 가지고 있는 모든 파일을 대상으로 "."가 표시된 현재 디렉토리를 찾기 시작할 것입니다:

find . -name "*.java"

아래에는 검색 결과에 대한 간단한 목록이 나열되어 있습니다:

find . -name "*.java"

./REGEXPvalidate/src/oracle/otnsamples/plsql/ConnectionManager.java

./REGEXPvalidate/src/oracle/otnsamples/plsql/DBManager.java

..

[주: 본 글에서 잘라 붙이기를 해 find 명령어를 실행하는 경우에는 자체 키보드를 사용해 큰따옴표("")를 바꿔야 올바른 결과를 얻을 수 있습니다.]

아래 명령어 역시 동일한 연산을 수행할 것입니다. 어떤 경우든, find 명령어에 전달되도록 escape 문을 통해 와일드카드 문자를 일반 문자로 처리해야 하며 쉘에 의해 해석되지 않아야 합니다. 따라서, 검색 문자열에 큰타옴표를 붙이거나 그 앞에 역슬래시(\)를 붙이십시오:

find . -name \*.java

find에 대한 인수는 옵션이기는 하지만, 검색 시작 위치를 지정하지 않은 경우에는 현재 디렉토리에서 기본적으로 검색이 시작됩니다. 옵션 사항이기는 하지만 테스트 조건을 지정하지 않은 경우에는 불완전하거나 선별되지 않은 결과값이 출력됩니다.

아래 3개의 find 명령어를 실행하면 똑같이 현재 디렉토리와 숨겨진 파일을 포함하는 모든 서브디렉토리의 모든 파일 목록이 검색됩니다:

find

find .

find . -print

이는 –la 옵션을 가진 ls 명령어를 실행하는 것과 비슷합니다. 백업을 위해 위 명령어의 출력물에 전체 경로 이름이 포함되기를 원하는 경우라면 시작 디렉토리에 대한 전체 경로를 지정해야 합니다:

find /home/bluher -name \*.java

/home/bluher/plsql/REGEXPvalidate/src/oracle/otnsamples/plsql/ConnectionManager.java

/home/bluher/plsql/REGEXPvalidate/src/oracle/otnsamples/plsql/DBManager.java/

...

또한, 검색 문자열에 1개 이상의 시작 디렉토리를 지정할 수도 있습니다. 적정 권한을 가진 사용자로서 실행되는 경우, 아래 명령어는 모든 jar 파일을 찾기 위해 /usr, /home 및 /tmp 디렉토리 순서로 내려갈 것입니다:

find /usr /home /tmp -name "*.jar"

적정 권한이 없는 사용자라면 많은 시스템 디렉토리를 검색하기 시작할 때 다음과 같은 오류 메시지가 나올 수 있습니다:

find: /tmp/orbit-root: Permission denied

다음과 같이 검색 문자열을 추가함으로써 불명확한 결과가 나오는 것을 피할 수 있습니다:

find /usr /home /tmp -name "*.jar" 2>/dev/null

이렇게 하면 모든 오류 메시지가 널(null) 파일로 전송되기 때문에 보다 정제된 출력물이 제공됩니다.

기본적으로 find 명령어는 대/소문자를 구별합니다. 대/소문자가 구별되는 find에서는 -name 테스트를 대신해 -iname 테스트를 사용하십시오.

find downloads -iname "*.gif"

downloads/.xvpics/Calendar05_enlarged.gif

downloads/lcmgcfexsmall.GIF

또한, 파일명 외에도 유형에 따라 파일을 검색할 수 있습니다. 예를 들어, 아래 명령어를 통해 디렉토리의 모든 서브디렉토리를 찾을 수 있습니다:

find . -type d

아래 명령어를 사용하면 /usr 디렉토리의 모든 심볼릭 링크(symbolic link)를 찾을 수 있습니다:

find /usr -type l

위 명령어를 실행하면 3,000개 이상의 링크 목록이 나타날 것입니다. 슈퍼유저(root) 권한을 통해 아래 명령어 가운데 하나를 실행하면 /usr 디렉토리의 링크 목록과 이것이 가리키는 파일이 나타납니다:

# find /usr/bin -type l -name "z*" -exec ls -l {} \;

lrwxrwxrwx 1 root root 8 Dec 12 23:17 /usr/bin/zsh -> /bin/zsh

lrwxrwxrwx 1 root root 5 Dec 12 23:17 /usr/bin/zless -> zmore

lrwxrwxrwx 1 root root 9 Dec 12 23:17 /usr/bin/zcat -> /bin/zcat

find /usr/bin -type l -name "z*" -ls

하지만, 보다 짧은 두 번째 명령어를 실행하면 디렉토리와 inode 정보를 가진 긴 파일 목록이 나올 것입니다. -exec 및 –ls 실행에 대해서는 후반부에서 다룰 것입니다

find가 찾을 수 있는 다른 파일 유형으로는 다음과 같은 것들이 있습니다

• b—block (buffered) special
• c—character (unbuffered) special
• p—named pipe (FIFO)
• s—socket

find 명령어의 시작점으로 루트를 사용하면 시스템 속도가 크게 느려질 수 있습니다. 반드시 명령어를 실행해야 하는 경우에는 사용량이 적은 시간대나 야간에 실행하는 것이 좋습니다. 아래 구문을 사용해 출력물을 파일로 보낼 수 있습니다.:

find / -print > masterfilelist.out

원치 않는 출력물을 대량 생산하는 find 명령어를 실수로 입력한 경우에는 CTRL-C를 누르기만 하면 가장 최근에 실행된 명령어가 중단됩니다.

여러 파일 시스템을 갖춘 엔터프라이즈 네트워크에서는 특히 find 명령어가 검색한 파일을 제한하는 것이 좋습니다. 필요한 수 만큼 옵션 및 테스트를 사용함으로써 시스템 상의 로드를 줄일 수 있습니다. 이를 위해 가장 유용하게 사용할 수 있는 옵션은 –xdev와 -mount입니다. 이들 옵션은 find 명령어가 MS-DOS, CD-ROM 또는 AFS와 같은 다른 파일 시스템 상의 디렉토리로 내려가지 않도록 함으로써 검색 범위를 좁혀줍니다. 따라서, 시작 디렉토리와 동일한 유형의 파일 시스템으로 검색을 제한할 수 있습니다.

듀얼 부팅 시스템 사용자는 mount 명령어가 실행되는 경우에 이러한 옵션을 사용할 수 있습니다. Windows 파티션이 관련되어 있다고 가정하면, 아래와 같은 명령어를 통해 마운팅 할 수 있습니다.:

mount -t vfat /dev/sda1 /mnt/msdos

여러분이 사용하는 실제 명령어는 시스템 설정 방법에 따라 달라집니다. df를 실행하거나 아래 명령어를 수행함으로써 파티션 마운팅 여부를 확인할 수 있습니다:

find /mnt/msdos -name "*.txt" 2> /dev/null

MS Windows 파티션에서는 파일 목록이 길 수 밖에 없습니다. 이제부터는 -mount 또는 -xdev 옵션을 통해 아래 명령어를 실행하십시오:

find / -name "*.txt" -mount 2> /dev/null

또는

find / -name "*.txt" -xdev 2> /dev/null

아래 예에서와 같이 -fstype 테스트를 사용해 find 명령어에 찾고자 하는 파일 시스템을 명확하게 알려줄 수도 있습니다:

find / -name "*.txt" -fstype vfat 2> /dev/null

시간 찾기

find 명령어는 시스템의 타임 스탬프를 토대로 파일 검색에 사용할 수 있는 여러 개의 옵션을 가지고 있습니다. 이러한 타임 스탬프로는 다음이 포함됩니다

mtime파일 내용이 마지막으로 수정된 시간
atime—파일을 읽기 또는 액세스한 시간
ctime—파일 상태가 변경된 시간

mtime 및 atime의 의미는 그 자체로 쉽게 알 수 있지만, ctime는 좀 더 설명이 필요합니다. inode는 각 파일에 메타 데이터를 가지고 있기 때문에 파일에 연결된 메타 데이터가 변경되면 inode 데이터도 변경됩니다. 파일에 대한 심볼릭 링크 생성, 파일에 대한 권한 변경, 파일 이동 등과 같은 다양한 작업으로 인해 이러한 메타 데이터 변경이 야기될 수 있습니다. 이러한 경우, 파일 내용에 대한 읽기나 수정은 수행되지 않기 때문에 themtime 및 atime은 변하지 않지만 ctime은 변합니다.

이러한 시간 옵션은 각기 -n, n 또는 +n로 지정된 n 값을 함께 사용해야 합니다.

• -n은 n 이하를 반환
• +n은 n 이상을 반환
• n은 정확히 n에 해당되는 값을 반환

보다 명확한 설명을 위해 몇 가지 예를 살펴 보겠습니다. 아래 명령어는 최근 1시간 동안 수정된 모든 파일을 찾아줍니다:

find . -mtime -1

./plsql/FORALLSample

./plsql/RegExpDNASample

/plsql/RegExpSample

-1 대신 1을 가진 동일 명령어를 실행하면 정확하게 1시간 전에 수정된 모든 파일을 찾을 수 있습니다:

find . -mtime 1

위 명령어는 정확하게 일치하는 값을 요청하기 때문에 모든 결과값이 나오지는 않습니다. 아래 명령어는 1시간 이전에 수정된 파일을 찾아줍니다:

find . -mtime +1

기본적으로 -mtime, -atime 및 –ctime는 최근 24 시간에 대한 타임 스탬프입니다. 하지만, 뒤에 daystart 옵션을 붙이면 오늘을 시작으로 24시간 주기가 시작됩니다. 또한, mmin, amin 및 cmin을 사용하면 분 단위로 변경된 타임 스탬프를 찾을 수 있습니다.

여러분의 계정으로 로그인한 후 즉시 아래 명령어를 실행하면 최근 1분 내에 읽은 모든 파일을 찾을 수 있습니다:

find . -amin -1

./.bashrc

/.bash_history

./.xauthj5FCx1

find 명령어만으로 파일의 위치를 찾으면 메타 데이터의 일부인 파일의 액세스 시간이 변경된다는 사실에 유의하십시오.

-newer, -anewer 및 –cnewer 옵션을 사용하면 특정 파일과 비교해 수정 또는 액세스된 파일을 찾을 수도 있습니다. 이는 -mtime, -atime 및 –ctime과 비슷합니다.

• -newer : 보다 최근에 내용이 수정된 파일
• -anewer : 보다 최근에 읽기가 수행된 파일
• -cnewer : 보다 최근에 상태가 변경된 파일

마지막 tar 파일 이후로 어떤 방법으로든지 수정된 홈 디렉토리의 파일을 모두 찾으려면 아래 명령어를 사용하십시오:

find . -newer backup.tar.gz

크기에 따른 파일 찾기

-size 옵션은 지정된 크기 기준에 부합하는 파일을 찾아줍니다. 크기가 5MB 이상인 모든 파일을 찾으려면 아래와 같이 하십시오

find / -size +5000000c 2> /dev/null

/var/log/lastlog

/var/log/cups/access_log.4

/var/spool/mail/bluher

마지막에 "c"를 붙이면 결과가 바이트 단위로 보고됩니다. 기본적으로 find 명령어는 512 바이트 블록의 수로 크기를 보고합니다. 또한, "c"를 "k"로 교체하는 경우에는 킬로바이트 수로, "w"를 사용하는 경우에는 2바이트 워드의 수로 결과를 표시할 수 있습니다.

-size 옵션은 모든 제로 바이트 파일을 찾거나 이들 파일을 /tmp/zerobyte 폴더로 이동하기 위해 자주 사용됩니다. 아래 명령어가 바로 이러한 연산을 수행합니다.

find test -type f -size 0 -exec mv {} /tmp/zerobyte \;

-exec 옵션은 find 명령어가 만나게 되는 파일의 모든 쉘 명령어를 수행할 수 있도록 해줍니다. 후반부에서 이 옵션의 보다 다양한 사용 예를 확인할 수 있습니다. 중괄호를 사용하면 빈 파일 각각을 이동시킬 수 있습니다

또한, -empty 옵션을 사용하면 빈 파일을 찾을 수 있습니다.

find test -empty

test/foo

test/test

권한 및 소유권에 따른 파일 찾기

find 명령어는 시스템 보안 모니터링을 위해 없어서는 안될 명령어입니다. 아래와 같이 기호법이나 8진법을 통해 사용 권한이 널리 열려있는 파일을 찾을 수 있습니다.

find . -type f -perm a=rwx -exec ls -l {} \;

또는

find . -type f -perm 777 -exec ls -l {} \;

-rwxrwxrwx 1 bluher users 0 May 24 14:14 ./test.txt

위의 명령어나 아래 명령어의 경우 -exec ls –l을 수행하고 있기 때문에, 반환된 파일의 실제 사용 권한을 확인할 수 있습니다. 이 명령어는 "기타 사용자" 및 그룹이 모두 쓰기를 수행할 수 있는 파일을 찾아줍니다.

find plsql -type f -perm -ug=rw -exec ls -l {} \; 2>/dev/null

또는

find plsql -type f -perm -220 -exec ls -l {} \; 2>/dev/null

-rw-rw-rw- 1 bluher users 4303 Jun 7 2004 plsql/FORALLSample/doc/otn_new.css

-rw-rw-rw- 1 bluher users 10286 Jan 12 2005 plsql/FORALLSample/doc/readme.html

-rw-rw-rw- 1 bluher users 22647 Jan 12 2005 plsql/FORALLSample/src/config.sql

..

아래 명령어들을 실행하면 사용자, 그룹 또는 둘 모두가 쓰기 작업을 할 수 있는 파일을 찾을 수 있습니다

find plsql -type f -perm /ug=rw -exec ls -l {} \; 2>/dev/null, or,

find plsql -type f -perm /220 -exec ls -l {} \; 2>/dev/null

-rw-r--r-- 1 bluher users 21473 May 3 16:02 plsql/regexpvalidate.zip

-rw-rw-rw- 1 bluher users 4303 Jun 7 2004 plsql/FORALLSample/doc/otn_new.css

-rw-rw-rw- 1 bluher users 10286 Jan 12 2005 plsql/FORALLSample/doc/readme.html

-rw-rw-rw- 1 bluher users 22647 Jan 12 2005 plsql/FORALLSample/src/config.sql

웹이나 기존 매뉴얼에는 아래 명령어로 나와 있을 것입니다.

find . -perm +220 -exec ls -l {} \; 2> /dev/null

+ 기호는 / 기호와 동일한 역할을 하지만, 새로운 버전의 GNU findutils에서는 권장되지 않고 있습니다.

시스템에서 쓰기 가능한 모든 파일을 찾으려면 아래 명령어를 사용하십시오

find / -wholename '/proc' -prune -o -type f -perm -0002 -exec ls -l {} \;

-rw-rw-rw- 1 bluher users 4303 Jun 7 2004/home/bluher/plsql/FORALLSample/doc/otn_new.css

-rw-rw-rw- 1 bluher users 10286 Jan 12 2005 /home/bluher/plsql/FORALLSample/doc/readme.html

...

4번째 사용 권한에 대해 앞으로 조금 더 다루겠지만, 마지막 필드의 "2"는 쓰기 비트로도 알려져 있는 파일 사용 권한의 "기타 사용자"에 해당됩니다. 우리는 설정된 다른 사용 권한이 무엇이든 관계 없이 기타 사용자를 위해 설정된 쓰기 권한을 가진 파일을 보고 싶다는 표시로 0002라는 사용 권한 모드 앞에 대시를 사용했습니다.

위의 명령어에서는 3가지 새로운 개념이 도입되었습니다. 패턴이 발견된 경우, – prune은 파일 패턴 "/proc"에서 -wholename 테스트를 사용함으로써 find 명령어가 이 디렉토리로 내려오지 않도록 막아줍니다. 불린 연산자 "-o"를 통해 find 명령어는 다른 디렉토리에서 명령어의 나머지 부분을 처리할 수 있습니다. 각 표현식 간에 가정된 암시적 and 연산자(-a)가 있기 때문에 좌측 표현식이 거짓(false)으로 평가된 경우 and 뒤에 나오는 표현식은 평가되지 않습니다. 따라서, -o 연산자가 필요합니다. 강제 우선 순위 적용을 위해 괄호를 사용하는 것처럼 find 명령어는 불린 연산자 -not, !,도 지원합니다.

시스템 관리자는 자주 find 명령어를 통해 해당 사용자나 그룹의 이름 또는 ID를 사용해 특정 사용자나 그룹의 정규 파일을 검색하고 있습니다:

[root] $ find / -type f -user bluher -exec ls -ls {} \;

여기, 이러한 명령어의 출력에 대한 간단한 예제가 나와 있습니다:

4 -rw-r--r-- 1 bluher users 48 May 1 03:09 /home/bluher/public_html/.directory

4 -rw-r--r-- 1 bluher users 925 May 1 03:09 /home/bluher/.profile

또한, find 명령어를 사용해 그룹 별로 파일을 검색할 수도 있습니다:

[root] $ find / -type f -group users

find / -type d -gid 100

이 명령어를 실행하면 그룹 ID 100이 소유하고 있는 디렉토리 목록이 나옵니다. 해당되는 uid 또는 gid를 찾기 위해 /etc/passwd 또는 /etc/group 파일에서 more 또는 cat 명령어를 실행할 수 있습니다

이 명령어는 알려진 특정 사용자 및 그룹에 관한 파일을 찾는 것 외에도 사용자나 그룹이 지정되지 않은 파일을 찾는 데도 유용합니다. 아래 명령어는 /etc/passwd 또는 /etc/group 파일에서 리스트를 가지고 있지 않은 파일을 식별합니다.

find / -nouser -o -nogroup

위 명령어는 실제로 시스템 상에 결과를 제공하는 것은 아니지만, 파일을 이동한 후에 사용자나 그룹이 지정되지 않은 파일을 식별하는 데 사용할 수 있습니다

이제, 본 섹션 초반부에 언급한 별도의 높은 사용 권한 문제를 해결할 수 있게 되었습니다.

SGID 및 SUID는 UNIX 기반 운영 체제 상의 파일 및 디렉토리에 할당할 수 있는 특별 액세스 권한 플래그입니다. 컴퓨터 시스템 액세스에 있어 일반 권한을 가진 사용자가 일시적으로 높아진 권한을 가지고 바이너리 실행 파일을 수행할 수 있습니다.

find / \( -perm -2000 -o -perm -4000 \) -ls

167901 12 -rwsr-xr-x 1 root root 9340 Jun 16 2006 /usr/bin/rsh

167334 12 -rwxr-sr-x 1 root tty 10532 May 4 2007 /usr/bin/wall

위 명령어에서 괄호가 escape 처리된 것을 볼 수 있습니다. 또한, 권한 간의 차이점을 확인할 수 있습니다. 첫 번째 파일에는 SGID 권한이 설정되어 있으며 두 번째 파일에는 SUID 권한이 설정되어 있습니다. 위 명령어의 마지막 연산은 -exec ls -dils 연산의 find 명령어와 유사합니다

find 명령어 제어

Linux의 많은 명령어와 달리, find 명령어는 -r 또는 -R 옵션이 없이도 서브디렉토리로 내려가지 않습니다. 이는 기본적으로 지원됩니다. 하지만, 때에 따라 이를 제한하고 싶을 수 있습니다. 이럴 경우, -depth, -maxdepth 및 –mindepth 옵션과 –prune 연산이 유용합니다

-prune이 얼마나 유용한지는 이미 확인했기 때문에 이제는 -depth, -maxdepth 및 -mindepth 옵션에 대해 살펴보겠습니다.

-maxdepth 및 -mindepth 옵션을 사용하면 find 명령어를 통해 검색하고자 하는 디렉토리 트리의 수준을 지정할 수 있습니다. find 명령어가 단 한 수준의 디렉토리를 찾도록 하고 싶은 경우에는 maxdepth 옵션을 사용할 수 있습니다.

아래 명령어를 실행해 디렉토리 트리의 상위 3개 수준의 로그 파일을 검색하면 –maxdepth의 효과를 확인할 수 있습니다. 이렇게 하면 –maxdepth 없이 실행할 때 보다는 훨씬 적은 출력 결과가 나옵니다

find / -maxdepth 3 -name "*log"

또한, find 명령어에게 디렉토리 트리에서 최소 3개 수준까지 디렉토리를 검색할 것을 지시할 수 있습니다.

find / -mindepth 3 -name "*log"

-depth 옵션은 내용 평가에 앞서 디렉토리를 평가할 수 있도록 해줍니다. 아래 명령어는 한 예입니다.:

find -name "*test*" -depth

./test/test

./test

./localbin/test

./localbin/test_shell_var

./localbin/test.txt

./test2/test/test

./test2/test

./test2

find 명령어의 세계

지금까지 find 명령어의 유용하지만 다소 혼란스러운 일부 기능에 대해 알아보았지만, find 명령어가 수행할 수 있는 추가 작업이 있습니다. 예를 들어, find 명령어가 기존 버전의 UNIX 및 기타 운영 체제와 호환 가능하도록 하고 여러 파일로 출력을 인쇄하도록 하는 등 연산을 수행할 수 있도록 하는 옵션이 있습니다. 본 자료를 읽은 다음에는 find 명령어에 대한 맨페이지(man page)를 이해할 수 있는 배경 지식을 갖추었을 것으로 생각하기 때문에 이 강력하면서도 유용한 툴을 직접 경험해 볼 것을 권합니다

Posted by redkite
, |

0012. 리눅스 루트 패스워드 분실 시

1.일단1.일단 시스템을 실행시키고 키보드에서 'e' 키를 누른다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.'e' 키를 누르면 아래 화면이 표시되는데 다시 'e''e' 키를 누릅니다.

 

 

 

 

 

 

 

 

 

 

 

 

3.출력된 행의 마지막에 한 칸 띄고띄고 '1' 을 입력

 

 

 

 

 

 

 

 

 

 

 

 

4.아래 화면이 나타나면 부팅시키기 위해서 'b' 키를 누른다.

 

 

 

 

 

 

 

 

 

 

 

 

5.'b' 키를 누르면 아래처럼 부팅이부팅이 진행된다

 

 

6.텍스트 모드이기는 하지만 부팅이 완료

 

 

 

 

 

 

 

7. passwd root 명령어를 입력하면 새로운 패스워드를 물어보는데 타이핑해도

아무런 표시가 되지 않는다. 모든 시스템이 그렇듯 패스워드는 2번 입력한다입력한다

제대로 패스워드가 변경되면 성공했다는 메시지가 출력된다

 

 

 

8.패스워드 변경을 성공했다면 시스템을 재부팅 시킨다(reboot)

rebootreboot 한 후 사용자명과 암호를 입력해서 사용

잊어버린 패스워드는 그만 잊어버리고 새로운 패스워드를 설정한다.

'02.서버-Linux' 카테고리의 다른 글

[리눅스]아파치 퍼포먼스 튜닝  (0) 2012.12.19
[리눅스]Find 명령어 완정 정복 가이드  (0) 2012.12.19
[리눅스]커널값 변경  (0) 2012.12.19
[리눅스]VIP 셋팅 방법  (0) 2012.12.19
[리눅스]RawDevice 설정  (0) 2012.12.19
Posted by redkite
, |

0009. Linux Kernel 값 변경


다른 UNIX 시스템과 달리, Linux 운영체제에서는 시스템이 실행 중인 상태에서 대부분의 커널 매개변수를 수정할 수 있습니다.
커널 매개변수를 변경한 뒤에 시스템을 리부팅할 필요도 없습니다. Oracle Database 10g 가 요구하는 커널 매개변수 설정이 아래와 같습니다. 아래 설정된 수치는 최소값을 의미하며, 시스템이 아래 명시된 것보다 높은 수치로 설정되어 있는 경우에는 변경하지 마시기 바랍니다.

kernel.shmall = 2097152
kernel.shmmax = 2147483648 (실 메모리의 반) physical memory *0.5 ~2147483648(2G)
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000

cat /proc/sys/kernel/sem
cat /proc/sys/kernel/shmall
cat /proc/sys/kernel/shmmax
cat /proc/sys/kernel/shmmni
cat /proc/sys/fs/file-max
cat /proc/sys/net/ipv4/ip_local_port_range

본 문서의 설명대로 Linux 운영체제를 설치한 경우라면 커널 매개변수가 디폴트 값으로 설정되어 있으므로, root로 로그인한 후
아래 명령을 복사하여 붙여 넣는 방법으로 실행할 수 있습니다.

cat >> /etc/sysctl.conf <<EOF
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000
EOF
/sbin/sysctl -p

Ex:
# cat >> /etc/sysctl.conf <<EOF
> kernel.shmall = 2097152
> kernel.shmmax = 2147483648
> kernel.shmmni = 4096
> kernel.sem = 250 32000 100 128
> fs.file-max = 65536
> net.ipv4.ip_local_port_range = 1024 65000
> EOF
# /sbin/sysctl -p
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
kernel.sysrq = 0
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000

설정을 확인하기 위해 아래 명령을 실행합니다:

/sbin/sysctl -a | grep shm
/sbin/sysctl -a | grep sem
/sbin/sysctl -a | grep file-max
/sbin/sysctl -a | grep ip_local_port_range

Ex:
# /sbin/sysctl -a | grep shm
kernel.shmmni = 4096
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shm-use-bigpages = 0
# /sbin/sysctl -a | grep sem
kernel.sem = 250 32000 100 128
# /sbin/sysctl -a | grep file-max
fs.file-max = 65536
# /sbin/sysctl -a | grep ip_local_port_range
net.ipv4.ip_local_port_range = 1024 65000

시스템의 매개변수가 위에 명시된 값보다 낮게 설정된 경우, /etc/sysctl.conf의 매개변수를 추가하거나 수정해야 합니다.
작업이 완료되면, 아래 명령을 실행하여 변경된 설정을 반영시킵니다:

/sbin/sysctl -p

Novell SUSE Linux 운영체제의 경우 아래 명령을 사용합니다.
/sbin/chkconfig boot.sysctl on

oracle 사용자 계정의 Shell Limit 설정

오라클은 Linux 계정 별로 실행되는 프로세스와 열린 파일의 수를 제한하는 것을 권장합니다. 이를 위해, root 계정에서 아래 명령을
복사하여 붙여 넣는 방법으로 실행합니다:
"open file descriptors"의 최대 값인 nofile (max number of open files)을 "65536"으로 single user에 대한 최대 활용 가능한 프로세스의 수인
nproc(max number of processes)를 "16384"로 수정한다

cat >> /etc/security/limits.conf <<EOF
oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65535
EOF

cat >> /etc/pam.d/login <<EOF
session required /lib/security/pam_limits.so
EOF

RHEL 2.1 / 3의 경우, 아래 명령을 사용합니다:

cat >> /etc/profile <<EOF
if [ $USER = "oracle" ]; then
if [ $SHELL = "/bin/ksh" ]; then
ulimit -p 16384
ulimit -n 65536
else
ulimit -u 16384 -n 65536
fi
umask 022
fi
EOF

cat >> /etc/csh.login <<EOF
if ( $USER == "oracle" ) then
limit maxproc 16384
limit descriptors 65536
umask 022
endif
EOF

SLES8의 경우, 아래 명령을 사용합니다:

cat >> /etc/profile.local <<EOF
if [ $USER = "oracle" ]; then
if [ $SHELL = "/bin/ksh" ]; then
ulimit -p 16384
ulimit -n 65536
else
ulimit -u 16384 -n 65536
fi
umask 022
fi
EOF

cat >> /etc/csh.login.local <<EOF
if ( $USER == "oracle" ) then
limit maxproc 16384
limit descriptors 65536
umask 022
endif
EOF

 

- Oracle 10g를 설치하고 지원가능한 OS : RHEL4(CentOS 4.x included), SLES9
- 한국에서는 주로 레드햇 계열을 많이 사용하므로 RHEL에 맞추어 기술한다.
- /etc/sysctl.conf에 다음을 추가 :
kernel.shmall = 2097152
kernel.shmmax = 536870912
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=262144
net.core.wmem_max=262144

 

vi 편집기로 열어서 편집하면 된다.

Posted by redkite
, |

Virtual IP 구성
==================================================================
/sbin/ifconfig eth0:0 192.168.100.51

==================================================================
vi /etc/sysconfig/network-scripts/ifcfg-eth0:0
DEVICE=eth0:0
IPADDR=192.168.100.51
NETMASK=255.255.255.255
NETWORK=192.168.100.0
BROADCAST=192.168.100.255
ONBOOT=yes
==================================================================

service network restart
ifconfig

제거
==================================================================
rm /etc/sysconfig/network-scripts/ifcfg-eth0:0
service network restart

'02.서버-Linux' 카테고리의 다른 글

[리눅스]루트 패스워드 분실 시  (0) 2012.12.19
[리눅스]커널값 변경  (0) 2012.12.19
[리눅스]RawDevice 설정  (0) 2012.12.19
[리눅스]fstab 오류 발생 처리  (0) 2012.12.19
[리눅스]패스워드 정책 설정  (0) 2012.12.19
Posted by redkite
, |

0068. [리눅스] rawdevice 설정

Linux에서 Raw Device를 관리하는 방법을 보자.

- Raw Device는 linux의 raw 명령어를 통하여 관리할 수 있다.
# raw
Usage:
raw /dev/raw/rawN
raw /dev/raw/rawN /dev/
raw -q /dev/raw/rawN
raw -qa

- Raw Device 확인 명령
# raw -qa

- /dev/sda1 파티션을 Raw device로 설정하고 싶다면
# raw /dev/sda1 /dev/raw/raw1

- Raw Device 제거 방법
# raw /dev/raw/raw1 0 0

- 재부팅해도 raw device 셋팅을 유지하고 싶다면

n Redhat AS 4 이전 버전까지는 /etc/sysconfig/rawdevices 파일을 이용한다.

# cat /etc/sysconfig/rawdevices

# raw device bindings
# format:
#
# example: /dev/raw/raw1 /dev/sda1
# /dev/raw/raw2 8 5

/dev/sda1 /dev/raw/raw1 ß 이런식으로 추가한다.


# service rawdevice restart ß 이런식으로 raw device를 재인식 시킨다.

n Redhat AS 5 이후 버전부터는 /etc/udev/rules.d/60-raw.rules 파일을 이용하여 관리한다.

# cat /etc/udev/rules.d/60-raw.rules

# Enter raw device bindings here.
#
# An example would be:
# ACTION=="add", KERNEL=="sda", RUN+="/bin/raw /dev/raw/raw1 %N"
# to bind /dev/raw/raw1 to /dev/sda, or
# ACTION=="add", ENV{MAJOR}=="8", ENV{MINOR}=="1", RUN+="/bin/raw /dev/raw/raw2 %M %m"
# to bind /dev/raw/raw2 to the device with major 8, minor 1.

# raw 설정

ACTION=="add", KERNEL=="xvdc", RUN+="/bin/raw /dev/raw/raw1 %N"

# permission 설정

ACTION=="add", KERNEL=="raw1", OWNER=="oracle", GROUP=="oinstall", MODE=="0660"


# /sbin/start_udev ß 이런식으로 raw device를 재인식 시킨다.

 

'02.서버-Linux' 카테고리의 다른 글

[리눅스]커널값 변경  (0) 2012.12.19
[리눅스]VIP 셋팅 방법  (0) 2012.12.19
[리눅스]fstab 오류 발생 처리  (0) 2012.12.19
[리눅스]패스워드 정책 설정  (0) 2012.12.19
[리눅스]DD 가상파일 생성  (0) 2012.12.19
Posted by redkite
, |

0062. [리눅스] fstab 오류 발생 처리

. /etc/fstab 파일의 편집 오류

/etc/fstab 파일을 수정을 하다가 오타를 치거나 잘못 삭제를 해버린 경우에 부팅이 안되거나 느려지게 된다. 이럴 경우 어떻게 해결할 수 있는지 알아보도록 한다.

[root@donghun ~]# vi /etc/fstab

LABEL=/ / ext3 defaults 1 1

LABEL=/home /home ext3 defaults 1 2

tmpfs /dev/shm tmpfs defaults 0 0

devpts /dev/pts devpts gid=5,mode=620 0 0

sysfs /sys sysfs defaults 0 0

proc /proc proc defaults 0 0

LABEL=SWAP-sda2 swap swap defaults 0 0

/dev/sdb? /data ext3 defaults,usrquota 1 2

à 마지막 줄에 일부러 오타를 냈다.

[root@donghun ~]# reboot

à 마운트를 시도하다가 실패를 했다는 메세지가 뜨면서 중간에 멈춘다. root 패스워드를 입력하면 repair filesystem 쉘로 로그인이 된다.

(repair filesystem) # vi /etc/fstab à 파일의 내용이 수정이 안된다.

(repair filesystem) # mount –o remount,rw / à /를 read/write로 다시 마운트 시킨다.

(repair filesystem) # vi /etc/fstab

LABEL=/ / ext3 defaults 1 1

LABEL=/home /home ext3 defaults 1 2

tmpfs /dev/shm tmpfs defaults 0 0

devpts /dev/pts devpts gid=5,mode=620 0 0

sysfs /sys sysfs defaults 0 0

proc /proc proc defaults 0 0

LABEL=SWAP-sda2 swap swap defaults 0 0

/dev/sdb1 /data ext3 defaults,usrquota 1 2

à 오타부분을 수정한다.

(repair filesystem) # reboot à 시스템이 정상적으로 재부팅 되면 성공

'02.서버-Linux' 카테고리의 다른 글

[리눅스]VIP 셋팅 방법  (0) 2012.12.19
[리눅스]RawDevice 설정  (0) 2012.12.19
[리눅스]패스워드 정책 설정  (0) 2012.12.19
[리눅스]DD 가상파일 생성  (0) 2012.12.19
[리눅스]메일 관리  (0) 2012.12.19
Posted by redkite
, |

0061. [리눅스] 패스워드 정책설정

/etc/pam.d/system-auth
~~~~~~~~~~~~~~~~
auth required /lib/security/pam_tally.so no_magic_root
account required /lib/security/pam_tally.so deny=2 no_magic_root reset

auth required pam_tally.so onerr=fail deny=5 no_magic_root

account required pam_tally.so onerr=fail no_magic_root reset


연속 3회 login 실패 시 계정이 잠김.
자동으로 풀리지 않음. 관리자가 잠금을 풀어줘야한다.
deny: 실패 회수, 3회 실패 적용은 2로 설정.
no_magic_root: root의 암호는 실제 lock은 걸지 않음
reset: 실패 회수 안에서 login하면 기존 실패 횟수를 reset, 실패에 대한 기록을 다시 함.

log 위치 : /var/log/faillog

# 잠금 해제
faillog -u oracle -r

# 확인 명령
pam_tally
faillog

# 초기화
pam_tally --user oracle --reset


script
--------------------------------------------------------------------------------
echo "
auth required /lib/security/pam_tally.so no_magic_root
account required /lib/security/pam_tally.so deny=2 no_magic_root reset
" >> /etc/pam.d/system-auth

RHEL5
~~~~~~~~~~~~~~~~~~

[root@rhel5 ~]# cat /etc/pam.d/system-auth [ 아래 위치가 중요 ]
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
# The below line is used to lock an account if user failed to authenticate 5 times and will be locked for 60 secs.
auth required pam_tally.so onerr=fail deny=3 unlock_time=60

auth sufficient pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 500 quiet
auth required pam_deny.so

account required pam_unix.so
# The below line is required for account lockout due to failed login attempt
account required pam_tally.so
account sufficient pam_succeed_if.so uid < 500 quiet
account required pam_permit.so

password requisite pam_cracklib.so try_first_pass retry=3
password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok
password required pam_deny.so

session optional pam_keyinit.so revoke
session required pam_limits.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid

'02.서버-Linux' 카테고리의 다른 글

[리눅스]RawDevice 설정  (0) 2012.12.19
[리눅스]fstab 오류 발생 처리  (0) 2012.12.19
[리눅스]DD 가상파일 생성  (0) 2012.12.19
[리눅스]메일 관리  (0) 2012.12.19
[리눅스]lsyncd – 실시간 파일 동기화  (0) 2012.12.19
Posted by redkite
, |

0060. [리눅스] DD 가상파일 생성

dd if=/dev/zero of=/data/dd_test_20GB bs=2048000 count=10000  ## 20GB 파일 생성시

♧ 모든 파티션 준비가 끝났다면 이제 각각의 파티션을 원하는 파일시스템으로 포맷.

■ mkfs - 리눅스 파일 시스템 만들기

mkfs [ -V ] [ -t fstype ] [ fs-options ] filesys [ blocks ]

▷ mkfs 명령어는 아래와 같은 리눅스 파일 시스템을 만든다.

mkfs.ext2, mkfs.ext3, mkfs.ext4, mkfs.cramfs, mkfs.msdos, mkfs.ntfs, mkfs.vfat … 등등

▷ 기본적인 사용 방법 예:

$ sudo mkfs -t ext3 /dev/sdb1

sdb1에 ext3 파일시스템 생성.

$ sudo mkfs -t ext3 -v -c /dev/sdb1

배드 플록 검사와 함께 좀 더 자세한 출력 요구.

$ sudo mkfs.ext3 -c /dev/sdb1

위 명령어와 동일한 경과

[ 가상 파일시스템 생성 ]

♧ 물리적으로 고정된 디스크 파티션을 직접 생성하지 않고 특정 파일시스템 유형을

테스트 하고자 한다면 가상 파일시스템을 사용할 수 있다.

(라이브 CD를 만들거나 가상 운영체제를 실행하는 경우에 유용)

▷ 1GB 크기의 빈 디스크 이미지 파일을 생성 & 포맷 & 마운트

/* 0으로 채워진 1GB 파일 생성 */

$ dd if=/dev/zero of=mydisk count=2048000

2048000+0 레코드 들어옴

2048000+0 레코드 나감

1048576000 바이트 (1.0 GB) 복사됨, 25.8721 초, 40.5 MB/초

/* 가상 파일시스템의 크기를 확인 */

$ du -sh mydisk

1001M mydisk

/* mkdisk 파일에 파일시스템을 만든다 */

$ mkfs -t ext4 mydisk

mke2fs 1.41.14 (22-Dec-2010)

mydisk is not a block special device.

Proceed anyway? (y,n) y

/* 마운트 위치 생성 & 디스크 이미지 마운트 */

$ sudo mkdir /mnt/image

$ sudo mount -o loop /tmp/mydisk /mnt/image

dd 명령어로 204800 블록(약 1GB)의 빈 디스크 이미지 생성.

mkfs 명령어로 사용자가 선택한 유형의 파일시스템을 생성.

→ 실제 블록 디바이스가 아니기 때문에 경고 출력

☞ 가상 파일시스템은 다른 파일시스템과 동일한 방법으로는 마운트 할 수 없다.

→ 마운트할 디렉토리를 생성한 다음, 파일(mydisk)를 루프 디바이스(-o loop)로서 마운트 해야 함

→ mount 명령 실행시 root 권한 필요

▶ 가상 파일시스템 /mnt/image 접근 사용.

$ sudo cd /mnt/image

마운트 지점으로 이동

$ sudo mkdir teset

파일시스템에 디렉토리 생성

$ sudo cp /etc/hosts .

파일을 파일시스템으로 복사

$ cd

파일시스템을 벗어난다.

$ sudo umount /mnt/image

파일시스템의 마운트를 해제

☞ 가상 파일시스템의 마운트를 해제한 다음, 파일을 다른 시스템으로 이동시키거나

다른 곳에서 사용하기 위해 CD에 기록해 둘 수 있다.

☞ 만약 이 가상 파일시스템이 더 이상 필요 없다면 단순히 파일을 삭제.

Posted by redkite
, |

0058. [리눅스] 메일관리

Mail Server 간단 명령어

-------------------------------------------------------------------

1. /etc/aliases 적용

[root@server3 ~]# vi /etc/aliases
96 #root: marc
97 music: movie
- music 사용자에게 오는 메일을 movie 사용자에게 보낸다.

[root@server3 ~]# newaliases
/etc/aliases: 77 aliases, longest 10 bytes, 775 bytes total
[root@server3 ~]# service sendmail restart
sm-client을 종료 중: [ OK ]
sendmail를 종료 중: [ OK ]
sendmail (을)를 시작 중: [ OK ]
sm-client를 시작 중: [ OK ]

-------------------------------------------------------------------

1-1. 메일 보내기

[root@server3 ~]# mail music@server3.co.kr
Subject: test

music mail

hi~~
.
Cc:

[root@server3 mqueue]# mailq
/var/spool/mqueue is empty
Total requests: 0
[root@server3 mqueue]#

-------------------------------------------------------------------

1-2. 메일 확인

- music 사용자
[root@server3 ~]# su - music
[music@server3 ~]$ mail

No mail for music
[music@server3 ~]$


- movie 사용자
[root@server3 ~]# su - movie
[movie@server3 ~]$ mail

Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/movie": 2 messages 1 new
1 MAILER-DAEMON@server Fri Dec 19 16:35 13/546 "DON'T DELETE THIS MES"
>N 2 root@server3.co.kr Mon Dec 22 09:29 18/590 "test"
& 2
Message 2:
From root@server3.co.kr Mon Dec 22 09:29:42 2008
Date: Mon, 22 Dec 2008 09:29:41 +0900
From: root <root@server3.co.kr>
To: music@server3.co.kr
Subject: test

music mail

hi~~


& q
Saved 1 message in mbox
Held 1 message in /var/spool/mail/movie
[movie@server3 ~]$

-------------------------------------------------------------------

2. /etc/mail/virtusertable

[root@server3 ~]# vi /etc/mail/virtusertable
webmaster@server3.co.kr guest@server3.co.kr

[root@server3 ~]# makemap hash /etc/mail/virtusertable < /etc/mail/virtusertable
or [root@server3 ~]# makemap hash /etc/mail/virtusertable.db < /etc/mail/virtusertable

[root@server3 ~]# mail webmaster@server3.co.kr
Subject: test
webmaster mail
.
Cc:

[root@server3 mqueue]# mailq
/var/spool/mqueue is empty
Total requests: 0
[root@server3 mqueue]#

-------------------------------------------------------------------

2-1. 메일 확인

[root@server3 ~]# su - guest
[guest@server3 ~]$ mail

Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/guest": 1 message 1 new
>N 1 root@server3.co.kr Mon Dec 22 09:34 16/600 "test"

& 1
Message 1:
From root@server3.co.kr Mon Dec 22 09:34:53 2008
Date: Mon, 22 Dec 2008 09:34:53 +0900
From: root <root@server3.co.kr>
To: webmaster@server3.co.kr
Subject: test

webmaster mail

& q

Saved 1 message in mbox
[root@server3 mqueue]#

-------------------------------------------------------------------

3. /etc/mail/sendmail.cf의 옵션 적용 - # Forward file search path

[root@server3 guest]# vi /etc/mail/sendmail.cf

233 # Forward file search path
234 #O ForwardPath=$z/.forward.$w:$z/.forward
235 O ForwardPath=/home/guest/.forward.$w:$z/.forward


[root@server3 guest]# vi .forward
movie

[root@server3 guest]# ls -la
-rw-r--r-- 1 root root 6 12월 22 09:49 .forward

[root@server3 guest]# chown guest.guest .forward
[root@server3 guest]# chmod 644 .forward
- .forward의 퍼미션을 변경해 준다. 자세한 내용은 아래 "참고"를 참고한다.
[root@server3 guest]# ls -la
-rw-r--r-- 1 guest guest 6 12월 22 09:49 .forward

[root@server3 guest]# service sendmail restart
sm-client을 종료 중: [ OK ]
sendmail를 종료 중: [ OK ]
sendmail (을)를 시작 중: [ OK ]
sm-client를 시작 중: [ OK ]

[root@server3 guest]# mail guest@server3.co.kr

Subject: test guest
guest -> movie

Hi~~
.
Cc:

[root@server3 mqueue]# mailq
/var/spool/mqueue is empty
Total requests: 0
[root@server3 mqueue]#

-------------------------------------------------------------------

- 참고 : .forward 파일의 퍼미션 적용 전
.forward파일 생성시 중요한 사항으로 보안성 강화를 위하여 .forward파일의 퍼미션과 .froward파일을 포함하는 디렉토리(사용자 계정 디렉토리)에 group의 퍼미션에 쓰기 권한이 없어야 sendmail 데몬이 .forward파일을 읽어서 포워딩 기능을 정상적으로 진행한다.
CentOS의 기본적인 유저생성시 생성되는 디렉토리 퍼미션은 700 이지만, 기본 파일 생성 퍼미션이 664로 생성되어 그룹 퍼미션에 쓰기 권한이 있기 때문에 .forward파일만 생성하였다고 해서 포워딩이 정상적으로 진행되지 않는다. 이럴때는 644로 .froward 파일의 퍼미션을 변경해 준다.


터미널 창 1
[guest@server3 ~]$ chmod 664 .forward
[guest@server3 ~]$ ls -la

-rw-rw-r-- 1 guest guest 6 12월 22 09:56 .forward

[root@server3 ~]# mail guest@server3.co.kr
Subject: test
guest -> movie
.
Cc:

[root@server3 ~]# mailq
/var/spool/mqueue is empty
Total requests: 0
[root@server3 ~]#


터미널 창 2
[root@server3 mqueue]# tail -f /var/log/maillog

Dec 22 10:20:54 server3 sendmail[7689]: mBM1KsY6007688: forward /home/guest/.forward: Group writable file

- /home/guest/.forward : group writable file라 해서 그룹 퍼미션과 관련된 설정때문에 메일이 제대로 전달되지 않는다.


메일 확인
[guest@server3 ~]$ mail - movie로 포워딩 되지 않고 guest 사용자에게 메일이 전달되었다.
Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/guest": 1 message 1 new
>N 1 root@server3.co.kr Mon Dec 22 10:20 16/588 "test"
& 1
Message 1:
From root@server3.co.kr Mon Dec 22 10:20:54 2008
Date: Mon, 22 Dec 2008 10:20:54 +0900
From: root <root@server3.co.kr>
To: guest@server3.co.kr
Subject: test

guest -> movie

& q

Saved 1 message in mbox
[guest@server3 ~]$

-------------------------------------------------------------------

3-1. 메일 확인

- guest 사용자
[guest@server3 ~]$ mail
No mail for guest
[guest@server3 ~]$

- movie 사용자
[movie@server3 ~]$ mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/movie": 1 message 1 new
>N 1 root@server3.co.kr Mon Dec 22 09:54 18/600 "test guest"
& 1
Message 1:
From root@server3.co.kr Mon Dec 22 09:54:10 2008
Date: Mon, 22 Dec 2008 09:54:10 +0900
From: root <root@server3.co.kr>
To: guest@server3.co.kr
Subject: test guest

guest -> movie

Hi~~

& q

Saved 1 message in mbox
[movie@server3 ~]$

-------------------------------------------------------------------

4. telnet으로 메일 보내기

[root@server3 ~]# telnet localhost 25 - telnet 을 이용해 25번 포트로 접속한다.
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
220 server3.co.kr ESMTP Sendmail 8.13.8/8.13.8; Mon, 22 Dec 2008 10:25:49 +0900
HELP - telnet으로 사용가능한 명령어 목록을 보여준다. 각 명령어들의 도움말은 HELP <Topic> 라고 입력한다.
214-2.0.0 This is sendmail
214-2.0.0 Topics:
214-2.0.0 HELO EHLO MAIL RCPT DATA
214-2.0.0 RSET NOOP QUIT HELP VRFY
214-2.0.0 EXPN VERB ETRN DSN AUTH
214-2.0.0 STARTTLS
214-2.0.0 For more info use "HELP <topic>".
214-2.0.0 To report bugs in the implementation see
214-2.0.0 http://www.sendmail.org/email-addresses.html
214-2.0.0 For local information send email to Postmaster at your site.
214 2.0.0 End of HELP info
MAIL FROM : guest@server3.co.kr - 메일 발송자 입력
250 2.1.0 guest@server3.co.kr... Sender ok
RCPT TO : movie@server3.co.kr - 메일 수신자 입력
250 2.1.5 movie@server3.co.kr... Recipient ok
DATA - 메세지 작성
354 Enter mail, end with "." on a line by itself
Hi guest
How are you?
. - 메세지 종료
250 2.0.0 mBM1PnBc007716 Message accepted for delivery
QUIT - 나가기
221 2.0.0 server3.co.kr closing connection
Connection closed by foreign host.
[root@server3 ~]#

-------------------------------------------------------------------

4-1. 메일 확인

movie 사용자
[movie@server3 ~]$ mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/movie": 1 message 1 new
>N 1 guest@server3.co.kr Mon Dec 22 10:28 13/481
& 1
Message 1:
From guest@server3.co.kr Mon Dec 22 10:28:55 2008
Date: Mon, 22 Dec 2008 10:25:49 +0900
From: guest@server3.co.kr
X-Authentication-Warning: server3.co.kr: server3 [127.0.0.1] didn't use HELO protocol

Hi guest
How are you?

& q

Saved 1 message in mbox
[movie@server3 ~]$


-------------------------------------------------------------------

5. mutt

- mail 명령어와 비슷한 메일을 확인하는 프로그램이다.


[root@server3 ~]# mutt

 



-------------------------------------------------------------------

6. 센드메일의 smtp 메일 발송 인증 제한하기

- CentOS에서는 사용자의 smtp 인증방식에 있어서 saslauthd를 사용한다.
스팸메일을 방지하고 서버관리자가 정식으로 인정한 사용자들만 메일을 보낼 수 있게 해야만 한다.
그래서
메일 발송을 위한 인증을 사용하기 위하여 CentOS 에서는 접속-기반 프로토콜에 대한 인증지원을 제공하는 cyrus-sasl 패키지를 이용하고 있다.
이 패키지의 경우 연계된 패키지가 많기 때문에 대부분 CentOS 인스톨시 자동으로 설치된다.


[root@server3 ~]# rpm -qa | grep cyrus-sasl

cyrus-sasl-plain-2.1.22-4
cyrus-sasl-2.1.22-4
cyrus-sasl-devel-2.1.22-4
cyrus-sasl-lib-2.1.22-4
[root@server3 ~]# rpm -qi cyrus-sasl
Name : cyrus-sasl Relocations: (not relocatable)
Version : 2.1.22 Vendor: CentOS
Release : 4 Build Date:
Install Date: Build Host: builder1.centos.org
Group : System Environment/Libraries Source RPM: cyrus-sasl-2.1.22-4.src.rpm
Size : 4835816 License: Freely Distributable
Signature : DSA/SHA1, 2007년 04월 04일 (수) 오전 09시 20분 45초, Key ID a8a447dce8562897
URL : http://asg.web.cmu.edu/sasl/sasl-library.html
Summary : Cyrus SASL 라이브러리.
Description :
cyrus-sasl 패키지는 SASL의 Cyrus 구현을 포함합니다. SASL는
Simple Authentication and Security Layer의 줄임말로서 접속-기반 프로토콜에
인증 지원을 제공하는 방식입니다.
[root@server3 ~]#

Posted by redkite
, |

0055. [리눅스] lsyncd -실시간 파일 동기화

예전에 HA관련에서 실시간 백업에 대해서 이야기를 논한적이 있습니다.

lsync에 대한것을 살짝 언급을 하였었고, 오늘 테스트를 해보았습니다.
문제가 있다면 disk I/O가 문제가 되어집니다.

최신 버전의 lsync구하는곳 (http://code.google.com/p/lsyncd/)
+ rsyncd도 최신 버전이여야 함. (CentOS 5.5에 default로 설치되어지는 rsync는 2.6 버전인것같습니다. 3버전으로 업글을 추천합니다...ㄷㄷ

1. 컴파일 (rsync http://samba.org/rsync)
일단 구하고 wget하고 tar도 해주고 ./configure ; make ; make install 합니다.

2. lsync 컴파일 (rpm이 없습니다. 위 알려드린 url에서 2.0.2를 다운 받습니다)
-> lua가 필요합니다. 설치 버전은 5.1.4 입니다.

2.1 LUA 5.1.4 컴파일 (http://www.lua.org/)
->wget 하고 tar zxvf 하고, make linux;make test;make install 합니다.

root@lb1:[Mon Oct 12 21:04:48]:[/opt/installs/lighttpd-1.5.0.cache]$ wget http://www.lua.org/ftp/lua-5.1.4.tar.gz
tar xvfz lua-5.1.4.tar.gz
cd lua-5.1.4
make linux
make install
cp etc/lua.pc /usr/lib/pkgconfig/ ## 파일 필요함
and you are ready to try again


2.2 그뎌 lsync 컴파일
-> 설치도중 에러가 납니다.
-> LUA 컴파일 dir로 이동하여 lua.pc 파일을 /usr/lib64/pkgconfig에 복사를 해줍니다. (linux가 64비트인지라)
-> make 도중 에러가 발생합니다....-_-;
(중도 포기를 예상하며 잠깐의 커피타임...)
->gcc -g -O2 -Wall -I/usr/local/include -o lsyncd lsyncd.o inotify.o -L/usr/local/lib -llua -lm
/usr/local/lib/liblua.a(loadlib.o): In function `ll_loadfunc':
loadlib.c:(.text+0x7d4): undefined reference to `dlsym'
loadlib.c:(.text+0x7e2): undefined reference to `dlerror'
loadlib.c:(.text+0x8ad): undefined reference to `dlopen'
loadlib.c:(.text+0x8c3): undefined reference to `dlerror'
/usr/local/lib/liblua.a(loadlib.o): In function `gctm':
loadlib.c:(.text+0xdbc): undefined reference to `dlclose'
collect2: ld returned 1 exit status
make[1]: *** [lsyncd] Error 1
make[1]: Leaving directory `/root/lsync/lsyncd-2.0.2'

이건 뭐다냥........................ vi config.status 파일을 수정합니다.

LIBLUA_LIBS = -L/usr/local/lib -llua -lm -ldl 혹은 LIBLUA_LIBS = -L/usr/local/lib -llua -lm

오오 그뎌 컴파일이 되어집니다..........헉헉 여기까지 오시느라 고생하셨습니다. ㅠ_ㅠ 잠깐 한숨 돌리시죠? (위에서 커피 마시고...-_-;)

rsync와 lsync가 컴파일이 모두 완료가 되어졌습니다.

여기서 잠깐...; lsync이 원리에 대해서 이야기를 잠깐 해보도록 하겠습니다.
lsync는 kernel에서 디스크 기록시에 event가 발생이 되어지는데 이 event를 감지하여 해당 file에 대한것을 rsync에게 넘기는 방식입니다.

그러다보니 이게 말로만 실시간이지 실시간이 안되어지는 부분도 존재합니다.
대표적인 예로는 db관련 부분입니다. 한번 thread들이 물면 놓지 않기 때문에 db서버가 내려가면서 file write event가 발생되어지지 않으면 sync가 되어지지 않습니다. 이것은 결국 로그도 동일한 현상이 발생이 되어지는 부분이 있으니 참고를 하세요

============제 멋대로 한 rsync conf=========
cat rsyncd.conf
[data]
path=/data/
comment=lsync_nosage
uid=nobody
gid=nobody
use chroot=yes
max connections=10
read only=yes

이것만 설정했습니다....테스트장비이니까요...(데헷....^_* << 아무래도 정신줄 놓은듯...)

그 다음 lsync를 올립니다.
처음에는 에러로그를 보기 위해서 nodaemon상태로 올립니다.

lsycn --nodaemon -rsync /data /lsync (/data는 소스 위치 /lsync는 타겟위치입니다 - 타겟 위치는 원격지 서버도 가능합니다.)

이 상태라면 lsync설치가 완료가 되어집니다.
고생하셨습니다.

'02.서버-Linux' 카테고리의 다른 글

[리눅스]DD 가상파일 생성  (0) 2012.12.19
[리눅스]메일 관리  (0) 2012.12.19
[리눅스]패스워드 만료일자 변경  (0) 2012.12.19
[리눅스]부트영역 복구하기  (0) 2012.12.19
[리눅스]명령어 로깅 설정  (0) 2012.12.19
Posted by redkite
, |

[root@mail ~]# chage -d 2011-05-25 jsclub

[root@mail ~]# chage -l jsclub

마지막으로 열쇠글을 바꾼 날 : 5월 25, 2011

열쇠글 만료 :안함

열쇠글이 비활성화 기간 :안함

계정 만료 : 3월 15, 2012

열쇠글을 바꿀 수 있는 최소 날 수 : 0

열쇠글을 바꿔야 하는 최대 날 수 : 99999

열쇠글 만료 예고를 하는 날 수 : 7

/etc/shadow

jsclub:$1$I2d5T0RE$3OC6qqnfrZgUo1U/ni.gE1:15119:0:99999:7::15414:

'02.서버-Linux' 카테고리의 다른 글

[리눅스]메일 관리  (0) 2012.12.19
[리눅스]lsyncd – 실시간 파일 동기화  (0) 2012.12.19
[리눅스]부트영역 복구하기  (0) 2012.12.19
[리눅스]명령어 로깅 설정  (0) 2012.12.19
[리눅스]USB 인식  (0) 2012.12.19
Posted by redkite
, |

0053. [리눅스] 부트영역 복구하기

리눅스 부팅 과정과 커널 패닉 조치요령

1. 리눅스 부팅 과정 이해의 필요성

리눅스 부팅 시 커널패닉이나 파일시스템 에러 같은 경우를 만났을 때 어떻게 해야 할지 몰라 당황하는 경우가 있다. 리눅스 부팅 과정의 이해를 통해 이러한 에러 상황을 효과적으로 대처 할 수 있다.

2. 리눅스 부팅 과정의 이해

1) 전원 ON

2) BIOS 프로그램 실행 – CPU, MEMORY, VGA 같은 하드웨어에 대한 진단 테스트(POST)를 실행한다. 이상 발생시 비프 음을 내며 멈춘다. POST(Power On Self Test)과정이 이상없이 수행되면 부트디바이스의 MBR(하드 디스크의 첫 섹터,크기는 512 byte)에서 부트로더를 불러들인다.

3) 부트로더가 실행되면 레드햇계열에서는 보통 다음과 같은 메시지가 출력되며 GRUB(GRUB이 부트로더이다)이 실행된다. GRUB은 커널이미지를 메모리에 로드한다.

Booting Red Hat Enterprise Linux Server (2.6.18-8.el5) in 5 seconds...

4) 그 다음 커널에 의한 초기화가 실행되고 드라이버의 적재가 이루어 진다. 이 과정은 dmesg명령이나 /var/log/dmesg 파일에서 확인 할 수 있다. 보통 다음과 같은 것들을 확인 할 수 있다.

커널버전 표시

램 용량 표시

CPU관련 정보 표시

SELinux 상태 표시

Kernel command line 명령 확인

램디스크 할당 (initramfs)

하드드라이브와 파티션 확인

네트워크 카드 확인

파일시스템 활성화

스왑 활성화

5)커널과 드라이버가 로드된 다음에는 /sbin/init 프로세스가 부팅 과정을 마무리 한다. 이때 실행되는 순서를 간략하게나마 나열하면

/sbin/init à /etc/inittab à /etc/rc.d/rc.sysinit à 각 런 레벨 서비스 스크립트

--> /etc/rc.local à 로그인 프롬프트

로 나타낼 수 있다.

3. 각 과정 별 트러블슈팅

1) grub.conf 파일이 손상되거나 내용이 변경되었을때

증상

부팅시 GURB관련 메뉴가 나오지 않음

부팅시 GRUB 콘솔 상태로 바로 이동

mv /boot/grub/grub.conf /boot/grub/grub.conf_bak

해결방법

GRUB 콘솔 명령어로 사용하여 부팅

grub 환경설정파일 손상

root (hd0,0)

cat /etc/fstab

find /etc/fstab

kernel /vmlinuz-2.6.18-92.el5 ro root=/dev/sda7

initrd /initrd-2.6.18-92.el5.img

boot

부팅후 GRUB관련 설정을 점검하고 원인을 찾아 해결한다.

GRUB을 재 설치 한다.

2) MBR 손상시 복구하기

BIOS가 POST과정을 끝마치면 하드디스크의 첫번째 섹터를 읽어드린다. 이부분을 MBR이라고 한다. MBR에는 부트로더와 파티션 정보가 들어있다. 다음과 같은 명령어로 부트로더를 지울 수 있다.

dd if=/dev/zero of=/dev/sda bs=446 count=1

bs를 512로 하면 파티션 정보까지 모두 손상되므로 테스트 서버 외에는 절대 실행하면 안된다. GRUB(부트로더)는 446바이트이내에 설치 되어 있다.

이제 복구를 해보자.

1번 시디로 부팅

#linux rescue

#chroot /mnt/sysimage

#/sbin/grub

grub-install /dev/sda

find /grub/stage1

find /grub/grub.conf

혹은

#/sbin/grub

root (hd0,0)

setup (hd0)

위와같이 GRUB을 재설치하고 리부팅한다.

3) /etc/fstab 손상시

cat /proc/mounts

mount –o remount,rw /

cat /proc/mounts

vi /etc/fstab

에러난 부분 수정후 리부팅

4)/sbin/init 명령어 손상시

rm /sbin/init

/bin/sh: ro: No such file or directory

Kernel panic - not syncing: Attempted to kill init!

SysVinit-2.86-14.i386.rpm 재설치

# linux rescue

#chroot /mnt/sysimage

#ftp 222.239.223.108

#cd centos/5.2/CentOS

#mget Sys*

rpm -Uvh –force SysVinit-2.86-14.i386.rpm

rpm -Vf /sbin/init

chroot /mnt/sysimage

/bin/bash 파일 손상시 다음과 같은 에러 메시지가 나온다.

chroot: cannot run command '/bin/sh' : No such file or directory

#ftp 222.239.223.108

#cd centos/5.2/CentOS

#mget bash*

rpm -Uvh --force --root=/mnt/sysimage bash-*.rpm

기타

/etc/initab, /etc/rc.d/rc.sysinit à initscripts-8.45.19.1.EL-1.el5.centos

주의사항: 시스템을 새로 설치하는게 빠른지 아니면 복구하는게 빠른지 판단을 하여 가장 빠른 복구 프로세스를 수행한다. 자료 백업과 보존을 최우선으로 한다. 가장 안전한 방법을 고른다.

4. 파일 시스템 오류검사 및 복구 요령

파일 시스템이 손상되었을 때 부팅중 문제가 발생 할 수 있다. 파일 시스템이 손상 되었을때의 대표적인 증상은 아래와 같다.

1) 파티션이 Read Only로 마운트 되면서 파일이 생성되지 않는다.

2) 부팅 과정 중 Ctrl+D 입력을 요구 하면서 더 이상 진행이 되지 않는다.

3) 파일시스템이 손상되었을 경우 dmesg명령어나 /var/log/messages에 에러가 남는다.

이러한 상황이 발생 했을 때 fsck명령으로 쉽게 복구 할 수 있다. 다만 파일시스템을 복구할 때 몇 가지 주의 사항이 있는데 이를 지키지 않을 시 데이터를 날려버릴 위험이 있으므로 반드시 다음 주의 사항을 지키면서 복구를 해야 한다.

먼저 파일 시스템을 마운트 시킨 상태에서 복구를 해서는 안된다.

df –h

cat /proc/mounts

명령으로 손상된 파티션이 마운트 되어 있는지 확인한다.

마운트 되어 있으면 umount 시킨 상태에서 복구 명령을 실행 시켜야 한다.

그러면 / 파티션 같은 경우에는 어떻게 복구해야 할까? / 파티션을 umount 시킨다면 복구명령을 실행 할 수 없으니 이런 의문이 당연히 떠 오를 것이다. 이럴때는 다음과 같이 / 파티션을 Read Only로 remount 시킨다음 체크를 실행한다.

#cat /proc/mounts

/dev/root / ext3 rw,data=ordered 0 0

와 같은 줄이 보인다. 다음 명령으로 / 파티션을 Read Only로 마운트 시킬 수 있다.

#mount -o remount,ro /

/dev/root / ext3 ro,data=ordered 0 0

/var /usr 파티션 같은 경우 다음과 같은 에러를 내면서 umount가 되지 않을 수도 있다. /usr 파티션이 사용되고 있기 때문이다.

umount /usr

umount: /usr: device is busy

umount: /usr: device is busy

그러므로 가장 확실한 방법은 잠시 서비스를 내리고 다음과 같이 1번 시디를 이용해서 rescue모드로 부팅을 해서 복구하는 방법이다.

#linux rescue nomount

/dev/sda1 파티션이 ext3 파일 시스템을 사용 하고 있을 때 다음과 같은 명령어로 복구 시킬 수 있다.

#e2fsck –j ext3 –vy /dev/sda1

badblock이 생겼을 때는 -c옵션을 주면 badblock을 체크한다. 그러나 가능하면 badblock이 생겼을 경우 빠른 시간내에 하드를 교체하는 것이 최선이다.

또한 손상 정도가 심한 경우는 파일시스템을 복구해도 차후 같은 증상을 가져 올 수 있기 때문에 서비스를 올린다음 해당 디스크를 교체하는 것이 좋다.

superblock이 손상되었을 경우 다음과 같은 명령어로 복구 시킬 수 있다.


#dumpe2fs /dev/hda1

명령어로 해당 파티션이 정보를 본다. 슈퍼블럭을 확인하고 다음과 같이 복구한다.


#fsck -b 8193 /dev/hda1

슈퍼블럭은 여러 백업본이 있기 때문에 하나가 안되면 다음과 같이 다음 슈퍼블럭을 선택해서 복구하면 된다.
#fsck -b 32768 /dev/hda2

5. 커널패닉이 발생했을 때 위에서 설명한 부팅 과정중 어디에서 에러가 나는지 찾을 수 있어야 한다

그러면 더욱 쉽게 문제점을 해결 할 수 있다. 일단 서버가 돌아가고 있는 상태라면 서버에 리눅스를 처음으로 설치 할 때는 커널 패닉이 없었다는 말이다. 그 뒤에 변화된 환경에 의해 커널패닉이 발생한 것이다.

부팅 할때 발생하는 커널패닉 메세지를 잘 보면 이에 대한 힌트가 담겨 있다. 만약에 운영체제 설치시 하드 디스크 사타 드라이버나 기타 레이드 카드 드라이버를 설치했다면 커널을 업데이트 한 후에는 다시 설치해 줘야 할 것이다. 그렇지 않다면 업데이트된 커널로 부팅을 하면 커널이 드라이버를 적재하는 과정에서 하드디스크(root(hd0,0))를 인식하지 못해서 커널패닉이 발생 할 것이다. 이럴때는 제일 처음 설치할 때의 커널로 부팅을 해 보는 것도 방법이다. 하드디스크의 / 파티션이 손상을 당해서 마운트가 제대로 되지 않으면 mount fail이 뜨면서 커널패닉이 발생할 것이다. 이럴때는 파일 시스템을 체크해서 복구해야 한다. 평소에 부팅할 때 보여지는 메세지들을 잘 분석하고 이해해두자. 리눅스 시스템을 이해하고 트러블슈팅을 하는데 많은 도움을 준다.

Posted by redkite
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함