TL;DR
Crossplane – это решение, которое следует рассмотреть, если ваша инфраструктура должна обслуживать приложения k8s.
История
Я использую Terraform в течение очень долгого времени. Он прост в использовании и имеет очень большую поддержку сообщества. Однако у каждого решения есть свои недостатки. Terraform – не самое лучшее решение, когда вам приходится работать с k8s.
Моя инфраструктура AWS тесно связана с моими приложениями K8S. Возможно, мне приходится загружать объекты на S3 или хранить данные в RDS. Если вы используете AWS EKS, вы должны быть хорошо знакомы с функцией IRSA (IAM roles for service accounts), которая предоставляет вашим учетным записям служб права доступа к AWS. Затем ваши подсистемы могут ссылаться на эти учетные записи служб и взаимодействовать с API AWS.
Итак, IAM-роли – это вещи AWS, а учетные записи сервисов – это вещи K8S. Вы должны создать как IAM-роли, так и учетные записи сервисов, используя некоторые методы.
Я могу использовать Terraform для создания как ролей IAM, так и учетных записей служб, но это очень неудобно для работы. При развертывании K8s необходимо применять не только учетные записи служб. Как насчет использования Terraform для развертывания всей инфраструктуры AWS и манифестов k8s? ИМО, НЕ ДЕЛАЙТЕ ЭТОГО. Argo CD, Flux CD или любые инструменты GitOps намного лучше, чем Terraform.
Никогда не решайте маленькую проблему за счет другой большой проблемы.
Теперь вернемся к моему вопросу, как я должен интегрировать роли IAM с учетными записями служб? Как насчет того, чтобы сделать наоборот, использовать k8s для предоставления IAM ролей?
И тут мне на глаза попадается Crossplane. Проще говоря, Crossplane – это k8s-стиль Terraform.
Учебник
Сейчас я собираюсь показать вам, как использовать Crossplane.
Необходимые условия
- Вам необходимо иметь привилегии администратора в вашей учетной записи AWS.
- Кластер k8s
1. Определите ваши переменные
Укажите любое значение, которое вам нравится.
EKS_CLUSTER_NAME=""
AWS_REGION=""
AWS_IAM_ROLE_NAME="${EKS_CLUSTER_NAME}-crossplane-controller"
2. Установка Crossplane с помощью штурвальной диаграммы
Все любят рулевые диаграммы 🙂
helm repo add crossplane https://charts.crossplane.io/master/
helm install --create-namespace --namespace crossplane-system crossplane crossplane/crossplane --version 1.9.0-rc.0.9.g243f1f47
3. Установите провайдера AWS
Crossplane может предоставлять инфраструктуру на многих платформах. Допустим, если вы хотите развернуть инфраструктуру на Azure, вы можете установить провайдера Azure.
cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1alpha1
kind: ControllerConfig
metadata:
name: aws-config
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/${AWS_IAM_ROLE_NAME}
spec:
podSecurityContext:
fsGroup: 2000
---
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-aws
spec:
package: crossplane/provider-aws:v0.27.0
controllerConfigRef:
name: aws-config
EOF
4. Создание роли IAM для IRSA
Это снова проблема курицы или яйца. Контроллер Crossplane должен иметь права на предоставление ресурсов AWS. Поэтому нам нужно вручную создать роль IAM.
SERVICE_ACCOUNT_NAME=$(kubectl get providers.pkg.crossplane.io provider-aws -o jsonpath="{.status.currentRevision}")
OIDC_PROVIDER=$(aws eks describe-cluster --name $EKS_CLUSTER_NAME --region $AWS_REGION --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:////")
read -r -d '' TRUST_RELATIONSHIP <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDC_PROVIDER}:sub": "system:serviceaccount:crossplane-system:${SERVICE_ACCOUNT_NAME}"
}
}
}
]
}
EOF
echo "${TRUST_RELATIONSHIP}" > trust.json
aws iam create-role
--role-name "${IAM_ROLE_NAME}"
--assume-role-policy-document file://trust.json
--description "IAM role for Crossplane provider-aws"
aws iam attach-role-policy --role-name "${IAM_ROLE_NAME}" --policy-arn=arn:aws:iam::aws:policy/AdministratorAccess
rm trust.json
cat <<EOF | kubectl apply -f -
apiVersion: aws.crossplane.io/v1beta1
kind: ProviderConfig
metadata:
name: aws-provider
spec:
credentials:
source: InjectedIdentity
EOF
6. Попробуйте
Давайте попробуем что-нибудь развернуть.
apiVersion: iam.aws.crossplane.io/v1beta1
kind: Role
metadata:
name: crossplane-sample-role
annotations:
spec:
deletionPolicy: Delete
forProvider:
description: "A role created by Crossplane"
assumeRolePolicyDocument: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
providerConfigRef:
name: aws-provider
---
apiVersion: iam.aws.crossplane.io/v1beta1
kind: Policy
metadata:
name: crossplane-sample-policy
spec:
deletionPolicy: Delete
forProvider:
name: crossplane-sample-policy
description: A policy created by Crossplane
document: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"eks:DescribeCluster"
],
"Resource": "*"
}
]
}
providerConfigRef:
name: aws-provider
---
apiVersion: iam.aws.crossplane.io/v1beta1
kind: RolePolicyAttachment
metadata:
name: crossplane-sample-role-policy-attachment
spec:
deletionPolicy: Delete
forProvider:
roleNameRef:
name: crossplane-sample-role
policyArnRef:
name: crossplane-sample-policy
providerConfigRef:
name: aws-provider
6. Очистка
Всегда полезно проводить очистку.
helm uninstall crossplane --namespace crossplane-system
kubectl delete ns crossplane-system
kubectl get crd -o name | grep crossplane.io | xargs kubectl delete
aws iam detach-role-policy --role-name ${AWS_IAM_ROLE_NAME} --policy-arn=arn:aws:iam::aws:policy/AdministratorAccess
aws iam delete-role --role-name "${AWS_IAM_ROLE_NAME}"
Обсуждение
Представьте, что вам нужно развернуть приложение, которому требуется ALB, RDS. Теперь вы можете упаковать все эти вещи с помощью k8s manifests. Больше не нужно использовать Terraform и гораздо меньше накладных расходов на управление.
Сделайте еще один шаг вперед, вы можете использовать Crossplane для замены Terraform для обеспечения любой инфраструктуры. Crossplane позволяет вам писать модули Terraform версии Crossplane, которые называются Configurations.
Так рекомендую ли я по-прежнему использовать Terraform? Да, рекомендую. Разработчикам может быть не очень удобно работать с k8s, а написание Terraform для них – это как написание простой программы. Кроме того, Terraform поддерживается большим сообществом, новые функции будут поддерживаться быстрее, а исправления ошибок – раньше.
Заключение
Короче говоря, если вы собираетесь развернуть некоторую инфраструктуру, предназначенную только для развертывания k8s, например, балансировщики нагрузки, IAM Roles для IRSA. Рассмотрите Crossplane.
Если вы собираетесь развернуть какую-то общую инфраструктуру или она не имеет отношения к вашим развертываниям k8s, например, сеть, бастионы EC2. Используйте Terraform.