使用 Python 编排 Kubernetes

由于 YAML的局限,它是配置文件,不够灵活,所以我便写了这个程序,目前还没有进入 Release 阶段。等我用一段时间,稳定了,就会升级。
建议先看看这篇文章,更能理解我的思路。
https://my.oschina.net/neochen/blog/5274725
安装方法
pip install netkiller-devops
演示代码
import os,sysmodule = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))print(module)sys.path.insert(0,module)from netkiller.kubernetes import *print("=" * 40, "Namespace", "=" * 40)namespace = Namespace()namespace.metadata().namespace('production')namespace.debug()# exit()print("=" * 40, "ConfigMap", "=" * 40)config = ConfigMap()config.apiVersion('v1')config.metadata().name('test').namespace('test')config.data({'host':'localhost','port':3306,'user':'root','pass':'123456'})# config.data({'redis.conf':'''|-# pidfile /var/lib/redis/redis.pid# dir /var/lib/redis# port 6379# bind 0.0.0.0# appendonly yes# protected-mode no# requirepass 123456# '''})config.dump()config.debug()print("=" * 40, "ServiceAccount", "=" * 40)account = ServiceAccount()account.metadata().name('search').namespace('search').labels({'app':'elasticsearch'})account.debug()print("=" * 40, "Pod", "=" * 40)pod = Pod()pod.apiVersion()pod.metadata().name('counter').annotations(['security.alpha.kubernetes.io/sysctls: kernel.shm_rmid_forced=1'])pod.metadata().namespace('development')spec = container = pod.spec()spec.restartPolicy('Always')spec.hostAliases([{'ip':'127.0.0.1','hostname':['www.netkiller.cn','db.netkiller.cn']}])spec.securityContext({'sysctls': ['name: net.core.somaxconn','value: "1024"'], 'privileged': 'true'})pod.spec().env([{'name':'HOST','valueFrom':{'configMapKeyRef':{'name': 'db-config','key': 'db.host'}}}])container = pod.spec().containers()container.name('nginx')container.image('nginx:latest').volumeMounts([{'name': 'config-volume','mountPath': '/etc/config'},{'name': 'config','mountPath': '/usr/local/etc/redis/redis.conf','subPath': 'redis.conf'}])container.command(['nginx -c /etc/nginx/nginx.conf'])pod.spec().containers().ports([{'containerPort':'6379'}])pod.spec().volumes().name('config-volume').configMap({'name':'special-config', 'items':[{'key':'cache','path':'/mnt/cache'}]})pod.debug()print("=" * 40, "Service", "=" * 40)service = Service()service.metadata().name('web')service.metadata().namespace('stage')service.spec().selector({'app': 'nginx'})service.spec().type('NodePort')service.spec().ports([{'name':'http','protocol':'TCP','port':'80','targetPort':'80'}])service.spec().externalIPs(['172.16.0.250'])service.spec().clusterIP('172.168.0.254')service.status().loadBalancer({'ingress': [{'ip': '127.18.10.12'}]})service.debug()print("=" * 40, "Service1", "=" * 40)service1 = Service()service1.metadata().name('mysql')service1.metadata().namespace('testing')service1.spec().selector({'app': 'mysql'})service1.spec().type('NodePort')service1.spec().ports([{'name':'mysql','protocol':'TCP','port':'3306','targetPort':'3306'}])service1.spec().externalIPs(['172.16.0.25'])service1.spec().clusterIP('172.168.0.25')service1.status().loadBalancer({'ingress': [{'ip': '127.18.10.1'}]})service1.debug()print("=" * 40, "Deployment", "=" * 40)deployment = Deployment()deployment.metadata().name('redis').labels({'app':'redis'})deployment.spec().replicas(2)deployment.spec().selector({'matchLabels':{'app':'redis'}})deployment.spec().template().metadata().labels({'app':'redis'})deployment.spec().template().spec().containers().name('redis').image('redis:alpine').ports([{'containerPort':'6379'}])deployment.debug()deployment.json()print("=" * 40, "Ingress", "=" * 40)ingress = Ingress()ingress.apiVersion('networking.k8s.io/v1beta1')ingress.metadata().name('springboot')ingress.metadata().namespace('stage')ingress.metadata().annotations(['nginx.ingress.kubernetes.io/rewrite-target: /','nginx.ingress.kubernetes.io/rewrite-target: /article/$1'])ingress.spec().rules([{'host':'www.netkiller.cn','http':{'paths': [{'backend':{'serviceName':'www', 'servicePort':80}}] }}])ingress.spec().rules([{'host':'article.netkiller.cn','http':{'paths': [{'path':'/($/.*)','backend':{'serviceName':'article', 'servicePort':80}}] }}])ingress.debug()
输出结果
======================================== Namespace ========================================apiVersion: v1kind: Namespacemetadata:namespace: production======================================== ConfigMap ========================================apiVersion: v1data:host: localhostpass: '123456'port: 3306user: rootkind: ConfigMapmetadata:name: testnamespace: test======================================== ServiceAccount ========================================apiVersion: v1kind: ServiceAccountmetadata:labels:app: elasticsearchname: searchnamespace: search======================================== Pod ========================================apiVersion: v1kind: Podmetadata:namespace: developmentspec:containers:- command:- - nginx -c /etc/nginx/nginx.confimages: nginx:latestname: nginxports:- containerPort: '6379'volumeMounts:- mountPath: /etc/configname: config-volume- mountPath: /usr/local/etc/redis/redis.confname: configsubPath: redis.confenv:- name: HOSTvalueFrom:configMapKeyRef:key: db.hostname: db-confighostAliases:- hostname:- www.netkiller.cn- db.netkiller.cnip: 127.0.0.1restartPolicy: AlwayssecurityContext:privileged: 'true'sysctls:- 'name: net.core.somaxconn'- 'value: "1024"'volumes:- configMap:items:- key: cachepath: /mnt/cachename: special-configname: config-volume======================================== Service ========================================apiVersion: v1kind: Servicemetadata:namespace: stagespec:clusterIP: 172.168.0.254externalIPs:- 172.16.0.250ports:- name: httpport: '80'protocol: TCPtargetPort: '80'selector:app: nginxtype: NodePortstatus:loadBalancer:ingress:- ip: 127.18.10.12======================================== Service1 ========================================apiVersion: v1kind: Servicemetadata:namespace: testingspec:clusterIP: 172.168.0.25externalIPs:- 172.16.0.25ports:- name: mysqlport: '3306'protocol: TCPtargetPort: '3306'selector:app: mysqltype: NodePortstatus:loadBalancer:ingress:- ip: 127.18.10.1======================================== Deployment ========================================apiVersion: apps/v1kind: Deploymentmetadata:labels:app: redisname: redisspec:replicas: 2selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- command:- - nginx -c /etc/nginx/nginx.confimages: redis:alpinename: redisports:- containerPort: '6379'volumeMounts:- mountPath: /etc/configname: config-volume- mountPath: /usr/local/etc/redis/redis.confname: configsubPath: redis.conf{'apiVersion': 'apps/v1', 'kind': 'Deployment', 'metadata': {'name': 'redis', 'labels': {'app': 'redis'}}, 'spec': {'replicas': 2, 'selector': {'matchLabels': {'app': 'redis'}}, 'template': {'metadata': {'labels': {'app': 'redis'}}, 'spec': {'containers': [{'name': 'redis', 'images': 'redis:alpine', 'volumeMounts': [{'name': 'config-volume', 'mountPath': '/etc/config'}, {'name': 'config', 'mountPath': '/usr/local/etc/redis/redis.conf', 'subPath': 'redis.conf'}], 'command': [['nginx -c /etc/nginx/nginx.conf']], 'ports': [{'containerPort': '6379'}]}]}}}}======================================== Ingress ========================================apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata:annotations:- 'nginx.ingress.kubernetes.io/rewrite-target: /'- 'nginx.ingress.kubernetes.io/rewrite-target: /article/$1'spec:rules:- host: www.netkiller.cnhttp:paths:- backend:serviceName: wwwservicePort: 80- host: article.netkiller.cnhttp:paths:- backend:serviceName: articleservicePort: 80path: /($/.*)
使用 python 替代 docker compose 编排容器
文章转载自netkiller,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




