-
- 2.1. API Versioning
- 2.2. API Groups
- 2.3. Object model
- 2.3.1. Object expression
- 2.3.2. Workloads Object Model
-
- 3.1. Namespaces
- 3.2. Pods
- 3.3. Labels
- 3.4. Selectors
- 3.5. annotations
- 3.6. Services
The REST API is the KeyStone of kubernetes .All operations and communications between components, and external users are API calls that the API Server handles . An object oriented architecture is used .
Main format:
/api/<version>
/apis/<group>/<version>/<resource>
To eliminate fields or restructure resource representations, Kubernetes supports multiple API versions, each at a different API path. The version is set at the API level rather than at the resource or field level to:
-
Ensure that the API presents a clear and consistent view of system resources and behavior.
-
Enable control access to end-of-life and/or experimental APIs. three main levels of stability in the API:
-
Alpha
:- Disabled by Default
- Used by
alpha
word, example:apiVersion: v1alpha1
- Features can be buggy
- The support of a feature can be dropped at any time and without any notice
- The API can change in a way that the feature may not work anymore
- For testing purposes only
-
Beta
:- Used by
beta
word, example:apiVersion: v1beta3
- Enabled by Default
- The feature is tested and considered as stable
- The support of the feature will not be dropped, though the details may change
- API schema may change
- non-business-critical uses because of potential for incompatible changes in subsequent releases
- Used by
-
Stable
:- Enabled by Default
- The version name is
vX
where X is an integer - Released and stable Feature with no change on the API schema
- May be used on a production grade.
An API Group is a REST compatible path that acts as the type descriptor for a kubernetes object . API Groups make it easier to extend k8s API. There is several types of groups used :
- The core (also called legacy) group, which is at REST path
/api/v1
and is not specified as part of theapiVersion
field, for example,apiVersion: v1
- The named groups are at REST path
/apis/$GROUP_NAME/$VERSION
, and use apiVersion:$GROUP_NAME/$VERSION
(for example,apiVersion: batch/v1
Most used ones :
apiVersion: v1
# for pods, volumes , pv, pvc,container
/apis/apps/v1/deployments
# deployements
/apis/batch/v1beta1/cronjobs
#cronjobs
example of group API:
Objects are a persistant entity that represent the desired state of the object within the cluster . EVERY object MUST have apiVersion
, kind
, and poses the nested fields: metadata.name
, (can be inhereted )metadata.namespace
, (can be generated Automatically)metadata.UID
apiVersion
: Kubernetes API version of the Objectkind
: Type of Kubernetes Objectmetadata.name
: Unique name of the Objectmetadata.namespace
: Scoped environment name that the object belongs to (will default to current).metadata.uid
: The (generated) uid for an object.
Files or other representations of k8s objects are generally represented in YAML. 2 main rules in writing YAML files :
- Uses white space alignment to denote ownership
- Three basic Data types :
- Mappings: hash or dictionary,
- Sequences: Array or list
- Scalar: String, number, bool ...
Workload related objects within k8s have an additional two nested fields spec
and status
:
status
: is managed by k8s and describes the actual state of the object and its historyspec
: Describes the desired state or configuration of the object to be created
Kubernetes has several core building blocks that make up the foundation of their higher level components.
Kubernetes supports multiple virtual clusters backed by the same physical cluster. These virtual clusters are called namespaces. Creating a new namespace is needed when :
- Divide cluster resources between multiple users (When several users or teams share a cluster with a fixed number of nodes, there is a concern that one team could use more than its fair share of resources. we talk abbout
resource quota
) - When we need a unique names of ressources in the namespace. Creating a new namespace provides a new scope for names .
- A mechanism to attach authorization and policy to a subsection of the cluster
kubectl api-resources --namespaced=false
Three initial namespaces:
default
: The default namespace for objects with no other namespacekube-system
: Objects and resources created by k8s itselfkube-public
: This namespace is created automatically and is readable by all users (including those not authenticated).This namespace is usually reserved for cluster bootstrapping and configuration.
When you create a Service, it creates a corresponding DNS entry. This entry is of the form <service-name>.<namespace-name>.svc.cluster.local
, which means that if a container just uses <service-name>
it will resolve to the service which is local to a namespace.
In this section we will discuss the implementation of pods not their significations , please refer to README
Example of attributes that can be used to declare a pod:
name
: The name of the containerimage
: The container imageports
: array of ports to expose. Can be granted a friendly name and protocol may be specifiedenv
: array of environment variablescommand
: Entrypoint array (equiv to Docker ENTRYPOINT)args
: Arguments to pass to the command (equiv to Docker CMD)
apiVersion: v1
kind: Pod
metadata:
name: multi-container-example
spec:
containers:
- name: nginx
image: nginx:stable-alpine
ports:
- containerPort: 80
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
- name: content
image: alpine:latest
command: ["/bin/sh", "-c"]
args:
- while true; do
date >> /html/index.html;
sleep 5;
done
volumeMounts:
- name: html
mountPath: /html
volumes:
- name: html
emptyDir: {}
Key/value pairs are used to group objects and resources together .Labels are intended to specify identifying attributes of objects that are meaningful and relevant to users without implying directly semantics to the core system (No technical labels but normal human readable names ) Labels are NOT characteristic of uniqueness .Each Key must be unique for a given object.
Example labels:
- "
release
" : "stable
", "release
" : "canary
- "
environment
" : "dev
", "environment
" : "qa
", "environment
" : "production
" - "
tier
" : "frontend
", "tier
" : "backend
", "tier
" : "cache
" - "
partition
" : "customerA
", "partition
" : "customerB
" - "
track
" : "daily
", "track
" : "weekly
"
Selectors use labels to filter or select objects, and are used throughout Kubernetes. Unlike names and UIDs, labels do not provide uniqueness. In general, we expect many objects to carry the same label(s).
Via a label selector, the client/user can identify a set of objects. The label selector is the core grouping primitive in Kubernetes.
The API currently supports two types of selectors:
- Equality-based:
=
,==
,!=
Matching objects must satisfy all of the specified label constraints - set-based :
in
,notin
andexists
(only the key identifier): allow filtering keys according to a set of values
You can use Kubernetes annotations to attach arbitrary non-identifying metadata to objects. Clients such as tools and libraries can retrieve this metadata. we can use annotations for :
- Build, release, or image information like timestamps, release IDs, git branch, PR numbers, image hashes, and registry address.
- User or tool/system provenance information, such as URLs of related objects from other ecosystem components. ...
annotations are not used to identify and select objects.
In this section we will discuss the implementation of services not their definition, please refer to README Note that every service type are not distingushed but built on top of one another
ClusterIP services exposes a service on a strictly cluster internal virtual IP.
apiVersion: v1
kind: Service
metadata:
name: example-prod
spec:
selector:
app: nginx
env: prod
ports:
- protocol: TCP
port: 80
targetPort: 80
from another pod we can access it via :
nslookup example-prod.default.svc.cluster.local
#Name: example-prod.default.svc.cluster.local
#Address 1: 10.96.28.176 example-prod.default.svc.cluster.local
Exposes the Service on each Node’s IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You’ll be able to contact the NodePort Service, from outside the cluster, by requesting <NodeIP>:<NodePort>
apiVersion: v1
kind: Service
metadata:
name: example-prod
spec:
type: NodePort
selector:
app: nginx
env: prod
ports:
- nodePort: 32410
protocol: TCP
port: 80
targetPort: 80
The LoadBalancer service extends NodePort turns it into a highly-available externally consumable resource.This service uses external cloud provider's load balancer to expose service externally :attention: MUST Work with some external system to provide cluster ingress
apiVersion: v1
kind: Service
metadata:
name: example-prod
spec:
type: LoadBalancer
selector:
app: nginx
env: prod
ports:
protocol: TCP
port: 80
targetPort: 80
ExternalName is used to reference endpoints OUTSIDE the cluster.it Creates an internal CNAME DNS entry that aliases another.
apiVersion: v1
kind: Service
metadata:
name: example-prod
spec:
type: ExternalName
spec:
externalName: example.com