インターネット接続のないVPC(VPC閉塞環境、プロキシ接続もなし)環境で、EKSクラスターを利用するためのセットアップの手順(ハンズオン)です。
eksctlコマンドを利用すれば比較的容易にEKSのプライベートクラスターが構築可能ですが(EKS Fully-Private Cluster参照)、EKSクラスターが、どのようなAWSサービスを活用しているのか、どのようなIAM権限や、通信経路が必要になるのかを学習することも目的としているため、スクラッチで順を追って構築する手順にしています。
このハンズオンで、以下の環境を構築できます。
- シンプルなEKSプライベートクラスター(ワーカーノードは、EC2タイプ)を用意し、シンプルなhttpdのpodを稼働させる
- Autoscalerを導入し、ワーカーノードをスケールイン/アウトさせる。
- AWS Load Balancer Controllerを導入し、ELBによるロードバランシングを実装する
EKSの構築の手順が複雑なため、手順の多くはCloudFormation化していますが、一部CLIで設定する箇所もあります。 またGUI(マネージメントコンソール)はUIが頻繁に変わるため、CloudFormationのスタック作成も含め全てAWS CLI(LinuxやMacのシェル環境を前提)での実行を前提としています。
シンプルなEKSプライベートクラスターを作成し、動作テストでpodを動かします。
下記を準備します。
- bashが利用可能な環境(LinuxやMacの環境)
- aws-cliのセットアップ
- AdministratorAccessポリシーが付与され実行可能な、aws-cliのProfileの設定
git clone https://github.com/Noppy/EKSPoC_For_SecureEnvironment.git
cd EKSPoC_For_SecureEnvironment
これ以降のAWS-CLIで共通で利用するパラメータを環境変数で設定しておきます。
export PROFILE=<PoC環境のAdministratorAccess権限が実行可能なプロファイル>
export REGION="ap-northeast-1"
# プロファイルの動作テスト
# COMPUTE_PROFILE
aws --profile ${PROFILE} sts get-caller-identity
aws --profile ${PROFILE} --region ${REGION} \
cloudformation deploy \
--stack-name EksPoc-VPC \
--template-file "./src/vpc-2az-4subnets.yaml" \
--parameter-overrides "file://./src/vpc.conf"
aws --profile ${PROFILE} --region ${REGION} \
cloudformation deploy \
--stack-name EksPoc-SG \
--template-file "./src/sg.yaml"
aws --profile ${PROFILE} --region ${REGION} \
cloudformation deploy \
--stack-name EksPoc-VpceSimple \
--template-file "./src/vpce_simple.yaml"
必要なIAMロールを準備します。
- AWS管理ポリシーを付与する場合おはこのタイミングで付与します。
- またカスタマー管理ポリシーまたはインラインポリシーでリソースの特定が不要な場合もこのタイミングでポリシーを付与します。
- リソースの特定が必要な場合(例えばECRのリポジトリのARNが必要など)は、リソース作成時に個別にポリシーを付与します。
aws --profile ${PROFILE} --region ${REGION} \
cloudformation deploy \
--stack-name EksPoc-IAM \
--template-file "./src/iam.yaml" \
--capabilities CAPABILITY_IAM
aws --profile ${PROFILE} --region ${REGION} \
cloudformation deploy \
--stack-name EksPoc-KMS \
--template-file "./src/kms.yaml"
# Bastion & DockerSG & kubectl
aws --profile ${PROFILE} --region ${REGION} \
cloudformation deploy \
--stack-name EksPoc-Instances \
--template-file "./src/instances.yaml"
aws --profile ${PROFILE} --region ${REGION} \
cloudformation deploy \
--stack-name EksPoc-Ecr \
--template-file "./src/ecr.yaml"
# DockerDevインスタンスのインスタンスID取得
DockerDevID=$(aws --profile ${PROFILE} --region ${REGION} --output text \
cloudformation describe-stacks \
--stack-name EksPoc-Instances \
--query 'Stacks[].Outputs[?OutputKey==`DockerDevId`].[OutputValue]')
echo "DockerDevID = $DockerDevID"
# SSMによるOSログイン
aws --profile ${PROFILE} --region ${REGION} \
ssm start-session \
--target "${DockerDevID}"
# ec2-userにスイッチ
sudo -u ec2-user -i
# Setup AWS CLI
REGION=$( \
TOKEN=`curl -s \
-X PUT \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600" \
"http://169.254.169.254/latest/api/token"` \
&& curl \
-H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')
aws configure set region ${REGION}
aws configure set output json
# 動作テスト(作成したECRレポジトリがリストに表示されることを確認)
aws ecr describe-repositories
# dockerのセットアップ
sudo yum install -y docker
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -a -G docker ec2-user
# usermod設定をセッションに反映するためsudoし直す
exit
# ec2-userにスイッチ
sudo -u ec2-user -i
# ec2-userユーザのセカンドグループにdockerが含まれていることを確認する
id
# dockerテスト(下記コマンドでサーバ情報が参照できることを確認)
docker info
# コンテナイメージ用のディレクトリを作成し移動
mkdir httpd-container
cd httpd-container
# データ用フォルダを作成
mkdir src
# dockerコンテナの定義ファイルを作成
cat > Dockerfile << EOL
# setting base image
FROM php:8.1-apache
RUN set -x && \
apt-get update && \
apt-get upgrade && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY src/ /var/www/html/
EOL
# アプリケーションのトップページを作成
cat > src/index.php << EOL
<html>
<head>
<title>PHP Sample</title>
</head>
<body>
<?php echo gethostname(); ?>
</body>
</html>
EOL
# Docker build
docker build -t httpd-sample:ver01 .
docker images
# コンテナの動作確認
docker run -d -p 8080:80 httpd-sample:ver01
docker ps # コンテナが稼働していることを確認
# 接続確認
# <title>PHP Sample</title>という文字が表示されたら成功!!
curl http://localhost:8080
REPO_URL=$( aws --output text \
ecr describe-repositories \
--repository-names ekspoc-repo \
--query 'repositories[].repositoryUri' ) ;
echo "
REPO_URL = ${REPO_URL}
"
# ECR登録用のタグを作成
docker tag httpd-sample:ver01 ${REPO_URL}:latest
docker images # 作成したtagが表示されていることを確認
# ECRログイン
# "Login Succeeded"と表示されることを確認
aws ecr get-login-password | docker login --username AWS --password-stdin ${REPO_URL}
# イメージのpush
docker push ${REPO_URL}:latest
# ECR上のレポジトリ確認
aws ecr list-images --repository-name ekspoc-repo
exit # ec2-userから戻る
exit # SSMからのログアウト
以下の作業は、Bastion兼高権限用インスタンスで作業します。 これは作成したEKSクラスターの初期状態でkubectlで操作可能なIAMは、EKSクラスターを作成した権限のみのためである。
# 高権限インスタンスのインスタンスID取得
HighAuthID=$(aws --profile ${PROFILE} --region ${REGION} --output text \
cloudformation describe-stacks \
--stack-name EksPoc-Instances \
--query 'Stacks[].Outputs[?OutputKey==`BastionAndHighAuthorityId`].[OutputValue]')
echo "HighAuthID = $HighAuthID"
# SSMによるOSログイン
aws --profile ${PROFILE} --region ${REGION} \
ssm start-session \
--target "${HighAuthID}"
# ec2-userにスイッチ
sudo -u ec2-user -i
# Setup AWS CLI
REGION=$( \
TOKEN=`curl -s \
-X PUT \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600" \
"http://169.254.169.254/latest/api/token"` \
&& curl \
-H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')
aws configure set region ${REGION}
aws configure set output json
EksAdmin環境でkubectl操作を可能にするためには、まずHightAuth環境でkubeconfigの初期設定の初期設定を行う必要がある。そのためにまずHighAuth環境でkubectlをセットアップする。
# kubectlのダウンロード
curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.22.6/2022-03-09/bin/linux/amd64/kubectl
curl -o kubectl.sha256 https://s3.us-west-2.amazonaws.com/amazon-eks/1.22.6/2022-03-09/bin/linux/amd64/kubectl.sha256
# チェックサム確認
if [ $(openssl sha1 -sha256 kubectl|awk '{print $2}') = $(cat kubectl.sha256 | awk '{print $1}') ]; then echo OK; else echo NG; fi
# kubectlのパーミッション付与と移動
chmod +x ./kubectl
mkdir -p $HOME/bin && mv ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH
echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
# 動作テスト
kubectl version --short --client
sudo yum -y install git
git clone https://github.com/Noppy/EKSPoC_For_SecureEnvironment.git
cd EKSPoC_For_SecureEnvironment
EKSクラスター作成は15分程度かかります。
aws cloudformation deploy \
--stack-name EksPoc-EksControlPlane \
--template-file "./src/eks_control_plane.yaml"
kubectlからクラスターが参照できるように設定を行います。
# EKSクラスター情報取得
EKS_CLUSTER_NAME=$(aws --output text cloudformation \
describe-stacks --stack-name EksPoc-EksControlPlane \
--query 'Stacks[].Outputs[?OutputKey==`ClusterName`].[OutputValue]' )
echo "EKS_CLUSTER_NAME = ${EKS_CLUSTER_NAME}"
# kubectl用のconfig取得
aws eks update-kubeconfig --name ${EKS_CLUSTER_NAME}
# kubectlコマンドからのk8sマスターノード接続確認
kubectl get svc
(この手順はセルフマネージド型ノードの場合は必要ですが、マネージド型ノードグループでは不要です)
ワーカーノードに適用するインスタンスロールをk8sのコントロールプレーンで認識し有効化するために、aws-auth
でマッピングを行います。
aws-auth ConfigMap が適用済みであるかどうかを確認します。
kubectl describe configmap -n kube-system aws-auth
Error from server (NotFound): configmaps "aws-auth" not found
というエラーが表示された場合は、以下のステップを実行してストック ConfigMap を適用します。
curl -o aws-auth-cm.yaml https://amazon-eks.s3.us-west-2.amazonaws.com/cloudformation/2020-10-29/aws-auth-cm.yaml
CloudFormationからWorkerNodeインスタンス用のIAMロールのARNを取得します。
aws --output text cloudformation describe-stacks \
--stack-name EksPoc-IAM \
--query 'Stacks[].Outputs[?OutputKey==`EC2k8sWorkerRoleArn`].[OutputValue]'
aws-auth-cm.yaml編集
<ARN of instance role (not instance profile)>
をWorkerNodeのインスタンスロールARNに修正します。
vi aws-auth-cm.yaml
中略
data:
mapRoles: |
- rolearn: <ARN of instance role (not instance profile)>
以下略
aws-authを適用します。
# aws-auth-cm.yamlの適用
kubectl apply -f aws-auth-cm.yaml
(セルフマネージド型ノードの場合や、マネージド型ノードグループで起動テンプレートのユーザーデータを使用してブートストラップスクリプトに引数を渡す必要がある場合は、Kubernetes API サーバーの URL と証明書の情報が必要です)
# WorkerへのSSH接続設定
KEY_NAME="CHANGE_KEY_PAIR_NAME" #SSH接続する場合
# KEY_NAME="" #SSH接続しない場合はブランクを設定する
EKS_CLUSTER_NAME=$(aws --output text cloudformation \
describe-stacks --stack-name EksPoc-EksControlPlane \
--query 'Stacks[].Outputs[?OutputKey==`ClusterName`].[OutputValue]' )
# EKS_B64_CLUSTER_CA=$(aws --output text cloudformation \
# describe-stacks --stack-name EksPoc-EksControlPlane \
# --query 'Stacks[].Outputs[?OutputKey==`CertificateAuthorityData`].[OutputValue]' )
# EKS_API_SERVER_URL=$(aws --output text cloudformation \
# describe-stacks --stack-name EksPoc-EksControlPlane \
# --query 'Stacks[].Outputs[?OutputKey==`ControlPlaneEndpoint`].[OutputValue]' )
echo "
KEY_NAME = ${KEY_NAME}
EKS_CLUSTER_NAME = ${EKS_CLUSTER_NAME}
# EKS_B64_CLUSTER_CA = ${EKS_B64_CLUSTER_CA}
# EKS_API_SERVER_URL = ${EKS_API_SERVER_URL}
"
(セルフマネージド型ノードの場合や、マネージド型ノードグループで起動テンプレートのユーザーデータを使用してブートストラップスクリプトに引数を渡す必要がある場合は、Kubernetes API サーバーの URL と証明書の情報が必要です。なお、マネージド型ノードグループでブートストラックスクリプトに引数を渡す場合、AMI ID の指定も必須となります)
aws cloudformation deploy \
--stack-name EksPoc-EksNodeGroup\
--template-file "./src/eks_worker_nodegrp.yaml" \
--parameter-overrides \
ClusterName="${EKS_CLUSTER_NAME}" \
KeyName="${KEY_NAME}"
# B64ClusterCa="${EKS_B64_CLUSTER_CA}" \
# ApiServerUrl="${EKS_API_SERVER_URL}"
# WorkerNode状態確認
kubectl get nodes --watch
aws-auth
にk8sのRBAC認証に対応させたいIAMユーザ/ロールを追加します。
手順の概要は以下のとおりです。
kubectl
コマンドでaws-auth ConfigMap
を開き編集する- 設定は
mapRoles
にリスト形式で追加する。追加する場合の設定はそれぞれ以下の通りrolearn:
またはuserarn
: IAMロールを追加する場合はrolearn
、IAMユーザを追加する場合はuserarn
で、対象のARNを指定する。username
: kubernetes内のユーザー名groups
: k8s内でのマッピング先のグループをリストで指定する。
- エディタで保存&終了(viエディタなので、
:
のあとwq
)すると反映してくれる。 - 参考情報
- 事前の情報取得
# kubectl実行用EC2のインスタンスロールのARN取得
KUBECTL_ROL_ARN=$(aws --output text cloudformation \
describe-stacks --stack-name EksPoc-IAM \
--query 'Stacks[].Outputs[?OutputKey==`EC2kubectlRoleArn`].[OutputValue]' )
echo "
KUBECTL_ROL_ARN = ${KUBECTL_ROL_ARN}
"
aws-auth ConfigMap
の編集
# aws-auth ConfigMapを開く
kubectl edit -n kube-system configmap/aws-auth
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
mapRoles: |
- rolearn: arn:aws:iam::616605178605:role/EksPoc-IAM-EC2k8sWorkerRole-8BI00X63GF2P
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
# ↓ココから下を追加
- rolearn: "$KUBECTL_ROL_ARN のARN値を指定"
username: kubectladmin
groups:
- system:masters
# ここまで
# 以下略
# aws-auth ConfigMapを開く
kubectl edit -n kube-system configmap/aws-auth
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
mapRoles: |
- rolearn: arn:aws:iam::616605178605:role/EksPoc-IAM-EC2k8sWorkerRole-8BI00X63GF2P
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
- rolearn: "$KUBECTL_ROL_ARN のARN値を指定"
username: kubectladmin
groups:
- system:masters
# ↓ココから下を追加
- rolearn: "コンソール操作時の権限のARNを指定"
username: consoleadmin
groups:
- system:masters
# ここまで
# 以下略
作成したEKSのkubernetes環境の動作確認のために事前にECRに登録したhttpdのDockerイメージを利用し以下のようなサービスを作成して、端末からアクセスできるかテストします。
参考情報
REPO_URL=$(aws --output text cloudformation \
describe-stacks --stack-name EksPoc-Ecr \
--query 'Stacks[].Outputs[?OutputKey==`EcrRepositoryUri`].[OutputValue]' )
echo "
REPO_URL = ${REPO_URL}
"
# Deployment定義ファイルの作成
# 環境固有となるECRレポジトリURL情報をDeploymentに設定します。
sed -e "s;REPO_URL;${REPO_URL};" k8s_define/httpd-deployment.yaml.template > httpd-deployment.yaml
cat httpd-deployment.yaml
# Service定義ファイルの確認
cat k8s_define/httpd-service.yaml
kubectlコマンドを利用して定義を適用します。
# Deploymentの適用
kubectl apply -f httpd-deployment.yaml
# Serviceの適用
kubectl apply -f k8s_define/httpd-service.yaml
- Deploymentの状態確認
kubectl get deployments -o wide httpd-deployment
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd-deployment 0/2 2 0 9s httpd 141247782993.dkr.ecr.ap-northeast-1.amazonaws.com/ekspoc-repo:latest app=httpd-pod
- Podの状態確認
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
httpd-deployment-65f68b9dfc-2bx8n 1/1 Running 0 29s 10.1.39.243 ip-10-1-42-54.ap-northeast-1.compute.internal <none> <none>
httpd-deployment-65f68b9dfc-9svlr 1/1 Running 0 29s 10.1.154.189 ip-10-1-147-247.ap-northeast-1.compute.internal <none> <none>
- Service状態確認
kubectl get svc -o wide httpd-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
httpd-service ClusterIP 172.20.170.144 <none> 8080/TCP 9m31s app=httpd-pod
ClusterIPは、通常kubernetesのクラスター内からのみからのアクセスとなりますが、kubectlコマンドでフォワードさせることでクラスター外の端末からアクセスが可能となります。
- ポートフォワーディング起動(この状態でwaitになります。終了する場合は
CTRL+C
で終了)
kubectl port-forward service/httpd-service 9999:8080
Forwarding from 127.0.0.1:9999 -> 80
Forwarding from [::1]:9999 -> 80
- 別端末から
kubectl port-forward
を実行しているOS上にログインします - 別端末で下記コマンドでhttpサーバの情報が参照できたら成功です
curl http://localhost:9999
<html>
<head>
<title>PHP Sample</title>
</head>
<body>
httpd-deployment-dbb8b7f8c-nbkg2 </body>
</html>
# Serviceの削除
kubectl delete -f k8s_define/httpd-service.yaml
# Deploymentの削除
kubectl delete -f httpd-deployment.yaml
以下の作業は、Bastion兼高権限用インスタンスで作業します。 作業のカレントディレクトリは、githubからcloneしたEKSPoC_For_SecureEnvironmentのリポジトリ直下を前提としています。
コマンドの中でJSONデータを処理するjqコマンドを利用するため、予めjqをインストールします。
sudo yum -y install jq
OIDCの認証情報取得のためにstsへのアクセスを行うため、STSのVPCエンドポイントを追加します。
aws cloudformation deploy \
--stack-name EksPoc-Vpce-oidc \
--template-file "./src/vpce_for_oidc.yaml"
サムプリントは、証明書の暗号化ハッシュです。
- 参考情報
OpenIdConnectIssuerUrl=$(aws --output text \
cloudformation describe-stacks \
--stack-name EksPoc-EksControlPlane \
--query 'Stacks[].Outputs[?OutputKey==`OpenIdConnectIssuerUrl`].[OutputValue]')
# IdP の設定ドキュメント取得のURL生成
URL="${OpenIdConnectIssuerUrl}/.well-known/openid-configuration"
echo $URL
# ドメイン取得
FQDN=$(curl $URL 2>/dev/null | jq -r '.jwks_uri' | sed -E 's/^.*(http|https):\/\/([^/]+).*/\2/g')
echo $FQDN
#サーバー証明書の取得
echo | openssl s_client -connect $FQDN:443 -servername $FQDN -showcerts
opensslコマンドを実行すると、次のような証明書が複数表示されます。 複数の証明書のうち表示される最後 (コマンド出力の最後) の証明書を特定します。
-----BEGIN CERTIFICATE-----
MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
VVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6
b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAd
BgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhcNMTEwNDI1MjA0NTIxWhcN
MTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYD
VQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25z
b2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFt
YXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ
21uUSfwfEvySWtC2XADZ4nB+BLYgVIk60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9T
rDHudUZg3qX4waLG5M43q7Wgc/MbQITxOUSQv7c7ugFFDzQGBzZswY6786m86gpE
Ibb3OhjZnzcvQAaRHhdlQWIMm2nrAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4
nUhVVxYUntneD9+h8Mg9q6q+auNKyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0Fkb
FFBjvSfpJIlJ00zbhNYS5f6GuoEDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTb
NYiytVbZPQUQ5Yaxu2jXnimvw3rrszlaEXAMPLE=
-----END CERTIFICATE-----
証明書 (-----BEGIN CERTIFICATE-----
および -----END CERTIFICATE-----
行を含む) をコピーして、テキストファイルに貼り付けます。次に、certificate.crt
という名前でファイルを保存します。
cat > certificate.crt
# コピーした証明書を貼り付けて、最後にCTRL+Dで終了する
# ファイルの確認
cat certificate.crt
THUMBPRINT=$(openssl x509 -in certificate.crt -fingerprint -noout | sed -E 's/SHA1 Fingerprint=(.*)/\1/g' | sed -E 's/://g')
echo $THUMBPRINT
aws iam create-open-id-connect-provider \
--url "${OpenIdConnectIssuerUrl}" \
--thumbprint-list "${THUMBPRINT}" \
--client-id-list "sts.amazonaws.com"
Cluster Autoscalerを導入して、kubernetesからAutoScalingを調整してスケールアップ/スケールインをコントローするようにします。
Cluster Autoscalerは、ワーカーノードのリソース利用状況に合わせて、EC2 Autoscalingのインスタンス数設定を変更することで、キャパシティーの調整を行います。 Cluster AutoscalerからEC2 Autoscalingを操作できるようにするために、EC2 AutoscalingのVPCエンドポイントを追加します。
aws cloudformation deploy \
--stack-name EksPoc-Vpce-Autoscaler \
--template-file "./src/vpce_for_autoscaler.yaml"
本検証環境は、kubernetesのワーカーノードから外部にはアクセスができないため、そのままではCluster Autoscalerのdockerイメージが取得できません。 そのためECRリポジトリを用意し、Cluster Autoscalerのdockerイメージを格納しておきます。
aws cloudformation deploy \
--stack-name EksPoc-AutoscalerEcr \
--template-file "./src/Autoscaler/ecr_for_autoscaler.yaml"
以下の作業は、別端末を開いてDockerインスタンスにログインして作業します。
- Dockerインスタンスへのログイン
export PROFILE=<PoC環境のAdministratorAccess権限が実行可能なプロファイル>
export REGION="ap-northeast-1"
# プロファイルの動作テスト
aws --profile ${PROFILE} sts get-caller-identity
# DockerDevインスタンスのインスタンスID取得
DockerDevID=$(aws --profile ${PROFILE} --region ${REGION} --output text \
cloudformation describe-stacks \
--stack-name EksPoc-Instances \
--query 'Stacks[].Outputs[?OutputKey==`DockerDevId`].[OutputValue]')
echo "DockerDevID = $DockerDevID"
# SSMによるOSログイン
aws --profile ${PROFILE} --region ${REGION} \
ssm start-session \
--target "${DockerDevID}"
- ec2-userへの変更
sudo -u ec2-user -i
- dockerイメージの情報取得
下記で表示されるイメージ情報のURI(
k8s.gcr.io/autoscaling/cluster-autoscaler
など)を控えておきます。
curl https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml 2> /dev/null | grep 'image:'
タグ情報は、ウェブブラウザで、GitHub の Cluster Autoscaler リリースページを開き、最新の (クラスターの Kubernetes のメジャーおよびマイナーバージョンに一致する) Cluster Autoscaler バージョンを見つけます。ととえば、クラスターの Kubernetes バージョンが 1.21 の場合、1.21 で始まる Cluster Autoscaler リリースを見つけます。次のステップで使用するので、そのリリースのセマンティックバージョン番号 (1.21.n) を書き留めておきます。
上記のimage情報を変数に入れておきます。
AUTOSCALER_PATH="<上記で控えておいたAutoscalerのイメージのuri:タグ情報>"
AutoscalerのDockerイメージをローカルにpullします。
docker pull "${AUTOSCALER_PATH}"
# 取得した情報の確認
docker images
- dockerイメージをECRに格納 Autoscaler用ECRのURI取得
REPO_URL=$( aws --output text \
ecr describe-repositories \
--repository-names autoscaler-repo \
--query 'repositories[].repositoryUri' ) ;
echo "
REPO_URL = ${REPO_URL}
"
ECRへのpush
# ECR登録用のタグを作成
docker tag ${AUTOSCALER_PATH} ${REPO_URL}:latest
docker images # 作成したtagが表示されていることを確認
# ECRログイン
# "Login Succeeded"と表示されることを確認
aws ecr get-login-password | docker login --username AWS --password-stdin ${REPO_URL}
# イメージのpush
docker push ${REPO_URL}:latest
# ECR上のレポジトリ確認
aws ecr list-images --repository-name autoscaler-repo
作業が完了したので、Dockerインスタンスからログアウトします
exit
exit
以後の作業は、Bastion兼高権限用インスタンスに戻って行います。
# EKSクラスターのOIDC情報取得
OIDCProviderId=$(aws --output text \
cloudformation describe-stacks \
--stack-name EksPoc-EksControlPlane \
--query 'Stacks[].Outputs[?OutputKey==`OpenIdConnectIssuerUrl`].[OutputValue]' | cut -d "/" -f 5)
echo "OIDCProviderId = ${OIDCProviderId}"
# 該当OIDCプロバイダーのARN取得
OIDCProviderARN=$(aws --output json iam list-open-id-connect-providers | jq -r '.OpenIDConnectProviderList[].Arn | select( . | contains("'${OIDCProviderId}'") )')
echo "OIDCProviderARN = ${OIDCProviderARN}"
# 該当OIDCプロバイダーのURI取得
OIDCProviderURI=$(aws --output text iam get-open-id-connect-provider --open-id-connect-provider-arn ${OIDCProviderARN} --query 'Url')
echo "OIDCProviderURI = ${OIDCProviderURI}"
sed -e "s;OIDCProviderARN;${OIDCProviderARN};g" \
-e "s;OIDCProviderURI;${OIDCProviderURI};g" \
src/Autoscaler/cluster_autoscaler_iam_role_trust_policy.json_template > cluster_autoscaler_iam_role_trust_policy.json
# EKSクラスター情報取得
EKS_CLUSTER_NAME=$(aws --output text cloudformation \
describe-stacks --stack-name EksPoc-EksControlPlane \
--query 'Stacks[].Outputs[?OutputKey==`ClusterName`].[OutputValue]' )
echo "EKS_CLUSTER_NAME = ${EKS_CLUSTER_NAME}"
IAM_ROLE_NAME=${EKS_CLUSTER_NAME}-Autoscaler_Role
# IAMロール作成
aws iam create-role \
--role-name "${IAM_ROLE_NAME}" \
--assume-role-policy-document "file://cluster_autoscaler_iam_role_trust_policy.json"
# IAMポリシー(インラインポリシー)のアタッチ
aws iam put-role-policy \
--role-name "${IAM_ROLE_NAME}" \
--policy-name Autoscaler \
--policy-document "file://./src/Autoscaler/cluster_autoscaler_iam_policy.json"
下記ドキュメントにAttach the above created policy to the instance role that's attached to your Amazon EKS worker nodes.
とあるので、同じIAMポリシーをワーカーノードのインスタンスロールにも付与します。
# ワーカーノードのインスタンスロールのロール名を取得
WORKER_ROLE_NAME=$(aws --output text cloudformation \
describe-stacks --stack-name EksPoc-IAM \
--query 'Stacks[].Outputs[?OutputKey==`EC2k8sWorkerRoleName`].[OutputValue]' )
echo "WORKER_ROLE_NAME = ${WORKER_ROLE_NAME}"
# IAMポリシー(インラインポリシー)のアタッチ
aws iam put-role-policy \
--role-name "${WORKER_ROLE_NAME}" \
--policy-name Autoscaler \
--policy-document "file://./src/Autoscaler/cluster_autoscaler_iam_policy.json"
# ロールのARNをメモ帳などに控えておきます。
aws --output text iam get-role --role-name "${IAM_ROLE_NAME}" --query 'Role.Arn'
curl -o cluster-autoscaler-autodiscover.yaml https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
エディタで開いて定義ファイルを編集します。
- クラスター名の変更
<YOUR CLUSTER NAME>
の部分を実際のEKSクラスター名に変更します。k8s.gcr.io/autoscaling/cluster-autoscaler:v1.22.2
の部分を、(2)-(b)で保管したECRに変更します。URIは(2)-(b)で取得したものでタグはlatest
にします- 変更後のimageパスの例:
999999999999.dkr.ecr.ap-northeast-1.amazonaws.com/autoscaler-repo:latest
- 変更後のimageパスの例:
- 起動オプションの変更
--aws-use-static-instance-list=true
を追加。(デフォルトではEC2インスタンスの最新リスト取得のためにapi.pricing.us-east-1.amazonaws.com
にアクセスするが、インターネット接続がない環境ではエラーになりAutoscalerが起動失敗するため無効化する)
serviceAccountName: cluster-autoscaler
containers:
- image: k8s.gcr.io/autoscaling/cluster-autoscaler:v1.22.2 <<== 変更する
name: cluster-autoscaler
resources:
limits:
cpu: 100m
memory: 600Mi
requests:
cpu: 100m
memory: 600Mi
command:
- ./cluster-autoscaler
- --v=4
- --stderrthreshold=info
- --cloud-provider=aws
- --skip-nodes-with-local-storage=false
- --expander=least-waste
- --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<YOUR CLUSTER NAME> <<== 変更する
- --aws-use-static-instance-list=true <<==追加する
- Autoscaler用IAMロールの追加
- Autoscalerで利用するOIDC認証を行うIAMロールを定義に追加します
- 追加場所と追加方法は、定義ファイル先頭の
metadata
セクションにannotations
で追加します。 arn:aws:iam::xxxxx:role/Amazon_CA_role
の部分を、(2)-(b)の(iii)で作成したIAMロールのARNに置き換えます。
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
annotations: <==行追加
eks.amazonaws.com/role-arn: arn:aws:iam::xxxxx:role/Amazon_CA_role # Add the IAM role created in the above C section. <==行追加
name: cluster-autoscaler
namespace: kube-system
kubectl apply -f cluster-autoscaler-autodiscover.yaml
kubectl get deployment/cluster-autoscaler -o wide -n kube-system
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
cluster-autoscaler 1/1 1 1 16s cluster-autoscaler 616605178605.dkr.ecr.ap-northeast-1.amazonaws.com/autoscaler-repo:latest app=cluster-autoscaler
READY
が1/1
になり、AVAILABLEが1
であれば成功です。
- ログを参照する場合は下記コマンドで確認できます。
kubectl -n kube-system logs -f deployment.apps/cluster-autoscaler
ハンズオン(その1)
の(7)で動作確認で利用したdeploymentを利用して、autoscalingの動作確認を行います。
httpd-deployment.yaml
のreplicas:
の数を2
から20
に変更します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment
labels:
app: httpd-dep
spec:
replicas: 2 <<= ここを2から20に変更する
selector:
matchLabels:
app: httpd-pod
<以下略>
kubectl apply -f httpd-deployment.yaml
# deploymentの状態確認
kubectl get deployments httpd-deployment
# ワーカーノードの確認
kubectl get nodes
また、AutoscalingのDesired capacity
が変更されているかを確認する。
AWS Load Balancer Controllerから、ELBを操作できるようにするために、Elastic Load BalancingのVPCエンドポイントを追加します。
aws cloudformation deploy \
--stack-name EksPoc-Vpce-AwsLoadBalancerController \
--template-file "./src/vpce_for_aws-load-balancer-controller.yaml"
本検証環境はkubernetesのワーカーノードから外部にはアクセスができないため、ECRリポジトリを用意しAWS Load Balancer Controllerのdockerイメージを格納しておきます。
- AWS Load Balancer Controller
aws cloudformation deploy \
--stack-name EksPoc-AwsLoadBalancerControllerEcr \
--template-file "./src/AWSLoadBalancerController/ecr_for_aws-load-balancer-controller.yaml"
- CERT-Manager
aws cloudformation deploy \
--stack-name EksPoc-CertManagerControllerEcr \
--template-file "./src/AWSLoadBalancerController/ecr_for_cert-manager-controller.yaml"
aws cloudformation deploy \
--stack-name EksPoc-CertManagerCainjectorEcr \
--template-file "./src/AWSLoadBalancerController/ecr_for_cert-manager-cainjector.yaml"
aws cloudformation deploy \
--stack-name EksPoc-CertManagerWebhookEcr \
--template-file "./src/AWSLoadBalancerController/ecr_for_cert-manager-webhook.yaml"
下記AWS Load Balancer ControllerのGitHubのリリース情報から、最新バージョンを確認する。 https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases
最新バージョンを確認したら下記情報を控えておく
- バージョン名: 例えば
v.2.4.4
など - Assetsの定義ファイルのURI: Assetsのリストでファイル名が
v2_4_4_full.yaml
などとあるYAML定義のURLを控える - DockerイメージのURI: リリース情報の冒頭に
Image: docker.io/amazon/aws-alb-ingress-controller:v2.4.4
という形で表示されているのでそこから取得するか、上記のYAML定義の中から情報を取得する。
以下の作業は、別端末を開いてDockerインスタンスにログインして作業します。
- Dockerインスタンスへのログイン
export PROFILE=<PoC環境のAdministratorAccess権限が実行可能なプロファイル>
export REGION="ap-northeast-1"
# プロファイルの動作テスト
aws --profile ${PROFILE} sts get-caller-identity
# DockerDevインスタンスのインスタンスID取得
DockerDevID=$(aws --profile ${PROFILE} --region ${REGION} --output text \
cloudformation describe-stacks \
--stack-name EksPoc-Instances \
--query 'Stacks[].Outputs[?OutputKey==`DockerDevId`].[OutputValue]')
echo "DockerDevID = $DockerDevID"
# SSMによるOSログイン
aws --profile ${PROFILE} --region ${REGION} \
ssm start-session \
--target "${DockerDevID}"
- ec2-userへの変更
sudo -u ec2-user -i
- DockerイメージのPull
AWSLBCTL_PATH="<(ii)で控えておいたAWS Load Balancer Controllerのイメージのuri:タグ情報>"
AWS Load Balancer ControllerのDockerイメージをローカルにpullします。
docker pull "${AWSLBCTL_PATH}"
# 取得した情報の確認
docker images
- dockerイメージをECRに格納 AWS Load Balancer Controller用ECRのURI取得
REPO_URL=$( aws --output text \
ecr describe-repositories \
--repository-names aws-load-balancer-controller-repo \
--query 'repositories[].repositoryUri' ) ;
echo "
REPO_URL = ${REPO_URL}
"
ECRへのpush
# ECR登録用のタグを作成
docker tag ${AWSLBCTL_PATH} ${REPO_URL}:latest
docker images # 作成したtagが表示されていることを確認
# ECRログイン
# "Login Succeeded"と表示されることを確認
aws ecr get-login-password | docker login --username AWS --password-stdin ${REPO_URL}
# イメージのpush
docker push ${REPO_URL}:latest
# ECR上のレポジトリ確認
aws ecr list-images --repository-name autoscaler-repo
同様にCertManagerのイメージをECRに保管します。最新情報は以下のデプロイ手順のCERT-Managerのノードが quay.io コンテナレジストリにアクセスできない場合
の説明を参照下さい。
-
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/aws-load-balancer-controller.html
-
マニフェストのダウンロード
curl -Lo cert-manager.yaml https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml
- イメージURIの取得
grep -e 'image:' cert-manager.yaml
image: "quay.io/jetstack/cert-manager-cainjector:v1.5.4"
image: "quay.io/jetstack/cert-manager-controller:v1.5.4"
image: "quay.io/jetstack/cert-manager-webhook:v1.5.4"
手動で以下を設定します
CERT_MGR_CAIN="<cert-manager-cainjectorのパスを設定>"
CERT_MGR_CONT="<cert-manager-controllerのパスを設定>"
CERT_MGR_WEBH="<cert-manager-webhookのパスを設定>"
- ECRレポジトリのURI取得
CERT_MGR_CAIN_REPO_URL=$( aws --output text \
ecr describe-repositories \
--repository-names cert-manager-cainjector-repo \
--query 'repositories[].repositoryUri' ) ;
CERT_MGR_CONT_REPO_URL=$( aws --output text \
ecr describe-repositories \
--repository-names cert-manager-controller-repo \
--query 'repositories[].repositoryUri' ) ;
CERT_MGR_WEBH_REPO_URL=$( aws --output text \
ecr describe-repositories \
--repository-names cert-manager-webhook-repo \
--query 'repositories[].repositoryUri' ) ;
echo "
CERT_MGR_CAIN_REPO_URL = ${CERT_MGR_CAIN_REPO_URL}
CERT_MGR_CONT_REPO_URL = ${CERT_MGR_CONT_REPO_URL}
CERT_MGR_WEBH_REPO_URL = ${CERT_MGR_WEBH_REPO_URL}
"
- イメージPull
docker pull "${CERT_MGR_CAIN}"
docker pull "${CERT_MGR_CONT}"
docker pull "${CERT_MGR_WEBH}"
確認します。
docker images
- ECRへのPush(cert-manager-cainjector)
docker tag ${CERT_MGR_CAIN} ${CERT_MGR_CAIN_REPO_URL}:latest
aws ecr get-login-password | docker login --username AWS --password-stdin ${CERT_MGR_CAIN_REPO_URL}
docker push ${CERT_MGR_CAIN_REPO_URL}:latest
aws ecr list-images --repository-name cert-manager-cainjector-repo
- ECRへのPush(cert-manager-controller)
docker tag ${CERT_MGR_CONT} ${CERT_MGR_CONT_REPO_URL}:latest
aws ecr get-login-password | docker login --username AWS --password-stdin ${CERT_MGR_CONT_REPO_URL}
docker push ${CERT_MGR_CONT_REPO_URL}:latest
aws ecr list-images --repository-name cert-manager-controller-repo
- ECRへのPush(cert-manager-webhook)
docker tag ${CERT_MGR_WEBH} ${CERT_MGR_WEBH_REPO_URL}:latest
aws ecr get-login-password | docker login --username AWS --password-stdin ${CERT_MGR_WEBH_REPO_URL}
docker push ${CERT_MGR_WEBH_REPO_URL}:latest
aws ecr list-images --repository-name cert-manager-webhook-repo
作業が完了したので、Dockerインスタンスからログアウトします
exit
exit
以後の作業は、Bastion兼高権限用インスタンスに戻って行います。
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.4/docs/install/iam_policy.json
# EKSクラスターのOIDC情報取得
OIDCProviderId=$(aws --output text \
cloudformation describe-stacks \
--stack-name EksPoc-EksControlPlane \
--query 'Stacks[].Outputs[?OutputKey==`OpenIdConnectIssuerUrl`].[OutputValue]' | cut -d "/" -f 5)
echo "OIDCProviderId = ${OIDCProviderId}"
# 該当OIDCプロバイダーのARN取得
OIDCProviderARN=$(aws --output json iam list-open-id-connect-providers | jq -r '.OpenIDConnectProviderList[].Arn | select( . | contains("'${OIDCProviderId}'") )')
echo "OIDCProviderARN = ${OIDCProviderARN}"
# 該当OIDCプロバイダーのURI取得
OIDCProviderURI=$(aws --output text iam get-open-id-connect-provider --open-id-connect-provider-arn ${OIDCProviderARN} --query 'Url')
echo "OIDCProviderURI = ${OIDCProviderURI}"
sed -e "s;OIDCProviderARN;${OIDCProviderARN};g" \
-e "s;OIDCProviderURI;${OIDCProviderURI};g" \
src/AWSLoadBalancerController/aws-load-balancer-controller_iam_role_trust_policy.json_template > aws-load-balancer-controller_iam_role_trust_policy.json
生成した信頼関係用ポリシーの確認をします。
cat aws-load-balancer-controller_iam_role_trust_policy.json
IAMロール名を設定します。
# EKSクラスター情報取得
EKS_CLUSTER_NAME=$(aws --output text cloudformation \
describe-stacks --stack-name EksPoc-EksControlPlane \
--query 'Stacks[].Outputs[?OutputKey==`ClusterName`].[OutputValue]' )
echo "EKS_CLUSTER_NAME = ${EKS_CLUSTER_NAME}"
LB_CTL_IAM_ROLE_NAME=${EKS_CLUSTER_NAME}-AWS-Loadbalancer-Controler-Role
IAMロールを作成します。
# IAMロール作成
aws iam create-role \
--role-name "${LB_CTL_IAM_ROLE_NAME}" \
--assume-role-policy-document "file://aws-load-balancer-controller_iam_role_trust_policy.json"
# IAMポリシー(インラインポリシー)のアタッチ
aws iam put-role-policy \
--role-name "${LB_CTL_IAM_ROLE_NAME}" \
--policy-name loadbalancer \
--policy-document "file://iam_policy.json"
AWS_LOAD_BALANCER_CONTROLLER_IAM_ROLL_ARN=$(aws --output text \
iam get-role --role-name "${LB_CTL_IAM_ROLE_NAME}" --query 'Role.Arn')
echo "
AWS_LOAD_BALANCER_CONTROLLER_IAM_ROLL_ARN = ${AWS_LOAD_BALANCER_CONTROLLER_IAM_ROLL_ARN}
"
テンプレートにIAMロールのARNを設定します。
sed -e "s;AmazonEKSLoadBalancerControllerRoleARN;${AWS_LOAD_BALANCER_CONTROLLER_IAM_ROLL_ARN};g" \
src/AWSLoadBalancerController/aws-load-balancer-controller-service-account.yaml_template > aws-load-balancer-controller-service-account.yaml
#確認します
cat aws-load-balancer-controller-service-account.yaml
kubectl apply -f aws-load-balancer-controller-service-account.yaml
下記コマンドで登録されていることを確認します。
kubectl -n kube-system get serviceaccount aws-load-balancer-controller
NAME SECRETS AGE
aws-load-balancer-controller 1 74s
curl -Lo cert-manager.yaml https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml
ダウンロードしたマニフェストのDockerイメージのURI(下記部分)をECRに格納したイメージのURIへ書き換えます。
image: "quay.io/jetstack/cert-manager-cainjector:v1.5.4"
image: "quay.io/jetstack/cert-manager-controller:v1.5.4"
image: "quay.io/jetstack/cert-manager-webhook:v1.5.4"
- ECRレポジトリのURI取得 取得したURIをメモ帳などに控えておきます。
CERT_MGR_CAIN_REPO_URL=$(aws --output text cloudformation describe-stacks \
--stack-name EksPoc-CertManagerCainjectorEcr \
--query 'Stacks[].Outputs[?OutputKey==`EcrRepositoryUri`].[OutputValue]')
CERT_MGR_CONT_REPO_URL=$(aws --output text cloudformation describe-stacks \
--stack-name EksPoc-CertManagerControllerEcr \
--query 'Stacks[].Outputs[?OutputKey==`EcrRepositoryUri`].[OutputValue]')
CERT_MGR_WEBH_REPO_URL=$(aws --output text cloudformation describe-stacks \
--stack-name EksPoc-CertManagerWebhookEcr \
--query 'Stacks[].Outputs[?OutputKey==`EcrRepositoryUri`].[OutputValue]')
echo "
CERT_MGR_CAIN_REPO_URL = ${CERT_MGR_CAIN_REPO_URL}
CERT_MGR_CONT_REPO_URL = ${CERT_MGR_CONT_REPO_URL}
CERT_MGR_WEBH_REPO_URL = ${CERT_MGR_WEBH_REPO_URL}
"
- マニフェストの編集
Dockerイメージを指定している3箇所(
image: "quay.io/jetstack/cert-manager-xxxxxx
部分)をECRに格納したイメージのURI:latest
に変更する。
vi cert-manager.yaml
編集後のimage:
部分の例。
image: "999999999999.dkr.ecr.ap-northeast-1.amazonaws.com/cert-manager-cainjector-repo:latest"
image: "999999999999.dkr.ecr.ap-northeast-1.amazonaws.com/cert-manager-controller-repo:latest"
image: "999999999999.dkr.ecr.ap-northeast-1.amazonaws.com/cert-manager-webhook-repo:latest"
kubectl apply \
--validate=false \
-f ./cert-manager.yaml
状態を確認します。READYが1/1
ならpodが正常に起動しておりOKです。
kubectl -n cert-manager get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
cert-manager 1/1 1 1 55s
cert-manager-cainjector 1/1 1 1 55s
cert-manager-webhook 1/1 1 1 55s
(1)-(b)で確認したAWS Load Balancer ControllerバージョンのYAML定義ファイルを取得します。
# v2_4_4_full.yamlの場合
curl -Lo v2_4_4_full.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.4.4/v2_4_4_full.yaml
curl -Lo v2_4_4_ingclass.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.4.4/v2_4_4_ingclass.yaml
- Cluster
- image変更
- arg変更
取得したクラスター名とLoadBalancerのECRのURIを控えておきます。
# EKSクラスター情報取得
EKS_CLUSTER_NAME=$(aws --output text cloudformation \
describe-stacks --stack-name EksPoc-EksControlPlane \
--query 'Stacks[].Outputs[?OutputKey==`ClusterName`].[OutputValue]' )
LBCTL_REPO_URL=$(aws --output text cloudformation describe-stacks \
--stack-name EksPoc-AwsLoadBalancerControllerEcr \
--query 'Stacks[].Outputs[?OutputKey==`EcrRepositoryUri`].[OutputValue]')
VPCID=$(aws --output text cloudformation describe-stacks \
--stack-name EksPoc-VPC \
--query 'Stacks[].Outputs[?OutputKey==`VpcId`].[OutputValue]')
REGION=$(aws configure get region)
echo "
EKS_CLUSTER_NAME = ${EKS_CLUSTER_NAME}
LBCTL_REPO_URL = ${LBCTL_REPO_URL}
VPCID = ${VPCID}
REGION = ${REGION}
"
取得したマニフェストの以下の部分を修正します
- 必須項目
- クラスター名変更:
--cluster-name=your-cluster-name
のyour-cluster-name
を変更します
- クラスター名変更:
- EC2インスタンスのIMDSへのアクセスが制限されているまたはFargate利用時
- 引数にVPC ID追加:
--aws-vpc-id=vpc-xxx
- リージョン追加:
--aws-region=region-code
- 引数にVPC ID追加:
- Privateクラスター固有の追加(NATGW等によるインターネット接続不可時)
- shield/waf無効化の追加:
--enable-shield=false
,--enable-waf=false
,--enable-wafv2=false
- Dockeイメージパス変更:
image:
をECRにPUSHしたイメージに変更
- shield/waf無効化の追加:
以下に変更例を示します。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/name: aws-load-balancer-controller
name: aws-load-balancer-controller
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: controller
app.kubernetes.io/name: aws-load-balancer-controller
template:
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/name: aws-load-balancer-controller
spec:
containers:
- args:
- --cluster-name=your-cluster-name #<<== クラスター名を変更
- --ingress-class=alb
- --aws-vpc-id=vpc-xxxxxxxx #<== 取得したVPC IDを入れて追加
- --aws-region=region-code #<== 取得したリージョンコードを入れて追加
- --enable-shield=false #<== 追加
- --enable-waf=false #<== 追加
- --enable-wafv2=false #<== 追加
image: amazon/aws-alb-ingress-controller:v2.4.4 #<<== ECRのイメージのパス "ECRURI:latest"に変更する
livenessProbe:
failureThreshold: 2
また以下の部分を削除します。(前のステップで追加された IAM ロールを持つアノテーションが、コントローラーがデプロイされる際に上書きされるのを防ぐため)
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/name: aws-load-balancer-controller
name: aws-load-balancer-controller
namespace: kube-system
---
# マニフェストの適用
# kubectl apply -f ファイル名
# 以下はv2_4_4_full.yamlファイルの場合
kubectl apply -f v2_4_4_full.yaml
kubectl apply -f v2_4_4_ingclass.yaml
状態を確認します。
kubectl get deployment -n kube-system aws-load-balancer-controller
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 1/1 1 1 3m11s
ALBを配置するPublic SubnetをAWS Load Balancer Controllerが検知できるようにするため、Public Subnetに以下のタグを追加します。
- 追加するタグ
- key:
kubernetes.io/role/elb
- value:
1
- key:
PUBSUB1ID=$(aws --output text cloudformation describe-stacks \
--stack-name EksPoc-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PublicSubnet1Id`].[OutputValue]')
PUBSUB2ID=$(aws --output text cloudformation describe-stacks \
--stack-name EksPoc-VPC \
--query 'Stacks[].Outputs[?OutputKey==`PublicSubnet2Id`].[OutputValue]')
echo "
PUBSUB1ID = ${PUBSUB1ID}
PUBSUB2ID = ${PUBSUB2ID}
"
aws ec2 create-tags --resources ${PUBSUB1ID} ${PUBSUB2ID} --tags 'Key=kubernetes.io/role/elb,Value=1'
以下のようにIngress(ALB)、NodePortのサービス、とhttpdのPodで構成するサンプルを稼働させます。
ハンズオン(その2)までの定義がある場合はまず削除します。
kubectl delete -f k8s_define/httpd-service.yaml
kubectl delete -f httpd-deployment.yaml
REPO_URL=$(aws --output text cloudformation \
describe-stacks --stack-name EksPoc-Ecr \
--query 'Stacks[].Outputs[?OutputKey==`EcrRepositoryUri`].[OutputValue]' )
echo "
REPO_URL = ${REPO_URL}
"
# Deployment定義ファイルの作成
# 環境固有となるECRレポジトリURL情報をDeploymentに設定します。
sed -e "s;REPO_URL;${REPO_URL};" k8s_define/httpd-ingress.yaml.template > httpd-ingress.yaml
cat httpd-ingress.yaml
kubectl apply -f httpd-ingress.yaml
状態を確認します。
kubectl get cm,deployment,pod,svc,ing -o wide
NAME DATA AGE
configmap/kube-root-ca.crt 1 2d3h
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/httpd-deployment 2/2 2 2 10m httpd 616605178605.dkr.ecr.ap-northeast-1.amazonaws.com/ekspoc-repo:latest app.kubernetes.io/name=httpd-pod
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/httpd-deployment-ff96f4749-7fgcl 1/1 Running 0 10m 10.1.154.230 ip-10-1-147-224.ap-northeast-1.compute.internal <none> <none>
pod/httpd-deployment-ff96f4749-m5b6r 1/1 Running 0 10m 10.1.46.57 ip-10-1-60-36.ap-northeast-1.compute.internal <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/httpd-service NodePort 172.20.192.129 <none> 80:32679/TCP 10m app.kubernetes.io/name=httpd-pod
service/kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 2d3h <none>
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/httpd-ingress alb * 80 83s
マネージメントコンソールなどで、ALBのURLを確認し、ブラウザやcurlコマンドでhttp://ALBのDNS
でアクセス可能か確認します。
接続できない場合は以下で原因を特定します。
- AWS Load Balancer Controllerを調査する
kubectl logs -n kube-system deployment.apps/aws-load-balancer-controller
- k8sのDeployment/service/ingressの調査方法 こちらを参考にします https://aws.amazon.com/jp/premiumsupport/knowledge-center/eks-resolve-failed-health-check-alb-nlb/