AWS EKSにArgo CDをインストールして、かんたんDevOps環境を作ってみます。
必要なもの
- AWSアカウント
- Route 53で管理されている実在するドメイン
- eksctl
- Helm
- kubectl
- argocd(CLI)
AWSアカウントは事前に用意しておいてください。
eksctl、Helm、kubectl、argocdは公式ドキュメントにインストール方法が記載されています。以下のドキュメントを参考にインストールをお願いします。 私は全てHomebrewからインストールしました。
EKS
以下のテキストをcluster.yaml
というファイルに保存してください。これはEKSクラスターを作るためのコードで、test
という名前のEKSクラスターが起動してきます。
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: test region: ap-northeast-1 version: '1.22' iam: withOIDC: true serviceAccounts: - metadata: name: aws-load-balancer-controller namespace: kube-system wellKnownPolicies: awsLoadBalancerController: true - metadata: name: external-dns namespace: kube-system wellKnownPolicies: externalDNS: true vpc: cidr: 10.21.0.0/16 nat: gateway: Single addons: - name: vpc-cni - name: coredns - name: kube-proxy managedNodeGroups: - name: ng-1 instanceType: t3.medium desiredCapacity: 1 minSize: 1 maxSize: 1 volumeSize: 20 privateNetworking: true iam: attachPolicyARNs: - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
EKSを起動します。
eksctl create cluster -f cluster.yaml
以下のコマンドを実行し、Server Version
が取得できれば成功です。
kubectl version --short
Argo CD
Argo CDをHelmからインストールするので、HelmにArgo CDのリポジトリを追加します。
helm repo add argo https://argoproj.github.io/argo-helm
Argo CDをargocd
というネームスペースにインストールします。
helm upgrade --install argocd argo/argo-cd --namespace argocd --create-namespace
ポートフォワードで接続できるようにします。後ほどALB経由で接続できるようにするので、これは一時的なものです。
kubectl port-forward service/argocd-server -n argocd 8080:443
Argo CDのadminパスワードを取得します。
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
argocdコマンドでログインします。Username
にはadmin
、Password
には先ほど取得したadminパスワード
を入力してください。
argocd login localhost:8080 --insecure
http://localhost:8080 にアクセスするとWEB UIからログインすることもできます。
AWS Load Balancer Controller
AWS Load Balancer Controllerは、Kubernetesリソースを介して動的にALBをプロビジョニングします。
AWS Load Balancer Controllerを使用するにはTargetGroupBinding
というカスタムリソースが必要になります。以下のコマンドで作成してください。
kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"
Argo CDにアプリケーションとして追加します。
argocd app create aws-load-balancer-controller \ --repo https://aws.github.io/eks-charts \ --helm-chart aws-load-balancer-controller \ --revision 1.4.5 \ --dest-namespace kube-system \ --dest-server https://kubernetes.default.svc \ --helm-set clusterName=test \ --helm-set serviceAccount.create=false \ --helm-set serviceAccount.name=aws-load-balancer-controller
このままではアプリケーションが追加されただけで、まだデプロイされていません。デプロイします。
argocd app sync aws-load-balancer-controller
ExternalDNS
ExternalDNSは、Kubernetesリソースを介して動的にRoute 53にDNSレコードを管理します。
Argo CDにアプリケーションとして追加します。
{{DOMAIN}}
はRoute 53で管理している実在のドメインにしてください。
domain={{DOMAIN}} txtownerid=test argocd app create external-dns \ --repo https://kubernetes-sigs.github.io/external-dns/ \ --helm-chart external-dns \ --revision 1.11.0 \ --dest-namespace kube-system \ --dest-server https://kubernetes.default.svc \ --helm-set "domainFilters[0]=$domain" \ --helm-set "txtOwnerId=$txtownerid" \ --helm-set policy=sync \ --helm-set serviceAccount.create=false \ --helm-set serviceAccount.name=external-dns
デプロイします。
argocd app sync external-dns
Argo CDをALB経由でアクセスできるようにする
ALBでgRPCを使うにはHTTPS接続が必須になります。HTTPSを使えるようにACMでSSL証明書を発行します。
{{SUBDOMAIN}}
はACMでSSL証明書を発行する対象のサブドメインにしてください。
domain={{SUBDOMAIN}} arn=$(aws acm request-certificate --domain-name $domain --validation-method DNS --query CertificateArn --output text) sleep 5 read name type value < <(aws acm describe-certificate --certificate-arn $arn --query 'Certificate.DomainValidationOptions[0].ResourceRecord.[Name,Type,Value]' --output text) hosted_zone_id=$(aws route53 list-hosted-zones --query 'HostedZones[].Id' --output text | cut -d/ -f3) cat <<EOF | aws route53 change-resource-record-sets --hosted-zone-id $hosted_zone_id --change-batch file:///dev/stdin { "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "$name", "Type": "$type", "TTL": 300, "ResourceRecords": [ { "Value": "$value" } ] } } ] } EOF
Argo CDをデフォルトのままインストールするとIngressが無効の状態になっていますが、設定としては存在しています。以下のコマンドで有効化してください。
domain={{SUBDOMAIN}} arn=$(aws acm list-certificates --query 'CertificateSummaryList[?DomainName==`'$domain'`].CertificateArn' --output text) helm upgrade -i argocd argo/argo-cd \ -n argocd --create-namespace \ --set 'server.service.type=NodePort' \ --set 'server.ingress.enabled=true' \ --set 'server.ingressGrpc.enabled=true' \ --set 'server.ingressGrpc.isAWSALB=true' \ --set "server.ingress.hosts[0]=$domain" \ --set "server.ingress.annotations.external-dns\.alpha\.kubernetes\.io/hostname=$domain" \ --set 'server.ingress.ingressClassName=alb' \ --set 'server.ingress.annotations.alb\.ingress\.kubernetes\.io/scheme=internet-facing' \ --set "server.ingress.annotations.alb\.ingress\.kubernetes\.io/certificate-arn=$arn" \ --set 'server.extraArgs[0]=--insecure'
AWSコンソールからALBとRoute 53を確認してください。先ほどインストールしたAWS Load Balancer ControllerがALBを起動し、ExternalDNSがRoute 53にレコードを追加してくれていれば成功です。
続いて、argocdコマンドのログイン先を変更します。今はポートフォワードのlocalhost:8080
を見ていると思いますが、ALBを追加したことにいより、LB経由でアクセスできるようになりました。
argocd login {{SUBDOMAIN}} --grpc-web
ブラウザでhttps://{{SUBDOMAIN}}/
にアクセスするとWEB UIから操作することも可能です。
片付け
片付けをするには少し順序があります。これはArgo CDで管理しているAWS Load Balancer ControllerとExternalDNSがArgo CDのLBとドメインを管理しており、かつ、Argo CDのログイン先がALBの方に向いているからです。Argo CDを先にアンインストールするとAWS Load Balancer ControllerとExternalDNSが残ってしまいますし、アプリの方を先にアンインストールするとargocdコマンドが使えなくなってしまいます。
以下の手順に沿って、片付けを進めてください。
IngressをOFFにしてALBとサブドメインを解放します。
helm upgrade --install argocd argo/argo-cd --namespace argocd --create-namespace --set 'server.service.type=NodePort' --set 'server.ingress.enabled=false'
ALBとドメインが削除されたのを確認してください。どちらもなくなっていればargocdコマンドが使えなくなっているので、ポートフォワードに切り替えます。
kubectl port-forward service/argocd-server -n argocd 8080:443
argocdコマンドのログイン先も変更します。
argocd login --insecure localhost:8080
アプリを削除します。
argocd app delete aws-load-balancer-controller argocd app delete external-dns
Argo CDをアンインストールします。
helm uninstall --namespace argocd argocd
EKSを削除します。
eksctl delete cluster -f cluster.yaml
Route 53からACMのドメイン認証で追加したCNAMEを削除します。
arn=$(aws acm list-certificates --query 'CertificateSummaryList[?DomainName==`'argocd.ttanaka.virtualtech.jp'`].CertificateArn' --output text) read name type value < <(aws acm describe-certificate --certificate-arn $arn --query 'Certificate.DomainValidationOptions[0].ResourceRecord.[Name,Type,Value]' --output text) hosted_zone_id=$(aws route53 list-hosted-zones --query 'HostedZones[].Id' --output text | cut -d/ -f3) cat <<EOF | aws route53 change-resource-record-sets --hosted-zone-id $hosted_zone_id --change-batch file:///dev/stdin { "Changes": [ { "Action": "DELETE", "ResourceRecordSet": { "Name": "$name", "Type": "$type", "TTL": 300, "ResourceRecords": [ { "Value": "$value" } ] } } ] } EOF
ACMからSSL証明書を削除します。
arn=$(aws acm list-certificates --query 'CertificateSummaryList[?DomainName==`'argocd.ttanaka.virtualtech.jp'`].CertificateArn' --output text) aws acm delete-certificate --certificate-arn $arn
以上で片付けは完了です。