This is a story about Derps and Kubernetes
The Derps in this talk are fictional Derps.
They are the product of the authors mind.
Any resemblance to actual Derps is coincidental.
There are 2 types of people:
Those who have broken Production
and those who haven’t
# Yet
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: real-ingress
namespace: prod
spec:
rules:
- host: foo.a-bad.dev
http: {}
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: dev-ingress
namespace: dev
spec:
rules:
- host: foo.a-bad.dev
http: {}
Um Kevin, Why did the API service stop working
git revert -m 'Kevin derped' && git push origin master -f
- Run a PIR
- Write up your PIR
- Action items for everyone!
- Hopefully fix them
Write a runbook and get people to not do the thing
How to stop your derps breaking production
Again
Gatekeeper
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: duplicateingress
spec:
crd:
spec:
names:
kind: duplicateIngress
listKind: duplicateIngressList
plural: duplicateIngresses
singular: duplicateIngress
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8suniqueingresshost
violation[{"msg": msg}] {
input.review.kind.kind == "Ingress"
host := input.review.object.spec.rules[_].host
other := data.inventory.namespace[_][_]["Ingress"][_]
other.spec.rules[_].host == host
msg := sprintf(
"https/kca.id.au/talks/opa-devfest/images/no.gif"
)
}
apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
name: config
namespace: "opa-operator"
spec:
sync:
syncOnly:
- group: "networking.k8s.io"
version: "v1beta1"
kind: "Ingress"
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: duplicateIngress
metadata:
name: kevin-is-terrible-at-names
spec:
match:
kinds:
- apiGroups: ["networking.k8s.io"]
version: ["v1beta1"]
kinds: ["Ingress"]
Error from server ([denied by kevin-is-terrible-at-names],
"https/kca.id.au/talks/opa-devfest/images/no.gif")
- Part of your CI build
- Yaml, Dockerfile, experimental HCL2
deny[]
instead of violation[]
But wait. there’s tests
test_collision {
input := {"review": review(ingress(*stuff*)}
inv := inventory_data([ingress( *otherstuff* )])
results := violation
with input as input
with data.inventory as inv
count(results) == 1
}