詳細検索

AWS CodePipeline + EKS アクション:これまでで最も簡単なコンテナ展開方法!

アバター
著者: Jatin Mehrotra

AWS CodePipeline + EKS アクション:これまでで最も簡単なコンテナ展開方法!
Englishから翻訳 • 原文を読む

Amazon Web Services(AWS)CodePipelineチームは、開発者やDevOpsエンジニアの運用オーバーヘッドを簡素化し、EKSクラスターに直接デプロイできるCodePipelineアクションを導入することで、EKSへのデプロイプロセスを効率化しました。

なぜそれがあなたにとって重要なのですか?

以前はDevOpsアプローチでEKSにリソースをデプロイする際、コードビルドプロジェクトやeks、kubectl、helmコマンド、その他の厄介なshellコマンドの管理をしなければならず、それでも一度で完璧にはなりませんでした。

今日これを試してみたので、EKSのデプロイメントパイプラインを100%簡素化する方法をお見せします。コードビルドはやめて、複雑なプロセスやスクリプト、コマンドをすべて取り除くことができます!!

建築

前提条件

  • EKSクラスタとパブリックエンドポイント。
  • deployment.yamlファイルのようなKubernetesリソース
  • 望むならチャートの舵取りも可能です。

注:このアップデートをEKSプライベートエンドポイントで試したい場合は、AWS Hero Arshad Zackeriyaによるこのブログをご覧ください。

どちらを好んでお好みでも、このリポジトリにhelm chartとdeployment.yamlの両方を提供しています。

舞台裏

Kubernetes マニフェストファイルの場合

 

  • このアクションはeks clusterにログインし、kubeconfigコンテキストを設定します
  • kubectlをインストール
  • Kubernetes マニフェストを適用
  • 展開リソース

舵取り図の場合

codepipeline bts with helm chart
  • このアクションはeks clusterにログインし、kubeconfigコンテキストを設定します
  • インスタルのヘルム
  • インスタルヘルムチャート

EKSクラスターを作成

クラスタはパブリックまたはプライベート(プライベートVPC内のものも含む)にできます。パイプラインは追加のインフラなしで、コンテナアプリケーションをデプロイするためにプライベートネットワークへの接続を自動的に確立します。

eks.tf

# eks クラスター

モジュール「eks」 {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.31"

cluster_name = local.cluster_name
cluster_version = 「1.32」
cluster_endpoint_public_access = 真


vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets

cluster_compute_config = {
enabled = 真
node_pools = [「汎用」]
  }

# クラスターアクセスエントリー
# 管理者として現在の発信者IDを追加する
enable_cluster_creator_admin_permissions = 真


タグ = {
環境 = 「開発」
Terraform = 「真」
  }
}

vpc.tf

モジュール「VPC」 {
source = "terraform-aws-modules/vpc/aws"
version = "5.19.0"

name = "codepipeline-eks-action"
cidr = "10.0.0.0/16"

azs = ["us-east-1a", "us-east-1b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.4.0/24", "10.0.5.0/24"]

enable_nat_gateway = 真
single_nat_gateway = 真
one_nat_gateway_per_az = 偽

enable_dns_hostnames = 真
enable_dns_support = 真

public_subnet_tags = {
「kubernetes.io/role/elb」=「1」
  }
private_subnet_tags = {
「kubernetes.io/role/internal-elb」=「1」
  }

タグ = {
環境 = 「テラフォーミング・プレイグラウンド」
  }
}

ポッド_identity.tf

data "aws_iam_policy_document" "allow_pod_identity" {
文{
効果=「許可」

プリンシパル {
type = 「サービス」
識別子 = ["pods.eks.amazonaws.com"]
    }

行動 = [
「sts:AssumeRole」
「sts:TagSession」
    ]
  }
}

リソース「aws_iam_role」「read_ecr」{
name = "read-ecr-role"
assume_role_policy = data.aws_iam_policy_document.allow_pod_identity.json
}

リソース「aws_iam_role_policy_attachment」「read_ecr」{
role = aws_iam_role.read_ecr.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
}

リソース「aws_eks_pod_identity_association」「read_ecr」{
cluster_name = local.cluster_name
名前空間 = 「デフォルト」
service_account = 「ecr-sa」
role_arn = aws_iam_role.read_ecr.arn
}

 

注:私はpod iditsとecrリポジトリ権限を使って、deployment.yaml用のecrイメージを取得しています。

クラスタの完全なコードが欲しい場合は、このリポジトリに従うことができます

EKSデプロイメントアクションでパイプラインを作成

ケース1:kubectl構成が使われる場合。

私はソースをGitHubとしてコードスタート接続を使っており、コードはこのリポジトリに存在していますcodepipeline helm config

  • クラスターを選択する
  • deployment.yamlファイル(私の場合はdeployment.yamlファイル)のパスを提供します。

ケース2:ヘルムチャートの使用時

codepipeline helm config
  • リリース名を入力してください
  • 操舵チャート(私の場合はテストチャート)を入力してください。

重要な一歩

注意:パイプラインが作成されたら、エラーを避けるためにパイプラインのサービスロールを編集するか、既存の役割を更新し、以下の権限を追加する必要があります。

{
「声明」: [
        {
「アクション」:[
「iam:PassRole」
            ],
「リソース」:「*」
「効果」:「許可」
「条件」:{
「StringEqualsIfExists」: {
「iam:PassedToService」: [
「cloudformation.amazonaws.com」、
「elasticbeanstalk.amazonaws.com」、
「ec2.amazonaws.com」、
「ecs-tasks.amazonaws.com」
                    ]
                }
            }
        },
        {
「アクション」:[
「codecommit:CancelUploadArchive」
「codecommit:GetBranch」
「codecommit:GetCommit」
「codecommit:GetRepository」
「codecommit:GetUploadArchiveStatus」
「codecommit:UploadArchive」
            ],
「リソース」:「*」
「効果」:「許可」
        },
        {
「アクション」:[
「codedeploy:CreateDeployment」
「codedeploy:GetApplication」
「codedeploy:GetApplicationRevision」
「codedeploy:GetDeployment」、
「codedeploy:GetDeploymentConfig」
「codedeploy:RegisterApplicationRevision」
            ],
「リソース」:「*」
「効果」:「許可」
        },
        {
「アクション」:[
「codestar-connections:UseConnection」
            ],
「リソース」:「*」
「効果」:「許可」
        },
        {
「アクション」:[
「elasticbeanstalk:*」
"ec2:*",
「elasticloadbalancing:*」
「autoscaling:*」
「cloudwatch:*」
「s3:*」
「sns:*」
「cloudformation:*」
「rds:*」、
「sqs:*」
「ecs:*」
            ],
「リソース」:「*」
「効果」:「許可」
        },
        {
「アクション」:[
"lambda:InvokeFunction",
"lambda:ListFunctions"
            ],
「リソース」:「*」
「効果」:「許可」
        },
        {
「アクション」:[
「opsworks:CreateDeployment」
「opsworks:DescribeApps」
「opsworks:DescribeCommands」
「opsworks:DescribeDeployments」
「opsworks:DescribeInstances」
「opsworks:DescribeStacks」
「opsworks:UpdateApp」
「opsworks:UpdateStack」
            ],
「リソース」:「*」
「効果」:「許可」
        },
        {
「アクション」:[
"cloudformation:CreateStack",
「cloudformation:DeleteStack」
「cloudformation:DescribeStacks」
「cloudformation:UpdateStack」
"cloudformation:CreateChangeSet",
「cloudformation:DeleteChangeSet」
「cloudformation:DescribeChangeSet」
「cloudformation:ExecuteChangeSet」
"cloudformation:SetStackPolicy",
「cloudformation:ValidateTemplate」
            ],
「リソース」:「*」
「効果」:「許可」
        },
        {
「アクション」:[
「codebuild:BatchGetBuilds」
「codebuild:StartBuild」
「codebuild:BatchGetBuildBatches」
「codebuild:StartBuildBatch」
            ],
「リソース」:「*」
「効果」:「許可」
        },
        {
「効果」:「許可」
「アクション」:[
「devicefarm:ListProjects」
「devicefarm:ListDevicePools」
「devicefarm:GetRun」
「devicefarm:GetUpload」
「devicefarm:CreateUpload」
「devicefarm:ScheduleRun」
            ],
「リソース」:「*」
        },
        {
「効果」:「許可」
「アクション」:[
「servicecatalog:ListProvisioningArtifacts」
「servicecatalog:CreateProvisioningArtifact」
「servicecatalog:DescribeProvisioningArtifact」
「servicecatalog:DeleteProvisioningArtifact」
「servicecatalog:UpdateProduct」
            ],
「リソース」:「*」
        },
        {
「効果」:「許可」
「アクション」:[
「cloudformation:ValidateTemplate」
            ],
「リソース」:「*」
        },
        {
「効果」:「許可」
「アクション」:[
「ecr:DescribeImages」
            ],
「リソース」:「*」
        },
        {
「効果」:「許可」
「アクション」:[
「states:DescribeExecution」
「states:DescribeStateMachine」
「states:StartExecution」
            ],
「リソース」:「*」
        },
        {
「効果」:「許可」
「アクション」:[
「appconfig:StartDeployment」
「appconfig:StopDeployment」
「appconfig:GetDeployment」
            ],
「リソース」:「*」
        },
        {
「効果」:「許可」
「アクション」:[
「logs:CreateLogGroup」
「logs:CreateLogStream」
「logs:PutLogEvents」
            ],
「リソース」: [
"arn:aws:logs:us-east-1:xxxx:log-group:/aws/codepipeline/eks-deploy-codepipeline",
"arn:aws:logs:us-east-1:xxxxx:log-group:/aws/codepipeline/eks-deploy-codepipeline:log-stream:*"
            ]
        },
        {
「Sid」:「EksClusterPolicy」
「効果」:「許可」
「アクション」:「eks:DescribeCluster」
「リソース」: [
                "*"
            ]
        },
        {
「Sid」:「EksVpcClusterPolicy」
「効果」:「許可」
「アクション」:[
「ec2:DescribeDhcpOptions」
「ec2:DescribeNetworkInterfaces」
"ec2:DescribeRouteTables",
「ec2:DescribeSubnets」
「ec2:DescribeSecurityGroups」
"ec2:DescribeVpcs"
            ],
「リソース」: [
                "*"
            ]
        },
        {
「効果」:「許可」
「アクション」:「ec2:CreateNetworkInterface」
「リソース」:「*」
「条件」:{
「StringEqualsIfExists」: {
「ec2:Subnet」: [
「arn:aws:ec2:us-east-1:292170836962:subnet/subnet-example1」
"arn:aws:ec2:us-east-1:292170836962:subnet/subnet-example2"
                    ]
                }
            }
        },
        {
「効果」:「許可」
「アクション」:「ec2:CreateNetworkInterfacePermission」
「リソース」:「*」
「条件」:{
「ArnEquals」:{
「ec2:Subnet」: [
「arn:aws:ec2:us-east-1:xxxx:subnet/subnet-example1」
「arn:aws:ec2:us-east-1:xxxx:subnet/subnet-example2」
                    ]
                }
            }
        },
        {
「効果」:「許可」
「アクション」:「ec2:DeleteNetworkInterface」
「リソース」:「*」
「条件」:{
「StringEqualsIfExists」: {
「ec2:Subnet」: [
「arn:aws:ec2:us-east-1:xxxxx:subnet/subnet-example1」
「arn:aws:ec2:us-east-1:xxxx:subnet/subnet-example2」
                    ]
                }
            }
        }
    ],
「バージョン」:「2012-10-17」
}

 

  • 上記のコードパイプラインサービスロールのために、AmazonEKSClusterAdminPolicyを使ってeksクラスタ内のアクセスエントリを作成します。

パイプラインを走らせろ

kubectlマニフェストが更新された場合

codepipeline execution

 

(base) jatin.mehrotra@CK0662-001 Codepipeline-eks-deployment-no-github % kubectl get pods
名前準備完了 ステータス 再始動 年齢
hello-k8s-74fd98b69b-2pwrv 1/1 ランニング 0 2分37秒
hello-k8s-74fd98b69b-g876f 1/1 ランニング 0 2分37秒
hello-k8s-74fd98b69b-phs77 1/1 ランニング 0 2分37秒

 

ヘルムチャートのマニフェストが更新される場合

codepipeline execution
(base) jatin.mehrotra@CK0662-001 Codepipeline-eks-deployment-no-github % kubectl get pods
名前準備完了 ステータス 再始動 年齢
test-67cbfddc66-2gcvj 1/1 running 0 10m

 

開発者、DevOpsの視点から

  • このアップデートにより、コードビルドプロジェクトや計算環境の管理、複雑なスクリプト、権限、ツールのインストール管理をする必要がなくなりました。
  • 以下は、このアップデート前にCodebuildで使っていたセットアップの画像です。本当に複雑な混乱です。
before this update config
  • これは、ビジネス課題やアプリケーション、監視やスケーリングなどのKubernetes課題に集中したい開発者、DevOpsエンジニア、インフラエンジニアにとって間違いなくゲームチェンジャーです。

これはFluxやArgoCDが採用しているGitOpsアプローチではありませんが、私の見解ではEKSクラスターにとって最良のDevOpsアプローチです。

*私は毎日、Linkedin*やXDevOps、Kubernetes、GenAIに関する素晴らしいAWSの最新情報をシェアしています。ぜひそちらをフォローして、あなたの生活をより楽にします。




Related Articles