Skip to content

Commit

Permalink
Merge pull request #116 from gopaddle-io/v0.0.2
Browse files Browse the repository at this point in the history
Merge latest version with main
  • Loading branch information
gopaddle-io authored Jan 29, 2024
2 parents 9485125 + af2c144 commit 52ca683
Show file tree
Hide file tree
Showing 146 changed files with 8,222 additions and 3,006 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
vendor/
labelconfig/*
main
configurator
.history
.vscode
.idea
33 changes: 25 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
FROM golang
MAINTAINER Bluemeric <info@bluemeric.com>
# Build the manager binary
FROM golang:1.16 as builder

RUN mkdir /app/
WORKDIR /app/

### Added artifacts into application working directory
Add configurator /app/
WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN go mod download

CMD ["./configurator"]
# Copy the go source
COPY main.go main.go
COPY apis/ apis/
COPY controllers/ controllers/
COPY pkg/ pkg/
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go

# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
USER 65532:65532

ENTRYPOINT ["/manager"]
151 changes: 106 additions & 45 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,52 +1,113 @@
ifndef DOCKER_IMAGE_REPO
DOCKER_IMAGE_REPO=gopaddle/configurator
endif

ifndef DOCKER_IMAGE_TAG
DOCKER_IMAGE_TAG=latest
# Image URL to use all building/pushing image targets
IMG ?= controller:latest
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false"

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
else
GOBIN=$(shell go env GOBIN)
endif

.PHONY: helm

# Setting SHELL to bash allows bash commands to be executed by recipes.
# This is a requirement for 'setup-envtest.sh' in the test target.
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec

all: build

##@ General

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
# More info on the usage of ANSI control characters for terminal formatting:
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
# More info on the awk command:
# http://linuxcommand.org/lc3_adv_awk.php

help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

##@ Development

manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases

generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

fmt: ## Run go fmt against code.
go fmt ./...

vet: ## Run go vet against code.
go vet ./...

ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
test: manifests generate fmt vet ## Run tests.
mkdir -p ${ENVTEST_ASSETS_DIR}
test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.8.3/hack/setup-envtest.sh
source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out

##@ Build

build: generate fmt vet ## Build manager binary.
go build -o bin/manager main.go

run: manifests generate fmt vet ## Run a controller from your host.
go run ./main.go

docker-build: test ## Build docker image with the manager.
sudo docker build -t ${IMG} .

docker-push: ## Push docker image with the manager.
sudo docker push ${IMG}

##@ Deployment

install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl apply -f -

uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl delete -f -

deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | kubectl apply -f -

undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/default | kubectl delete -f -


CONTROLLER_GEN = $(shell pwd)/bin/controller-gen
controller-gen: ## Download controller-gen locally if necessary.
$(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1)

KUSTOMIZE = $(shell pwd)/bin/kustomize
kustomize: ## Download kustomize locally if necessary.
$(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v3@v3.8.7)

clean: clean-configurator
build: build-configurator
push: push-image
deploy: deploy-configurator deploy-crds
remove: remove-configurator cleanup
cleanup: cleanup-crds

clean-configurator:
-rm -f configurator
-docker rmi ${DOCKER_IMAGE_REPO}:${DOCKER_IMAGE_TAG}

deploy-configurator:
-kubectl create ns configurator
-kubectl apply -f deploy/configurator-serviceaccount.yaml
-kubectl apply -f deploy/configurator-clusterrole.yaml
-kubectl apply -f deploy/configurator-clusterrolebinding.yaml
-kubectl apply -f deploy/configurator-deployment.yaml

deploy-crds:
-kubectl apply -f deploy/crd-customConfigMap.yaml
-kubectl apply -f deploy/crd-customSecret.yaml

remove-configurator:
-kubectl delete -f deploy/configurator-deployment.yaml
-kubectl delete -f deploy/configurator-clusterrolebinding.yaml
-kubectl delete -f deploy/configurator-clusterrole.yaml
-kubectl delete -f deploy/configurator-serviceaccount.yaml

cleanup-crds:
-kubectl delete -f deploy/crd-customConfigMap.yaml
-kubectl delete -f deploy/crd-customSecret.yaml

build-configurator:
-go mod vendor
-go build -o configurator .
-docker build . -t ${DOCKER_IMAGE_REPO}:${DOCKER_IMAGE_TAG}

push-image:
-docker push ${DOCKER_IMAGE_REPO}:${DOCKER_IMAGE_TAG}
# go-get-tool will 'go get' any package $2 and install it to $1.
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
define go-get-tool
@[ -f $(1) ] || { \
set -e ;\
TMP_DIR=$$(mktemp -d) ;\
cd $$TMP_DIR ;\
go mod init tmp ;\
echo "Downloading $(2)" ;\
GOBIN=$(PROJECT_DIR)/bin go get $(2) ;\
rm -rf $$TMP_DIR ;\
}
endef

helm:
cd helm && helm package ../helm-src/configurator
Expand All @@ -56,4 +117,4 @@ helm-install:
-helm upgrade --install --create-namespace --namespace configurator configurator helm-src/configurator

helm-uninstall:
-helm uninstall -n configurator configurator
-helm uninstall -n configurator configurator
36 changes: 36 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
domain: configurator.gopaddle.io
layout:
- go.kubebuilder.io/v3
multigroup: true
projectName: configurator
repo: github.com/gopaddle-io/configurator
resources:
- api:
crdVersion: v1
namespaced: true
controller: true
domain: configurator.gopaddle.io
group: configurator.gopaddle.io
kind: CustomConfigMap
path: github.com/gopaddle-io/configurator/apis/configurator.gopaddle.io/v1alpha1
version: v1alpha1
- controller: true
group: core
kind: ConfigMap
path: k8s.io/api/core/v1
version: v1
- controller: true
group: core
kind: Secret
path: k8s.io/api/core/v1
version: v1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: configurator.gopaddle.io
group: configurator.gopaddle.io
kind: CustomSecret
path: github.com/gopaddle-io/configurator/apis/configurator.gopaddle.io/v1alpha1
version: v1alpha1
version: "3"
112 changes: 19 additions & 93 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
[![Discord](https://discordapp.com/api/guilds/864856848279666730/widget.png?style=banner2)](https://discord.gg/dr24Z4BmP8)

# Configurator
Configurator is a version control and a sync service that keeps Kubernetes ConfigMaps and Secrets in sync with the deployment. Configurator uses CRDs to create CustomConfigMaps and CustomSecrets that in turn create ConfigMaps and Secrets with a postfix. As and when a change is detected in the CustomConfigMap or CustomSecret, Configurator automaticatlly generates a new ConfigMap with a new postfix. This acts like a version control for the ConfigMaps.
In order to keep the deployments and statefulsets in sync with the ConfigMap and Secret version, users must start with creating a CustomConfigMap as the first step. This creates a new ConfigMap with a postfix ie., first version. Users then have to reference the ConfigMap along with the postfix in their deployment and satefulset specifications. From them on, users can edit the CustomConfigMap directly. Any change in the CustomConfigMap will be automatically rolled out to all the deployments and statefulsets referencing the initial configMap version. A change in ConfigMap not only creates a new ConfigMap version, but also rolls out a new deployment version. This enables both rolling update and rollback of ConfigMaps in sync with the deployment versions.

Configurator is a version control and a sync service that keeps Kubernetes ConfigMaps and Secrets in sync with the deployments. When a ConfigMap content is changed, Configurator creates a custom resource of type CustomConfigMap (CCM) with a postfix. CCM with a postfix acts like ConfigMap revision. Configurator then copies the modified contents of the ConfigMap in to the CCM resource and triggers a rolling update on deployments using the ConfigMap. Configurator keeps the ConfigMap contents in sync with the deployment revisions with the help of annotations and works well for both rolling updates and rollbacks. Configurator supports GitOps workflows as well.

# Supported Versions
- K8s 1.16+
Expand All @@ -19,108 +17,36 @@ Check out the [Configurator website](https://gopaddle-io.github.io/configurator/

Join the community at our [discord server]((https://discord.gg/dr24Z4BmP8))

# How to use Configurator.

### Building and Deploying Configurator
Build the source code and the docker image for Configurator. Push the image to registry and deploy configurator in the cluster.
```sh
make clean build push deploy
```
# How to install Configurator
Configurator can be installed using Helm chart.

### Removing Configurator
Remove the configurator deployment from cluster and delete local binary and docker image
### Pre-requisite
* [Install Helm](https://helm.sh/docs/intro/install/)
* [Install kubectl in your local environment](https://kubernetes.io/docs/tasks/tools/)
* Add the contents of the Kubernetes configuration file to your local ~/.kube/config file
* Check if you could access your kubernetes cluster using kubectl command
```sh
make remove clean
$ kubectl version
```

### Deploy Configurator using YAML files
YAML files for deploying the latest version of Configurator is available under the deploy folder.You need to deploy the CRDs, the controller and the service/role binding.
```sh
kubectl apply -f deploy/crd-customConfigMap.yaml
kubectl apply -f deploy/crd-customSecret.yaml
kubectl create ns configurator
kubectl apply -f deploy/configurator-clusterrole.yaml
kubectl apply -f deploy/configurator-clusterrolebinding.yaml
kubectl apply -f deploy/configurator-serviceaccount.yaml
kubectl apply -f deploy/configurator-deployment.yaml
```
Verify if configurator resources are created successfully.
### Add configurator helm repository
Choose Configurator helm repostry based on the Configuration version. To use Configurator version 0.0.2, add the repo below:
```sh
kubectl get deployment -n configurator
NAME READY UP-TO-DATE AVAILABLE AGE
configurator-controller 1/1 1 1 4h38m
$ helm repo add gopaddle_configurator https://github.com/gopaddle-io/configurator/raw/v0.0.2/helm
```

### Using Configurator
Once configurator is deployed in the cluster, start creating customConfigMaps. Example customConfigMaps are available under artifacts/examples folder.
Create customConfigMap. This will create a configMap with a postfix.
```sh
kubectl apply -f artifacts/exmaples/example-customConfigMap.yaml
```
List the configMap and make a note of the postfix for the first time.
### Install configurator to cluster
To install Configurator in the cluster.
```sh
kubectl get configMap -n test
NAME DATA AGE
testconfig-srseq 1 9s
$ helm install configurator gopaddle_configurator/configurator --version 0.4.0-alpha
```
Here "srseq" is the postfix.
Create deployment referencing the newly created configMap and its postfix. Please note the deployment metadata label must contain the config name and the config postfix that was created initially. say <configname>=<postfix>. Under the VolumeMounts section use the complete name of the configMap along with the postfix.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: busybox-deployment
labels:
testconfig: srseq
app: busybox
spec:
replicas: 1
revisionHistoryLimit: 1
strategy:
type: RollingUpdate
selector:
matchLabels:
app: busybox
template:
metadata:
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Container 1 is Running ; sleep 3600']
volumeMounts:
- mountPath: /test
name: test-config
volumes:
- name: test-config
configMap:
name: testconfig-srseq
```
From now, you can directly update the customConfigMap and this will create a configMap with a new postfix and will automatically sync up the related deployments with the newly created configMap.
Same functionality applies for secrets as well.

### Listing and Viewing the Custom ConfigMaps and Secrets
### Removing Configurator
To remove Configurator from the cluster.
```sh
kubectl get ccm -n <namespace>
kubectl get customconfigmap -n <namespace>
kubectl describe ccm -n <namespace>
kubectl describe customconfigmap -n <namespace>
kubectl delete ccm -n <namespace>
kubectl delete customconfigmap -n <namespace>
kubectl get customsecret -n <namespace>
kubectl get ccs -n <namespace>
kubectl describe customsecret -n <namespace>
kubectl describe ccs -n <namespace>
kubectl delete customsecret -n <namespace>
kubectl delete ccs -n <namespace>
$ helm delete configurator gopaddle_configurator/configurator
```

### Architecture
<img src="https://gopaddle-marketing.s3.ap-southeast-2.amazonaws.com/configurartor-architecture.png">

### License

[Apache License Version 2.0](/LICENSE.md)
Expand All @@ -131,4 +57,4 @@ kubectl delete ccs -n <namespace>
3. Ensure the README is updated with any interface or architecture changes.

## Maintainers
Congurator is maintained by [gopaddle.io](https://gopaddle.io) team.
Configurator is maintained by [gopaddle.io](https://gopaddle.io) team.
Loading

0 comments on commit 52ca683

Please sign in to comment.