CDK8S — это структура разработки программного обеспечения для определения приложений Kubernetes и многоразовых абстракций с использованием знакомых языков программирования и богатых объектно-ориентированных API. CDK8S генерирует чистые kubernetes yaml — вы можете использовать CDK8, чтобы определить приложения для любых кластер Kubernetes, работающих в любом месте.
Этот пост предоставляет вам несколько примеров кода Python CDK8S Python для создания развертываний K8S, услуг, готовности и живых зондов, состояние состояния, настойчивому объему и Cronjob
Что в этом документе
- Начало работы с CDK8S
- Создать кластер IP развертывания и целевой порту
- Создание приложения развертывания с готовностью и зондами живота
- Создать состояние состояния с постоянным томом
- Создать секрет прикрепления к развертыванию
- Создать Cronjob с постоянным томом претензий
- Заключение
🚀 Начало работы с CDK8S
Начало работы 1 Предварительные условия
- Python.7.7.
- Pipenv версия 2018.11.26 или выше.
2. Новый проект
$ mkdir hello $ cd hello $ cdk8s init python-app Initializing a project from the python-app template
🚀 Создайте кластер IP развертывания IP и целевой порту
from constructs import Construct from imports import k8s class ClusterIp(Construct): def __init__(self, scope: Construct, id: str): super().__init__(scope, id) app_name = 'wappip' label = {'app': app_name} k8s.KubeDeployment( self, "ClusterIpDeployment", metadata=k8s.ObjectMeta(name=app_name), spec=k8s.DeploymentSpec( replicas=2, selector=k8s.LabelSelector(match_labels=label), template=k8s.PodTemplateSpec( metadata=k8s.ObjectMeta(labels=label, name=app_name), spec=k8s.PodSpec( containers=[k8s.Container( name=app_name, image="katacoda/docker-http-server:latest", ports=[k8s.ContainerPort(container_port=80)] )] ) ) ) ) k8s.KubeService( self, 'ClusterIpService', metadata=k8s.ObjectMeta(name=app_name), spec=k8s.ServiceSpec( type='NodePort', ports=[k8s.ServicePort(port=80, node_port=30080, name="80")], selector=label ) ) k8s.KubeService( self, 'ClusterIpTargetPortService', metadata=k8s.ObjectMeta(name=f"{app_name}-targetport"), spec=k8s.ServiceSpec( ports=[k8s.ServicePort(port=8080, target_port=k8s.IntOrString.from_number(80), name="8080")], selector=label ) )
#!/usr/bin/env python from constructs import Construct from cdk8s import App, Chart from clusterip import ClusterIp class MyChart(Chart): def __init__(self, scope: Construct, id: str): super().__init__(scope, id) ClusterIp(self, 'clusterip') app = App() MyChart(app, "clusterip") app.synth()
2. Запустить
⚡ $ cdk8s synth dist/clusterip.k8s.yaml ⚡ $ cat dist/clusterip.k8s.yaml apiVersion: apps/v1 kind: Deployment metadata: name: wappip spec: replicas: 2 selector: matchLabels: app: wappip template: metadata: labels: app: wappip name: wappip spec: containers: - image: katacoda/docker-http-server:latest name: wappip ports: - containerPort: 80 -------- apiVersion: v1 kind: Service metadata: name: wappip spec: ports: - name: "80" nodePort: 30080 port: 80 selector: app: wappip type: NodePort -------- apiVersion: v1 kind: Service metadata: name: wappip-targetport spec: ports: - name: "8080" port: 8080 targetPort: 80 selector: app: wappip
🚀 Создание приложения развертывания с готовностью и зондами живота
from constructs import Construct from imports import k8s import re class ReadinessLivenesProbes(Construct): def __init__(self, scope: Construct, id: str): super().__init__(scope, id) for _name in ['frontend', 'bad-frontend']: if re.search('bad', _name): image_tag = 'unhealthy' toleration = k8s.Toleration() affinity = k8s.Affinity() else: image_tag = 'health' toleration = k8s.Toleration( effect='NoSchedule', key='fe', operator='Equal', value='healthy' ) affinity = k8s.Affinity( node_affinity=k8s.NodeAffinity( required_during_scheduling_ignored_during_execution=k8s.NodeSelector( node_selector_terms=[ k8s.NodeSelectorTerm( match_expressions=[ k8s.NodeSelectorRequirement( key='kubernetes.io/hostname', operator='In', values=['kube1'] ) ] ) ] ) ) ) label = {'app': _name} k8s.KubeDeployment( self, f"FrontendHealthy{_name}", metadata=k8s.ObjectMeta(labels=label, name=_name), spec=k8s.DeploymentSpec( replicas=1, selector=k8s.LabelSelector(match_labels=label), template=k8s.PodTemplateSpec( metadata=k8s.ObjectMeta(labels=label), spec=k8s.PodSpec( containers=[ k8s.Container( name=_name, image=f"katacoda/docker-http-server:{image_tag}", ports=[k8s.ContainerPort(container_port=80)], resources=k8s.ResourceRequirements( limits={"memory": k8s.Quantity.from_string('3000Mi'), "cpu": k8s.Quantity.from_string('1000m')}, requests={"memory": k8s.Quantity.from_string('300Mi'), "cpu": k8s.Quantity.from_string('200m')} ), readiness_probe=k8s.Probe( http_get=k8s.HttpGetAction(port=k8s.IntOrString.from_number(80), path='/'), initial_delay_seconds=1, timeout_seconds=1 ), liveness_probe=k8s.Probe( http_get=k8s.HttpGetAction(port=k8s.IntOrString.from_number(80), path='/'), initial_delay_seconds=1, failure_threshold=3, timeout_seconds=1 ) ) ], tolerations=[toleration], affinity=affinity ) ) ) )
🚀 Создать состояние состояния с постоянным томом
from constructs import Construct, Node from imports import k8s class StateFulSet(Construct): def __init__(self, scope: Construct, id: str): super().__init__(scope, id) msql_name = 'msql' msql_label = {'ss': msql_name} k8s.KubeStatefulSet( self, "MsqlStatefulSet", metadata=k8s.ObjectMeta(name=msql_name), spec=k8s.StatefulSetSpec( replicas=1, selector=k8s.LabelSelector(match_labels=msql_label), service_name=msql_name, template=k8s.PodTemplateSpec( metadata=k8s.ObjectMeta(labels=msql_label, name=msql_name), spec=k8s.PodSpec( containers=[k8s.Container( name=msql_name, image="openshift/mysql-55-centos7", ports=[k8s.ContainerPort(container_port=3306)], env=[ k8s.EnvVar(name='MYSQL_ROOT_PASSWORD', value='yourpassword'), k8s.EnvVar(name='MYSQL_USER', value='wp_user'), k8s.EnvVar(name='MYSQL_PASSWORD', value='wp_pass'), k8s.EnvVar(name='MYSQL_DATABASE', value='wp_db'), ], volume_mounts=[k8s.VolumeMount(mount_path='/var/lib/mysql/data', name='mysql-persistent-storage')] )] ) ), volume_claim_templates=[ k8s.KubePersistentVolumeClaimProps( metadata=k8s.ObjectMeta(name="mysql-persistent-storage"), spec=k8s.PersistentVolumeClaimSpec( access_modes=["ReadWriteOnce"], resources=k8s.ResourceRequirements(requests={"storage": k8s.Quantity.from_string("2Gi")}) ) ) ] ) ) k8s.KubePersistentVolume( self, "STSPersistentVolume1", metadata=k8s.ObjectMeta(name='nfs-0001'), spec=k8s.PersistentVolumeSpec( access_modes=['ReadWriteOnce', 'ReadWriteMany'], capacity={'storage': k8s.Quantity.from_string('2Gi')}, nfs=k8s.NfsVolumeSource(path='/exports/data-0001', server='192.168.121.210'), persistent_volume_reclaim_policy='Retain' ) ) k8s.KubePersistentVolume( self, "STSPersistentVolume2", metadata=k8s.ObjectMeta(name='nfs-0002'), spec=k8s.PersistentVolumeSpec( access_modes=['ReadWriteOnce', 'ReadWriteMany'], capacity={'storage': k8s.Quantity.from_string('5Gi')}, nfs=k8s.NfsVolumeSource(path='/exports/data-0002', server='192.168.121.210'), persistent_volume_reclaim_policy='Retain' ) )
🚀 Создайте секретную прикрепление к развертыванию
from constructs import Construct, Node from imports import k8s class Secrete(Construct): def __init__(self, scope: Construct, id: str): super().__init__(scope, id) app_name = 'myscecret' label = {'app': app_name} k8s.KubeDeployment( self, "SecreteDeployment", metadata=k8s.ObjectMeta(name=app_name), spec=k8s.DeploymentSpec( replicas=1, selector=k8s.LabelSelector(match_labels=label), template=k8s.PodTemplateSpec( metadata=k8s.ObjectMeta(labels=label, name=app_name), spec=k8s.PodSpec( containers=[ k8s.Container( name=app_name, image="alpine:latest", ports=[k8s.ContainerPort(container_port=80)], command=['sleep', '9999'], env=[ k8s.EnvVar( name='SECRET_USERNAME', value_from=k8s.EnvVarSource( secret_key_ref=k8s.SecretKeySelector(key='username', name='test-secret') ) ), k8s.EnvVar( name='SECRET_PASSWORD', value_from=k8s.EnvVarSource( secret_key_ref=k8s.SecretKeySelector(key='password', name='test-secret') ) ) ] ) ] ) ) ) ) k8s.KubeSecret( self, 'Secrete', metadata=k8s.ObjectMeta(name='test-secret'), type='Opaque', data={"username": "YWRtaW4=", "password": "YTYyZmpiZDM3OTQyZGNz"} )
🚀 создать Cronjob с постоянным томом претензий
from constructs import Construct, Node from imports import k8s class DocCronjob(Construct): def __init__(self, scope: Construct, id: str): super().__init__(scope, id) app_name = 'doc-clean' label = {'app': app_name} k8s.KubeCronJobV1Beta1( self, "DocCronjob", metadata=k8s.ObjectMeta(name=app_name, labels=label), spec=k8s.CronJobSpec( job_template=k8s.JobTemplateSpec( metadata=k8s.ObjectMeta(name=app_name), spec=k8s.JobSpec( template=k8s.PodTemplateSpec( metadata=k8s.ObjectMeta(name=app_name), spec=k8s.PodSpec( containers=[ k8s.Container( name=app_name, image="busybox", volume_mounts=[k8s.VolumeMount(mount_path='/opt/Documents', name='efs')], args=['/bin/sh', '-c', 'find /opt/Documents/Viewer/cache -type d -mtime +6 -exec rm -r {} \;; find /opt/Documents/Viewer -type f -mtime +6 -exec rm {} \;' ] ), ], restart_policy='OnFailure', volumes=[ k8s.Volume( name='efs', persistent_volume_claim=k8s.PersistentVolumeClaimVolumeSource( claim_name='efs-pvc' ) ) ] ) ) ) ), schedule='0 1 * * SAT' ) )
🚀 вывод
CDK8S просто находится в бета-версии, вы должны рассмотреть возможность использовать его для производства, пока не достигнет определенного уровня зрелости (возможно, первая основная версия)
🌠 Блог · Github · Stackoverflow · LinkedIn · Группа · Страница · Twitter 🌠.
Оригинал: «https://dev.to/vumdao/cdk8s-example-2glk»