Oracle Functions에서 OCI 인스턴스 시작, 중지 및 재부팅

Oracle Functions (Fn)를 사용하여 OCI 인스턴스를 시작, 중지 및 재부팅하는 기능을 소개합니다.
실행 방법과 코드 해설에 대해 설명합니다.

Fn, OracleFunctions에 대해, 어떠한 것인가 메모 쓰기를 게재했으므로 좋으면 봐 주세요.
· Oracle Functions에 대한 메모

실행 방법



인스턴스의 OCID를 지정해 대상을 기동, 정지, 재기동시킵니다. Go에서 해요.

OCI SDK를 실행하는데 본 기사에서는 RSA 비밀키를 컨테이너 이미지에 저장하는 방법을
하지만, 여기 에 기재되어 있는 Interface 를 구현하는 방법 쪽이 시큐어이므로 추천입니다.

※추기
OCI SDK의 실행에 대해 자원 프린시펄을 사용하는 방법을 가르쳐 주셨습니다.
· [Oracle Cloud] 리소스 주체를 Oracle Functions에서 사용해 보았습니다.
이 방법으로 위의 보안 문제를 해결할 수 있기 때문에 꼭 참고하십시오.

전제



Oracle Functions 설정 끝난 것.
· 대상 인스턴스를 중지합니다.

소스 코드 준비



실물은 Git에 저장하고 있습니다.
인스턴스 시작 : htps : // 기주 b. 코 m / y- 아라키 - t / f 응 - 오시 코 m 뿌테 / t Ree / Ma s r / s rt
인스턴스 중지 : htps : // 기주 b. 코 m / y- 아라키 - t / f 응 - 오시 코 m 뿌테 / t Ree / Ma s r / s 및 p
 재기동에 대해서는 코드를 이렇게 편집하면 구현할 수 있다는 설명을,
마지막에 기재되어 있습니다.

Functions 개발 환경에서 위의 소스 코드를 다운로드합니다.



├Dockerfile (배포시 설정 설명)
├func.go (메인 처리를 기재)
├func.yaml (name : 함수 이름 포함)
└Gopkg.toml

Dockerfile에 자격 증명 정보



Dockerfile의 자격 증명 정보를 수정합니다. 처음에는 인스턴스 시작을 시도해 보겠습니다.
ENV TENANT_OCID=Fnセットアップ時のテナンシーOCID
ENV USER_OCID=Fnセットアップ時のユーザOCID
ENV REGION=Fnセットアップ時のリージョン
ENV FINGERPRINT=Fnセットアップ時のフィンガープリント
# Target INSTANCE OCIDE
ENV INSTANCE_OCID=対象インスタンスのOCID

Fn 애플리케이션 작성



인스턴스 제어용 fn-compute-app라는 응용 프로그램을 만듭니다.
fn create app --annotation oracle.com/oci/subnetIds='["OracleFunctions用に作成したSubnetのOCID"] fn-compute-app

함수 배포 (개인 키도 동시에 전달)



  준비한 소스 코드를 배포합니다. 인스턴스 시작 소스 코드의 디렉토리로 이동하여 실행합니다.
# Fnセットアップ時に作成した鍵をコピー
cp  ~/.oci/oci_api_key.pem .

# 権限変更(デプロイ後は削除してよい)
chmod 644 oci_api_key.pem

# デプロイ
fn -v deploy --app fn-compute-app --build-arg PRIVATE_KEY_NAME=oci_api_key.pem

실행



fn invoke 명령으로 함수를 실행하고 OCI 콘솔에서 중지된 대상 인스턴스가 시작되었는지 확인할 수 있다면 OK입니다.
fn invoke fn-compute-app start

정지의 경우도 마찬가지로 코드를 배치해, fn invoke fn-compute-app stop 로 실행할 수 있습니다.

코드 해설 (func.go)



이하 인스턴스 기동 쪽의 메인 처리를 기재하는, func.go입니다.
package main

import (
        // Goの各パッケージインポート
        "context"
        "encoding/json"
        "io"
        "io/ioutil"
        "log"
        "os"

        // fdk(GoでFnのコードを書くための開発キット)をインポート
        fdk "github.com/fnproject/fdk-go"

        // oci go sdkで今回使うcommonとcoreパッケージをインポート
        "github.com/oracle/oci-go-sdk/common"
        "github.com/oracle/oci-go-sdk/core"
)

// main関数の実行。Goはmain関数でリターンされた処理が実行される。
// 下記のociComputeEventHandler(インスタンス起動関数)を呼び出している。
func main() {
        fdk.Handle(fdk.HandlerFunc(ociComputeEventHandler))
}

// dockerイメージデプロイ時の鍵格納パス
const privateKeyFolder string = "/function"

//ファンクション成功時メッセージ
const successMsg string = "Started Compute Instance information successfully"

//インスタンス起動処理の内容
func ociComputeEventHandler(ctx context.Context, in io.Reader, out io.Writer) {

        // クレデンシャルを変数に格納
        tenancy := os.Getenv("TENANT_OCID")
        user := os.Getenv("USER_OCID")
        region := os.Getenv("REGION")
        fingerprint := os.Getenv("FINGERPRINT")
        passphrase := os.Getenv("PASSPHRASE")
        instance := os.Getenv("INSTANCE_OCID")
        log.Println("INSTANCE_OCID ", instance)

        // クレデンシャル情報をログに出力
        log.Println("TENANT_OCID ", tenancy)
        log.Println("USER_OCID ", user)
        log.Println("REGION ", region)
        log.Println("FINGERPRINT ", fingerprint)
        log.Println("OCI_PRIVATE_KEY_FILE_NAME ", privateKeyName)
        log.Println("PRIVATE_KEY_LOCATION ", privateKeyLocation)
        log.Println("INSTANCE_OCID ", instance)

        // 秘密鍵を読み込み、変数格納
        privateKey, err := ioutil.ReadFile(privateKeyLocation)

        // 秘密鍵の読み込み失敗時
        if err == nil {
                log.Println("read private key from ", privateKeyLocation)
        } else {
                resp := FailedResponse{Message: "Unable to read private Key", Error: err.Error()}
                log.Println(resp.toString())
                json.NewEncoder(out).Encode(resp)
                return
        }

        // クレデンシャル情報設定 (OCI SDKのcommonパッケージにある関数を使って最初設定する。)
        rawConfigProvider := common.NewRawConfigurationProvider(tenancy, user, region, fingerprint, string(privateKey), common.String(passphrase))
        // クレデンシャル情報設定 (この後coreパッケージの関数を使うので、coreの関数で再度設定する。)
        cc, err := core.NewComputeClientWithConfigurationProvider(rawConfigProvider)

        // クレデンシャル設定エラー時の処理
        if err != nil {
                resp := FailedResponse{Message: "Problem getting Compute Client handle", Error: err.Error()}
                log.Println(resp.toString())
                json.NewEncoder(out).Encode(resp)
                return
        }

        //// インスタンス起動処理
        // 一番右のstartを変更すればその他インスタンス操作も可能
        // start:起動、stop:停止、reset:再起動、softstop:OSのシャットダウンコマンドを使い停止、softreset:OSのシャットダウンコマンドで再起動
        _, updateErr := cc.InstanceAction(context.Background(), core.InstanceActionRequest{InstanceId: common.String(instance), Action: core.InstanceActionActionEnum("start") })

        // エラー処理
        if updateErr != nil {
                resp := FailedResponse{Message: "Problem starting instance", Error: updateErr.Error()}
                log.Println(resp.toString())
                json.NewEncoder(out).Encode(resp)
                return
        }

        // 成功時ログ出力
        log.Println(successMsg)

        out.Write([]byte(successMsg))
}

// エラーハンドリング用の構造体
type FailedResponse struct {
        Message string
        Error   string
}

// エラーメッセージ関数
func (response FailedResponse) toString() string {
        return response.Message + " due to " + response.Error
}

OCI Go SDK 사용법



자격 증명을 설정하면 OCI SDK를 사용할 수 있습니다. 그런 다음 공식 문서을 참조하여 OCI Go SDK의 함수를 사용합니다.

코드의 인스턴스 시작 부분을 자세히 살펴보십시오.
_, updateErr := cc.InstanceAction(context.Background(), core.InstanceActionRequest{InstanceId: common.String(instance), Action: core.InstanceActionActionEnum("start") })

우선 이번 OCI Go SDK의 핵심 패키지 에 들어 있는 함수, InstanceAction 를 사용했습니다↓


InstanceAction에서 호출하는 InstanceActionRequest라는 구조체의 사양을 보면,
InstanceId와 Action이라는 항목이 필수(mandatory)라고 알 수 있습니다↓


Action 항목은 또한 InstanceActionActionEnum이라는 구조체를 사용하도록 지정되어 있으며, Start나 Stop 등 정의되어 있습니다↓

그 때문에 소스 코드내의 InstanceActionActionEnum("start") 를 InstanceActionActionEnum("reset") 등 변경하면 재기동도 마찬가지로 작성할 수 있습니다.
func.yaml의 name : start도 name : reset이면 함수 이름도 바뀝니다.

마지막으로



이 소스 코드에서는 대상 인스턴스의 OCID를 지정해야 하지만 편집하면 여러 대 단번에 처리할 수도 있습니다.
24/365에서 시작할 필요가 없는 인스턴스에 적용하거나 이벤트 기능이나 다른 함수와 연동해도 좋을지도 모릅니다.

좋은 웹페이지 즐겨찾기