TECHSTEP

ITインフラ関連の記事を公開してます。

【メモ】 ArgoCDでAWS ALBを利用するときの設定

はじめに

先日ArgoCDをAmazon EKS上にデプロイし、AWS ALB経由でArgoCD UIにアクセスしようとした際、幾つかの設定変更が必要であることが分かったので、備忘録として残しておきます。

ArgoCD - AWS ALBの構成

ArgoCD + AWS ALBの構成は、大まかには以下のようになります。ArgoCDのWeb UIはArgoCD Serverが提供します。AWS ALBはNodePortを経由してArgoCD Serverにアクセスし、Web UIへの接続を実現します。

f:id:FY0323:20201115120103p:plain

このため、AWS ALBからArgoCDにアクセスするには、argocd-server というCluster IPをNode Portに変更することでアクセスできそうです。

ArgoCDデプロイ時にNodePortが作成されるよう、試しに以下のようなyamlファイルを用意します。ここではtype: NodePortに変更し、spec.nodePortを追加しています。

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: server
    app.kubernetes.io/name: argocd-server
    app.kubernetes.io/part-of: argocd
  name: argocd-server
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 30080
  - name: https
    port: 443
    protocol: TCP
    targetPort: 8080
    nodePort: 30443
  selector:
    app.kubernetes.io/name: argocd-server

元としたマニフェストファイル: GitHub: argoproj/argo-cd

またAWS ALBは以下のようなCloudFrmationファイルを用意し、作成しました。

AWSTemplateFormatVersion: '2010-09-09'
Description: ALB for ArgoCD Server

Parameters:
  ALBName:
    Type: String
    Default: "eks-yamaji-alb"
  TargetGroupPort:
    Type: String
    Default: "30080"
  Scheme:
    Type: String
    Default: "internet-facing"

Resources:
  ListenerHttp:
    Properties:
      DefaultActions:
        - Type: "forward"
          TargetGroupArn: !Ref "TargetGroup"
      LoadBalancerArn: !Ref "LoadBalancer"
      Port: 80
      Protocol: HTTP
    Type: AWS::ElasticLoadBalancingV2::Listener
  LoadBalancer:
    Properties:
      Name: !Sub ${ALBName}
      SecurityGroups:
        - !Ref "SecurityGroup"
      Subnets:
        - "subnet-xxxxxxxxxxxxxxxx"
      Scheme: !Sub ${Scheme}
      Type: "application"
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
  SecurityGroup:
    Properties:
      GroupDescription: !Sub ${ALBName}-sg
      SecurityGroupIngress:
        - CidrIp: "local client ip address"
          FromPort: 80
          IpProtocol: tcp
          ToPort: 80
        - CidrIp: "10.0.0.0/16"
          FromPort: 30080
          IpProtocol: tcp
          ToPort: 30080
      VpcId: "vpc-xxxxxxxxxxxxxxxx"
    Type: AWS::EC2::SecurityGroup
  TargetGroup:
    Properties:
      Name: !Sub ${ALBName}-tg
      Port: !Sub ${TargetGroupPort}
      Protocol: HTTP
      VpcId: "vpc-xxxxxxxxxxxxxxxx"
    Type: AWS::ElasticLoadBalancingV2::TargetGroup

上記2つのYamlファイルを利用してリソースを作成し、セキュリティグループの設定変更と、ターゲットグループの追加を行いました。

設定としては以上で接続されるはずですが、以下のようにALBからターゲットグループへのヘルスチェックで307メッセージが表示され、失敗します。

f:id:FY0323:20201115120158p:plain

なお、ALBのヘルスチェックの設定を色々と変更しましたが、ヘルスチェックが失敗する状況は改善されませんでした。

ArgoCDでAWS ALBを利用する設定

ArgoCDの公式ドキュメントには、ArgoCD Serverへアクセスした際の動きが記載されています。ArgoCD Serverへのアクセスは、デフォルトでTLSを有効化するよう、HTTP (80)宛ての通信はHTTPS (443)へと転送されます。

この結果、ヘルスチェックでPort: 80にアクセスしたトラフィックPort: 443へと転送され、その結果として上の画像のようなメッセージが表示されることがわかります。

ArgoCD設定内容

ArgoCD Serverは、コンテナ起動時に--insecureオプションを付与することで、TLSを無効化して起動することができます。--insecureオプションを付与すると、デフォルトのような転送処理を無効化することができます。ここでは以下の例のように、ArgoCDインストール時のマニフェストファイルを修正します。

参考:GitHub: argoproj/argo-cd

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/component: server
    app.kubernetes.io/name: argocd-server
    app.kubernetes.io/part-of: argocd
  name: argocd-server
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: argocd-server
  template:
    metadata:
      labels:
        app.kubernetes.io/name: argocd-server
    spec:
      containers:
      - command:
        - argocd-server
        - --staticassets
        - /shared/app
        - --insecure # このオプションを追加
        image: argoproj/argocd:latest
        imagePullPolicy: Always
        name: argocd-server
        ports:
        - containerPort: 8080
        - containerPort: 8083
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 3
          periodSeconds: 30
        volumeMounts:
        - mountPath: /app/config/ssh
          name: ssh-known-hosts
        - mountPath: /app/config/tls
          name: tls-certs
      serviceAccountName: argocd-server
      volumes:
      - emptyDir: {}
        name: static-files
      - configMap:
          name: argocd-ssh-known-hosts-cm
        name: ssh-known-hosts
      - configMap:
          name: argocd-tls-certs-cm
        name: tls-certs

上記のように修正することで転送は抑制され、結果としてヘルスチェックが成功するようになります。

f:id:FY0323:20201115120314p:plain

ArgoCD CLIでのアクセス方法

ArgoCD Serverはargocdコマンドを実行した際のアクセス先としても機能します。argocdコマンドはアクセス時にgRPCを利用しており、ArgoCD ServerはWeb UIへのアクセスとargocdコマンドの接続先に同じPort: 443を利用しています。

ArgoCD Server起動時に--insecureオプションを利用していると、Port: 443への転送が無効化され、gRPCが利用できず、ログインができなくなるという問題があります。

$ argocd login --insecure albdomain.ap-northeast-1.elb.amazonaws.com:80
WARNING: server is not configured with TLS. Proceed (y/n)? y
Username: admin
Password:
FATA[0009] rpc error: code = Unavailable desc = transport is closing

これを解消するには、argocdコマンドのオプションの一つである--grpc-webを利用することができます。このオプションを指定することでgRPCを利用し、CLI経由でアクセスすることができます。

$ argocd login --insecure albdomain.ap-northeast-1.elb.amazonaws.com:80 --grpc-web
WARNING: server is not configured with TLS. Proceed (y/n)? y
Username: admin
Password:
'admin' logged in successfully
Context 'albdomain.ap-northeast-1.elb.amazonaws.com:80' updated

なおargocd loginコマンドのオプションは以下の通りです。

$ argocd login --help
Log in to Argo CD
Usage:
 argocd login SERVER [flags]
Flags:
 -h, --help              help for login
     --name string       name to use for the context
     --password string   the password of an account to authenticate
     --sso               perform SSO login
     --sso-port int      port to run local OAuth2 login application (default 8085)
     --username string   the username of an account to authenticate
Global Flags:
     --auth-token string               Authentication token
     --client-crt string               Client certificate file
     --client-crt-key string           Client certificate key file
     --config string                   Path to Argo CD config (default "/home/testadm/.argocd/config")
     --grpc-web                        Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2.
     --grpc-web-root-path string       Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root.
 -H, --header strings                  Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers)
     --insecure                        Skip server certificate and domain verification
     --logformat string                Set the logging format. One of: text|json (default "text")
     --loglevel string                 Set the logging level. One of: debug|info|warn|error (default "info")
     --plaintext                       Disable TLS
     --port-forward                    Connect to a random argocd-server port using port forwarding
     --port-forward-namespace string   Namespace name which should be used for port forwarding
     --server string                   Argo CD server address
     --server-crt string               Server certificate file

参考ドキュメント