728x90
반응형

net.netfilter.nf_conntrack_max

 

nf_conntrack은 ip_conntrack의 후속 커널 모듈로 netfilter가 네트워크에서 발생하는 커넥션에 대해 해당 내용을 기록하고 추적하기 위한 모듈이다.

일반적으로 활성화되지는 않지만 iptables를 이용한 NAT 환경 같은 경우에 사용되기도 한다.

특히 아래와 같은 경우에 사용자 모르게 활성화되어서 사용되는 경우가 있다.

 

  • iptables -t nat -L 같은 NAT 테이블 확인 명령을 한번이라도 수행한 경우

  • docker와 같이 iptables의 NAT 기능이 필요한 애플리케이션을 사용할 경우

 

단순히 해당 모듈이 활성화된다고 해서 문제가 되지는 않지만 접속량이 많은 네트워크 서비스를 제공하는 경우에는 nf_conntrack을 기본 값으로 사용할 경우 연결을 기록하는 테이블의 크기를 기본 값인 65536을 사용하기 때문에 문제가 발생할 수 있다.

따라서 해당 값을 서버의 환경에 맞추어 충분히 늘려주는게 좋다.

 

 

nf_conntrack_max

 

nf_conntrack_max는 nf_conntrack 모듈이 기록할 최대 연결 개수를 지정하는 파라미터이다.

기본 값은 65536이며 적당히 크게 잡아줘도 무방하지만 단순히 값을 크게 잡는 것이 좋지만은 않다.

 

아래는 Conntrack Hash Table이 어떻게 구현되어있는지에 대한 그림이다.

 

 

Hash Table의 각 구성 요소는 bucket이라는것으로 구성되어 있으며 Bucket은 내부적으로 연결 리스트로 구현되어 있다.

Table은 O(1)의 효율을 보여주지만 연결 리스트의 경우 O(n)의 효율을 보여주기 때문에 연결 리스트를 최소화하고 Hash Table의 크기를 키우는게 가장 좋아 보인다.

 

하지만 Hash Table을 크게 갖는 다는 것은 그만큼 정적으로 많은 메모리를 할당해서 사용해야하는 부담이 존재한다.

예를 들어 2097152개의 연결을 처리하기 위해 nf_conntrack_max 값을 2097152로 지정하고 Hash Table도 동일한 크기로 잡게 된다면 단순히 Hash Table을 구성하는데 아래와 같은 메모리 자원을 사용하게 된다.

 

  • 연결을 기록하는 각 엔트리의 크기는 308byte라고 한다.

  • 2097152(Hash 크기) * 308byte / 1048576(1MiB) = 616MB

  • 즉 600MB가 넘는 크기를 Hash Table 구성에만 낭비하게 된다.

 

따라서 단순히 Hash Table 크기 자체를 크게하기 보다는 연결 리스트를 적절히 활용하여 성능과 공간의 균형을 맞추는게 좋다.

 

 

Hash Table의 크기가 부족할 경우 Table이 full이라면 메시지와 함께 들어오는 패킷은 모두 Drop 되어버린다.

 

 

커널 2.6 버전을 기점으로 파라미터 이름이 변경되었다.

 

커널 문서에는 아래와 같이 nf_contrack_max 값을 정의하고 있다. (ip_contrack 시절에는 8배였다.)

 

 

여기에는 nf_conntrack_buckets는 bucket들의 개수이며 다시 말해 Hash Table의 크기를 의미한다.

커널 문서에는 Hash Table 크기의 4배로 Max 값을 지정하는걸 기본으로 하고 있기 때문에 각 Hash Table의 bucket은 4개의 노드를 갖는 연결 리스트로 구성된다.

따라서 앞서 살펴본 2097152개의 연결을 처리하는 경우로 살펴본다면 616MB의 크기는 154MB로 줄어들게 된다.

 

옛날의 ip_contrack 시절에는 Conntrack_Max 값에 대한 기본 값을 결정하는 요소에는 시스템 아키텍처도 변수로 작용했었다.

Conntrack_Max를 수식으로 표현하면 아래와 같다. (Link : https://wiki.khnet.info/index.php/Conntrack_tuning)

 

 

 

nf_conntrack_buckets

 

네트워크 관련 커널 파라미터 설정에는 정답이라는 것은 없다.

다만 무작정 nf_contrack_max를 키우기만 하면 연결 리스트에 대해 부하가 높아지기 때문에 nf_contrack_buckets 값도 같이 조절을 해 주어야 한다.

 

 

4GB 메모리에는 65536이 적합하지만 별도로 Hash 크기를 지정해서 모듈을 올리지 않는다면 16384 값으로 정해지게 된다.

이 상황에서 nf_contrack_max를 계속 키우게 되면 연결 리스트 길이만 계속 길어지기 때문에 바람직하지 않다.

 

최근 시스템들은 많은 메모리를 가지고 있기 때문에 65536개 이상의 연결을 충분히 처리할 수 있으며 Hash 크기에 대한 모듈 파라미터를 지정해서 수동으로 로딩하지 않고 docker나 iptables에 의해서 자동으로 로딩되므로 

이 값을 변경해 주어야 하는데 한 번 모듈이 올라가게 되면 sysctl을 이용해서 커널 파라미터 값을 변경할 수 없으며 sysfs를 통해서만 변경이 가능하다.

 

 

여기서 nf_conntrack 모듈을 지우고 내렸다가 다시 올린다면 연결되어 있던 네트워크 세션이 모두 끊어지기 때문에 모듈자체를 건드려서는 안된다.

 

 

Values 설정

 

요즘 시스템은 메모리가 넉넉하기 때문에 65536의 배수로 적당히 지정하고 거기에 맞추어 Hash 크기를 지정하는 것도 방법이다.

또는 과거 ip_conntrack 시절에 계산하던 방법을 차용하면 아래와 같이 계산해 볼 수 있다.

 

 

nf_conntrack_max, nf_conntrack_buckets 외에도 네트워크 서비스를 위해서 몇 가지 중요한 설정 값이 있다.

 

먼저 nf_conntrack_generic_timeout이 있는 Layer 4 기반 타임아웃 설정 값으로 기본 값은 600초로 되어 있다. 

이 값이 너무 길기 때문에 이를 적절히 (예를 들면 120) 낮춰주는게 좋다.

 

그리고 활성화된 연결에 대한 타임아웃 파라미터로 nf_conntrack_tcp_timeout_established이 있으며 기본 값은 4332000초 (5일) 이다.

이 값 또한 적당히 낮춰 주는게 좋다.

 

아래는 추천하는 설정이다.

 

예를 들어 32GB 메모리를 가지고 있는 64bit 시스템에 대해서는 아래와 같이 설정값을 추천할 수 있다.

다만 nf_conntrack_max는 필요에 따라 임의로 적정값을 직접 지정해도 무방하다.

특히, 연결 양이 많지 않은 네트워크 서비스 시스템에서 기본 값으로도 충분할 경우가 많다.

 

 

키                                                        계산                                            값

nf_conntrack_max                                32 * 1073741824 / 16384 / 2       1048576

nf_conntrack_buckets                           nf_conntrack_max / 4                   262144

nf_conntrack_generic_timeout                                                                 120

nf_conntrack_tcp_timeout_established                                                      54000

 

아래는 설정 스크립트이다.

#!/bin/bash
#
# nf-setup.sh: nf_conntrack configurator
#
# by lunatine
#
_arch=1
_max=0
_bucket=0
_gto=120
_tcp=54000

help() {
    cat << EOF
  $ nf-setup.sh [OPTIONS ...]

  Options:
    -m|--max   : nf_conntrack_max (default: memsize / 16384 / arch bit)
    -b|--bucket: nf_conntrack_buckets (default: nf_conntrack_max / 4)
    -g|--gto   : nf_conntrack_generic_timeout (default: 120)
    -t|--tcp   : nf_conntrack_tcp_timeout_established (default: 54000)
    -h|--help  : help message
EOF
}

# get arguments
while [[ -n $1 ]]
do
    case "$1" in
        # nf_conntrack_max
        -m|--max) _max=$1; shift 2;;
        -b|--bucket) _bucket=$1; shift 2;;
        -g|--gto) _gto=$1; shift 2;;
        -t|--tcp) _tcp=$1; shift 2;;
        -h|--help) help; exit 0;;
    esac
done

if [ "$(id -u)" -ne 0 ]; then
    echo "[Error] root privilege required ..."
    exit 1
else
    for modname in nf_conntrack nf_conntrack_ipv4
    do
        if [ "$(lsmod | grep -c $modname)" -eq 0 ]; then
            echo "[Error] No $modname module found"
            exit 1
        fi
    done
fi

# when nf_conntrack_max omitted
if [ "$_max" -eq 0 ]; then
    memtotal=$(grep MemTotal /proc/meminfo | awk '{print $2}')
    [ "$(uname -m)" == "x86_64" ] && _arch=2
    _max=$(( memtotal * 1024 / 16384 / _arch ))
fi

# when nf_conntrack_buckets omitted
if [ "$_bucket" -eq 0 ]; then
    _bucket=$(( _max / 4 ))
fi

# asking for apply
CONF_VALUES="
[Applying]
---------------------------------------------------
  nf_connectrack_max                  : $_max
  nf_conntrack_generic_timeout        : $_gto
  nf_conntrack_tcp_timeout_established: $_tcp
  nf_conntrack hash size              : $_bucket
---------------------------------------------------
  are you sure? (Cancel: Ctrl+C) "
read -p "$CONF_VALUES" ans

# apply configurations
sed -i "/^net.netfilter.nf_conntrack_max/d" /etc/sysctl.conf
sed -i "/^net.netfilter.nf_conntrack_buckets/d" /etc/sysctl.conf
sed -i "/^net.netfilter.nf_conntrack_generic_timeout/d" /etc/sysctl.conf
sed -i "/^net.netfilter.nf_conntrack_tcp_timeout_established/d" /etc/sysctl.conf
{
    echo "net.netfilter.nf_conntrack_max = $_max"
    echo "net.netfilter.nf_conntrack_generic_timeout = $_gto"
    echo "net.netfilter.nf_conntrack_tcp_timeout_established = $_tcp"
} >> /etc/sysctl.conf
echo $_bucket > /sys/module/nf_conntrack/parameters/hashsize

# Result
cat << EOF
[Result]
---------------------------------------------------
  max                    : $(sysctl net.netfilter.nf_conntrack_max)
  hash size (buckets)    : $(sysctl net.netfilter.nf_conntrack_buckets)
  generic_timeout        : $(sysctl net.netfilter.nf_conntrack_generic_timeout)
  tcp_timeout_established: $(sysctl net.netfilter.nf_conntrack_tcp_timeout_established)
---------------------------------------------------
EOF

exit 0

 

 

참고

https://lunatine.net/2018/04/12/nf_conntrackgwa-docker/

https://medium.com/naver-cloud-platform/nf-conntrack-full%EB%A1%9C-%EC%9D%B8%ED%95%9C-packet-drop-%EB%8C%80%EC%9D%91-2586146e6714

https://blog.pages.kr/tag/nf_conntrack_max

https://jjinisystem.tistory.com/22

 

반응형

'Linux' 카테고리의 다른 글

Linux ReadLink  (0) 2020.10.25
Linux ulimit  (0) 2019.02.20
Linux Namespace  (0) 2018.12.17
Linux Service 만들기 (CentOS7)  (0) 2018.11.14
lvm의 기본 개념  (0) 2018.10.12
728x90
반응형

심볼릭 링크가 연결되어 있는 원본 파일을 찾는 명령어이다.

readlink는 심볼릭링크인 path가 가르키는 원본의 파일 이름을 돌려준다. 알아낸 원본 파일을 이름은 buffer에 저장된다.

bufsize는 buffer의 저장 크기이다. 만약 buffer의 크기가 원본 파일의 이름을 담기에 충분히 크지 않다면 나머지 부분은 잘리게 된다.

readlink는 원본 파일의 완전한 경로를 가져온다.

 

사용법

# readlink -{Option} File

 

Example

 

# ls -al test.txt

lrwxrwxrwx 1 root root 13 Oct 25 14:38 test.txt -> /tmp/test.txt

 

# readlink -f test.txt

/tmp/test.txt

 

Options

-f (canonicalize)

  • 주어진 이름의 모든 구성 요소에 있는 모든 심볼릭 링크를 따라가면서 정규화한다. 마지막 구성 요소를 제외하고 모두 존재해야한다.

 

-e (canonicalize-existing)

  • 주어진 이름의 모든 구성 요소에 있는 모든 심볼릭 링크를 따라가며 정규화 한다. 마지막 구성 요소를 제외하고 모두 존재해야한다.

 

-m (canonicalize-missing) 

  • 구성 요소 존재에 대한 요구 사항없이 주어진 이름의 모든 구성 요소에 있는 모든 심볼릭 링크를 따라 정규화한다.

 

 

Return

 

성공할 경우 Buffer에 들어 있는 문자의 갯수가 반환되며 에러가 발생했다면 -1 Return되며 적당한 Error 코드가 설정된다.

 

 

Error

- ENOTDIR

경로가 디렉토리(:12)가 아니다.

 

- EINVAL

bufsize 가 양수가 아닐경우

 

- ENAMETOOLONG

경로이름이 너무 길경우

 

- ENOENT

명명된 파일이 존재하지 않을경우

 

- EACCES

path 에 접근하기 위한 디렉토리 권한이 없을경우

 

- EINVAL

파일이 심볼릭 링크가 아닐때

 

 

참고

https://zetawiki.com/wiki/%EB%A6%AC%EB%88%85%EC%8A%A4_readlink

https://www.joinc.co.kr/w/man/2/readlink

 

 

반응형

'Linux' 카테고리의 다른 글

nf_conntrack_max  (1) 2020.10.25
Linux ulimit  (0) 2019.02.20
Linux Namespace  (0) 2018.12.17
Linux Service 만들기 (CentOS7)  (0) 2018.11.14
lvm의 기본 개념  (0) 2018.10.12
728x90
반응형
ulimit 란?

- 프로세스들에 대한 시스템 자원사용을 제한

- Apache와 같은 웹 서비스를 운영 시 동시 접속자가 많은 경우 구동되는 Apache 프로세스 수와 해당 프로세스가 처리하게되는 파일 수 또한 증가하게 되는데 이에 따라 시스템에서도 해당 설정을 조정하는 방법이 필요로 하기에 사용

- 프로세스의 자원 한도를 설정하는 방법에는 soft와 hard가 있음

- ulimit 명령어를 사용하면 커널의 성능과 기능에 영향을 주게 되므로 사용시에 주의해서 사용 

- sysvinit 환경과 systemd 환경에서 설정하는 방법이 달라짐


한도

soft 
  • 새로운 프로그램을 생성하면 기본적으로 적용되는 한도 

hard 
  • 소프트한도에서 최대로 늘릴 수 있는 한도


설정 목록

nofile 
  • 해당 도메인 (사용자, 그룹)이 오픈할 수 있는 최대 파일 개수
  • 오픈할수 있는 파일기술자(FD: file descriptor)의 최대 개수 제한

nproc 
  • 해당 도메인 (사용자, 그룹)의 최대 프로세스 개수
  • 한 사용자에게 허용 가능한 프로세스(user processes)의 최대 개수 제한

core 
  • Core 파일 크기를 제한
  • 코어(core) 파일 생성시 최대 크기 제한

data
  • 데이터 최대 크기
  • 프로세스 데이터세그먼트(process data segment)의 최대 크기 제한

fsize 
  • 파일 최대 크기
  • 쉘에 의해 만들어질 수 있는 파일의 최대크기 제한

memlock 
  • 최대 잠겨진 메모리 주소 공간 
  • 쉘에 허용 가능한 가상메모리(virtual memory)의 최대량 제한

rss 
  • 최대 상주 메모리 크기
  • 메모리에 상주(resident set size)할수 있는 최대 크기 제한

stack 
  • 스택 최대 크기 
  • 스택크기(stack size)의 최대크기 제한

cpu 
  • 최대 CPU 시간 
  • 초(second)당 사용 가능한 CPU의 최대 허용 시간(cpu time) 제한

as 
  • 주소 공간 제한
  • 512byte 블록단위로 파이프크기(pipe size)설정

maxlogins 
  • 이 사용자의 최대 로그인 수

maxsyslogins 
  • 시스템의 최대 로그인 수

priority 
  • 사용자 프로세스를 실행하는 우선 순위

locks 
  • 사용자가 보유할 수 있는 최대 파일 잠금 수

sigpending 
  • 보류 중인 최대 신호 수

msgqueue 
  • POSIX 메시지 큐에서 사용하는 최대 메모리

nice 
  • 값으로 올릴 수 있는 최대 nice 순위 [-20 ~ 19]

rtprio 
  • 최대 실시간 우선 순위

chroot 
  • 루트를 디렉토리로 변경 (데비안 특정)


옵션

-a : 모든 제한 값 출력

-b : 최대 소켓 버퍼 크기 제한

-d : 프로세스의 데이터 세그먼트 최대 크기 제한

-e : 최대 우선 예약 순위

-f : 쉘에 의해 생성된 파일의 최대 크기 제한

-i : 보류중인 신호의 최대 수 제한

-l : 메모리에 잠길 수 있는 최대 크기 제한

-s : stack 최대 크기 제한

-t : CPU의 초당 사용시간 제한

-m : 메모리에 상주 가능한 최대 크기 제한

-c : core파일이 생성될때의 최대 크기 제한

-u : 특정 사용자의 사용가능한 프로세스의 최대갯수 제한

-v : 쉘이 사용할 수 있는 가상 메모리의 최대 크기 제한

-p : 512 byte 블록으로 파이프 크기를 설정

-q : POSIX 메시지 대기 행렬의 최대 byte 수 제한

-r : 최대 실시간 스케줄링 우선 순위

-n : 오픈가능한 FD의 갯수 제한 (too many open file 등의 Error가 발생하는 경우 해당 값을 수정하여 해결 가능)

-x : 최대 파일 잠금 수 제한

-S : 주어진 자원에 대한 소프트 한도 설정

-H : 주어진 자원에 대한 하드 한계 설정

-T : 최대 스레드 수 제한


값 확인

- core file size : 코어파일의 최대 크기 (-c 옵션)

- data seg size : 프로세스의 데이터 세그먼트 최대 크기 (-d 옵션)

- scheduling priority : 쉘에서 생성되는 파일의 최대 크기 (-e 옵션)

- file size : 파일의 최대 크기 (-f 옵션)

- pending signals : 보류중인 신호 제한 (-i 옵션)

- max locked memory : 메모리에 잠길 수 있는 최대 크기 (-l 옵션)

- max memory size : resident set size의 최대 크기 (메모리 최대크기로 -m 옵션)

- open files : 한 프로세스에서 열 수 있는 open file descriptor의 최대 수 (열수 있는 최대 파일 수로 -n 옵션)

- pipe size : 512 byte 블록의 파이프 크기 (-p 옵션)

- POSIX message queues : POSIX 메시지 대기 행렬의 최대 byte 수 (-q 옵션)

- real-time priority : 최대 실시간 스케줄링 우선 순위 (-r 옵션)

- stack size :  stack 최대 크기 (-s 옵션)

- cpu time : 총 누적된 CPU 시간[초] (-t 옵션)

- max user processes : 단일 유저가 사용가능한 프로세스의 최대 갯수 (-u 옵션)

- virtual memory : 쉘에서 사용가능 한 가상 메모리의 최대 용량 (-v 옵션)

- file locks : 최대 잠금 파일 수 (-x 옵션)


설정방법 (/etc/security/limit.conf)

<Domain> <Type> <Item> <Value>

- Domain : 제한할 대상 작성 (*, User명, 그룹명) - 그룹에 적용할 경우 @가 붙음

- Type : 강하게 제한할 것인지 여유를 줄 것인지 결정 (Soft, Hard)

- Item : 제한할 항목으로 core, data, seg, file size 등 여러가지 존재 (stack, nproc, nofile 등등)

- Value : 제한하고자 하는 설정 값


Sysvinit ulimit 사용 예제

- 동시 접속자 수의 증가로 Apache 프로세스가 증가하여 max user process 또는 open files 수가 설정값을 초과해 동작할 시 Apache hang 현상이 발생될 수 있다.

# ulimit -u 2048
위의 명령으로 변경하는 방법이 있으나 실제 적용되진 않는다. 변경된 것처럼 보여지더라도 재로그인 또는 재부팅 시 기본 설정으로 다시 적용된다.

실제 적용 방법으로는

1. ulimit 명령을 통한 -n -u를 사용하여 max user process와 open files 개수를 수정한다.
    # ulimit -n 2048
    # ulimit -u 4096
    # ulimit -a

2. /etc/security/limits.conf 파일 수정
    - 프로세스 user 별로 설정을 지정할 수 있으며 이와 같이 적용시 특정 user만 해당 설정이 무분별하게 자원을 많이 사용하게 되는 부분에 대한 보안이 가능
    # vim /etc/security/limits.conf
        daemon    soft    nproc    4096
        daemon    hard    nproc    4096
    - daemon : user
    - soft 또는 hard : 한도 지정 
    - nproc 4096 : 한도 숫자 지정

3. /etc/profile 수정
    # ulimit setting
    ulimit -u 8192 -> max number of process 수정
    ulimit -n 2048 -> open files 값 수정
    # source /etc/profile
    # ulimit -a


설정 적용 안될 시

daemon     soft    nproc    83728

- 해당 설정에도 가끔 쓰레드가 부족하여 서비스가 구동되지 않는 증상 발생 

- 값의 최대치는 65535 이지만 메모리가 많은 경우 이 이상으로 설정 가능 (값에 unlimit 로 제한을 두지 않기도함), limit.conf의 soft 부분을 주석처리하고 limits.d/90-nproc.conf 파일의 내용을 수정해야함


참고 URL




systemd에서 ulimit 설정

systemd에서는 /etc/security/limits*를 완전히 무시한다. 그러므로 systemd에서 limits 설정은 기존 방법과 다르게 설정하여야 한다.

적용 순위는 Service Daemon -> Global


1. 전역 (Global) 으로 설정

파일 경로
System : /etc/systemd/system.conf
User : /etc/systemd/user.conf


해당 파일 내에서 값을 변경하는 것이다. 이 파일은 systmed의 일부로 systemd의 값을 설정하는 파일이다. 기본 시스템 작업을 제어하기 위한 옵션 세트가 포함되어 있다.

참고 URL



2. Systemd 내에서 서비스별 설정

2.1) 디렉토리 생성
# mkdir /etc/systemd/system/rabbitmq-server.service.d

2.2) limit 파일 생성 및 설정
# vim /etc/systemd/system/rabbitmq-server.service.d/limits.conf
[Service]
LimitNOFILE=64000


2.3) limit 확인
# cat /proc/[PID]/limits


3. Service Daemon File에서 설정

Service Daemon 별로 limits 설정값을 다르게 설정할 수 있다. 이 이유는 systemd는 작은 구성 파일과 완전히 병렬로 서비스 시작을 지원하는 새로운 init 시스템이기 때문이다.

systemctl status [Service] 명령으로 서비스의 실행 파일 위치를 찾는다.


서비스 실행 파일을 찾았다면 vi를 통해 해당 파일 내에서 limits에 대한 부분을 수정할 수 있다.

# vim /lib/systemd/system/nginx.service


[Service] 항목안에 설정되어야 하며 이 파일안에서 설정할 수 있는 옵션 리스트는 아래와 같다.

Options

Directive    
ulimit equivalent
Unit
LimitCPU=
ulimit -t
Seconds
LimitFSIZE=
ulimit -f
Bytes
LimitDATA=
ulimit -d
Bytes
LimitSTACK=
ulimit -s
Bytes
LimitCORE=
ulimit -c
Bytes
LimitRSS=
ulimit -m
Bytes
LimitNOFILE=
ulimit -n
Number of File Descriptors
LimitAS=
ulimit -v
Bytes
LimitNPROC=
ulimit -u
Number of Processes
LimitMEMLOCK=
ulimit -l
Bytes
LimitLOCKS=
ulimit -x
Number of Locks
LimitSIGPENDING=
ulimit -i
Number of Queued Signals
LimitMSGQUEUE=
ulimit -q
Bytes
LimitNICE=
ulimit -e
Nice Level
LimitRTPRIO=
ulimit -r
Realtime Priority
LimitRTTIME=
No equivalent
Microseconds


참고 URL





반응형

'Linux' 카테고리의 다른 글

nf_conntrack_max  (1) 2020.10.25
Linux ReadLink  (0) 2020.10.25
Linux Namespace  (0) 2018.12.17
Linux Service 만들기 (CentOS7)  (0) 2018.11.14
lvm의 기본 개념  (0) 2018.10.12
728x90
반응형
NameSpace란?


  • 하나의 시스템에서 프로세스를 격리시킬 수 있는 가상화 기술 (각 별개의 독립된 공간을 사용하는 것처럼 격리된 환경을 제공하는 경량 프로세스 가상화 기술)
  • VM에서는 각 게스트 머신별 독립적인 공간을 제공하고 서로가 충돌하지 않도록 하는 기능을 갖고 있다. 리눅스에서 동일한 역활을 하는 것이 Namespace이며 커널에 내장되어 있음
  • Hypervisor는 Hardware Resource를 가상화 하고 위에 올라가는 Guest OS에는 가상화 된 형태의 H/W를 제공하게 되므로 각 Guest OS는 완전히 다른 환경으로 분리된다.
    하지만 Namespace의 경우 Hardware Resource 레벨의 가상화가 아니고 동일한 OS와 동일한 Kernel에서 작동하게 된다. 단지 격리된 환경만 제공하는 것
    (Namespace는 H/W 자원을 가상화하는 것이 아니라 Linux 내의 자원을 가상화 하는 것)
  • unshare : NameSpace를 분리하는 명령어로 확인 가능


종류

  1. MNT (파일시스템 마운트)
    - 파일 시스템 마운트 포인트를 격리
    - 호스트 파일시스템에 구해받지 않고 독립적으로 파일시스템을 마운트하거나 언마운트 가능
    -m : Mount NameSpace를 의미
    # unshare -m /bin/bash
    - readlink : 심볼릭 링크의 원본을 찾는 명령어
    /proc/  : 시스템의 여러 실시간 정보들을 디렉토리와 파일 형태로 저장. linux 에서 가상 파일시스템에 위치하는 가상 디렉토리이며 실제 존재하지 않고 메모리에 저장
    # readlink /proc/OOO(pid)/ns/mnt -> 현재 프로세스의 Mount 정보를 확인

  1. UTS
    - 독립적인 Hostname 할당
    - 각각의 리눅스 컨테이너가 자신의 식별자 (hostname -f 로 확인)를 유지관리하기 위해 호스트이름과 도메인이름을 네임스페이스별로 격리
    - 호스트 이름에 종속적인 대부분의 어플리케이션에 중요한 기능이 -u 옵션을 통해 구현 가능
    # unshare -u /bin/bash

  1. IPC 
    - 프로세스간 데이터 교환 및 프로세스와 쓰레드간의 작업을 동기화하는 기능을 제공
    - semaphore, file locking, mutex오 가타은 자원에 대한 접근제어를 제공하며 컨테이너에서 실제 프로세스를 분리하기 위해서도 필요

  1. PID
    - 프로세스 ID를 분할하여 관리하기 위해 필요
    - systemd 프로세스만 가질 수 있는 PID 1번을 독립적으로 추가할당하며 동일한 OS에서 systemd 프로세스 뿐만 아니라 여러 프로세스가 PID 충돌없이 실행 가능하게 한다.

  1. USR
    - 프로세스가 namespace 내부와 기본 namespace 간에 각기 다른 사용자 및 그룹 ID를 가질 수 있도록 지원
    - 독립적인 사용자 할당, UID와 GID 격리

  1. NET
    - NameSpace 간에 Network 충돌 방지 (중복 포트 바인딩 등)
    - 네트워크 장치, 주소, 경로 및 방화벽 규칙 같은 네트워크 자원을 격리
    - 네트워크 스택의 논리적 복사본을 효과적을 생성하여 여러 namespace가 동일 포트로 다수의 서비스 제공하는 것을 가능하게 한다. (iproute2 package등을 이용하여 구현 가능)


반응형

'Linux' 카테고리의 다른 글

Linux ReadLink  (0) 2020.10.25
Linux ulimit  (0) 2019.02.20
Linux Service 만들기 (CentOS7)  (0) 2018.11.14
lvm의 기본 개념  (0) 2018.10.12
Linux Software Raid 복구  (0) 2018.10.04
728x90
반응형
service 파일 생성

- /usr/lib/systemd/system 디렉토리 아래에 확장자가 .service인 파일을 만들면, systemctl 명령을 통해 서비스를 제어할 수 있습니다.
Ex) /usr/lib/systemd/system/서비스이름.service
- 참고로 CentOS 7 이전에는 기존 서비스 관리 명령어였던 chkconfig를 통해 /etc/init.d/* 에 등록된 서비스들을 제어했었습니다.
- CentOS 7에서는 systemctl을 통해 서비스를 관리합니다.



.service 내용 작성

service 파일은 크게 Unit, Service, Install 3가지의 섹션으로 나뉩니다.

다음은 톰캣 서비스( tomcat.service ) 설정 파일을 작성한 것입니다.


이런 식으로 tomcat.service 파일을 생성하면,
# systemctl enable tomcat
명령어로 서버가 실행될 때 톰캣 서비스가 실행될 수 있도록 할 수 있고,
# systemctl start tomcat
명령어를 통해 수동으로 톰캣 서비스를 실행할 수 있습니다.

[Unit]

Description=
해당 유닛에 대한 상세한 설명을 포함한다.

Requires=
상위 의존성을 구성한다. 필요 조건으로서, 이 목록이 포함하는 유닛이 정상적일 경우 유닛이 시작된다.

RequiresOverridable=
"Requires=" 옵션과 유사하다. 하지만 이 경우 "사용자에 의해서" 서비스가 시작하는데 상위 의존성이 있는 유닛 구동에 실패 하더라도 이를 무시하고 유닛을 시작한다. (즉 상위 의존성을 무시한다.) 자동 시작의 경우 적용되지 않는다.

Requisite=, RequisiteOverridable=
"Requires=" 와 "RequiresOverridable=" 와 유사하다. 상위 의존성 유닛이 시작되지 않았다면 바로 실패를 반환한다.

Wants=
"Requires=" 보다 다소 완화된 옵션이다. 충분 조건으로서, 상위 의존성 목록에 포함된 유닛이 시작되지 않았더라도 전체 수행 과정에 영향을 끼치지 않는다. 이 옵션은 하나의 유닛을 다른 유닛과 연계할 경우 사용하게 된다.

BindsTo=
"Requires=" 와 매우 유사하다. 네트워크 카드가 물리적 장애가 발생한 경우와 같이 systemd의 개입이 없이 갑작스레 서비스가 사라진 경우 관련된 유닛도 같이 중지하도록 설정한다.

PartOf=
"Requires=" 와 매우 유사하다. 상위 의존성의 유닛을 중지하거나 재시작하는 경우 해당 유닛 또한 중지나 재시작을 수행한다. 하나의 서비스가 다른 하나의 일부로서 의존성을 만들어내는 경우 필요하다.

Conflicts=
베타적 관계를 설정한다. 만일 '유닛1' 의 "Conflicts=" 설정이 '유닛2' 로 되어 있다면 '유닛1'이 시작된 경우 '유닛2'가 중지되고, '유닛1'이 중지된 경우 '유닛2'가 시작한다. 이 옵션은 "After=" 와 "Before=" 옵션과는 독립적으로 작동한다.

Before=, After=
유닛 시작의 전후 관계를 설정한다. 해당 설정은 "Requires=" 설정과는 독립적이다. "Before=" 에 나열된 유닛이 시작되기 전에 실행하고 "After=" 은 해당 유닛이 시작된 이후 나열된 유닛이 실행한다. 시스템 종료 시에는 반대 순서로 동작한다.

OnFailure=
해당 유닛이 "실패" 상태가 되면 수행할 유닛 목록 (예 "/" 파일 시스템 마운트 실패시 복구 모드 수행)

PropagatesReloadTo=, ReloadPropagatedFrom=
재구성(reload) 명령을 다른 유닛에게 전파하거나 혹은 지정된 다른 유닛으로부터 재구성(reload) 명령을 전파 받는다.

RequiresMountsFor=
절대 경로로 지정하여 유닛을 구동하는데 필요한 마운트 목록을 자동으로 구성하여 "Requires=", "After=" 을 수행한다. 즉 필요한 마운트 경로가 준비되어 있는지 점검하고 마운트를 미리 진행한다.

OnFailureIsolate=[yes|no]
"yes" 인 경우 "OnFailure=" 에 선언된 목록과는 격리 모드(isolation mode)로 작동한다. 즉 해당 유닛에 종속성이 없는 모든 유닛은 중지된다. "OnFailureIsolate=yes" 인 경우 "OnFailure=" 옵션에 하나의 유닛만 설정 할 수 있다.

IgnoreOnIsolate=[yes|no]
"yes"인 경우 다른 유닛과 격리(isolation)할 때 중지하지 않는다.


[Service]

Type=[simple|forking|oneshot|notify|dbus]
유닛 타입을 선언한다.
  • "simple" (기본값) - 유닛이 시작된 경우 즉시 systemd는 유닛의 시작이 완료됐다고 판단한다. 다른 유닛과 통신하기 위해 소켓을 사용하는 경우 이 설정을 사용하면 안된다.
  • "forking" - 자식 프로세스 생성이 완료되는 단계까지를 systemd가 시작이 완료되었다고 판단하게 된다. 부모 프로세스를 추적할 수 있도록 PIDFile= 필드에 PID 파일을 선언해 주어야 한다.
  • "oneshot" - "simple" 과 다소 유사하지만 단일 작업을 수행하는데 적합한 타입이다. 또한 실행 후 해당 실행이 종료되더라도 RemainAfterExit=yes 옵션을 통해 유닛을 활성화 상태로 간주할 수 있다.
  • "notify" - "simple" 과 동일하다. 다만 유닛이 구동되면 systemd에 시그널을 보낸다. 이때 시그널에 대한 내용은 libsystemd-daemon.so에 선언되어 있다.
  • "dbus" - D-Bus에 지정된 BusName 이 준비될 때까지 대기한다. 다시 말해서, D-Bus가 준비된 후에 유닛이 시작되었다고 간주한다.

RemainAfterExit=[yes|no]
유닛이 종료된 후에도 활성화 상태로 판단한다.

GuessMainPID=[yes|no]
이 옵션은 "Type=forking"이고, "PIDFile="(빈 값)인 경우에 작동한다. systemd가 유닛이 정상적으로 시작되었는지 명확한 판단이 어려운 경우에 사용된다. 만일 여러 데몬 프로세스로 구성된 유닛이라면 PID를 잘못 추측할 수도 있다. 그로 인해 오류 검출이나 자동 재시작 등의 작업이 불가능 할 수 있는데, 이 옵션은 이러한 문제를 방지하는 기능을 한다.

PIDFile=
PID 파일의 절대 경로를 지정한다. 만일 유닛 타입이 forking 이라면 해당 설정을 추가해 주어야 한다.

BusName=
D-Bus의 버스 이름을 지정한다. Type=dbus 인 경우 필수 사항이다. 다른 Type 의 경우라도 D-Bus 버스 이름을 다르게 사용하는 경우 별도로 설정을 해주는 것이 좋다.

Environment=
해당 유닛에서 사용할 환경 변수를 선언한다. 또한 반드시 "Exec*=" 옵션보다 상단에 위치해야 한다. 예제는 아래와 같다.
Environment='ONE=one' 'TWO=two two'

EnvironmentFile=
해당 유닛에서 사용할 환경 변수 파일을 정의한다. 환경 변수 파일에서 "#" 와 ";" 로 시작되는 라인은 주석으로 처리된다. "Environment=" 와 같이 사용하는 경우 "Environment=" 옵션값이 먹게 된다. 또한 반드시 "Exec*=" 옵션보다 상단에 위치해야 한다.

ExecStart=
시작 명령을 정의한다. 실행 명령어는 반드시 절대 경로 또는 변수(${STRINGS}와 같이)로 시작해야 하며, 다중 명령어를 지원한다. 예제는 아래와 같다.
ExecStart="commnad1"
ExecStart="command2"
ExecStart="command3"
혹은 ExecStart="command1; command2; command3"

ExecStop=
중지 명령을 정의한다. 사용법은 "ExecStart="와 동일하다. 중지 방식은 "KillMode=" 로 지정된다.

KillMode=[control-group|process|none]
중지 방법에 대해서 선언한다.
  • "control-group" (기본값) - 해당 유닛의 그룹에 포함된 모든 프로세스를 중지 시킨다.
  • "process" - 메인 프로세스만 중지 시킨다.
  • "none" - 아무런 행동도 하지 않는다.
  • 여기에서 그룹은 어떤 유닛과 그에 종속성을 가지는 다른 유닛들을 말한다.

ExecReload=
재구성을 수행할 명령을 정의한다.

ExecStartPre=, ExecStartPost=, ExecStopPre=, ExecStopPost=
유닛 시작, 중지 등의 동작과 관련하여 수행할 추가 명령을 정의한다. 사용법은 "ExecStart=" 동일하다.

RestartSec=
재시작 명령을 수행할 때, 중지 후 다시 시작하기까지 대기(sleep)하는 시간을 설정한다. 기본값은 "100ms" 이다. 각각 "min", "s", "ms" 단위로 설정한다. 해당 설정은 Restart= 옵션이 있는 경우에만 적용된다.

TimeoutStartSec=
유닛의 시작이 완료될 때까지 대기하는 시간을 설정한다. 기본값은 90초(90s)이며, 만일 Type=oneshot 인 경우 해당 설정이 해당 설정이 적용되지 않는다. 만일 시작 완료에 대해 반환이 될 때까지 대기하려면 "TimeoutStartSec=0" 으로 설정한다.

TimeoutStopSec=
유닛의 중지가 완료될 때까지 대기하는 시간을 설정한다. 기본값은 90초(90s)이며, 위의 "TimeoutStartSec=" 옵션과 동일하게 "TimeoutStopSec=0" 으로 설정하면 반환이 될 때까지 대기한다. "TimeoutStopSec" 에 설정된 시간 안에 종료되지 않으면 SIGKILL 시그널을 보내서 강제로 종료시킨다.

TimeoutSec=
"TimeoutStartSec=" 와 "TimeoutStopSec=" 을 동시에 설정한다.

WatchdogSec=
유닛 시작 후에 주기적으로 생존을 감시하기 위한 질의(keep-alive ping)를 하는데, 이 질의가 반환되까지의 대기 시간을 설정한다. "Restart=" 옵션이 "on-failure", "always" 인 경우 유효하며, 여기에 지정된 시간 안에 응답이 없다면 자동으로 유닛을 재시작한다. 기본값은 "0" 으로 유닛의 생존을 감시하지 않는다.
Restart=[no|on-success|on-failure|on-watchdog|on-abort|always]
유닛이 죽었거나 "WatchdogSec="에 지정된 생존 응답 시간이 초과한 경우 재시작한다. "ExecStartPre=", "ExecStartPost=", "ExecStopPre=", "ExecStopPost=", "ExecReload=" 에 설정된 유닛의 경우에는 포함되지 않으며, 이 유닛에만 해당된다.
  • "no" (기본값) - 유닛을 다시 시작하지 않는다.
  • "on-success" - 유닛이 정상적으로 종료됐을 경우에만 재시작한다. 종료 시 "0"을 반환했거나, SIGHUP, SIGINT, SIGTERM, SIGPIPE와 같은 시그널 또는 "SuccessExitStatus=" 설정에서 지정된 반환 코드 목록에 따라 모두 성공으로 인식해 재시작을 하게 된다.
  • "on-failure" - 유닛이 비정상적으로 종료된 경우에 재시작한다. 반환이 "0"이 아닌 경우나 비정상적인 시그널을 받고 종료된 경우, "WatchdogSec="에 지정된 생존 응답 시간을 초과한 경우에 유닛을 재시작한다.
  • "on-watchdog" - "WatchdogSec="에 지정된 생존 응답 시간을 초과한 경우에 유닛을 재시작한다.
  • "on-abort" - 지정되지 않은 반환을 받은 경우에 유닛을 재시작한다.
  • "always" - 종료 상태에 관계없이 무조건 재시작하며, 수동으로 중지하더라도 다시 시작됨을 주의해야 한다.

SuccessExitStatus=
성공으로 판단할 시그널을 설정해 준다. 아래의 예를 참고하자.
"SuccessExitStatus=1 2 8 SIGKILL"

RestartPreventExitStatus=
재시작하지 않을 반환을 정의하며, 굳이 재시작하지 않아도 되는 반환이 있다면 유용하다.
"RestartPreventExitStatus=1 6 SIGABRT"

PermissionsStartOnly=[yes|no]
"User=", "Group=" 옵션 등과 같이 권한 설정을 적용하여 시작한다. 해당 설정은 "ExecStart="에서만 적용되며, "ExecStartPre=", "ExecStartPost=", "ExecReload=", "ExecStop=", "ExecStopPost="에서는 적용되지 않는다.

User=, Group=
유닛의 프로세스를 수행할 사용자/그룹의 이름을 지정한다.

RootDirectoryStartOnly=[yes|no]
프로세스의 루트 디렉토리를 지정한다. chroot() 함수를 사용하여 구동된다. 해당 설정은 "ExecStart="에서만 적용 되며 "ExecStartPre=", "ExecStartPost=", "ExecReload=", "ExecStop=", "ExecStopPost="에서는 적용되지 않는다.

RootDirectory=
chroot() 함수로 변경할 디렉토리를 지정한다.

WorkingDirectory=
프로세스의 작업 디렉토리를 지정한다. 별도의 지정이 없으면 유닛은 최상위 디렉토리("/")를 작업 디렉토리로 사용한다. 특정 디렉토리 상에서 실행되는 프로세스에서 필요하다.

NonBlocking=[yes|no]
소켓 기술자에 O_NONBLOCK 플래그를 사용한다. yes일 경우 STDIN/STDOUT/STDERR을 제외한 모든 소켓에 O_NONBLOCK 플래그가 지정된다. 즉 사용되는 모든 소켓이 비봉쇄로 동작한다.

NotifyAccess=[none|main|all]
서비스 상태 알림 소켓으로의 접근을 제어한다. 해당 접근은 sd_notify() 함수를 사용한다.
  • "none" - 유닛 상태에 대한 모든 정보를 무시한다.
  • "main" (기본값) - 메인 프로세스에 대해서만 상태 정보 알림을 허용한다.
  • "all" - 모든 유닛. 즉 컨트롤 그룹의 유닛 상태 정보 알림을 허용한다.
  • "Type=notify" 혹은 "WatchdogSec="가 설정된 경우 "NotifyAccess="를 "main" 혹은 "all"로 설정하여 접근 가능하게 설정해야 한다.

Sockets=
유닛에서 사용하는 소켓의 이름을 지정한다. 기본으로 "<유닛명>.socket"으로 생성되지만 지정된 이름으로 소켓을 사용하는 경우 별도의 설정이 가능하다. 또한 하나의 유닛에서 여러 소켓 목록을 일괄적으로 관리하는 경우 "Sockets=" 옵션이 여러번 사용될 수도 있다. 만일 "Sockets=" 옵션이 아무런 설정 없이 단독으로 사용되는 경우 소켓 목록이 리셋되게 된다.
StartLimitInterval=, StartLimitBurst=
위의 두 설정값을 이용하여 제한된 시간에 너무 많은 재시작 ("Restart=") 이 발생되는 것을 방지한다. 기본값에 따르면 10초 간격으로 5번까지 서비스 시작을 허용하고 이후에 재시작 이벤트가 발생하면 자동으로 재시작하지 않도록 설정한다. 유닛 재시작 이벤트가 무한으로 발생하는 것을 방지하며, 추후 관리자가 수동으로 복구할 수 있도록 한다.
  • "StartLimitInterval=" 옵션의 경우 기본값 10초(10s), "0" 으로 설정할 경우 비활성화한다.
  • "StartLimitBurst=" 옵션의 경우 기본값 5회.

StartLimitAction=[none|reboot|reboot-force|reboot-immediate]
만일 복구 재시도가 제한된 설정 (Service Recovery Limit > StartLimitInterval * StartLimitBurst) 내에 완료되지 않는다면 어떠한 조치를 취할 것인지 정의한다.
  • "none" (기본값) - 아무런 조치도 하지 않는다.
  • "reboot" - 시스템을 재부팅한다. (systemctl reboot과 동일)
  • "reboot-force" - 메모리 상의 데이터를 디스크와 동기화한 후에 시스템을 강제로 제부팅한다. (systemctl reboot -f와 동일)
  • "reboot-immediate" - 메모리 상의 데이터를 디스크와 동기화하지 않고 바로 시스템을 강제로 재부팅한다.

Nice=
해당 유닛의 프로세스의 nice 값을 지정한다. "-20" 부터 "19" 까지 정수형으로 등록한다.

OOMScoreAdjust=
OOM(Out Of Memory) killer 작동 시 프로세스 우선 순위를 미리 지정할 수 있다. "-1000" 에서 "1000" 까지 정수형으로 등록한다.

UMask=
umask 값을 선언한다. 별도의 설정이 없으면 기본값은 "0022" 이다.

SyslogFacility=
로그 시설을 설정할 수 있다. "kern, user, mail, daemon, auth, syslog, lpr, news, uucp, cron, authpriv, ftp, local0, local1, local2, local3, local4, local5, local6, local7" 등의 값으로 설정 가능하다.

SyslogLevel=
로그 수준을 설정할 수 있다. "emerg, alert, crit, err, warning, notice, info, debug" 등 설정이 가능하다.

TCPWrapName=
TCP 래퍼를 사용하기 위한 설정이다.

PAMName=
PAM 보안을 사용하기 위한 설정이다.


[Install]

Alias=
유닛의 별칭을 지정한다. "systemctl enable" 명령어를 통해서 별칭을 생성할 수 있다. 별칭은 유닛 파일 확장자(유닛 타입)를 가지고 있어야 한다.
(service, socket, mount, swap 등이 있다. 예: httpd.service 의 Alias=apache.service)

WantedBy=, RequiredBy=
"systemctl enable" 로 유닛을 등록할 때 등록에 필요한 유닛을 지정한다. 해당 유닛을 등록하기 위한 종속성 검사 단계로 볼 수 있다. 따라서 해당 설정은 [Unit] 섹션의 "Wants=" 와 "Requires=" 옵션과 관계 있다.

Also=
"systemctl enable"과 "systemctl disable"로 유닛을 등록하거나 해제할 때, 여기에 지정된 다른 유닛도 같이 등록, 해제하도록 할 수 있다.


반응형

'Linux' 카테고리의 다른 글

Linux ulimit  (0) 2019.02.20
Linux Namespace  (0) 2018.12.17
lvm의 기본 개념  (0) 2018.10.12
Linux Software Raid 복구  (0) 2018.10.04
Linux Software Raid 설정  (0) 2018.10.01
728x90
반응형
lvm의 기본 개념

- 로지컬 볼륨 매니저(Logical Volume Manager)는 기존에 있던 파티션을 합쳐 새롭게 구성하는 기능

PE(physical media) : 일반적인 물리적 하드 디스크
ex) /dev/hda, /dev/sda 등, 여기서 /dev/hda 란 윈도우에서 c 드라이브를 말함

PV(Physical Volume) : 각각 파티션을 나눈 것, 파일 타입은 lvm을 사용할 수 있게 8e(Linux LVM)로 설정
ex) /dev/ hda1, /dev/hda2 

PE(Physical Extents) : 하드 디스크를 제어할 때 블럭(PE) 단위로 제어, 블럭 하나는 대개 MB 단위의 크기
ex) 볼륨그룹 크기가 184MB이고, 기본 PE가 4MB일 때 PE의 개수는 46개가 된다.
       pvcrate에서 옵션으로 -l을 사용하면 pe 단위로 사용

VG(Volume Group) : PV로 되어 있는 파티션을 그룹으로 설정, /dev/hda1을 하나의 그룹으로 만들 수도 있고, /dev/hda1 + /dev/hda2처럼 파티션 두 개를 하나의 그룹으로 만들 수 있다. 그밖에도 다양하게 그룹 설정을 할 수 있다.

LV(Logical Volume) : 마운트 포인터로 사용할 실질적인 파티션이다. 크기를 바꿀 수 있다.

Filesystem : ext2, reiserfs 등의 리눅스에서 사용하는 모든 파일 시스템을 사용할 수 있다.



# LVM을 만드는 순서

  1. 하드디스크를 LVM을 만들 수 있게 파티션 생성
  2. 물리볼륨 생성 (pvcreate)
  3. 위 물리볼륨들을 볼륨그룹을 생성하여 묶는다. (vgcreate)
  4. 위 볼륨그룹을 원하는 크기대로 나눠 논리볼륨 생성 (lvcreate)
  5. 파일시스템으로 포맷





LVM 부가 설명


◆ 일반적으로 유닉스 시스템에서 저장 장치를 쓰는 방법은 그 장치의 블록 디바이스(Block Device)에 파일 시스템 (File System)을 만들어서 (다른 표현으로는 포맷(Format)한다라고 하지만 유닉스의 세계에서는 잘 쓰지 않는다.) 디렉토리에 마운트 시키는 것이다. 예를 들어, 두번째 버스의 프라이머리 ide 디스크의 첫번째 파티션에 reiserfs 파일 시스템을 만든 후, /debian/ftp 라는 디렉토리에 마운트를 시킨다면 다음과 같은 절차를 밟을 것이다.

# mkfs -t reiserfs /dev/hdc1
# 화면에 나오는 질문에 y 라고 답변
# mount -t reiserfs /dev/hdc1 /debian/ftp

◆  lvm을 써도 마찬가지 절차를 밟는다. 단지, 실제 블록 디바이스가 아닌 가상의 블록 디바이스를 쓴다는 점이 틀리다.

◆  실제적으로 lvm은 커널에서 파일 시스템과 블록 디바이스 사이에 위치하여 동작한다.


 
◆ VG, PV, LV

- VG(Volume Group)은 LVM의 가장 기본적인 요소이다. 쉽게 말하자면 가상 디스크라고 할 수 있는데, 하나 이상의 실제 물리적으로 존재하는 블록 디바이스가 모여서 VG를 이루게 된다.

- 그 물리적인 블록 디바이스를 PV(Physical Volume)라고 하는데, 거의 대부분의 장치를 PV로 쓸 수 있다. 하드디스크 및 그 파티션, 소프트웨어/하드웨어 RAID 장치, 심지어 Loopback 블록 디바이스(파일 시스템상의 파일을 블록 디바이스처럼 쓸 수 있게 해준다)까지도 말이다.

- PV와 대비되는 것이 LV(Logical Volume)이다. 이것은 가상 파티션이라고도 할 수 있는데, VG를 적당히 나누어 할당한 것이 LV이다. 사용자는 LV를 일반 디스크나 파티션처럼 쓰면 된다.

- 정리하자면, <그림2>를 보면 알 수 있듯이, 하나 이상의 PV가 모여 VG를 이루고, VG를 가상적으로 나누어 할당하면 LV이 된다.

- 참고적으로, 한 시스템에서 VG는 최대 99개까지 만들 수 있고, 하나의 VG에는 PV, LV 모두 최대 256개까지 할당할 수 있다.

 

◆ PE와 LE

- PE(Physical Extent)와 LE(Logical Extent)는 각각 물리적 할당단위와 논리적 할당단위를 뜻한다. 이 둘은 물리적인 위치나 크기는 같다.
그러므로 PE가 LV에 할당되면 LE가 된다라고 볼 수 있다..

- VG를 나누어 LV로 할당할 때 LVM은 하드디스크의 섹터처럼 작은 단위로 하지 않고 적당한 크기의 PE로 하게 된다. 그 이유는 할당단위가 극히 작으면, 할당정보가 엄청나게 커지고, 그에따라 시스템의 성능도 느려질 것이다. 또한 할당할 수 있는 크기에도 한계가 생길 것이다. PE의 크기는 VG를 만들 때에 정해지는데, 그에 따라서 VG의 최대 크기가 정해진다. 하나의 VG에는 65536개까지 PE를 할당할 수 있고, PE의 크기는 최소 8KB에서 2배씩 늘어나 최대 512MB까지이다. 그러므로 VG의 최대 크기의 범위는 최소 512MB(8KB x 65536)에서 최대 32TB(512MB x 65536)일 것이다.
 


◆ VGDA

- PV의 앞 부분에는 VGDA(Volume Group Descriptor Area)라는 부분이 있어서 VG의 모든 정보가 기록된다. 같은 VG에 속해 있는 PV들은 VGDA의 내용이 같다.

- 그 내용은, VG의 이름, 상태, 속해있는 PV, LV들, PE, LE들의 할당 상태 등이다. LVM은 이 VGDA 를 참조하고, 갱신하면서 모든 일을 수행한다.
 


◆ Linear Mapping LV 와 Striped Mapping LV

- 앞서 언급한 대로 LVM은 소프트웨어 RAID를 어느 정도는 대체할 수 있다. lvm에서는 두 가지 방식으로 LV를 만들 수 있는데, Linear RAID 와 대응되는 Linear Mapping 방식과 RAID Level 0 과 대응되는 Striped Mapping 방식이 그것이다.

- 두 방식의 차이점은 두개 이상의 비어있는 PV를 가지고 있는 VG에 LV를 할당할 때에, PE를 어떻게 배치시키는가 이다.

- Linear Mapping 방식은 일반적인 것으로써, PE를 순차적으로 할당시킨다. 예를 들어 <그림4>의 왼쪽 그림을 보면, 각각 3개의 PE가 있는 PV1, PV2으로 이루어진 VG1에 4개의 LE를 가진 LV1을 할당한다고 할 때에, LVM은 먼저 PV1에 3개의 PE를 순차적으로 할당하고 나머지 1개의 PE는 PV2에 할당한다.

- 반면, Striped Mapping 방식은 <그림4>의 오른쪽 그림에 나타나 있듯이, 위에서와 같은 환경으로 할당한다고 할 때에, PE는 적당한 크기의 조각들(stripes?)로 나누어진다. LVM는 그것을 두 PV에 분산하여 할당하게 된다. 그러므로 두 PV들에 할당된 PE의 갯수는 같다.

- Striped Mapping 방식의 목적은 두개 이상의 PV를 동시에 읽고 씀으로서, 속도 향상을 바랄 수가 있다는 것이다. 물론, PV들이 서로 독립적인 장치이어야지, 같은 장치 내의 파티션들이라면 오히려 역효과가 날 것이다.
 


◆ Snapshots

- 규모가 큰 시스템에서 서비스의 중지없이 백업을 할 때에 가장 큰 문제점이 백업도중에 데이터가 변경되는 것이다. 그러면 백업 자체가 무용지물이 될 수도 있기 때문이다.

- 그런 문제를 해결하려면 어느 시점에 데이터가 변경되지 못하게 고정시키는 것인데, 그런 기능을 구현한 것이 Snapshot LV이다.

- Snapshot LV는 기존의 LV를 복사하며 별도의 읽기 전용의 LV를 만드는 것이기 때문에, 데이터 변경을 걱정하지 않고 백업을 마칠 수 있을 것이다.



반응형

'Linux' 카테고리의 다른 글

Linux Namespace  (0) 2018.12.17
Linux Service 만들기 (CentOS7)  (0) 2018.11.14
Linux Software Raid 복구  (0) 2018.10.04
Linux Software Raid 설정  (0) 2018.10.01
LVM unknown disk 복구  (0) 2018.10.01
728x90
반응형

Linux Software Config


1. Stop and Start


1.1) Stop


# mdadm –detail /dev/md0
































- Stop후 다시 Start 하기위해서는 UUID를 알고 있어야한다. (UUID로 start 하려는 경우)


# mdadm -S /dev/md0








# mdadm –detail /dev/md0

으로 확인하면 출력되지 않음.




1.2) Start

# mdadm --assemble --scan -v (전체 start)

# mdadm --assemble –scan -uuid=d62fd767:c5161187:89ef017d:a9ea6101 (uuid로 하나 start)




2. Software Raid 장애 복구


2-1) Disk 장애 발생














2-2) 강제 Fail (Test 할 경우)

# mdadm /dev/md0 -f /dev/sdc1




































2-3) Raid Group에서 제거

# mdadm /dev/md0 -r /dev/sdc1




































2-4) Raid 복구

# mdadm /dev/md0 -a /dev/sdc1

새로운 disk를 삽입하여 fdisk로 파티션 생성 후 타입을 fd로 지정

- Raid 그룹안에 포함시킨다






반응형

'Linux' 카테고리의 다른 글

Linux Service 만들기 (CentOS7)  (0) 2018.11.14
lvm의 기본 개념  (0) 2018.10.12
Linux Software Raid 설정  (0) 2018.10.01
LVM unknown disk 복구  (0) 2018.10.01
Linux nfsiostat  (0) 2018.09.13
728x90
반응형

Linux Software Raid 설정


사전 작업

raid를 구성할 2개의 파티션을 생성후 fdisk에서 type을 fd로 설정






1. raid devices 생성


# mknod /dev/md0 b 9 0

b : block devices

9 : md 장치의 주 번호가 9

0 : 0번 째 장치


Ex) 만약 2번째 장치이면

# mknod /dev/md1 b 9 1



2. raid 구성


# mdadm -C /dev/md0 --level=raid1 --raid-devices=2 /dev/sda1 /dev/sdc1

이후 continue에서 y













- C : create

--level : raid 레벨

--raid-devices : raid를 구성할 devices 숫자



3. raid 확인


# mdadm --detail /dev/md0




























4. Mount or format


# mkfs -t xfs -f /dev/md0

# mount /dev/md0 /test



반응형

'Linux' 카테고리의 다른 글

lvm의 기본 개념  (0) 2018.10.12
Linux Software Raid 복구  (0) 2018.10.04
LVM unknown disk 복구  (0) 2018.10.01
Linux nfsiostat  (0) 2018.09.13
Linux IPMI Log로 HW 장애 확인  (0) 2018.08.28
728x90
반응형

정상적인 상태일 경우 lvs





정상적인 상태일 경우 pvs






- lv cache가 정상적으로 구동하지 않는 경우





- pv확인 시 disk 장애가 발생한 경우






해결 방법


1. 새로운 disk 삽입



2. fdisk를 통한 파티션 생성

# fdisk /dev/sda



3. pvdisplay로 장애난 disk의 pv uuid 확인















4. 메타데이터와 pv uuid를 통해 복구

# pvcreate --uuid "a2Lfiu-JoO2-3cte-dvAO-r12j-lvrn-bbi2z5" --restorefile /etc/lvm/archive/vg_hybrid_00015-1742953829.vg /dev/sda1













--restorefile의 경우 /etc/lvm/archive/ 아래있는 파일중 lvm 정상적으로 구성된 가장 마지막 버전을 찾아야 한다. 장애가 발생한 상태도 저장되기에 uuid status를 잘 확인해야한다.

반응형

'Linux' 카테고리의 다른 글

Linux Software Raid 복구  (0) 2018.10.04
Linux Software Raid 설정  (0) 2018.10.01
Linux nfsiostat  (0) 2018.09.13
Linux IPMI Log로 HW 장애 확인  (0) 2018.08.28
Linux Kdump 구성 (Rhel 6)  (0) 2018.08.23
728x90
반응형
nfsiostat란?


- NFS 클라이언트에서 NFS 파일 시스템을 모니터링하는 명령어

- iostat 명령의 경우 로컬 저장장치를 모니터링할 수 있지만 파일시스템이나 가상 파일 시스템(VFS)이 응용 프로그램 I/O에 어떤 영향을 미치는지에 대한 정보는 알수 가 없다.

- NFS 노드에 대한 I/O 정보를 확인가능



사용법


# nfsiostat [옵션]


옵션

-a : 속성 캐시와 관련된 통계를 표시
-d : 디렉터리 조작과 관련된 통계를 표시
-l 또는 --list=OOO : 첫 번째 리스트 마운트 지점에 대해서만 통계를 표시
-p : 페이지 캐시에 관련된 통계만 표시
-s : ops/ 초 단위로 NFS 마운트 포인트 정렬



사용 예제

# nfsiostat







ops/s : 초당 작업 수
rpc bklog : 백로그 대기열 길이
KB/s : 초당 kb I/O 수
KB/op : 각 작업당 I/O 수
retrans : 재전송 횟수
avg RTT(ms) : 클라이언트 커널이 RPC 요청을 보낸 시간부터 현재까지의 시간 (응답 받는 시간)
avg exe (ms) : NFS 클라이언트가 RPC 요청을 커널에 적용할 때까지의 시간 (RPC 요청이 완료되면 RTT 시간에 포함됨)


반응형

'Linux' 카테고리의 다른 글

Linux Software Raid 설정  (0) 2018.10.01
LVM unknown disk 복구  (0) 2018.10.01
Linux IPMI Log로 HW 장애 확인  (0) 2018.08.28
Linux Kdump 구성 (Rhel 6)  (0) 2018.08.23
Linux sysrq  (0) 2018.08.23

+ Recent posts