Skip to content

Commit

Permalink
feat: Take k8s manifest as input instead of docker compose (#30)
Browse files Browse the repository at this point in the history
The Kardinal CLI now takes as input a K8S manifest containing pairs of
Service / Deployment specs. Those objects are added to the flow requests
sent to the kontrol service.

K8S manifest:

```
apiVersion: v1
kind: Service
metadata:
  labels:
    app: redis-prod
    version: v1
  name: redis-prod
  namespace: voting-app
spec:
  ports:
    - name: tcp-redis
      port: 6379
      protocol: TCP
      targetPort: 6379
  selector:
    app: redis-prod
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: redis-prod
    version: v1
  name: redis-prod-v1
  namespace: voting-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis-prod
      version: v1
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "true"
      labels:
        app: redis-prod
        version: v1
    spec:
      containers:
        - name: redis-prod
          image: bitnami/redis:6.0.8
          env:
            - name: ALLOW_EMPTY_PASSWORD
              value: "yes"
            - name: REDIS_PORT_NUMBER
              value: "6379"
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 250m
              memory: 256Mi
          ports:
            - containerPort: 6379
              name: redis

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: voting-app-ui
    version: v1
  name: voting-app-ui
  namespace: voting-app
spec:
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: 80
---
apiVersion: v1
  selector:
    app: voting-app-ui
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: voting-app-ui
    version: v1
  name: voting-app-ui-v1
  namespace: voting-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: voting-app-ui
      version: v1
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "true"
      labels:
        app: voting-app-ui
        version: v1
    spec:
      containers:
        - name: azure-vote-front
          image: voting-app-ui
          imagePullPolicy: IfNotPresent
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 250m
              memory: 256Mi
          ports:
            - containerPort: 80
          env:
            - name: REDIS
              value: "redis-prod"
```

POST request:

```
### POST ('127.0.0.1', 62359) - HTTP/1.1 - /tenant/a1bc5679-db0b-4468-b2fb-6d9e47aa2910/flow/create

### Headers ###
Host: localhost:8080
User-Agent: Go-http-client/1.1
Content-Length: 2394
Content-Type: application/json
Accept-Encoding: gzip

### POST content ###
{
  "image-locator": "voting-app",
  "service-configs": [
    {
      "deployment": {
        "kind": "Deployment",
        "apiVersion": "apps/v1",
        "metadata": {
          "name": "redis-prod-v1",
          "namespace": "voting-app",
          "creationTimestamp": null,
          "labels": {
            "app": "redis-prod",
            "version": "v1"
          }
        },
        "spec": {
          "replicas": 1,
          "selector": {
            "matchLabels": {
              "app": "redis-prod",
              "version": "v1"
            }
          },
          "template": {
            "metadata": {
              "creationTimestamp": null,
              "labels": {
                "app": "redis-prod",
                "version": "v1"
              },
              "annotations": {
                "sidecar.istio.io/inject": "true"
              }
            },
            "spec": {
              "containers": [
                {
                  "name": "redis-prod",
                  "image": "bitnami/redis:6.0.8",
                  "ports": [
                    {
                      "name": "redis",
                      "containerPort": 6379
                    }
                  ],
                  "env": [
                    {
                      "name": "ALLOW_EMPTY_PASSWORD",
                      "value": "yes"
                    },
                    {
                      "name": "REDIS_PORT_NUMBER",
                      "value": "6379"
                    }
                  ],
                  "resources": {
                    "limits": {
                      "cpu": "250m",
                      "memory": "256Mi"
                    },
                    "requests": {
                      "cpu": "100m",
                      "memory": "128Mi"
                    }
                  }
                }
              ]
            }
          },
          "strategy": {
            "type": "RollingUpdate",
            "rollingUpdate": {
              "maxUnavailable": "25%",
              "maxSurge": "25%"
            }
          }
        },
        "status": {}
      },
      "service": {
        "kind": "Service",
        "apiVersion": "v1",
        "metadata": {
          "name": "redis-prod",
          "namespace": "voting-app",
          "creationTimestamp": null,
          "labels": {
            "app": "redis-prod",
            "version": "v1"
          }
        },
        "spec": {
          "ports": [
            {
              "name": "tcp-redis",
              "protocol": "TCP",
              "port": 6379,
              "targetPort": 6379
            }
          ],
          "selector": {
            "app": "redis-prod"
          }
        },
        "status": {
          "loadBalancer": {}
        }
      }
    },
    {
      "deployment": {
        "kind": "Deployment",
        "apiVersion": "apps/v1",
        "metadata": {
          "name": "voting-app-ui-v1",
          "namespace": "voting-app",
          "creationTimestamp": null,
          "labels": {
            "app": "voting-app-ui",
            "version": "v1"
          }
        },
        "spec": {
          "replicas": 1,
          "selector": {
            "matchLabels": {
              "app": "voting-app-ui",
              "version": "v1"
            }
          },
          "template": {
            "metadata": {
              "creationTimestamp": null,
              "labels": {
                "app": "voting-app-ui",
                "version": "v1"
              },
              "annotations": {
                "sidecar.istio.io/inject": "true"
              }
            },
            "spec": {
              "containers": [
                {
                  "name": "azure-vote-front",
                  "image": "voting-app-ui",
                  "ports": [
                    {
                      "containerPort": 80
                    }
                  ],
                  "env": [
                    {
                      "name": "REDIS",
                      "value": "redis-prod"
                    }
                  ],
                  "resources": {
                    "limits": {
                      "cpu": "250m",
                      "memory": "256Mi"
                    },
                    "requests": {
                      "cpu": "100m",
                      "memory": "128Mi"
                    }
                  },
                  "imagePullPolicy": "IfNotPresent"
                }
              ]
            }
          },
          "strategy": {
            "type": "RollingUpdate",
            "rollingUpdate": {
              "maxUnavailable": "25%",
              "maxSurge": "25%"
            }
          }
        },
        "status": {}
      },
      "service": {
        "kind": "Service",
        "apiVersion": "v1",
        "metadata": {
          "name": "voting-app-ui",
          "namespace": "voting-app",
          "creationTimestamp": null,
          "labels": {
            "app": "voting-app-ui",
            "version": "v1"
          }
        },
        "spec": {
          "ports": [
            {
              "name": "http",
              "protocol": "TCP",
              "port": 80,
              "targetPort": 80
            }
          ],
          "selector": {
            "app": "voting-app-ui"
          }
        },
        "status": {
          "loadBalancer": {}
        }
      }
    }
  ],
  "service-name": "voting-app"
}

127.0.0.1 - - [10/Jul/2024 14:24:07] "POST /tenant/a1bc5679-db0b-4468-b2fb-6d9e47aa2910/flow/create HTTP/1.1" 200 -
```
  • Loading branch information
laurentluce authored Jul 12, 2024
1 parent f71df5b commit 4bcda1f
Show file tree
Hide file tree
Showing 16 changed files with 337 additions and 349 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ INFO[0000] Using tenant UUID 58d33536-3c9e-4110-aa83-bf112ae94a49
3. Deploy the voting-app application with Kardinal

```bash
kardinal deploy --docker-compose ./examples/voting-app/docker-compose.yaml
kardinal deploy --k8s-manifest ./examples/voting-app/k8s-manifest.yaml
```

4. Check the current topology in the cloud Kontrol FE using this URL: https://app.kardinal.dev/{use-your-tenant-UUID-here}/traffic-configuration
Expand All @@ -144,7 +144,7 @@ minikube tunnel
1. Create a new flow to test a development `voting-app-ui-v2` version in production

```bash
kardinal flow create voting-app-ui kurtosistech/demo-voting-app-ui-v2 --docker-compose ./examples/voting-app/docker-compose.yaml
kardinal flow create voting-app-ui kurtosistech/demo-voting-app-ui-v2 --k8s-manifest ./examples/voting-app/k8s-manifest.yaml
```

2. Check how the topology has changed, to reflect both prod and the dev version, in the cloud Kontrol FE using this URL: https://app.kardinal.dev/{use-your-tenant-UUID-here}/traffic-configuration
Expand All @@ -155,7 +155,7 @@ kardinal flow create voting-app-ui kurtosistech/demo-voting-app-ui-v2 --docker-c
1. Remove the flow created for the `voting-app-ui-v2`

```bash
kardinal flow delete --docker-compose ./examples/voting-app/docker-compose.yaml
kardinal flow delete --k8s-manifest ./examples/voting-app/k8s-manifest.yaml
```

2. Check the topology again to, it's showing only the production version as the beginning, in the cloud Kontrol FE using this URL: https://app.kardinal.dev/{use-your-tenant-UUID-here}/traffic-configuration
Expand Down Expand Up @@ -226,7 +226,7 @@ cd kardinal-playground/voting-app-demo
6. Deploy the voting-app application with Kardinal:

```bash
kardinal deploy --docker-compose docker-compose.yaml
kardinal deploy --k8s-manifest k8s-manifest.yaml
```

7. Check the initial Kardinal traffic configuration:
Expand Down Expand Up @@ -261,7 +261,7 @@ This will set up port-forwarding for the production version of the voting app.
12. To create a new development flow:

```bash
kardinal flow create voting-app-ui voting-app-ui-dev -d compose.yml
kardinal flow create voting-app-ui voting-app-ui-dev --k8s-manifest k8s-manifest.yml
```

13. After creating the development flow, check the Kardinal traffic configuration again:
Expand All @@ -281,7 +281,7 @@ Now you can access both the production and development versions:
15. To remove the development flow:

```bash
kardinal flow delete -d compose.yml
kardinal flow delete --k8s-manifest k8s-manifest.yml
```

16. After deleting the development flow, check the Kardinal traffic configuration once more:
Expand Down
124 changes: 124 additions & 0 deletions examples/voting-app/k8s-manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: redis-prod
version: v1
name: redis-prod
namespace: voting-app
spec:
ports:
- name: tcp-redis
port: 6379
protocol: TCP
targetPort: 6379
selector:
app: redis-prod
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: redis-prod
version: v1
name: redis-prod-v1
namespace: voting-app
spec:
replicas: 1
selector:
matchLabels:
app: redis-prod
version: v1
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations:
sidecar.istio.io/inject: "true"
labels:
app: redis-prod
version: v1
spec:
containers:
- name: redis-prod
image: bitnami/redis:6.0.8
env:
- name: ALLOW_EMPTY_PASSWORD
value: "yes"
- name: REDIS_PORT_NUMBER
value: "6379"
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
ports:
- containerPort: 6379
name: redis

---
apiVersion: v1
kind: Service
metadata:
labels:
app: voting-app-ui
version: v1
name: voting-app-ui
namespace: voting-app
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: voting-app-ui
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: voting-app-ui
version: v1
name: voting-app-ui-v1
namespace: voting-app
spec:
replicas: 1
selector:
matchLabels:
app: voting-app-ui
version: v1
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations:
sidecar.istio.io/inject: "true"
labels:
app: voting-app-ui
version: v1
spec:
containers:
- name: voting-app-ui
image: kurtosistech/demo-voting-app-ui
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
ports:
- containerPort: 80
env:
- name: REDIS
value: "redis-prod"
Loading

0 comments on commit 4bcda1f

Please sign in to comment.