Skip to content
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

Add Dockerfile and initialization scripts for jac-cloud deployment #1528

Open
wants to merge 5 commits 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
16 changes: 16 additions & 0 deletions jac-cloud/scripts/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM python:3.12-slim

RUN apt-get update && \
apt-get install -y --no-install-recommends git && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

WORKDIR /app/littlex
RUN git clone --branch main --depth 1 https://github.com/Jaseci-Labs/littleX.git /app/littlex && \
pip install --no-cache-dir -r littleX_BE/requirements.txt openai jac-splice-orc

COPY init_jac_cloud.sh /app/
RUN chmod +x /app/init_jac_cloud.sh

EXPOSE 8000
CMD ["/bin/bash", "/app/init_jac_cloud.sh"]
186 changes: 186 additions & 0 deletions jac-cloud/scripts/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
## Usage Documentation for jac-cloud Deployment
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add this to rest of the jac documentation? @Jayanaka-98 and @savini98 can help point you towards how to do that.


### Overview
The `jac-cloud` deployment provides a Kubernetes-based system for running JAC applications using the `jac-splice-orc` plugin. This setup includes:
1. A Docker image with necessary dependencies.
2. A Kubernetes configuration for creating required resources like namespaces, service accounts, roles, and bindings.
3. Dynamic configuration through environment variables and ConfigMaps.

---

### Prerequisites
1. **Kubernetes Cluster**: Ensure you have access to a Kubernetes cluster.
2. **kubectl**: Install the Kubernetes command-line tool.
3. **Docker**: Build and push the `jac-cloud` Docker image if necessary.
4. **Namespace**: The target namespace should be created before deploying resources.
5. **OpenAI API Key**: Add your OpenAI API key in base64 format for secret management.

---

### Directory Structure
```
jac-cloud/
├── scripts/
│ ├── Dockerfile
│ ├── init_jac_cloud.sh
│ ├── jac-cloud.yml
│ ├── module-config.yml
```

---

### Step-by-Step Guide

#### 1. Build and Push the Docker Image
Build the `jac-cloud` Docker image using the `Dockerfile` in the `scripts` directory.

```bash
docker build -t your-dockerhub-username/jac-cloud:latest -f jac-cloud/scripts/Dockerfile .
docker push your-dockerhub-username/jac-cloud:latest
```

Update the `image` field in `jac-cloud.yml` with your Docker image path.

---
#### 2. Apply the ConfigMap for Dynamic Configuration
Apply the `module-config.yml` file to configure module-specific settings:

```bash
kubectl apply -f jac-cloud/scripts/module-config.yml
```
This will:
- Create the `littlex` namespace.

---

#### 3. Apply Namespace and Resources
Run the following command to apply the Kubernetes resources:

```bash
kubectl apply -f jac-cloud/scripts/jac-cloud.yml
```

This will:
- Set up RBAC roles and bindings.
- Deploy the `jac-cloud` application in the `littlex` namespace.

---

#### 4. Add the OpenAI API Key (Optional)
Replace `your-openai-key` with your actual API key, encode it in base64, and create the secret:

```bash
echo -n "your-openai-key" | base64
```

Replace the base64 value in the `data.openai-key` field of the secret definition in `jac-cloud.yml`, and then apply it:

```bash
kubectl apply -f jac-cloud/scripts/jac-cloud.yml
```

---

#### 5. Verify Deployment
Ensure that all resources are created successfully:

```bash
kubectl get all -n littlex
```

You should see the `jac-cloud` pod running along with associated resources.

---

### Configuration Details

#### 1. Environment Variables
| Variable | Description | Default Value |
|--------------------|------------------------------------------|---------------|
| `NAMESPACE` | Target namespace for the deployment. | `default` |
| `CONFIGMAP_NAME` | Name of the ConfigMap to mount. | `module-config` |
| `FILE_NAME` | JAC file to execute in the pod. | `example.jac` |
| `OPENAI_API_KEY` | OpenAI API key (retrieved from secret). | None |

---

#### 2. ConfigMap (`module-config.yml`)
Defines configuration for dynamically loaded modules:

```json
{
"numpy": {
"lib_mem_size_req": "100Mi",
"dependency": [],
"lib_cpu_req": "500m",
"load_type": "remote"
},
"transformers": {
"lib_mem_size_req": "2000Mi",
"dependency": ["torch", "transformers"],
"lib_cpu_req": "1.0",
"load_type": "remote"
},
"sentence_transformers": {
"lib_mem_size_req": "2000Mi",
"dependency": ["sentence-transformers"],
"lib_cpu_req": "1.0",
"load_type": "remote"
}
}
```

---

### Validation and Troubleshooting

#### Verify Namespace
Ensure the `littlex` namespace exists:
```bash
kubectl get namespaces
```

#### Verify ConfigMap
Check if the `module-config` ConfigMap is applied:
```bash
kubectl get configmap -n littlex
```

#### Verify Deployment
Ensure the `jac-cloud` pod is running:
```bash
kubectl get pods -n littlex
```

---

### Advanced Usage

#### Redeploying with Updated Configurations
To update the ConfigMap or deployment:
1. Modify the respective YAML file.
2. Apply the changes:
```bash
kubectl apply -f jac-cloud/scripts/module-config.yml
kubectl apply -f jac-cloud/scripts/jac-cloud.yml
```

#### Access Logs
Monitor the logs of the `jac-cloud` pod:
```bash
kubectl logs -f deployment/jac-cloud -n littlex
```

#### Scale the Deployment
To scale the `jac-cloud` deployment:
```bash
kubectl scale deployment jac-cloud --replicas=3 -n littlex
```

---

### Cleanup
To remove all resources:
```bash
kubectl delete namespace littlex
```
39 changes: 39 additions & 0 deletions jac-cloud/scripts/init_jac_cloud.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash

# Exit on any error
set -e

echo "=== Starting jac-cloud Pod Initialization ==="

# Default values for variables
NAMESPACE=${NAMESPACE:-default}
CONFIGMAP_NAME=${CONFIGMAP_NAME:-module-config}
FILE_NAME=${FILE_NAME:-example.jac}

# Display configuration
echo "Using Namespace: $NAMESPACE"
echo "Running Jac File: $FILE_NAME"

# Helper function for logging
log_info() {
echo "[INFO] $1"
}

log_error() {
echo "[ERROR] $1"
exit 1
}

# Step 1: Initialize Pod Manager and Kubernetes setup
log_info "Running orc_initialize for namespace: $NAMESPACE..."
if ! jac orc_initialize "$NAMESPACE"; then
log_error "orc_initialize failed. Exiting..."
fi
log_info "orc_initialize completed successfully."

# Step 2: Start Jac Serve
log_info "Starting Jac Serve with file: $FILE_NAME..."
if ! jac serve "$FILE_NAME"; then
log_error "Jac Serve failed. Exiting..."
fi

125 changes: 125 additions & 0 deletions jac-cloud/scripts/jac-cloud.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# 1. Namespace: littlex
apiVersion: v1
kind: Namespace
metadata:
name: littlex
---
# 2. ServiceAccount: jac-cloud-sa (in the littlex namespace)
apiVersion: v1
kind: ServiceAccount
metadata:
name: jac-cloud-sa
namespace: littlex
---
# 3. ClusterRole: Define permissions for the jac-cloud system
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: jac-cloud-cluster-role
rules:
# Core Kubernetes resources permissions
- apiGroups: [""]
resources:
- "namespaces"
- "pods"
- "services"
- "configmaps"
verbs: ["get", "list", "create", "delete", "watch", "patch", "update"]

# ServiceAccount permissions
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "list", "create", "delete", "watch", "patch", "update"]

# RBAC permissions
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["get", "list", "create", "delete", "watch", "patch", "update"]

# Apps API group for managing deployments
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "create", "delete", "watch", "patch", "update"]

# Allow access to secrets (e.g., for OpenAI API key)
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch"]
---
# 4. ClusterRoleBinding: Bind ClusterRole to the ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jac-cloud-cluster-role-binding
subjects:
- kind: ServiceAccount
name: jac-cloud-sa
namespace: littlex
roleRef:
kind: ClusterRole
name: jac-cloud-cluster-role
apiGroup: rbac.authorization.k8s.io
---
# 5. Deployment: jac-cloud application deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: jac-cloud
namespace: littlex
spec:
replicas: 1
selector:
matchLabels:
app: jac-cloud
template:
metadata:
labels:
app: jac-cloud
spec:
# Attach the ServiceAccount for RBAC
serviceAccountName: jac-cloud-sa
containers:
- name: jac-cloud
image: ashishmahendra/littlex:0.1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have to use a custom image? can we make this work with the python base image?

imagePullPolicy: Always

# Environment variables for dynamic configuration
env:
- name: CONFIG_FILE_PATH
value: "/cfg/module_config.json"
- name: NAMESPACE
value: "littlex"
- name: CONFIGMAP_NAME
value: "module-config"
- name: FILE_NAME
value: "littleX_BE/_archive/littleX_full.jac"
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: openai-secret
key: openai-key

# Mount ConfigMap for application configuration
volumeMounts:
- name: config-vol
mountPath: /cfg
volumes:
- name: config-vol
configMap:
name: module-config
items:
- key: module_config.json
path: module_config.json

# Restart policy
restartPolicy: Always
---
# 6. Secret: OpenAI API key (optional example for completeness)
apiVersion: v1
kind: Secret
metadata:
name: openai-secret
namespace: littlex
type: Opaque
data:
openai-key: "c2stcHJvai0xTnRDVGpoUDg4YTFCcFU0cXUyclQzQmxia0ZKRjh2NndqbHgzZDVRWWNrMjBubjY="
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this your key?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably omit this before we merge it.

Loading