Kubernetes Operator amin'ny Python tsy misy rafitra sy SDK

Kubernetes Operator amin'ny Python tsy misy rafitra sy SDK

Go amin'izao fotoana izao dia manana ampihimamba amin'ny fiteny fandaharana izay nofidin'ny olona hanoratra fanambarana ho an'ny Kubernetes. Misy antony tsy mitongilana amin'izany, toy ny:

  1. Misy rafitra matanjaka ho an'ny fampandrosoana ny mpandraharaha ao amin'ny Go - Operator SDK.
  2. Ny fampiharana manova lalao toa an'i Docker sy Kubernetes dia voasoratra ao amin'ny Go. Ny fanoratana ny mpampiasa anao amin'ny Go dia midika hoe miteny mitovy fiteny amin'ny tontolo iainana.
  3. Fampisehoana avo lenta amin'ny fampiharana Go sy fitaovana tsotra ahafahana miasa miaraka amin'ny concurrency ivelan'ny boaty.

NB: Raha ny marina, ny fomba hanoratana ny fanambaranao manokana ao amin'ny Go, izahay efa voalaza ao amin'ny iray amin'ireo fandikan-teny nataon'ny mpanoratra vahiny.

Ahoana anefa raha voasakana tsy hianatra Mandehana ianao noho ny tsy fahampian'ny fotoana na, raha tsorina, ny antony manosika? Ny lahatsoratra dia manome ohatra amin'ny fomba ahafahanao manoratra fanambarana tsara amin'ny fampiasana ny iray amin'ireo fiteny malaza indrindra izay fantatry ny injeniera DevOps rehetra - Python.

Hihaona: Copier - operator kopia!

Ohatra, eritrereto ny mamolavola fanambarana tsotra natao handikana ny ConfigMap na rehefa miseho ny toerana misy anarana vaovao na rehefa miova ny iray amin'ireo singa roa: ConfigMap sy Secret. Amin'ny fomba fijery azo ampiharina, ny mpandraharaha dia mety ilaina amin'ny fanavaozana be dia be amin'ny fanamafisana ny fampiharana (amin'ny fanavaozana ny ConfigMap) na amin'ny fanavaozana ny angon-drakitra miafina - ohatra, ny fanalahidy amin'ny fiaraha-miasa amin'ny Docker Registry (rehefa manampy Secret amin'ny namespace).

Ary noho izany, inona no tokony hananan'ny mpandraharaha tsara:

  1. Ny fifandraisana amin'ny mpandraharaha dia atao amin'ny fampiasana Famaritana loharano manokana (antsoina hoe CRD avy eo).
  2. Ny operator dia azo amboarina. Mba hanaovana izany dia hampiasa sainam-baiko sy fari-piainan'ny tontolo iainana isika.
  3. Ny fananganana ny Docker container sy ny tabilao Helm dia natao mba ahafahan'ny mpampiasa mametraka mora foana (ara-bakiteny miaraka amin'ny baiko iray) ny mpandraharaha ao amin'ny cluster Kubernetes.

CRD

Mba hahafantaran'ny mpandraharaha ny loharanon-karena sy ny toerana hijerena azy dia mila mametraka fitsipika ho azy isika. Ny fitsipika tsirairay dia aseho ho zavatra CRD tokana. Sahan inona no tokony ananan'ity CRD ity?

  1. Karazana loharano, izay hotadiavintsika (ConfigMap na Secret).
  2. Lisitry ny toerana misy anarana, izay tokony hisy ny loharanon-karena.
  3. selector, izay hikaroka loharano ao amin'ny namespace.

Andeha hofaritana ny CRD:

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: copyrator.flant.com
spec:
  group: flant.com
  versions:
  - name: v1
    served: true
    storage: true
  scope: Namespaced
  names:
    plural: copyrators
    singular: copyrator
    kind: CopyratorRule
    shortNames:
    - copyr
  validation:
    openAPIV3Schema:
      type: object
      properties:
        ruleType:
          type: string
        namespaces:
          type: array
          items:
            type: string
        selector:
          type: string

Ary hamorona izany avy hatrany izahay fitsipika tsotra - hikaroka ao amin'ny namespace misy ny anarana default ConfigMap rehetra misy marika toy ny copyrator: "true":

apiVersion: flant.com/v1
kind: CopyratorRule
metadata:
  name: main-rule
  labels:
    module: copyrator
ruleType: configmap
selector:
  copyrator: "true"
namespace: default

Vonona! Ankehitriny dia mila mahazo vaovao momba ny fitsipikay izahay. Avelao aho hanao famandrihana avy hatrany fa tsy hanoratra fangatahana amin'ny Server API cluster ny tenanay. Mba hanaovana izany dia hampiasa tranomboky Python efa vita izahay kubernetes-client:

import kubernetes
from contextlib import suppress


CRD_GROUP = 'flant.com'
CRD_VERSION = 'v1'
CRD_PLURAL = 'copyrators'


def load_crd(namespace, name):
    client = kubernetes.client.ApiClient()
    custom_api = kubernetes.client.CustomObjectsApi(client)

    with suppress(kubernetes.client.api_client.ApiException):
        crd = custom_api.get_namespaced_custom_object(
            CRD_GROUP,
            CRD_VERSION,
            namespace,
            CRD_PLURAL,
            name,
        )
    return {x: crd[x] for x in ('ruleType', 'selector', 'namespace')}

Vokatry ny fampandehanana ity code ity dia mahazo ireto manaraka ireto isika:

{'ruleType': 'configmap', 'selector': {'copyrator': 'true'}, 'namespace': ['default']}

Tsara: nahavita nahazo fitsipika ho an'ny mpandraharaha izahay. Ary ny tena zava-dehibe dia nanao ilay antsoina hoe fomba Kubernetes izahay.

Fiovaovan'ny tontolo iainana na saina? Raisinay ny zava-drehetra!

Andeha isika hiroso amin'ny fandrindrana opΓ©rateur lehibe. Misy fomba roa fototra amin'ny fanamafisana ny fampiharana:

  1. mampiasa safidy andalana baiko;
  2. mampiasa fari-piainana manodidina.

Ny safidy andalana baiko dia ahafahanao mamaky fika mora kokoa, miaraka amin'ny fanohanana sy fanamarinana karazana data. Ny tranomboky mahazatra Python dia manana module argparser, izay hampiasainay. Ny antsipiriany sy ny ohatra momba ny fahaizany dia hita ao antontan-taratasy ofisialy.

Ho an'ny tranga misy antsika dia toy izao ny ohatra iray amin'ny fametrahana ny sainam-pibaiko amin'ny famakiana baiko:

   parser = ArgumentParser(
        description='Copyrator - copy operator.',
        prog='copyrator'
    )
    parser.add_argument(
        '--namespace',
        type=str,
        default=getenv('NAMESPACE', 'default'),
        help='Operator Namespace'
    )
    parser.add_argument(
        '--rule-name',
        type=str,
        default=getenv('RULE_NAME', 'main-rule'),
        help='CRD Name'
    )
    args = parser.parse_args()

Amin'ny lafiny iray, amin'ny fampiasana ny fari-piainan'ny tontolo iainana ao amin'ny Kubernetes, azonao atao ny mamindra mora foana ny fampahalalana momba ny serivisy momba ny pod ao anaty fitoeran-javatra. Ohatra, afaka mahazo fampahafantarana momba ny namespace iasan'ny pod isika miaraka amin'ireto fanamboarana manaraka ireto:

env:
- name: NAMESPACE
  valueFrom:
     fieldRef:
         fieldPath: metadata.namespace 

Lojika operator

Mba hahatakarana ny fomba hanasarahana ny fomba fiasa amin'ny ConfigMap sy Secret, dia hampiasa sarintany manokana izahay. Avy eo dia azontsika takarina ny fomba ilaintsika hanarahana sy hamoronana ilay zavatra:

LIST_TYPES_MAP = {
    'configmap': 'list_namespaced_config_map',
    'secret': 'list_namespaced_secret',
}

CREATE_TYPES_MAP = {
    'configmap': 'create_namespaced_config_map',
    'secret': 'create_namespaced_secret',
}

Manaraka, mila mandray hetsika avy amin'ny mpizara API ianao. Andao hampihatra izany toy izao manaraka izao:

def handle(specs):
    kubernetes.config.load_incluster_config()
    v1 = kubernetes.client.CoreV1Api()

    # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ для слСТСния Π·Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ
    method = getattr(v1, LIST_TYPES_MAP[specs['ruleType']])
    func = partial(method, specs['namespace'])

    w = kubernetes.watch.Watch()
    for event in w.stream(func, _request_timeout=60):
        handle_event(v1, specs, event)

Aorian'ny fandraisana ny hetsika dia miroso amin'ny lojika fototra amin'ny fanodinana azy isika:

# Π’ΠΈΠΏΡ‹ событий, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄Π΅ΠΌ Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ
ALLOWED_EVENT_TYPES = {'ADDED', 'UPDATED'}


def handle_event(v1, specs, event):
    if event['type'] not in ALLOWED_EVENT_TYPES:
        return

    object_ = event['object']
    labels = object_['metadata'].get('labels', {})

    # Π˜Ρ‰Π΅ΠΌ совпадСния ΠΏΠΎ selector'Ρƒ
    for key, value in specs['selector'].items():
        if labels.get(key) != value:
            return
    # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Π΅ namespace'Ρ‹
    namespaces = map(
        lambda x: x.metadata.name,
        filter(
            lambda x: x.status.phase == 'Active',
            v1.list_namespace().items
        )
    )
    for namespace in namespaces:
        # ΠžΡ‡ΠΈΡ‰Π°Π΅ΠΌ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅, устанавливаСм namespace
        object_['metadata'] = {
            'labels': object_['metadata']['labels'],
            'namespace': namespace,
            'name': object_['metadata']['name'],
        }
        # Π’Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ создания/обновлСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
        methodcaller(
            CREATE_TYPES_MAP[specs['ruleType']],
            namespace,
            object_
        )(v1)

Efa vonona ny lojika lehibe! Ankehitriny dia mila manangona izany rehetra izany ao anaty fonosana Python iray isika. Manomana ny rakitra izahay setup.py, manorata fampahalalana meta momba ny tetikasa ao:

from sys import version_info

from setuptools import find_packages, setup

if version_info[:2] < (3, 5):
    raise RuntimeError(
        'Unsupported python version %s.' % '.'.join(version_info)
    )


_NAME = 'copyrator'
setup(
    name=_NAME,
    version='0.0.1',
    packages=find_packages(),
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
    ],
    author='Flant',
    author_email='[email protected]',
    include_package_data=True,
    install_requires=[
        'kubernetes==9.0.0',
    ],
    entry_points={
        'console_scripts': [
            '{0} = {0}.cli:main'.format(_NAME),
        ]
    }
)

NB: Ny mpanjifa kubernetes ho an'ny Python dia manana ny endriny manokana. Misy fampahalalana bebe kokoa momba ny fifanarahana eo amin'ny dikan-tenin'ny mpanjifa sy ny dikan-teny Kubernetes matrices mifanentana.

Toy izao ny tetikasanay:

copyrator
β”œβ”€β”€ copyrator
β”‚   β”œβ”€β”€ cli.py # Π›ΠΎΠ³ΠΈΠΊΠ° Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строкой
β”‚   β”œβ”€β”€ constant.py # ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΠ»ΠΈ Π²Ρ‹ΡˆΠ΅
β”‚   β”œβ”€β”€ load_crd.py # Π›ΠΎΠ³ΠΈΠΊΠ° Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ CRD
β”‚   └── operator.py # Основная Π»ΠΎΠ³ΠΈΠΊΠ° Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°
└── setup.py # ΠžΡ„ΠΎΡ€ΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΊΠ΅Ρ‚Π°

Docker sy Helm

Ny Dockerfile dia ho tena tsotra: raiso ny sary python-alpine fototra ary apetraho ny fonosanay. Andao hanemotra ny fanatsarana azy ho amin'ny fotoana tsara kokoa:

FROM python:3.7.3-alpine3.9

ADD . /app

RUN pip3 install /app

ENTRYPOINT ["copyrator"]

Ny fametrahana ho an'ny mpandraharaha dia tena tsotra ihany koa:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Chart.Name }}
spec:
  selector:
    matchLabels:
      name: {{ .Chart.Name }}
  template:
    metadata:
      labels:
        name: {{ .Chart.Name }}
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: privaterepo.yourcompany.com/copyrator:latest
        imagePullPolicy: Always
        args: ["--rule-type", "main-rule"]
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
      serviceAccountName: {{ .Chart.Name }}-acc

Farany, mila mamorona anjara sahaza ho an'ny mpandraharaha manana zo ilaina ianao:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ .Chart.Name }}-acc

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: {{ .Chart.Name }}
rules:
  - apiGroups: [""]
    resources: ["namespaces"]
    verbs: ["get", "watch", "list"]
  - apiGroups: [""]
    resources: ["secrets", "configmaps"]
    verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: {{ .Chart.Name }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: {{ .Chart.Name }}
subjects:
- kind: ServiceAccount
  name: {{ .Chart.Name }}

Ny vokany

Toy izany no nahafahanay nanangana ny mpandraharaha anay manokana ho an'ny Kubernetes amin'ny Python, tsy misy tahotra, fanalam-baraka na fianarana. Mazava ho azy fa mbola manana toerana hitomboany izy: amin'ny hoavy dia ho afaka hikarakara fitsipika maro izy, hiasa amin'ny kofehy maromaro, hanara-maso tsy miankina ny fanovana ao amin'ny CRDs ...

Mba hijerena akaiky kokoa ny kaody dia napetrakay ao fitehirizam-bahoaka. Raha mila ohatra momba ny mpandraharaha matotra kokoa ampiharina amin'ny Python ianao dia azonao atao ny mampitodika ny sainao amin'ny mpandraharaha roa amin'ny fametrahana mongodb (ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΈ ny faharoa).

PS Ary raha kamo loatra amin'ny hetsika Kubernetes ianao na zatra mampiasa Bash fotsiny, dia nanomana vahaolana vonona amin'ny endrika ny mpiara-miasa aminay. shell-operator (Isika nanambara tamin'ny Aprily).

PPS

Vakio ihany koa ao amin'ny bilaoginay:

Source: www.habr.com

Add a comment