Skip to content

Commit

Permalink
Adds helm chart (#245)
Browse files Browse the repository at this point in the history
* Adds helm chart
* Update README
* Adds workflow to publish helm chart
* Add workflow to lint helm chart on PRs
  • Loading branch information
marcinc authored Jun 21, 2022
1 parent 6ef032a commit d0f3c31
Show file tree
Hide file tree
Showing 15 changed files with 693 additions and 55 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/helm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
name: Publish Chart

on:
push:
branches:
- master

jobs:
release-helm-chart:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Install Helm
uses: azure/setup-helm@v1
with:
version: v3.8.1
- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.4.0
env:
CR_SKIP_EXISTING: true
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
29 changes: 29 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
name: Lint

on:
pull_request:
types: [opened, reopened, synchronize]

permissions:
contents: read

jobs:
helm:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Helm
uses: azure/setup-helm@v1
with:
version: v3.8.1
- uses: actions/setup-python@v2
with:
python-version: 3.7
- name: Set up chart-testing
uses: helm/chart-testing-action@v2.2.1
- name: Run chart-testing (lint)
run: ct lint
130 changes: 75 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
![Stability:Beta](https://img.shields.io/badge/stability-beta-orange)
![CircleCI](https://img.shields.io/circleci/build/github/appvia/krane/master)
[![GitHub tag (latest SemVer)](https://img.shields.io/github/v/release/appvia/krane)](https://github.com/appvia/krane/releases/latest)
![License: Apache-2.0](https://img.shields.io/github/license/appvia/kore)
![License: Apache-2.0](https://img.shields.io/github/license/appvia/krane)
![Docker Repository on Quay.io](https://img.shields.io/badge/container-ready-brightgreen)

_Krane_ is a simple Kubernetes RBAC static analysis tool. It identifies potential security risks in K8s RBAC design and makes suggestions on how to mitigate them. _Krane_ dashboard presents current RBAC security posture and lets you navigate through its definition.
Expand Down Expand Up @@ -55,14 +55,14 @@ _Krane_ docker image will be pre-built automatically if not already present on l

Note that when running `docker-compose` locally, _Krane_ won't start RBAC _report_ and _dashboard_ automatically. Instead, the container will sleep for 24h by default - this value can be adjusted in `docker-compose.override.yml`. Exec into a running _Krane_ container to run commands. Local `docker-compose` will also mount kube config (`~/.kube/config`) inside the container enabling you to run reports against any Kubernetes clusters to which you already have access to.

Exec into a running Krane container.
```sh
# Exec into a running Krane container

docker-compose exec krane bash
```

# Once in the container you can start using `krane` commands. Try `krane -help`.

$ krane -h
Once in the container you can start using `krane` commands. Try `krane -help`.
```sh
krane -h
```

To inspect what services are running and the associated ports:
Expand Down Expand Up @@ -136,6 +136,13 @@ NOTE: _Krane_ expects the following files (in either YAML or JSON format) to be
- rolebindings
- clusterrolebindings

If Pod Security Policies are not in use you may bypass the expectation above by creating a `psp` file manually with the following content:
```json
{
"items": []
}
```

#### Inside a Kubernetes cluster

To run a report from a container running in Kubernetes cluster
Expand Down Expand Up @@ -417,9 +424,50 @@ You may control certain aspects of in-cluster execution with the following envir

### Local or Remote K8s Cluster

If your K8s cluster comes with built-in [Compose-on-Kubernetes](https://github.com/docker/compose-on-kubernetes) controller support (`docker-desktop` supports it by default), then you can deploy _Krane_ and its dependencies with a single [docker stack](https://docs.docker.com/engine/reference/commandline/stack_deploy/) command:
#### Helm Chart

Before we begin, you'll need the following tools:
* [Helm CLI](https://helm.sh/docs/intro/install/)

Install helm chart:
```sh
$ helm repo add appvia https://appvia.github.io/krane
$ helm repo update
$ helm install krane appvia/krane --namespace krane --create-namespace --set image.tag=latest
```

See [values.yaml](helm/krane/values.yaml) file for details of other settable options and parameters.

#### K8s manifests

```sh
kubectl create \
--context <docker-desktop> \
--namespace krane \
-f k8s/redisgraph-service.yaml \
-f k8s/redisgraph-deployment.yaml \
-f k8s/krane-service.yaml \
-f k8s/krane-deployment.yaml
```

Note that _Krane_ dashboard service is not exposed by default!
```sh
kubectl port-forward svc/krane 8000 \
--context=<docker-desktop> \
--namespace=krane

# Open Krane dashboard at http://localhost:8000
```

You can find the example deployment manifests in [k8s](k8s/) directory.

Modify manifests as required for your deployments making sure you reference the correct version of _Krane_ docker image in its [deployment file](k8s/krane-deployment.yml). See [Krane Docker Registry](https://quay.io/repository/appvia/krane?tab=tags) for available tags, or just use `latest`.

#### Compose-on-Kubernetes

If your K8s cluster comes with built-in [Compose-on-Kubernetes](https://github.com/docker/compose-on-kubernetes) controller support (`docker-desktop` supports it by default), then you can deploy _Krane_ and its dependencies with a single [docker stack](https://docs.docker.com/engine/reference/commandline/stack_deploy/) command:

```sh
docker stack deploy \
--orchestrator kubernetes \
--namespace krane \
Expand All @@ -431,58 +479,30 @@ Note: Make sure your current kube context is set correctly prior to running the

The application Stack should be now deployed to a Kubernetes cluster and all services ready and exposed. Note that _Krane_ will automatically start its report loop and dashboard server.

```sh
docker stack services --orchestrator kubernetes --namespace krane krane
```
$ docker stack services --orchestrator kubernetes --namespace krane krane

Command above will produce the following output:
```
ID NAME MODE REPLICAS IMAGE PORTS
0de30651-dd5 krane_redisgraph replicated 1/1 redislabs/redisgraph:1.99.7 *:6379->6379/tcp
aa377a5f-62b krane_krane replicated 1/1 quay.io/appvia/krane:latest *:8000->8000/tcp
```

Check your Kubernetes cluster RBAC security posture by visiting
```
http://localhost:8000
```
Check your Kubernetes cluster RBAC security posture by visiting http://localhost:8000.

Note that for remote cluster deployments you'll likely need to port-forward _Krane_ service first
```
```sh
kubectl --context=my-remote-cluster --namespace=krane port-forward svc/krane 8000
```

To delete the Stack
```
```sh
docker stack rm krane \
--orchestrator kubernetes \
--namespace krane
```

Alternatively, deploy with [kubectl](https://kubectl.docs.kubernetes.io/):

```
kubectl create \
--context docker-desktop \
--namespace krane \
-f k8s/redisgraph-service.yaml \
-f k8s/redisgraph-deployment.yaml \
-f k8s/krane-service.yaml \
-f k8s/krane-deployment.yaml
```

Note that _Krane_ dashboard services are not exposed by default!
```sh
kubectl port-forward svc/krane 8000 \
--context=docker-desktop \
--namespace=krane

# Open Krane dashboard

http://localhost:8000
```

You can find the example deployment manifests in [k8s](k8s/) directory.

Modify manifests as required for your deployments making sure you reference the correct version of _Krane_ docker image in its [deployment file](k8s/krane-deployment.yml). See [Krane Docker Registry](https://quay.io/repository/appvia/krane?tab=tags) for available tags, or just use `latest`.

## Notifications

Krane will notify you about detected anomalies of medium and high severity via its Slack integration.
Expand All @@ -496,25 +516,25 @@ This section describes steps to enable local development.
### Setup

Install _Krane_ code dependencies with
```
```sh
./bin/setup
```

### Dependencies

_Krane_ depends on [RedisGraph](https://oss.redislabs.com/redisgraph/). `docker-compose` is the quickest way to get _Krane_'s dependencies running locally.

```
```sh
docker-compose up -d redisgraph
```

To inspect RedisGraph service is up:
```
```sh
docker-compose ps
```

To stop services:
```
```sh
docker-compose down
```

Expand All @@ -523,32 +543,32 @@ docker-compose down
At this point you should be able to modify _Krane_ codebase and test results by invoking commands in local shell.

```sh
./bin/krane --help # to get help
./bin/krane report -k docker-desktop # to generate your first report for
# local docker-desktop k8s cluster
$ ./bin/krane --help # to get help
$ ./bin/krane report -k docker-desktop # to generate your first report for
# local docker-desktop k8s cluster
...
```

To enable Dashboard UI local development mode
```
cd dashboard
npm install
npm start
```sh
$ cd dashboard
$ npm install
$ npm start
```

This will automatically start the Dashboard server, open default browser and watch for source files changes.

_Krane_ comes preconfigured for improved developer experience with [Skaffold](https://skaffold.dev/). Iterating on the project and validating the application by running the entire stack in local or remote Kubernetes cluster just got easier.
Code hot-reload enables local changes to be automatically propagated to the running container for faster development lifecycle.

```
```sh
skaffold dev --kube-context docker-desktop --namespace krane --port-forward
```

### Tests

Run tests locally with
```
```sh
bundle exec rspec
```

Expand Down
23 changes: 23 additions & 0 deletions charts/krane/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
15 changes: 15 additions & 0 deletions charts/krane/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: v2
name: krane
description: A Helm chart for Krane
type: application
version: 0.1.1
appVersion: "v0.1.1"
sources:
- https://github.com/appvia/krane
maintainers:
- name: Appvia
email: info@appvia.io
url: https://appvia.io
- name: Marcin
email: marcin.ciszak@appvia.io
url: https://github.com/marcinc
22 changes: 22 additions & 0 deletions charts/krane/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "krane.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "krane.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "krane.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "krane.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
Loading

0 comments on commit d0f3c31

Please sign in to comment.