본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

Fly Machines에서 사용자 코드 실행하기 (Run User Code on Fly Machines)

원문 보기 위키 갱신

Fly Machines을 함수형 서비스(FaaS)처럼 활용해 사용자 코드를 실행하는 방법을 알려드려요. Machines의 REST API로 여러 리전에 걸쳐 사용자 코드를 빠르게 띄우고, 유휴 시 자동 종료되도록 해 컴퓨팅 비용을 절약할 수 있어요.

출처: 문서

본문

Fly Machines은 약 300ms 만에 인스턴스를 부팅할 수 있는 빠른 REST API를 가진 Firecracker VM이에요. Fly.io가 지원하는 어느 리전에서든 실행할 수 있어요.

Machines의 한 가지 용도는 서비스를 확장하기 위해 사용자 코드를 실행하거나, 그 자체로 서비스로 쓰는 거예요. 사람들은 이것을 **Functions-as-a-Service (FaaS)**라고 부르기도 해요.

사용자 코드는 위험으로 가득 차 있어요. Fly Machines은 가장 끔찍하고 버그투성이이며 노골적으로 적대적인 사용자 코드조차 안전하게 실행해요. 대부분의 FaaS는 비슷하게 동작해요. 일반적인 아이디어: 사용자 코드를 패키징하고, 런타임 환경을 정의하고, VM에서 코드를 실행한 다음, 유휴 상태가 되면 VM을 꺼서 컴퓨팅 요금을 아껴요. 그러면서 사용자에게 요청당 요금을 청구하는 거죠!

사용자 코드를 Docker 이미지로 패키징하는 것은 대부분 여러분의 몫이에요. 나머지는 우리가 도와드릴 수 있어요.

Machines API 사용하기 (Working with the Machines API)

Machines는 간단한 REST API로 운영돼요. 먼저 Machines 문서를 방문해 이 가이드를 준비하세요.

런타임 Docker 이미지 가져오기 또는 만들기

함수형 서비스에는 사용자 코드를 부팅하고 유휴 상태가 되면 종료할 수 있는 잘 정의된 런타임 환경이 필요해요.

여기서는 몇 분간 비활성 상태 후 종료되는 작은 Golang HTTP 프록시 뒤에서 실행되는 간단한 Fastify 서버를 사용할 거예요.

앱 만들기 (Create an app)

고유한 이름을 선택하고 머신을 함께 그룹화하는 데 필요한 애플리케이션을 만드세요. 이 애플리케이션은 인터넷에서 머신에 접근하는 게이트웨이이기도 해요.

curl -i -X POST \\\
    -H "Authorization: Bearer ***" -H "Content-Type: application/json" \\\
    "${FLY_API_HOSTNAME}/v1/apps" \\\
  -d '{
      "app_name": "my-app-name",
      "org_slug": "personal",
      "network": "my-app-name-network"
    }'

Status: 201

network 필드에 주목하세요. 이 필드는 앱을 조직의 다른 프라이빗 네트워크와 격리하는 데 필요해요. 커스텀 프라이빗 네트워크에 대해 더 알아보세요.

앱에 IP 주소를 할당하세요. 이렇게 하면 해당 IP에서, 그리고 my-app-name.fly.dev를 통해 앱에 접근할 수 있어요.

fly ips allocate-v4 -a my-app-name

새 머신 실행하기 (Launch a new machine)

Docker 이미지와 네트워킹 구성을 제공해 사용자 머신을 실행하세요.

curl -i -X POST \\\
    -H "Authorization: Bearer ***" -H "Content-Type: application/json" \\\
    "${FLY_API_HOSTNAME}/v1/apps/my-app-name/machines" \\\
  -d '{
      "name": "quirky-machine",
      "config": {
        "image": "flyio/fastify-functions",
        "env": {
          "APP_ENV": "production"
        },
        "services": [
          {
            "ports": [
              {
                "port": 443,
                "handlers": [
                  "tls",
                  "http"
                ]
              },
              {
                "port": 80,
                "handlers": [
                  "http"
                ]
              }
            ],
            "protocol": "tcp",
            "internal_port": 8080
          }
        ],
        "checks": {
            "httpget": {
                "type": "http",
                "port": 8080,
                "method": "GET",
                "path": "/",
                "interval": "15s",
                "timeout": "10s"
            }
        }
      }
    }'

Status: 200

Machines는 영구적이므로 응답의 ID를 잘 보관해 두세요.

사용자의 서비스는 이 API 호출 직후 부팅돼요. 실행 속도는 이미지 크기에 비례해요. 작은 이미지는 2초 안에 부팅되어야 해요. 크고 복잡한 이미지는 부팅이 훨씬 느려요.

https://my-app-name.fly.dev에서 새 머신에 접근해 보세요. 120초(기본값, 구성 가능) 동안 요청이 없으면 머신이 종료되지만, 요청이 들어오면 자동으로 다시 시작돼요.

다른 리전에서 Machine 실행하기

그 머신은 여러분에게 가장 가까운 리전에서 실행됐어요. 호주 사용자에게 사용자 함수가 빠르게 실행되길 원한다고 해 보죠. 거기에 다른 머신을 실행해 볼게요.

할당한 Anycast IP는 배포된 머신이 있는 가장 가까운 리전으로 트래픽을 라우팅해요. 머신이 중지된 상태라면 자동으로 시작돼요.

curl -i -X POST \\\
    -H "Authorization: Bearer ***" -H "Content-Type: application/json" \\\
    "${FLY_API_HOSTNAME}/v1/apps/my-app-name/machines" \\\
  -d '{
      "name": "machine-syd",
      "config": {
        "image": "flyio/fastify-functions",
        "env": {
          "APP_ENV": "production"
        },
        "services": [
          {
            "ports": [
              {
                "port": 443,
                "handlers": [
                  "tls",
                  "http"
                ]
              },
              {
                "port": 80,
                "handlers": [
                  "http"
                ]
              }
            ],
            "protocol": "tcp",
            "internal_port": 8080
          }
        ]
      },
      "region": "syd"
    }'

Status: 200

Machine 중지하기 (Stop a machine)

FaaS 환경에서는 보통 머신이 종료되길 기다릴 거예요. 하지만 필요하다면 API 호출로 중지할 수도 있어요.

curl -i -X POST \\\
    -H "Authorization: Bearer ***" -H "Content-Type: application/json" \\\
    "${FLY_API_HOSTNAME}/v1/apps/my-app-name/machines/d5683210c7968e/stop" 

Status: 200

{
  "ok": true
}

기존 Machine 시작하기

일단 생성되면 머신은 삭제할 때까지 중지하고 시작할 수 있어요. 좋은 소식은 이미지가 첫 실행 후 캐시된다는 거예요. 기존 머신을 시작하는 것은 매우 빠르답니다.

기존 Machine ID를 다시 사용해 시작하세요:

curl -i -X POST \\\
    -H "Authorization: Bearer ***" -H "Content-Type: application/json" \\\
    "${FLY_API_HOSTNAME}/v1/apps/my-app-name/machines/d5683210c7968e/start" 

Status: 200

{
  "previous_state": "stopped"
}

start API 호출은 머신이 중지(stopped) 상태일 때만 성공적으로 반환돼요. 다만 실행 중인 머신에 start를 호출해도 안전해요. 머신 상태가 확실하지 않다면 그냥 start를 호출하고 오류 응답은 무시하세요.

시작 작업은 파일 시스템 변경을 지워요. 사용자 프로세스는 새로운 런타임 환경으로 시작돼요. 재할당되기 전에 중지하기만 하면 머신을 사용자 간에 공유해도 안전해요.

배포 세부 정보 확인하기

이제 머신 몇 대가 실행 중이니 fly logs -a my-app-name으로 무슨 일이 일어나는지 볼 수 있어요. 또한 개요는:

```bash cmd fly status -a my-app-name ```
App
  Name     = my-app-name
  Owner    = personal
  Hostname = my-app-name.fly.dev

Machines
ID            	NAME          	REGION	STATE    	CREATED
10e286064b1867	machine-syd   	syd   	started	2022-05-20T17:07:36Z
0e286e40cee686	quirky-machine	cdg   	stopped	2022-05-20T17:07:04Z

여기서 하나의 Machine이 종료된 것을 볼 수 있어요.

가장 유사한 API 호출은 앱의 모든 Machine을 나열해요:

curl -i -X GET \\\
    -H "Authorization: Bearer ***" -H "Content-Type: application/json" \\\
    "${FLY_API_HOSTNAME}/v1/apps/my-app-name/machines" 

Status: 200

Machine 삭제하기

다 사용했으면 머신을 삭제하세요:

curl -i -X DELETE \\\
    -H "Authorization: Bearer ***" -H "Content-Type: application/json" \\\
    "${FLY_API_HOSTNAME}/v1/apps/my-app-name/machines/d5683210c7968e" 

Status: 200

{
  "ok": true
}

추가 참고 사항 (Additional notes)

Machines API는 새롭고 가능성으로 가득 차 있어요. 아직 모든 것을 완성하지 못했으니 질문이 있으면 포럼에 글을 올려 주세요! 주목할 만한 몇 가지 사항이 있어요:

위에서 설명한 wake-on-request 동작은 리전당 머신이 하나 이상 실행될 때 예측 불가능할 수 있어요.

deploy, scale, autoscaling 같은 표준 flyctl 작업은 현재 Machines에서 지원되지 않아요.

ssh는 지원돼요. 머신의 IPv6 주소(fly machines list에서)로 SSH할 수 있어요:

fly ssh console 'your:machines:ipv6:address:0:0:0:0'

또는 fly ssh console -s를 사용해 목록에서 연결할 머신을 선택할 수 있어요:

fly ssh console -a my-app-name -s
? Select instance:  [Use arrows to move, type to filter]
> sjc (fdaa:0:6787:a7b:a15f:ee6a:3882:2)
  sjc (fdaa:0:6787:a7b:a15f:c306:4566:2)
  sjc (fdaa:0:6787:a7b:a15f:1a8c:2c01:2)

더 알아보기 (Learn more)