AWS Service Operator
- AWS Service Operatorとは、AWSのリソースを管理するOperator
- CRD(CustomResourceDefinition)としてKuberenetesクラスタにデプロイする
- AWSのリソース(S3のBucketやDynamoDB等)を使用するサービスをKubernetesにデプロイする場合、Kubernetesのサービスはマニフェストファイルで記述できるが、AWSのリソースは別途CFn(CloudFormation)やTerraformで作成する必要がある。AWS Service Operatorを使用することで、AWSのリソースも含めてKubernetesのマニフェストファイルで管理することができる。
Operatorとは
- Operatorとは、Kubernetesそのものが持つ機能を拡張し、人手などを介して実施していた作業をKubernetes上で管理することで自動化する仕組み
- もともとはCoreOS,IncがKubernetesの監視ツールであるPrometheusやetcdの運用管理を自動化するために作られた
- Operatorの仕組みを支えているのがControl Loop
- Control Loopはクラスタの状態を監視し、あるべき状態との差分がある場合にはそれを調整するKubernetes上の仕組み
- Control LoopはKubernetesが持つリソースとコントローラによって実現されている
- 例えばDeploymentやReplicasetなどの既存リソースに対しては、DeploymentコントローラやReplicasetコントローラが稼働しており、これらのコントローラがAPIを経由して状態の監視、及びリソースの作成・削除等の指示を行なっている
- Cotrol Loopの仕組みを利用するため、Operatorで扱うリソースを対象とした「カスタムリソース」と「カスタムコントローラ」を作成する必要がある
Custom Resource(カスタムリソース)
- PodやDeploymentなどのリソースは、コアリソースと呼ばれ、Kubernetes上で管理されている
- ユーザーが独自で追加できるリソースがカスタムリソース
- 既存のKubernetes APIを拡張してできる独自のデータ構造
- APIを拡張する方法の1つが、CRDによるもの
Custom Controller
- カスタムコントローラは、カスタムリソースの状態を確認しながら、それによって管理されるオブジェクトを調整するコントローラ
- 開発自体はclient-goやkubebuilder、OpenSDKを利用して行われ、Deploymentとして展開される
AWS Service Operatorのデプロイ
- AWS Service Operatorで対応しているサービスは以下の通り
- DynamoDBのデーブル
- S3のバケット
- ECRのレポジトリ
- SNSのトピックとサブスクリプション
- SQSのキュー
環境
- Kubernetesクラスタ
- EKS
- Kubernetesバージョン
- v1.12.7
IAM Role作成
- AWSのリソースにアクセスできるようにIAM Roleを作成
- 一旦AdministratorAccessのPolicyをアタッチする
マニフェストファイル
- 提供されているマニフェストファイルをダウンロードする
$ wget https://raw.githubusercontent.com/awslabs/aws-service-operator/master/configs/aws-service-operator.yaml
- マニフェストファイルを見ると、一番下にDeploymentの記載があり、これがカスタムコントローラに対応
aws-service-operator.yaml(抜粋)
kind: Deployment
apiVersion: apps/v1beta1
metadata:
name: aws-service-operator
namespace: aws-service-operator
spec:
replicas: 1
template:
metadata:
annotations:
iam.amazonaws.com/role: arn:aws:iam::XXXXXXXXXXX:role/AWS-Operator
labels:
app: aws-service-operator
spec:
serviceAccountName: aws-service-operator
containers:
- name: aws-service-operator
image: awsserviceoperator/aws-service-operator:v0.0.1-alpha4
imagePullPolicy: Always
args:
- server
- --cluster-name=operator-test
- --region=ap-northeast-1
- --account-id=XXXXXXXXXXX
- spec.template.spec.containers.argsの内容を自分の環境の値に設定
- 今回使用するクラスタではkube2iamがセットアップされているので、spec.metadata.annotationsに先ほど作成したIAM Roleのarnを指定している。これにより、Deploymentから作成されるPodにそのIAM Roleを付与することができる。kube2iamがセットアップされていない場合は、IAM Roleをノードグループへアタッチする必要がある。
デプロイ
$ kubectl apply -f aws-service-operator.yaml
- CRDが作成されていることが確認できる
$ kubectl get customresourcedefinitions
NAME CREATED AT
alertmanagers.monitoring.coreos.com 2019-08-06T10:48:53Z
cloudformationtemplates.service-operator.aws 2019-08-06T11:27:25Z
dynamodbs.service-operator.aws 2019-08-06T11:27:25Z
ecrrepositories.service-operator.aws 2019-08-06T11:27:25Z
elasticaches.service-operator.aws 2019-08-06T11:27:25Z
prometheuses.monitoring.coreos.com 2019-08-06T10:48:54Z
prometheusrules.monitoring.coreos.com 2019-08-06T10:48:54Z
s3buckets.service-operator.aws 2019-08-06T11:27:25Z
servicemonitors.monitoring.coreos.com 2019-08-06T10:48:54Z
snssubscriptions.service-operator.aws 2019-08-06T11:27:25Z
snstopics.service-operator.aws 2019-08-06T11:27:25Z
sqsqueues.service-operator.aws 2019-08-06T11:27:26Z
- これにより、定義したリソースをkubectlコマンドで扱えるようになった
- まだリソースは作成していないが、例えばs3bucketsの情報を取得する場合は以下の通り
$ kubectl get s3buckets
No resources found.
- コントローラは以下のように確認
$ kubectl get pod -n aws-service-operator
NAME READY STATUS RESTARTS AGE
aws-service-operator-5b65c8545-pvmv2 1/1 Running 0 35h
サンプルアプリケーションのデプロイ
マニフェストファイル
- サンプルアプリケーションのマニフェストファイルを取得する
$ wget https://gist.githubusercontent.com/christopherhein/1cb7da812a197ac3cc547ed2495faf9d/raw/4909e8ad6b35843e1696735e9f62301e9bde7ff9/dynamodb-app.yaml
このマニフェストファイルでは、DynamoDB、Service、Deploymentが作成され、PodからDynamoDBのテーブルを参照する作りになっている
DynamoDBの記述は以下の通り
dynamodb-app.yaml(抜粋)
apiVersion: service-operator.aws/v1alpha1
kind: DynamoDB
metadata:
name: dynamo-table
spec:
hashAttribute:
name: name
type: S
rangeAttribute:
name: created_at
type: S
readCapacityUnits: 5
writeCapacityUnits: 5
- PodからDynamoDBを参照するため、aws-service-operator.yamlと同様にDeploymentのspec.metadata.annotationsにIAM Roleのarnを指定する必要がある
デプロイ
$ kubectl apply -f dynamodb-app.yaml
dynamodb.service-operator.aws/dynamo-table created
service/frontend created
deployment.apps/frontend created
- 以下のようにDynamoDBのリソースを確認できる
$ kubectl get dynamodb
NAME AGE
dynamo-table 10m
アプリが起動しない問題
- DynamoDBなどの作成は問題なくできたもののデプロイしたPodが正常に起動していない
$ kubectl get pod
frontend-9f44cbb5b-4777b 0/1 CreateContainerConfigError 0 44m
- describeコマンドを打つとconfigmapsが見つからないというエラーが出ている
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 58m default-scheduler Successfully assigned default/frontend-9f44cbb5b-4777b to ip-192-168-106-94.ap-northeast-1.compute.internal
Normal Pulled 56m (x8 over 58m) kubelet, ip-192-168-106-94.ap-northeast-1.compute.internal Successfully pulled image "christopherhein/dynamoapp:latest"
Warning Failed 56m (x8 over 58m) kubelet, ip-192-168-106-94.ap-northeast-1.compute.internal Error: configmaps "dynamo-table" not found
Normal Pulling 3m13s (x222 over 58m) kubelet, ip-192-168-106-94.ap-northeast-1.compute.internal pulling image "christopherhein/dynamoapp:latest"
- ConfigMapからDynamoDBのテーブル名を参照しているため、その参照ができずにエラーが出ている模様
- Issueにあげました
まとめ
- カスタムリソースの例として、AWSのリソースを扱えるものをデプロイした
- これにより、DynamoDBなどのAWSリソースをKubernetesのリソースとして扱うことができるようになった
- Operatorの自作もやってみたい