Skip to content

(chore): steps to deploy in kubernetes cluster #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ NPM_VERSION ?= $(shell echo $(shell git describe --tags --always) | sed 's/^v//'
OSES = darwin linux windows
ARCHS = amd64 arm64

CONTAINER_ENGINE ?= podman
CONTAINER_REGISTRY ?= quay.io
CONTAINER_REPO ?= foo/kubernetes-mcp-server
CONTAINER_TAG ?= latest
CONTAINER_IMAGE := $(CONTAINER_REGISTRY)/$(CONTAINER_REPO):$(CONTAINER_TAG)

CLEAN_TARGETS :=
CLEAN_TARGETS += '$(BINARY_NAME)'
CLEAN_TARGETS += $(foreach os,$(OSES),$(foreach arch,$(ARCHS),$(BINARY_NAME)-$(os)-$(arch)$(if $(findstring windows,$(os)),.exe,)))
Expand All @@ -43,6 +49,8 @@ help: ## Display this help
clean: ## Clean up all build artifacts
rm -rf $(CLEAN_TARGETS)

##@ Build Targets

.PHONY: build
build: clean tidy format ## Build the project
go build $(COMMON_BUILD_ARGS) -o $(BINARY_NAME) ./cmd/kubernetes-mcp-server
Expand All @@ -54,6 +62,19 @@ build-all-platforms: clean tidy format ## Build the project for all platforms
GOOS=$(os) GOARCH=$(arch) go build $(COMMON_BUILD_ARGS) -o $(BINARY_NAME)-$(os)-$(arch)$(if $(findstring windows,$(os)),.exe,) ./cmd/kubernetes-mcp-server; \
))

.PHONY: image-build
image-build:
$(CONTAINER_ENGINE) build -t $(CONTAINER_IMAGE) .

.PHONY: image-push
image-push:
$(CONTAINER_ENGINE) push $(CONTAINER_IMAGE)

.PHONY: image
image: image-build image-push

##@ NPM Targets

.PHONY: npm-copy-binaries
npm-copy-binaries: build-all-platforms ## Copy the binaries to each npm package
$(foreach os,$(OSES),$(foreach arch,$(ARCHS), \
Expand All @@ -79,13 +100,24 @@ npm-publish: npm-copy-binaries ## Publish the npm packages
jq '.optionalDependencies |= with_entries(.value = "$(NPM_VERSION)")' ./npm/kubernetes-mcp-server/package.json > tmp.json && mv tmp.json ./npm/kubernetes-mcp-server/package.json; \
cd npm/kubernetes-mcp-server && npm publish

##@ Python Targets

.PHONY: python-publish
python-publish: ## Publish the python packages
cd ./python && \
sed -i "s/version = \".*\"/version = \"$(NPM_VERSION)\"/" pyproject.toml && \
uv build && \
uv publish

##@ Deployment Targets

.PHONY: kube-deploy
kube-deploy:
@echo "Deploying $(CONTAINER_IMAGE) to Kubernetes..."
IMAGE_TO_DEPLOY="$(CONTAINER_IMAGE)" envsubst '$$IMAGE_TO_DEPLOY' < deploy/kubernetes/deploy.yaml | kubectl apply -f -

##@ Utility Targets

.PHONY: test
test: ## Run the tests
go test -count=1 -v ./...
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ extensions:

```

### Native Kubernetes Application
[Deploy in Kubernetes.](./deploy/kubernetes/README.md)

## 🎥 Demos <a id="demos"></a>

### Diagnosing and automatically fixing an OpenShift Deployment
Expand Down Expand Up @@ -156,7 +159,7 @@ uvx kubernetes-mcp-server@latest --help
### Configuration Options

| Option | Description |
|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sse-port` | Starts the MCP server in Server-Sent Event (SSE) mode and listens on the specified port. |
| `--log-level` | Sets the logging level (values [from 0-9](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md)). Similar to [kubectl logging levels](https://kubernetes.io/docs/reference/kubectl/quick-reference/#kubectl-output-verbosity-and-debugging). |
| `--kubeconfig` | Path to the Kubernetes configuration file. If not provided, it will try to resolve the configuration (in-cluster, default location, etc.). |
Expand Down
90 changes: 90 additions & 0 deletions deploy/kubernetes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Kubernetes MCP Server Deployment

This guide explains how to deploy the "Kubernetes MCP Server" to a Kubernetes cluster.

## Prerequisites

1. **`envsubst`:** A utility for substituting environment variables in shell-format strings.
* Verify with: `envsubst --version`


## Deployment Steps

1. **Navigate to the Project Directory:**
Open your terminal and change to the root directory of this project where the `Makefile` is located.

1. **Set the Container Image (Optional):**
The `Makefile` is designed to use a `CONTAINER_IMAGE` variable.
* **Default Image:** If not specified, it defaults to `quay.io/foo/kubernetes-mcp-server:latest`.
* **Override Image:** You can specify a different container image and tag by setting the `CONTAINER_IMAGE` variable when running `make`.

1. **Build the Image:**
This command builds the container image and pushes it into the registry.

```bash
make image
```

1. **Deploy to Kubernetes:**
Run the following command:
```bash
make kube-deploy
```
Or, if overriding the image:
```bash
make kube-deploy CONTAINER_IMAGE=your-registry/your-image-name:your-tag
```

## Verifying the Deployment

Once the deployment is complete, you can verify that the application is running:

1. **Check Pods:**
The application runs in the `mcp-system` namespace.
```bash
kubectl get pods -n mcp-system
```
You should see a pod with a name like `kubernetes-mcp-server-xxxxxxxxxx-xxxxx` in a `Running` state.

2. **Check Service:**
```bash
kubectl get svc -n mcp-system
```
You should see the `kubernetes-mcp-server` service listed.

3. **View Logs:**
```bash
kubectl logs -n mcp-system -l app=kubernetes-mcp-server -f
```

## Accessing the Application

The `kubernetes-mcp-server` service is typically exposed within the cluster. To access it from your local machine, you can use `kubectl port-forward`.

**Port Forwarding:**

1. Open a new terminal window.
2. Run the following command to forward a local port (e.g., 8081) to the service's port (8080):
```bash
kubectl port-forward svc/kubernetes-mcp-server -n mcp-system 8081:8080
```
* `8081:8080`: Maps local port `8081` to the service's target port `8080`.

Keep this terminal window open. While `kubectl port-forward` is running, your server will be accessible on `http://localhost:8081`.


## Goose SSE Configuration

If you are using [Goose](https://block.github.io/goose/) to connect to Server-Sent Events (SSE) provided by the `kubernetes-mcp-server`, you can configure it as follows.

```yaml
extensions:
kubernetes-remote:
description: null
enabled: true
envs: {}
name: kubernetes-remote
timeout: 200 # Timeout in seconds for the SSE connection
type: sse
uri: http://localhost:8081/sse # Points to the local port forwarded to the k8s service
```
68 changes: 68 additions & 0 deletions deploy/kubernetes/deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
apiVersion: v1
kind: Namespace
metadata:
name: mcp-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubernetes-mcp-server
namespace: mcp-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubernetes-mcp-server
namespace: mcp-system
subjects:
- kind: ServiceAccount
name: kubernetes-mcp-server
namespace: mcp-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: edit
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: kubernetes-mcp-server
namespace: mcp-system
labels:
app: kubernetes-mcp-server
spec:
selector:
matchLabels:
app: kubernetes-mcp-server
replicas: 1
template:
metadata:
labels:
app: kubernetes-mcp-server
deployment: kubernetes-mcp-server
spec:
serviceAccountName: kubernetes-mcp-server
containers:
- name: server
image: ${IMAGE_TO_DEPLOY}
ports:
- name: http
containerPort: 8080
protocol: TCP
resources: {}
---
apiVersion: v1
kind: Service
metadata:
name: kubernetes-mcp-server
namespace: mcp-system
labels:
app: kubernetes-mcp-server
spec:
selector:
app: kubernetes-mcp-server
deployment: kubernetes-mcp-server
ports:
- port: 8080
targetPort: http
protocol: TCP