Author Archives: AR-CHI-VES

Authoritative vs Non-authoritative domains / DNS servers

An authoritative answer comes from a name server that is considered authoritative for the domain which it’s returning a record for (one of the name servers in the list for the domain you did a lookup on).

An authoritative name server is a name server that has the original source files of a domain zone files. The is where the domain administrator has configured the DNS records for a domain. Authoritative DNS server can be master DNS server or its slaves.

Example, Authoritative DNS server,

domain tecadmin.net’s authoritative are alec.ns.cloudflare.com and athena.ns.cloudflare.com. If you directly query to these DNS servers, they will return authoritative answer because they have the original files of domain zone.

$ nslookup tecadmin.net alec.ns.cloudflare.com

Server:         alec.ns.cloudflare.com
Address:        173.245.59.59#53

Name:   tecadmin.net
Address: 104.27.188.217
Name:   tecadmin.net
Address: 104.27.189.217

A non-authoritative answer comes from anywhere else (a name server not in the list for the domain you did a lookup on).

Example, Non-authoritative DNS server, 8.8.8.8 of Google DNS

Non-authoritative name servers do not contain original source files of domain’s zone. They have a cache file for the domains that is constructed from all the DNS lookups done previously. If a DNS server responded for a DNS query which doesn’t have original file is known as a Non-authoritative answer.

$ nslookup tecadmin.net

Server:         8.8.8.8
Address:        8.8.8.8#53

Non-authoritative answer:
Name:   tecadmin.net
Address: 104.27.189.217
Name:   tecadmin.net
Address: 104.27.188.217

What is recursive DNS?

A recursive DNS lookup is where one DNS server communicates with several other DNS servers to hunt down an IP address and return it to the client. This is in contrast to an iterative DNS query, where the client communicates directly with each DNS server involved in the lookup. While this is a very technical definition, a closer look at the DNS system and the difference between recursion and iteration should help clear things up.

The OSI Model & How Information Travels Through The Internet

A user tells their browser to fetch a page from techiess.com The browser makes an HTTPS request to techiess.com. To fetch the required web page it passes the request to its HTTP protocol handler, that is Layer 7 of the OSI model, the Application layer.

When the HTTP protocol handler at Layer 7 recognizes that the request is for a secure document, it passes the request to the TLS library at Layer 5 and 6 of the OSI model. These layers are called the Session and Presentation layers.

In order to open a secure channel, the TLS library needs to establish a connection to the destination. It passes a connection request to TCP which lives at Layer 4 of the OSI model, the Transport layer. The TCP handler receives the connection request. Then, it creates a packet with the “SYN” flag set — the first part of the three-way handshake with the remote server to establish a connection.

After the TCP handler has created a packet to initiate a connection, it passes the packet down to IP which lives at OSI Layer 3, also called the Network Layer. The network layer receives the packet and adds the correct IP information to its header. That informs the internet routers how to route the packet to its destination IP address.

Now that the network layer has a routable packet, it passes it down to Layer 2, the Data-Link layer. The data-link layer adds the router’s MAC address as the local destination address, allowing the router to send the packet out to the Internet.

In order for the packet to get onto the basic networking transmission technologies of the network, it is then passed to OSI Layer 1 or the Physical Layer to complete the task. The physical layer takes the binary packet and physically encodes it onto network cabling — or places it onto the airwaves in the case of a WiFi network — and the packet begins its journey across the local network and out to the wider Internet.

Once the packet reaches the destination server, the whole process reverses and the packet travels back up the layers of the OSI model.

This process happens constantly as your computer communicates with other remote servers on the Internet.

This article is from https://www.wordfence.com/learn/understanding-the-osi-model-video/

==========

OSI Model is 7 layers, Application, Presentation, Session, Transport, Network, Data-Link, Physical. Application layer is for application such as DNS, SMTP, FTP, Telnet, … Presentation layer is for format data, encryption/decryption, Session layer is start/stop session, Transport layer is TCP/UDP, Port Number, Network layer is IP address, Routers, Data-Link layer is MAC Address, switches, Physical layer is cable, Network Interface Cards(NIC), hub.

# How to internet works

For example via HTTPS, we open a page from browser and then browser makes an HTTPS request via HTTP protocol handler. This is application layer, layer 7 of OSI model.

HTTP protocol handler recognizes this request is a secure document. It passes to TLS library at Presentation layer, layer 6 of OSI model and start session at Session layer, layer 5 of OSI model.

TLS libray needs to establish a connection to the destination and it passes a connection request to TCP, Transport layer, layer 4 of OSI model. TCP handler receives and creates packet with “SYN” flag set – it is first part of three-way handshaking.

TCP handler created a packet to initiate a connection, it passes the packet down to IP address, Network Layer. This Network layer routes the packet to destination IP address.

Data-Link Layer, 2nd layer of OSI model, add router’s MAC address as local address, allowing the router to send the packet out to the internet.

And then Physical Layer to complete the task. It takes binary packet and physically encodes it onto network cable or wifi network.

Once the packet reaches the destination server, the whole process reverses and the packet travels back up the layers of the OSI Model.

Linux #26 : Process 종료 및 그에 따른 간단한 설명

Linux System을 운영하다보면 특정 Process를 죽이기 위해 “kill” command를 사용하는 경우가 있죠. “/etc/init.d/” 안에 Control Lib Script로 등록되는 일반적인 Process는 비정상적인 경우가 아니면 “kill”을 사용할 필요가 없는데 경우에 따라서 “kill”을 통해서 Process를 죽여할 때가 있습니다.

시작은 어떤 Process를 죽여야하고 그 Process의 pid(Process ID)가 무엇인지를 확인하는게 필요하죠.

# ps ax
PID TTY STAT TIME COMMAND
1 ? Ss 2:51 init [3]
2 ? S 0:00 [kthreadd]
3 ? S 0:43 [migration/0]
4 ? S 0:16 [ksoftirqd/0]
5 ? S 0:36 [migration/1]
19331 ? Sl 3:57 /sbin/rsyslogd -c5
22222 ? S 1111:11 /usr/local/sbin/proftpd
22560 tty1 Ss+ 0:00 /sbin/mingetty --long-hostname tty1
23384 ? S 0:00 /usr/local/apache2/bin/httpd -k restart
24406 ? S 0:05 /usr/local/apache2/bin/httpd -k restart
24605 ? Ss 2:20 /usr/local/apache2/bin/httpd -k restart
25081 ? S 0:00 /usr/local/apache2/bin/httpd -k restart

“ps ax” command를 통해서 확인하면 대충 이렇겠죠. “ps -elf”라고 입력하면 더 많은 정보가 나옵니다. “ps”에 대해서는 다음시간에 더 자세히 다루도록 하구요.

예로 proftpd daemon을 죽일예정이고,

# ps ax | grep proftpd
22222 ? S 1111:11 /usr/local/sbin/proftpd
..

이런 식으로 표시가 되겠죠. 그리고, pid가 22222 인걸 알 수 있죠. 기본적으로 “kill [pid]”와 같이 실행을 하게 되는데 default로 -TERM이 지정되게 됩니다. 즉

# kill -TERM 22222 = kill 22222

와 같은 것이죠. 여기서 TERM은 Terminate 입니다. “kill” command에서 지정 가능한 Signal은 여러 종류가 있습니다. “-l” option을 지정하면 볼 수 있는데,

# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT
17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU
25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN
35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4
39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6
59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX

이렇게나 많아요. 실제 “kill”에서 사용할 때는 앞의 SIG를 제외하고 예를 들면 1) SIGHUP는 HUP(Hang UP), 2) SIGINT는 INT(Initial) 으로 처리하게 됩니다.
많이 쓰는 건 앞에서 말씀드린 15) SIGTERM 이네요. Default이기도 하고

따라서, 좀 전에 22222 PID를 “kill” 하면 아래와 같이,

#kill -TERM 22222 or kill 22222
[1]+ TErminated /usr/local/sbin/proftpd

와 비슷하게 처리가 될 겁니다. 그런데, “kill” command로 죽일 수 없는 Processs들을 언젠가 만나실 수 있는데 Zombie Process라고도 합니다. 이런 Process들을 죽이려면 때로는 System을 Reboot 해야하는 경우도 있죠. Process의 Status는 위에 “ps ax”의 option 중 “a”가 추가 되었을 때 확인 가능합니다.

# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 10356 476 ? Ss Apr07 2:51 init [3]
root 2 0.0 0.0 0 0 ? S Apr07 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S Apr07 0:43 [migration/0]
root 4 0.0 0.0 0 0 ? S Apr07 0:16 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S Apr07 0:36 [migration/1]
root 6 0.0 0.0 0 0 ? S Apr07 0:17 [ksoftirqd/1]
..
www 23384 0.0 0.0 219396 8316 ? S 06:08 0:00 /usr/local/apache2/bin/httpd -k restart
www 24406 0.0 0.1 225404 18756 ? S May27 0:05 /usr/local/apache2/bin/httpd -k restart
root 24605 0.0 0.0 219264 11172 ? Ss Apr11 2:20 /usr/local/apache2/bin/httpd -k restart
www 25081 0.0 0.0 219528 9588 ? S 05:42 0:00 /usr/local/apache2/bin/httpd -k restart

좀 더 자세하게 볼 수 있도록 “u” option을 더 추가했습니다.

Process의 Status Code를 설명 해 드리면,

PROCESS STATE CODES
Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a
process.
D Uninterruptible sleep (usually IO)
R Running or runnable (on run queue)
S Interruptible sleep (waiting for an event to complete)
T Stopped, either by a job control signal or because it is being traced.
W paging (not valid since the 2.6.xx kernel)
X dead (should never be seen)
Z Defunct ("zombie") process, terminated but not reaped by its parent.

For BSD formats and when the stat keyword is used, additional characters may be displayed:
< high-priority (not nice to other users)
N low-priority (nice to other users)
L has pages locked into memory (for real-time and custom IO)
s is a session leader
l is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
+ is in the foreground process group

아참 꼭 “man” command를 통해 Linux 일반적인 command들의 내용을 참조하는 습관을 기르세요. 최고의 Guide라고 생각이 들어요. 아래 따로 설명을 드렸지만 위 Man page의 내용을 보면 사실 필요없지 않나 생각이 드네요.

D : IO 순번을 기다리는 상태
R : 실행 중
S : 대기 중
T : 중단 중
W : Swapout 된 상태
X : 죽은 상태
Z : Zombie

< : 높은 우선 순위로 실행 중
N : 낮은 우선 순위로 실행 중
L : Real Time 처리 등으로 메모리내에 고정 되어 실행 중 등등

여기서 Zombie는 CPU Time은 소비하지 않는데, Physical Memory나 Swap Memory를 사용하고 있는 경우가 있습니다. 따라서, 계속 늘어나게 된다면 Memory Leak이 발생을 하겠지요.
간단하지만, 알아두면 좋을 듯 하네요.

Linux #25 : Shutdown Command의 Risk를 줄이는 방법

Linux를 운영하다 보면 Shutdown을 해야 하는 경우가 있고 별 생각없이 shutdown -h now를 날리는 경우가 많이 있습니다. 아차하고 생각하는 찰나에 Console 창을 잘 못 골라 다른 서버이구나 싶으면 정말 울고 싶겠죠.

이런 상황을 일단 만들지 않도록 Double-Check을 하는게 굉장히 중요하지만, 사람이라는게 실수를 하는지라 좋은 Command 습관을 기른다면 이런 상황을 좀 더 여유롭게 대처 할 수 있겠지요.

일단 Shutdown Command는 Root에서만 가능하므로 Root를 획득해야 하는 건 당연한데 일반 User Account로 Shutdown 날리는 모습은 다른 사람들에게 보여주지는 맙시다. 🙂
그럼, shutdown -h now에서 해방이 되기 위해서는 now를 추가하는 습관을 과감히 버려야 합니다. 당장 Shutdown을 하고 싶겠지만, High Priority Server 일 수록 계획적이고 여유를 가지고 Shutdown을 날리는게 좋겠지요. Now 대신 아래와 같이 Time을 지정합니다.

# shutdown -h +15
or
# shutdown -h 0:15

Guide)
[hour:min] : 시간과 분은 2 Digits의 수치를 지정 할 수 있습니다. 예를 들어서 지금부터 1시간 30분후에 Shutdown 하고 싶으면 "shutdown -h 01:15"라고 입력하면 됩니다.
[+min] : 지정한 몇분 이후에 Shutdown이 되겠지요. 앞에서 설명 했던 것 처럼 15분의 경우 "shutdown -h +15" 입니다.

이렇게 하면 15분 후에 Shutdown이 시작되게 되고 혹시 잘 못 날린 Shutdown Command라면 대처할 시간적인 여유를 갖게 되겠지요.

이제, 이런 Shutdown까지 시간적인 여유가 생긴 상황에서 혹시 무언가 문제가 있다는 것을 발견하고 Shutdown을 중지 할 수 있는 기회가 있고, 충분한 시간적인 여유가 있다면 High Priority Server이면 일수록 행복한 상황일 것입니다.

그럼, Shutdown을 어떻게 중지 시켜야 할까요?
Shutdown이라고 하는게 shutdown command에 의해서 활성화가 됨으로 “shutdown -h +15″와 같이 Command를 날리고 15분이 지나기 전까지는 이 Command만 활성화 되어 있겠죠.
결과적으로 Shutdown command를 kill command로 내리면 됩니다.

"ps ax"라는 command로 process를 확인 하면 "shutdown -h +15"를 보실 수 있지요.
# ps ax
PID TT STAT TIME COMMAND
...
1745 ?? S<s 0:00.00 shutdown -h +15
1749 p0 R+ 0:00.00 ps ax
...

# ps ax | grep shutdown | sed -e 's/^ * //' | cut -d ' ' -f 1
이 Command의 목적은 PID 값을 호출하는 것이고, 즉 Kill과 같이 사용하면

# kill `ps ax | grep shutdown | sed -e 's/^ * //' | cut -d ' ' -f 1`
Kill [PID]가 실행 된 이후

# ps ax | grep shutdown

으로 "shutdown -h +15" Command가 정상적으로 Killed 되었는지를 확인 하시면 됩니다.

추가로, “wall” command로 Shutdown 전 Login하고 있는 모든 User에게 Message를 보내거나, 사전에 /etc/motd를 수정해서 여기서 motd는 Message of the day라는 건 아시죠.
사전에 Shutdown Schedule을 공유 하는 것도 System Operation에 좋은 배려라고 볼 수 있습니다.

Linux #24 : Remote Syslog Configuration

이번 내용은 Remote Syslog Server를 구축하는 방법입니다. 요즘은 더욱 강화된 rsyslog를 더 많이 사용하고 있는데, 그 건 다음시간에 다루도록 하겠습니다.
일단 일반 Syslog 서버를 Remote Syslog 서버로 바꾸기 위해서는 아래와 같은 설정이 필요합니다.

Remote Syslog Server
Change configuration file /etc/sysconfig/syslog

# vi /etc/sysconfig/syslog
..
SYSLOGD_OPTIONS="-m 0" => SYSLOGD_OPTIONS="-m 0 -r"
..
:wq!

-r means receiving log data from the other servers.

Restart Syslog daemon

# /etc/init.d/syslog restart or service syslog restart

그리곤, Target이 될 각 Server를 설정하면 됩니다.

Changing configuration file /etc/syslog.conf

# vi /etc/syslog.conf
..
kern.warining;*.err;authpriv.none @syslog
*.info;mail.none;authpriv.none;cron.none @syslog
authpriv.* @syslog
*.emerg @syslog
local7.* @syslog
..
:wq!

@syslog라고 입력을 했는데, 이 경우 /etc/hosts에 syslog의 IP가 정의 되어 있거나 /etc/resolv.conf에 base domain이 정의가 되어 있어야 겠죠.

# vi /etc/hosts
..
192.168.1.10 syslog
..

or

# vi /etc/resolv.conf
search techiess.com
nameserver 192.168.1.1
nameserver 192.168.1.2

그리고, 다시 Restart Syslog daemon 하면 완료가 됩니다.
또한, Log Processing, Parsing tool들을 사용하면 Log를 통합해서 모니터링 할 수 있습니다.

Syslog를 Remote로 전송하는 경우 TCP/UDP 514 Port를 사용하게 되는데 단점이 전송해야하는 Log의 양이 많아지는 경우는 Log의 Lost가 발생 할 수 있습니다.
따라서, Log를 전송해야만 하는 것들만 처리 될 수 있도록 Front Filtering을 고려하면 Network Traffic도 Saving하고 더욱 효율이 좋아질 것 입니다.

Syslog는 일반적으로 사용되는 Log tool인데, rsyslog, syslog-ng 등 좀 더 다양한 기능을 구현 할 수 있는 Log tool도 있습니다.
이런 것들은 다음 시간에 다루도록 하겠습니다.

Linux #23 : IO Monitoring with Cacti #2

IO Monitoring with Cacti #1에서 Rsync를 이용해서 Cacti Server에 Data를 전송한다고 하였는데 아래와 같이 rsync를 설정하였습니다.

$ more /etc/rsyncd.conf
..
[iomon]
path = [File Location Directory]/iomon
uid = root
gid = root
read only = false
hosts allow = [Allowed IP Addresses]
hosts deny =
..

Monitoring Target 서버에서 온 Data file은 지난번에 설명했던 것 처럼 아래와 같은 형식이 었고,

$ more iostat_[IP_Address]_emcpowerd
device:emcpowerd tps:48 brs:289 bws:101 br:17368 bw:6096 rrqms:0 wrqms:0 rs:36 ws:12 rsecs:289 wsecs:101 rkbs:8 wkbs:71555 avgrqsz:2 avgqusz:20 await:100 svctm:100 util:100
$ more iostat_[IP_Address]_emcpowerh
device:emcpowerh tps:0 brs:0 bws:0 br:0 bw:0 rrqms:0 wrqms:0 rs:0 ws:0 rsecs:0 wsecs:0 rkbs:0 wkbs:63182 avgrqsz:0 avgqusz:0 await:100 svctm:100 util:100

이런 형식의 Data file은 Cacti에서 간단한 설정으로 값을 수집할 수 있습니다. 여러 서버를 처리해야 함으로 아래와 같이 $1, $2 변수를 Cacti에서 index 값으로 입력 할 수 있게 하였습니다.

$1 => IP Address
$2 => Device Name


$ more mcd.sh
#!/bin/sh
DATA=`cat /[iomon location]/iomon/iostat_$1_$2`
echo $DATA

이제 나머지 부분은 Cacti에서 만들어진 Graph, Data Template과 Collection Methods의 Data Input Methods 기능을 이용하면 됩니다.

Linux #21 : MySQL Log를 Syslog(Remote Syslog)로 관리

정말 오래간만에 하는 포스팅 인듯 하네요. = =;

MySQL의 Error log를 Remote Syslog를 통해서 관리를 해보고자 아래와 같이 Script를 만들어 보았습니다.
Syslog 수집 서버를 구성하고 수집 서버를 통해서 MySQL Error Log를 통합 관리 하기 위하여 사용하고 있습니다.
Remote Syslog 수집 서버에 개발해 놓은 Application에 Filtering 기능을 이용하여 MySQL과 관련 된 Critical Log를 검출하여
Alert를 발생시키는 구조입니다.

### MYSQL_LOG_TO_SYSLOG.SH
#!/bin/sh
# ================================================================
# -process
# Mysql Alert Log to Remote Syslog
# -process content
# Mysql Alert Log to Remote Syslog
# -how to use
# Mysql_Log_To_Syslog.sh
#
# -NOTE
#
# -created date
# 2010/05/17 Jeff Kim
#
# ================================================================
##################################################################
MYSQL_VAR=[MySQL Var Directory]
FACILITY=syslog
PRIORITY=info
HOSTNAME=`hostname`
SCRIPT_NAME="MYSQL ALERT LOG TO SYSLOG"

function Printmsg {
TYPE="$1"
TEXT="$2"
echo "`date \"+%Y-%m-%d %H:%M\"` [$1] $2" >> $TMP/message.log
echo "`date \"+%Y-%m-%d %H:%M\"` [$1] $2"
logger -p daemon.notice "[$1] $2"
}

function Endscript {
Printmsg "INFO" "End Script : $SCRIPT_NAME."
echo "################################################################################################"
exit
}

function Startscript {
SCRIPT_START="$INIT_SCRIPTS"
if [ -z "$SCRIPT_START" ];then
cat < ###############################################################################################
$DATE_TIME [INFO] ### $SCRIPT_NAME ###
EOF
fi

#if [ "$SCRIPT_START" != ""y"" ];then
# Endscript
#else
# Printmsg "INFO" "Pressed 'y' : $SCRIPT_NAME"
#fi
}

function Whoamiroot {
WHOAMI=`whoami`
if [ "$WHOAMI" != "root" ];then
Printmsg "ERROR" "Permission deny. Only root!"
Printmsg "INFO" "Forced-end this script."
Endscript
fi
}

Startscript

if [ "$HOSTNAME" = "" ];then
Printmsg "ERROR" "Please, Check Host Name.";Endscript
else
Printmsg "INFO" "nohup tail -f ${MYSQL_VAR}/${HOSTNAME}.err | logger -t MySQL -p ${FACILITY}.${PRIORITY} &"
nohup tail -f ${MYSQL_VAR}/${HOSTNAME}.err | logger -t MySQL -p ${FACILITY}.${PRIORITY} &
fi
Endscript

script가 실행되고 있고, remote syslog 서버에 Log를 보내는 설정이 되어 있다면 MySQL Error가 발생하는 즉시 Syslog와 Remote Syslog 서버에 MySQL 관련 Log가 기록이 됩니다. 그리고 이 로그를 다시 재처리하면 MySQL의 Log를 모니터링 할 수 있지요.

Linux #22 : IO Monitoring with Cacti #1

iostat command를 통해서 IO Status Data를 수집하는데 Cacti로 Graph를 그리기 위해서 아래와 같이 매일 1분단위로 Data를 수집합니다.
60 (Sec) / 1441 (1일). Crontab에 등록하여 그날 그날의 Data가 저장되도록 rotate를 합니다.

#!/bin/sh
# ================================================================
# -process
# Gathering IOstat data per day
# -process content
# Gathering IOstat data per day
# -how to use
# Gathering_iostat_per_day.sh
# in crontab (everyday 23:59)
# 59 23 * * * [File Location Directory]/Gathering_iostat_per_day.sh
#
# -NOTE
#
# -created date
# 2011/08/17 Jeff Kim
#
# ================================================================
BASE=[File Location Directory]
##################################################################

iostat -xt 60 1441 > $BASE/iostat_`date +%Y%m%d -d +1day` &
iostat -dt 60 1441 > BASE/iostat_tps_`date +%Y%m%d -d +1day` &

iostat에서 측정가능한 Parameter에 대한 iostat key를 만들었는데 아래와 같습니다. 개별 Parameter의 Data 추출시 이용하게 됩니다.
뒤에 나오게 되는 Script를 보시면 이 Key가 Cacti에서 Index로 사용됩니다.

$ more iostat_key.infodevice:
tps:
brs:
bws:
br:
bw:
rrqms:
wrqms:
rs:
ws:
rsecs:
wsecs:
rkbs:
wkbs:
avgrqsz:
avgqusz:
await:
svctm:
util:

또, 개별 Device에 대한 측정값이므로 device Key를 만들었고 아래와 같습니다. EMC Storage를 사용하고 있어서 emcpower[X]라는 device name이고 device에 따라 name이 다르므로 수정해야 합니다.

$ more device.infoemcpowerb
emcpowerd

예로 iostat -xt 를 찍어보면 아래와 같이 출력됩니다.

$ iostat -xt
Linux [Kernel Version] ([HostName]) 12/14/2011 _x86_64_ (8 CPU)

12/14/2011 11:26:15 AM
avg-cpu: %user %nice %system %iowait %steal %idle
1.66 0.00 0.50 0.94 0.00 96.90

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 0.06 1.90 13.29 1.16 187.92 24.52 14.71 0.11 7.49 1.90 2.74
cciss/c0d0 0.00 12.62 1.53 2.93 12.25 124.46 30.66 0.03 7.25 0.32 0.14
cciss/c0d1 0.00 42.27 44.05 1.87 352.42 353.05 15.36 1.17 25.50 0.08 0.38
emcpowerb 0.00 0.00 0.00 0.00 0.00 0.00 7.99 0.00 3.46 1.09 0.00
emcpowerd 0.00 0.00 26.70 6.14 374.29 49.09 12.89 0.52 8.66 29.06 95.42

Data가 수집되고 있고(위 script 내용대로라면 iostat_20111214, iostat_tps_20111214), device key(device.info)와 iostat key(iostat_key.info)가 존재한다면 아래의 script를 통해 필요한 값을 추출하고 이를 Cacti에서 Graph로 그릴 수 있도록 처리 가능합니다. Crontab에 등록하여 Data file이 갱신될 수 있도록 하고 수집 cycle은 1분으로 되어 있는데 조정하시면 됩니다.

$ more Monitoring_iostat_to_cacti.sh#!/bin/sh
# ================================================================
# -process
# Monitoring IOstat data to cacti
# -process content
# Monitoring IOstat data to cacti
# -how to use
# [File Location Directory]/Monitoring_iostat_to_cacti.sh bond0
# in crontab (every min)
# * * * * * [File Location Directory]/Monitoring_iostat_to_cacti.sh bond0
# -NOTE
#
# -created date
# 2011/08/19 Jeff Kim
#
# ================================================================
BASE=[File Location Directory]
DEVICES=`cat $BASE/device.info`
DATE=`date +%Y%m%d`
KEYS=`cat $BASE/iostat_key.info`
###################################################################

rm -f $BASE/tmp*
for device in $DEVICES
do
TMP1=`cat $BASE/iostat_tps_$DATE | grep $device | cat -n | /usr/bin/perl -ane 's/\s+/,/g;print "$_\n";' | tail -n 1 | tr ',' '\n'`
TMP2=`cat $BASE/iostat_$DATE | grep $device | cat -n | /usr/bin/perl -ane 's/\s+/,/g;print "$_\n";' | tail -n 1 | tr ',' '\n'`
num=0
for value in $TMP1
do
if [ $num -ge 1 ];then
echo $value >> $BASE/tmp_iostat_value
fi
num=`expr $num + 1`
done
num=0
for value in $TMP2
do
if [ $num -ge 2 ];then
echo $value >> $BASE/tmp_iostat_value
fi
num=`expr $num + 1`
done

num=1
for key in $KEYS
do
echo $key`cat $BASE/tmp_iostat_value | head -n $num | tail -n1 | awk -F"." '{print $1};'` >> $BASE/tmp_iostat_$device
num=`expr $num + 1`
done

cat $BASE/tmp_iostat_$device | tr '\n' ' ' > $BASE/iostat_`/sbin/ifconfig $1 | grep "inet addr:" | awk -F" " '{print $2};' | awk -F":" '{print $2};'`_$device
rm -f $BASE/tmp*
rsync -arv $BASE/iostat_`/sbin/ifconfig $1 | grep "inet addr:" | awk -F" " '{print $2};' | awk -F":" '{print $2};'`_$device [Cacti_Server_HostName]::[Rsync Community Name]
done

Script를 보면 rsync로 Cacti Server에 Data를 전송하고 있는데 Cacti Server에서 Data File을 체크하는게 SNMP EXEC등으로 받아가는 것 보다 간편해서 그렇게 하고 있습니다. 그럼, 어떤 file들을 보내게 되는냐 하면

$ more iostat_[IP_Address]_emcpowerd
device:emcpowerd tps:48 brs:289 bws:101 br:17368 bw:6096 rrqms:0 wrqms:0 rs:36 ws:12 rsecs:289 wsecs:101 rkbs:8 wkbs:71555 avgrqsz:2 avgqusz:20 await:100 svctm:100 util:100
$ more iostat_[IP_Address]_emcpowerh
device:emcpowerh tps:0 brs:0 bws:0 br:0 bw:0 rrqms:0 wrqms:0 rs:0 ws:0 rsecs:0 wsecs:0 rkbs:0 wkbs:63182 avgrqsz:0 avgqusz:0 await:100 svctm:100 util:100

이 Data file은 crontab에 설정된 내용대로 매분(혹은 매 5분) 단위로 갱신되고 Local 및 Cacti server에 전송이 되겠죠. Cacti Server에서 이 Data값을 이용해서 Graph를 그리면 됩니다. 나머지 부분은 Linux #23 : IO Monitoring with Cacti #2 에서 설명하도록 하겠습니다.

Linux #20 : RedHat Linux Kernel Crash Analysis

지난 시간에는 NetDump를 통한 Crash Dump에 대해서 적었었죠.
(그 이후 몇 달만에 이 글을 쓰는지 모르겠네요. 정리는 한 참 전에 해 놓고.. 나름 바쁘다는 핑계로 = =;)
Dump를 뜨는 것도 중요하죠. Console화면을 놓치는 경우 Linux에서 발생한 Kernel Panic과 같은 Error를 Dump File이 없이 확인 하는 게 어렵기 때문에.
그럼, 그걸 분석하는 방법을 배워야 겠죠.

그래서 RedHat Crash Utility라는게 존재 합니다. 이 Tool을 사용하기 위해서는 3개지의 전제 조건이 필요합니다.

  • Kernel Object File : A vmlinux Kernel Object file이 있어야하고, 일반적으로는 /boot, /lib/modules에서 존재합니다.
  • Kernel Crash Dump : Diskdump, Netdump, Kdump 등에 의해서 Dump된 Filename이 vmcore 혹은 vmcore.incomplete가 있어야하며 일반적으로 /var/crash에 저장됩니다.
  • Linux Kernel Version : Red Hat Linux 6.0 이하가 아니면 됩니다.

** 여기서 사용한 Version은 RHEL 4 U5 x86_64입니다.

Install Crash Utility의 설치
설치는 간단하게 RPM Package로 가능합니다. 설치된 crash file의 경로는 /usr/bin/crash.

$ rpm -ivh crash-4.0-3.9.x86_64.rpm
warning: crash-4.0-3.9.x86_64.rpm: V3 DSA signature: NOKEY, key ID 443e1821
Preparing... ########################################### [100%]
1:crash ########################################### [100%]

또한, Kernel을 Debug하기 위한 Kernel-debuginfo RPM Package가 필요하다.

# rpm -ivh kernel-debuginfo-2.6.9-55.EL.x86_64.rpm
Preparing... ########################################### [100%]
1:kernel-debuginfo ########################################### [100%]
# ls -l /usr/lib/debug/lib/modules/
total 16
drwxr-xr-x 3 root root 4096 Apr 25 17:55 2.6.9-55.EL
drwxr-xr-x 3 root root 4096 Apr 25 17:55 2.6.9-55.ELlargesmp
drwxr-xr-x 3 root root 4096 Apr 25 17:56 2.6.9-55.ELsmp
drwxr-xr-x 3 root root 4096 Apr 25 17:56 2.6.9-55.ELxenU
# ls -l /usr/lib/debug/lib/modules/2.6.9-55.EL
total 38320
drwxr-xr-x 9 root root 4096 Mar 21 15:24 kernel
-rwxr-xr-x 1 root root 39190296 Apr 20 2007 vmlinux

위에서 언급 한 것 처럼 System Crash(Kernal Panic)에 의해 저장되는 file은 vmcore이고, 해당 file은 /var/crash에 저장된다.
Dump를 통해서 저장 된 vmcore file을 확인 해 보자.

# strings vmcore | fgrep -m1 'Linux '
Linux version 2.6.9-55.ELsmp ([email protected]) (gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)) #1 SMP Fri Apr 20 16:36:54 EDT 2007

이제 모든 준비가 완료 되었으니, crash를 실행 해 봅시다. 아래와 같이 실행합니다.

# crash [Module vmlinux의 위치] [vmcore file의 위치]

# crash /usr/lib/debug/lib/modules/2.6.9-55.ELsmp/vmlinux /var/crash/[IP Address]-2011-03-16-22\:28/vmcore

crash 4.0-3.9
Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006 IBM Corporation
Copyright (C) 1999-2006 Hewlett-Packard Co
Copyright (C) 2005 Fujitsu Limited
Copyright (C) 2005 NEC Corporation
Copyright (C) 1999, 2002 Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions. Enter "help copying" to see the conditions.
This program has absolutely no warranty. Enter "help warranty" for details.

GNU gdb 6.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...

KERNEL: /usr/lib/debug/lib/modules/2.6.9-55.ELsmp/vmlinux
DUMPFILE: /var/crash/[IP Address]-2011-03-16-22:28/vmcore
CPUS: 8
DATE: Sat Mar 19 13:24:07 2011
UPTIME: 9 days, 17:24:48
LOAD AVERAGE: 0.25, 0.28, 0.22
TASKS: 190
NODENAME: [HostName]
RELEASE: 2.6.9-55.ELsmp
VERSION: #1 SMP Fri Apr 20 16:36:54 EDT 2007
MACHINE: x86_64 (2666 Mhz)
MEMORY: 8.7 GB
PANIC: ""
PID: 0
COMMAND: "swapper"
TASK: 10037e627f0 (1 of 8) [THREAD_INFO: 100069a6000]
CPU: 6
STATE: TASK_RUNNING (PANIC)

crash>

얼마전에 절 괴롭혔던 HP DL360G5 장비의 Memory 관련 Error 입니다. Physical Memory Check를 해도 Error가 검출되지 않아
결국 Server와 Memory를 교체하고 그 뒤로 동일한 Error는 발생하지 않았습니다.

Crash의 명령어를 통해 좀 더 다양하게 확인 가능합니다.. 명령어는 아래와 같이 help 로 확인 할 수 있습니다.

crash> help

* files mod runq union
alias foreach mount search vm
ascii fuser net set vtop
bt gdb p sig waitq
btop help ps struct whatis
dev irq pte swap wr
dis kmem ptob sym q
eval list ptov sys
exit log rd task
extend mach repeat timer

crash version: 4.0-3.9 gdb version: 6.1
For help on any command above, enter "help ".
For help on input options, enter "help input".
For help on output options, enter "help output".

Linux #19 : Installation Apache + PHP + Subversion

PHP개발을 위해 Apache와 Subversion을 구축 할 때 사용했던 App와 설치 옵션 들입니다.

SQLite
Link : http://www.sqlite.org/
Current Source version : 3.6.15

$ ./configure
$ make;make install

Linux(RHEL)에 설치된 Version을 사용해도 되고 Source Version을 별도로 설치해서 사용해도 됩니다.

BDB (Berkeley DB)
Link : http://www.oracle.com/technetwork/database/berkeleydb/downloads/index.html
Current Source version : 4.7.25

$ cd $BASE/build_unix
$ ../dist/configure --prefix=/usr/local
$ make install

Apr과 Apr-util은 다른 이것 저것들을 해보기 위해서 설치 했습니다. 개인적으로 App들을 개별적인 Directory에 관리하는 걸 선호해서 prefix를 일일이 설정 해 주기도 합니다.

Apr
Link : http://apr.apache.org/
Current Source version : 1.3.5

$ ./configure --prefix=/usr/local/apr

Apr-util
Link : http://apr.apache.org/
Current Source version : 1.3.7

$ ./configure --prefix=/usr/local/apr --with-berkeley-db=/usr/local/lib --with-apr=/usr/local/apr --with-ldap

Apache
Link : http://httpd.apache.org/
Current Source version : 2.2.11

$ ./configure --prefix=/usr/local/apache2 --enable-proxy --enable-proxy-http --enable-proxy-balancer --enable-dav --enable-rewrite --enable-deflate --enable-headers --enable-logio --enable-expires --enable-so --with-berkeley-db=/usr --with-expat=builtin --with-ldap --enable-authnz-ldap=shared --enable-ldap=shared --with-ssl=/usr --enable-ssl --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr

Subversion
Link : http://subversion.tigris.org/
Current Source version : 1.6.3

$ ./configure --with-apxs=/usr/local/apache2/bin/apxs --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr --with-berkeley-db=db.h:/usr/local/include:/usr/local/lib:db-4.7 --with-sqlite=/usr/local/sqlite --with-neon=/usr/local --with-ssl

PHP
Link : http://www.php.net/
Current Source version : 5.2.8

$ ./configure --prefix=/usr/local/php --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/local//mysql --with-gd --with-pear --with-ldap --enable-sysvsem --enable-sysvshm --enable-sysvmsg --with-gettext --with-curl -enable-gd-native-ttf --with-pic --enable-wddx --with-kerberos --with-mcrypt --enable-mbstring --enable-sockets --with-freetype-dir --with-jpeg-dir --with-snmp --enable-ucd-snmp-hack --enable-pcntl --with-zlib

혹 compile이 안되고 아래와 같은 Error가 있을 경우, libtool-ltdl을 설치합니다.

/usr/bin/ld: cannot find -lltdl
collect2: ld returned 1 exit status
$ yum install libtool-ltdl.x86_64 libtool.x86_64 or libtool-ltdl.i386 libtoolxi386

그럼, 이제 PHP와 Subversion을 사용하기 위한 Apache를 설정합니다.

PHP 관련 설정

$ vi /usr/local/apache2/conf/httpd.conf
..
# PHP
Include conf/extra/httpd-php.conf
..
$ vi /usr/local/apache2/conf/extra/https-php.conf
#
# PHP is an HTML-embedded scripting language which attempts to make it
# easy for developers to write dynamically generated webpages.
#
LoadModule php5_module modules/libphp5.so
#
# Cause the PHP interpreter to handle files with a .php extension.
#
AddHandler php5-script .php
AddType text/html .php
#
# Add index.php to the list of files that will be served as directory
# indexes.
#
DirectoryIndex index.php
#
# Uncomment the following line to allow PHP to pretty-print .phps
# files as PHP source code:
#
#AddType application/x-httpd-php-source .phps

Subversion관련 설정

$ vi /usr/local/apache2/conf/httpd.conf
..
# SVN
Include conf/extra/httpd-svn.conf
..
$ vi /usr/local/apache2/conf/extra/https-svn.conf
DAV svn
SVNPath /home/www/svn/project1
# Apache의 authentication을 사용할 경우
AuthType Basic
AuthName "Secure Area"
AuthUserFile /usr/local/apache2/.htaccess
Require valid-user jeff

.htaccess File을 생성할 필요가 있으므로 아래와 같이..

$ /usr/local/apache2/bin/htpasswd -c /usr/local/apache2/.htaccess jeff
New password:

SVN과 관련 된 Repository를 생성 한다. 위 설정대로라면

$ svnadmin create /home/www/svn/project1

이후 WebDAV를 경유해서 Repository에 접근 할 시 아래와 같은 에러가 발생 한다면


Could not open the requested SVN filesystem

$ tail -f /usr/local/apache2/log/error_log
(20014)Internal error: SQLite compiled for 3.6.15, but running with 3.3.7
Could not fetch resource information. [500, #0]
Could not open the requested SVN filesystem [500, #200030]
Could not open the requested SVN filesystem [500, #200030]

이는 PHP를 먼저 설치하고 Subversion을 설치 할 경우 아래와 같은 Error가 나는 경우가 있는데, 이는 /usr/local/apache2/modules/mod_dav_svn.so이 SQLite의 3.6.15가 설치되었음에도 불구하고 3.3.7을 보고 있는 경우로 PHP Module인 libphp5.so가 입력되어 있으면 libphp5.so로 인해 Subversion을 도입시에 같은 오래된 library를 link해 버리는 문제가 있습니다.
따라서 PHP Module을 comment 처리 한 후에 Subversion을 재설치하면 해결이 됩니다.