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

adds keycloak-operator image #2656

Merged
merged 4 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions generated.tf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

216 changes: 216 additions & 0 deletions images/keycloak-operator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<!--monopod:start-->
# keycloak-operator
| | |
| - | - |
| **OCI Reference** | `cgr.dev/chainguard/keycloak-operator` |


* [View Image in Chainguard Academy](https://edu.chainguard.dev/chainguard/chainguard-images/reference/keycloak-operator/overview/)
* [View Image Catalog](https://console.enforce.dev/images/catalog) for a full list of available tags.
* [Contact Chainguard](https://www.chainguard.dev/chainguard-images) for enterprise support, SLAs, and access to older tags.*

---
<!--monopod:end-->

<!--overview:start-->
A Kubernetes Operator based on the Operator SDK for installing and managing Keycloak.
<!--overview:end-->

<!--getting:start-->
## Download this Image
The image is available on `cgr.dev`:

```
docker pull cgr.dev/chainguard/keycloak-operator:latest
```
<!--getting:end-->

<!--body:start-->
## Usage

### Kubernetes

You can install the Operator on a vanilla Kubernetes cluster by using kubectl commands:

Install the CRDs by entering the following commands:

```bash
kubectl apply -f https://raw.githubusercontent.com/keycloak/keycloak-k8s-resources/24.0.4/kubernetes/keycloaks.k8s.keycloak.org-v1.yml
kubectl apply -f https://raw.githubusercontent.com/keycloak/keycloak-k8s-resources/24.0.4/kubernetes/keycloakrealmimports.k8s.keycloak.org-v1.yml
```

Next, install the Keycloak operator with Chainguard images using following steps:


##### Step 1: Download the YAML file and save it with a different name
curl -o keycloak-operator.yml https://raw.githubusercontent.com/keycloak/keycloak-k8s-resources/24.0.4/kubernetes/kubernetes.yml

##### Step 2: Use sed to replace the image repository for Keycloak (adjust for macOS)
sed -i '' 's|quay\.io/keycloak/keycloak:.*|cgr.dev/chainguard/keycloak:latest|' keycloak-operator.yml

##### Step 3: Use sed to replace the image repository for Keycloak Operator (adjust for macOS)
sed -i '' 's|quay\.io/keycloak/keycloak-operator:.*|cgr.dev/chainguard/keycloak-operator:latest|' keycloak-operator.yml

##### Step 4: Apply the modified YAML file
kubectl apply -f keycloak-operator.yml

**NOTE** : The above sed commands were for MacOS (BSD based), for Linux GNU based, replace `sed -i '' 's` with `sed -i 's`

Currently the Operator watches only the namespace where the Operator is installed.


### Basic Keycloak deployment with Keycloak Operator

Once the Keycloak Operator is installed and running in the cluster namespace, you can set up the other deployment prerequisites.

* Database

* Hostname

* TLS Certificate and associated keys

#### Database

For development purposes, you can use an ephemeral PostgreSQL pod installation. To provision it, follow the approach below:

Create YAML file `example-postgres.yaml`:

```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql-db
spec:
serviceName: postgresql-db-service
selector:
matchLabels:
app: postgresql-db
replicas: 1
template:
metadata:
labels:
app: postgresql-db
spec:
containers:
- name: postgresql-db
image: postgres:15
volumeMounts:
- mountPath: /data
name: cache-volume
env:
- name: POSTGRES_USER
value: testuser
- name: POSTGRES_PASSWORD
value: testpassword
- name: PGDATA
value: /data/pgdata
- name: POSTGRES_DB
value: keycloak
volumes:
- name: cache-volume
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: postgres-db
spec:
selector:
app: postgresql-db
type: LoadBalancer
ports:
- port: 5432
targetPort: 5432
```

Apply the changes:

```bash
kubectl apply -f example-postgres.yaml
```

#### Hostname

For a production ready installation, you need a hostname that can be used to contact Keycloak. See [Configuring the hostname](https://www.keycloak.org/server/hostname) for the available configurations.

For development purposes, this guide will use `test.keycloak.org`.

#### TLS Certificate and key
See your Certification Authority to obtain the certificate and the key.

For development purposes, you can enter this command to obtain a self-signed certificate:

```bash
openssl req -subj '/CN=test.keycloak.org/O=Test Keycloak./C=US' -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
```

You should install it in the cluster namespace as a Secret by entering this command:

```bash
kubectl create secret tls example-tls-secret --cert certificate.pem --key key.pem
```

### Deploying Keycloak

Consider storing the Database credentials in a separate Secret. Enter the following commands:

```bash
kubectl create secret generic keycloak-db-secret \
--from-literal=username=testuser \
--from-literal=password=testpassword
```

For a basic deployment, you can stick to the following approach:

Create YAML file `example-kc.yaml`:

```yaml
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
instances: 1
db:
vendor: postgres
host: postgres-db
usernameSecret:
name: keycloak-db-secret
key: username
passwordSecret:
name: keycloak-db-secret
key: password
http:
tlsSecret: example-tls-secret
hostname:
hostname: test.keycloak.org
proxy:
headers: xforwarded # double check your reverse proxy sets and overwrites the X-Forwarded-* headers
```

Apply the changes:

```bash
kubectl apply -f example-kc.yaml
```
To check that the Keycloak instance has been provisioned in the cluster, check the status of the created CR by entering the following command:

```bash
kubectl get keycloaks/example-kc -o go-template='{{range .status.conditions}}CONDITION: {{.type}}{{"\n"}} STATUS: {{.status}}{{"\n"}} MESSAGE: {{.message}}{{"\n"}}{{end}}'
```
When the deployment is ready, look for output similar to the following:

```yaml
CONDITION: Ready
STATUS: true
MESSAGE:
CONDITION: HasErrors
STATUS: false
MESSAGE:
CONDITION: RollingUpdate
STATUS: false
MESSAGE:
```

For further reference, please refer to [official documentation of the project](https://www.keycloak.org/guides#operator)
<!--body:end-->
22 changes: 22 additions & 0 deletions images/keycloak-operator/config/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
terraform {
required_providers {
apko = { source = "chainguard-dev/apko" }
}
}

variable "extra_packages" {
description = "The additional packages to install"
default = [
"keycloak-operator",
"keycloak-operator-compat"
]
}

data "apko_config" "this" {
config_contents = file("${path.module}/template.apko.yaml")
extra_packages = var.extra_packages
}

output "config" {
value = jsonencode(data.apko_config.this.config)
}
25 changes: 25 additions & 0 deletions images/keycloak-operator/config/template.apko.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
contents:
packages:

accounts:
groups:
- groupname: keycloak
gid: 1000
users:
- username: keycloak
uid: 1000
gid: 1000
run-as: 1000

paths:
- path: /opt/keycloak
type: directory
permissions: 0o777
uid: 1000
gid: 1000
recursive: true

work-dir: /opt/keycloak

entrypoint:
command: java -Djava.util.logging.manager=org.jboss.logmanager.LogManager -jar quarkus-run.jar
13 changes: 13 additions & 0 deletions images/keycloak-operator/generated.tf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions images/keycloak-operator/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
terraform {
required_providers {
oci = { source = "chainguard-dev/oci" }
}
}

variable "target_repository" {
description = "The docker repo into which the image and attestations should be published."
}

module "config" { source = "./config" }

module "keycloak-operator" {
source = "../../tflib/publisher"
name = basename(path.module)
target_repository = var.target_repository
config = module.config.config

build-dev = true

}

module "test" {
source = "./tests"
digest = module.keycloak-operator.image_ref
}

resource "oci_tag" "latest" {
depends_on = [module.test]
digest_ref = module.keycloak-operator.image_ref
tag = "latest"
}

resource "oci_tag" "latest-dev" {
depends_on = [module.test]
digest_ref = module.keycloak-operator.dev_ref
tag = "latest-dev"
}

14 changes: 14 additions & 0 deletions images/keycloak-operator/metadata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: keycloak-operator
image: cgr.dev/chainguard/keycloak-operator
logo: https://storage.googleapis.com/chainguard-academy/logos/keycloak-operator.svg
endoflife: ""
console_summary: ""
short_description: "A Kubernetes Operator based on the Operator SDK for installing and managing Keycloak."
compatibility_notes: ""
readme_file: README.md
upstream_url: https://github.com/keycloak/keycloak/tree/main/operator
keywords:
- application
- tools
- operator
- kubernetes