github.com/argoproj/argo-cd@v1.8.7/docs/operator-manual/ingress.md (about)

     1  # Ingress Configuration
     2  
     3  Argo CD runs both a gRPC server (used by the CLI), as well as a HTTP/HTTPS server (used by the UI).
     4  Both protocols are exposed by the argocd-server service object on the following ports:
     5  
     6  * 443 - gRPC/HTTPS
     7  * 80 - HTTP (redirects to HTTPS)
     8  
     9  There are several ways how Ingress can be configured.
    10  
    11  ## [Ambassador](https://www.getambassador.io/)
    12  
    13  The Ambassador Edge Stack can be used as a Kubernetes ingress controller with [automatic TLS termination](https://www.getambassador.io/docs/latest/topics/running/tls/#host) and routing capabilities for both the CLI and the UI.
    14  
    15  The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command. Given the `argocd` CLI includes the port number in the request `host` header, 2 Mappings are required.
    16  
    17  ### Option 1: Mapping CRD for Host-based Routing
    18  ```yaml
    19  apiVersion: getambassador.io/v2
    20  kind: Mapping
    21  metadata:
    22    name: argocd-server-ui
    23    namespace: argocd
    24  spec:
    25    host: argocd.example.com
    26    prefix: /
    27    service: argocd-server:443
    28  ---
    29  apiVersion: getambassador.io/v2
    30  kind: Mapping
    31  metadata:
    32    name: argocd-server-cli
    33    namespace: argocd
    34  spec:
    35    host: argocd.example.com:443
    36    prefix: /
    37    service: argocd-server:443
    38  ```
    39  
    40  Login with the `argocd` CLI using the extra `--grpc-web-root-path` flag for gRPC-web.
    41  
    42  ```shell
    43  argocd login <host>:<port> --grpc-web-root-path /
    44  ```
    45  
    46  ### Option 2: Mapping CRD for Path-based Routing
    47  
    48  The API server must be configured to be available under a non-root path (e.g. `/argo-cd`). Edit the `argocd-server` deployment to add the `--rootpath=/argo-cd` flag to the argocd-server command.
    49  
    50  ```yaml
    51  apiVersion: getambassador.io/v2
    52  kind: Mapping
    53  metadata:
    54    name: argocd-server
    55    namespace: argocd
    56  spec:
    57    prefix: /argo-cd
    58    rewrite: /argo-cd
    59    service: argocd-server:443
    60  ```
    61  
    62  Login with the `argocd` CLI using the extra `--grpc-web-root-path` flag for non-root paths.
    63  
    64  ```shell
    65  argocd login <host>:<port> --grpc-web-root-path /argo-cd
    66  ```
    67  
    68  
    69  ## [kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx)
    70  
    71  ### Option 1: SSL-Passthrough
    72  
    73  Argo CD serves multiple protocols (gRPC/HTTPS) on the same port (443), this provides a
    74  challenge when attempting to define a single nginx ingress object and rule for the argocd-service,
    75  since the `nginx.ingress.kubernetes.io/backend-protocol` [annotation](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-protocol)
    76  accepts only a single value for the backend protocol (e.g. HTTP, HTTPS, GRPC, GRPCS).
    77  
    78  In order to expose the Argo CD API server with a single ingress rule and hostname, the
    79  `nginx.ingress.kubernetes.io/ssl-passthrough` [annotation](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#ssl-passthrough)
    80  must be used to passthrough TLS connections and terminate TLS at the Argo CD API server.
    81  
    82  ```yaml
    83  apiVersion: extensions/v1beta1
    84  kind: Ingress
    85  metadata:
    86    name: argocd-server-ingress
    87    namespace: argocd
    88    annotations:
    89      kubernetes.io/ingress.class: nginx
    90      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    91      nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    92  spec:
    93    rules:
    94    - host: argocd.example.com
    95      http:
    96        paths:
    97        - backend:
    98            serviceName: argocd-server
    99            servicePort: https
   100  ```
   101  
   102  The above rule terminates TLS at the Argo CD API server, which detects the protocol being used,
   103  and responds appropriately. Note that the `nginx.ingress.kubernetes.io/ssl-passthrough` annotation
   104  requires that the `--enable-ssl-passthrough` flag be added to the command line arguments to
   105  `nginx-ingress-controller`.
   106  
   107  #### SSL-Passthrough with cert-manager and Let's Encrypt
   108  
   109  ```yaml
   110  apiVersion: extensions/v1beta1
   111  kind: Ingress
   112  metadata:
   113    name: argocd-server-ingress
   114    namespace: argocd
   115    annotations:
   116      cert-manager.io/cluster-issuer: letsencrypt-prod
   117      kubernetes.io/ingress.class: nginx
   118      kubernetes.io/tls-acme: "true"
   119      nginx.ingress.kubernetes.io/ssl-passthrough: "true"
   120      # If you encounter a redirect loop or are getting a 307 response code 
   121      # then you need to force the nginx ingress to connect to the backend using HTTPS.
   122      #
   123      # nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
   124  spec:
   125    rules:
   126    - host: argocd.example.com
   127      http:
   128        paths:
   129        - backend:
   130            serviceName: argocd-server
   131            servicePort: https
   132          path: /
   133    tls:
   134    - hosts:
   135      - argocd.example.com
   136      secretName: argocd-secret # do not change, this is provided by Argo CD
   137  ```
   138  
   139  ### Option 2: Multiple Ingress Objects And Hosts
   140  
   141  Since ingress-nginx Ingress supports only a single protocol per Ingress object, an alternative
   142  way would be to define two Ingress objects. One for HTTP/HTTPS, and the other for gRPC:
   143  
   144  HTTP/HTTPS Ingress:
   145  ```yaml
   146  apiVersion: extensions/v1beta1
   147  kind: Ingress
   148  metadata:
   149    name: argocd-server-http-ingress
   150    namespace: argocd
   151    annotations:
   152      kubernetes.io/ingress.class: "nginx"
   153      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
   154      nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
   155  spec:
   156    rules:
   157    - http:
   158        paths:
   159        - backend:
   160            serviceName: argocd-server
   161            servicePort: http
   162      host: argocd.example.com
   163    tls:
   164    - hosts:
   165      - argocd.example.com
   166      secretName: argocd-secret # do not change, this is provided by Argo CD
   167  ```
   168  
   169  gRPC Ingress:
   170  ```yaml
   171  apiVersion: extensions/v1beta1
   172  kind: Ingress
   173  metadata:
   174    name: argocd-server-grpc-ingress
   175    namespace: argocd
   176    annotations:
   177      kubernetes.io/ingress.class: "nginx"
   178      nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
   179  spec:
   180    rules:
   181    - http:
   182        paths:
   183        - backend:
   184            serviceName: argocd-server
   185            servicePort: https
   186      host: grpc.argocd.example.com
   187    tls:
   188    - hosts:
   189      - grpc.argocd.example.com
   190      secretName: argocd-secret # do not change, this is provided by Argo CD
   191  ```
   192  
   193  The API server should then be run with TLS disabled. Edit the `argocd-server` deployment to add the
   194  `--insecure` flag to the argocd-server command:
   195  
   196  ```yaml
   197  spec:
   198    template:
   199      spec:
   200        containers:
   201        - name: argocd-server
   202          command:
   203          - /argocd-server
   204          - --staticassets
   205          - /shared/app
   206          - --repo-server
   207          - argocd-repo-server:8081
   208          - --insecure
   209  ```
   210  
   211  The obvious disadvantage to this approach is that this technique requires two separate hostnames for
   212  the API server -- one for gRPC and the other for HTTP/HTTPS. However it allows TLS termination to
   213  happen at the ingress controller.
   214  
   215  
   216  ## [Traefik (v2.2)](https://docs.traefik.io/)
   217  
   218  Traefik can be used as an edge router and provide [TLS](https://docs.traefik.io/user-guides/grpc/) termination within the same deployment.
   219  
   220  It currently has an advantage over NGINX in that it can terminate both TCP and HTTP connections _on the same port_ meaning you do not require multiple hosts or paths.
   221  
   222  The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command.
   223  
   224  ### IngressRoute CRD
   225  ```yaml
   226  apiVersion: traefik.containo.us/v1alpha1
   227  kind: IngressRoute
   228  metadata:
   229    name: argocd-server
   230    namespace: argocd
   231  spec:
   232    entryPoints:
   233      - websecure
   234    routes:
   235      - kind: Rule
   236        match: Host(`argocd.example.com`)
   237        priority: 10
   238        services:
   239          - name: argocd-server
   240            port: 80
   241      - kind: Rule
   242        match: Host(`argocd.example.com`) && Headers(`Content-Type`, `application/grpc`)
   243        priority: 11
   244        services:
   245          - name: argocd-server
   246            port: 80
   247            scheme: h2c
   248    tls:
   249      certResolver: default
   250      options: {}
   251  ```
   252  
   253  ## AWS Application Load Balancers (ALBs) And Classic ELB (HTTP Mode)
   254  
   255  ALBs and Classic ELBs don't fully support HTTP2/gRPC, which is used by the `argocd` CLI.
   256  Thus, when using an AWS load balancer, either Classic ELB in
   257  passthrough mode is needed, or NLBs.
   258  
   259  ```shell
   260  $ argocd login <host>:<port> --grpc-web
   261  ```
   262  
   263  ## Authenticating through multiple layers of authenticating reverse proxies
   264  
   265  ArgoCD endpoints may be protected by one or more reverse proxies layers, in that case, you can provide additional headers through the `argocd` CLI `--header` parameter to authenticate through those layers.
   266  
   267  ```shell
   268  $ argocd login <host>:<port> --header 'x-token1:foo' --header 'x-token2:bar' # can be repeated multiple times
   269  $ argocd login <host>:<port> --header 'x-token1:foo,x-token2:bar' # headers can also be comma separated
   270  ```
   271  ## ArgoCD Server and UI Root Path (v1.5.3)
   272  
   273  ArgoCD server and UI can be configured to be available under a non-root path (e.g. `/argo-cd`).
   274  To do this, add the `--rootpath` flag into the `argocd-server` deployment command:
   275  
   276  ```yaml
   277  spec:
   278    template:
   279      spec:
   280        name: argocd-server
   281        containers:
   282        - command:
   283          - /argocd-server
   284          - --staticassets
   285          - /shared/app
   286          - --repo-server
   287          - argocd-repo-server:8081
   288          - --rootpath
   289          - /argo-cd
   290  ```
   291  NOTE: The flag `--rootpath` changes both API Server and UI base URL. 
   292  Example nginx.conf:
   293  
   294  ```
   295  worker_processes 1;
   296  
   297  events { worker_connections 1024; }
   298  
   299  http {
   300  
   301      sendfile on;
   302  
   303      server {
   304          listen 443;
   305  
   306          location /argo-cd/ {
   307              proxy_pass         https://localhost:8080/argo-cd/;
   308              proxy_redirect     off;
   309              proxy_set_header   Host $host;
   310              proxy_set_header   X-Real-IP $remote_addr;
   311              proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
   312              proxy_set_header   X-Forwarded-Host $server_name;
   313              # buffering should be disabled for api/v1/stream/applications to support chunked response
   314              proxy_buffering off;
   315          }
   316      }
   317  }
   318  ```
   319  Flag ```--grpc-web-root-path ``` is used to provide a non-root path (e.g. /argo-cd)
   320  
   321  ```shell
   322  $ argocd login <host>:<port> --grpc-web-root-path /argo-cd
   323  ```
   324  
   325  ## UI Base Path
   326  
   327  If the Argo CD UI is available under a non-root path (e.g. `/argo-cd` instead of `/`) then the UI path should be configured in the API server.
   328  To configure the UI path add the `--basehref` flag into the `argocd-server` deployment command:
   329  
   330  ```yaml
   331  spec:
   332    template:
   333      spec:
   334        name: argocd-server
   335        containers:
   336        - command:
   337          - /argocd-server
   338          - --staticassets
   339          - /shared/app
   340          - --repo-server
   341          - argocd-repo-server:8081
   342          - --basehref
   343          - /argo-cd
   344  ```
   345  
   346  NOTE: The flag `--basehref` only changes the UI base URL. The API server will keep using the `/` path so you need to add a URL rewrite rule to the proxy config.
   347  Example nginx.conf with URL rewrite:
   348  
   349  ```
   350  worker_processes 1;
   351  
   352  events { worker_connections 1024; }
   353  
   354  http {
   355  
   356      sendfile on;
   357  
   358      server {
   359          listen 443;
   360  
   361          location /argo-cd {
   362              rewrite /argo-cd/(.*) /$1  break;
   363              proxy_pass         https://localhost:8080;
   364              proxy_redirect     off;
   365              proxy_set_header   Host $host;
   366              proxy_set_header   X-Real-IP $remote_addr;
   367              proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
   368              proxy_set_header   X-Forwarded-Host $server_name;
   369              # buffering should be disabled for api/v1/stream/applications to support chunked response
   370              proxy_buffering off;
   371          }
   372      }
   373  }
   374  ```