AWS 데디케이티드 서버 호스팅 지원

이 문서는 AWS 클라우드 서비스에서 데디케이티드 서버를 호스팅하는 방법에 대해서 설명합니다.

AWS 클라우드에서 데디케이티드 서버를 호스팅하면 설정에 따라 자동으로 인스턴스를 생성하거나 삭제하는 오토스케일링 기능을 지원합니다.

Important

서버 구성 시 데디케이티드 서버 지원 내용을 참고하여 보안 설정을 해주세요.

AWS 데디케이티드 서버 호스팅

AWS 데디케이티드 서버 호스팅에 대한 기본적인 동작은 다음과 같습니다.

  • AWS 데디케이티드 서버 호스팅을 활성화하면 게임 서버 시작 후 MANIFEST 의 설정을 바탕으로 주기적으로 (약 30초) 인스턴스를 계산하고 스케일 아웃을 진행합니다.

  • AWS 데디케이티드 서버 호스팅 시 기존보다 높은 버전의 데디케이티드 서버가 생성된 경우, 이미 실행 중인 낮은 버전의 데디케이티드 서버들은 Deprecated 대상이 됩니다.

  • Deprecated 대상이 된 서버들은 인스턴스 계산에 포함하지 않으며, 매치 대상에 포함하지도 않습니다. 매치가 0 인 Deprecated 대상 서버들은 종료됩니다.

그럼, 본격적으로 AWS 데디케이티드 서버 호스팅의 사용 방법에 대해서 알아보겠습니다.

VM 이미지(AMI) 준비

AWS 데디케이티드 서버 호스팅 기능을 사용하기 위해서는 funapi-dedicated-server-host 패키지와 데디케이티드 서버 실행파일이 설치된 VM 이미지가 필요합니다.

VM 이미지는 데디케이티드 서버 호스트를 생성할 때 사용하며 생성 과정은 아래와 같습니다.

  1. 호스트 매니저를 실행할 EC2 인스턴스를 생성합니다.

  2. 해당 인스턴스에 데디케이티드 서버 호스트 매니저를 설치하고, 데디케이티드 서버 실행파일을 복사합니다.

  3. 호스트 매니저 설정 파일을 설정하고, 정상적으로 동작하는지 확인합니다.

  4. 여기 를 참고하시어 호스트가 부팅될 때 호스트 매니저가 자동으로 실행되도록 서비스로 등록해 주세요.

  5. 설정이 문제없는 것이 확인됐다면 해당 인스턴스를 종료하고 VM 이미지로 만듭니다.

5-1) 이미지로 만들려는 인스턴스를 선택하고 우클릭 후 Image - Create Image 를 클릭해 주세요.

_images/dedicated-server-create-image-1.png

5-2) Image name 을 포함한 필요한 정보를 입력하고 Create Image 를 클릭하여 VM 이미지 생성을 완료해 주세요.

_images/dedicated-server-create-image-2.png

5-3) IMAGES - AMIs 페이지에서 생성한 VM 이미지를 확인할 수 있습니다.

_images/dedicated-server-create-image-3.png

이렇게 만든 VM 이미지를 AWS 데디케이티드 서버 호스팅에 사용합니다.

아이펀 엔진 설정

AWS 데디케이티드 서버 호스팅 기능을 사용하기 위해서는 아이펀 엔진 서버에 관련 설정을 추가해야 합니다.

MANIFEST 파일 안에 있는 DedicatedServerManager 항목에 다음과 같은 값들을 설정해야 합니다.

"DedicatedServerManager": {
  "aws_settings":
  [
    {
      // 리전 1
      "image_id": "ami-7478521b",
      "instance_type":"t2.small",
      "instance_name":"dedi_server",
      "key_name": "key_name",
      "min_instances": 5,
      "max_instances": 15,
      "reserved_instances": 2,
      "subnet_id":"subnet-9036f7dc",
      "security_group_id":[
          "sg-f7bec69c"
      ],
      "region" : "ap-south-1",
      "aws_key_id" : "<API 키>",
      "aws_secret_key" : "<API 시크릿>",
      "user_data": "sudo systemctl start funapi-dedicated-server-host",
      "termination_delay": 1
    }
  ],
  "use_aws_dedicated_server_hosting": true,
  "dedicated_server_orchestrator_verbose_log": true
  "dedicated_server_spawn_timeout": 30,
  "dedicated_server_verbose_log": true
},
...
  • use_aws_dedicated_server_hosting: AWS 데디케이티드 서버 호스팅 활성화 여부를 설정합니다.

  • dedicated_server_orchestrator_verbose_log: AWS 데디케이티드 서버 호스팅 관련 로그 출력 여부를 설정합니다.

  • image_id: AWS 데디케이티드 서버 호스팅에 사용할 이미지. 준비 단계 5-3 에서 확인한 AMI ID 를 넣어줍니다.

  • instance_type: 생성할 AWS 인스턴스 타입을 입력합니다. 위 예제에서는 t2.small 을 입력했습니다.

  • instance_name: 마킹할 인스턴스 이름을 입력합니다.

  • key_name: 인스턴스 생성 시 사용할 SSH 키페어 이름을 입력합니다.

  • min_instances: AWS 데디케이티드 서버 호스팅 시 유지할 최소 인스턴스 개수를 입력합니다.

  • max_instances: AWS 데디케이티드 서버 호스팅 시 생성할 인스턴스의 최대 개수를 입력합니다.

  • reserved_instances: 유지할 대기 인스턴스의 최소 개수를 입력합니다. 대기 인스턴스는 매치가 없는 인스턴스를 말합니다.

  • subnet_id: 사용할 서브넷 아이디를 입력합니다.

  • security_group_id: 사용할 보안 그룹 목록을 입력합니다.

  • region: 인스턴스를 띄울 지역을 입력합니다.

  • aws_key_id: AWS API 키를 입력합니다.

  • aws_secret_key: AWS API 시크릿을 입력합니다.

  • user_data: 서버 시작 시 인스턴스 안에서 실행할 명령어 입니다. AWS EC2 인스턴스 생성 시 User data 로 지정하는 부분입니다.

  • termination_delay: 종료 대기 시간을 설정 합니다. deprecated 서버들은 설정 값만큼의 시간이 지나면 AWS 상에서 삭제합니다.

Note

오토스케일링 시 인스턴스 개수는 min_instance, max_instance, reserved_instance 값에 따라 결정됩니다. 예를 들어 max_instance = 8, min_instance = 3, reserved_instance = 2 라면 AWS 데디케이티드 서버 호스팅 시작 시 min_instance 값인 3개의 인스턴스를 생성합니다. 이후 2개의 인스턴스에 매치가 생성되면 대기 인스턴스는 1개가 되고 reserved_instance 값에 따라 1개의 새로운 인스턴스를 생성합니다.

Warning

region 에는 Region 값을 입력해야 합니다(예: ap-south-1). ap-south-1a 와 같은 Availability Zone 값과 혼동하여 사용하지 않도록 주의해주세요.

데디케이티드 서버 호스트 설정 콜백

서버가 실행 중일 때, 대기하는 인스턴스의 수를 조절할 수 있는 콜백을 정의할 수 있습니다.

typedef boost::function<uint32_t (
              uint32_t current_instance_count,
              uint32_t idle_instance_count,
              uint32_t min_instance_count,
              uint32_t max_instance_count,
              uint32_t reserved_instance_count)>
    ConfigureReservedInstanceCountCallback;

void RegisterConfigureReservedInstanceCountCallback(
              const ConfigureReservedInstanceCountCallback &callback);
public static class DedicatedServerManager
{
  public delegate uint ConfigureReservedInstanceCountCallback (
                uint current_instance_count,
                uint idle_instance_count,
                uint min_instance_count,
                uint max_instance_count,
                uint reserved_instance_count);

  public static void RegisterConfigureReservedInstanceCountCallback(
                ConfigureReservedInstanceCountCallback callback)
}

콜백이 지정되어 있으면 인스턴스 계산 주기에 따라 콜백을 실행하며, 콜백을 통해 스폰할 대기 인스턴스 개수를 결정합니다.

콜백이 지정되어있지 않으면 MANIFESTreserved_instance 값을 사용합니다.

AWS 데디케이티드 서버 호스팅 실행 결과

AWS 데디케이티드 서버 호스팅을 사용 설정을 완료하면 아래와 같이 설정값에 따라 자동으로 인스턴스를 생성합니다.

_images/dedicated-server-aws-instance.png

Note

2개 이상의 리전 을 사용하는 경우나 스팟 인스턴스 를 이용하고자 하는 경우에 대해서는 다음 절에서 자세히 설명하겠습니다.

데디케이티드 서버 State 서비스

2개 이상의 AWS 리전에서 인스턴스를 생성하려는 경우나 아이펀 엔진 서버와 인스턴스를 생성할 리전이 다를 경우, 다시말해 공용 네트워크 상에 서버들을 구성할 때는 정보를 중계하는 Redis 서버의 보안이 문제가 될 수 있습니다.

이런 문제를 보완하기 위해서 Redis 서버의 프록시 역할을 하는 웹서버인 State 서비스를 제공합니다.

아래는 State 서비스를 사용하도록 설정하는 방법을 설명합니다.

Warning

State 서비스는 OAuth 기반으로 통신하기 때문에 OAuth 서버가 필요합니다. OAuth 서버는 아이펀 엔진에서 제공하는 기능이 아니므로 필요한 경우 직접 준비해 주셔야 합니다.

State 서비스 설치

Redis 가 있는 서버에 아래 명령어를 입력하여 데디케이티드 서버 State 서비스를 설치합니다.

// ubuntu
$ sudo apt-get install -y funapi1-ds-state-service
$ sudo systemctl start funapi-ds-state-service

// centos
$ sudo yum install -y funapi1-ds-state-service
$ sudo systemctl start funapi-ds-state-service

State 서비스 설정

데디케이티드 서버 State 서비스의 설정 가능한 항목과 설명은 funapi-ds-state-service.flag 파일에 있으며, 패키지 설치 시에 /etc/funapi-ds-state-service/ 디렉터리와 함께 생성됩니다.

funapi-ds-state-service.flag

# 서비스 주소 및 포트 번호를 지정합니다.
--host=0.0.0.0
--port=5005

# Redis 호스트 주소 및 포트 번호를 지정합니다.
--redis_host=127.0.0.1
--redis_port=6379

# Redis를 `AUTH {auth-string}` 커맨드로 보호하는 중이라면, `auth-string` 값을 입력합니다.
#--redis_auth=


# OAuth 서비스의 base url과 verification url을 지정합니다.
# OAuth 서비스는 Bearer 토큰을 확인할 수 있는 API를 제공해야합니다.
--oauth_base_url=http://127.0.0.1:8000/
--oauth_verification_url=oauth/info


# TLS (https) 를 사용 여부 및 cert 파일과 key 파일 경로를 지정합니다.
--enable_tls=False
--tls_cert_file_path=/etc/your-cert/example.ifunfactory.com/fullchain.pem
--tls_key_file_path=/etc/your-cert/example.ifunfactory.com/privkey.pem

서버앱의 MANIFEST 와 호스트 매니저의 설정 파일( .flag ) 에도 설정을 추가해야 합니다.

MANIFEST

"DedicatedServerManager": {
  "aws_settings":
  [
     {
      // 리전 1
      ...
    },
    {
      // 리전 2
      ...
    }
  ],
  ...
  "dedicated_server_enable_oauth" : true,
  "dedicated_server_oauth_base_url":"http://127.0.0.1:8000/",
  "dedicated_server_oauth_token_url":"oauth/token?grant_type=client_credentials",
  "dedicated_server_oauth_verification_url":"oauth/info",
  "dedicated_server_oauth_client_id":"dev",
  "dedicated_server_oauth_client_secret":"dev",
  "dedicated_server_state_service_url":"http://127.0.0.1:5005/",
},
  • dedicated_server_enable_oauth: OAuth 활성화 여부를 설정합니다. State 서비스 사용 시 필요하므로 true 로 설정해 주세요.

  • dedicated_server_oauth_base_url: OAuth 인증 서버 주소를 입력합니다.

  • dedicated_server_oauth_token_url: OAuth 토큰 발급 URL을 입력합니다.

  • dedicated_server_oauth_verification_url: OAuth 토큰 인증 URL을 입력합니다.

  • dedicated_server_oauth_client_id: OAuth 클라이언트 ID를 입력합니다.

  • dedicated_server_oauth_client_secret: OAuth 시크릿을 입력합니다.

  • dedicated_server_state_service_url”: State 서버 주소를 입력합니다.

funapi-dedicated-server-host.flag

...
--enable_oauth=True
--oauth_base_url=http://127.0.0.1:8000/
--oauth_verification_url=/oauth/info
--oauth_auth_url=/oauth/token?grant_type=client_credentials
--oauth_client_id=dev
--oauth_client_secret=dev
--oauth_content_type=application/json

--state_service_endpoint=http://127.0.0.1:5005
...

OAuth 관련 값들과 State 서비스가 설치된 주소를 입력합니다.

외부에서 AWS 데디케이티드 서버 호스팅 설정 변경

외부에서 데디케이티드 서버 매니저의 AWS 설정을 변경하기 위해서는 JWT 토큰이 필요합니다. JWT 토큰 인증 시 OAuth 인증 서버가 필요하므로 OAuth 서버 설정도 함께 필요합니다.

AWS 동적 업데이트를 위한 설정

MANIFEST 파일에 아래와 같은 설정을 추가해 주세요.

"DedicatedServerManager": {
  ...
  "dedicated_server_enable_oauth" : true,
  "dedicated_server_oauth_base_url":"http://127.0.0.1:8000/",
  "dedicated_server_oauth_token_url":"oauth/token?grant_type=client_credentials",
  "dedicated_server_oauth_verification_url":"oauth/info",
  "dedicated_server_oauth_client_id":"dev",
  "dedicated_server_oauth_client_secret":"dev",
  "dedicated_server_state_service_url":"http://127.0.0.1:5005/",
  "dedicated_server_oauth_use_jwt":true,
  "dedicated_server_aws_settings_allow_update":true,
  "dedicated_server_oauth_jwt_public_key":"/dsm/rsa_sha256.key.pub"
},
  • dedicated_server_oauth_use_jwt: JWT 사용 여부를 설정합니다. AWS 동적 업데이트 사용시 필요하므로 true 로 설정해 주세요.

  • dedicated_server_aws_settings_allow_update: AWS 동적 업데이트 사용 여부를 설정합니다.

  • dedicated_server_oauth_jwt_public_key: JWT pub 키 파일 경로를 입력합니다. OAuth 인증 서버에서 제공하는 pub 키를 사용하면 됩니다.

AWS 설정 동적 업데이트

REST API 로 AWS 설정을 가져오거나 변경할 수 있습니다. API 호출 시 OAuth 인증 서버에서 발급 받은 JWT 토큰을 헤더에 넣어줘야 합니다.

AWS 설정 가져오기

GET /v1/dedicated_server/aws_settings/

Header: Authorization: Bearer <JWT 토큰>

AWS 설정 업데이트

PUT /v1/dedicated_server/aws_settings/

Header: Authorization: Bearer <JWT 토큰>

Body: MANIFEST/DedicatedServerManager/”aws_settings” 에 들어갈 내용

(예제) AWS 설정 업데이트

$ curl -X PUT -H "Authorization: Bearer <JWT 토큰>" \
       -d '[{"image_id":"ami-7478521b","instance_type":"t2.small","instance_name":"dedi_server","key_name":"ds", \
             "min_instances":1,"max_instances":15,"reserved_instances":1,"subnet_id":"subnet-9036f7dc", \
             "security_group_id":["sg-f7bec69c"],"region":"ap-south-1","aws_key_id":"<API 키>","aws_secret_key":"<시크릿>", \
             "user_data":"#!/bin/bash\nsudo systemctl start funapi-dedicated-server-host","termination_delay":1}]'\
       http://35.168.138.220:8014/v1/dedicated_server/aws_settings/

JWT 권한 승인 콜백

JWT 클레임을 승인하는 콜백을 등록합니다.

typedef boost::function<bool (
    const std::string &uri, const fun::Json &claim)> JwtAuthorizationCallback;

static void RegisterJwtAuthorizationCallback(
    const JwtAuthorizationCallback &callback);
public static class DedicatedServerManager
{
  public delegate bool JwtAuthorizationCallback (string uri, JObject claim);

  public static void RegisterJwtAuthorizationCallback( JwtAuthorizationCallback callback);
}

JWT 사용 설정 시 유효한 콜백입니다.

스팟 인스턴스 사용

AWS 데디케이티드 서버 호스팅 시 스팟 인스턴스를 사용하도록 설정할 수 있습니다.

Warning

스팟 인스턴스는 가격 설정에 따라 예상하지 못한 순간에 인스턴스가 종료될 수 있기 때문에 주의해서 사용해 주세요.

스팟 인스턴스를 사용하기 위해서는 Spot Fleet Tagging role 이 필요합니다. 먼저 아래와 같은 순서로 EC2 - Spot Fleet Tagging Role 을 생성해 주세요.

  1. IAM - Roles 창으로 이동한 후 Create role 버튼을 눌러주세요.

_images/dedicated-server-spot-role-1.png
  1. EC2 - Spot Fleet Tagging 을 선택한 후 Next 버튼을 눌러주세요.

_images/dedicated-server-spot-role-2.png
  1. AmazonEC2SpotFleetTaggingRole 을 확인한 후 Next 버튼을 눌러주세요.

_images/dedicated-server-spot-role-3.png
  1. 필요하다면 tag 를 추가하신 후 Next 버튼을 눌러주세요.

_images/dedicated-server-spot-role-4.png
  1. Role name 을 입력하고 Create role 버튼을 눌러 생성을 완료해 주세요.

_images/dedicated-server-spot-role-5.png

그리고 MANIFEST 파일의 DedicatedServerManager 항목에 스팟 인스턴스 전용 설정을 추가하면 됩니다.

"DedicatedServerManager": {
  "aws_settings":
  [
    {
      ...
      // spot 전용
      "use_spot_fleet":true,
      "spot_iam_role_arn": "arn:aws:iam::477526298615:role/dsm-spot-fleet",
      "spot_max_price": 0.01,
      "spot_termination_threshold_price":0.015,
      "spot_block_duration_hours":6
    }
  ],
  ...
}
  • use_spot_fleet: 스팟 인스턴스 활성화 여부를 설정합니다.

  • spot_iam_role_arn: 위에서 생성한 Role 의 ARN (Amazon Resource Name) 을 입력합니다.

  • spot_max_price: 이 가격을 넘으면 스팟 인스턴스를 생성하지 않습니다.

  • spot_termination_threshold_price: 이 가격을 넘으면 스팟 인스턴스를 종료합니다.

  • spot_block_duration_hours: 스팟 인스턴스를 유지할 최소 시간을 설정합니다. 1-6 시간 사이 값을 설정할 수 있습니다.

스팟 인스턴스를 사용하도록 설정하면 인스턴스 생성이 필요한 경우 아래와 같이 스팟 리퀘스트를 생성합니다.

_images/dedicated-server-spot-instance.png