ஃப்ரேம்வொர்க்குகள் மற்றும் SDK இல்லாமல் பைத்தானில் குபெர்னெட்ஸ் ஆபரேட்டர்

ஃப்ரேம்வொர்க்குகள் மற்றும் SDK இல்லாமல் பைத்தானில் குபெர்னெட்ஸ் ஆபரேட்டர்

குபெர்னெட்டஸுக்கு அறிக்கைகளை எழுத மக்கள் தேர்வு செய்யும் நிரலாக்க மொழிகளில் Go தற்போது ஏகபோக உரிமையைக் கொண்டுள்ளது. இதற்கு புறநிலை காரணங்கள் உள்ளன, எடுத்துக்காட்டாக:

  1. Go-வில் ஆபரேட்டர்களை உருவாக்குவதற்கான சக்திவாய்ந்த கட்டமைப்பு உள்ளது - ஆபரேட்டர் SDK.
  2. Docker மற்றும் Kubernetes போன்ற கேம்-மாற்றும் பயன்பாடுகள் Go இல் எழுதப்பட்டுள்ளன. Go இல் உங்கள் ஆபரேட்டரை எழுதுவது என்பது சுற்றுச்சூழல் அமைப்புடன் ஒரே மொழியைப் பேசுவதாகும்.
  3. Go பயன்பாடுகளின் உயர் செயல்திறன் மற்றும் பெட்டிக்கு வெளியே ஒரே நேரத்தில் வேலை செய்வதற்கான எளிய கருவிகள்.

NB: மூலம், Go இல் உங்கள் சொந்த அறிக்கையை எப்படி எழுதுவது, நாங்கள் ஏற்கனவே விவரிக்கப்பட்டுள்ளது வெளிநாட்டு எழுத்தாளர்களின் எங்கள் மொழிபெயர்ப்புகளில் ஒன்றில்.

ஆனால், நேரமின்மை அல்லது எளிமையாகச் சொன்னால், Go கற்றுக்கொள்வதிலிருந்து நீங்கள் தடுக்கப்பட்டால் என்ன செய்வது? ஒவ்வொரு DevOps பொறியாளருக்கும் தெரிந்த மிகவும் பிரபலமான மொழிகளில் ஒன்றைப் பயன்படுத்தி நீங்கள் எப்படி ஒரு நல்ல அறிக்கையை எழுதலாம் என்பதற்கான உதாரணத்தை கட்டுரை வழங்குகிறது - பைதான்.

சந்திப்பு: நகலி - நகல் ஆபரேட்டர்!

எடுத்துக்காட்டாக, ஒரு புதிய பெயர்வெளி தோன்றும் போது அல்லது இரண்டு நிறுவனங்களில் ஒன்று மாறும்போது ConfigMap ஐ நகலெடுக்க வடிவமைக்கப்பட்ட ஒரு எளிய அறிக்கையை உருவாக்குவதைக் கவனியுங்கள்: ConfigMap மற்றும் Secret. நடைமுறைக் கண்ணோட்டத்தில், ஆப்ஸ் உள்ளமைவுகளை மொத்தமாகப் புதுப்பிப்பதற்கு (ConfigMap ஐப் புதுப்பிப்பதன் மூலம்) அல்லது ரகசியத் தரவைப் புதுப்பிப்பதற்கு ஆபரேட்டர் பயனுள்ளதாக இருக்கும் - எடுத்துக்காட்டாக, Docker Registry உடன் பணிபுரியும் விசைகள் (பெயர்வெளியில் ரகசியத்தைச் சேர்க்கும் போது).

எனவே ஒரு நல்ல ஆபரேட்டருக்கு என்ன இருக்க வேண்டும்:

  1. ஆபரேட்டருடனான தொடர்பு பயன்படுத்தி மேற்கொள்ளப்படுகிறது விருப்ப வள வரையறைகள் (இனிமேல் CRD என குறிப்பிடப்படுகிறது).
  2. ஆபரேட்டரை கட்டமைக்க முடியும். இதைச் செய்ய, கட்டளை வரி கொடிகள் மற்றும் சூழல் மாறிகளைப் பயன்படுத்துவோம்.
  3. டோக்கர் கொள்கலன் மற்றும் ஹெல்ம் விளக்கப்படத்தின் உருவாக்கம் வடிவமைக்கப்பட்டுள்ளது, இதனால் பயனர்கள் எளிதாக (அதாவது ஒரு கட்டளையுடன்) ஆபரேட்டரை தங்கள் குபெர்னெட்ஸ் கிளஸ்டரில் நிறுவ முடியும்.

சி.ஆர்.டி.

ஆபரேட்டருக்கு என்ன ஆதாரங்களைத் தேட வேண்டும், எங்கு பார்க்க வேண்டும் என்பதை அறிய, அவருக்கு ஒரு விதியை அமைக்க வேண்டும். ஒவ்வொரு விதியும் ஒரு சிஆர்டி பொருளாகக் குறிப்பிடப்படும். இந்த CRD என்ன துறைகளை கொண்டிருக்க வேண்டும்?

  1. வள வகை, நாம் தேடும் (ConfigMap அல்லது Secret).
  2. பெயர்வெளிகளின் பட்டியல், இதில் வளங்கள் அமைந்திருக்க வேண்டும்.
  3. தேர்வி, இதன் மூலம் நாம் பெயர்வெளியில் ஆதாரங்களைத் தேடுவோம்.

சிஆர்டியை விவரிப்போம்:

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

நாங்கள் அதை உடனடியாக உருவாக்குவோம் எளிய விதி — பெயருடன் பெயர்வெளியில் தேட default போன்ற லேபிள்களுடன் அனைத்து கான்ஃபிக்மேப் copyrator: "true":

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

தயார்! இப்போது எப்படியாவது நமது ஆட்சியைப் பற்றிய தகவல்களைப் பெற வேண்டும். கிளஸ்டர் ஏபிஐ சர்வருக்கு நாமே கோரிக்கைகளை எழுத மாட்டோம் என்பதை இப்போதே முன்பதிவு செய்கிறேன். இதைச் செய்ய, நாங்கள் ஒரு ஆயத்த பைதான் நூலகத்தைப் பயன்படுத்துவோம் kubernetes-வாடிக்கையாளர்:

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

இந்த குறியீட்டை இயக்குவதன் விளைவாக, பின்வருவனவற்றைப் பெறுகிறோம்:

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

சிறந்தது: ஆபரேட்டருக்கான விதியைப் பெற முடிந்தது. மற்றும் மிக முக்கியமாக, குபெர்னெட்ஸ் வழி என்று அழைக்கப்படுவதை நாங்கள் செய்தோம்.

சுற்றுச்சூழல் மாறிகள் அல்லது கொடிகள்? நாங்கள் எல்லாவற்றையும் எடுத்துக்கொள்கிறோம்!

முக்கிய ஆபரேட்டர் உள்ளமைவுக்கு செல்லலாம். பயன்பாடுகளை உள்ளமைக்க இரண்டு அடிப்படை அணுகுமுறைகள் உள்ளன:

  1. கட்டளை வரி விருப்பங்களைப் பயன்படுத்தவும்;
  2. சூழல் மாறிகளைப் பயன்படுத்தவும்.

கட்டளை வரி விருப்பங்கள், தரவு வகை ஆதரவு மற்றும் சரிபார்ப்புடன் அமைப்புகளை மிகவும் நெகிழ்வாக படிக்க அனுமதிக்கிறது. பைத்தானின் நிலையான நூலகத்தில் ஒரு தொகுதி உள்ளது argparser, நாங்கள் பயன்படுத்துவோம். அதன் திறன்களின் விவரங்கள் மற்றும் எடுத்துக்காட்டுகள் கிடைக்கின்றன அதிகாரப்பூர்வ ஆவணங்கள்.

எங்கள் விஷயத்தில், வாசிப்பு கட்டளை வரி கொடிகளை அமைப்பதற்கான எடுத்துக்காட்டு இதுவாக இருக்கும்:

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

மறுபுறம், Kubernetes இல் சூழல் மாறிகளைப் பயன்படுத்தி, கொள்கலனுக்குள் உள்ள பாட் பற்றிய சேவைத் தகவலை நீங்கள் எளிதாக மாற்றலாம். எடுத்துக்காட்டாக, பின்வரும் கட்டுமானத்துடன் பாட் இயங்கும் பெயர்வெளி பற்றிய தகவலைப் பெறலாம்:

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

ஆபரேட்டர் தர்க்கம்

ConfigMap மற்றும் Secret உடன் பணிபுரியும் முறைகளை எவ்வாறு பிரிப்பது என்பதைப் புரிந்து கொள்ள, நாங்கள் சிறப்பு வரைபடங்களைப் பயன்படுத்துவோம். பொருளைக் கண்காணிக்கவும் உருவாக்கவும் என்ன முறைகள் தேவை என்பதை நாம் புரிந்து கொள்ளலாம்:

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

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

அடுத்து, நீங்கள் API சேவையகத்திலிருந்து நிகழ்வுகளைப் பெற வேண்டும். அதை பின்வருமாறு செயல்படுத்துவோம்:

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)

நிகழ்வைப் பெற்ற பிறகு, அதைச் செயலாக்குவதற்கான முக்கிய தர்க்கத்திற்குச் செல்கிறோம்:

# Типы событий, на которые будем реагировать
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)

முக்கிய தர்க்கம் தயாராக உள்ளது! இப்போது இதையெல்லாம் ஒரு பைதான் தொகுப்பாக தொகுக்க வேண்டும். நாங்கள் கோப்பை தயார் செய்கிறோம் setup.py, திட்டம் பற்றிய மெட்டா தகவலை அங்கு எழுதவும்:

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: Python க்கான kubernetes கிளையன்ட் அதன் சொந்த பதிப்பைக் கொண்டுள்ளது. கிளையன்ட் பதிப்புகள் மற்றும் குபெர்னெட்டஸ் பதிப்புகளுக்கு இடையே உள்ள இணக்கத்தன்மை பற்றிய கூடுதல் தகவலைக் காணலாம் பொருந்தக்கூடிய மெட்ரிக்குகள்.

இப்போது எங்கள் திட்டம் இதுபோல் தெரிகிறது:

copyrator
├── copyrator
│   ├── cli.py # Логика работы с командной строкой
│   ├── constant.py # Константы, которые мы приводили выше
│   ├── load_crd.py # Логика загрузки CRD
│   └── operator.py # Основная логика работы оператора
└── setup.py # Оформление пакета

டோக்கர் மற்றும் ஹெல்ம்

Dockerfile நம்பமுடியாத அளவிற்கு எளிமையாக இருக்கும்: அடிப்படை பைதான்-ஆல்பைன் படத்தை எடுத்து எங்கள் தொகுப்பை நிறுவவும். சிறந்த நேரம் வரை அதன் தேர்வுமுறையை ஒத்திவைப்போம்:

FROM python:3.7.3-alpine3.9

ADD . /app

RUN pip3 install /app

ENTRYPOINT ["copyrator"]

ஆபரேட்டருக்கான வரிசைப்படுத்தலும் மிகவும் எளிது:

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

இறுதியாக, தேவையான உரிமைகளுடன் ஆபரேட்டருக்கு பொருத்தமான பாத்திரத்தை நீங்கள் உருவாக்க வேண்டும்:

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

இதன் விளைவாக

அதனால்தான், பயமோ, பழியோ, அல்லது கோ கற்றோ இல்லாமல், பைத்தானில் குபெர்னெட்டஸுக்கு எங்கள் சொந்த ஆபரேட்டரை உருவாக்க முடிந்தது. நிச்சயமாக, இது இன்னும் வளர இடமுள்ளது: எதிர்காலத்தில் இது பல விதிகளை செயல்படுத்தவும், பல நூல்களில் வேலை செய்யவும், அதன் CRD களில் ஏற்படும் மாற்றங்களை சுயாதீனமாக கண்காணிக்கவும் முடியும்.

குறியீட்டை உன்னிப்பாகப் பார்க்க, நாங்கள் அதைச் சேர்த்துள்ளோம் பொது களஞ்சியம். Python ஐப் பயன்படுத்தி செயல்படுத்தப்பட்ட மிகவும் தீவிரமான ஆபரேட்டர்களின் எடுத்துக்காட்டுகளை நீங்கள் விரும்பினால், mongodb ஐப் பயன்படுத்த இரண்டு ஆபரேட்டர்கள் மீது உங்கள் கவனத்தைத் திருப்பலாம் (первый и இரண்டாவது).

PS மேலும் நீங்கள் குபெர்னெட்டஸ் நிகழ்வுகளைச் சமாளிக்க மிகவும் சோம்பேறியாக இருந்தால் அல்லது நீங்கள் பாஷைப் பயன்படுத்துவதற்கு மிகவும் பழக்கமாக இருந்தால், எங்கள் சகாக்கள் படிவத்தில் ஒரு ஆயத்த தீர்வைத் தயாரித்துள்ளனர். ஷெல்-ஆபரேட்டர் (நாங்கள் அறிவிக்கப்பட்டது அது ஏப்ரல் மாதம்).

பிபிஎஸ்

எங்கள் வலைப்பதிவிலும் படிக்கவும்:

ஆதாரம்: www.habr.com

கருத்தைச் சேர்