SlideShare a Scribd company logo
Extend and Build on	
Kubernetes
Dr.	Stefan	Schimanski
sttts@redhat.com
@the1stein
Kubernetes Meetup Frankfurt,	Mar	10	2017
Nune Isabekyan,	https://x-team.com/blog/introduction-kubernetes-architecture/
Disclaimer:
Kubernetes happens to be able to launch pods.	It‘s even quite good at	it.
We will	not	launch pods today.
Restful
http	API
/
/version
/api
/api/v1/pods
/api/v1/pods/status
/apis
/apis/batch
/apis/batch/v2alpha1
/apis/batch/v2alpha1/jobs
/apis/batch/v2alpha1/cronjobs
/apis/batch/v1
/apis/batch/v1/jobs
kube-apiserver
kubeletproxy
Node:
$	kubectl create -f	foo.yaml
User:
scheduler
controller
manager
apiserver
ingress
controller
Master:
cloud native	apps
Pods:
$	kube-apiserver
--secure-port 0	
--etcd-servers	http://127.0.0.1:2379
--service-cluster-ip-range	10.0.0.0/16
--storage-backend	etcd2
--storage-media-type	application/json
$ etcd
$ kubectl config set-cluster	local --server=http://127.0.0.1:8080
$	kubectl config set-context local --cluster=local
$	kubectl config use-context local
$ kubectl get namespaces –v=7
$ kubectl get namespace default -o	json
$ kubectl annotate namespace default meetup=hello
$	curl http://127.0.0.1:8080/api/v1/namespaces/default
$ etcdctl get /	--recursive
$ etcdctl get /registry/namespaces/default
$ etcdctl -o	extended get /registry/namespaces/default
$	http	GET http://127.0.0.1:8080/api/v1/namespaces/default
{
"apiVersion":	"v1",				
"kind": "Namespace",
"metadata": {
"annotations": {
"meetup": “hallo"
},
"creationTimestamp":	"2017-03-10T07:51:39Z",								
"name": "default",
"resourceVersion": “73",
},
"spec": { "finalizers": ["kubernetes“]	},
"status": { "phase": "Active“ }
}
$	http	GET http://127.0.0.1:8080/api/v1/namespaces/default |	
jq ".metadata.annotations["meetup"]	= "$(date)""	|	
http	PUT http://127.0.0.1:8080/api/v1/namespaces/default
HTTP/1.1	200	OK
Content-Length:	341
Content-Type:	application/json
Date:	Fri,	10	Mar	2017	08:28:01	GMT
$	while true;	do
http	GET	http://127.0.0.1:8080/api/v1/namespaces/default |	
jq ".metadata.annotations["meetup"]	=	"$(date)""	|	
http	--check-status	PUT	http://127.0.0.1:8080/api/v1/namespaces/default ||	break
done
HTTP/1.1	409	Conflict
Content-Length:	310
Content-Type:	application/json
Date:	Fri,	10	Mar	2017	08:27:58	GMT
{				
"apiVersion":	"v1",				
"code":	409,			
"details":	{							
"kind":	"namespaces",								
"name":	"default“
},				
"kind":	"Status",				
"message":	"Operation	cannot be fulfilled on	namespaces "default":	the object has been
modified;	please apply your changes to the latest version and try again",				
"metadata":	{},				
"reason":	"Conflict",				
"status":	"Failure“
/apis/batch/v2alpha1/jobs
Apigroup Version			Resource
HTTP	paths:
{
“apiVersion“:	“v2alpha1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
{				
"apiVersion":	"v1",				
"kind":	"Status",				
"metadata":	{},				
"code":	409,			
"message":	“...",				
"status":	"Failure“
}
/apis/batch/v2alpha1/jobs
{
“apiVersion“:	“v2alpha1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
Resource vs.	Kind
http	path vs.	logical object
/apis/extensions/v1alpha1/jobs
/apis/batch/v2alpha1/jobs
/apis/batch/v1/jobs {
“apiVersion“:	“v1alpha1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
{
“apiVersion“:	“v2alpha1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
{
“apiVersion“:	“v1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
/apis/extensions/v1alpha1/jobs
/apis/batch/v2alpha1/jobs
/apis/batch/v1/jobs {
“apiVersion“:	“v1alpha1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
{
“apiVersion“:	“v2alpha1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
{
“apiVersion“:	“v1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
/apis/extensions/v1alpha1/jobs/nightly
/apis/batch/v2alpha1/jobs/nightly
/apis/batch/v1/jobs/nightly
{
“apiVersion“:	“v1alpha1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{		...	}
}
{
“apiVersion“:	“v2alpha1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
{
“apiVersion“:	“v1beta1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
*	I	omitted the namespace in	/apis/batch/v1/jobs/namespaces/default/nightly
{
“apiVersion“:	“v1alpha1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
{
“apiVersion“:	“v2alpha1“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
{
“apiVersion“:	“v1	“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
etcd
{
“apiVersion“:	“v1	“,
“kind“:	“Job“,
“metadata“:	{
“name“:	“nightly“
},
“spec“:	{	 ...	}
}
Protobuf
or
JSON
storage
version
encoding
I	want my own kinds
and store them in	the apiserver and use kubectl.
Discovery
how kubectl knows which kinds/resources exist
$	http	127.0.0.1:8080/apis/	
{
"groups":	[{
"name": "batch",
"preferredVersion": {"groupVersion": "batch/v1", "version": "v1“},
"versions": [{"groupVersion": "batch/v1",		"version":	"v1"}]
},	...]
}
$	http	127.0.0.1:8080/apis/batch/v1
{
"apiVersion":	"v1",
"groupVersion":	"batch/v1",
"kind":	"APIResourceList",
"resources":	[{
"kind":	"Job",
"name":	"jobs",
"namespaced":	true,
"verbs":	["create",	"delete",	"deletecollection",
"get",	"list",	"patch",	"update",	"watch“
]
},	...]
}
resource name ⇒ /apis/batch/v1/jobs
Third	Party	Resources
Third	Party	Resources
*	they are marked as beta in	the API,	but	became beta before we even had alpha.
apiVersion:	extensions/v1beta1
kind:	ThirdPartyResource
metadata:		
name:	databases.example.com
description:	"A	specification of a	SQL	database.“
versions:
- name:	v1
$	kubectl create –f	databases-tpr.yaml
apiVersion:	extensions/v1beta1
kind:	ThirdPartyResource
metadata:		
name:	databases.example.com
description:	"A	specification of a	SQL	database.“
versions:
- name:	v1
$	kubectl create –f	databases-tpr.yaml $	kubectl create –f	wordpress-databases.yaml
apiVersion:	example.com/v1
kind:	Databases
metadata:
name:	wordpress
spec:
user:	wp
password:	secret
encoding:	unicode
apiVersion:	extensions/v1beta1
kind:	ThirdPartyResource
metadata:		
name:	database.example.com
description:	"A	specification of a	SQL	database.“
versions:
- name:	v1
$	kubectl create –f	databases-tpr.yaml $	kubectl create –f	wordpress-database.yaml
apiVersion:	example.com/v1
kind:	Database
metadata:
name:	wordpress
spec:
user:	wp
password:	secret
encoding:	unicode
$ kubectl get databases –w --no-headers
wordpress <none>				{"apiVersion":"example.com/v1","kind":"Databases",...
wordpress <none>				{"apiVersion":"example.com/v1","kind":"Databases",...
Extend and build on Kubernetes
https://github.com/kubernetes/features/issues/95
ThirdPartyResources are limited
• no version conversion
• no defaulting
• no validation
• no subresources (scale,	status)
• no admission
• alpha ⇒ API	might change
• but: demand is high,	expect improvements in	1.7+
• Today‘s users of TPRs:
https://gist.github.com/philips/a97a143546c87b86b870a82a753db14c
Controllers
where is the business logic?
$	while true;	do
http	GET	http://127.0.0.1:8080/api/v1/namespaces/default |	
jq ".metadata.annotations["meetup"]	=	"$(date)""	|	
http	--check-status	PUT	http://127.0.0.1:8080/api/v1/namespaces/default ||	break
done
⟲
$	kubectl get namespaces -w --no-headers	|	
while read NS	STATUS	TIME	;	do
#	do	whatever you like	here,	e.g.	change the namespace
echo	"$NS	changed“
done
⟲
$	curl -f	'http://127.0.0.1:8080/api/v1/namespaces?watch=true&resourceVersion=4711‘
{"type":"ADDED","object":{"kind":"Namespace","apiVersion":"v1","metadata":{"name ...
{"type":“MODIFIED","object":{"kind":"Namespace","apiVersion":"v1","metadata":{"name ...
{"type":“DELETED","object":{"kind":"Namespace","apiVersion":"v1","metadata":{"name ...
API	Aggregation
Why
• ThirdPartyResources are limited
• no version conversion
• no defaulting
• no validation
• no subresources (scale,	status)
• no admission
• Some things need full power	of Go
• Service	catalog
• OpenShift PaaS
• other powerful	APIs
≫ Goal:	allow powerful	extensions without modifying Kubernetes itself
Alpha	in	v1.6:	k8s.io/apiserver
• generic apiserver library in	Go
• today used inside
• kube-apiserver
• federation apiserver
• service catalog
• allows creation of custom apiservers in	a	couple hundred lines of code
• each custom apiserver is its own process,	communicating via	HTTPS
• delegates authentication/authorization to kube-apiserver
• uses etcd storage (possibly shared with kube)
Nune Isabekyan,	https://x-team.com/blog/introduction-kubernetes-architecture/
kube-apiserver service catalog PaaS
kube-aggregator
kube-apiserver service catalog PaaS
kube-aggregator
API API API
API
Pods Jobs ... announcement ... build test project
kube-apiserver kube-apiserver kube-apiserver
federation
apiserver
API API API
API
Pods replicasets Pods replicasets Pods replicasets
deployment service
Europe US Asia
Not	this:	
federation
controllers⟲
federated resources:
availability zones +	regions:
kube-apiserver service catalog PaaS
kube-aggregator
discoverydiscovery
kube-apiserver service catalog PaaS
kube-aggregator
GET
GET	/apis/servicecatalog/subscription/database-prod-wordpress
kube-apiserver service catalog PaaS
kube-aggregator
GET	/apis/servicecatalog/subscription/database-prod-wordpress
GET
RBAC Namespace
kube-apiserver service catalog PaaS
kube-aggregator
GET
Vision:	
$ helm install service-catalog
$ kubectl create service-announcement ....
GET	/apis/servicecatalog/subscription/database-prod-wordpress
Extend and build on Kubernetes
Status
• will	be part of Kubernetes 1.6	as an	alpha
• https://github.com/kubernetes/sample-apiserver
• potentially kube-aggregator integrated into kube-apiserver in	1.7
Links
• https://docs.google.com/document/d/1y16jKL2hMjQO0trYBJJSczPA
Wj8vAgNFrdTZeCincmI/
Two Ways to Extend the K8s	API - Add	resources to a	Kubernetes API	
with TPR	or AA
• https://github.com/kubernetes/community/blob/master/contributor
s/design-proposals/aggregated-api-servers.md
• https://gist.github.com/philips/a97a143546c87b86b870a82a753db1
4c - Kubernetes Third-Party	Resource Users
https://github.com/kubernetes/community/blob/master/contributors/devel/client-libraries.md
Backup
Restful
http	API
/
/version
/api
/api/v1/pods
/api/v1/pods/status
/apis
/apis/batch
/apis/batch/v2alpha1
/apis/batch/v2alpha1/jobs
/apis/batch/v2alpha1/cronjo
/apis/batch/v1beta1
/apis/batch/v1beta1/jobs
/apis/batch/v2alpha1/jobs
Group			Version			ResourceHTTP	paths:
In	Go: gvk :=	schema.GroupVersionKind{Group:	“batch“,	Version:	“v2alpha1“,	Kind:	“Job“}
obj :=	api.Scheme.New(gvk)
codec :=	api.Codecs.LegacyCodec(gvk.GroupVersion())
codec.Decode(reqBody,	gvk,	obj)
type	Job struct {
metav1.TypeMeta
metav1.ObjectMeta
Spec JobSpec
Status	JobStatus
}
pkg/apis/batch/v2alpha1/types.go
type	TypeMeta struct {
Kind	string
APIVersion string
}
type	ObjectMeta struct {
Name	string
...
}
Restful
http	API
/
/version
/api
/api/v1/pods
/api/v1/pods/status
/apis
/apis/batch
/apis/batch/v2alpha1
/apis/batch/v2alpha1/jobs
/apis/batch/v2alpha1/cronjo
/apis/batch/v1beta1
/apis/batch/v1beta1/jobs
MaxInFlightLimit
TimeoutForNonLongRunningRequests
Panic	Recovery
CORS
Authentication
Audit
Impersonation
Authorization
k8s.io/apiserver/pkg/server.
DefaultBuildHandlerChain
„Filters“
k8s.io/apiserver/pkg/server/routes/index.go – /
k8s.io/apiserver/pkg/server/routes/version.go – /version
k8s.io/apiserver/pkg/server/routes/swagger.go – /swaggerapi
k8s.io/apiserver/pkg/server/routes/openapi.go – /swagger.json
„Routes“
mux
k8s.io/apiserver/pkg/endpoints.APIGroupVersion.InstallREST
AddSupportedResourcesWebService – /apis/batch/v2alpha1
k8s.io/apiserver/pkg/endpoints.APIInstaller.Install
/apis/batch/v2alpha1/jobs
/apis/batch/v2alpha1/cronjobs
...
WithRequestInfo
ctx.RequestInfo
Restful
http	API
mux
k8s.io/apiserver/pkg/endpoints.APIGroupVersion.InstallREST
AddSupportedResourcesWebService – /apis/batch/v2alpha1
k8s.io/apiserver/pkg/endpoints.APIInstaller.Install
/apis/batch/v2alpha1/jobs
/apis/batch/v2alpha1/cronjobs
...
pkg/apis/batch
type Jobs	struct
pkg/apis/batch/v2alpha1
type Jobs	struct
api.Scheme
k8s.io/apiserver
pkg/api
api.Scheme.Convert(&internalJob,	&v2alohaJob)
/apis/batch/v2alpha1/jobs
GET
PUT
POST
DELETE
...
/status
/scale
/proxy
...
subresources
Restful
http	API
mux
pkg/apis/batch
type Jobs	struct
pkg/apis/batch/v2alp
ha1
type Jobs	struct
api.Sche
me api.Scheme.Convert(&job,	&v1job)
POST
/apis/batch/v2alpha1/jobs
k8s.io/apiserver
pkg/endpoints/handlers.CreateNamedResource
binary
JSON
payload
Go	struct
v2alpha1.Job
HTTP
Request
Go	struct
internal.Job
Store
k8s.io/apiserver
pkg/registry/generic
Storage
k8s.io/apiserver
pkg/storage/etcd3
ProtoBuf
Job
Go	struct
v2alpha1.Job
etcd
type Scheme struct
• AddKnownTypes(gv, obj Object)
• Default(src Object)
• Copy(src Object) Object
• Convert(in, out interface{})
• New(gvk) Object
ApiGroup
pkg/apis/batch
pkg/apis/batch/v1
pkg/apis/batch/v2alpha1
pkg/apis/batch/register.go
pgk/apis/batch/install
Group
Version
Kind
Resource
type Object interface
• GetObjectKind() string
client-go/pkg/api.Scheme
client-go/pkg/api.Codecs
Discovery
type APIGroupList struct
type APIVersions struct
type APIResourceList struct
GroupVersionKind „gvk“
GroupVersionResource
Unversioned types
Unstructured
List
Registry / Storage
type Storage interface
type Lister interface
type Updater interface
type Getter interface
type Deleter interface
....
deepcopy-gen
conversion-gen
defaulting-gen
Code Generation
type OwnerReference struct
type ObjectReference struct
type TypeMeta struct
type ObjectMeta struct
Meta
api.Scheme
api.Codecs
api.Registry
api.GroupFactoryRegistry
Globals

More Related Content

PDF
Cutting the Kubernetes Monorepo in pieces – never learnt more about git
PDF
Kubernetes API - deep dive into the kube-apiserver
PDF
Git deep dive – chopping Kubernetes
PDF
Meetup - Principles of the kube api and how to extend it
PDF
Extending kubernetes with CustomResourceDefinitions
PDF
Extending the Kube API
PDF
An Introduction to the Kubernetes API
PDF
Extending Kubernetes – Admission webhooks
Cutting the Kubernetes Monorepo in pieces – never learnt more about git
Kubernetes API - deep dive into the kube-apiserver
Git deep dive – chopping Kubernetes
Meetup - Principles of the kube api and how to extend it
Extending kubernetes with CustomResourceDefinitions
Extending the Kube API
An Introduction to the Kubernetes API
Extending Kubernetes – Admission webhooks

What's hot (20)

PDF
Kubernetes extensibility: crd & operators
PDF
Beyond static configuration
PDF
[表示が崩れる場合ダウンロードしてご覧ください] 2018年のDocker・Moby
PDF
Kubelet with no Kubernetes Masters | DevNation Tech Talk
PDF
KubeCon EU 2018 – Sig API Machinery Deep Dive
PPTX
CI Implementation with Kubernetes at LivePerson by Saar Demri
PDF
Continuous Deployment with Jenkins on Kubernetes
PDF
Container Days Boston - Kubernetes in production
PDF
KubeCon EU 2016: Kubernetes and the Potential for Higher Level Interfaces
PDF
CAPS: What's best for deploying and managing OpenStack? Chef vs. Ansible vs. ...
PPTX
Managing Docker Containers In A Cluster - Introducing Kubernetes
PDF
Kubernetes best practices
PPTX
Zero to Continuous Delivery on Google Cloud
PDF
Continuous Delivery in Enterprise Environments using Docker, Ansible and Jenkins
PDF
Cluster Networking with Docker
PDF
Enabling Microservices @Orbitz - DockerCon 2015
PDF
The Big Cloud native FaaS Lebowski
PPTX
Java Day Kharkiv - Next-gen engineering with Docker and Kubernetes
PDF
Achieving CI/CD with Kubernetes
PDF
OpenStack Preso: DevOps on Hybrid Infrastructure
Kubernetes extensibility: crd & operators
Beyond static configuration
[表示が崩れる場合ダウンロードしてご覧ください] 2018年のDocker・Moby
Kubelet with no Kubernetes Masters | DevNation Tech Talk
KubeCon EU 2018 – Sig API Machinery Deep Dive
CI Implementation with Kubernetes at LivePerson by Saar Demri
Continuous Deployment with Jenkins on Kubernetes
Container Days Boston - Kubernetes in production
KubeCon EU 2016: Kubernetes and the Potential for Higher Level Interfaces
CAPS: What's best for deploying and managing OpenStack? Chef vs. Ansible vs. ...
Managing Docker Containers In A Cluster - Introducing Kubernetes
Kubernetes best practices
Zero to Continuous Delivery on Google Cloud
Continuous Delivery in Enterprise Environments using Docker, Ansible and Jenkins
Cluster Networking with Docker
Enabling Microservices @Orbitz - DockerCon 2015
The Big Cloud native FaaS Lebowski
Java Day Kharkiv - Next-gen engineering with Docker and Kubernetes
Achieving CI/CD with Kubernetes
OpenStack Preso: DevOps on Hybrid Infrastructure
Ad

Similar to Extend and build on Kubernetes (20)

PDF
Kubernetes Architecture - beyond a black box - Part 1
PDF
What Does Kubernetes Look Like?: Performance Monitoring & Visualization with ...
PPTX
Introduction+to+Kubernetes-Details-D.pptx
PDF
Extending kubernetes
PDF
Kubernetes for java developers - Tutorial at Oracle Code One 2018
PPTX
Introduction to kubernetes
PDF
Introduction to Kubernetes Workshop
PDF
Getting started with kubernetes
PDF
Introduction to kubernetes
PDF
Kubernetes Architecture and Introduction – Paris Kubernetes Meetup
PDF
Kubernetes extensibility
PDF
DevJam 2019 - Introduction to Kubernetes
PDF
From CoreOS to Kubernetes and Concourse CI
PDF
Get you Java application ready for Kubernetes !
PDF
Kubernetes Basics
PDF
Kubernetes for Java developers
PDF
The App Developer's Kubernetes Toolbox
PDF
Kubernetes for the PHP developer
PDF
Kubernetes - Starting with 1.2
PPTX
Kubernetes 101
Kubernetes Architecture - beyond a black box - Part 1
What Does Kubernetes Look Like?: Performance Monitoring & Visualization with ...
Introduction+to+Kubernetes-Details-D.pptx
Extending kubernetes
Kubernetes for java developers - Tutorial at Oracle Code One 2018
Introduction to kubernetes
Introduction to Kubernetes Workshop
Getting started with kubernetes
Introduction to kubernetes
Kubernetes Architecture and Introduction – Paris Kubernetes Meetup
Kubernetes extensibility
DevJam 2019 - Introduction to Kubernetes
From CoreOS to Kubernetes and Concourse CI
Get you Java application ready for Kubernetes !
Kubernetes Basics
Kubernetes for Java developers
The App Developer's Kubernetes Toolbox
Kubernetes for the PHP developer
Kubernetes - Starting with 1.2
Kubernetes 101
Ad

Recently uploaded (20)

PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
iTop VPN Free 5.6.0.5262 Crack latest version 2025
PPTX
Patient Appointment Booking in Odoo with online payment
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
17 Powerful Integrations Your Next-Gen MLM Software Needs
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
Advanced SystemCare Ultimate Crack + Portable (2025)
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
DOCX
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
PPTX
Why Generative AI is the Future of Content, Code & Creativity?
PDF
Complete Guide to Website Development in Malaysia for SMEs
PDF
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
PDF
Designing Intelligence for the Shop Floor.pdf
PPTX
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
Wondershare Filmora 15 Crack With Activation Key [2025
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
iTop VPN Free 5.6.0.5262 Crack latest version 2025
Patient Appointment Booking in Odoo with online payment
Internet Downloader Manager (IDM) Crack 6.42 Build 41
How to Choose the Right IT Partner for Your Business in Malaysia
Design an Analysis of Algorithms II-SECS-1021-03
17 Powerful Integrations Your Next-Gen MLM Software Needs
Odoo Companies in India – Driving Business Transformation.pdf
Advanced SystemCare Ultimate Crack + Portable (2025)
CHAPTER 2 - PM Management and IT Context
wealthsignaloriginal-com-DS-text-... (1).pdf
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
Why Generative AI is the Future of Content, Code & Creativity?
Complete Guide to Website Development in Malaysia for SMEs
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
Designing Intelligence for the Shop Floor.pdf
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx

Extend and build on Kubernetes