logo

Kubernetes - apimachinery

Last Updated: 2024-03-03

https://github.com/kubernetes/apimachinery

k8s.io/apimachinery: a shared dependency for servers (e.g. apiserver) and clients (e.g. client-go, kubectl, etc.) to work with Kubernetes APIs. It includes:

  • universal lower-level data structures like apiVersion, kind, name, uid, creationTimestamp, etc. Also TypeMeta, ObjectMeta.
  • Object Serialization to JSON, YAML, or Protobuf.
  • Scheme (runtime.Scheme) and RESTMapper.
  • Field and Label Selectors (k8s.io/apimachinery/pkg/labels)
  • API Error Handling(k8s.io/apimachinery/pkg/api/errors)
  • Utils (apimachinery/pkg/util)
  • k8s.io/apimachinery/pkg/apis/meta/v1
  • k8s.io/apimachinery/pkg/runtime/schema

k8s: Schema vs Scheme

Both in k8s.io/apimachinery/pkg/runtime.

TL;DR: Scheme is for conversion; Schema is on one side of the conversion.

  • Schema: the go types, schema.GroupVersionKind
    • k8s.io/apimachinery/pkg/runtime/schema
  • Scheme: defines methods for serializing and deserializing API objects.
    • k8s.io/apimachinery/pkg/runtime/scheme

A "kind" is a GroupVersionKind, a "type" is a Go type (reflect.Type).

Every set of controllers needs a Scheme, which provides mappings between Kinds and their corresponding Go types.

To create a new Scheme:

var scheme = runtime.NewScheme()

The runtime.Scheme struct is such a registry containing the kind to type and type to kind mappings for all kinds of Kubernetes objects.

Defined in k8s.io/apimachinery/pkg/runtime

How to check conditions

// "k8s.io/apimachinery/pkg/api/meta"

conds := Foo.Status.Conditions

meta.IsStatusConditionTrue(conds, conditionType)

LabelSelector and Selector

LabelSelector is a struct (2 fields: MatchLabels and MatchExpressions); in manifest it looks like this:

spec:
  selector:
    matchLabels:
      example.com/laebl-1: foo
      example.com/label-2: bar
      example.com/label-3: baz

Selector (k8s.io/apimachinery/pkg/labels/selector.go) is an internal representation of LabelSelector with the actual logic:

import (
  metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  "k8s.io/apimachinery/pkg/labels"
)

selector, err := metav1.LabelSelectorAsSelector(mytype.Spec.Selector)

selector.Matches(labels.Set(myothertype.GetLabels()))

Conversion (in k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go):

func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error)

How to set Labels and Annotations?

https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1

// Get the corresponding cluster
if err := c.Get(ctx, fooKey, foo); err != nil {
  return fmt.Errorf("failed to get foo object: %w", err)
}

// Set Label.
metav1.SetMetaDataLabel(&foo.ObjectMeta, myLabel, myValue)

// Set Annotation.
metav1.SetMetaDataAnnotation(&foo.ObjectMeta, myAnnotation, myValue)

Object

apimachinery defines Object interface, it requires gvk to be available.

objects := []runtime.Object{}