Jail 다루기

앞서 ZFS를 다루는 방법을 배웠고, jail의 특장점도 알아보았습니다.

이번에는 jail을 다루는 방법을 앞서 만든 가상 머신을 이용해 알아 보도록 하겠습니다.

Jail을 만들고 다루는 방법도 어렵지 않습니다. 감옥으로 떠나 봅시다.

Jail 이 수감될 pool 설정하기

jail은 FreeBSD 의 OS 수준의 가상화입니다. 독립된 FreeBSD 시스템이 격리되어 있는 것인데, 이 jail이 위치할 pool이 필요합니다.

Jail 탭으로 이동하면 다음과 같은 화면이 나타납니다. 눈썰미 좋은 분은 ‘FreeNAS WebUI 둘러보기’ 와 다른 점을 알 수 있을 것입니다.

초기 FreeNAS WebUI 의 jail 탭

Pool을 추가하고 난 후의 FreeNAS WebUI 의 jail 탭

pool을 추가하자 무언가 메뉴가 생겼음을 알 수 있습니다.

FreeNAS 11.2 의 jail은 iocage 라는 프로그램에 의해 관리됩니다. jail 은 자신이 위치할 (자신이 저장될) dataset 이 필요한데, iocage 는 첫 번째 pool을 자동으로 선택합니다. 그래서 이 경우엔 첫 번째 pool 인 Raid_test_1 이 선택되었습니다.

iocage 는 선택한 pool 의 최상위 dataset 아래에 iocage 이라는 이름의 dataset 을 만들고 그 아래에 필요한 파일과 dataset 을 자동으로 만듭니다.

iocage 는 FreeBSD 릴리즈를 iocage/download 에 다운로드 받고, iocage/releases 에 저장합니다.

그 후 jail을 만들 때 iocage/releases 에 저장된 릴리즈를 복사해 iocage/jail/jail이름/root 아래에 복사합니다.

jail이 저장될 pool은 CONFIG를 눌러 변경할 수 있습니다. 만약 pool을 변경할 시, 기존 pool에 저장된 jail이나 템플렛 등의 데이터가 마이그레이션 됩니다.

jail이 저장되는 pool은 최소한 10Gb 의 여유 공간이 있어야 합니다. (60Gb 이상을 추천합니다.) jail이 저장되는 iocage dataset 은 공유할 수 없습니다. iocage 아래의 dataset 들은 서로 독립적이며 데이터를 공유하지 않습니다. defaults.json 은 jail을 만들 때 기본 설정이 들어 있습니다. 수정하지 않는 것이 좋습니다.

Jail 만들기

간단하게 바로 jail을 만들어 보겠습니다.

jail 도 다른 여러 설정들처럼 ADD를 눌러 만들 수 있고, 고급 설정일반 설정이 있습니다. 먼저 jail을 기본 기본 설정으로 만들어보겠습니다.

ADD를 누르면 아래와 같은 jails/add/Wizard 로 이동합니다.

jail Name 은 만들고자 하는 jail의 이름이고, Release 는 jail 이 어떤 FreeBSD 릴리즈를 사용할지 선택하는 것입니다.

이름은 Test_Jail_1 으로, Release 는 11-2-RELEASE 를 선택하겠습니다.

그 후 NEXT.

그럼 아래와 같은 네트워크 구성 메뉴가 나타납니다.

ipv4 와 ipv6 주소를 설정할 수 있습니다.  ipv4 만 DHCP로 자동 구성 해 보겠습니다. DHCP Autoconfigure IPv4 를 선택하고 NEXT.

그럼 아래와 같이 jail의 설정을 검토하는 화면이 나타납니다.

올바른 설정을 한 것인지 확인한 후, SUBMIT을 누르면 jail이 만들어집니다.

처음 Jail을 만들거나 새로운 FreeBSD 릴리즈를 다운로드 받을 때에는 FreeBSD 릴리즈를 다운로드 받는데 시간이 좀 걸립니다. 다운로드가 된 이후에는 다운로드받은 릴리즈를 복사하면 되기 때문에 jail 을 만드는 속도가 빠릅니다.

jail 이 다 만들어지면 jail 탭으로 되돌아가고 아래와 같이 Test_Jail_1 이 만들어졌음을 알 수 있습니다.

DHCP 로 구성한 jail은 기본적으로 BPF (버클리 패킷 필터) 가 켜져 있으며 vnet으로 구성됩니다. IPv4 는 jail 이 동작할 때 받아 옵니다. 그럼 jail을 구동해보도록 하겠습니다.

를 눌러 드롭다운 메뉴를 열고 Start 를 클릭합니다.

잠깐의 로딩 후 jail 이 시작될 것입니다.

WebUI로 jail의 쉘에 접속하기

를 눌러 Shell 을 클릭하면 WebUI를 통해 jail 내부로 쉘을 통해 접근할 수 있습니다.

exit 를 입력하면 쉘이 종료됩니다.

네트워크 직접 구성하기

위에서 네트워크를 DHCP로 구성하였습니다. 이번에는 네트워크를 직접 구성해보도록 하겠습니다.

ADD를 눌러 jail 마법사로 이동한 후,

  1. 이름은 Test_Jail_2
  2. 릴리즈는 11.2-RELEASE(fetched) 를 선택합니다.

fetched가 붙은 것을 알 수 있습니다. 다운로드되었다는 뜻입니다. 이제 다운로드 된 release를 복사하기만 하면 되기 때문에 처음 jail을 만들때보다 훨씬 빠르게 jail을 만들 수 있습니다.

NEXT를 눌러 네트워크 구성으로 넘어갑니다.

vnet 을 체크하고

IPv4 Interfacevnet0 을 선택합니다.

IPv4 Address10.0.2.17

IPv4 Netmask24

IPv4 Default Router (디폴트 게이트웨이) 는 10.0.2.2

그 후 NEXT를 눌러 설정 확인 화면으로 넘어갑니다.

처음 jail을 만들 때와 다르게 즉시 생성되는 것을 알 수 있습니다.

아래와 같이 새로운 jail이 만들어졌습니다.

Test_Jail_2의 start 를 눌러 시작할 수 있습니다.

Jail 을 만들 때에는 특별한 경우가 아니면 이렇게 고정 IP 를 잡아 주는 것이 좋습니다. 그래야 IP 가 바뀌어서 서비스가 안 되는 것을 막을 수 있기 때문입니다.

고급 설정으로 jail 구성하기

기본 설정만으로도 jail을 구성하고 생성할수 있습니다. 하지만 고급 설정에서 더 자세하게 jail을 만들 수 있습니다. jail을 고급스럽게 만들어봅시다.

jail 메뉴에서 ADD를 눌러 jail 마법사 메뉴로 이동한 다음, ADVANCED JAIL CREATION 을 눌러 고급 메뉴로 이동합니다.

갑자기 설정이 왕창 늘어났습니다. 자주 사용하는 것만 간단하게 살펴 보도록 하겠습니다.

늘 말하듯 자세한 내용은 FreeNAS 유저 가이드북을 보면 되겠습니다.

Basic Properties
Jail Properties
Network Properties
Custom Properties

고급 설정은 크게 4부분으로 구분되어 있습니다.

Basic Properties 에서는 jail의 이름을 정하고, IP 를 설정합니다. Auto-Start 를 체크 할 경우, FreeNAS 부팅시 자동으로 시작됩니다.

Jail Properties 에서는 Jail 시스템의 다양한 설정이 가능합니다. 시작, 정지 시 실행될 스크립트, 보안 레벨, jail 접근 가능 유저, 각종 옵션 허용 등의 설정이 가능합니다. 이 부분은 잘 쓰이진 않으나, 몇몇 특별한 경우에는 조정해주어야 할 수 있습니다.

Network Properties 에서는 Jail의 네트워크의 세부 설정이 가능합니다. 이 부분도 그렇게 잘 쓰이진 않으나, 가끔 조정해 주어야 할 수도 있습니다.

Custom Properties 에서는 jail 소유자, 시작 우선 순위, 리눅스 호환성, proc 마운트, jail 저장 위치, tun 장치 허용 등의 설정을 할 수 있습니다.

Jail에 관한 건 이후 FreeNAS 서버를 구축하면서 더 자세하게 작성할 것이긴 합니다만, 백문이 불여일견 한번 고급스럽게 Jail을 만들어보도록 하겠습니다.

  • Basic Properties
    • Jail 의 이름은 Test_Jail_3
    • Release11.2-RELEASE(fetched)
    • VNET 체크
    • IPv4 인터페이스는 vnet0
    • IPv4 주소는 10.0.2.18
    • IPv4 넷마스크는 24
    • IPv4 디폴트 라우터는 10.0.2.2
    • IPv6 는 설정하지 않고
    • Auto-start 체크
  • Jail Properties 
    • allow_raw_sockets 체크 (원시 소켓을 허용합니다.)
    • allow_mount 체크 (마운트 가능)
  • Custom Properties
    • priority90 (기본값이 99니, 기본값으로 설정된 jail보다 빨리 시작됨)
    • mount_procfs 체크 (proc 마운트)
    • allow_tun (tun 인터페이스 생성 허용)

이렇게 구성하고 jail을 만들면 jail 목록에서 Test_Jail_3가 생성되었음 알 수 있습니다.

이렇게 생성된 jail은 위에서 설정한 특징을 갖습니다.

Test_Jail_3 는 고정IP 를 가지고, 부팅시 자동 시작되고, 원시 소켓에 접근할 수 있으며, 몇몇 파일시스템을 마운트할 수 있습니다. 또한, 다른 jail보다 더 빨리 시작되고, proc이 마운트 되어 있으며 tun 인터페이스를 만들 수 있습니다.

이러한 특별한 설정은 설치하고자 하는 서비스의 요구에 맞게 설정해 주면 됩니다.

일괄 작업

Jail 의 체크 박스를 선택하면 아래와 같이 Batch Operations 라는 메뉴가 나타납니다.

말 그대로 일괄 작업을 할 수 있는 것입니다. 일괄 작업은 차례대로 실행됩니다.

UPDATE 는 FreeBSD를 업데이트 하는 것입니다. Jail 내부에서 freebsd-update 명령어를 실행하는 것과 같습니다.

Jail 명령어

FreeNAS 의 jail은 iocage 라는 프로그램으로 관리됩니다.

jail 관련해서 가장 자주 사용하는 명령어는 아래와 같습니다.

  • jls
    현재 실행중인 jail의 목록을 확인합니다.
  • iocage list
    현재 존재하는 모든 jail의 목록을 표시합니다.
  • iocage start jail_name
    jail_name 이라는 이름의 jail을 시작합니다.
  • iocage stop jail_name
    jail_name 이라는 이름의 jail을 정지합니다.
  • iocage restart jail_name
    jail_name 이라는 이름의 jail을 재시작합니다.
  • iocage console jail_name
    jail_name 이라는 이름의 jail의 콘솔로 로그인합니다. jail이 꺼져 있을 경우, jail을 시작한 후 로그인합니다.
  • iocage exec jail_name ls
    jail_name 이라는 이름의 jail에서 ls 명령을 실행하고 결과를 출력합니다.
  • iocage update jail_name
    jail_name 이라는 이름의 jail 의 freebsd 를 업데이트합니다.
  • iocage snapshot jail_name
    jail_name 이라는 이름의 jail 의 스냅샷을 찍습니다.

iocage 또는 iocage –help 명령어를 입력하면 iocage 의 모든 명령어를 볼 수 있습니다.

하나씩 해 보도록 하겠습니다.

먼저 jls 부터 입력해 보겠습니다.

root@freenas[~]# jls
   JID  IP Address      Hostname                      Path
     1                  Test_Jail_1                   /mnt/Raid_test_1/iocage/jails/Test_Jail_3/root
     2                  Test_Jail_2                   /mnt/Raid_test_1/iocage/jails/Test_Jail_1/root
     3                  Test_Jail_3                   /mnt/Raid_test_1/iocage/jails/Test_Jail_2/root

현재 앞서 생성한 3개의 jail 이 동작하고 있음을 알 수 있습니다.

Test_Jail_2 을 종료해 보겠습니다.

root@freenas[~]# iocage stop Test_Jail_2
* Stopping Test_Jail_2
  + Running prestop OK
  + Stopping services OK
  + Tearing down VNET OK
  + Removing devfs_ruleset: 7 OK
  + Removing jail process OK
  + Running poststop OK

Test_Jail_2 가 종료되었습니다.

다시 jls 명령을 입력해 보겠습니다.

root@freenas[~]# jls
   JID  IP Address      Hostname                      Path
     1                  Test_Jail_1                   /mnt/Raid_test_1/iocage/jails/Test_Jail_3/root
     3                  Test_Jail_3                   /mnt/Raid_test_1/iocage/jails/Test_Jail_1/root

Test_Jail_2 가 사라졌음을 알 수 있습니다.

iocage list 를 입력해 현재 존재하는 jail의 목록을 확인해 보겠습니다.

root@freenas[~]# iocage list
+-----+-------------+-------+--------------+-----------+
| JID |    NAME     | STATE |   RELEASE    |    IP4    |
+=====+=============+=======+==============+===========+
| 1   | Test_Jail_1 | up    | 11.2-RELEASE | DHCP      |
+-----+-------------+-------+--------------+-----------+
| -   | Test_Jail_2 | down  | 11.2-RELEASE | 10.0.2.17 |
+-----+-------------+-------+--------------+-----------+
| 3   | Test_Jail_3 | up    | 11.2-RELEASE | 10.0.2.18 |
+-----+-------------+-------+--------------+-----------+

Test_Jail_2가 정지 상태임을 알 수 있습니다.

다시 Test_Jail_2 를 실행해 보겠습니다.

root@freenas[~]# iocage start Test_Jail_2
* Starting Test_Jail_2
  + Started OK
  + Configuring VNET OK
  + Starting services OK

다시 jls 를 입력해 보겠습니다.

root@freenas[~]# jls
   JID  IP Address      Hostname                      Path
     1                  Test_Jail_1                   /mnt/Raid_test_1/iocage/jails/Test_Jail_3/root
     3                  Test_Jail_3                   /mnt/Raid_test_1/iocage/jails/Test_Jail_1/root
     4                  Test_Jail_2                   /mnt/Raid_test_1/iocage/jails/Test_Jail_2/root

재밌는 것이 보입니다. Test_Jail_2의 JID가 4 입니다.

JID 는 jail 마다 고유하게 소유하고, jail 이 시작된 순서대로 가집니다.

Test_Jail_1을 재시작 해보겠습니다.

root@freenas[~]# iocage restart Test_Jail_1
* Stopping Test_Jail_1
  + Running prestop OK
  + Stopping services OK
  + Tearing down VNET OK
  + Removing devfs_ruleset: 6 OK
  + Removing jail process OK
  + Running poststop OK
* Starting Test_Jail_1
  + Started OK
  + Configuring VNET OK
  + DHCP Address: 10.0.2.16/24
  + Starting services OK

종료 후 시작과 동일합니다.

iocage 명령어를 이용해 Test_Jail_3 의 콘솔로 진입해 보겠습니다.

root@freenas[~]# iocage console Test_Jail_3
FreeBSD 11.2-STABLE (FreeNAS.amd64) #0 r325575+95cc58ca2a0(HEAD): Fri May 10 15:57:35 EDT 2019

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories:   https://www.FreeBSD.org/security/
FreeBSD Handbook:      https://www.FreeBSD.org/handbook/
FreeBSD FAQ:           https://www.FreeBSD.org/faq/
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/
FreeBSD Forums:        https://forums.FreeBSD.org/

Documents installed with the system are in the /usr/local/share/doc/freebsd/
directory, or can be installed later with:  pkg install en-freebsd-doc
For other languages, replace "en" with a language code like de or fr.

Show the version of FreeBSD installed:  freebsd-version ; uname -a
Please include that output and any error messages when posting questions.
Introduction to manual pages:  man man
FreeBSD directory layout:      man hier

Edit /etc/motd to change this login announcement.
root@Test_Jail_3:~ #

root@freenas[~]# 이 root@Test_Jail_3:~ # 으로 바뀌었습니다. Test_Jail_3 내부로 진입한 것입니다.

몇 가지 명령어를 입력해 보도록 하겠습니다.

root@Test_Jail_3:~ # mkdir /test_dir_1
root@Test_Jail_3:~ # mkdir /test_dir_2
root@Test_Jail_3:~ # ls -al /
total 112
drwxr-xr-x  20 root  wheel    24 May 26 22:15 .
drwxr-xr-x  20 root  wheel    24 May 26 22:15 ..
-rw-r--r--   2 root  wheel   957 Jun 21  2018 .cshrc
-rw-r--r--   2 root  wheel   474 Jun 21  2018 .profile
-r--r--r--   1 root  wheel  6197 Jun 21  2018 COPYRIGHT
drwxr-xr-x   2 root  wheel    47 May 25 02:57 bin
drwxr-xr-x   9 root  wheel    52 May 25 02:57 boot
dr-xr-xr-x  12 root  wheel   512 May 26 21:32 dev
drwxr-xr-x  27 root  wheel   108 May 26 21:32 etc
drwxr-xr-x   4 root  wheel    56 May 25 02:57 lib
drwxr-xr-x   3 root  wheel     5 Jun 21  2018 libexec
drwxr-xr-x   2 root  wheel     2 Jun 21  2018 media
drwxr-xr-x   2 root  wheel     2 Jun 21  2018 mnt
drwxr-xr-x   2 root  wheel     2 Jun 21  2018 net
dr-xr-xr-x   1 root  wheel     0 May 26 22:15 proc
drwxr-xr-x   2 root  wheel   148 May 25 02:57 rescue
drwxr-xr-x   2 root  wheel     7 May 26 22:12 root
drwxr-xr-x   2 root  wheel   137 Jun 21  2018 sbin
lrwxr-xr-x   1 root  wheel    11 May 25 02:52 sys -> usr/src/sys
drwxr-xr-x   2 root  wheel     2 May 26 22:15 test_dir_1
drwxr-xr-x   2 root  wheel     2 May 26 22:15 test_dir_2
drwxrwxrwt   6 root  wheel     6 May 26 21:32 tmp
drwxr-xr-x  14 root  wheel    14 Jun 21  2018 usr
drwxr-xr-x  24 root  wheel    24 May 26 21:32 var

test_dir_1test_dir_2 디렉토리를 생성하였습니다.

root@Test_Jail_3:~ # ls -al /mnt/
total 9
drwxr-xr-x   2 root  wheel   2 Jun 21  2018 .
drwxr-xr-x  20 root  wheel  24 May 26 22:15 ..

mnt 디렉토리 아래에는 아무 것도 없음을 확인했습니다.

root@Test_Jail_3:~ # exit
logout
root@freenas[~]#

빠져 나오고 싶을 때에는 exit 를 입력해 호스트로 빠져 나올 수 있습니다.

host 에서 jail 에 로그인 하지 않고도 jail 내부에서 명령어를 실행 할 수 있습니다. iocage exec 명령어를 이용하면 됩니다. 쉘 스크립트 등을 짤 때 상당히 편리합니다.

root@freenas[~]# iocage exec Test_Jail_3 touch /root/testfile_1

root@freenas[~]# iocage exec Test_Jail_3 touch /root/testfile_2

root@freenas[~]#

Test_Jail_3 내부에서 /root 디렉토리 아래에 testfile_1testfile_2를 만들었습니다. 출력할 결과가 없을 경우 빈 줄이 출력됩니다.

root@freenas[~]# iocage exec Test_Jail_3 ls -al /root
total 41
drwxr-xr-x   2 root  wheel    9 May 26 22:28 .
drwxr-xr-x  20 root  wheel   24 May 26 22:15 ..
-rw-r--r--   2 root  wheel  957 Jun 21  2018 .cshrc
-rw-------   1 root  wheel  348 May 26 22:28 .history
-rw-r--r--   1 root  wheel  149 Jun 21  2018 .k5login
-rw-r--r--   1 root  wheel  395 Jun 21  2018 .login
-rw-r--r--   2 root  wheel  474 Jun 21  2018 .profile
-rw-r--r--   1 root  wheel    0 May 26 22:28 testfile_1
-rw-r--r--   1 root  wheel    0 May 26 22:28 testfile_2

root@freenas[~]#

Test_Jail_3 에서 ls -al /root 명령어를 실행했습니다. testfile_1 과 testfile_2 파일이 있는 것을 알 수 있습니다.

만약 여러 개의 명령어를 한 번에 입력하고자 한다면 작은 따움표로 묶으면 됩니다.

root@freenas[~]# iocage exec Test_Jail_3 'mkdir /mnt/test_1 /mnt/test_2 && ls /mnt'
test_1  test_2

root@freenas[~]#

/mnt 아래에 test_1test_2라는 디렉토리를 만들고 /mnt 의 디렉토리와 파일 목록을 확인했습니다.

Jail 은 ZFS 파일 시스템 위에 있으므로 ZFS 의 다양한 기능을 사용할 수 있습니다. 당연히 스냅샷을 찍을 수도 있습니다.

root@freenas[~]# iocage snapshot Test_Jail_3
Snapshot: Raid_test_1/iocage/jails/Test_Jail_3@2019-04-15_12:50:39 created.

스냅샷을 찍어 두면 무언가가 잘못되었을 때 쉽게 롤백이 가능합니다. 롤백은 WebUI 에서도 가능하고, iocage rollback 명령어를 이용할수도 있습니다.

FreeBSD 또한 다른 모든 OS 처럼 OS 업데이트가 필요합니다. FreeNAS 는 FreeNAS 개발팀에 의해 FreeNAS 를 업데이트하면서 FreeBSD의 업데이트 또한 이루어집니다만, Jail 은 독립된 환경이라서 직접 업데이트 해 주어야 합니다.

root@freenas[~]# iocage update Test_Jail_3
Snapshot: Raid_test_1/iocage/jails/Test_Jail_3@ioc_update_11.2-RELEASE-p10 created.

* Updating Test_Jail_3 to the latest patch level...
src component not installed, skipped
Looking up update.FreeBSD.org mirrors... 2 mirrors found.
Fetching metadata signature for 11.2-RELEASE from update1.freebsd.org... done.
Fetching metadata index... done.
Fetching 2 metadata patches.. done.
Applying metadata patches... done.
Inspecting system... done.
Preparing to download files... done.
Fetching 33 patches.....10....20....30. done.
Applying patches... done.
The following files will be updated as part of updating to
11.2-RELEASE-p11:
/bin/freebsd-version
/lib/libc.so.7
/rescue/[
(...)
/usr/share/zoneinfo/Europe/Vatican
/usr/share/zoneinfo/zone.tab
src component not installed, skipped
Installing updates... done.

Test_Jail_3 has been updated successfully.
root@freenas[~]#

자동으로 스냅샷을 찍고, 업데이트합니다. 이미 최신 버전이라면 아래와 같은 결과가 나타납니다.

root@freenas[~]# iocage update Test_Jail_3
Snapshot already exists!

이미 스냅샷이 있다 = 이 버전의 업데이트가 이미 이루어졌다 로 판단해서 업데이트 하지 않습니다.

마운트 포인트

jail 내부는 격리된 공간입니다. 외부의 데이터에 접근할 수가 없습니다. 한번 확인해 보겠습니다.

앞서 Test_Jail_3 에서 몇 개의 디렉토리와 파일을 만든 것을 기억하실 것입니다.

호스트의 쉘에다 몇가지 명령어를 입력해 보도록 하겠습니다.

root@freenas[~]# ls -al /
total 54
drwxr-xr-x  20 root  wheel    27 May 27 06:22 .
drwxr-xr-x  20 root  wheel    27 May 27 06:22 ..
-rw-r--r--   2 root  wheel   887 May 26 06:36 .cshrc
-rw-r--r--   1 root  wheel   405 May 26 06:36 .profile
lrwxr-xr-x   1 root  wheel    13 May 26 06:36 .rnd -> /var/tmp/.rnd
drwxr-xr-x   2 root  wheel    47 May 26 06:36 bin
drwxr-xr-x   9 root  wheel    58 May 26 10:11 boot
drwxr-xr-x   3 root  wheel     3 Apr  8 08:30 compat
drwxr-xr-x   3 root  wheel     3 Apr  8 08:30 conf
-r--r--r--   1 root  wheel  6142 May 26 06:36 COPYRIGHT
drwxr-xr-x   7 www   www      12 May 26 21:49 data
dr-xr-xr-x  12 root  wheel   512 May 27 06:21 dev
-rw-------   1 root  wheel  4096 May 27 06:22 entropy
drwxr-xr-x  30 root  wheel  8064 May 26 21:50 etc
drwxr-xr-x   4 root  wheel    56 May 26 06:36 lib
drwxr-xr-x   3 root  wheel     4 May 26 06:36 libexec
drwxr-xr-x   2 root  wheel     2 May 26 06:40 media
drwxr-xr-x   4 root  wheel   192 May 27 06:22 mnt
drwxr-xr-x   2 root  wheel     2 May 26 06:40 net
dr-xr-xr-x   2 root  wheel     2 May 26 06:40 proc
drwxr-xr-x   2 root  wheel   145 May 26 06:36 rescue
drwxr-xr-x   3 root  wheel    15 May 26 21:52 root
drwxr-xr-x   2 root  wheel   132 May 26 06:36 sbin
lrwxr-xr-x   1 root  wheel    11 May 26 06:36 sys -> usr/src/sys
lrwxr-xr-x   1 root  wheel     8 May 26 06:36 tmp -> /var/tmp
drwxr-xr-x  14 root  wheel    14 May 26 06:40 usr
drwxr-xr-x  27 root  wheel  1728 May 27 06:23 var

test_dir_1 과 test_dir_2 가 없습니다.

root@freenas[~]# ls -al /mnt
total 7
drwxr-xr-x   4 root  wheel  192 May 27 06:22 .
drwxr-xr-x  20 root  wheel   27 May 27 06:22 ..
-rw-r--r--   1 root  wheel    5 May 26 06:36 md_size
drwxrwxr-x   3 root  wheel    3 May 25 02:41 Raid_test_1
drwxr-xr-x   4 root  wheel    4 May 23 04:53 single_disk

Raid_test_1 과 single_disk, 앞서 만든 pool 이 host 의 /mnt/ 아래에 마운트되어 있습니다.

root@freenas[~]# ls -al
total 17
drwxr-xr-x   3 root  wheel    14 May 26 22:20 .
drwxr-xr-x  20 root  wheel    27 May 27 06:22 ..
-rw-r--r--   1 root  wheel  1128 May 26 06:36 .bashrc
-rw-r--r--   2 root  wheel   887 May 26 06:36 .cshrc
-rw-r--r--   1 root  wheel   140 May 26 06:36 .gdbinit
-rw-r--r--   1 root  wheel    80 May 26 06:36 .k5login
-rw-r--r--   1 root  wheel    96 May 26 06:36 .login
-rw-r--r--   1 root  wheel   559 May 26 06:36 .profile
-rw-r--r--   1 root  wheel  1128 May 26 06:36 .shrc
drwxr-xr-x   2 root  wheel     2 Apr  8 08:40 .ssh
-rw-r--r--   1 root  wheel   119 May 26 06:36 .warning
-rw-r--r--   1 root  wheel    88 May 26 06:36 .zlogin
-rw-------   1 root  wheel   174 May 26 21:49 .zsh-histfile
-rw-r--r--   1 root  wheel   634 May 26 06:36 .zshrc

testfile_1 과 testfile_2 도 없습니다.

이로써 jail 내부가 격리되어 있다는 걸 알 수 있습니다. 격리된 공간이기 때문에 외부 리소스에는 영향을 끼칠 수 없습니다. 극단적인 예로, jail 내부에서 rm -rf /* 명령을 내리더라도 host 에는 영향이 가지 않습니다.

jail 이 격리된 FreeBSD 공간이라면 문제가 하나 발생합니다.

‘외부에 있는 데이터에 엑세스 할 수 없다면, 외부의 특정 데이터가 필요한 jail은 어덯게 만들어야 하지?’

jail은 그것을 해결하기 위해 마운트 포인트라는 기술을 사용합니다. 개념은 아주 간단합니다. jail 외부의 어떤 디렉토리를 jail 내부의 어떤 디렉토리에 ‘마운트’ 시키는 것입니다.

마운트 포인트는 jail 이 시작될 때 마운트 되고, 종료될때 해제됩니다.

한 번 해 보도록 하겠습니다.

밑작업

앞서 Test_Jail_3 내부에 여러 개의 디렉토리를 만들었습니다.

또한 zfs 다루기에서 여러 개의 dataset 또한 만들었습니다.

/mnt/test_1 에는 /mnt/single_disk/snap_dataset_1/child_dataset_1_2/child_dataset_1_2_1 를 마운트 할 것이고,

/mnt/test_2 에는 /mnt/single_disk/snap_dataset_2 를 마운트 할 것입니다.

마운트 하기에 앞서 /mnt/single_disk/snap_dataset_1/child_dataset_1_2/child_dataset_1_2_1/mnt/single_disk/snap_dataset_2 아래에 몇 개의 디렉토리와 파일을 만들도록 하겠습니다.

root@freenas[~]# cd /mnt/single_disk/snap_dataset_1/child_dataset_1_2/child_dataset_1_2_1
root@freenas[...child_dataset_1_2/child_dataset_1_2_1]# mkdir -p 1_2_1_data_dir_1 1_2_1_data_dir_2/child_dir_1/child_dir_2 1_2_1_data_dir_3
root@freenas[...child_dataset_1_2/child_dataset_1_2_1]# touch 1_2_1_data_file_1 1_2_1_data_file_2
root@freenas[...child_dataset_1_2/child_dataset_1_2_1]# ls
1_2_1_data_dir_1        1_2_1_data_dir_2        1_2_1_data_dir_3        1_2_1_data_file_1       1_2_1_data_file_2
root@freenas[...child_dataset_1_2/child_dataset_1_2_1]#
root@freenas[...child_dataset_1_2/child_dataset_1_2_1]# cd /mnt/single_disk/snap_dataset_2
root@freenas[/mnt/single_disk/snap_dataset_2]# mkdir 2_data_dir_1 2_data_dir_2 2_data_dir_3
root@freenas[/mnt/single_disk/snap_dataset_2]# touch 2_data_file_1 2_data_file_2 2_data_file_3 2_data_file_4
root@freenas[/mnt/single_disk/snap_dataset_2]#

마운트하기

몇 개의 디렉토리와 빈 파일을 만들었습니다. 이제 마운트 해 보도록 하겠습니다.

먼저 Test_Jail_3 Jail을 종료해야 합니다. jail이 종료된 상태이여야만 마운트 포인트를 추가할 수 있습니다.

iocage stop Test_Jail_3 를 입력해 종료하거나, WebUI 에서 Test_Jail_3 를 종료한 후,
WebUI의 Jails 메뉴에서 Test_Jail_3 의 를 눌러 드롭다운 메뉴를 연 후 Mount points 를 클릭해 마운트 포인트 추가 메뉴로 이동합니다.

그곳에서 ACTIONS 를 누르면 + Add Mount Point 버튼이 나타나는데, 그것을 클릭해 마운트 포인트 추가 메뉴로 이동합니다.

Source 는 마운트 될 대상 디렉토리, Destination 은 마운트 할 목적지 디렉토리입니다.

를 눌러 디렉토리 트리를 탐색할 수도 있고, 경로를 직접 입력할 수도 있습니다.

Source/mnt/single_disk/snap_dataset_1/child_dataset_1_2/child_dataset_1_2_1를,

Destination/mnt/Raid_test_1/iocage/jails/Test_Jail_3/root/mnt/test_1 를 선택하였습니다.

Read-Only 를 체크하면 읽기 전용으로 마운트됩니다.

jail 의 경로
여기서 재밌는 것을 볼 수 있습니다. destination 은 jail 내부에서의 경로가 아니라, host 에서 보는 절대 경로를 기준으로 합니다.
그래서 iocage 의 루트 dataset 인 /mnt/Raid_test_1/iocage 아래에 jail 들이 수감되는 jails dataset 이 있고 그 아래에 Test_Jail_3 가 수감되어 있으며, 그 아래에 root 즉 jail의 데이터가 저장되는 디렉토리가 있는 것을 알 수 있습니다. 그리고 그 다음에 /mnt/test_1 이 나타납니다.
즉 /(jail이 수감된 pool)/iocage/jail/(jail의 이름)/root/ 아래에 jail이 수감되어 있는 것입니다.

SAVE 를 눌러 마운트 포인트를 저장 합니다.

마찬가지 방법으로 /mnt/Raid_test_1/iocage/jails/Test_Jail_3/root/mnt/test_2/mnt/single_disk/snap_dataset_2 를 마운트 하겠습니다.

참고
마운트 포인트의 를 눌러 Edit 을 누르면 마운트 포인트를 수정할 수 있지만, 오류가 발생하는 경우가 있습니다.
마운트 포인트를 수정해야 할 경우에는, 마운트 포인트를 삭제한 후 다시 만들어 주는 것이 좋습니다.

마운트 포인트를 추가하였으니 jail으로 로그인하겠습니다.

iocage console Test_Jail_3

마운트가 잘 되었는지 확인해 보겠습니다.

root@Test_Jail_3:~ # cd /mnt/
root@Test_Jail_3:/mnt # ls
test_1  test_2
root@Test_Jail_3:/mnt # cd test_1
root@Test_Jail_3:/mnt/test_1 # ls
1_2_1_data_dir_1        1_2_1_data_dir_2        1_2_1_data_dir_3        1_2_1_data_file_1       1_2_1_data_file_2
root@Test_Jail_3:/mnt/test_1 # cd 1_2_1_data_dir_2/child_dir_1/child_dir_2/
root@Test_Jail_3:/mnt/test_1/1_2_1_data_dir_2/child_dir_1/child_dir_2 # cd /mnt
root@Test_Jail_3:/mnt # cd test_2/
root@Test_Jail_3:/mnt/test_2 # ls
2_data_dir_1    2_data_dir_2    2_data_dir_3    2_data_file_1   2_data_file_2   2_data_file_3   2_data_file_4
root@Test_Jail_3:/mnt/test_2 #

host 에서 만든 파일과 디렉토리가 있는 것을 알 수 있습니다. 마운트 된 상태니 당연히 디렉토리나 파일을 jail에서 만들 수도 있습니다.

root@Test_Jail_3:/mnt/test_2 # mkdir jail_dir
root@Test_Jail_3:/mnt/test_2 # touch jail_file
root@Test_Jail_3:/mnt/test_2 # ls
2_data_dir_1    2_data_dir_2    2_data_dir_3    2_data_file_1   2_data_file_2   2_data_file_3   2_data_file_4   jail_dir        jail_file

정상적으로 만들어집니다.

마운트 포인트 주의사항

마운트 포인트를 만들 때 2가지 주의 사항이 있습니다.

첫 번째는 각 경로 (Source 와 Destination) 가 각각 88자를 넘어서는 안된다는 것입니다.
이는 FreeBSD Jail 의 제약으로서, 88자가 넘는 경로를 마운트 포인트에 추가하였을 경우, jail 의 시작에 실패합니다.

두 번째는 dataset 이 마운트 되어 있는 디렉토리를 마운트 할 때에는 최하위 dataset 을 마운트 해야 한다는 것입니다.

무슨 말이냐면, /mnt/single_disk/snap_dataset_1/child_dataset_1_2/ 은 최하위 dataset 이 마운트 되어 있는 경로입니다. 즉, jail에 마운트 해도 됩니다.
/mnt/single_disk/snap_dataset_1/ 은 하위에 child_dataset_1_2 라는 dataset 이 마운트 되어 있는 상황이니 jail에 마운트 해서는 안됩니다.

만약 최하위 dataset 이 아닌 dataset 을 마운트 할 시 datset 의 마운트가 깨져서 일시적으로 데이터에 접근할 수 없게 됩니다.

만약 실수로 최하위 dataset 이 아닌 dataset 을 마운트해서 데이터에 접근할 수 없게 되었다면, jail의 마운트 포인트를 제거한 후, FreeNAS 를 재부팅하면 됩니다.

중요한 사항이니 잘 기억해 두시길 바랍니다.

Jail에서 프로그램 설치

FreeBSD 도 데비안 리눅스의 apt나 centos 의 yum 과 같은 소프트웨어 매니저가 있습니다. 바로 pkgport 입니다. ‘pkg 와 port’ 에서 더 자세히 다룰 것입니다만, 여기서도 잠깐 사용해 보도록 하겠습니다.

pkg 를 사용해 transmission 이라는 프로그램을 설치해 보겠습니다.

root@Test_Jail_3:/mnt/test_2 # pkg update
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]:

pkg 명령을 처음 사용하면 pkg 가 시스템에 설치되어 있지 않으니 설치 할 것이냐 묻습니다. y를 눌러 설치합니다.

Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:11:amd64/quarterly, please wait...
Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done
[Test_Jail_3] Installing pkg-1.10.5_5...
[Test_Jail_3] Extracting pkg-1.10.5_5: 100%
Updating FreeBSD repository catalogue...
pkg: Repository FreeBSD load error: access repo file(/var/db/pkg/repo-FreeBSD.sqlite) failed: No such file or directory
[Test_Jail_3] Fetching meta.txz: 100%    940 B   0.9kB/s    00:01
[Test_Jail_3] Fetching packagesite.txz: 100%    6 MiB 668.2kB/s    00:10
Processing entries: 100%
FreeBSD repository update completed. 31990 packages processed.
All repositories are up to date.
root@Test_Jail_3:/mnt/test_2 #

설치가 다 되면 pkg update 명령이 실행됩니다. pkg 레포를 읽어 오고 새로 고치는 것입니다.

pkg search 명령을 이용해 transmission 이라는 패키지가 있는지 검색해보겠습니다.

root@Test_Jail_3:/mnt/test_2 # pkg search transmission
py27-transmissionrpc-0.11_1    Python module that communicates with Transmission through JSON-RPC
py36-transmissionrpc-0.11_1    Python module that communicates with Transmission through JSON-RPC
transmission-2.94_4            Meta-port for Transmission BitTorrent client
transmission-cli-2.94_3        Meta-port for Transmission BitTorrent client
transmission-daemon-2.94_3     Meta-port for Transmission BitTorrent client
transmission-gtk-2.94_4        Meta-port for Transmission BitTorrent client
transmission-qt5-2.94_8        Meta-port for Transmission BitTorrent client
transmission-remote-gui-gtk2-5.16.0 Remote GUI for transmission daemon
transmission-remote-gui-qt5-5.16.0 Remote GUI for transmission daemon
transmission-web-2.94_3        Meta-port for Transmission BitTorrent client
root@Test_Jail_3:/mnt/test_2 #

pkg install transmission-2.94_4 또는 pkg install transmission 을 입력해 설치할 수 있습니다.

root@Test_Jail_3:/mnt/test_2 # pkg install transmission-2.94_4
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
Updating database digests format: 100%
The following 125 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        transmission: 2.94_4
        transmission-web: 2.94_3
        transmission-gtk: 2.94_4
        pango: 1.42.4_1
        libXrender: 0.9.10_2
        libX11: 1.6.7,1
(...중략...)
        libnotify: 0.7.7_1
        libevent: 2.1.8_3
        dht: 0.25
        libb64: 1.2.1
        transmission-daemon: 2.94_3
        transmission-cli: 2.94_3

Number of packages to be installed: 125

The process will require 642 MiB more space.
112 MiB to be downloaded.

Proceed with this action? [y/N]:

y 를 입력하면 설치가 시작되고, n을 누르거나 ^C (Control+C) 를 누르면 취소됩니다. y를 입력하면 설치됩니다.

설치는 3 단계로 나뉩니다.

  1. fetch (다운로드)
  2. 압축 풀기와 설치. 설치 과정에서 추가적으로 해야 하는 게 있으면 자동으로 진행합니다. 예를 들어 유저를 만들거나, 자동 실행 스크립트를 만들거나 하는 것입니다.
  3. 설치한 패키지들의 메세지 표시

transmission 이 설치되었습니다. 물론 설치만 한 것이지 여러 가지 설정이나, 자동 시작 설정 등은 하지 않은 상태입니다.

Plugin Jail

앞서 jail 을 만들고 pkg 를 이용해 프로그램을 설치해보았습니다. 이번엔 plugin jail을 이용해 보겠습니다.

plugin jail은 freenas 개발팀에서 만들어 놓은 jail으로 plugin을 설치하기만 하면 해당 기능을 하는 jail이 만들어집니다. 예를 들어 transmission plugin을 설치하면 transmission 을 실행하는 jail 이 만들어지는 것입니다.

일반적인 jail과 다른 점이 몇 가지 있는데,

  1. 일반적인 jail이 유저가 직접 구성해서 만듦에 반해 plugin jail은 미리 만들어 져 있음. 즉, 설치가 편리하지만 커스텀이 어려움.
  2. 일반적인 jail이 여러 가지 기능을 하나의 jail 에서 수행할 수 있음에 반해, plugin jail은 하나의 기능만을 수행하도록 구성되어 있음. 즉, 여러 가지 기능이 필요한 경우 여러 개의 plugin jail을 설치해야 함.

그럼 plugin jail을 설치해 보도록 하겠습니다.

WebUI 의 Plugin – Available 로 이동하면 아래와 같이 ‘설치 가능한’ plugin 의 목록이 표시됩니다.

여기서 transmission 을 찾아 설치해 보겠습니다.

설치하고자 하는 plugin 의 를 누르면 Install 이 표시됩니다. 누르면 설치 마법사로 이동합니다.

plugin 도 다른 jail 처럼 고급 설정을 하거나 ip를 지정하는 등의 설정이 가능합니다만, 지금은 dhcp 로 구성하도록 하겠습니다. SAVE를 누르면 설치가 시작됩니다.

위와 같은 메세지창이 표시되고 plugin의 설치가 진행됩니다. 시간이 좀 걸릴 수도 있습니다.

설치가 끝나면 위와 같은 설치 과정과 각종 정보가 포함된 메세지를 표시합니다.

필자는 plugin jail을 사용하지 않고 직접 구성하는 것을 추천합니다.

Jail 삭제하기

jail의 삭제는 jail 을 만드는 것 보다 더 쉽습니다. 뭐, 언제나 창조보다는 파괴가 더 간단한 법이죠. Test_Jail_2를 한번 파괴해 보도록 하겠습니다.

Test_Jail_2의 를 누르면 delete 라는 버튼이 보일 것입니다. 그것을 누르면 아래와 같은 메세지가 표시됩니다.

늘 그러했듯 Confirm을 누르면 DELETE 가 활성화됩니다. DELETE를 누르면 jail이 삭제됩니다.

plugin jail 도 똑같은 방법으로 삭제하면 됩니다.

마무리하며

jail을 만드는 법, 지우는 법, 마운트 포인트 만드는 방법과 지우는 방법, 그리고 plugin jail 을 설치하는 방법을 알아보았습니다.

다음 포스팅에서는 FreeNAS 를 업데이트 하는 방법에 대해서 알아보겠습니다.

시리즈 네비게이션<< ZFS 다루기FreeNAS 업데이트 >>

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다