35. 서버 관리 Part 4: 서버 배포

iFun Engine으로 작성한 게임 서버는 서비스 설정을 지정하고, 이를 패키지로 묶어서 개별 서버에 설치/업그레이드 할 수 있습니다. 이 문서에서는 그 과정을 설명합니다. 현재 Ubuntu 14.04 / 16.04 과 CentOS 6.5 / 7 을 지원합니다.

35.1. 서비스 설정하기

Centos 6.5 와 Ubuntu 14.04 는 upstart 를 활용하며, Centos 7 과 Ubuntu 16.04 는 systemd 를 이용합니다.

35.1.1. Upstart: Centos 6.5 & Ubuntu 14.04

프로젝트 소스 디렉터리의 ({{project-name}}-source) 다음 내용을 수정해서 서비스 설정을 수정할 수 있습니다.

etc/upstart/init/{{project-name}}.conf

서비스 스크립트 설정을 가지고 있는 파일입니다. 추가적인 수정사항은 Upstart Intro, Cookbook and Best Practises 를 참고해서 수정해주세요.

Note

Flavor: 역할에 따라 서버 구분하기 에 언급된 flavor 를 사용할 경우, 파일 이름은 etc/upstart/init/{{project-name}}.{{flavor}}.conf 입니다.

Note

1.0.0-1051 버전 이전에 생성한 프로젝트인 경우, etc/init 디렉터리와 etc/default 디렉터리에 설정파일이 있습니다.

etc/upstart/default/{{project-name}}

서비스 설정에서 사용할 값들을 정의하는 파일입니다.

# Sets this to 1 to enable, to 0 to disable
enabled=1
uid=root
gid=root
  • enabled: 서비스 활성화 여부. 이 값이 1이면 서버가 재시작한 후에 서비스가 자동으로 시작합니다.
  • uid: 서비스를 실행할 계정. 기본 값은 root 지만, 보안을 위해 다른 계정을 할당할 것을 권장합니다.
  • gid: 서비스를 실행할 그룹. 기본 값 대신 보안을 위해 다른 그룹을 할당할 것을 권장합니다.

Note

Flavor: 역할에 따라 서버 구분하기 에 언급된 flavor 를 사용할 경우, 파일 이름은 etc/upstart/default/{{project-name}}.{{flavor}} 입니다.

35.1.2. Systemd: Centos 7 & Ubuntu 16.04

프로젝트 소스 디렉터리의 etc/systemd/{{project-name}}.service 파일이 설정 파일입니다. 세부 사항은 Systemd 페이지를 확인해주세요.

Note

Flavor: 역할에 따라 서버 구분하기 에 언급된 flavor 를 사용할 경우, 파일 이름은 etc/systemd/{{project-name}}.{{flavor}}.service 입니다.

예제: 서비스를 실행할 유저 변경하기

보안 상의 이유로, root 대신에 다른 유저를 생성하고, 해당 유저 계정으로 서비스를 실행하는 것을 권장합니다. 아래는 centos 라는 유저와 그룹으로 서비스를 실행하게끔 수정한 예시입니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Service]
LimitNOFILE=999999

# It is strongly recommended that one should use uid:gid other than the root
# NOTE: Please update User=, Group=, and ExecStartPre=
User=centos
Group=centos

# Makes the daemon automatically restart
Type=simple
Restart=on-failure
RestartSec=5s

# create directories, and change permissions (with root privileges)
PermissionsStartOnly=true
ExecStartPre=/usr/bin/mkdir -p /var/log/funapi/example/glog \
  /var/log/funapi/example/activity \
  /var/crash/funapi/example
# NOTE: change root:root to service's uid:gid
ExecStartPre=/usr/bin/chown -R centos:centos /var/log/funapi/example/glog \
  /var/log/funapi/example/activity \
  /var/crash/funapi/example

ExecStart=/usr/bin/example-launcher

35.2. 패키지 생성

패키지 생성에 대해서는 서버 관리 Part 3: 서버 패키징 을 참고해주세요.

35.3. 패키지 설치/업그레이드

35.3.1. Ubuntu 14.04, 16.04

서버 관리 Part 3: 서버 패키징 에서 설명된 대로 deb 파일을 생성합니다. 이 파일을 서버에 복사한 후 dpkg 명령으로 설치합니다.

가령 example 이라는 이름의 게임인 경우 다음과 같습니다.

$ sudo dpkg -i example_0.0.1_install.deb
[sudo] password for ubuntu:
Selecting previously unselected package example.
(Reading database ... 424079 files and directories currently installed.)
Preparing to unpack example_0.0.1_install.deb ...
Unpacking example (0.0.1) ...
Setting up example (0.0.1) ...
Processing triggers for ureadahead (0.100.0-16) ...
ureadahead will be reprofiled on next reboot

Important

만약 funapi1-runtime 이 설치되지 않은 경우 패키지 설치 오류 메시지가 나옵니다. 이런 경우에는 다음 명령을 실행하면 자동으로 필요한 패키지와 서버 패키지가 설치됩니다.

$ sudo apt-get install -f

35.3.2. Centos 6.5, 7

서버 관리 Part 3: 서버 패키징 에서 설명된 대로 rpm 파일을 생성합니다. 이 파일을 서버에 복사한 후 rpm 명령으로 설치합니다.

가령 example 이라는 이름의 게임인 경우 다음과 같습니다.

$ sudo rpm -i example_0.0.1_install.rpm

Important

만약 funapi1-runtime 이 설치되지 않은 경우 패키지 설치 오류 메시지가 나옵니다. 이런 경우에는 다음 명령을 실행해서 funapi1-runtime 을 먼저 설치합니다.

$ sudo yum install funapi1-runtime

35.4. 서비스 시작/종료하기

35.4.1. Upstart: Centos 6.5 & Ubuntu 14.04

start, stop 명령으로 서비스를 시작하고 종료할 수 있습니다.

가령 example 이라는 서버를 설치한 경우 다음과 같이 실행합니다.

35.4.1.1. 서비스 시작

$ sudo start example
example start/running, process 27687

35.4.1.2. 서비스 종료

$ sudo stop example
example stop/waiting

35.4.2. Systemd: Centos 7 & Ubuntu 16.04

systemctl 명령을 이용해서 서비스를 활성화 하고 시작, 종료할 수 있습니다.

가령 example 이라는 서버를 설치한 경우 다음과 같이 실행합니다.

35.4.2.1. 서비스 활성화

서버 재시작 할 때 게임 서비스가 자동으로 뜨게 하기 위해서는 다음 명령으로 서비스를 활성화 합니다.

$ sudo systemctl enable example

35.4.2.2. 서비스 시작

$ sudo systemctl start example

35.4.2.3. 서비스 종료

$ sudo systemctl stop example

35.5. 서비스 실행 로그 보기

upstart 나 systemd 는 서버가 실행되거나 종료될 때 별도의 로그를 생성합니다. 이를 통해서 서비스가 원활히 실행되고 있는지 확인할 수 있습니다.

Note

게임 서버 자체의 로그는 프로그래밍 Part1: 디버그용 로그 을 참고해주세요.

Note

게임 서버의 coredump 에 대해서는 덤프파일 디버깅 & CPU 프로파일링 을 참고해주세요.

35.5.1. Upstart: Centos 6.5 & Ubuntu 14.04

Upstart로 실행한 경우, 서비스 로그는 /var/log/upstart/{{project-name}}.log 파일에 남습니다.

만일 example 이라는 서버의 경우 다음과 같이 로그를 볼 수 있습니다.

$ sudo less /var/log/upstart/example.log

35.5.2. Systemd: Centos 7 & Ubuntu 16.04

Systemd로 실행한 경우, 서비스 로그는 journalctl -x -u {{project-name}} 명령으로 확인할 수 있습니다.

만일 example 이라는 서버의 경우 다음과 같이 로그를 볼 수 있습니다.

$ sudo journalctl -x -u example

35.6. 패키지 버전 고정하기

라이브 환경에서는 사용하는 funapi1-runtime 나 에이전트, 혹은 개발하는데 사용한 외부 라이브러리의 버전을 고정해야하는 경우가 있습니다. 아래와 같은 방법을 이용하시면 됩니다.

35.6.1. Ubuntu 환경에서 버전 고정하기

버전 고정:

funapi1-runtime 의 버전을 고정한다고 하면, 다음과 같이 명령을 입력하면 됩니다.

$ sudo apt-mark hold funapi1-runtime

해당 명령 후에는 apt-get upgrade 등에서 해당 패키지를 제외하고 업데이트하게 됩니다.

버전이 고정된 패키지 확인:

$ sudo apt-mark showhold
funapi1-runtime

위에서 입력한 패키지가 버전이 고정된 것을 확인하실 수 있습니다.

버전 고정 해제:

다음 명령으로 패키지 버전이 고정된 것을 풀 수 있습니다.

$ sudo apt-mark unhold funapi1-runtime

이 이후에는 패키지를 업그레이드할 수 있습니다.

35.6.2. CentOS 환경에서 버전 고정하기

CentOS 환경에서 버전을 고정하려면 추가 패키지가 필요합니다. 다음 명령으로 설치해주시면 됩니다.

$ sudo yum install yum-versionlock

yum-versionlock 패키지를 설치한 후에 아래 명령들을 실행할 수 있습니다.

버전 고정:

funapi1-runtime 의 버전을 고정한다고 하면, 다음과 같이 명령을 입력하면 됩니다.

$ sudo yum versionlock funapi1-runtime

해당 명령 후에는 yum update 등에서 해당 패키지를 제외하고 업데이트하게 됩니다.

버전이 고정된 패키지 확인:

$ sudo yum -q versionlock list
0:funapi1-runtime-1.0.0-1680centos7.*

위에서 입력한 패키지가 버전이 고정된 것을 확인하실 수 있습니다.

버전 고정 해제:

다음 명령으로 패키지 버전이 고정된 것을 풀 수 있습니다.

$ sudo yum versionlock delete funapi1-runtime

이 이후에는 패키지를 업그레이드할 수 있습니다.

Important

CentOS 6에서는 sudo yum versionlock delete '*:funapi1-runtime*' 처럼 입력하셔야 합니다.

35.7. 비표준 위치에 게임 서버 설치하기

35.7.1. 비표준 위치에 게임 서버 패키지 설치하기

앞에서는 DEBRPM 형태의 파일을 만들어서 배포하는 것을 설명했습니다. 이런 패키지 파일은 미리 정해진 위치에 게임 서버를 설치하고, root 권한도 필요로 합니다.

그러나 경우에 따라서는 root 권한을 취득할 수 없는 경우도 있을 수 있고, 특정 디렉토리 아래 게임 서버 내용을 모두 설치해야될 수도 있습니다. 예를 들어, 퍼블리셔에게 게임 서버를 전달하면 퍼블리셔가 사용하는 Linux 계정 아래 게임 패키지가 그대로 설치되길 바라는 경우를 생각해볼 수 있습니다. 이런 경우는 설치 위치를 강제하는 DEBRPM 으로는 곤란하고 tar.gz 로 패키지를 생성해서 퍼블리셔에게 전달하고 퍼블리셔가 원하는 위치에 압축을 풀게 하는 것이 좋습니다. (tar.gz 의 생성에 관련해서는 생성 가능한 패키지 타입 을 참고하세요.)

편의상 우리가 만드는 게임의 이름을 hello 라고 하고, lobby flavor 를 사용했다고 하겠습니다. 그러면 생성되는 패키지는 hello_0.0.1_install-lobby.tar.gz 가 될 것입니다. 이제 퍼블리셔가 관리하는 리눅스 서버의 계정이 zeus 라고 가정했을 때, 퍼블리셔는 저 패키지를 /home/zeus 아래에서 풀었을 것입니다.

$ cd /home/zeus
$ tar zxf hello_0.0.1_install-lobby.tar.gz

이렇게 하면 /home/zeus 아래에 DEBRPM 으로 설치했을 때 / 디렉토리 아래 설치되었을 내용들이 그대로 복사된 것을 확인하실 수 있을 겁니다.

35.7.2. 비표준 위치에 게임 서버 패키지 설치하고 서비스로 띄우기

그런데, 이 방법은 파일은 복사하지만, upstartsystemd 처럼 게임 서버를 서비스로 (즉, 데몬으로) 실행시키는 것을 자동으로 해줄 수는 없습니다. 따라서 이런 설정은 수작업으로 해줘야됩니다.

또한 서비스를 등록하더라도 / 가 아니라 우리가 지정한 /home/zeus 에서 게임 서버를 찾을 수 있게끔 경로를 지정하는 작업도 필요합니다. 이 작업들은 게임 서버 OS를 세팅할 때 처음 1회만 하면 됩니다.

아래는 Upstart 와 Systemd 의 경우에 대해서 서비스를 등록하는 방법을 설명합니다. 두 가지 방법 모두, 환경 변수를 지정해주고 스크립트를 등록해주는 작업을 하게 됩니다.

35.7.2.1. 서비스 설정 파일에 지정 가능한 환경 변수

  • GAME_ROOT_DIR: 게임 서버가 설치된 경로를 지정합니다. 지정하지 않으면 / 가 기본값으로 사용됩니다.
  • GAME_MANIFEST_OVERRIDE: 임시로 MANIFEST.json 오버라이드하기 에 기술된 MANIFEST.json 오버라이드 파일 위치를 지정합니다. 지정하지 않으면 /etc/{{project}}/MANIFEST.override.json 으로 기본 지정됩니다.
  • GAME_LOG_ROOT_DIR: 로그 파일들이 생성될 디렉토리를 지정합니다. 지정하지 않으면 기본값으로 /var/log/funapi/게임이름 이 사용됩니다.
  • GAME_CRASHDUMP_ROOT_DIR: 코어덤프 디렉토리를 지정합니다. 지정하지 않으면 기본값으로 /var/crash/funapi/게임이름 이 사용됩니다.
  • GAME_GLOG_OPTIONS: Google logging 의 추가 옵션을 지정합니다. 지정하지 않으면 기본값으로 –max_log_size=10 –stop_logging_if_full_disk 가 사용됩니다.
  • GAME_CONTACT_EMAIL_ADDRESS: 게임 서버가 죽는 경우 알림을 받을 이메일 주소를 지정합니다. 지정하지 않으면 이메일을 보내지 않습니다.

Tip

GAME_CONTACT_EMAIL_ADDRESS 를 세팅하면 게임 서버가 죽을 때마다 알림 메일을 받을 수 있어서 편리합니다.

35.7.2.2. Upstart (Ubuntu 14.04) 인 경우 수작업으로 서비스 등록하기

/home/zeus 아래 보면 etc 라는 디렉토리가 있을 것입니다. 그리고 그 안에는 변수 설정을 포함하는 default 라는 디렉토리와 실제 서비스 스크립트을 포함하는 init 디렉토리가 하위 디렉토리로 존재합니다.

$ cd /home/zeus
$ ls etc
default init

우리 게임 이름이 hello 이며 lobby flavor 이므로 각 하위 디렉토리에는 다음과 같은 파일들이 존재할 것입니다.

$ ls etc/default
hello.lobby

$ ls etc/init
hello.lobby.conf

서비스가 우리가 게임을 설치한 /home/zeus 에서 프로그램을 찾게끔, 변수 설정 파일인 etc/default/hello.lobby 에 다음처럼 환경 변수를 export 를 붙여서 정의합니다. 그 외에도 서비스 설정 파일에 지정 가능한 환경 변수 에 언급된 다른 변수들도 쓸 수 있습니다.

export GAME_ROOT_DIR=/home/zeus

Important

export 를 반드시 쓰셔야 합니다.

이제 GAME_ROOT_DIR 을 지정했으면 다음처럼 파일들을 복사해줍니다.

$ sudo cp /home/zeus/etc/default/hello.lobby /etc/default/
$ sudo cp /home/zeus/etc/init/hello.lobby.conf /etc/init/

게임 서버를 실행하기 위해서는 다음과 같이 실행합니다.

$ sudo service hello start

35.7.2.3. Systemd (CentOS 7 / Ubuntu 16.04) 인 경우 수작업으로 서비스 등록하기

/home/zeus 아래에 lib/systemd/system/ 라는 디렉토리가 있을 것이고 그 아래 hello.lobby.service 라는 systemd 서비스 설정 파일이 존재할 것입니다.

$ ls lib/systemd/system
hello.lobby.service

이 파일을 다음처럼 복사합니다.

$ sudo cp lib/systemd/system/hello.lobby.service /lib/systemd/system/

그리고 /etc/default/hello.lobby 라는 환경 변수 설정 파일을 만들고, systemd 가 우리가 게임을 설치한 /home/zeus 에서 프로그램을 찾게끔 다음처럼 써줍니다. 서비스 설정 파일에 지정 가능한 환경 변수 에 나열된 다른 변수들도 쓸 수 있습니다.

GAME_ROOT_DIR=/home/zeus

Important

Ubuntu 의 경우와는 다르게 export 를 쓰지 않습니다.

이제 다음처럼 게임 서버를 실행할 수 있습니다.

$ sudo systemctl start hello.lobby