Skip to content

Commit

Permalink
rollouts: add development docs and releasing notes (#3873)
Browse files Browse the repository at this point in the history
  • Loading branch information
natasha41575 committed Mar 11, 2023
1 parent 1046ea2 commit 70bdf1c
Show file tree
Hide file tree
Showing 7 changed files with 351 additions and 2 deletions.
9 changes: 9 additions & 0 deletions rollouts/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ help: ## Display this help.
.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
make license

.PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
Expand All @@ -68,6 +69,14 @@ fmt: ## Run go fmt against code.
vet: ## Run go vet against code.
go vet ./...

.PHONY: tidy
tidy: ## Run go mod tidy against code.
go mod tidy

.PHONY: license
license: ## Add licenses.
../scripts/update-license.sh

.PHONY: test
test: manifests generate fmt vet envtest ## Run tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out
Expand Down
7 changes: 6 additions & 1 deletion rollouts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@

Rollouts is a component for deploying KRM configuration to multiple kubernetes clusters.

More details coming soon.
You can run Rollouts:

* On GKE (getting started guide coming soon)
* [Locally](./docs/running-locally.md), intended primarily for [development](./docs/development.md)

If you already have rollouts installed, there is a user guide coming soon.
14 changes: 14 additions & 0 deletions rollouts/controllers/remoterootsync_controller_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package controllers

import (
Expand Down
86 changes: 86 additions & 0 deletions rollouts/docs/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Development

## Changing Rollouts API

If you change the API resources, in `api/.../*.go`, update the generated code and manifests by running:

```sh
make generate
make manifests
```

Remove current Rollout and RemoteSync objects from your cluster. Then, remove old CRDs and apply the
new CRDs to your cluster by running:

```sh
make uninstall
make install
```

## Components

Rollouts comprises of several software components:

* [api](../api): Definition of the KRM API supported by the rollouts controllers.
* [config](../config): The generated rollouts manifests.
* [controllers](../controllers): The controllers and related code for the Rollout CRDs.
* [manifests](../manifests): The generated rollouts manifests in kpt package format.
* [clusterstore](../pkg/clusterstore): Represents a store of kubernetes clusters.
* [packageclustermatcher](../pkg/packageclustermatcher): Matches discovered packages to known clusters.
* [packagediscovery](../pkg/packagediscovery): Discovers config packages to be rolled out.
* [tokenexchange](../pkg/tokenexchange): Exchanges tokens for authenticating GCP service accounts.
* [rolloutsclient](../rolloutsclient): A client for the rollouts API.

## Running Rollouts

See dedicated documentation on running Rollouts:

* [locally](running-locally.md)
* on GKE (getting started guide coming soon)

## Build the Container Images

Build Docker images of Rollout components:

```sh
# Build Images
make docker-build

# Push Images to Docker Registry
make docker-push

# Supported make variables:
# IMG - image name and tag

# Example:
gcr.io/<your-project>/rollouts-controller:v0.0.x make docker-push
```

## Running Locally

Follow [running-locally.md](./running-locally.md) to run Rollouts locally.

## Releasing

Follow [releasing.md](./releasing.md) for the current Rollouts release process.

## Makefile Targets

* `make manifests`: generate Rollouts manifests under `config`
* `make generate`: generate code based on Rollouts API definitions (runs k8s code generators)
* `make tidy`: run go mod tidy
* `make fmt`: formats golang sources
* `make vet`: vets golang sources
* `make test`: runs tests
* `make build`: builds manager binary
* `make docker-build`: builds Rollouts Docker images
* `make docker-push`: pushes Rollouts Docker images
* `make install`: install CRDs into the K8s cluster specified in ~/.kube/config
* `make uninstall`: uninstall CRDs from the K8s cluster specified in ~/.kube/config
* `make deploy`: deploy controller to the K8s cluster specified in ~/.kube/config (must provide IMG variable for the controller image)
* `make undeploy`: undeploy controller from the K8s cluster specified in ~/.kube/config
* `make license`: add licenses to source code

## VSCode

[VSCode](https://code.visualstudio.com/) works really well for editing and debugging.
35 changes: 35 additions & 0 deletions rollouts/docs/releasing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Releasing Rollouts

The current release process for Rollouts is manual and subject to change. Here are the steps.

## Build the controller images

First, go to the [kpt-dev](https://console.cloud.google.com/gcr/images/kpt-dev/global/rollouts-controller?project=kpt-dev) to view existing rollouts controller images. Note the previous released version so that
you can decide what the next release version should be.

For example, if the previous released version is `v0.0.2`, you will most likely want to do `v0.0.3` next.

Set the next release version:
```sh
export VERSION=<version>
```

Build the docker image:
```sh
IMG=gcr.io/kpt-dev/rollouts-controller:$VERSION make docker-build
```

Make sure you are connected to the kpt-dev project, and then push the image:
```sh
gcloud config set project kpt-dev
IMG=gcr.io/kpt-dev/rollouts-controller:$VERSION make docker-push
```

Run the `create-manifests` script to update the manifests:

```sh
./scripts/create-manifests.sh --controller-image gcr.io/kpt-dev/rollouts-controller:$VERSION
```

Create a pull request with the generated changes. Users can now use `kpt pkg get` to pull the
new Rollout manifests with the updated image.
196 changes: 196 additions & 0 deletions rollouts/docs/running-locally.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
# Running Rollouts Locally

## Prerequisites

To run Rollouts locally, you will need:

* Linux machine (technically it is possible to run Rollouts locally on a Mac but
due to differences in Docker between Linux and Mac, the Rollouts scripts are
confirmed to work on Linux)
* [go 1.19](https://go.dev/dl/) or newer
* `make`
* Access to GKE clusters.

## Cluster Setup

### Creating a management cluster with KCC running
First, you must create a config-controller cluster. You can follow the instructions on the
[config-controller-setup guide](https://cloud.google.com/anthos-config-management/docs/how-to/config-controller-setup) to create a config-controller cluster.

Make sure your kubeconfig is connected to this cluster:

```sh
KUBECONFIG=~/.kube/admin-cluster gcloud container clusters get-credentials <your cluster> --region <your region> --project <your project>
```

### Provisioning child clusters
The next step will be to provision new child clusters. This example names the child cluster `gke-n`;
you can replace `gke-n` with whatever name you want for your child cluster.

```sh
# first step is to create a deployable instance of the package
kpt pkg get git@github.com:droot/kpt-packages.git/cluster@main gke-n --for-deployment

# now render the package
kpt fn render

# assuming your kubectl is configured to talk to a management cluster with KCC running (the previous step).
# provision the cluster using following commands
KUBECONFIG=~/.kube/admin-cluster kpt live init gke-n
KUBECONFIG=~/.kube/admin-cluster kpt live apply gke-n
```

You can repeat the above steps to create as many child clusters as you want.

### Setting up kubeconfig
Next, we will configure kubeconfig to be able to talk to each cluster individually.

```sh
# once kpt live status is showing current for a cluster package
# run the following
KUBECONFIG=~/.kube/gke-n gcloud container clusters get-credentials gke-n --region us-west1 --project <your project>

# now ~/.kube/gke-n file has been updated with the credentials for gke-n cluster
# verify if this is working
KUBECONFIG=~/.kube/gke-n kubectl get pods -n kube-system
```

### Set up Config Sync
Rollouts requires a git syncer installed on child clusters. Currently, only Config Sync is supported.
To install Config Sync on your child clusters, follow these steps.

First, set the release version of Config Sync that you would like to install:

```sh
export CS_VERSION=vX.Y.Z
```

Then, apply the core Config Sync manifests to your cluster:

```sh
KUBECONFIG=~/.kube/gke-n kubectl apply -f "https://github.com/GoogleContainerTools/kpt-config-sync/releases/download/${CS_VERSION}/config-sync-manifest.yaml"
```

Then, for kubernetes version v1.25 and newer, optionally apply the asm.yaml manifest:

```sh
KUBECONFIG=~/.kube/gke-n kubectl apply -f "https://github.com/GoogleContainerTools/kpt-config-sync/releases/download/${CS_VERSION}/acm-psp.yaml"
```

If you wish to install Config Sync from source instead of using a released version, you can follow
the [Config Sync installation guide](https://github.com/GoogleContainerTools/kpt-config-sync/blob/main/docs/installation.md).


## Running Rollouts locally

Clone this repository into `${GOPATH}/src/github.com/GoogleContainerTools/kpt`.

```sh
git clone https://github.com/GoogleContainerTools/kpt.git "${GOPATH}/src/github.com/GoogleContainerTools/kpt"
```

Enter the rollouts directory:

```
cd rollouts
```

Download dependencies:

```sh
make tidy
```

Assuming your kubeconfig is configured to talk to the management cluster with KCC installed (that you created
in the above steps), apply the manifests:

```sh
KUBECONFIG=~/.kube/admin-cluster make install
```

Confirm the CRDs are installed:

```sh
KUBECONFIG=~/.kube/admin-cluster kubectl api-resources | grep gitops.kpt.dev

progressiverolloutstrategies gitops.kpt.dev/v1alpha1 true ProgressiveRolloutStrategy
remotesyncs gitops.kpt.dev/v1alpha1 true RemoteSync
rollouts gitops.kpt.dev/v1alpha1 true Rollout
```

Now you are ready to run the controller locally:

```sh
KUBECONFIG=~/.kube/admin-cluster go run main.go
```

## Creating a Rollout object

Here is an example of a simple `Rollout` object:

```yaml
apiVersion: gitops.kpt.dev/v1alpha1
kind: Rollout
metadata:
name: sample
spec:
description: sample
clusters:
sourceType: KCC
packages:
sourceType: GitHub
github:
selector:
org: droot
repo: store
directory: namespaces
revision: main
targets:
selector:
matchLabels:
location/city: example
syncTemplate:
type: RootSync
packageToTargetMatcher:
type: AllClusters
strategy:
type: RollingUpdate
rollingUpdate:
maxConcurrent: 2
```

Apply this to your management cluster with `kubectl apply -f`. View the created Rollout, RemoteSyncs, and RootSync objects to verify that the controller is running properly:

```sh
# see the rollouts object
KUBECONFIG=~/.kube/admin-cluster kubectl get rollouts sample

# see the remotesync objects that the rollouts controller created
KUBECONFIG=~/.kube/admin-cluster kubectl get remotesyncs

# see the rootsync object that the remotesync controller created
KUBECONFIG=~/.kube/gke-n kubectl get rootsyncs -nconfig-management-system
```

Deleting the Rollout object should likewise delete the associated RemoteSync and Rootsync objects. You can
look at the controller logs to verify that the various Remotesync/Rootsync objects are being created, updated,
or deleted.

## Restarting Rollouts

If you make code changes, all you have to do is stop the controller (ctrl+C in the terminal where it is running),
and rerun `go run main.go`.

If you make changes to the Rollouts API, refer to the `Changing Rollouts API` section in the [development guide](./development.md).

## Troubleshooting

### Deleting the Rollout object

The controllers must be running when you delete the Rollout object; otherwise the finalizer will prevent deletion. If you find yourself stuck on deleting a Rollout or RemoteSync object due to an API change or change
in the controller code, you can manually remove the finalizer from the object using `kubectl edit`.

### API Changes

Make sure you reinstall the CRDs if there are changes to the API. Failure to do so can result in unexpected
behavior in the controllers.
6 changes: 5 additions & 1 deletion rollouts/scripts/create-manifests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,8 @@ function set_controller_image {
validate
generate_crds
generate_controller_manifests
set_controller_image ${CONTROLLER_IMAGE}
set_controller_image ${CONTROLLER_IMAGE}

# cleanup
make license
kpt fn render manifests

0 comments on commit 70bdf1c

Please sign in to comment.