 |
|
난이도 : 초급 Teodor ZlatanovGold Software Systems
2002 년 1 월 01 일 cfengine (설정 엔진)은, 쉬운 관리 태스크는 자동으로 어려운 태스크는 좀더 쉽게 만드는 유닉스 관리 툴이다. 이 글에서는 cfengine 관리 툴에 익숙해 질 수 있도록 간단한 사용방법을 설명한다.
이 글은 초급 또는 중급의 시스템 관리자들에게 초점을 맞추었다; 설명과 예제는 초급의 시스템 관리 개념을 알고있다는 전제하에
설명과 예제 수준을 조정했다.
이 글의 예제를 사용하기 위해서는 여러분의 시스템은 최신 (2000년 이후) UNIX 계열(Linux, Solaris, BSD)이어야
한다.
Cfengine은 개발중이다. Version 1.6.3은 안정적이며 이 글의 토대가 된 버전이다. 현재 알파 테스팅 중인 version
2.0은 아키텍쳐를 재작업하고 있고 새로운 기능들을 추가했으며, 신택스는 거의 변화하지 않았다. cfengine의 전체 기능과
version 2.0의 특징은 cfengine 홈페이지를 방문하기 바란다 (참고자료).
cfengine
Cfengine은 시스템 관리 방식을 변화시킬 것이다. 여러분은 명령어를 실행하고 시스템이 안정적인 상태로 되는 것을 감시하게
될 것이다. 약속하건데, 이것은 마술과 같을 것이다. Cfengine은 파일을 편집하고 명령어를 실행하고 차를 마시는 동안 symlink를
만들것이다.
Cfengine은 여러분을 개의치 않는다. 여전히 설정 파일을 만들고 최종 제품 단계에 이르기 전에 테스트를 해야 할 것이다.
다시말해서 cfengine의 어떤 부분은 유해가 될 것이다.
Cfengine은 시스템 수렴(convergence)을 가능하게 한다. 하지만 왜 수렴이 필요한가? 우선, 시스템 관리자가
원하는 것은 마음의 평안이다; 그 밖에 일은 부차적인 것이다. 안정성, 신뢰성, 예견가능성 등은 마음의 평화를 얻는 수단이다.
간단한 듯이 보이지만 훌륭한 시스템 관리자에게 묻을 때마다 이 대답을 듣게 될 것이다. 수렴(Convergence)은 안정성,
신뢰성, 예견 가능성을 얻을 수 있도록 도와준다.
안정성(Stability)은 의도하지 않은 변경에 대한 저항력으로 정의할 수 있다. cfengine이 수렴을
구현할 때는 일련의 규칙을 통해 수행한다. 계획이 잘된 규칙은 시스템을 이상적인 상태로 만든다. 예를 들어, 중요한 시스템 symlink는
cfengine이 실행될 때마다 다시 만들어질 수 있다. 또는 로컬 카피가 변경될 때마다 init.d 시작 스크립트는 믿을 수
있는 저장소에서 복사될 수 있다. cfengine이 프로세스의 실행을 보지 못한다면 프로세스는 재시작 될 수 있다.
신뢰성(Reliability)은 문제들 사이에서 살아남을 수 있는 머신의 능력이다. 네트워크 정지(network
outage)나 실패한 디스크는 훌륭한 신뢰성 테스트가 될 수 있다. 여러분의 시스템이 이러한 문제들 속에서 살아남을 수 있는가?
이상적인 상태로 수렴했다면 시스템은 이미 안정적인 상태거나 이상적적인 상태에 가까이 있다고 볼 수 있다. 신뢰성은 cfengine
단독으로 이루어지는 것은 아니다. 수렴은 이것을 용이하게 한다. 안정성은 신뢰성의 중요한 재산이다. 안정적인 시스템이 이러한
문제들로 인한 영향을 덜 받기 때문이다. 마지막으로 cfengine의 수렴은 "blank" 시스템을 원하는 상태로 바꾸는 것을
가능하게 한다.
원하는 상태와 이상적인 상태에 대해서 좀 더 설명해야 겠다. 지금까지 단지 하나의 이상적인 상태가 있다고 가정했다.
현실적으로 모든 머신에 맞는 이상적인 상태라는 것은 없다. 머신은 태스크, 로케이션(location), 연결, 사용자, OS
종류, 버전 등으로 구분된다. 모든 시스템 관리자들은 위에 제시된 것을 기준으로 구분한다. 모든 머신에 맞는 이상적인 상태가
없다면 기존의 머신 클래스를 위한 이상적인 상태는 존재한다. 이것이 cfengine의 디자인 목표이다. Cfengine은 실질적으로
이상적인 상태를 찾고 그러한 상태를 쉽게 수렴한다.
예견가능성(Predictability)은 머신이 기대한 대로 작동하는 능력이다. 수렴은 시스템을 안정적이고 신뢰성있게
만듦으로서 예견가능성을 획득한다. 게다가 새로운 머신이 이상적인 상태로 수렴되면 대체되기 전의 기존 머신처럼 작동할 수 있다.
머신이 알려진 상태로 수렴될 때 시스템을 추가하거나 대체하는 비용을 측정하기는 매우 쉽다. 마지막으로 여러분의 시스템을 위해
작성된 소프트웨어는 그들이 이상적인 상에 있다는 것을 기대할 수 있다.
cfengine 개요
Cfengine는 여러 프로그램으로 구성되어 있다. 주요한 하나가 version 1.6.3에 있는 cfengine
이다. cfengine 프로그램은 파일에서 일단의 규칙을 번역하고 그러한 규칙이 요구한대로 실행한다. 정확히 말해서, cfengine
프로그램은 cfengine 언어의 인터프리터이다. 그리고 모든 cfengine 프로그램들은 그 인터프리터용 스크립트이다.
version 1.6.3에는 cfd 라고 하는 데몬 프로그램도 있다. 그리고 이와 비슷한것이 cfrun이다.
Cfd는 version 2.0에서 강화될 것이다. 다행스럽게도 cfd 없이 내가 필요로 하는 태스크를 달성할 수
있었다. 나는 ssh보다 명백한 스크립트를 통해 cfengine을 시작하기를 좋아한다. cfd 보다 약간 느리지만 감시하기는
더욱 편리하다. cfengine에 의해 생긴 에러와 원격에서 정의된 클래스는 cfd를 통해 시작할 때 신뢰성이 떨어진다. 원격
파일 복사의 경우, cfd가 신뢰할 수 없고 보안 위험성을 가지고 있다는 것을 발견했다. 그래서 대신 rsync를 사용한다.
cfengine의 작성자 Mark Burgess는 cfd가 version 2.0에서는 훨씬 향상될 것이고 rsync는 불필요하게
된다고 말했다. 2.0이 나올때까지 cfd 사용을 자제하기 바란다.
cfengine으로 시작하려면, 컴파일 및 설치를 해야한다. RPM과 솔라리스 패키지도 사용가능하다 (참고자료).
영구적인 파일 체크섬을 저장하려면 Berkeley DB 지원으로 컴파일 해야 한다. 그런다음 설정 파일을 만든다. cfengine이
파일 이름 없이 호출될 때 실행되는 주요한 한가지는 /etc/cfengine/cfengine.conf 이다.
다음은 cfengine용 시작 설정이다. 완성된 제품은 아니다. 실제로 시작하기 전에 cfengine 레퍼런스와 튜토리얼을
주의깊게 읽어야 한다(참고자료). 설정 결과를 보려면 -v -n
옵션을 사용하여 cfengine을 시도해보라.
Listing 1. cfengine용 시작 설정 파일
/etc/cfengine/cfengine.conf
# note that only some of the possible sections are used here;
# refer to the cfengine documentation for the full list of sections
# you can have. Comments, as you can see, are like shell or Perl
# comments.
# see the tutorial and reference for any unexplained phenomena
import:
any::
cf.groups
groups:
# all groups are defined in cf.groups, imported above, but you can
# define extras here. The format is simple:
class = ( machine1 machine2 )
# and then any machine named machine1 or machine2 will have that class
# defined.
# the control section sets up how cfengine will behave
control:
any::
# you have to state in AddInstallable what classes unknown to cfengine
# by default you will be using. Run cfengine as "cfengine -v" to see
# the built-in classes you don't have to define. Here we divide
# machines into the ones that run inetd and the ones that run xinetd,
# as an example.
AddInstallable = ( inetd xinetd )
editfilesize = ( 300000 )
moduledirectory = ( /etc/cfengine/modules )
domain = ( yourdomain.com )
any::
LogDirectory = ( /etc/cfengine/log )
netmask = ( 255.255.255.0 )
Repository = ( /etc/cfengine/repository )
sysadm = ( "tzz@iglou.com" )
# Bug in cfengine: actionsequence must follow LogDirectory and Repository
actionsequence = ( directories files editfiles copy links processes disable
shellcommands )
directories:
# this ensures that these directories will be created when cfengine runs
/etc/cfengine/log
/etc/cfengine/repository
/etc/cfengine/cfcollector
files:
any::
# set the permissions for these files
/etc/sudoers mode=0440 owner=root group=root action=fixall
/etc/hosts.allow mode=0644 owner=root group=root action=fixall
/etc/hosts.deny mode=0644 owner=root group=root action=fixall
# just warn if this file's permissions are wrong
/etc/shadow mode=0400 owner=root action=warnall inform=true
# CERT advisory CA-2001-05, for Solaris only
solaris::
/usr/lib/dmi/snmpXdmid mode=0000 owner=root group=root action=fixall
# example of setting permissions differently for different OS types
# (not Linux and Linux), and negating classes
!linux::
/.ssh mode=0700 owner=root action=fixall inform=true
linux::
/root/.ssh mode=0700 owner=root action=fixall inform=true
editfiles:
any::
# add the rsync service to /etc/services and /etc/inetd.conf
{ /etc/services
SetLine "rsync 873/tcp # rsync"
AppendIfNoLineMatching "rsync.*"
}
{ /etc/inetd.conf
# add rsync
SetLine "rsync stream tcp nowait root /usr/local/bin/rsync rsyncd --daemon"
AppendIfNoLineMatching "rsync.*"
}
copy:
# set up sshd startup script, from trusted master distribution in /etc/cfengine
/etc/cfengine/sshd dest=/etc/init.d/sshd repository=/etc/cfengine/repository
links:
any::
# link the sshd init.d script to /etc/rc3.d, overwriting existing
# links if they exist
/etc/rc3.d/S72local_sshd ->! /etc/init.d/sshd
processes:
# invoke cfengine with "cfengine -DHupInetd" to define this class and
# send inetd the HUP signal (the machine has to be in the inetd class
# discussed above, too). This is an example of compound classes.
inetd.HupInetd::
"inetd" signal=hup
disable:
# empty this file (this can also be used to rotate logs, with
# different rotate options)
/etc/rc3.d/S77dmi rotate=empty
shellcommands:
any::
# always put the contents of the $domain variable in this file.
# note that all the cfengine variables can be interpolated inside strings.
"/bin/echo $(domain) > /etc/cfengine/cfdomainname"
|
 |

|
간단한 사용법: 파일 편집 및 복사
파일을 편집하려면, editfiles 섹션을 사용한다. 신택스는 다소 복잡하다. 하지만 이 예제에서는
가능한 몇 가지의 명령어만을 사용할 것이다. 전체 명령어는 cfengine 레퍼런스 (참고자료)를
참조하라.
Listing 2. 파일 편집하기
editfiles:
development::
{ /etc/sudoers
DeleteLinesContaining "cpa "
}
accounting::
{ /etc/sudoers
SetLine "cpa ALL=(ALL) ALL"
AppendIfNoLineMatching "cpa .*"
}
|
Listing 2에서, 사용자 "cpa"는 개발 부서에서 회계 부서로 이동했을 때 어떤 일이 일어나는지 보았다. 개발 머신
상에 sudo 액세스는 취소되어야 한다. 그리고 회계 머신상의 sudo 액세스가 필요하다. control:
섹션에서 선언한 머신 클래스를 AddInstallable()에서 사용한다. 머신 클래스에 근거하여 적절한
액션이 취해져야 한다. "cpa1"라는 이름의 사용자는 이러한 규칙에서는 문제가 되지 않는다. 특별히 "a" 다음에 공간을 요청했기
때문이다.
파일 복사도 간단하다. Listing 1의 스켈레톤 예제에서, sshd을 설정한 copy:와 links:
섹션을 보았지만 그들이 무엇을 하는가?
Listing 3. 파일 복사
copy:
# set up the sshd startup script
/etc/cfengine/sshd dest=/etc/init.d/sshd repository=/etc/cfengine/repository
links:
any::
# link the sshd init.d script to /etc/rc3.d
/etc/rc3.d/S72local_sshd ->! /etc/init.d/sshd
|
copy:의 저장소 옵션은, 이것이 겹쳐쓰여야 할 경우, cfengine에게 기존 sshd 스크립트를
어디에 두어야 할 지를 말하고 있다. 이 옵션은 사고에 대비한 보험이라고 할 수 있다.
links: 섹션은 오른쪽 시작 디렉토리에 링크를 만든다. 이것이 Solaris 또는 System
V 시작 구조라는 것을 주목해라. 리눅스 계열은 solaris::/linux:: 클래스 구역에서 핸들되지만,
여기에서는 예제를 더욱 단순하게 만드는 길을 택했다. 감탄사 부호(!)는 선택적인 것으로, 기존 링크가 겹쳐쓰여야 하는지의 여부를
말해주고 있다.
전체 디렉토리의 내용은 한번에 복사 또는 링크 될 수 있다. 예를 들어, /etc/cfengine/sbin에 있는 모든 파일을
/usr/local/sbin로 한번에 복사 또는 링크할 수 있었다. 필요한 복사 및 링크만 수행될 것이다. Cfengine은
copy: 명령어에 원격 복사 옵션을 적용하지만 복사는 cfd를 통해 수행된다. cfd 자체의 문제 때문에
생산 환경에는 불충분하다는 것을 깨달았다.
고급 사용: 프로세스 재시작 하기
프로세스는 cfengine 하위 설정을 이용하여 최상으로 핸들된다. 이는 보통 /etc/cfengine/cf.minute 에
저장되어 있다. cf.minute 에 cfengine.conf 가 사용하는 것과 같은 cf.groups 그룹 정의를 포함시키고
cfengine -f /etc/cfengine/cf.minute를 사용하여 이것을 호출해보자.
아래 예제는 프로세스의 재시작 및 시그널링 방법이다.
Listing 4. 프로세스의 재시작 및 시그널링
processes:
any::
# restart cfd if it's not running already
"/usr/local/sbin/cfd" restart "/etc/init.d/start-cfd start"
# restart sshd if it's not running already
"/usr/local/sbin/sshd" restart "/etc/init.d/sshd start"
# HUP inetd if the HupInetd class is defined, see listing 1
inetd.HupInetd::
"inetd" signal=hup
|
Cfd는 cfengine 데몬이다. 잦은 재시작에도 불구하고 불안정한것으로 드러났다. version 2.0 이상의 데몬은 훨씬
더 나을 것이라고 기대된다.
기타 컴퓨터 소프트웨어와 마찬가지로, 그룹과 같은 데몬 소프트웨어는 구현의 다양성으로 고전을 면치 못한다. cfengine과
관련하여 두 종류의 데몬이 있다. fork와 exit를 하는 데몬inetd, sshd,cfd)과 그렇지 않은 데몬 (qmail
startup daemon)이다.
fork과 exit 데몬의 경우, cfengine은 훌륭하게 작동한다."non-forking" 데몬의 경우,
cfengine은 특별한 도움이 필요하다. version 2.0에서 이것은 해결될 것으로 보인다.
결론
cfengine이 무엇을 할 수 있는지에 대해 표면적인 부분만 다루었다. 직접 시도해보기 바란다. 그 전에 반드시 cfengine
레퍼런스를 검토하기 바란다.
Version 1.6.3은 cfd 데몬을 제외하고는 매우 안정적이다. 신택스 다음 버전(2.0)으로 넘어갔다. 몇 가지 추가
사항도 생겼다.
Cfengine은 독보적인 시스템 관리 툴이다. 직접 사용하고 있지는 않더라도, 개념과 실행은 여러분이 지금 하고 있는 작업에
도움을 줄 것이다. 일단 사용해 보면 cfengine이 매우 유연하고 놀라울 만큼 유용할 것이라는 것을 알 수 있을 것이다.
참고자료
필자소개  | |  | Teodor Zlatanov는
보스턴 대학에서 컴퓨터 공학을 전공했다. 졸업 후 Perl, Java, C, C++를 사용하여 프로그램을 개발하였다. |
기사에 대한 평가
 |
| 이 문서 북마킹 하기
|
|