Kubernetes Operator muPython isina masisitimu uye SDK

Kubernetes Operator muPython isina masisitimu uye SDK

Go parizvino ine monopoly pamitauro yekuronga vanhu vanosarudza kunyora zvirevo zveKubernetes. Pane zvikonzero zvechinangwa zveizvi, zvakadai se:

  1. Kune hurongwa hwakasimba hwekuvandudza vashandisi muGo - Operator SDK.
  2. Mashandisirwo ekuchinja-mutambo senge Docker uye Kubernetes akanyorwa muGo. Kunyora mushandisi wako muGo kunoreva kutaura mutauro mumwechete neiyo ecosystem.
  3. Kuita kwepamusoro kweGo zvikumbiro uye maturusi akareruka ekushanda neconcurrency kunze kwebhokisi.

NB: Nenzira, kunyora chirevo chako pachako muGo, isu zvatotsanangurwa mune imwe yeshanduro dzedu nevanyori vekune dzimwe nyika.

Asi ko kana ukadziviswa kudzidza Enda nekushaiwa nguva kana, nokungotaura, kukurudzira? Chinyorwa chinopa muenzaniso wekuti iwe unogona sei kunyora chirevo chakanaka uchishandisa imwe yemitauro inonyanya kufarirwa iyo inenge yese DevOps mainjiniya anoziva - Python.

Sangana: Copier - kopi opareta!

Semuyenzaniso, funga kugadzira chirevo chakareruka chakagadzirirwa kukopa ConfigMap kungave panoonekwa nzvimbo itsva yezita kana kana chimwe chezvikamu zviviri zvachinja: ConfigMap uye Chakavanzika. Kubva pamaonero anoshanda, mushandisi anogona kubatsira pakugadzirisa kwakawanda kwezvirongwa zvekushandisa (nekugadzirisa iyo ConfigMap) kana kugadzirisa zvakavanzika data - semuenzaniso, makiyi ekushanda neDocker Registry (kana uchiwedzera Chakavanzika kune iyo namespace).

Uye saka, izvo mushandisi akanaka anofanira kuve nazvo:

  1. Kudyidzana nemushandisi kunoitwa uchishandisa Custom Resource Definitions (inozonzi CRD).
  2. Mushandisi anogona kugadzirwa. Kuti tiite izvi, isu tichashandisa mitsara yekuraira mireza uye nharaunda zvinosiyana.
  3. Iko kuvakwa kweDocker mudziyo uye Helm chati yakagadzirirwa kuitira kuti vashandisi vagone nyore (chaizvo nemirairo imwe) kuisa opareta muboka ravo reKubernetes.

CRD

Kuti mushandisi azive kuti ndezvipi zvekushandisa uye kuti anotarisa kupi, tinofanira kugadza mutemo kwaari. Mutemo wega wega uchamiririrwa sechinhu chimwe chete cheCRD. Ndeapi minda inofanirwa kuve neCRD iyi?

  1. Resource type, iyo yatichatsvaga (ConfigMap kana Chakavanzika).
  2. Rondedzero yemazita, umo zviwanikwa zvinofanira kuwanikwa.
  3. Seleta, yatichatsvaga zviwanikwa munzvimbo yezita.

Ngatitsanangurirei 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

Uye isu tichazvigadzira ipapo mutemo wakapfava β€” kutsvaga munzvimbo yezita nezita default ese ConfigMap ine mavara akadai copyrator: "true":

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

Ready! Zvino isu tinoda neimwe nzira kuwana ruzivo nezve mutemo wedu. Rega ndiite chengetedzo ipapo ipapo kuti hatizonyora zvikumbiro kune cluster API Server isu pachedu. Kuti tiite izvi, isu tichashandisa yakagadzirira-yakagadzirwa Python raibhurari 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')}

Nekuda kwekushandisa iyi kodhi, tinowana zvinotevera:

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

Great: takakwanisa kuwana mutemo kune anoshanda. Uye zvakanyanya kukosha, isu takaita inonzi Kubernetes nzira.

Mamiriro ezvinhu akasiyana kana mireza? Tinotora zvese!

Ngatiendei kune main operator configuration. Pane nzira mbiri dzekutanga dzekugadzirisa maapplication:

  1. shandisa mitsetse yemirairo sarudzo;
  2. shandisa mamiriro akasiyana.

Command line sarudzo dzinokutendera kuti uverenge zvigadziriso zviri nyore, nerutsigiro rwemhando yedata uye kusimbiswa. Python's standard library ine module argparser, yatichashandisa. Tsanangudzo uye mienzaniso yekugona kwayo inowanikwa mukati zvinyorwa zvepamutemo.

Kune yedu kesi, izvi ndizvo izvo muenzaniso wekumisikidza kuverenga mutsara wemirairo mireza ingaite se:

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

Kune rimwe divi, uchishandisa nharaunda zvinosiyana muKubernetes, unogona kuendesa zviri nyore ruzivo rwesevhisi nezve pod mukati memudziyo. Semuenzaniso, tinogona kuwana ruzivo nezve nzvimbo yezita umo pod iri kushanda neinotevera kuvaka:

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

Operator logic

Kuti tinzwisise nzira yekuparadzanisa nzira dzekushanda neConfigMap uye Chakavanzika, isu tichashandisa yakakosha mepu. Ipapo tinogona kunzwisisa kuti ndedzipi nzira dzatinoda kutevedzera uye kugadzira chinhu:

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

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

Tevere, iwe unofanirwa kugamuchira zviitiko kubva kune API server. Ngatiishandise sezvinotevera:

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)

Mushure mekugamuchira chiitiko, tinoenda kune chikuru logic yekuchigadzirisa:

# Π’ΠΈΠΏΡ‹ событий, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄Π΅ΠΌ Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ
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)

Iyo huru logic yakagadzirira! Zvino isu tinoda kurongedza zvese izvi mune imwe Python package. Isu tinogadzirira faira setup.py, nyora meta ruzivo nezve purojekiti ipapo:

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: Iyo kubernetes mutengi wePython ine yayo shanduro. Ruzivo rwakawanda nezve kuenderana pakati peshanduro dzevatengi uye Kubernetes shanduro dzinogona kuwanikwa mukati kugarisana matrices.

Zvino purojekiti yedu inoita seizvi:

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

Docker uye Helm

Iyo Dockerfile ichave yakapusa zvakapusa: tora base python-alpine mufananidzo uye isa yedu package. Ngatimbosendekai optimization yayo kusvika nguva dziri nani:

FROM python:3.7.3-alpine3.9

ADD . /app

RUN pip3 install /app

ENTRYPOINT ["copyrator"]

Deployment kune opareta zvakare iri nyore kwazvo:

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

Pakupedzisira, iwe unofanirwa kugadzira basa rakakodzera kune anoshanda nekodzero dzinodiwa:

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 }}

Mugumisiro

Ndiwo maitiro, pasina kutya, kunyomba, kana kudzidza Go, isu takakwanisa kuvaka yedu yedu opareta yeKubernetes muPython. Ehe, ichine nzvimbo yekukura: mune ramangwana ichakwanisa kugadzirisa mitemo yakawanda, kushanda mushinda dzakawanda, yakazvimiririra kutarisa shanduko mumaCRD ayo ...

Kuti tikupe kunyatsotarisisa kodhi, taisa mukati public repository. Kana iwe uchida mienzaniso yeakanyanya kuomarara maopareta anoitwa uchishandisa Python, unogona kutendeudzira kutarisa kwako kune vaviri vanoshanda kuti vatumire mongodb (ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΈ yechipiri).

PS Uye kana iwe uchinyanya usimbe kubata neKubernetes zviitiko kana iwe wakangojaira kushandisa Bash, vatinoshanda navo vakagadzirira mhinduro yakagadzirira mufomu. shell-operator (Isu yakaziviswa muna Kubvumbi).

PPS

Verenga zvakare pablog yedu:

Source: www.habr.com

Voeg