What happens:
Create a mult-version CRD with a conversion webhook configured with an invalid CABundle:
$ kubectl apply -f crd.yaml
customresourcedefinition.apiextensions.k8s.io/replicant.stable.example.com created
Read the CRD back:
| package main | |
| import ( | |
| "fmt" | |
| ) | |
| // An interface can be implemented by a function type definition. | |
| // This can be convenient for allowing inline function declarations | |
| // of interfaces with only a single function. |
| +++ [0829 20:58:12] Generating protobufs for 70 targets | |
| +++ [0829 20:58:12] protoc 23.4 not found (can install with hack/install-protoc.sh); generating containerized... | |
| +++ [0829 20:58:12] Verifying Prerequisites.... | |
| +++ [0829 20:58:13] Building Docker image kube-build:build-41f60316fe-5-v1.31.0-go1.22.5-bullseye.0 | |
| +++ [0829 20:58:14] Syncing sources to container | |
| +++ [0829 20:58:23] Output from this container will be rsynced out upon completion. Set KUBE_RUN_COPY_OUTPUT=n to disable. | |
| +++ [0829 20:58:23] Running build command... | |
| +++ [0829 20:58:48] Syncing out of container | |
| +++ [0829 20:58:51] Generating deepcopy code for 254 targets | |
| +++ [0829 20:59:02] Generating swagger for 58 targets |
What happens:
Create a mult-version CRD with a conversion webhook configured with an invalid CABundle:
$ kubectl apply -f crd.yaml
customresourcedefinition.apiextensions.k8s.io/replicant.stable.example.com created
Read the CRD back:
| # config for 1 control plane node and 2 workers (necessary for conformance) | |
| kind: Cluster | |
| apiVersion: kind.x-k8s.io/v1alpha4 | |
| networking: | |
| ipFamily: ipv4 | |
| kubeProxyMode: iptables | |
| # don't pass through host search paths | |
| # TODO: possibly a reasonable default in the future for kind ... | |
| dnsSearch: [] | |
| nodes: |
| # KEP Authors | |
| echo keps/*/*/kep.yaml | xargs -n 1 yq "select(.status == \"implemented\" or .status == \"implementable\") | .authors[]" | sort | uniq -c | sort -n | |
| # KEP Reviewers | |
| echo keps/*/*/kep.yaml | xargs -n 1 yq "select(.status == \"implemented\" or .status == \"implementable\") | .reviewers[]" | sort | uniq -c | sort -n | |
| # KEP Approvers |
Kubernetes generateName randomly generates a 5 char sequence that is appended as a "hash" to the generateName prefix (spoiler: It's not really a hash, just an encoded random number).
Each char in the sequence is from the "bcdfghjklmnpqrstvwxz2456789" range.
This leads to
But there is a problem with collisions. There is a 50% chance of hitting a collision before generating even 5000 names, and a 0.1% chance at only 500 names!
| echo keps/sig-api-machinery/*/kep.yaml | xargs -n 1 yq 'select(.stage=="alpha" and .status =="implementable") | .title' | |
| Union types | |
| Migrating API objects to latest storage version | |
| Graduate Server-side Get and Partial Objects to GA | |
| OwnerReference Resource Field | |
| Consistent Reads from Cache | |
| Publish versioning information in OpenAPI | |
| OpenAPI Enum Types | |
| Transition from SPDY to Websockets | |
| CRD Validation Ratcheting |
First, install podman and buildah. These tools support running containers build for other architectures like arm64 and ppc64le.
Next, create a Dockerfile, e.g.:
FROM ppc64le/golang:1.20.7-alpine
ADD kubernetes /kubernetes
Note that this dockerfile is for ppc64le, so can't be run directly with docker on an amd64 linux machine.
case "replace":
if target != nil && len(args) >= 2 {
sz := l.sizeEstimate(*target)
toReplaceSz := l.sizeEstimate(args[0])
if toReplaceSz.Min == 0 {
toReplaceSz.Min = 1 // replace will replace each char with the replacement if an empty "to replace" string is given
}
replaceWithSz := l.sizeEstimate(args[1])
fmt.Printf("replace sz: %v\n", sz)
case "replace":
if target != nil && len(args) >= 2 {
sz := l.sizeEstimate(*target)
toReplaceSz := l.sizeEstimate(args[0])
replaceWithSz := l.sizeEstimate(args[1])
fmt.Printf("replace sz: %v\n", sz)
fmt.Printf("toReplaceSz: %v\n", toReplaceSz)
fmt.Printf("replaceWithSz: %v\n", replaceWithSz)