你还在用YAML编排K8s吗?看看这篇吧

2021-10-20 11:09:37 浏览数 (1)

使用 Python 编排 Kubernetes

由于 YAML的局限,它是配置文件,不够灵活,所以我便写了这个程序,目前还没有进入 Release 阶段。等我用一段时间,稳定了,就会升级。

建议先看看这篇文章,更能理解我的思路。

https://my.oschina.net/neochen/blog/5274725

安装方法

pip install netkiller-devops

演示代码

代码语言:javascript复制
import os,sys

module = 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()

输出结果

代码语言:javascript复制
======================================== Namespace ========================================
apiVersion: v1
kind: Namespace
metadata:
  namespace: production

======================================== ConfigMap ========================================
apiVersion: v1
data:
  host: localhost
  pass: '123456'
  port: 3306
  user: root
kind: ConfigMap
metadata:
  name: test
  namespace: test

======================================== ServiceAccount ========================================
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app: elasticsearch
  name: search
  namespace: search

======================================== Pod ========================================
apiVersion: v1
kind: Pod
metadata:
  namespace: development
spec:
  containers:
  - command:
    - - nginx -c /etc/nginx/nginx.conf
    images: nginx:latest
    name: nginx
    ports:
    - containerPort: '6379'
    volumeMounts:
    - mountPath: /etc/config
      name: config-volume
    - mountPath: /usr/local/etc/redis/redis.conf
      name: config
      subPath: redis.conf
  env:
  - name: HOST
    valueFrom:
      configMapKeyRef:
        key: db.host
        name: db-config
  hostAliases:
  - hostname:
    - www.netkiller.cn
    - db.netkiller.cn
    ip: 127.0.0.1
  restartPolicy: Always
  securityContext:
    privileged: 'true'
    sysctls:
    - 'name: net.core.somaxconn'
    - 'value: "1024"'
  volumes:
  - configMap:
      items:
      - key: cache
        path: /mnt/cache
      name: special-config
    name: config-volume

======================================== Service ========================================
apiVersion: v1
kind: Service
metadata:
  namespace: stage
spec:
  clusterIP: 172.168.0.254
  externalIPs:
  - 172.16.0.250
  ports:
  - name: http
    port: '80'
    protocol: TCP
    targetPort: '80'
  selector:
    app: nginx
  type: NodePort
status:
  loadBalancer:
    ingress:
    - ip: 127.18.10.12

======================================== Service1 ========================================
apiVersion: v1
kind: Service
metadata:
  namespace: testing
spec:
  clusterIP: 172.168.0.25
  externalIPs:
  - 172.16.0.25
  ports:
  - name: mysql
    port: '3306'
    protocol: TCP
    targetPort: '3306'
  selector:
    app: mysql
  type: NodePort
status:
  loadBalancer:
    ingress:
    - ip: 127.18.10.1

======================================== Deployment ========================================
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: redis
  name: redis
spec:
  replicas: 2
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - command:
        - - nginx -c /etc/nginx/nginx.conf
        images: redis:alpine
        name: redis
        ports:
        - containerPort: '6379'
        volumeMounts:
        - mountPath: /etc/config
          name: config-volume
        - mountPath: /usr/local/etc/redis/redis.conf
          name: config
          subPath: 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/v1beta1
kind: Ingress
metadata:
  annotations:
  - 'nginx.ingress.kubernetes.io/rewrite-target: /'
  - 'nginx.ingress.kubernetes.io/rewrite-target: /article/$1'
spec:
  rules:
  - host: www.netkiller.cn
    http:
      paths:
      - backend:
          serviceName: www
          servicePort: 80
  - host: article.netkiller.cn
    http:
      paths:
      - backend:
          serviceName: article
          servicePort: 80
        path: /($/.*)

0 人点赞