Crossplane лучше, чем Terraform в мире K8S


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.

Оцените статью
Procodings.ru
Добавить комментарий