No project description provided
Project description
pdk8s
Generating Kubernetes definitions (yaml) with python, inspired by cdk8s. The main use case is to use those definitions with helm. This means cdk8s does replace all the templating that helm does - but helm still takes care of rolling out your changes to your cluster.
Getting started
Installing pdk8s
Prerequisites
- Python >= 3.7.
- Python knowledge
Installation via PyPi
pdk8s is available on PyPi, you can install it with your preferred python package manage, pip
, pipenv
, etc:
pip install pdk8s
Intro
The format of pdk8s
charts is similar to helm charts, just that they are python instead of yaml. Your “python chart" must define the following variables:
name
: Name of your chartchart_version
: This is the chart version. This version number should be incremented each time you make changes to the chart and its templates, including the app version. Versions are expected to follow Semantic Versioning.app_version
: This is the version number of the application being deployed. This version number should be incremented each time you make changes to the application. Versions are not expected to follow Semantic Versioning. They should reflect the version the application is using.chart
: Your chart. A list orpdk8s.k8s.Chart
(or actually any iterable python object) of k8s resources.
If you had a déjà vu while reading - that is because the description for chart_version
and app_version
are copied straight from Helm ;)
Getting started
$ pdk8s init
chart_name [awesome chart]: Webserver Example
slug [webserver_example]:
chart_version [0.1.0]:
app_version [0.1.0]:
You will find a new folder and files named: webserver_example/chart.py
. Inside this file you will find a hello world example:
chart = [
k8s.Deployment(name='deployment',
spec=k8s.DeploymentSpec(
replicas=2,
selector=k8s.LabelSelector(match_labels=label),
template=k8s.PodTemplateSpec(
metadata=k8s.ObjectMeta(labels=label),
spec=k8s.PodSpec(containers=[
k8s.Container(
name='hello-kubernetes',
image='paulbouwer/hello-kubernetes:1.7',
ports=[k8s.ContainerPort(container_port=8080)])]))))
]
Which you can turn into a running helm chart with:
$ pdk8s synth
You will find your generated chart under dist
:
├── chart.py └── dist ├── Chart.yaml ├── templates │ └── generated.yaml └── values.yaml
Per default pdk8s synth
loads the chart.py
in the current directory. You can also use -i
to specify a different python file. Also the chart.py
generated by pdk8s init
provides the same api as pdk8s
except without the -i
option:
$ ./chart.py synth
Creating Ressources
Creating a service:
from pdk8s import k8s
service = k8s.Service(name="service",
spec=k8s.ServiceSpec(
type="LoadBalancer",
ports=[k8s.ServicePort(port=80, target_port=8080)],
selector={"app": "hello-k8s"}))
chart = [service]
All pdk8s
classes are pydantic data classes. Which provides - among other things - automatic conversion for parameters, so you can just as well write:
from pdk8s import k8s
k8s.Service(name="service",
spec={
"type": "LoadBalancer",
"ports": [{"port": 80, "target_port": 8080}],
"selector": {"app": "hello-k8s"}})
Manipulating
All attributes can be manipulated after creation:
deployment = k8s.Deployment(name='deployment',
spec=k8s.DeploymentSpec(
replicas=2))
deployment.spec.replicas = math.randint(0, 666)
Note 1: Automatic casting is only available on creation. deployment.spec = {"replicas": 2}
would not work.
Note 2: Currently all required parameters must be provided at creation time. You cannot create an empty k8s.Deployment()
. This might change.
CamelCase names
The Kubernetes APIs use camelCase for naming attributes, while python usually uses snake_case. pdk8s
also follows the snake_case convention, same as cdk8s
.
pdk8s
provides aliases for all arguments:
k8s.ServicePort(port=80, target_port=8080)
k8s.ServicePort(port=80, targetPort=8080)
Both work and result in the same result. This is for compatibility when importing from other sources (and makes pdk8s.k8s.parse
possible).
Importing existing charts
You might already have templates you want to build upon, you can easily import them using pdk8s.k8s.parse
. Let's assume you have the following chart.yaml
:
apiVersion: v1
kind: Service
metadata:
name: service
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: hello-k8s
type: LoadBalancer
With:
import pdk8s
from pdk8s import k8s
my_chart = k8s.parse("example/chart.yaml")
my_chart[0].name = "service_new"
pdk8s.synth(my_chart)
You get:
apiVersion: v1
kind: Service
metadata:
name: service_new
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: hello-k8s
type: LoadBalancer
Compatibility to cdk8s
There are a few differences that make code between the cdk8s
and pdk8s
incompatible. A good overview can be archived by comparing the following to examples:
Pure python
cdk8s
is written in TypeScript and with the power of jsii usable from other languages, as python. pdk8s
is written in pure python with no bridge to other languages. This means you are limited to python and cannot reuse charts written in other languages. Therefore, a pdk8s
is focused on providing an awesome experience writing charts in python: Readable tracebacks, happy IDE and linters, ...
Context / Constructs
Currently, there is no equivalent of "constructs" in pdk8s
. In cdk8s
highlevel objects (e.g. Service
) are special: They have an extra argument (the first one) which is the context in which they are defined, e.g. k8s.Service(self, ...)
where self
is the context.
In pdk8s
there is no special treatment of these types. There might be later on, but they would be added and not replaced.
This allows for more flexibility on how to construct your chart generator.
Names
In cdk8s
names are automatically made unique by adding a hash to it. pdk8s
does not observe this behavior. Also in pdk8s
names must be provided as keyword argument.
# cdk8s
k8s.Service(Chart("hello"), "service")
# kind: Service
# apiVersion: v1
# metadata:
# name: hello-service-9878228b
# pdk8s
k8s.Service(name='service')
# kind: Service
# apiVersion: v1
# metadata:
# name: service
IntOrString
# cdk8s
k8s.ServicePort(port=80, target_port=k8s.IntOrString.from_number(8080))
# pdk8s
k8s.ServicePort(port=80, target_port=8080)
# k8s.IntOrString might be added for compatibility later on
Why
TODO explain why this exists (NIH syndrom)
Design Decisions
Generate at build time
Generate everything at build time and not runtime as it makes it easier for linters and other dev tools, like IDEs.
Attribute case
CamelCase?
Naming
Versioning
Development and building
Currently, generating the code of pdk8s
depends on a patched version of datamodel-code-generator
. I am working on upstreaming changes to not depend on local patches anymore.
Sources
- https://github.com/kubernetes/kubernetes/tree/master/api/openapi-spec - openapi definition.
- https://github.com/instrumenta/kubernetes-json-schema - JSON Schema of Kubernetes API, generated from official openapi definitions. Used by cdk8s.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file pdk8s-0.2.2.tar.gz
.
File metadata
- Download URL: pdk8s-0.2.2.tar.gz
- Upload date:
- Size: 131.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.0.9 CPython/3.8.3 Linux/5.7.7-200.fc32.x86_64
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c5f6ffb489aa6528cbd0847c85987ae9a79e4d30ad6484f9a26a4097e1e9b2b5 |
|
MD5 | 7ef2bcadf28ce2c307f38c3b447e3d90 |
|
BLAKE2b-256 | d236c17872e7c2fc6edf1656dc0f948eee435bf32009d0f91f3e3c304734591a |
File details
Details for the file pdk8s-0.2.2-py3-none-any.whl
.
File metadata
- Download URL: pdk8s-0.2.2-py3-none-any.whl
- Upload date:
- Size: 199.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.0.9 CPython/3.8.3 Linux/5.7.7-200.fc32.x86_64
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2f71141f52289d996c75d8debb13b420bdafe6370128fe614019e2c08938c833 |
|
MD5 | f4a70c459fedc784ea1c8f62c06521f3 |
|
BLAKE2b-256 | a34f617371af79e69f3cbbdac6e8cbc0d5bcecc597817fed14beaef365a908b0 |