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 ```