LoginSignup
2
2

More than 5 years have passed since last update.

Oracle Functions (Fn) で、Custom DockerImageを使ってFunction実行

Last updated at Posted at 2019-02-18

はじめに

Oracle Function で、独自に作成したDockerImage を使用して Function を実行する方法を書きます。
シンプルな関数を実行する場合であればカスタムする必要はありませんが、複雑なDockerImageを使用しなければならない場合には、とても有効な手段です。

Oracle Functions 自体ののチュートリアルはこちらを参照してください
https://qiita.com/sugimount/items/018e08f575ecefb1546c

独自に作成するDockerImageの概要

今回は、以下の内容のDockerImageを作成します。Dockerコンテナ内に事前に必要なファイルを格納しておきたいニーズに出会ったことがあり、これを想定しています。

  • DockerImageに、テスト用のファイルを格納して build する
  • DockerImage内で Go言語を動かして、テスト用のファイルの中身を出力し、JSONとしてResponseする

この内容を確認することで、DockerImageを独自に作成して Oracle Functions で実行する流れが掴めると思います。

Function の初期テンプレートを生成

適当な作業ディレクトリへ移動します。自分の場合はGo言語で作成するため、GOPATH が通っているディレクトリを選んでいます。

mkdir /home/ubuntu/go-third-party/src/fn_work
cd /home/ubuntu/go-third-party/src/fn_work

fn init コマンドで、go言語の初期テンプレートを生成します。

fn init --runtime go custom_runtime

自動生成されたディレクトリへ移動します

cd custom_runtime

独自のDockerImage作成

まずは、テスト用のファイルを生成します。

echo 'Hello! I am file!' >> iamfile.txt

Go言語のソースコードを作ります。今回は以下のソースコードを作ります。
環境変数 FUNC_OPEN_FILEPATH で与えたファイルを読み込み、JSONとしてResponseする内容です。

package main

import (
        "context"
        "encoding/json"
        "fmt"
        "io"
        "os"

        fdk "github.com/fnproject/fdk-go"
)

// BUFSIZE 読み込みバッファーサイズ
const BUFSIZE = 1024

func main() {
        fdk.Handle(fdk.HandlerFunc(printFile))
}

func printFile(ctx context.Context, in io.Reader, out io.Writer) {
        // file read
        file, err := os.Open(os.Getenv("FUNC_OPEN_FILEPATH"))
        if err != nil {
                fmt.Println("error!")
                return
        }

        defer file.Close()

        buf := make([]byte, BUFSIZE)
        context := ""
        for {
                n, err := file.Read(buf)
                if n == 0 {
                        break
                }
                if err != nil {
                        // Readエラー処理
                        break
                }

                context = string(buf[:n])
        }

        // make struct
        msg := struct {
                Message string `json:"message"`
        }{}

        msg.Message = context

        json.NewEncoder(out).Encode(&msg)
}

fn で使用する、定義ファイルを編集します。runtimeを go から、独自のDockerImageを使用することを意味する dockerへ変更します。

> vim func.yaml
schema_version: 20180708
name: custom_runtime
version: 0.0.1
runtime: docker <======== go から dockerに書き換え
entrypoint: ./func
format: http-stream

Dockerfileを作ります。マルチステージビルドを使っています。マルチステージビルド自体は、こちらを読むとわかりやすいと思います。
今回確認したいポイントは以下の通りです

  • 作成したテストファイル iamfile.txt を、/function/iamfile.txt に格納している
vim Dockerfile
FROM golang:1.11.5 as builder
WORKDIR /go/src/funcdir
COPY Gopkg.toml .
COPY func.go .
RUN go get -u github.com/golang/dep/cmd/dep && \
    dep ensure
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o func .

FROM alpine:3.9
WORKDIR /function/
COPY --from=builder /go/src/funcdir/func .
COPY iamfile.txt /function/iamfile.txt
ENTRYPOINT ["/function/func"]

以下のファイル構成になっているとよいです

> tree /home/ubuntu/go-third-party/src/fn_work/custom_runtime
/home/ubuntu/go-third-party/src/fn_work/custom_runtime
├── Dockerfile
├── Gopkg.toml
├── func.go
├── func.yaml
└── iamfile.txt

正常にDockerImageをBuild出来るか確認を行います (docker build で直接やってもよいです)

fn -v build

実行例

> fn -v build
Building image phx.ocir.io/sugimount2/oracle-function/custom_runtime:0.0.1
FN_REGISTRY:  phx.ocir.io/sugimount2/oracle-function
Current Context:  sugi-context
Sending build context to Docker daemon  41.47kB
Step 1/10 : FROM golang:1.11.5 as builder
 ---> 901414995ecd
Step 2/10 : WORKDIR /go/src/funcdir
 ---> Using cache
 ---> 279adebb201e
Step 3/10 : COPY Gopkg.toml .
 ---> Using cache
 ---> a0ed62dd646f
Step 4/10 : COPY func.go .
 ---> Using cache
 ---> 70919180fbb6
Step 5/10 : RUN go get -u github.com/golang/dep/cmd/dep &&     dep ensure
 ---> Using cache
 ---> 6d10b5c6b642
Step 6/10 : RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o func .
 ---> Using cache
 ---> a05adf4cd5e2
Step 7/10 : FROM alpine:3.9
 ---> caf27325b298
Step 8/10 : WORKDIR /function/
 ---> Using cache
 ---> b75514413267
Step 9/10 : COPY --from=builder /go/src/funcdir/func .
 ---> Using cache
 ---> d13fa27ed5ba
Step 10/10 : ENTRYPOINT ["/function/func"]
 ---> Using cache
 ---> 10382affeec1
Successfully built 10382affeec1
Successfully tagged phx.ocir.io/sugimount2/oracle-function/custom_runtime:0.0.1

Function phx.ocir.io/sugimount2/oracle-function/custom_runtime:0.0.1 built successfully.

正常に build できたら、fn deploy を実行して、Oracle Functions に Deploy します。

fn --verbose deploy --app env-app

環境変数を設定します。FUNC_OPEN_FILEPATH に、DockerFIleで格納したテスト用ファイルの格納先を示しています

fn config func env-app custom_runtime FUNC_OPEN_FILEPATH /function/iamfile.txt

確認

> fn ls config func env-app custom_runtime
KEY                     VALUE
FUNC_OPEN_FILEPATH      /function/iamfile.txt

Functionを実行します

fn --verbose invoke env-app custom_runtime

以下のように、テスト用のファイルの中身をReadして、JSONとしてResponseしているのが確認できました。

> fn --verbose invoke env-app custom_runtime
{"message":"Hello! I am file!\n"}

参考URL

Creating a Function from a Docker Image
http://fnproject.io/tutorials/ContainerAsFunction/

Packaging your Function
https://github.com/fnproject/docs/blob/master/fn/develop/packaging.md

Fn Tutorial
http://fnproject.io/tutorials/

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2