Rèiteachadh pròiseict taobh a-staigh agus taobh a-muigh Kubernetes

Sgrìobh mi o chionn ghoirid freagairt mu bheatha pròiseict ann an Docker agus còd deasbaid taobh a-muigh dheth, far an tug e iomradh goirid gun urrainn dhut an siostam rèiteachaidh agad fhèin a dhèanamh gus am bi an t-seirbheis ag obair gu math ann an Kuber, a ’tarraing suas dìomhaireachdan, agus a’ ruith gu h-ionadail gu h-iomchaidh, eadhon taobh a-muigh Docker gu tur. Chan eil dad iom-fhillte, ach is dòcha gum bi an “reasabaidh” a tha air a mhìneachadh feumail do chuideigin :) Tha an còd ann am Python, ach chan eil an loidsig ceangailte ris a’ chànan.

Rèiteachadh pròiseict taobh a-staigh agus taobh a-muigh Kubernetes

Is e seo cùl na ceiste: aon uair bha aon phròiseact ann, an toiseach b’ e monolith beag a bh ’ann le goireasan agus sgriobtaichean, ach thar ùine dh’ fhàs e, air a roinn ann an seirbheisean, a thòisich an uair sin air a roinn ann am meanbh-sheirbheisean, agus an uairsin air àrdachadh. An toiseach, chaidh seo uile a dhèanamh air VPS lom, chaidh na pròiseasan airson còd a stèidheachadh agus a chleachdadh air an robh iad fèin-ghluasadach a’ cleachdadh Ansible, agus chaidh gach seirbheis a chuir ri chèile le config YAML leis na roghainnean agus na h-iuchraichean riatanach, agus chaidh faidhle config coltach ris a chleachdadh airson cur air bhog ionadail, a bha gu math goireasach, oir .k tha an rèiteachadh seo air a luchdachadh a-steach do nì cruinneil, ruigsinneach bho àite sam bith sa phròiseact.

Ach, tha am fàs anns an àireamh de microservices, na ceanglaichean aca, agus feum air logadh agus sgrùdadh meadhanaichte, air thoiseach air gluasad gu Kuber, a tha fhathast a’ dol air adhart. Còmhla ri cuideachadh ann a bhith a 'fuasgladh nan duilgheadasan a chaidh ainmeachadh, tha Kubernetes a' tabhann a dhòighean-obrach a thaobh riaghladh bun-structair, a 'gabhail a-steach ris an canar Secrets и dòighean a bhith ag obair còmhla riutha. Tha an uidheamachd àbhaisteach agus earbsach, agus mar sin gu litearra tha e na pheacadh gun a bhith ga chleachdadh! Ach aig an aon àm, bu mhath leam an cruth gnàthach agam a chumail airson a bhith ag obair leis an config: an toiseach, airson a chleachdadh ann an èideadh ann an diofar microservices den phròiseact, agus san dàrna àite, a bhith comasach air an còd a ruith air an inneal ionadail a ’cleachdadh aon shìmplidh faidhle config.

A thaobh seo, chaidh an uidheamachd airson rud rèiteachaidh a thogail atharrachadh gus a bhith comasach air obrachadh an dà chuid leis an fhaidhle config clasaigeach againn agus le dìomhaireachdan bho Kuber. Chaidh structar rèiteachaidh nas cruaidhe a shònrachadh cuideachd, ann an cànan an treas Python, mar a leanas:

Dict[str, Dict[str, Aonadh[str, int, seòladh]]]

Is e sin, is e faclair le earrannan ainmichte a th’ anns a’ chogfig mu dheireadh, agus tha gach fear dhiubh na fhaclair le luachan bho sheòrsan sìmplidh. Agus tha earrannan a’ toirt cunntas air rèiteachadh agus ruigsinneachd air goireasan de sheòrsa sònraichte. Eisimpleir de phìos den rèiteachadh againn:

adminka:
  django_secret: "ExtraLongAndHardCode"

db_main:
  engine: mysql
  host: 256.128.64.32
  user: cool_user
  password: "SuperHardPassword"

redis:
  host: 256.128.64.32
  pw: "SuperHardPassword"
  port: 26379

smtp:
  server: smtp.gmail.com
  port: 465
  email: [email protected]
  pw: "SuperHardPassword"

Aig an aon àm, an raon engine faodar stòran-dàta a chuir a-steach air SQLite, agus redis suidhich gu mock, a 'sònrachadh cuideachd ainm an fhaidhle a shàbhaladh - tha na crìochan sin air an aithneachadh agus air an giullachd gu ceart, a tha ga dhèanamh furasta an còd a ruith gu h-ionadail airson debugging, deuchainn aonad agus feumalachdan sam bith eile. Tha seo gu sònraichte cudromach dhuinn leis gu bheil mòran fheumalachdan eile ann - tha pàirt den chòd againn airson grunn àireamhachadh anailis, bidh e a’ ruith chan ann a-mhàin air frithealaichean le orchestration, ach cuideachd le diofar sgriobtaichean, agus air coimpiutairean luchd-anailis a dh’ fheumas a bhith ag obair troimhe. agus debug pìoban giollachd dàta iom-fhillte gun a bhith draghail mu chùisean backend. Co-dhiù, cha bhiodh e air a ghoirteachadh a bhith a’ roinneadh gu bheil na prìomh innealan againn, a’ toirt a-steach còd cruth config, air an stàladh tro setup.py - còmhla tha seo ag aonachadh ar còd ann an aon eag-shiostam, neo-eisimeileach bho àrd-ùrlar agus dòigh cleachdaidh.

Tha an tuairisgeul air pod Kubernetes a’ coimhead mar seo:

containers:
  - name : enter-api
    image: enter-api:latest
    ports:
      - containerPort: 80
    volumeMounts:
      - name: db-main-secret-volume
        mountPath: /etc/secrets/db-main

volumes:
  - name: db-main-secret-volume
    secret:
      secretName: db-main-secret

Is e sin, tha gach dìomhair a 'toirt cunntas air aon earrann. Tha na dìomhaireachdan fhèin air an cruthachadh mar seo:

apiVersion: v1
kind: Secret
metadata:
  name: db-main-secret
type: Opaque
stringData:
  db_main.yaml: |
    engine: sqlite
    filename: main.sqlite3

Còmhla tha seo a’ leantainn gu cruthachadh faidhlichean YAML air an t-slighe /etc/secrets/db-main/section_name.yaml

Agus airson cuirmean ionadail, tha an config air a chleachdadh, suidhichte ann an eòlaire freumh a’ phròiseict no air an t-slighe a tha air a shònrachadh ann an caochladair na h-àrainneachd. Chithear an còd le uallach airson na goireasan sin anns an spoiler.

config.py

__author__ = 'AivanF'
__copyright__ = 'Copyright 2020, AivanF'

import os
import yaml

__all__ = ['config']
PROJECT_DIR = os.path.abspath(__file__ + 3 * '/..')
SECRETS_DIR = '/etc/secrets'
KEY_LOG = '_config_log'
KEY_DBG = 'debug'

def is_yes(value):
    if isinstance(value, str):
        value = value.lower()
        if value in ('1', 'on', 'yes', 'true'):
            return True
    else:
        if value in (1, True):
            return True
    return False

def update_config_part(config, key, data):
    if key not in config:
        config[key] = data
    else:
        config[key].update(data)

def parse_big_config(config, filename):
    '''
    Parse YAML config with multiple section
    '''
    if not os.path.isfile(filename):
        return False
    with open(filename) as f:
        config_new = yaml.safe_load(f.read())
        for key, data in config_new.items():
            update_config_part(config, key, data)
        config[KEY_LOG].append(filename)
        return True

def parse_tiny_config(config, key, filename):
    '''
    Parse YAML config with a single section
    '''
    with open(filename) as f:
        config_tiny = yaml.safe_load(f.read())
        update_config_part(config, key, config_tiny)
        config[KEY_LOG].append(filename)

def combine_config():
    config = {
        # To debug config load code
        KEY_LOG: [],
        # To debug other code
        KEY_DBG: is_yes(os.environ.get('DEBUG')),
    }
    # For simple local runs
    CONFIG_SIMPLE = os.path.join(PROJECT_DIR, 'config.yaml')
    parse_big_config(config, CONFIG_SIMPLE)
    # For container's tests
    CONFIG_ENVVAR = os.environ.get('CONFIG')
    if CONFIG_ENVVAR is not None:
        if not parse_big_config(config, CONFIG_ENVVAR):
            raise ValueError(
                f'No config file from EnvVar:n'
                f'{CONFIG_ENVVAR}'
            )
    # For K8s secrets
    for path, dirs, files in os.walk(SECRETS_DIR):
        depth = path[len(SECRETS_DIR):].count(os.sep)
        if depth > 1:
            continue
        for file in files:
            if file.endswith('.yaml'):
                filename = os.path.join(path, file)
                key = file.rsplit('.', 1)[0]
                parse_tiny_config(config, key, filename)
    return config

def build_config():
    config = combine_config()
    # Preprocess
    for key, data in config.items():
        if key.startswith('db_'):
            if data['engine'] == 'sqlite':
                data['filename'] = os.path.join(PROJECT_DIR, data['filename'])
    # To verify correctness
    if config[KEY_DBG]:
        print(f'** Loaded config:n{yaml.dump(config)}')
    else:
        print(f'** Loaded config from: {config[KEY_LOG]}')
    return config

config = build_config()

Tha an loidsig an seo gu math sìmplidh: bidh sinn a ’cothlamadh configs mòra bho eòlaire a’ phròiseict agus slighean a rèir caochladair àrainneachd, agus earrannan beaga config bho dhìomhaireachd Kuber, agus an uairsin gan ullachadh ro-làimh. A bharrachd air cuid de chaochladairean. Tha mi a 'toirt fa-near, nuair a thathar a' lorg faidhlichean bho dhìomhaireachd, gu bheilear a 'cleachdadh cuingealachadh doimhneachd, oir tha K8s a' cruthachadh pasgan falaichte anns gach dìomhair far a bheil na dìomhaireachdan fhèin air an stòradh, agus dìreach ceangal air a shuidheachadh aig ìre nas àirde.

Tha mi an dòchas gum bi na tha air a mhìneachadh feumail do chuideigin :) Gabhar ri beachdan agus molaidhean sam bith a thaobh tèarainteachd no raointean eile airson leasachadh. Tha beachd na coimhearsnachd inntinneach cuideachd, is dòcha gum b’ fhiach taic a chuir ri ConfigMaps (chan eil am pròiseact againn gan cleachdadh fhathast) agus an còd fhoillseachadh air GitHub / PyPI? Gu pearsanta, tha mi a’ smaoineachadh gu bheil rudan mar sin ro fa leth airson pròiseactan a bhith uile-choitcheann, agus beagan sùil a thoirt air buileachadh dhaoine eile, mar am fear a tha air a thoirt seachad an seo, agus deasbad air nuances, molaidhean agus cleachdaidhean as fheàrr, a tha mi an dòchas fhaicinn anns na beachdan , tha gu leòr 😉

Chan fhaod ach luchd-cleachdaidh clàraichte pàirt a ghabhail san sgrùdadh. Soidhnig a-steach, mas e do thoil e.

Am bu chòir dhomh foillseachadh mar phròiseact/leabharlann?

  • 0,0%Bhiodh, bhithinn a’ cleachdadh /tabhartas0

  • 33,3%Tha, tha sin fìor mhath4

  • 41,7%Chan e, cò a dh'fheumas a dhèanamh iad fhèin nan cruth fhèin agus a rèir am feumalachdan5

  • 25,0%Stadaidh mi o fhreagairt 3

Bhòt 12 neach-cleachdaidh. Cha do stad 3 neach-cleachdaidh.

Source: www.habr.com

Cuir beachd ann