AWS Controllers for Kubernetes(ACK) ことはじめ vol.2 ~ 実践編 ~
※ 本記事は、2022/1/10 現在で著者が検証として諸々触ってみた内容をまとめたものです。ACK は現在デベロッパープレビューな OSS です。後述しますが未実装な機能や改善の余地があり、その実装も今後変更される可能性がに大いにございます。
長くなってしまったので、3 編に分けております。この記事は Vol.2 です。ACK をご存知でない方やこれから試してみたい方はまず環境を整える必要があるので、vol.1 からご覧になることを推奨します。
- vol.1 ~ 導入編 ~
- vol.2 ~ 実践編 ~
- vol.3 ~ 気になることを確認してみた編 ~
目次
ACK で S3 バケットを触ってみる
さて前回の記事で準備が整ったので、色々試していきます。まずは S3 で試します。
以下のようなシンプルなマニフェストを書きました。S3 のマニフェスト Yaml のパラメータは API リファレンスを参照ください。また、各サービスコントローラーの Github にもサンプルとなる Yaml があります。S3 だとこちら。
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
name: ack-s3-bucket-hama
spec:
name: ack-s3-bucket-hama
さて、早速できた マニフェストでデプロイしてみましょう!
$ kubectl apply -f s3-bucket.yaml
--output--
bucket.s3.services.k8s.aws/ack-s3-bucket-hama created
デプロイできました。早速リソースができているか確認すると、Kubernetes 上にリソースができており、また S3 バケット実体もできています。
$ kubectl get bucket
--output--
NAME AGE
ack-s3-bucket-hama 43s
$ aws s3api list-buckets | jq '.Buckets[] | select(.Name | test("^ack-s3-bucket-hama"))'
--output--
{
"Name": "ack-s3-bucket-hama",
"CreationDate": "2022-01-09T07:37:28+00:00"
}
今度はこのマニフェストを編集します。バージョニングを有効化しました。
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
name: ack-s3-bucket-hama
spec:
name: ack-s3-bucket-hama
versioning:
status: Enabled
このマニフェストを再度 Apply します。
$ kubectl apply -f s3-bucket.yaml
--output--
bucket.s3.services.k8s.aws/ack-s3-bucket-hama configured
configured
で更新されました。そして、先ほど作成したバケットでバージョニングが有効化されていることが確認できました。
$ aws s3api list-buckets | jq '.Buckets[] | select(.Name | test("^ack-s3-bucket-hama"))'
--output--
{
"Name": "ack-s3-bucket-hama",
"CreationDate": "2022-01-09T07:37:28+00:00"
}
$ aws s3api get-bucket-versioning --bucket ack-s3-bucket-hama
--output--
{
"Status": "Enabled"
}
最後に Kubernetes 上でリソースを削除してみます。
$ kubectl delete -f s3-bucket.yaml
--output--
bucket.s3.services.k8s.aws "ack-s3-bucket-hama" deleted
deleted
になり、kubernetes 上からも AWS 上のバケットの実体としても削除されたことが確認できました。
$ kubectl get bucket
--output--
No resources found in default namespace.
$ aws s3api list-buckets | jq '.Buckets[] | select(.Name | test("^ack-s3-bucket-hama"))'
--output--
no response
一通り操作しましたが、実際裏でどんなことが起きているのか?また触っているとうまくいかないこともあるでしょう。デバッグとしてサービスコントローラーの log を見てみます。
create/update/delete の各イベントや、update の際に宣言したリソースの状態が変わった時の差分がログとして表示されており、カスタムコントローラーでどんなことをしているか非常にわかりやすいです。
$ kubectl logs ack-s3-controller-s3-chart-86986fb68f-j8lpp -n $ACK_K8S_NAMESPACE
---
...
1.6419669211030383e+09 INFO ackrt created new resource {"account": "xxxxxxxxxxxx", "role": "", "region": "us-west-2", "kind": "Bucket", "namespace": "default", "name": "ack-s3-bucket-hama", "is_adopted": false, "generation": 1}
1.641973046783967e+09 INFO ackrt desired resource state has changed {"account": "xxxxxxxxxxxx", "role": "", "region": "us-west-2", "kind": "Bucket", "namespace": "default", "name": "ack-s3-bucket-hama", "is_adopted": false, "generation": 2, "diff": [{"Path":{"Parts":["Spec","ACL"]},"A":null,"B":"private|bucket-owner-read|bucket-owner-full-control"},{"Path":{"Parts":["Spec","Versioning","Status"]},"A":"Enabled","B":null},{"Path":{"Parts":["Spec","Website","ErrorDocument"]},"A":{"key":"error.html"},"B":null},{"Path":{"Parts":["Spec","Website","IndexDocument"]},"A":{"suffix":"index.html"},"B":null}]}
1.641973047537799e+09 INFO ackrt updated resource {"account": "xxxxxxxxxxxx", "role": "", "region": "us-west-2", "kind": "Bucket", "namespace": "default", "name": "ack-s3-bucket-hama", "is_adopted": false, "generation": 2}
1.6419966414173994e+09 INFO ackrt deleted resource {"account": "xxxxxxxxxxxx", "role": "", "region": "us-west-2", "kind": "Bucket", "namespace": "default", "name": "ack-s3-bucket-hama", "generation": 3}
また、Kubernetes を通して作った S3 バケットを AWS から直接編集・削除をしてみましたが、変更した設定はそのままでマニフェストの宣言状態に収束されず、削除したバケットも再作成されませんでした。ログ上も無反応だったので、ACK のコントローラーからリソース作成・変更・削除操作時以外の状態監視は現状されていないようでした。
訂正。こちらの Issue に記載の通り、実装としてはあるけど頻繁なチェックはリソースへの負担も大きく現状は8h間隔でのチェックみたいです。
後述しますが、Crossplane の方はこの辺対応しており、個人的には Kubernetes っぽく宣言状態を保つような動きをしてほしいなと思っていますので、ACK でも今後に期待です。 の方がチェック感覚が短いというところで、どっちがいいのかは微妙なところですね。
ACK で EKS クラスターを触ってみる
さて、今度は EKS クラスターを EKS で管理します。Kubernetes のクラスター自体も Kubernetes で管理したい瞬間ないですか?
2021/09/29 に AWS Dev Day で ACK の話をした時はまだ EKS Controller は IN PROGRESS
だったんですが、11月に晴れて Preview としてリリースされましたので、早速触ってみました。
インストールまではACK 導入手順 の通りなのですが、(2021/01/10 現在) 一部動かないところがあり、補足を入れます。
EKS では FullAccess Policy がないため、インラインポリシーかセルフ管理のポリシーを書くことになるのですが、recommended-inline-policy
には以下のように書いてあります。そして、このままだと主に IAM 周りの権限が足りません。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"eks:*"
],
"Resource": "*"
}
]
}
特に EKS というサービスが Kubernetes のクラスターや関連リソースを操作するために、「EKS サービスに IAM ロールを渡す」アクセス権限をサービスコントローラーが持っている必要があります。つまり iam:PassRole
が必要です。取り急ぎ、以下のようなポリシーにすることで動作しました。ちょっとした検証しかできていないので、実際はもっと権限が必要な気はします。ちゃんと Issue 書いて、pull request しますかね。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:ListAttachedRolePolicies",
"ec2:DescribeSubnets",
"eks:*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PassedToService": "eks.amazonaws.com"
}
}
}
]
}
これで準備ができたので、早速 EKS クラスターを作ります。クラスター・ノードグループ・アドオン(vpc-cni, coredns, kube-proxy) のマニフェスト Yaml を書きました。EKS のマニフェスト Yaml のパラメータは API リファレンスを参照ください。サンプル Yaml はこちらです。
apiVersion: eks.services.k8s.aws/v1alpha1
kind: Cluster
metadata:
name: ack-hama-cluster
spec:
name: ack-hama-cluster
version: "1.21"
roleARN: "$CLUSTER_ROLE"
resourcesVPCConfig:
endpointPublicAccess: true
subnetIDs:
- "$SUBNET_1"
- "$SUBNET_2"
- "$SUBNET_3"
logging:
clusterLogging:
- enabled: true
types:
- api
- audit
- authenticator
- scheduler
---
apiVersion: eks.services.k8s.aws/v1alpha1
kind: Nodegroup
metadata:
name: ack-hama-ng
spec:
name: ack-hama-ng
clusterName: ack-hama-cluster
instanceTypes:
- "m5.large"
subnets:
- "$SUBNET_1"
- "$SUBNET_2"
- "$SUBNET_3"
nodeRole: "$NODEGROUP_ROLE"
scalingConfig:
minSize: 3
maxSize: 3
desiredSize: 3
---
apiVersion: eks.services.k8s.aws/v1alpha1
kind: Addon
metadata:
name: ack-hama-vpc-cni
spec:
name: vpc-cni
addonVersion: v1.10.1-eksbuild.1
clusterName: ack-hama-cluster
---
apiVersion: eks.services.k8s.aws/v1alpha1
kind: Addon
metadata:
name: ack-hama-coredns
spec:
name: coredns
addonVersion: v1.8.4-eksbuild.1
clusterName: ack-hama-cluster
---
apiVersion: eks.services.k8s.aws/v1alpha1
kind: Addon
metadata:
name: ack-hama-kube-proxy
spec:
name: kube-proxy
addonVersion: v1.21.2-eksbuild.2
clusterName: ack-hama-cluster
早速できたマニフェストでデプロイしてみます。
$ kubectl apply -f eks.yaml
--output--
cluster.eks.services.k8s.aws/ack-hama-cluster created
nodegroup.eks.services.k8s.aws/ack-hama-ng created
addon.eks.services.k8s.aws/ack-hama-vpc-cni created
addon.eks.services.k8s.aws/ack-hama-coredns created
addon.eks.services.k8s.aws/ack-hama-kube-proxy created
はい、できました。
$ aws eks describe-cluster --name ack-hama-cluster
--output--
{
"cluster": {
"name": "ack-hama-cluster",
"arn": "arn:aws:eks:us-west-2:xxxxxxxxxxxx:cluster/ack-hama-cluster",
"createdAt": "2022-01-09T16:13:32.036000+00:00",
"version": "1.21",
~ snip ~
$ aws eks list-nodegroups --cluster-name ack-hama-cluster
--output--
{
"nodegroups": [
"ack-hama-ng"
]
}
$ aws eks list-addons --cluster-name ack-hama-cluster
--output--
{
"addons": [
"coredns",
"kube-proxy",
"vpc-cni"
]
}
この後、S3 の時と同様にマニフェストを編集して Apply してみましたがうまく反映されず、「あれ?」と思って log を見てみると、“not implemented” error が出ていました (2022/01/10 確認)。おそらく現状は未実装で明示的に 501 エラーを返すようになっているのかと思います。そのうち解消されるでしょう。プレビューですし仕方ない。
ちなみに削除は問題なく動作しました。
$ kubectl logs ack-eks-controller-eks-chart-cb5bcd9bd-md697 -n $ACK_K8S_NAMESPACE
---
2022-01-10T14:23:26.476Z INFO ackrt desired resource state has changed {"account": "xxxxxxxxxxxx", "role": "", "region": "us-west-2", "kind": "Cluster", "namespace": "default", "name": "ack-hama-cluster", "is_adopted": false, "generation": 5, "diff": [{"Path":{"Parts":["Spec","Logging","ClusterLogging"]},"A":[{"enabled":true,"types":["api","audit","authenticator","scheduler"]}],"B":[{"enabled":true,"types":["api","audit","authenticator"]},{"enabled":false,"types":["controllerManager","scheduler"]}]},{"Path":{"Parts":["Spec","ResourcesVPCConfig","EndpointPrivateAccess"]},"A":true,"B":false},{"Path":{"Parts":["Spec","Tags"]},"A":null,"B":{}}]}
2022-01-05T14:23:26.487Z ERROR controller-runtime.controller Reconciler error {"controller": "cluster", "request": "default/ack-hama-cluster", "error": "not implemented"}
2022-01-10T14:26:55.878Z INFO ackrt desired resource state has changed {"account": "xxxxxxxxxxxx", "role": "", "region": "us-west-2", "kind": "Nodegroup", "namespace": "default", "name": "ack-hama-ng", "is_adopted": false, "generation": 3, "diff": [{"Path":{"Parts":["Spec","InstanceTypes"]},"A":["m5.xlarge"],"B":["m5.large"]},{"Path":{"Parts":["Spec","Labels"]},"A":null,"B":{}},{"Path":{"Parts":["Spec","ScalingConfig","DesiredSize"]},"A":2,"B":3},{"Path":{"Parts":["Spec","ScalingConfig","MaxSize"]},"A":2,"B":3},{"Path":{"Parts":["Spec","ScalingConfig","MinSize"]},"A":2,"B":3},{"Path":{"Parts":["Spec","Tags"]},"A":null,"B":{}}]}
2022-01-10T14:26:55.890Z ERROR controller-runtime.controller Reconciler error {"controller": "nodegroup", "request": "default/ack-hama-ng", "error": "not implemented"}
つづく!
もう少し続くのじゃ。
関連リンク: