Skip to content

Add a basic ghost package #3381

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

Merged
merged 3 commits into from
Jul 19, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
12 changes: 12 additions & 0 deletions package-examples/ghost/Kptfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: ghost
annotations:
config.kubernetes.io/local-config: "true"
info:
description: sample description
pipeline:
mutators:
- image: gcr.io/kpt-fn/set-namespace:v0.3.4
configPath: package-context.yaml
10 changes: 10 additions & 0 deletions package-examples/ghost/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
```bash
# Fetch ghost helm charts
helm fetch --untar bitnami/ghost
# By default networking, metrics are disabled.
helm template example ghost > rendered.yaml
rm -rf ghost
# Restructure the KRM resources by app. This should give two directories: ./mariadb /ghost
kubectl-slice -f rendered.yaml --template '{{ index "app.kubernetes.io/name" .metadata.labels }}/{{.kind | lower}}-{{.metadata.name|dottodash}}.yaml' -o ghost
rm rendered.yaml
```
12 changes: 12 additions & 0 deletions package-examples/ghost/ghost/Kptfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: ghost
annotations:
config.kubernetes.io/local-config: "true"
info:
description: sample description
pipeline:
mutators:
- image: gcr.io/kpt-fn/set-labels:v0.1.5
configPath: setlabels.yaml
21 changes: 21 additions & 0 deletions package-examples/ghost/ghost/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# ghost

## Description
sample description

## Usage

### Fetch the package
`kpt pkg get REPO_URI[.git]/PKG_PATH[@VERSION] ghost`
Details: https://kpt.dev/reference/cli/pkg/get/

### View package content
`kpt pkg tree ghost`
Details: https://kpt.dev/reference/cli/pkg/tree/

### Apply the package
```
kpt live init ghost
kpt live apply ghost --reconcile-timeout=2m --output=table
```
Details: https://kpt.dev/reference/cli/live/
108 changes: 108 additions & 0 deletions package-examples/ghost/ghost/deployment-example-ghost.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-ghost
namespace: example
spec:
replicas: 1
strategy:
type: RollingUpdate
template:
metadata:
annotations:
checksum/secrets: 711677f8a87ff3df1d09863858613b5dbecb3f6b8ea51a8c37b40762aff66a20
spec:
affinity:
podAffinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
namespaces:
- "example"
Copy link
Contributor

Choose a reason for hiding this comment

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

Does set-namespace know about this field?

Copy link
Contributor Author

@yuwenma yuwenma Jul 18, 2022

Choose a reason for hiding this comment

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

set-namespace misses this field and also misses the podAffinityTerm.namespaceSelector, which means kustomize does not handle this field either.
I need to do a sanity check across 1.24 core/v1/types.go

topologyKey: kubernetes.io/hostname
weight: 1
nodeAffinity:
securityContext:
fsGroup: 1001
containers:
- name: example-ghost
image: docker.io/bitnami/ghost:4.45.0-debian-10-r0
imagePullPolicy: "IfNotPresent"
securityContext:
runAsNonRoot: true
runAsUser: 1001
env:
- name: BITNAMI_DEBUG
value: "false"
- name: ALLOW_EMPTY_PASSWORD
value: "yes"
- name: GHOST_DATABASE_HOST
value: "example-mariadb"
- name: GHOST_DATABASE_PORT_NUMBER
value: "3306"
- name: GHOST_DATABASE_NAME
value: "bitnami_ghost"
- name: GHOST_DATABASE_USER
value: "bn_ghost"
- name: GHOST_DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: example-mariadb
key: mariadb-password
- name: GHOST_HOST
value: "aa/"
- name: GHOST_PORT_NUMBER
value: "2368"
- name: GHOST_USERNAME
value: "user"
- name: GHOST_PASSWORD
valueFrom:
secretKeyRef:
name: example-ghost
key: ghost-password
- name: GHOST_EMAIL
value: "user@example.com"
- name: GHOST_BLOG_TITLE
value: "User's Blog"
- name: GHOST_ENABLE_HTTPS
value: "no"
- name: GHOST_EXTERNAL_HTTP_PORT_NUMBER
value: "80"
- name: GHOST_EXTERNAL_HTTPS_PORT_NUMBER
value: "443"
- name: GHOST_SKIP_BOOTSTRAP
value: "no"
ports:
- name: http
containerPort: 2368
protocol: TCP
livenessProbe:
httpGet:
path: /
port: "http"
scheme: HTTP
initialDelaySeconds: 120
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1
readinessProbe:
httpGet:
path: /
port: "http"
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 6
successThreshold: 1
resources:
limits: {}
requests: {}
volumeMounts:
- name: ghost-data
mountPath: /bitnami/ghost
volumes:
- name: ghost-data
persistentVolumeClaim:
claimName: example-ghost
17 changes: 17 additions & 0 deletions package-examples/ghost/ghost/ingress-example-ghost.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ghost
namespace: example
spec:
rules:
- host: ghost.local
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: example-ghost
port:
name: http
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-ghost-ingress
spec:
ingress:
8 changes: 8 additions & 0 deletions package-examples/ghost/ghost/package-context.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: kptfile.kpt.dev
annotations:
config.kubernetes.io/local-config: "true"
data:
name: example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Source: ghost/templates/pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: example-ghost
namespace: example
spec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: "8Gi"
8 changes: 8 additions & 0 deletions package-examples/ghost/ghost/secret-example-ghost.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: example-ghost
namespace: example
type: Opaque
data:
ghost-password: amRYdHhYYVFueg==
14 changes: 14 additions & 0 deletions package-examples/ghost/ghost/service-example-ghost.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: example-ghost
namespace: example
spec:
type: LoadBalancer
externalTrafficPolicy: Cluster
sessionAffinity: None
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
10 changes: 10 additions & 0 deletions package-examples/ghost/ghost/setlabels.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: fn.kpt.dev/v1alpha1
kind: SetLabels
metadata:
name: ghost
annotations:
config.kubernetes.io/local-config: "true"
labels:
Copy link
Contributor

Choose a reason for hiding this comment

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

No spec?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😞 no spec. I think all custom functionConfig type do not follow the spec status rule. The argument is that those resources won't be deployed to the cluster so it is not a strict spec/status. Skipping spec saves some manual editing.

I'm more happy to add the spec to functionConfig, because it does help answering questions like "what fields & resources a user could be interested in modifying" https://kubernetes.slack.com/archives/C0155NSPJSZ/p1657561360040189

Copy link
Contributor

Choose a reason for hiding this comment

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

This KRM format has at least 4-6 lines of boilerplate even without the spec line (apiVersion, kind, metadata, name, annotations), so we'll want to figure out how to make it easy to generate, such as via the UI and/or a CLI with autocomplete.

Copy link
Contributor

Choose a reason for hiding this comment

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

Or generate it given the function name, if we have a catalog that can map between functions and input types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I really like the idea of autogenerating function config for users by only requiring users to provide the function name. Even from my own experience, writing a function config is a big bottleneck to use KRM functions.

Put this as a feature request in #3379

app.kubernetes.io/name: ghost
app.kubernetes.io/instance: example
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this label is interesting. We want this to be coming from package-context.data.name. Is this wired currently ? if not, we should take this out ? because example will not represent an instance in our solution.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's not wired. The first user that tried to use kpt for an application ran into this. You provided an ApplyReplacements solution on slack.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I was wondering if the current package wires using the ApplyReplacements or Starlark.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is not wired. My plan for this package is to start from helm charts to discover as many feature gaps as possible. So this package contains some helm assumptions like configMap to pass in INI file , secret in auto roll deployment, secret reference and usage in livenessProbe and readiness probe.

For this specific value, helm assumes the namespace is "default" (which is convenience because users can install the charts without dealing w/ namespace), and this instance is the helm release name which is used to "differentiate releases for different app". I'm wondering what can be a good equivalent filter on kpt side.

Copy link
Contributor

Choose a reason for hiding this comment

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

On the kpt side, the deployment package name is similar to the release name.

app.kubernetes.io/component: ghost
12 changes: 12 additions & 0 deletions package-examples/ghost/mariadb/Kptfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: mariadb
annotations:
config.kubernetes.io/local-config: "true"
info:
description: sample description
pipeline:
mutators:
- image: gcr.io/kpt-fn/set-labels:v0.1.5
configPath: setlabels.yaml
21 changes: 21 additions & 0 deletions package-examples/ghost/mariadb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# mariadb

## Description
sample description

## Usage

### Fetch the package
`kpt pkg get REPO_URI[.git]/PKG_PATH[@VERSION] mariadb`
Details: https://kpt.dev/reference/cli/pkg/get/

### View package content
`kpt pkg tree mariadb`
Details: https://kpt.dev/reference/cli/pkg/tree/

### Apply the package
```
kpt live init mariadb
kpt live apply mariadb --reconcile-timeout=2m --output=table
```
Details: https://kpt.dev/reference/cli/live/
36 changes: 36 additions & 0 deletions package-examples/ghost/mariadb/configmap-example-mariadb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Source: ghost/charts/mariadb/templates/primary/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: example-mariadb
namespace: example
data:
my.cnf: |-
[mysqld]
skip-name-resolve
explicit_defaults_for_timestamp
basedir=/opt/bitnami/mariadb
plugin_dir=/opt/bitnami/mariadb/plugin
port=3306
socket=/opt/bitnami/mariadb/tmp/mysql.sock
tmpdir=/opt/bitnami/mariadb/tmp
max_allowed_packet=16M
bind-address=*
pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid
log-error=/opt/bitnami/mariadb/logs/mysqld.log
character-set-server=UTF8
collation-server=utf8_general_ci
slow_query_log=0
slow_query_log_file=/opt/bitnami/mariadb/logs/mysqld.log
long_query_time=10.0

[client]
port=3306
socket=/opt/bitnami/mariadb/tmp/mysql.sock
default-character-set=UTF8
plugin_dir=/opt/bitnami/mariadb/plugin

[manager]
port=3306
socket=/opt/bitnami/mariadb/tmp/mysql.sock
pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Source: ghost/charts/mariadb/templates/primary/networkpolicy-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-mariadb-ingress
spec:
ingress:
8 changes: 8 additions & 0 deletions package-examples/ghost/mariadb/package-context.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: kptfile.kpt.dev
annotations:
config.kubernetes.io/local-config: "true"
data:
name: example
Copy link
Contributor

Choose a reason for hiding this comment

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

so variant constructor pattern isn't support well (or tested :)) for nested packages, so will be interesting to see how this plays out.

Copy link
Contributor

Choose a reason for hiding this comment

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

A user in slack has encountered similar issues using Config Connector subpackages (e.g., CloudSQL).

10 changes: 10 additions & 0 deletions package-examples/ghost/mariadb/prometheusrule-example-mariadb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Source: ghost/charts/mariadb/templates/prometheusrules.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: example-mariadb
namespace: example
spec:
groups:
- name: example-mariadb
rules: []
10 changes: 10 additions & 0 deletions package-examples/ghost/mariadb/secret-example-mariadb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Source: ghost/charts/mariadb/templates/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: example-mariadb
namespace: example
type: Opaque
data:
mariadb-root-password: "QjJVSUR2SVcyeg=="
mariadb-password: "Z0NIeHBKNjlhNg=="
15 changes: 15 additions & 0 deletions package-examples/ghost/mariadb/service-example-mariadb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Source: ghost/charts/mariadb/templates/primary/svc.yaml
apiVersion: v1
kind: Service
metadata:
name: example-mariadb
namespace: example
spec:
type: ClusterIP
sessionAffinity: None
ports:
- name: mysql
port: 3306
protocol: TCP
targetPort: mysql
nodePort: null
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Source: ghost/charts/mariadb/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: example-mariadb
namespace: example
automountServiceAccountToken: false
10 changes: 10 additions & 0 deletions package-examples/ghost/mariadb/setlabels.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: fn.kpt.dev/v1alpha1
kind: SetLabels
metadata:
name: mariadb
annotations:
config.kubernetes.io/local-config: "true"
labels:
app.kubernetes.io/name: mariadb
app.kubernetes.io/instance: example
app.kubernetes.io/component: primary
Loading