github.com/argoproj/argo-cd/v3@v3.2.1/docs/operator-manual/ingress.md (about) 1 # Ingress Configuration 2 3 Argo CD API server 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, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). Given the `argocd` CLI includes the port number in the request `host` header, 2 Mappings are required. 16 Note: Disabling TLS in not required if you are using grpc-web 17 18 ### Option 1: Mapping CRD for Host-based Routing 19 ```yaml 20 apiVersion: getambassador.io/v2 21 kind: Mapping 22 metadata: 23 name: argocd-server-ui 24 namespace: argocd 25 spec: 26 host: argocd.example.com 27 prefix: / 28 service: https://argocd-server:443 29 --- 30 apiVersion: getambassador.io/v2 31 kind: Mapping 32 metadata: 33 name: argocd-server-cli 34 namespace: argocd 35 spec: 36 # NOTE: the port must be ignored if you have strip_matching_host_port enabled on envoy 37 host: argocd.example.com:443 38 prefix: / 39 service: argocd-server:80 40 regex_headers: 41 Content-Type: "^application/grpc.*$" 42 grpc: true 43 ``` 44 45 Login with the `argocd` CLI: 46 47 ```shell 48 argocd login <host> 49 ``` 50 51 ### Option 2: Mapping CRD for Path-based Routing 52 53 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. 54 55 ```yaml 56 apiVersion: getambassador.io/v2 57 kind: Mapping 58 metadata: 59 name: argocd-server 60 namespace: argocd 61 spec: 62 prefix: /argo-cd 63 rewrite: /argo-cd 64 service: https://argocd-server:443 65 ``` 66 67 Example of `argocd-cmd-params-cm` configmap 68 ```yaml 69 apiVersion: v1 70 kind: ConfigMap 71 metadata: 72 name: argocd-cmd-params-cm 73 namespace: argocd 74 labels: 75 app.kubernetes.io/name: argocd-cmd-params-cm 76 app.kubernetes.io/part-of: argocd 77 data: 78 ## Server properties 79 # Value for base href in index.html. Used if Argo CD is running behind reverse proxy under subpath different from / (default "/") 80 server.basehref: "/argo-cd" 81 # Used if Argo CD is running behind reverse proxy under subpath different from / 82 server.rootpath: "/argo-cd" 83 ``` 84 85 Login with the `argocd` CLI using the extra `--grpc-web-root-path` flag for non-root paths. 86 87 ```shell 88 argocd login <host>:<port> --grpc-web-root-path /argo-cd 89 ``` 90 91 ## [Contour](https://projectcontour.io/) 92 The Contour ingress controller can terminate TLS ingress traffic at the edge. 93 94 The Argo CD API server should be run with TLS disabled. Edit the `argocd-server` Deployment to add the `--insecure` flag to the argocd-server container command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). 95 96 It is also possible to provide an internal-only ingress path and an external-only ingress path by deploying two instances of Contour: one behind a private-subnet LoadBalancer service and one behind a public-subnet LoadBalancer service. The private Contour deployment will pick up Ingresses annotated with `kubernetes.io/ingress.class: contour-internal` and the public Contour deployment will pick up Ingresses annotated with `kubernetes.io/ingress.class: contour-external`. 97 98 This provides the opportunity to deploy the Argo CD UI privately but still allow for SSO callbacks to succeed. 99 100 ### Private Argo CD UI with Multiple Ingress Objects and BYO Certificate 101 Since Contour Ingress supports only a single protocol per Ingress object, define three Ingress objects. One for private HTTP/HTTPS, one for private gRPC, and one for public HTTPS SSO callbacks. 102 103 Internal HTTP/HTTPS Ingress: 104 ```yaml 105 apiVersion: networking.k8s.io/v1 106 kind: Ingress 107 metadata: 108 name: argocd-server-http 109 annotations: 110 kubernetes.io/ingress.class: contour-internal 111 ingress.kubernetes.io/force-ssl-redirect: "true" 112 spec: 113 rules: 114 - host: internal.path.to.argocd.io 115 http: 116 paths: 117 - path: / 118 pathType: Prefix 119 backend: 120 service: 121 name: argocd-server 122 port: 123 name: http 124 tls: 125 - hosts: 126 - internal.path.to.argocd.io 127 secretName: your-certificate-name 128 ``` 129 130 Internal gRPC Ingress: 131 ```yaml 132 apiVersion: networking.k8s.io/v1 133 kind: Ingress 134 metadata: 135 name: argocd-server-grpc 136 annotations: 137 kubernetes.io/ingress.class: contour-internal 138 spec: 139 rules: 140 - host: grpc-internal.path.to.argocd.io 141 http: 142 paths: 143 - path: / 144 pathType: Prefix 145 backend: 146 service: 147 name: argocd-server 148 port: 149 name: https 150 tls: 151 - hosts: 152 - grpc-internal.path.to.argocd.io 153 secretName: your-certificate-name 154 ``` 155 156 External HTTPS SSO Callback Ingress: 157 ```yaml 158 apiVersion: networking.k8s.io/v1 159 kind: Ingress 160 metadata: 161 name: argocd-server-external-callback-http 162 annotations: 163 kubernetes.io/ingress.class: contour-external 164 ingress.kubernetes.io/force-ssl-redirect: "true" 165 spec: 166 rules: 167 - host: external.path.to.argocd.io 168 http: 169 paths: 170 - path: /api/dex/callback 171 pathType: Prefix 172 backend: 173 service: 174 name: argocd-server 175 port: 176 name: http 177 tls: 178 - hosts: 179 - external.path.to.argocd.io 180 secretName: your-certificate-name 181 ``` 182 183 The argocd-server Service needs to be annotated with `projectcontour.io/upstream-protocol.h2c: "https,443"` to wire up the gRPC protocol proxying. 184 185 The API server should then be run with TLS disabled. Edit the `argocd-server` deployment to add the 186 `--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). 187 188 Contour httpproxy CRD: 189 190 Using a contour httpproxy CRD allows you to use the same hostname for the GRPC and REST api. 191 192 ```yaml 193 apiVersion: projectcontour.io/v1 194 kind: HTTPProxy 195 metadata: 196 name: argocd-server 197 namespace: argocd 198 spec: 199 ingressClassName: contour 200 virtualhost: 201 fqdn: path.to.argocd.io 202 tls: 203 secretName: wildcard-tls 204 routes: 205 - conditions: 206 - prefix: / 207 - header: 208 name: Content-Type 209 contains: application/grpc 210 services: 211 - name: argocd-server 212 port: 80 213 protocol: h2c # allows for unencrypted http2 connections 214 timeoutPolicy: 215 response: 1h 216 idle: 600s 217 idleConnection: 600s 218 - conditions: 219 - prefix: / 220 services: 221 - name: argocd-server 222 port: 80 223 ``` 224 225 ## [kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx) 226 227 ### Option 1: SSL-Passthrough 228 229 Argo CD serves multiple protocols (gRPC/HTTPS) on the same port (443), this provides a 230 challenge when attempting to define a single nginx ingress object and rule for the argocd-service, 231 since the `nginx.ingress.kubernetes.io/backend-protocol` [annotation](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-protocol) 232 accepts only a single value for the backend protocol (e.g. HTTP, HTTPS, GRPC, GRPCS). 233 234 In order to expose the Argo CD API server with a single ingress rule and hostname, the 235 `nginx.ingress.kubernetes.io/ssl-passthrough` [annotation](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#ssl-passthrough) 236 must be used to passthrough TLS connections and terminate TLS at the Argo CD API server. 237 238 ```yaml 239 apiVersion: networking.k8s.io/v1 240 kind: Ingress 241 metadata: 242 name: argocd-server-ingress 243 namespace: argocd 244 annotations: 245 nginx.ingress.kubernetes.io/force-ssl-redirect: "true" 246 nginx.ingress.kubernetes.io/ssl-passthrough: "true" 247 spec: 248 ingressClassName: nginx 249 rules: 250 - host: argocd.example.com 251 http: 252 paths: 253 - path: / 254 pathType: Prefix 255 backend: 256 service: 257 name: argocd-server 258 port: 259 name: https 260 ``` 261 262 The above rule terminates TLS at the Argo CD API server, which detects the protocol being used, 263 and responds appropriately. Note that the `nginx.ingress.kubernetes.io/ssl-passthrough` annotation 264 requires that the `--enable-ssl-passthrough` flag be added to the command line arguments to 265 `nginx-ingress-controller`. 266 267 #### SSL-Passthrough with cert-manager and Let's Encrypt 268 269 ```yaml 270 apiVersion: networking.k8s.io/v1 271 kind: Ingress 272 metadata: 273 name: argocd-server-ingress 274 namespace: argocd 275 annotations: 276 cert-manager.io/cluster-issuer: letsencrypt-prod 277 nginx.ingress.kubernetes.io/ssl-passthrough: "true" 278 # If you encounter a redirect loop or are getting a 307 response code 279 # then you need to force the nginx ingress to connect to the backend using HTTPS. 280 # 281 nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" 282 spec: 283 ingressClassName: nginx 284 rules: 285 - host: argocd.example.com 286 http: 287 paths: 288 - path: / 289 pathType: Prefix 290 backend: 291 service: 292 name: argocd-server 293 port: 294 name: https 295 tls: 296 - hosts: 297 - argocd.example.com 298 secretName: argocd-server-tls # as expected by argocd-server 299 ``` 300 301 ### Option 2: SSL Termination at Ingress Controller 302 303 An alternative approach is to perform the SSL termination at the Ingress. Since an `ingress-nginx` Ingress supports only a single protocol per Ingress object, two Ingress objects need to be defined using the `nginx.ingress.kubernetes.io/backend-protocol` annotation, one for HTTP/HTTPS and the other for gRPC. 304 305 Each ingress will be for a different domain (`argocd.example.com` and `grpc.argocd.example.com`). This requires that the Ingress resources use different TLS `secretName`s to avoid unexpected behavior. 306 307 HTTP/HTTPS Ingress: 308 ```yaml 309 apiVersion: networking.k8s.io/v1 310 kind: Ingress 311 metadata: 312 name: argocd-server-http-ingress 313 namespace: argocd 314 annotations: 315 nginx.ingress.kubernetes.io/force-ssl-redirect: "true" 316 nginx.ingress.kubernetes.io/backend-protocol: "HTTP" 317 spec: 318 ingressClassName: nginx 319 rules: 320 - http: 321 paths: 322 - path: / 323 pathType: Prefix 324 backend: 325 service: 326 name: argocd-server 327 port: 328 name: http 329 host: argocd.example.com 330 tls: 331 - hosts: 332 - argocd.example.com 333 secretName: argocd-ingress-http 334 ``` 335 336 gRPC Ingress: 337 ```yaml 338 apiVersion: networking.k8s.io/v1 339 kind: Ingress 340 metadata: 341 name: argocd-server-grpc-ingress 342 namespace: argocd 343 annotations: 344 nginx.ingress.kubernetes.io/backend-protocol: "GRPC" 345 spec: 346 ingressClassName: nginx 347 rules: 348 - http: 349 paths: 350 - path: / 351 pathType: Prefix 352 backend: 353 service: 354 name: argocd-server 355 port: 356 name: https 357 host: grpc.argocd.example.com 358 tls: 359 - hosts: 360 - grpc.argocd.example.com 361 secretName: argocd-ingress-grpc 362 ``` 363 364 The API server should then be run with TLS disabled. Edit the `argocd-server` deployment to add the 365 `--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). 366 367 The obvious disadvantage to this approach is that this technique requires two separate hostnames for 368 the API server -- one for gRPC and the other for HTTP/HTTPS. However it allows TLS termination to 369 happen at the ingress controller. 370 371 372 ## [Traefik (v3.0)](https://docs.traefik.io/) 373 374 Traefik can be used as an edge router and provide [TLS](https://docs.traefik.io/user-guides/grpc/) termination within the same deployment. 375 376 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. 377 378 The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command or set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). 379 380 ### IngressRoute CRD 381 ```yaml 382 apiVersion: traefik.io/v1alpha1 383 kind: IngressRoute 384 metadata: 385 name: argocd-server 386 namespace: argocd 387 spec: 388 entryPoints: 389 - websecure 390 routes: 391 - kind: Rule 392 match: Host(`argocd.example.com`) 393 priority: 10 394 services: 395 - name: argocd-server 396 port: 80 397 - kind: Rule 398 match: Host(`argocd.example.com`) && Header(`Content-Type`, `application/grpc`) 399 priority: 11 400 services: 401 - name: argocd-server 402 port: 80 403 scheme: h2c 404 tls: 405 certResolver: default 406 ``` 407 408 ## AWS Application Load Balancers (ALBs) And Classic ELB (HTTP Mode) 409 AWS ALBs can be used as an L7 Load Balancer for both UI and gRPC traffic, whereas Classic ELBs and NLBs can be used as L4 Load Balancers for both. 410 411 When using an ALB, you'll want to create a second service for argocd-server. This is necessary because we need to tell the ALB to send the GRPC traffic to a different target group than the UI traffic, since the backend protocol is HTTP2 instead of HTTP1. 412 413 ```yaml 414 apiVersion: v1 415 kind: Service 416 metadata: 417 annotations: 418 alb.ingress.kubernetes.io/backend-protocol-version: GRPC # This tells AWS to send traffic from the ALB using GRPC. Plain HTTP2 can be used, but the health checks wont be available because argo currently downgrade non-grpc calls to HTTP1 419 labels: 420 app: argogrpc 421 name: argogrpc 422 namespace: argocd 423 spec: 424 ports: 425 - name: "443" 426 port: 443 427 protocol: TCP 428 targetPort: 8080 429 selector: 430 app.kubernetes.io/name: argocd-server 431 sessionAffinity: None 432 type: NodePort 433 ``` 434 435 Once we create this service, we can configure the Ingress to conditionally route all `application/grpc` traffic to the new HTTP2 backend, using the `alb.ingress.kubernetes.io/conditions` annotation, as seen below. Note: The value after the . in the condition annotation _must_ be the same name as the service that you want traffic to route to - and will be applied on any path with a matching serviceName. 436 437 Also note that we can configure the health check to return the gRPC health status code `OK - 0` from the argocd-server by setting the health check path to `/grpc.health.v1.Health/Check`. By default, the ALB health check for gRPC returns the status code `UNIMPLEMENTED - 12` on health check path `/AWS.ALB/healthcheck`. 438 439 ```yaml 440 apiVersion: networking.k8s.io/v1 441 kind: Ingress 442 metadata: 443 annotations: 444 alb.ingress.kubernetes.io/backend-protocol: HTTPS 445 # Use this annotation (which must match a service name) to route traffic to HTTP2 backends. 446 alb.ingress.kubernetes.io/conditions.argogrpc: | 447 [{"field":"http-header","httpHeaderConfig":{"httpHeaderName": "Content-Type", "values":["application/grpc"]}}] 448 alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' 449 # Use this annotation to receive OK - 0 instead of UNIMPLEMENTED - 12 for gRPC health check. 450 alb.ingress.kubernetes.io/healthcheck-path: /grpc.health.v1.Health/Check 451 alb.ingress.kubernetes.io/success-codes: '0' 452 name: argocd 453 namespace: argocd 454 spec: 455 rules: 456 - host: argocd.argoproj.io 457 http: 458 paths: 459 - path: / 460 backend: 461 service: 462 name: argogrpc # The grpc service must be placed before the argocd-server for the listening rules to be created in the correct order 463 port: 464 number: 443 465 pathType: Prefix 466 - path: / 467 backend: 468 service: 469 name: argocd-server 470 port: 471 number: 443 472 pathType: Prefix 473 tls: 474 - hosts: 475 - argocd.argoproj.io 476 ``` 477 478 ## [Istio](https://www.istio.io) 479 You can put Argo CD behind Istio using following configurations. Here we will achieve both serving Argo CD behind istio and using subpath on Istio 480 481 First we need to make sure that we can run Argo CD with subpath (ie /argocd). For this we have used install.yaml from argocd project as is 482 483 ```bash 484 curl -kLs -o install.yaml https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml 485 ``` 486 487 save following file as kustomization.yml 488 489 ```yaml 490 apiVersion: kustomize.config.k8s.io/v1beta1 491 kind: Kustomization 492 resources: 493 - ./install.yaml 494 495 patches: 496 - path: ./patch.yml 497 ``` 498 499 And following lines as patch.yml 500 501 ```yaml 502 # Use --insecure so Ingress can send traffic with HTTP 503 # --bashref /argocd is the subpath like https://IP/argocd 504 # env was added because of https://github.com/argoproj/argo-cd/issues/3572 error 505 --- 506 apiVersion: apps/v1 507 kind: Deployment 508 metadata: 509 name: argocd-server 510 spec: 511 template: 512 spec: 513 containers: 514 - args: 515 - /usr/local/bin/argocd-server 516 - --staticassets 517 - /shared/app 518 - --redis 519 - argocd-redis:6379 520 - --insecure 521 - --basehref 522 - /argocd 523 - --rootpath 524 - /argocd 525 name: argocd-server 526 env: 527 - name: ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT 528 value: "0" 529 ``` 530 531 After that install Argo CD (there should be only 3 yml file defined above in current directory ) 532 533 ```bash 534 kubectl apply -k ./ -n argocd --wait=true 535 ``` 536 537 Be sure you create secret for Istio ( in our case secretname is argocd-server-tls on argocd Namespace). After that we create Istio Resources 538 539 ```yaml 540 apiVersion: networking.istio.io/v1alpha3 541 kind: Gateway 542 metadata: 543 name: argocd-gateway 544 namespace: argocd 545 spec: 546 selector: 547 istio: ingressgateway 548 servers: 549 - port: 550 number: 80 551 name: http 552 protocol: HTTP 553 hosts: 554 - "*" 555 tls: 556 httpsRedirect: true 557 - port: 558 number: 443 559 name: https 560 protocol: HTTPS 561 hosts: 562 - "*" 563 tls: 564 credentialName: argocd-server-tls 565 maxProtocolVersion: TLSV1_3 566 minProtocolVersion: TLSV1_2 567 mode: SIMPLE 568 cipherSuites: 569 - ECDHE-ECDSA-AES128-GCM-SHA256 570 - ECDHE-RSA-AES128-GCM-SHA256 571 - ECDHE-ECDSA-AES128-SHA 572 - AES128-GCM-SHA256 573 - AES128-SHA 574 - ECDHE-ECDSA-AES256-GCM-SHA384 575 - ECDHE-RSA-AES256-GCM-SHA384 576 - ECDHE-ECDSA-AES256-SHA 577 - AES256-GCM-SHA384 578 - AES256-SHA 579 --- 580 apiVersion: networking.istio.io/v1alpha3 581 kind: VirtualService 582 metadata: 583 name: argocd-virtualservice 584 namespace: argocd 585 spec: 586 hosts: 587 - "*" 588 gateways: 589 - argocd-gateway 590 http: 591 - match: 592 - uri: 593 prefix: /argocd 594 route: 595 - destination: 596 host: argocd-server 597 port: 598 number: 80 599 ``` 600 601 And now we can browse http://{{ IP }}/argocd (it will be rewritten to https://{{ IP }}/argocd 602 603 604 ## Google Cloud load balancers with Kubernetes Ingress 605 606 You can make use of the integration of GKE with Google Cloud to deploy Load Balancers using just Kubernetes objects. 607 608 For this we will need these five objects: 609 - A Service 610 - A BackendConfig 611 - A FrontendConfig 612 - A secret with your SSL certificate 613 - An Ingress for GKE 614 615 If you need detail for all the options available for these Google integrations, you can check the [Google docs on configuring Ingress features](https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features) 616 617 ### Disable internal TLS 618 619 First, to avoid internal redirection loops from HTTP to HTTPS, the API server should be run with TLS disabled. 620 621 Edit the `--insecure` flag in the `argocd-server` command of the argocd-server deployment, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). 622 623 ### Creating a service 624 625 Now you need an externally accessible service. This is practically the same as the internal service Argo CD has, but with Google Cloud annotations. Note that this service is annotated to use a [Network Endpoint Group](https://cloud.google.com/load-balancing/docs/negs) (NEG) to allow your load balancer to send traffic directly to your pods without using kube-proxy, so remove the `neg` annotation if that's not what you want. 626 627 The service: 628 629 ```yaml 630 apiVersion: v1 631 kind: Service 632 metadata: 633 name: argocd-server 634 namespace: argocd 635 annotations: 636 cloud.google.com/neg: '{"ingress": true}' 637 cloud.google.com/backend-config: '{"ports": {"http":"argocd-backend-config"}}' 638 spec: 639 type: ClusterIP 640 ports: 641 - name: http 642 port: 80 643 protocol: TCP 644 targetPort: 8080 645 selector: 646 app.kubernetes.io/name: argocd-server 647 ``` 648 649 ### Creating a BackendConfig 650 651 See that previous service referencing a backend config called `argocd-backend-config`? So lets deploy it using this yaml: 652 653 ```yaml 654 apiVersion: cloud.google.com/v1 655 kind: BackendConfig 656 metadata: 657 name: argocd-backend-config 658 namespace: argocd 659 spec: 660 healthCheck: 661 checkIntervalSec: 30 662 timeoutSec: 5 663 healthyThreshold: 1 664 unhealthyThreshold: 2 665 type: HTTP 666 requestPath: /healthz 667 port: 8080 668 ``` 669 670 It uses the same health check as the pods. 671 672 ### Creating a FrontendConfig 673 674 Now we can deploy a frontend config with an HTTP to HTTPS redirect: 675 676 ```yaml 677 apiVersion: networking.gke.io/v1beta1 678 kind: FrontendConfig 679 metadata: 680 name: argocd-frontend-config 681 namespace: argocd 682 spec: 683 redirectToHttps: 684 enabled: true 685 ``` 686 687 --- 688 !!! note 689 690 The next two steps (the certificate secret and the Ingress) are described supposing that you manage the certificate yourself, and you have the certificate and key files for it. In the case that your certificate is Google-managed, fix the next two steps using the [guide to use a Google-managed SSL certificate](https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs#creating_an_ingress_with_a_google-managed_certificate). 691 692 --- 693 694 ### Creating a certificate secret 695 696 We need now to create a secret with the SSL certificate we want in our load balancer. It's as easy as executing this command on the path you have your certificate keys stored: 697 698 ``` 699 kubectl -n argocd create secret tls secret-yourdomain-com \ 700 --cert cert-file.crt --key key-file.key 701 ``` 702 703 ### Creating an Ingress 704 705 And finally, to top it all, our Ingress. Note the reference to our frontend config, the service, and to the certificate secret. 706 707 --- 708 !!! note 709 710 GKE clusters running versions earlier than `1.21.3-gke.1600`, [the only supported value for the pathType field](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress#creating_an_ingress) is `ImplementationSpecific`. So you must check your GKE cluster's version. You need to use different YAML depending on the version. 711 712 --- 713 714 If you use the version earlier than `1.21.3-gke.1600`, you should use the following Ingress resource: 715 ```yaml 716 apiVersion: networking.k8s.io/v1 717 kind: Ingress 718 metadata: 719 name: argocd 720 namespace: argocd 721 annotations: 722 networking.gke.io/v1beta1.FrontendConfig: argocd-frontend-config 723 spec: 724 tls: 725 - secretName: secret-example-com 726 rules: 727 - host: argocd.example.com 728 http: 729 paths: 730 - pathType: ImplementationSpecific 731 path: "/*" # "*" is needed. Without this, the UI Javascript and CSS will not load properly 732 backend: 733 service: 734 name: argocd-server 735 port: 736 number: 80 737 ``` 738 739 If you use the version `1.21.3-gke.1600` or later, you should use the following Ingress resource: 740 ```yaml 741 apiVersion: networking.k8s.io/v1 742 kind: Ingress 743 metadata: 744 name: argocd 745 namespace: argocd 746 annotations: 747 networking.gke.io/v1beta1.FrontendConfig: argocd-frontend-config 748 spec: 749 tls: 750 - secretName: secret-example-com 751 rules: 752 - host: argocd.example.com 753 http: 754 paths: 755 - pathType: Prefix 756 path: "/" 757 backend: 758 service: 759 name: argocd-server 760 port: 761 number: 80 762 ``` 763 764 As you may know already, it can take some minutes to deploy the load balancer and become ready to accept connections. Once it's ready, get the public IP address for your Load Balancer, go to your DNS server (Google or third party) and point your domain or subdomain (i.e. argocd.example.com) to that IP address. 765 766 You can get that IP address describing the Ingress object like this: 767 768 ``` 769 kubectl -n argocd describe ingresses argocd | grep Address 770 ``` 771 772 Once the DNS change is propagated, you're ready to use Argo with your Google Cloud Load Balancer 773 774 ## Authenticating through multiple layers of authenticating reverse proxies 775 776 Argo CD 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. 777 778 ```shell 779 $ argocd login <host>:<port> --header 'x-token1:foo' --header 'x-token2:bar' # can be repeated multiple times 780 $ argocd login <host>:<port> --header 'x-token1:foo,x-token2:bar' # headers can also be comma separated 781 ``` 782 ## ArgoCD Server and UI Root Path (v1.5.3) 783 784 Argo CD server and UI can be configured to be available under a non-root path (e.g. `/argo-cd`). 785 To do this, add the `--rootpath` flag into the `argocd-server` deployment command: 786 787 ```yaml 788 spec: 789 template: 790 spec: 791 name: argocd-server 792 containers: 793 - command: 794 - /argocd-server 795 - --repo-server 796 - argocd-repo-server:8081 797 - --rootpath 798 - /argo-cd 799 ``` 800 NOTE: The flag `--rootpath` changes both API Server and UI base URL. 801 Example nginx.conf: 802 803 ``` 804 worker_processes 1; 805 806 events { worker_connections 1024; } 807 808 http { 809 810 sendfile on; 811 812 server { 813 listen 443; 814 815 location /argo-cd/ { 816 proxy_pass https://localhost:8080/argo-cd/; 817 proxy_redirect off; 818 proxy_set_header Host $host; 819 proxy_set_header X-Real-IP $remote_addr; 820 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 821 proxy_set_header X-Forwarded-Host $server_name; 822 # buffering should be disabled for api/v1/stream/applications to support chunked response 823 proxy_buffering off; 824 } 825 } 826 } 827 ``` 828 Flag ```--grpc-web-root-path ``` is used to provide a non-root path (e.g. /argo-cd) 829 830 ```shell 831 $ argocd login <host>:<port> --grpc-web-root-path /argo-cd 832 ``` 833 834 ## UI Base Path 835 836 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. 837 To configure the UI path add the `--basehref` flag into the `argocd-server` deployment command: 838 839 ```yaml 840 spec: 841 template: 842 spec: 843 name: argocd-server 844 containers: 845 - command: 846 - /argocd-server 847 - --repo-server 848 - argocd-repo-server:8081 849 - --basehref 850 - /argo-cd 851 ``` 852 853 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. 854 Example nginx.conf with URL rewrite: 855 856 ``` 857 worker_processes 1; 858 859 events { worker_connections 1024; } 860 861 http { 862 863 sendfile on; 864 865 server { 866 listen 443; 867 868 location /argo-cd { 869 rewrite /argo-cd/(.*) /$1 break; 870 proxy_pass https://localhost:8080; 871 proxy_redirect off; 872 proxy_set_header Host $host; 873 proxy_set_header X-Real-IP $remote_addr; 874 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 875 proxy_set_header X-Forwarded-Host $server_name; 876 # buffering should be disabled for api/v1/stream/applications to support chunked response 877 proxy_buffering off; 878 } 879 } 880 } 881 ```