この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
おはようございます、加藤です。Amazon EKSにアップデートが行われました。
Amazon EKS Cluster Endpoint Access Control - Amazon EKS
従来、kubectl
でアクセスするエンドポイントは必ずパブリックに公開され、AWS IAMとk8sのRBACによって保護されていました。
今回のアップデートによってプライベートにのみエンドポイントを公開するといった設計が可能になります。
アップデートの内容
最初に、この機能はAWS PrivateLinkエンドポイントではありません、Amazon VPCのコンソールから操作はできずEKSに対して操作する必要があります。
EKSのコンソールにアクセスし、クラスターのネットワーキングの項目を確認してみるとAPI server endpoint accessという項目が存在します。
普段私が触っている検証用のEKSではPrivate: Disabled
, Public: Enabled
と設定されていました。
ドキュメントを元にこれらの設定がどういう意味か確認していきます。
| パブリックアクセス | プライベートアクセス | 動作 | | ------------------ | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 有効 | 無効 | Amazon EKSクラスターのデフォルトの状態 クラスターの存在するVPC内からのAPIアクセスは、VPC外に出るがAmazonのネットワーク内のみを通る(Worker Nodes→Controll Planeの通信など) インターネットからAPIアクセスが可能 | | 有効 | 有効 | クラスターの存在するVPC内からのAPIアクセスは、プライベートVPCエンドポイントにアクセスする インターネットからAPIアクセスが可能 | | 無効 | 有効 | クラスターの存在するVPC内からのAPIアクセスする必要がある インターネットからAPIアクセスが不可能 |
上記でクラスターの存在するVPCと記載していますが、VPNやDirect Connectなどによって継っている範囲も含みます。
プライベートアクセスの制限事項
EKSクラスターが存在するVPCで下記の設定を有効にする必要があります。
- enableDnsHostnames: true
- enableDnsSupport: true
設定方法(パブリック無効/プライベート有効)
踏み台サーバーを立てる
インスタンスプロファイルを作成します。
AWS管理ポリシーのAmazonEC2RoleforSSM
と下記のインラインポリシーを関連付けしておきます。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"eks:UpdateClusterConfig",
"eks:DescribeUpdate",
"eks:DescribeCluster",
"eks:ListClusters"
],
"Resource": "*"
}
]
}
EC2インスタンスを1台立ち上げて、先程作成したインスタンスプロファイルを関連付けます。
Controll PlaneのSecurity Groupの設定
踏み台サーバーからControll Planeに対して、HTTPS(TCP/443)アクセスを許可します。
アクセス権限の付与
踏み台サーバー(のIAMロール)にアクセス権限を付与します。下記ドキュメントを参考に設定してください。system:masters
に所属させました。
groups:
- system:masters
クラスターのユーザーまたは IAM ロールの管理 - Amazon EKS
踏み台をサーバーのセットアップ
踏み台サーバーに接続し作業を行います。
最新のAWS CLIをインストール
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
sudo python get-pip.py
sudo pip install awscli
kubectlのインストール
curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.11.5/2018-12-06/bin/linux/amd64/kubectl
chmod +x ./kubectl
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH
echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
aws-iam-authenticatorのインストール
curl -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.11.5/2018-12-06/bin/linux/amd64/aws-iam-authenticator
chmod +x ./aws-iam-authenticator
mkdir -p $HOME/bin && cp ./aws-iam-authenticator $HOME/bin/aws-iam-authenticator && export PATH=$HOME/bin:$PATH
echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
kubeconfigの取得
aws eks --region ap-northeast-1 update-kubeconfig --name shared-cluster
動作確認
kubectl version
クラスターの設定を変更
現在が、インターネット経由でAPIアクセスできる事を確認しておきます。kubectl version
で確認しました。
踏み台サーバーに接続し作業を行います。
APIアクセスの設置をパブリック無効/プライベート有効に変更します。
cluster_name=YOUR_CLUSTER_NAME
public_access=false
private_access=true
aws eks --region ap-northeast-1 update-cluster-config \
--name ${cluster_name} \
--resources-vpc-config endpointPublicAccess=${public_access},endpointPrivateAccess=${private_access}
下記のようなレスポンスがコンソールに表示され、クラスター設定の変更が始まります。
{
"update": {
"status": "InProgress",
"errors": [],
"params": [
{
"type": "EndpointPublicAccess",
"value": "false"
},
{
"type": "EndpointPrivateAccess",
"value": "true"
}
],
"type": "EndpointAccessUpdate",
"id": "YOUR_UPDATE_ID",
"createdAt": 1553058197.196
}
}
進行状況は下記のコマンドで確認ができます。
aws eks --region ap-northeast-1 describe-update --name ${cluster_name} --update-id YOUR_UPDATE_ID
動作確認
踏み台からはAPIアクセスが可能なままですが、インターネット経由だと不可能になりました。
kubectl version
の結果を見るとXXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com
がAPIのアドレスで、これが名前解決ができていない様です。
kubectl version
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.5", GitCommit:"753b2dbc622f5cc417845f0ff8a77f539a4213ea", GitTreeState:"clean", BuildDate:"2018-12-06T01:33:57Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"darwin/amd64"}
Unable to connect to the server: dial tcp: lookup XXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com on 10.63.200.10:53: no such host
踏み台で名前解決してみました。プライベートIPアドレスで解決ができています。
dig XXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com
; <<>> DiG 9.9.4-RedHat-9.9.4-73.amzn2.1.1 <<>> XXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15661
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 0
;; QUESTION SECTION:
;XXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com. IN A
;; ANSWER SECTION:
XXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com. 60 IN A 192.168.131.209
XXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com. 60 IN A 192.168.104.190
;; AUTHORITY SECTION:
XXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com. 172800 IN NS ns-XXXX.awsdns-00.org.
XXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com. 172800 IN NS ns-XXXX.awsdns-00.co.uk.
XXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com. 172800 IN NS ns-XXXX.awsdns-00.net.
XXXXXXXXXXXX.yl4.ap-northeast-1.eks.amazonaws.com. 172800 IN NS ns-XXXX.awsdns-00.com.
;; Query time: 4 msec
;; SERVER: 192.168.0.2#53(192.168.0.2)
;; WHEN: Wed Mar 20 05:15:00 UTC 2019
;; MSG SIZE rcvd: 254
ドキュメントを確認するとこの名前解決を行うためにバックエンド(ユーザーからは見えない)でAmazon EKSがRoute53 プライベートホストゾーンを作成し名前解決を提供してくれているようです。 ドキュメントによるとVPNやDirect Connect経由でもプライベートアクセスが可能ですが、Route53 Resolverを使うなど名前解決はしっかりと検討すべきですね。(パブリック無効の時はVPC外から基本的にプライベートIPアドレスも解決できない)
あとがき
従来のVPCエンドポイントは、VPC内から出ないでAWSサービスにアクセスできるという仕組みでパブリックからのアクセスを禁止するものではありません。しかし、このEKS独自の仕組みはパブリックアクセスの禁止が可能という事が大きな特徴です。
個人的な見解としては、この設定を行ってしまうとVPC外からアクセスができなくなり、例えばCodeBuildからkubectl
を叩く事が出来なくなってしまいます。思わぬ落とし穴を作ってしまうかなと感じています。使うのは明確にやむを得ない理由がある場合に留めた方が良いでしょう。