Skip to content

Commit

Permalink
Add kubemark provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Ben Moss committed Oct 22, 2020
1 parent be5ff75 commit 0991602
Show file tree
Hide file tree
Showing 72 changed files with 4,897 additions and 0 deletions.
28 changes: 28 additions & 0 deletions test/infrastructure/kubemark/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Build the manager binary
FROM golang:1.13 as builder

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

# Copy the go source
COPY main.go main.go
COPY api/ api/
COPY controllers/ controllers/
COPY util/ util/

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on 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 nonroot:nonroot

ENTRYPOINT ["/manager"]
178 changes: 178 additions & 0 deletions test/infrastructure/kubemark/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@

# Image URL to use all building/pushing image targets
IMAGE_NAME ?= cluster-api-kubemark-controller
TAG ?= dev
ARCH ?= amd64
PROD_REGISTRY := gcr.io/k8s-staging-cluster-api
CONTROLLER_IMG ?= $(PROD_REGISTRY)/$(IMAGE_NAME)
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
CRD_OPTIONS ?= "crd:trivialVersions=true"

# 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

all: manager

# Run tests
test: generate fmt vet manifests
go test ./... -coverprofile cover.out

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

# Run against the configured Kubernetes cluster in ~/.kube/config
run: generate fmt vet manifests
go run ./main.go

# Install CRDs into a cluster
install: manifests
kustomize build config/crd | kubectl apply -f -

# Uninstall CRDs from a cluster
uninstall: manifests
kustomize build config/crd | kubectl delete -f -

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

# Generate manifests e.g. CRD, RBAC etc.
manifests: controller-gen
$(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." crd:crdVersions=v1 output:crd:artifacts:config=config/crd/bases

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

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

# Generate code
generate: controller-gen
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

# Build the docker image
docker-build: test
$(MAKE) ARCH=$(ARCH) docker-build-core

.PHONY: docker-build-core
docker-build-core: ## Build the docker image for controller-manager
docker build --pull --build-arg ARCH=$(ARCH) --build-arg LDFLAGS="$(LDFLAGS)" . -t $(CONTROLLER_IMG)-$(ARCH):$(TAG)
$(MAKE) set-manifest-image MANIFEST_IMG=$(CONTROLLER_IMG)-$(ARCH) MANIFEST_TAG=$(TAG) TARGET_RESOURCE="./config/manager/manager_image_patch.yaml"
$(MAKE) set-manifest-pull-policy TARGET_RESOURCE="./config/manager/manager_pull_policy.yaml"

# Push the docker image
.PHONY: docker-push
docker-push: ## Push the docker image
docker push $(CONTROLLER_IMG)-$(ARCH):$(TAG)

# find or download controller-gen
# download controller-gen if necessary
controller-gen:
ifeq (, $(shell which controller-gen))
@{ \
set -e ;\
CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
cd $$CONTROLLER_GEN_TMP_DIR ;\
go mod init tmp ;\
go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.5 ;\
rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
}
CONTROLLER_GEN=$(GOBIN)/controller-gen
else
CONTROLLER_GEN=$(shell which controller-gen)
endif

## --------------------------------------
## Release
## --------------------------------------
ROOT_DIR_RELATIVE := .

include $(ROOT_DIR_RELATIVE)/common.mk

TOOLS_DIR := hack/tools
TOOLS_DIR_DEPS := $(TOOLS_DIR)/go.sum $(TOOLS_DIR)/go.mod $(TOOLS_DIR)/Makefile
TOOLS_BIN_DIR := $(TOOLS_DIR)/bin
KUSTOMIZE := $(TOOLS_BIN_DIR)/kustomize

PATH := $(abspath $(TOOLS_BIN_DIR)):$(PATH)

export PATH

RELEASE_DIR := out

$(RELEASE_DIR):
mkdir -p $@

PULL_POLICY ?= Always

.PHONY: release
release: clean-release ## Builds and push container images using the latest git tag for the commit.
@if [ -z "${RELEASE_TAG}" ]; then echo "RELEASE_TAG is not set"; exit 1; fi
@if ! [ -z "$$(git status --porcelain)" ]; then echo "Your local git repository contains uncommitted changes, use git clean before proceeding."; exit 1; fi
git checkout "${RELEASE_TAG}"
# Set the manifest image to the production bucket.
$(MAKE) set-manifest-image \
MANIFEST_IMG=$(PROD_REGISTRY)/$(IMAGE_NAME) MANIFEST_TAG=$(RELEASE_TAG) \
TARGET_RESOURCE="./config/manager/manager_image_patch.yaml" # Set manifest image for EKS bootstrap provider to the production bucket.
$(MAKE) set-manifest-pull-policy PULL_POLICY=IfNotPresent TARGET_RESOURCE="./config/manager/manager_pull_policy.yaml"
$(MAKE) release-manifests
$(MAKE) release-templates
# Add metadata to the release artifacts
cp metadata.yaml $(RELEASE_DIR)/metadata.yaml

.PHONY: release-manifests
release-manifests: $(RELEASE_DIR) $(KUSTOMIZE) ## Builds the manifests to publish with a release
$(KUSTOMIZE) build config > $(RELEASE_DIR)/infrastructure-components.yaml

.PHONY: set-manifest-image
set-manifest-image:
$(info Updating kustomize image patch file for manager resource)
sed -i'' -e 's@image: .*@image: '"${MANIFEST_IMG}:$(MANIFEST_TAG)"'@' $(TARGET_RESOURCE)

.PHONY: release-templates
release-templates: $(RELEASE_DIR)
cp templates/cluster-template.yaml $(RELEASE_DIR)/cluster-template.yaml
cp templates/cluster-template-capd.yaml $(RELEASE_DIR)/cluster-template-capd.yaml

.PHONY: clean-release
clean-release: ## Remove the release folder
rm -rf $(RELEASE_DIR)

.PHONY: set-manifest-pull-policy
set-manifest-pull-policy:
$(info Updating kustomize pull policy file for manager resources)
sed -i'' -e 's@imagePullPolicy: .*@imagePullPolicy: '"$(PULL_POLICY)"'@' $(TARGET_RESOURCE)

ALL_ARCH = amd64 arm arm64 ppc64le s390x

.PHONY: docker-build-all ## Build all the architecture docker images
docker-build-all: $(addprefix docker-build-,$(ALL_ARCH))

docker-build-%:
$(MAKE) ARCH=$* docker-build

docker-push-%:
$(MAKE) ARCH=$* docker-push

.PHONY: docker-push-all ## Push all the architecture docker images
docker-push-all: $(addprefix docker-push-,$(ALL_ARCH))
$(MAKE) docker-push-core-manifest

export DOCKER_CLI_EXPERIMENTAL=enabled

.PHONY: docker-push-core-manifest
docker-push-core-manifest: ## Push the fat manifest docker image.
## Minimum docker version 18.06.0 is required for creating and pushing manifest images.
docker manifest create --amend $(CONTROLLER_IMG):$(TAG) $(shell echo $(ALL_ARCH) | sed -e "s~[^ ]*~$(CONTROLLER_IMG)\-&:$(TAG)~g")
@for arch in $(ALL_ARCH); do docker manifest annotate --arch $${arch} ${CONTROLLER_IMG}:${TAG} ${CONTROLLER_IMG}-$${arch}:${TAG}; done
docker manifest push --purge ${CONTROLLER_IMG}:${TAG}
$(MAKE) set-manifest-image MANIFEST_IMG=$(CONTROLLER_IMG)-$(ARCH) MANIFEST_TAG=$(TAG) TARGET_RESOURCE="./config/manager/manager_image_patch.yaml"
$(MAKE) set-manifest-pull-policy TARGET_RESOURCE="./config/manager/manager_pull_policy.yaml"
10 changes: 10 additions & 0 deletions test/infrastructure/kubemark/PROJECT
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
domain: cluster.x-k8s.io
repo: github.com/benmoss/cluster-api-provider-kubemark
resources:
- group: infrastructure
kind: KubemarkMachine
version: v1alpha3
- group: infrastructure
kind: KubemarkMachineTemplate
version: v1alpha3
version: "2"
86 changes: 86 additions & 0 deletions test/infrastructure/kubemark/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
```
________ __ ___ ____ ____
/ ____/ /_ _______/ /____ _____ / | / __ \/ _/
/ / / / / / / ___/ __/ _ \/ ___/ / /| | / /_/ // /
/ /___/ / /_/ (__ ) /_/ __/ / / ___ |/ ____// /
\____/_/\__,_/____/\__/\___/_/ /_/ |_/_/ /___/
____ _ __
/ __ \_________ _ __(_)___/ /__ ______
/ /_/ / ___/ __ \ | / / / __ / _ \/ ___(_)
/ ____/ / / /_/ / |/ / / /_/ / __/ / _
/_/ /_/ \____/|___/_/\__,_/\___/_/ (_)
__ __ __ __
/ //_/_ __/ /_ ___ ____ ___ ____ ______/ /__
/ ,< / / / / __ \/ _ \/ __ `__ \/ __ `/ ___/ //_/
/ /| / /_/ / /_/ / __/ / / / / / /_/ / / / ,<
/_/ |_\__,_/_.___/\___/_/ /_/ /_/\__,_/_/ /_/|_|
```

## What is the Cluster API Provider Kubemark

Cluster API Provider Kubemark (CAPK) is a provider for [Cluster
API][cluster_api] (CAPI) that allows users to deploy fake, [Kubemark][kubemark_docs]-backed machines to their
clusters. This is useful in a variety of scenarios, such load-testing and
simulation testing.

It is slightly similar to [CAPD][capd], the Docker
provider, in that it does not deploy actual infrastructure resources (VMs or
bare-metal machines). It differs significantly in that Kubemark nodes only
pretend to run pods scheduled to them. For more information on Kubemark, the
[Kubemark developer guide][kubemark_docs] has more details.

## Getting started
At this point the Kubemark provider is extremely alpha. To deploy the Kubemark
provider, you can add the latest release to your clusterctl config file, by
default located at `~/.cluster-api/clusterctl.yaml`.

```yaml
providers:
- name: "kubemark"
url: "https://github.com/benmoss/cluster-api-provider-kubemark/releases/latest/infrastructure-components.yaml"
type: "InfrastructureProvider"
```
For demonstration purposes, we'll use the [CAPD][capd] provider. Other
providers will also work, but CAPD is supported with a custom
[template](templates/cluster-template-capd.yaml) that makes deployment super
simple.
Initialize this provider into your cluster by running:
```bash
clusterctl init --infrastructure kubemark,capd
```

Once initialized, you'll need to deploy your workload cluster using the `capd`
flavor to get a hybrid CAPD/CAPK cluster:

```bash
clusterctl config cluster wow --infrastructure kubemark --flavor capd --kubernetes-version 1.19.1 --control-plane-machine-count=1 --worker-machine-count=4 | kubectl apply -f-
```

You should see your cluster come up and quickly become available with 4 Kubemark machines connected to your CAPD control plane.

For other providers, you can either create a custom hybrid cluster template, or deploy the control plane and worker machines separately, specifiying the same cluster name:

```bash
clusterctl config cluster wow --infrastructure aws --kubernetes-version 1.19.1 --control-plane-machine-count=1 | kubectl apply -f-
clusterctl config cluster wow --infrastructure kubemark --kubernetes-version 1.19.1 --worker-machine-count=4 | kubectl apply -f-
```

## Using tilt
To deploy the Kubemark provider, the recommended way at this time is using
[Tilt][tilt]. Clone this repo and use the [CAPI tilt guide][capi_tilt] to get
Tilt setup. Add `kubemark` to the list of providers in your
`tilt-settings.json` file and you should be off to the races.

<!-- References -->

[capd]: https://github.com/kubernetes-sigs/cluster-api/tree/master/test/infrastructure/docker
[kubemark_docs]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scalability/kubemark-guide.md
[cluster_api]: https://github.com/kubernetes-sigs/cluster-api
[tilt]: https://tilt.dev
[capi_tilt]: https://master.cluster-api.sigs.k8s.io/developer/tilt.html
41 changes: 41 additions & 0 deletions test/infrastructure/kubemark/api/v1alpha3/condition_consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
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 v1alpha3

import clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"

const (
// InstanceReadyCondition reports on current status of the EC2 instance. Ready indicates the instance is in a Running state.
InstanceReadyCondition clusterv1.ConditionType = "InstanceReady"

// InstanceNotFoundReason used when the instance couldn't be retrieved.
InstanceNotFoundReason = "InstanceNotFound"
// InstanceTerminatedReason instance is in a terminated state.
InstanceTerminatedReason = "InstanceTerminated"
// InstanceStoppedReason instance is in a stopped state.
InstanceStoppedReason = "InstanceStopped"
// InstanceNotReadyReason used when the instance is in a pending state.
InstanceNotReadyReason = "InstanceNotReady"
// InstanceProvisionStartedReason set when the provisioning of an instance started.
InstanceProvisionStartedReason = "InstanceProvisionStarted"
// InstanceProvisionFailedReason used for failures during instance provisioning.
InstanceProvisionFailedReason = "InstanceProvisionFailed"
// WaitingForClusterInfrastructureReason used when machine is waiting for cluster infrastructure to be ready before proceeding.
WaitingForClusterInfrastructureReason = "WaitingForClusterInfrastructure"
// WaitingForBootstrapDataReason used when machine is waiting for bootstrap data to be ready before proceeding.
WaitingForBootstrapDataReason = "WaitingForBootstrapData"
)
36 changes: 36 additions & 0 deletions test/infrastructure/kubemark/api/v1alpha3/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
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 v1alpha3 contains API Schema definitions for the infrastructure v1alpha3 API group
// +kubebuilder:object:generate=true
// +groupName=infrastructure.cluster.x-k8s.io
package v1alpha3

import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "infrastructure.cluster.x-k8s.io", Version: "v1alpha3"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
Loading

0 comments on commit 0991602

Please sign in to comment.