This repository provides a complete guide and all the necessary scripts to set up a local Knative development environment on an Apple Silicon (ARM64) Mac. It uses Rancher Desktop, Minikube, and a custom Go application to demonstrate a real-world CloudEvents workflow.
The core of this setup is a robust shell script that automates the creation and destruction of a fully configured Knative cluster.
- Platform: macOS (Apple Silicon/ARM64)
- Container Runtime: Rancher Desktop v1.19.3
- Kubernetes: Minikube (latest) with Kubernetes
v1.32.6 - Knative: Serving & Eventing
v1.18.0 - Go:
v1.24
- Prerequisites
- Environment Setup
- The Go CloudEvents Application
- Build and Push the Application Image
- Deploy and Test the Knative Application
- Cleanup
Before you begin, you must install the following tools. We recommend using Homebrew for easy installation on macOS.
This provides the Docker environment that Minikube will use.
- Download and install Rancher Desktop.
- Important Configuration: During the first-run wizard or in
Preferences -> Container Engine, ensure you selectdockerd (moby)as the container runtime. This is required for Minikube's Docker driver.
If there is a docker.sock error export the following:
export DOCKER_HOST=unix:///$HOME/.rd/docker.sockMinikube defaults to 4 cpus and 7GB memory. Ensure Rancher Desktop has been setup 'Preferences' - 'Virtual Machine' - 'Hardware'. Set the '# CPUs' and 'Memory(GB)'.
function start_cluster() {
echo "--- 2. Starting Minikube Cluster (${CLUSTER_PROFILE}) ---"
minikube start \
--profile "${CLUSTER_PROFILE}" \
--driver=docker \
--cpus=4 \
--memory=7g \
--kubernetes-version=${KUBERNETES_VERSION}
minikube profile "${CLUSTER_PROFILE}"
echo "--- 3. Waiting for Kubernetes API server to be ready ---"
kubectl wait --for=condition=Available=True deployment/coredns -n kube-system --timeout=300s
}If you don't have Homebrew, install it first. Then, open your terminal and run:
# Install Go (for building the app)
brew install go
# Install Minikube (for the Kubernetes cluster)
brew install minikube
# Install the Knative CLI (kn)
brew install knkubectl and docker CLIs are automatically installed and configured by Rancher Desktop.
This step uses the provided script to create a fully configured Knative cluster on your machine.
git clone https://github.com/tomconn/knative.git
cd knativechmod +x scripts/manage-cluster.shRun the start command. This process will take several minutes as it downloads container images and sets up the cluster.
./scripts/manage-cluster.sh start🔑 Sudo Password: You will be prompted for your macOS password one time. This is required for minikube tunnel to create a network route from your Mac to the cluster, which is essential for accessing your services.
When the script finishes, you will have a ready-to-use Knative cluster with a "magic" sslip.io domain configured for easy access.
This repository includes a sample Go application (cmd/event-display/main.go) that acts as a sink for CloudEvents. It's designed to:
- Receive events via HTTP POST requests.
- Parse them using the official CloudEvents Go SDK.
- Log the event's type and source to the console.
It is built to be a native ARM64 binary for compatibility with Apple Silicon hardware.
To run our Go app in Knative, we need to build it into a container image and push it to a registry. We will use the GitHub Container Registry (ghcr.io).
Important: Because our local machine is ARM64, we will perform a multi-arch build. This creates an image that works on both ARM64 (like our Mac) and AMD64 (common in cloud environments).
You need a GitHub Personal Access Token (PAT) with write:packages scope.
- Create a PAT here.
- Log in via the Docker CLI, using your GitHub username and the PAT as the password.
# Replace <YOUR_GITHUB_USERNAME> with your actual username
export GITHUB_USER="<YOUR_GITHUB_USERNAME>"
export GITHUB_TOKEN="<YOUR_PERSONAL_ACCESS_TOKEN>"
echo $GITHUB_TOKEN | docker login ghcr.io -u $GITHUB_USER --password-stdinThe docker buildx command handles building for multiple platforms and pushing in a single step.
# Define the image name
export IMAGE_NAME="ghcr.io/${GITHUB_USER}/event-display:latest"
# Build for both ARM64 and AMD64 and push to the registry
docker buildx build \
--platform linux/arm64,linux/amd64 \
--tag $IMAGE_NAME \
--push \
.Your container image is now available at your public GitHub Packages repository.
Now we will deploy two Knative components:
- A
PingSourcethat generates a new CloudEvent every minute. - Our
event-displayservice to receive and log these events.
Create a file named deploy.yaml with the following content. Remember to replace <YOUR_GITHUB_USERNAME> with your actual GitHub username.
apiVersion: sources.knative.dev/v1
kind: PingSource
metadata:
name: cron-ping-source
spec:
schedule: "* * * * *" # Every minute
contentType: "application/json"
data: '{"message": "Hello from PingSource!"}'
sink:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: event-display
---
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: event-display
spec:
template:
spec:
containers:
- image: ghcr.io/<YOUR_GITHUB_USERNAME>/event-display:latestApply this configuration to your cluster:
kubectl apply -f deploy.yamlIf you haven't already, give the new script execute permissions.
chmod +x scripts/run-event-display.shExecute the script from the root of the project. It will handle cleaning up old resources, deploying the new ones, and verifying that the service starts correctly.
./scripts/run-event-display.shWait about a minute for the first ping event to be sent. We can watch the logs of our event-display pod to see the events as they arrive.
Once the script completes successfully, it will provide you with the final command needed to see your application in action.
-
Wait for the first event: The
PingSourceis configured to send an event once every minute. -
Watch the logs: Run the command provided by the script's output to follow the logs of your running container.
kubectl logs -l serving.knative.dev/service=event-display -c user-container --follow
You have successfully completed the entire workflow when you see the following output appear in your terminal, repeating every minute:
Received a CloudEvent!
- Type: dev.knative.sources.ping
- Source: /apis/v1/namespaces/default/pingsources/cron-ping-source
- Subject:
- Data: {"message":"Hello from Knative Eventing!"}
Congratulations! You have a fully working local Knative environment receiving and processing CloudEvents.
When you are finished, you can completely remove the cluster and all related resources by running the destroy command.
./scripts/manage-cluster.sh destroyThis will stop the tunnel process and delete the Minikube cluster, returning your system to a clean state.