Friday, May 13, 2016

KvmTroubleShooting

부팅후 일정 시간(5min~) 경과후 tcpdump 실행시 network 단절 | system down 현상 분석


문제 발생 서버 정보

Date

2012/10/17

Server

한국의 KVM 제공 업체들 중의 하나

OS 정보

CentOS 6.3 / x86_86 / 2.6.32-279.9.1.el6.x86_64

CPU 정보

processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 6
model           : 2
model name      : QEMU Virtual CPU version 0.14.1
stepping        : 3
cpu MHz         : 2200.000
cache size      : 512 KB
fpu             : yes
fpu_exception   : yes
cpuid level     : 4
wp              : yes
flags           : fpu de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36   clflush mmx fxsr sse sse2 syscall nx lm up unfair_spinlock pni cx16 popcnt hypervisor lahf_lm abm sse4a
bogomips        : 4400.00
TLB size        : 1024 4K pages
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual

문제 확인 필요 사항들

  • KVM 의 물리적 구성 정보
  • KVM 의 Network 구성 정보
  • KVM 의 부모 머신의 튜닝 정보(network…current_clocksource…)

문제의 현상

시스템 부팅후 몇분 경과후 -i 옵션을 제외한 tcpdump 실행시 시스템 멈춤 현상.
멈춤이 풀린후 tcpdump 재실행시 정상 출력됨.
tcpdump 마지막 실행후 5분 이상 경과후 tcpdump 재실행시 시스템 멈춤 현상 재발생.
해당 현상은 tcpdump 마지막 실행후 경과 시간이 길어질수록 재실행시 멈춤 현상이 더 오래 지속 됨.
해당 현상이 발생 될때 간혹 /var/log/messages 에 아래 와 같은 로그가 기록 됨.
kernel: Clocksource tsc unstable (delta = -25769803766 ns). Enable .........

문제의 원인

  1. KVM 의 guest 머신의 usb device 장치 인식 실패 가능성?
  2. libcap 의 API 오류 가능성?

문제의 재현

  1. tcpdump 를 통한 재현
    $ tcpdump

  2. tcpdump 소스스 분석을 통해 pcap_lookupdev() 함수에서 hang 확인

  3. 간단하게 code 를 통한 재현 [libpcap hang 재현 코드]
    $ vi pcap_hang.c

    
    #include <stdio.h>
    
    
    #include <pcap.h>
    
    
    int main()
    {
    char *dev=NULL, errbuf[256];
    dev =  (dev == NULL) ? pcap_lookupdev(errbuf) : dev;
    if (dev == NULL) {
      fprintf(stderr, "pcap_lookupdev : %s\n", errbuf);
      return(1);
    }
    printf("# Interface: %s\n", dev);
    return(0);
    }

    $ gcc -o pcap_hang pcap_hang.c -lpcap
    $ ./pcap_hang

문제의 해결 방법들

  1. Option -i 로 interface 를 명시 하는것으로 이슈는 해결 된다.
    $ tcpdump -i eth0

  2. libpcap 의 수정

    • Call 추적

      0 pcap_lookupdev()->pcap_findalldevs() : libpcap-1.3.0/inet.c
      1 pcap_findalldevs()->pcap_platform_finddevs() : libpcap-1.3.0/fad-getad.c
      2 pcap_platform_finddevs()->usb_platform_finddevs() : libpcap-1.3.0/pcap-linux.c
      3 usb_platform_finddevs()->usb_dev_add() : libpcap-1.3.0/pcap-usb-linux.c
    • 문제를 발생하는 Call은 libpcap의 pcap_lookupdev() 함수 실행시 문제가 발생 하는 것으로 보인다.

    • 문제가 발생하는 함수의 중요 부분은 usb_dev_add() 부분으로 PCAP_SUPPORT_USB 를 define 하지 않고 Compile 하면 된다.
  3. 근본적인 문제 해결을 위해서는 아래 사항 또한 확인이 필요해 보인다. (Parent 에 권한이 없는 외부 서버)

    • host & guest 머신의 ntpd 실행 여부를 확인 및 동기화 설정

      • CPU Clock 를 위한 host & guest 의 시간 동기화는 필수 이다.
    • KVM 부모 머신과 자식 머신의 current_clocksource 를 동일하게 설정

      • clocksource 실시간 변경하기
        $ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
        kvm-clock tsc hpet acpi_pm

        $ echo "hpet" > /sys/devices/system/clocksource/clocksource0/current_clocksource

      • clocksource 부팅시 적용하기
        $ vi /etc/grub.conf

        kernel /boot/vmlinuz-2.6.32-279.9.1.el6.x86_64 …... clocksource=hpet

    • perf 등의 명령어를 사용하여 상태를 모니터링

관련 링크

Related kernel mailing list



CreateYumRepository

구축 환경


  • OS
    • CentOS 6
  • Arch
    • x86_64

RPM Build Server 구축


Install RPM for Build & Repository

$ yum install rpm-build
$ yum install createrepo
$ yum install rng-tools

Create GPG Key

/proc/sys/kernel/random/entropy_avail 의 값 증가 시키기(1000이상)

$ rngd -r /dev/urandom

GPG key 생성하기(Default 옵션으로 진행)

$ gpg --gen-key

gpg (GnuPG) 2.0.14; Copyright (C) 2009 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: directory `/root/.gnupg' created
gpg: new configuration file `/root/.gnupg/gpg.conf' created
gpg: WARNING: options in `/root/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/root/.gnupg/secring.gpg' created
gpg: keyring `/root/.gnupg/pubring.gpg' created
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: YoungJoo.Kim
Email address: vozltx@gmail.com
Comment: Vozlt Corp.
You selected this USER-ID:
    "YoungJoo.Kim (Vozlt Corp.) <vozltx@gmail.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

can't connect to `/root/.gnupg/S.gpg-agent': 그런 파일이나 디렉터리가 없습니다
gpg-agent[1841]: directory `/root/.gnupg/private-keys-v1.d' created

                                                                                                                                                                                      3Please re-enter this passphrase                                                                                                                3                                                                                                                                               3Passphrase ***********_____________________________                                                                                            3                                                                                                                                               3      <OK>                             <Cancel>            

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key A511F848 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/A511F848 2013-02-19
      Key fingerprint = 5DBB 3608 1F7C 8114 D27D  923A F79D 8B55 A511 F848
uid                  YoungJoo.Kim (Vozlt Corp.) <vozltx@gmail.com>
sub   2048R/FEAA622E 2013-02-19

GPG Key 생성 확인

$ gpg --list-keys

/root/.gnupg/pubring.gpg
------------------------
pub   2048R/A511F848 2013-02-19
uid                  YoungJoo.Kim (Vozlt Corp.) <vozltx@gmail.com>
sub   2048R/FEAA622E 2013-02-19

GPG Key 내보내기(Rpm 으로 묶어서 배포)

$ gpg --export -a 'YoungJoo.Kim' > RPM-GPG-KEY-CentOS-6-Vozlt

GPG Key 설치하기(빌드시에는 안해도 됨)

$ rpm --import RPM-GPG-KEY-CentOS-6-Vozlt

/etc/rpm/macros.key 작성하기(빌드만 하려면 4, 5 제외하고 여기까지만 하면 됨)

$ vi /etc/rpm/macros.key

# %_signature, %_gpg_name 을 정확하게 기재한다.(gpg --list-keys 로 확인)
%_sourcedir         %{_topdir}/SOURCES/%{name}
%_signature         gpg
%_gpg_name          YoungJoo.Kim (Vozlt Corp.) <vozltx@vozlt.org>
%packager           Vozlt manager <vozltx@vozlt.org>
%vendor             Vozlt Corp.
%dist               .el6.vozlt
%_topdir            /usr/src/redhat

관련 링크

GPG Key Manual

RPM Repository Server 구축


Repository Directory 생성

$ mkdir -p /repository/centos/6/SRPMS
$ mkdir -p /repository/centos/6/i386
$mkdir -p /repository/centos/6/x86_64

GPG Key 복사

$ cp -af RPM-GPG-KEY-CentOS-6-Vozlt /repository/centos/6

RPM 저장

$ cp -af /usr/src/redhat/RPMS/x86_64/*.rpm /repository/centos/6/x86_64/
$ createrepo /repository/centos/6/x86_64

YUM RPM Repository 등록

remote 구축시

$ vi /etc/yum.repos.d/Vozlt.repo

[vozlt]
name=CentOS-$releasever - rpms.example.com
baseurl=http://rpms.example.com/centos/$releasever/$basearch/
gpgcheck=1
gpgkey=http://rpms.example.com/centos/$releasever/RPM-GPG-KEY-CentOS-6-Vozlt

local 구축시

$ vi /etc/yum.repos.d/Vozlt-local.repo

[vozlt]
name=CentOS-$releasever - rpms.example.com
baseurl=file:///repository/centos/$releasever/$basearch/
gpgcheck=1
gpgkey=file:///repository/centos/$releasever/RPM-GPG-KEY-CentOS-6-Vozlt

Repository WebRoot 설정

/repository

Repository 등록 확인

$ yum clean all
$ yum repolist



Monday, May 2, 2016

Yum

특정 저장소 파일만 출력


$ yum --disablerepo="*" --enablerepo="vozlt-base" list available

Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Available Packages
debugmode.x86_64                     1:9.03.31-2.el6.vozlt                   vozlt-base
mysql-bench.x86_64                   1:5.6.15-1.el6.vozlt                    vozlt-base
mysql-embedded.x86_64                1:5.6.15-1.el6.vozlt                    vozlt-base
mysql-embedded-devel.x86_64          1:5.6.15-1.el6.vozlt                    vozlt-base
mysql-test.x86_64                    1:5.6.15-1.el6.vozlt                    vozlt-base


XeHookFpc

Xpressengine full page cache handler


간단하게 구현한 xpressengine 의 풀 페이지 캐쉬 프로그램입니다.
모듈이나 애드온 형태가 아닙니다.
몇달전에 xpressengine 설치해서 돌려보니 상당히 무겁다는것을 체감한후 속도 개선을 위해 간단하게 제작한 프로그램입니다.
테스트는 1.7.4에서 진행 했었고 공개하기전 1.7.5에서도 간단하게 해보았습니다.
작동을 위해서는 우선적으로 Memcached 설정이 활성화 되어져 있어야 합니다.
개발된 코드(xe-hook-fpc)와 일치하는 작동을 위해서는 cpage, page 등의 변수등에 대한 skin 설정도 정확하게 이루어져야 합니다.
조회수 업데이트 및 리스트 업데이트등의 동적인 페이지 구현에 있어서 몇가지 문제점들을 가지고 있는 프로그램입니다.
사용시에 유의하세요!

프로젝트 홈


https://github.com/vozlt/xe-hook-fpc

요구사항


  • Xpressengine(1.7.4+)
  • Memcached

Xpressengine memcached 설정


이미 설정 되어 있다면 생략
$ vi [Installed xpressengine path]/files/config/db.config.php

'use_object_cache' => 'memcache://localhost:11211'

설치


$ git clone git://github.com/vozlt/xe-hook-fpc.git

$ cd xe-hook-fpc

$ bash install.sh install [Installed xpressengine path]

삭제


$ cd xe-hook-fpc

$ bash install.sh uninstall [Installed xpressengine path]

테스트 환경


OS: centos6(x86_64)
WEB: nginx
PHP: php-fpm-5.5, php-opcache-5.5
MYSQL: mysql-5.6

적용 전후 함수들의 호출 수


액션 적용시 미적용시
document 7177 518
list 4862 455

xhprof 를 사용해서 분석한 내용이며 페이지 로딩 속도 및 시스템의 부하 또한 비례 할 것입니다.(10배이상)

Xhprof 결과


xe-hook-fpc 미적용:document

enter image description here

xe-hook-fpc 적용:document

enter image description here

xe-hook-fpc 미적용:list

enter image description here

xe-hook-fpc 적용:list

enter image description here

기본 캐쉬 만료 시간


액션 만료시간(초)
index 300
list 3600
document 3600
comment 3600
searched result 3600
menu 3600

캐쉬 만료시간은 [xpressengine 설치경로]/config/config.user.inc.php 에서 설정 가능하며 0으로 설정하면 해당 action은 캐쉬하지 않습니다.

$ vi [Installed xpressengine path]/config/config.user.inc.php

define('__XE_HOOK_FPC_INDEX_EXPIRES__', 300); /* index's cache expires time(sec) */
define('__XE_HOOK_FPC_LIST_EXPIRES__', 3600); /* list's cache expires time(sec) */
define('__XE_HOOK_FPC_DOCUMENT_EXPIRES__', 3600); /* document's cache expires time(sec) */
define('__XE_HOOK_FPC_COMMENT_EXPIRES__', 3600); /* comment's cache expires time(sec) */
define('__XE_HOOK_FPC_SEARCH_EXPIRES__', 3600); /* searched result's cache expires time(sec) */
define('__XE_HOOK_FPC_MENU_EXPIRES__', 3600); /* menu's cache expires time(sec) */

캐쉬키 출력하기

$ vi layouts/[your layout path]/layout.html

<!--fpc:debug_info:s--><!--fpc:debug_info:e-->

레이아웃등에 위처럼 설정후 xe-hook-fpc 를 활성화 하고 정상적으로 캐쉬가 생성되면 아래처럼 html 에 출력 됩니다.

<!--debug_info{fpc:pc:ProcCacheDocument:board:1:0:login}-->

기타

xe-hook-fpc 구현시에 게시글(댓글포함)의 (추가|삭제|수정) 등의 변화시에 저장된 캐쉬를 삭제하는 처리는 해놓았지만 위에서 언급했듯이 
cpage, page 등등의 변수가 해당 동작(추가|삭제|수정)시에 정확하게 전달되어야 합니다.
동적인 처리를 위해 내부로직에서 조회수등의 치환등의 몇개 정보는 구현해 놓았으나 너무 많은 경우의 수로 인하여 언급하지 않겠습니다. 
그리고 솔직히 만든지 몇달 되기도 했고 xpressengine 내부적인 흐름도 모두 본것도 아니라서 제 환경에서는 대충 잘 동작하게는 했지만 다른분들은 어떨실지 모르겠습니다.
풀캐쉬로 인해 동적인 페이지 구현에 있어서 여러가지 단점은 존재하지만 잘 설정하시면 효과는 아마도 깜짝 놀라실 거에요:)