# Installation

This guide walks you through setting up Flux v2 (hereafter: "Flux") to
manage one or more Kubernetes clusters.

## Prerequisites

You will need a Kubernetes cluster version **1.16** or newer
and kubectl version **1.18** or newer.

## Install the Flux CLI

With Homebrew:

```sh
brew install fluxcd/tap/flux
```

With Bash:

```sh
curl -s https://toolkit.fluxcd.io/install.sh | sudo bash

# enable completions in ~/.bash_profile
. <(flux completion bash)
```

Command-line completion for `zsh`, `fish`, and `powershell`
are also supported with their own sub-commands.

Binaries for macOS, Windows and Linux AMD64/ARM are available for download on the
[release page](https://github.com/fluxcd/flux2/releases).

Verify that your cluster satisfies the prerequisites with:

```sh
flux check --pre
```

## Bootstrap

Using the `flux bootstrap` command you can install Flux on a
Kubernetes cluster and configure it to manage itself from a Git
repository.

The bootstrap creates a Git repository if one doesn't exist and
commits the Flux components manifests to the main branch. Then it
configures the target cluster to synchronize with that repository by
setting up SSH deploy keys.

If the Flux components are present on the cluster, the bootstrap
command will perform an upgrade if needed. The bootstrap is
idempotent, it's safe to run the command as many times as you want.

You can choose what components to install and for which cluster with:

```sh
flux bootstrap <GIT-PROVIDER> \
  --components=source-controller,kustomize-controller,helm-controller,notification-controller \
  --components-extra=image-reflector-controller,image-automation-controller \
  --path=clusters/my-cluster \
  --version=latest
```

!!! hint "ARM"
    When deploying to a Kubernetes cluster with ARM architecture,
    you can use `--arch=arm` for ARMv7 32-bit container images
    and `--arch=arm64` for ARMv8 64-bit container images.

If you wish to install a specific version, use the Flux
[release tag](https://github.com/fluxcd/flux2/releases) e.g. `--version=v0.2.0`.

With `--path` you can configure the directory which will be used to reconcile the target cluster.
To control multiple clusters from the same Git repository, you have to set a unique path per
cluster e.g. `clusters/staging` and `clusters/production`:

```sh
./clusters/
├── staging # <- path=clusters/staging
│   └── flux-system # <- namespace dir generated by bootstrap
│       ├── gotk-components.yaml
│       ├── gotk-sync.yaml
│       └── kustomization.yaml
└── production-cluster # <- path=clusters/production
    └── flux-system
```

After running bootstrap you can place Kubernetes YAMLs inside a dir under path
e.g. `clusters/staging/my-app`, and Flux will reconcile them on your cluster.

!!! hint "Change the default branch"
    If you wish to change the branch to something else than main, create the repository manually,
    push a branch to origin and then use `flux bootstrap <GIT-PROVIDER> --branch=your-branch`.

For examples on how you can structure your Git repository see:

* [flux2-kustomize-helm-example](https://github.com/fluxcd/flux2-kustomize-helm-example)
* [flux2-multi-tenancy](https://github.com/fluxcd/flux2-multi-tenancy)

### GitHub and GitHub Enterprise

Generate a [personal access token](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line)
that can create repositories by checking all permissions under `repo`.

Export your GitHub personal access token as an environment variable:

```sh
export GITHUB_TOKEN=<your-token>
```

Run the bootstrap for a repository on your personal GitHub account:

```sh
flux bootstrap github \
  --owner=my-github-username \
  --repository=my-repository \
  --path=clusters/my-cluster \
  --personal
```

!!! hint "Deploy Key"
    The bootstrap command creates a ssh key which it stores as a secret in the
    Kubernetes cluster. The key is also used to create a deploy key in the GitHub
    repository. The new deploy key will be linked to the personal access token used
    to authenticate. Removing the personal access token will remove the deploy key.

Run the bootstrap for a repository owned by a GitHub organization:

```sh
flux bootstrap github \
  --owner=my-github-organization \
  --repository=my-repository \
  --team=team1-slug \
  --team=team2-slug \
  --path=clusters/my-cluster
```

When you specify a list of teams, those teams will be granted maintainer access to the repository.

To run the bootstrap for a repository hosted on GitHub Enterprise, you have to specify your GitHub hostname:

```sh
flux bootstrap github \
  --hostname=my-github-enterprise.com \
  --ssh-hostname=my-github-enterprise.com \
  --owner=my-github-organization \
  --repository=my-repository \
  --branch=main \
  --path=clusters/my-cluster
```

If your GitHub Enterprise has SSH access disabled, you can use HTTPS and token authentication with:

```sh
flux bootstrap github \
  --token-auth \
  --hostname=my-github-enterprise.com \
  --owner=my-github-organization \
  --repository=my-repository \
  --branch=main \
  --path=clusters/my-cluster
```

### GitLab and GitLab Enterprise

Generate a [personal access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html)
that grants complete read/write access to the GitLab API.

Export your GitLab personal access token as an environment variable:

```sh
export GITLAB_TOKEN=<your-token>
```

Run the bootstrap for a repository on your personal GitLab account:

```sh
flux bootstrap gitlab \
  --owner=my-gitlab-username \
  --repository=my-repository \
  --branch=master \
  --path=clusters/my-cluster \
  --token-auth \
  --personal
```

To run the bootstrap for a repository using deploy keys for authentication, you have to specify the SSH hostname:

```sh
flux bootstrap gitlab \
  --ssh-hostname=gitlab.com \
  --owner=my-gitlab-username \
  --repository=my-repository \
  --branch=master \
  --path=clusters/my-cluster
```

!!! hint "Authentication"
    When providing the `--ssh-hostname`, a read-only (SSH) deploy key will be added
    to your repository, otherwise your GitLab personal token will be used to
    authenticate against the HTTPS endpoint instead.

Run the bootstrap for a repository owned by a GitLab group:

```sh
flux bootstrap gitlab \
  --owner=my-gitlab-group \
  --repository=my-repository \
  --branch=master \
  --path=clusters/my-cluster
```

To run the bootstrap for a repository hosted on GitLab on-prem or enterprise, you have to specify your GitLab hostname:

```sh
flux bootstrap gitlab \
  --hostname=my-gitlab.com \
  --token-auth \
  --owner=my-gitlab-group \
  --repository=my-repository \
  --branch=master \
  --path=clusters/my-cluster
```

### Generic Git Server

For other Git providers such as Bitbucket, Gogs, Gitea, Azure DevOps, etc you can manually setup the repository and the deploy key.

Create a Git repository and clone it locally:

```sh
git clone ssh://<host>/<org>/my-repository
cd my-repository
```

Create a directory inside the repository:

```sh
mkdir -p ./clusters/my-cluster/flux-system
```

Generate the Flux manifests with:

```sh
# on ARM64/AARCH64 clusters use --arch=arm64
flux install --version=latest \
  --arch=amd64 \
  --export > ./clusters/my-cluster/flux-system/gotk-components.yaml
```

If your cluster must pull images from a private container registry, first you should pull
the toolkit images from GitHub Container Registry and push them to your registry, for example:

```sh
docker pull ghcr.io/fluxcd/source-controller:v0.2.0
docker tag ghcr.io/fluxcd/source-controller:v0.2.0 registry.internal/fluxcd/source-controller:v0.2.0
docker push registry.internal/fluxcd/source-controller:v0.2.0
```

Create the pull secret in the `flux-system` namespace:

```sh
kubectl create ns flux-system

kubectl -n flux-system create secret generic regcred \
    --from-file=.dockerconfigjson=/.docker/config.json \
    --type=kubernetes.io/dockerconfigjson
```

Set your registry domain, and the pull secret when generating the manifests:

```sh
flux install --version=latest \
  --registry=registry.internal/fluxcd \
  --image-pull-secret=regcred \
  --export > ./clusters/my-cluster/flux-system/gotk-components.yaml
```

Commit and push the manifest to the master branch:

```sh
git add -A && git commit -m "add components" && git push
```

Apply the manifests on your cluster:

```sh
kubectl apply -f ./clusters/my-cluster/flux-system/gotk-components.yaml
```

Verify that the controllers have started:

```sh
flux check
```

Create a `GitRepository` object on your cluster by specifying the SSH address of your repo:

```sh
flux create source git flux-system \
  --url=ssh://git@<host>/<org>/<repository> \
  --ssh-key-algorithm=ecdsa \
  --ssh-ecdsa-curve=p521 \
  --branch=master \
  --interval=1m
```

You will be prompted to add a deploy key to your repository.
If you don't specify the SSH algorithm, then `flux` will generate an RSA 2048 bits key.

!!! hint "Azure DevOps"
    Azure DevOps requires a non-default Git implementation (`libgit2`) to be enabled, so that the Git v2 protocol is supported.
    Note that this implementation does not support shallow cloning, and it is therefore advised to only resort to this option if a
    connection fails with the default configuration.
    Additionally, the current implementation of image automation does not support Azure DevOps as has no Git implementation with
    this protocol. This limitation will likely change in the future.

    If you are using Azure DevOps you need to specify a different Git implementation than the default:
    
    ```sh
    flux create source git flux-system \
      --git-implementation=libgit2 \
      --url=git@ssh.dev.azure.com/v3/org/project/repository \
      --branch=master \
      --interval=1m
    ```

    Note that unlike `git`, Flux does not support the
    ["shorter" scp-like syntax for the SSH protocol](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols#_the_ssh_protocol)
    (e.g. `ssh.dev.azure.com:v3`).
    Use the [RFC 3986 compatible syntax](https://tools.ietf.org/html/rfc3986#section-3) instead: `ssh.dev.azure.com/v3`.

If your Git server supports basic auth, you can set the URL to HTTPS and specify the credentials with:

```sh
flux create source git flux-system \
  --url=https://<host>/<org>/my-repository \
  --username=my-username \
  --password=my-password \
  --branch=master \
  --interval=1m
```

Create a `Kustomization` object on your cluster:

```sh
flux create kustomization flux-system \
  --source=flux-system \
  --path="./clusters/my-cluster" \
  --prune=true \
  --interval=10m
```

Export both objects, generate a `kustomization.yaml`, commit and push the manifests to Git:

```sh
flux export source git flux-system \
  > ./clusters/my-cluster/flux-system/gotk-sync.yaml

flux export kustomization flux-system \
  >> ./clusters/my-cluster/flux-system/gotk-sync.yaml

cd ./clusters/my-cluster/flux-system && kustomize create --autodetect

git add -A && git commit -m "add sync manifests" && git push
```

To upgrade the Flux components to a newer version, run the install command and commit the changes:

```sh
flux install --version=latest \
  --export > ./clusters/my-cluster/flux-system/gotk-components.yaml

git add -A && git commit -m "update flux" && git push
```

The source-controller will pull the changes on the cluster, then the kustomize-controller
will perform a rolling update of all Flux components including itself.

## Bootstrap with Terraform

The bootstrap procedure can be implemented with Terraform using the Flux provider published on
[registry.terraform.io](https://registry.terraform.io/providers/fluxcd/flux).

The provider consists of two data sources (`flux_install` and `flux_sync`) for generating the
Kubernetes manifests that can be used to install or upgrade Flux:

```hcl
data "flux_install" "main" {
  target_path    = "clusters/my-cluster"
  arch           = "amd64"
  network_policy = false
  version        = "latest"
}

data "flux_sync" "main" {
  target_path = "clusters/my-cluster"
  url         = "https://github.com/${var.github_owner}/${var.repository_name}"
  branch      = "main"
}
```

For more details on how to use the Terraform provider
please see [fluxcd/terraform-provider-flux](https://github.com/fluxcd/terraform-provider-flux).

## Customize Flux manifests

You can customize the Flux components in the Git repository where you've run bootstrap with Kustomize patches.

First clone the repository locally and generate a `kustomization.yaml` file with:

```sh
cd ./clusters/production && kustomize create --autodetect
```

Assuming you want to add custom annotations and labels to the Flux controllers in `clusters/production`.
Create a Kustomize patch and set the metadata for source-controller and kustomize-controller pods:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: source-controller
  namespace: flux-system
spec:
  template:
    metadata:
      annotations:
        custom: annotation
      labels:
        custom: label
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kustomize-controller
  namespace: flux-system
spec:
  template:
    metadata:
      annotations:
        custom: annotation
      labels:
        custom: label
```

Save the above file as `flux-system-patch.yaml` inside the `clusters/production` dir.

Edit `clusters/production/kustomization.yaml` and add the patch:

```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - flux-system
patchesStrategicMerge:
  - flux-system-patch.yaml
```

Push the changes to main branch:

```sh
git add -A && git commit -m "add production metadata" && git push
```

Flux will detect the change and will update itself on the production cluster.

## Dev install

For testing purposes you can install Flux without storing its manifests in a Git repository:

```sh
flux install --arch=amd64
```

Or using kubectl:

```sh
kubectl apply -f https://github.com/fluxcd/flux2/releases/latest/download/install.yaml
```

Then you can register Git repositories and reconcile them on your cluster:

```sh
flux create source git podinfo \
  --url=https://github.com/stefanprodan/podinfo \
  --tag-semver=">=4.0.0" \
  --interval=1m

flux create kustomization podinfo-default \
  --source=podinfo \
  --path="./kustomize" \
  --prune=true \
  --validation=client \
  --interval=10m \
  --health-check="Deployment/podinfo.default" \
  --health-check-timeout=2m
```

You can register Helm repositories and create Helm releases:

```sh
flux create source helm bitnami \
  --interval=1h \
  --url=https://charts.bitnami.com/bitnami

flux create helmrelease nginx \
  --interval=1h \
  --release-name=nginx-ingress-controller \
  --target-namespace=kube-system \
  --source=HelmRepository/bitnami \
  --chart=nginx-ingress-controller \
  --chart-version="5.x.x"
```

## Upgrade

Update Flux CLI to the latest release with `brew upgrade fluxcd/tap/flux` or by
downloading the binary from [GitHub](https://github.com/fluxcd/flux2/releases).

Verify that you are running the latest version with:

```sh
flux --version
```

### Bootstrap upgrade

If you've used the [bootstrap](#bootstrap) procedure to deploy Flux,
then rerun the bootstrap command for each cluster using the same arguments as before:

```sh
flux bootstrap github \
  --owner=my-github-username \
  --repository=my-repository \
  --branch=main \
  --path=clusters/my-cluster \
  --personal
```

The above command will clone the repository, it will update the components manifest in
`<path>/flux-system/gotk-components.yaml` and it will push the changes to the remote branch.

Tell Flux to pull the manifests from Git and upgrade itself with:

```sh
flux reconcile source git flux-system
```

Verify that the controllers have been upgrade with:

```sh
flux check
```

!!! hint "Automated upgrades"
    You can automate the components manifest update with GitHub Actions
    and open a PR when there is a new Flux version available.
    For more details please see [Flux GitHub Action docs](https://github.com/fluxcd/flux2/tree/main/action).

### Terraform upgrade

Update the Flux provider to the [latest release](https://github.com/fluxcd/terraform-provider-flux/releases)
and run `terraform apply`.

Tell Flux to upgrade itself in-cluster or wait for it to pull the latest commit from Git:

```sh
kubectl annotate --overwrite gitrepository/flux-system reconcile.fluxcd.io/requestedAt="$(date +%s)"
```

### In-cluster upgrade

If you've installed Flux directly on the cluster, then rerun the install command:

```sh
flux install --version=latest
```

The above command will download the latest manifests from
[GitHub](https://github.com/fluxcd/flux2/releases) and it will apply them on your cluster.
You can verify that the controllers have been upgraded to the latest version with `flux check`.

If you've installed Flux directly on the cluster with kubectl,
then rerun the command using the latest manifests from the `main` branch:

```sh
kustomize build https://github.com/fluxcd/flux2/manifests/install?ref=main | kubectl apply -f-
```

## Uninstall

You can uninstall the Flux components with:

```sh
flux uninstall --crds
```

The above command will delete the custom resources definitions, the
controllers, and the namespace where they were installed.
