⏪ back

My journey of Kubernetes

through client-go and k8s-conformance test writing

Caleb Woodbine <calebwoodbine.public@gmail.com>

Introduction

  • test writing as an introduction to Kubernetes
  • how I initially got started contributing to Kubernetes
  • why you might like to contribute to Kubernetes

About me

based in Wellington, New Zealand. Software and infrastructure engineer. Cloud & Open Source enthusiast.

https://calebwoodbine.nz

Background and some past projects

  • Safe Surfer
    • consumer routers
    • production infrastructure
  • ii.nz
    • Kubernetes conformance
    • sig-k8s-infra
  • personal
    • FlatTrack (software for humans living together)

Learning by doing

into test writing with Kubernetes and Go.

Exploring Kubernetes resources and API

...
- pkg/
- cmd/
- test/
  - e2e/
    - apps/
    - scheduling/
    ...
  - conformance/
    - testdata/
      - conformance.yaml
      ...
    ...
...

reading and building mental-models

Reading existing tests

Resource model in client-go

pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})

matches up with /api/v1/pods

deployments, err := clientset.AppsV1().Deployments("").List(context.TODO(), metav1.ListOptions{})

matches up with /apis/apps/v1/deployments

RESOURCE, err := clientset.APIGROUP().API("").ACTION(context.TODO(), ...)

matches up with /apis/APIGROUP/VERSION/API

kubectl goodness

powerful to explore when working inside a cluster

kubectl get --raw /
{
  "paths": [
    "/.well-known/openid-configuration",
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",
    "/apis/admissionregistration.k8s.io",
    "/apis/admissionregistration.k8s.io/v1",
    "/apis/apiextensions.k8s.io",
    "/apis/apiextensions.k8s.io/v1",
    "/apis/apiregistration.k8s.io",
    "/apis/apiregistration.k8s.io/v1",
    "/apis/apps",
    "/apis/apps/v1",
    "/apis/authentication.k8s.io",
    "/apis/authentication.k8s.io/v1",
    "/apis/authorization.k8s.io",
    "/apis/authorization.k8s.io/v1",
    "/apis/autoscaling",

it’s all JSON!

kubectl goodness

kubectl explain pod
KIND:     Pod
VERSION:  v1

DESCRIPTION:
     Pod is a collection of containers that can run on a host. This resource is
     created by clients and scheduled onto hosts.

FIELDS:
   apiVersion	<string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

   kind	<string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

Kubernetes conformance (cncf.io/ck)

keeping Kubernetes consistent for core built-in APIs. a strategic initiative in the CNCF in conjunction with ii.nz

the certification process requires each distribution to pass a set of tests and provide evidence and instructions for reproducing the data.

vendors

Test writing

Environment set up: APISnoop

using some plumbing, write each Kubernetes api-server request to a database

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: RequestResponse
kubectl create namespace apisnoop
helm install -n apisnoop snoopdb charts/snoopdb
helm install -n apisnoop auditlogger charts/auditlogger

Endpoint discovery and mock tickets

mock/exercise an API and prove change in API surface coverage

determine untested endpoints

cs.k8s.io

find things in the code base

write a small sample to evaluate and see results

prove the change in coverage

new ticket in k/k

example: https://issues.k8s.io/88302

Test writing and the Ginkgo e2e test framework

after the endpoint and basic test are approved

...
ginkgo.It("resource should do the thing the resource does", func(ctx context.Context) {
  list, err := clientset.SomeResource(f.Namespace.Name).List(ctx, resourcev1.ListOptions{})
  gomega.Expect(err).To(BeNil(), "failure to list resource")
  gomega.Expect(len(list.Items)).ToNot(gomega.Equal(0), "no items found")
})
...

this goes in the k/k/test/e2e

new PR for the tests

feedback on the new PR

Soaking

View the job logs

Kubernetes-native CI system built around and for the way that the community works.

Test writing and the Ginkgo e2e test framework

the entrypoint changes

...
ginkgo.It("resource should do the thing the resource does", func(ctx context.Context) {
  list, err := clientset.SomeResource(f.Namespace.Name).List(ctx, resourcev1.ListOptions{})
  gomega.Expect(err).To(BeNil(), "failure to list resource")
  gomega.Expect(len(list.Items)).ToNot(gomega.Equal(0), "no items found")
})
...

Test writing and the Ginkgo e2e test framework

the entrypoint changes

...
framework.ConformanceIt("resource should do the thing the resource does", func(ctx context.Context) {
  list, err := clientset.SomeResource(f.Namespace.Name).List(ctx, resourcev1.ListOptions{})
  gomega.Expect(err).To(BeNil(), "failure to list resource")
  gomega.Expect(len(list.Items)).ToNot(gomega.Equal(0), "no items found")
})
...

conformance today

automations

Contributing to Kubernetes

Onboarding

  • attend a meeting in a SIG (relevant to you or not)
  • start positively interacting and contributing
  • be open to learning!

becoming an org member

https://github.com/kubernetes/org/issues/1238

opening a ticket to kubernetes/org

(https://github.com/kubernetes/org/issues/new?assignees=&labels=area%2Fgithub-membership&projects=&template=membership.yml&title=REQUEST%3A+New+membership+for+%3Cyour-GH-handle%3E)

code of conduct

it mostly comes down to

✨ be kind ✨

https://www.cncf.io/conduct

community values

  • distribution is better than centralisation
  • community over product or companies
  • automation over process
  • inclusive is better than exclusive
  • evolution is better than stagnation

https://www.kubernetes.dev/community/values

SIGs and WGs

find your fit!

Kubernetes currently has ~23 special interest groups and 8 working groups, such as

  • sig-architecture
  • sig-contribex (contributor experience)
  • sig-docs
  • sig-k8s-infra (project infrastructure)
  • sig-security

and many many more!

see: https://www.kubernetes.dev/community/community-groups, https://github.com/kubernetes/community

Meetings

each SIG has meetings on their different areas each week or so. meetings are structured around a document, often including fields like

  • who’s attending
  • reoccuring topics
  • open discussion

Why you might like to contribute

  • be apart of a community
    • what is the most important thing? the people! the people! the people!
  • be apart of an industry standard
  • add something that’s important to your focus/company into the project
  • welcoming and helpful folks
  • fun and cool solutions to work powerfully together
  • you’re invited!

k8s.dev

join on Slack via https://slack.k8s.io

Questions

(end)