6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

前書き

掲題の通り、StepFunctionからEKSjobを呼び出すシステムを構築する際に詰まったポイントを備忘録として記しておきたいと思います。

StepFunctionとは

公式より

AWS Step Functions は、デベロッパーが AWS のサービスを利用して分散型アプリケーションを構築し、プロセスを自動化し、マイクロサービスのオーケストレーション、データと機械学習のパイプラインを構築できるようにするビジュアルワークフローサービスです。

個人的にStepFunctionというのは、Lambdaをトリガーとして異なるサービスを呼び出すようなつながりがたくさんある複雑なシステムを、簡潔にまとめ上げられるシステムなのかなーと思っています。
StepFunctionで作り上げた一連のシステムは、ステートマシンという単位で表されます。EC2で言うインスタンスみたいなものですね。

やりたいこと

まずはEKSとの疎通を確認したいと思い、StepFunctionからEKSjobを呼び出して終了するだけの単純なステートマシンを作りたい!と思って構築を始めました。
image.png

マネコンからはJSON形式でしか扱えないみたいです...
YAML対応待ってます!

こちらがソースコードです。長いので折りたたんでいます。
{
  "Comment": "A description of my state machine",
  "StartAt": "EKS RunJob",
  "States": {
    "EKS RunJob": {
      "Type": "Task",
      "Resource": "arn:aws:states:::eks:runJob",
      "Parameters": {
        "ClusterName": "eks-cluster-name",
        "CertificateAuthority": "xxxxxxxxxx",
        "Endpoint": "https://xxxxxxxxxx.eks.amazonaws.com",
        "Job": {
          "apiVersion": "batch/v1",
          "kind": "Job",
          "metadata": {
            "name": "my-example-job"
          },
          "spec": {
            "template": {
              "metadata": {
                "name": "my-example-job"
              },
              "spec": {
                "containers": [
                  {
                    "name": "my-function-name",
                    "image": "perl",
                    "command": [
                      "perl"
                    ],
                    "args": [
                      "-Mbignum=bpi",
                      "-wle",
                      "print bpi(2000)"
                    ]
                  }
                ],
                "restartPolicy": "Never"
              }
            }
          }
        }
      },
      "Next": "EKS Delete"
    },
    "EKS Delete": {
      "Type": "Task",
      "Resource": "arn:aws:states:::eks:call",
      "Parameters": {
        "ClusterName": "eks-cluster-name",
        "CertificateAuthority": "xxxxxxxxxx",
        "Endpoint": "https://xxxxxxxxxx.eks.amazonaws.com",
        "Method": "DELETE",
        "Path": "/apis/batch/v1/namespaces/default/jobs/my-example-job",
        "RequestBody": {
          "apiVersion": "v1",
          "kind": "Namespace",
          "metadata": {
            "name": "my-namespace",
            "labels": {
              "name": "my-namespace"
            }
          }
        }
      },
      "End": true
    }
  }
}

構築開始

EKSと疎通できるようにするために、RBACを用いてステートマシンに割り当てられたロールからEKSにアクセスできるようにします。eksctlコマンドを用いてロールを割り当てます。
StepFunctionはマネージドサービスなので、セキュリティグループなどの穴あけは不要です。

ロールのarnをコピーペーストすると以下のようになります。

eksctl create iamidentitymapping 
--cluster dev-cluster 
--arn  arn:aws:iam::xxxxxxxxxx:role/service-role/StepFunctions-EKS-RunJob-StateMachine-role-4b53263d 
--group system:masters --username my-statemachine

ロールには適切なポリシーをアタッチしたし、RBACも完璧!と思って実行したら以下のようなエラーが出ました。


{
  "resourceType": "eks",
  "resource": "runJob",
  "error": "EKS.ConnectTimeoutException",
  "cause": "An error occurred when attempting to call the Kubernetes API server."
}

筆者はまずここで詰まっていました。
ネットを調べてみると、全く同じ状況に陥っている様子の記事がありました。

こちらによると、arnの箇所に/service-roleを書いてはいけないそうです。
ということで、正しくは以下のようになります。

eksctl create iamidentitymapping 
--cluster dev-cluster 
--arn  arn:aws:iam::xxxxxxxxxx:role/StepFunctions-EKS-RunJob-StateMachine-role-4b53263d 
--group system:masters --username my-statemachine

ですが、それでもエラーが変わらない。
もう一度エラーをよく見てみます。


{
  "resourceType": "eks",
  "resource": "runJob",
  "error": "EKS.ConnectTimeoutException",
  "cause": "An error occurred when attempting to call the Kubernetes API server."
}

先ほど引用したサイトでは、ロールによる認可が行われていないことによるエラーは以下のようになるとのことでした。

エラー
EKS.401
原因
{
  "ResponseBody": {
    "kind": "Status",
    "apiVersion": "v1",
    "metadata": {},
    "status": "Failure",
    "message": "Unauthorized",
    "reason": "Unauthorized",
    "code": 401
  },
  "StatusCode": 401,
  "StatusText": "Unauthorized"
}

どうやら認可云々の話よりもっと手前の、アクセス自体が拒否されているようなエラーに見えます。

公式サイトを見てみると、こんな注意書きがありました。

注記
Step Functions EKS 統合は、公開エンドポイントにアクセスできる Kubernetes API だけをサポートします。デフォルトでは、EKS クラスターの API サーバーエンドポイントにはパブリックアクセス権があります。詳細については、Amazon EKS ユーザーガイドの「Amazon EKS クラスターエンドポイントアクセスコントロール 」を参照してください。

どうやら、インターネットに公開されていないAPIサーバーエンドポイントに対してステートマシンはアクセスすることができないようです。

パブリックに公開しないと叩けない?世のEKSはパブリックに公開されているのか?と疑問に思い、Kubernetesマスターの先輩に疑問をぶつけてみました。
先輩からの回答によると、結局RBACを行うのでパブリックに公開することが多いよ~とのことでした。

EKSのマネコンを確認すると、APIサーバーエンドポイントがプライベートだったのでコンソール上からパブリックおよびプライベートに変更しました。
image.png

2度のエラーを乗り越え、ついに成功することができました!!!緑色って素晴らしいですね。
image.png

感想

StepFunctionでECSタスクを呼び出している記事はちらほら見かけたのですが、EKSjobを呼び出している記事はほとんどありませんでした。EKSよりもECSのほうがよく使われているんですかね? 

初めて他を探しても見つからない独自性の高い記事だと自負できる記事が書けた気がしてとても嬉しいです。

6
3
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
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?