Argo CDでGitLab SSOを利用する
Argo CDは自前でユーザ管理の仕組みを持たず*1,外部のIdentity Providerに認証を移譲するという設計思想になっています.Argo CDのHelm chartにはDexがバンドルされており,様々なIdentity Providerと連携させることが可能です.本稿では,Argo CDでGitLab SSOを利用する方法を紹介します.
Argo CDはOpenID Connectに対応しています.また,GitLabは自身がOpenID Connect Identity Providerになることが可能です.しかし,Argo CDが必要とする groups
claimをGitLabがサポートしていないため,直接連携させることはできません.Argo CDのoidc configでGitLabを指定すると,GitLabで以下のエラーが表示されます(argo-cd#1195).
The requested scope is invalid, unknown, or malformed
代わりに,DexのGitLab connectorを利用することで,Argo CD→Dex→GitLabの流れで連携が可能です.
GitLabの設定
admin area→Applicationsもしくはユーザの設定→Applicationsから,新しいアプリケーションを作成します.以下のように設定します.
- Name: 任意
- Redirect URI:
https://argocd.example.com/api/dex/callback
- Scopes:
read_user
,openid
Dex GitLab connectorではOAuth2を利用するとの記述がありますが,実際はOpenID Connectが利用されるようです.openid
スコープを許可しないとエラーになります.
Argo CDの設定
Helmfileを利用する場合は以下のように設定します.
repositories: - name: argo url: https://argoproj.github.io/argo-helm releases: - name: argocd namespace: argocd chart: argo/argo-cd values: - config: url: https://argocd.example.com dexConfig: connectors: # GitLab SSO - type: gitlab id: gitlab name: GitLab config: baseURL: https://gitlab.com clientID: xxxxxxxx clientSecret: xxxxxxxx rbac: # assign the admin role to everyone policyDefault: role:admin
上記ではすべてのユーザにadminロールを割り当てていますが,GitLabグループに応じてアクセス制御を行うとよいでしょう.
動作確認
下図のように LOGIN VIA GITLAB ボタンが表示されるはずです.ボタンをクリックし,GitLabの同意画面が表示された後,ログインできれば成功です.
See Also
- Argo CD and Dex
- GitLab SSO
*1:ローカルでは組み込みのadminユーザのみ利用できます.
AWS Cluster AutoscalerをTerraformとHelmfileでデプロイする
Cluster Autoscalerを利用すると,CPUやメモリの要求量に応じてノード数を自動的に増減させることが可能です.
本稿では,Amazon EKSで以下を利用する方法を紹介します.
Cluster AutoscalerのPodにIAMロールを割り当てるため,あらかじめkube2iamもしくはkiamをデプロイしておく必要があります.詳しくは下記を参照してください.
(2020/9/23 追記)Cluster AutoscalerのHelm chartはgithub.com/kubernetes/autoscalerに移動しました。また、権限の割り当てはIAM Roles for Service Accountsが推奨されています。
Worker Auto Scaling Groupの修正
Auto Scaling GroupにAuto Discovery用のタグを追加します.
terraform-aws-eks module を利用している場合は以下のように autoscaling_enabled = true
を追加すればよいです.詳しくはモジュールの Autoscaling を参照してください.
worker_groups_launch_template_mixed = [ { # 中略 autoscaling_enabled = true asg_min_size = 1 asg_max_size = 8 asg_desired_capacity = 4 }, ]
kopsを利用している場合は kops edit ig nodes
で以下のようにノード用のタグを追加します.
cloudLabels: k8s.io/cluster-autoscaler/enabled: 1 k8s.io/cluster-autoscaler/CLUSTER_NAME: 1
IAM Roleの作成
Cluster AutoscalerがAuto Scaling Groupを取得したり変更したりするためのIAM Roleを作成します.必要なIAMポリシーは cluster-autoscaler/cloudprovider/aws に記載されています.
# IAM role for Cluster Autoscaler resource "aws_iam_role" "cluster_autoscaler" { name = "${var.cluster_name}-cluster-autoscaler" assume_role_policy = data.aws_iam_policy_document.kube2iam_assume_role.json } resource "aws_iam_role_policy" "cluster_autoscaler" { role = aws_iam_role.cluster_autoscaler.name policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "autoscaling:DescribeAutoScalingGroups", "autoscaling:DescribeAutoScalingInstances", "autoscaling:DescribeLaunchConfigurations", "autoscaling:DescribeTags", "autoscaling:SetDesiredCapacity", "autoscaling:TerminateInstanceInAutoScalingGroup" ], "Resource": "*" } ] } EOF } data "aws_iam_policy_document" "kube2iam_assume_role" { statement { actions = ["sts:AssumeRole"] principals { type = "Service" identifiers = ["ec2.amazonaws.com"] } principals { type = "AWS" identifiers = [module.eks.worker_iam_role_arn] } } }
Helm chartのデプロイ
stable/cluster-autoscaler chart をデプロイします.
releases: # https://github.com/helm/charts/tree/master/stable/cluster-autoscaler - name: cluster-autoscaler namespace: kube-system chart: stable/cluster-autoscaler values: - cloudProvider: aws awsRegion: ap-northeast-1 autoDiscovery: clusterName: {{ .Environment.Values.clusterName }} rbac: create: true podAnnotations: # IAM role for Cluster Autoscaler iam.amazonaws.com/role: {{ .Environment.Values.clusterName }}-cluster-autoscaler # https://github.com/helm/charts/tree/master/stable/metrics-server - name: metrics-server namespace: kube-system chart: stable/metrics-server environments: default: values: - clusterName: CLUSTER_NAME
Cluster Autoscalerのログにエラーが出ていないことを確認します.IAMロールやIAMポリシーが不適切な場合はエラーが出ます.
スケールアップの動作確認
ここでは以下のように echoserver をデプロイします.
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: echoserver namespace: echoserver spec: replicas: 1 template: metadata: labels: app: echoserver spec: containers: - image: gcr.io/google_containers/echoserver:1.10 name: echoserver ports: - containerPort: 8080
ここで,以下のようにCPU requestを設定します.1ノード2コアの場合は1500mにするとよいでしょう.要求値が大きすぎると,Cluster Autoscalerはノードを追加してもスケジュール不可能と判断してしまいます.
spec: template: spec: containers: - image: gcr.io/google_containers/echoserver:1.10 name: echoserver ports: - containerPort: 8080 resources: requests: cpu: 1500m
Cluster Autoscalerのログを確認します.以下のように Upcoming 1 nodes
と表示されると成功です.同時に,Auto Scaling GroupのDesired Capacityが書き換わっていることを確認します.しばらく経つと,ノードが増えてPodがスケジュールされるはずです.
I0927 11:50:35.158353 1 scale_up.go:263] Pod echoserver/echoserver-74fd7d865f-vkzqb is unschedulable I0927 11:50:35.158391 1 scale_up.go:300] Upcoming 0 nodes I0927 11:50:35.158521 1 scale_up.go:423] Best option to resize: ASG_NAME I0927 11:50:35.158540 1 scale_up.go:427] Estimated 1 nodes needed in ASG_NAME I0927 11:50:35.158556 1 scale_up.go:529] Final scale-up plan: [{ASG_NAME 4->5 (max: 8)}] I0927 11:50:35.158572 1 scale_up.go:694] Scale-up: setting group ASG_NAME size to 5 I0927 11:50:45.523906 1 scale_up.go:263] Pod echoserver/echoserver-74fd7d865f-vkzqb is unschedulable I0927 11:50:45.524041 1 scale_up.go:300] Upcoming 1 nodes I0927 11:52:36.144782 1 clusterstate.go:194] Scale up in group ASG_NAME finished successfully in 2m0.794268739s
スケールダウンの動作確認
前のセクションで設定したCPU requestを削除します.
デフォルトでは,Cluster Autoscalerがノードが必要ないと判断してから10分後に実際にノードを削除します(詳しくは How does scale-down work? を参照してください).Cluster Autoscalerのログを確認し,以下のように Terminating EC2 instance
が表示されると成功です.
I0927 11:57:07.790306 1 scale_down.go:407] Node ip-172-19-67-52.ap-northeast-1.compute.internal - utilization 0.055000 I0927 11:57:07.790634 1 static_autoscaler.go:359] ip-172-19-67-52.ap-northeast-1.compute.internal is unneeded since 2019-09-27 11:57:07.773690521 +0000 UTC m=+2997.491422805 duration 0s I0927 12:07:12.161679 1 static_autoscaler.go:359] ip-172-19-67-52.ap-northeast-1.compute.internal is unneeded since 2019-09-27 11:57:07.773690521 +0000 UTC m=+2997.491422805 duration 10m4.367847963s I0927 12:07:12.161767 1 scale_down.go:600] ip-172-19-67-52.ap-northeast-1.compute.internal was unneeded for 10m4.367847963s I0927 12:07:12.161868 1 scale_down.go:819] Scale-down: removing empty node ip-172-19-67-52.ap-northeast-1.compute.internal I0927 12:07:12.176857 1 delete.go:64] Successfully added toBeDeletedTaint on node ip-172-19-67-52.ap-northeast-1.compute.internal I0927 12:07:12.391908 1 auto_scaling_groups.go:269] Terminating EC2 instance: i-066bc60549f083e38
最後に,Auto Scaling Groupのdesired capacityが元に戻っていることを確認します.
GitLab RunnerとkanikoでDockerイメージをビルドする
DockerやKubernetesでGitLab Runnerを実行する場合,GitLab RunnerでDockerイメージをビルドするにはDocker in Dockerの特権モードを構成する必要があります.kanikoを利用すると,特権モードを使わずにDockerイメージをビルドできます.
本稿では,GitLab Runner上でkanikoを利用してDockerイメージをビルドし,Amazon ECRにDockerイメージをpushするまでの流れを紹介します. https://docs.gitlab.com/ee/ci/docker/using_kaniko.html で説明されている内容を元にしています.
ここでは,以下の前提とします.
- Kubernetes上のPodにIAM Roleを割り当てることが可能なこと(kube2iam等を利用)
- Kubernetes上にGitLab Runnerがデプロイされていること
- GitLabのリポジトリにソースコードとDockerfileが配置されていること
- Amazon ECRにリポジトリを作成済みであること
IAM Roleの割り当て
GitLab Runner workerがECRにアクセスできるように,GitLab Runner workerのPodにIAM Roleを割り当てます.具体的な方法は下記を参照してください.
.gitlab-ci.ymlの作成
kanikoを利用するには gcr.io/kaniko-project/executor
イメージを指定します.イメージには amazon-ecr-credential-helper が組み込まれており,/kaniko/.docker/config.json
で credHelpers
を設定するとIAM Roleを利用してECRにアクセスできます.
.gitlab-ci.yml
を以下のように設定します.
stages: - push push: stage: push image: name: gcr.io/kaniko-project/executor:debug entrypoint: [""] variables: ECR_HOST: xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com script: - | cat > /kaniko/.docker/config.json <<EOF { "credHelpers": { "${ECR_HOST}": "ecr-login" } } EOF - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $ECR_HOST/repository-name:latest dependencies: - build tags: - app
ビルドを実行した後,ECRのリポジトリにイメージが表示されると成功です.
トラブルシューティング
ECRにアクセスする権限がない場合や /kaniko/.docker/config.json
が適切に設定されていない場合は以下のエラーが表示されます.
error checking push permissions -- make sure you entered the correct tag name, and that you are authenticated correctly, and try again: checking push permission for "xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/repository-name:latest": unsupported status code 401; body: Not Authorized
参考までに, gcr.io/kaniko-project/executor
イメージの環境変数は以下に設定されています.
ENV DOCKER_CREDENTIAL_GCR_CONFIG=/kaniko/.config/gcloud/docker_credential_gcr_config.json ENV DOCKER_CONFIG=/kaniko/.docker/ ENV SSL_CERT_DIR=/kaniko/ssl/certs ENV PATH=/usr/local/bin:/kaniko ENV USER=/root ENV HOME=/root
(2019/9/27追記) kanikoのイメージは debug
タグを利用する必要があります.latest
タグのイメージでは以下のエラーが出て動作しないようです.
Error: failed to start container "build": Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown