Verkstillingar innan og utan Kubernetes

Ég skrifaði nýlega svar um líf verkefnisins í Docker og villuleitarkóða utan þess, þar sem hann minntist stuttlega á að þú getur búið til þitt eigið stillingarkerfi þannig að þjónustan virki vel í Kuber, dregur upp leyndarmál og keyrir þægilega á staðnum, jafnvel utan Docker að öllu leyti. Ekkert flókið, en „uppskriftin“ sem lýst er getur verið gagnleg fyrir einhvern :) Kóðinn er í Python, en rökfræðin er ekki bundin við tungumálið.

Verkstillingar innan og utan Kubernetes

Forsaga spurningarinnar er þessi: Einu sinni var eitt verkefni, fyrst var það lítill einleikur með tólum og skriftum, en með tímanum stækkaði það, skiptist í þjónustur, sem aftur fór að skipta í örþjónustur, og svo stækkað. Í fyrstu var allt þetta gert á berum VPS, ferlarnir við að setja upp og dreifa kóða sem voru sjálfvirkir með Ansible, og hver þjónusta var sett saman með YAML stillingum með nauðsynlegum stillingum og lyklum og svipuð stillingarskrá var notuð fyrir staðbundnar kynningar, sem var mjög þægilegt, vegna þess að .k þessi stilling er hlaðin inn í alþjóðlegan hlut, aðgengilegur hvar sem er í verkefninu.

Hins vegar fjölgar örþjónustum, tengingum þeirra og þörf á miðlægri skráningu og eftirliti, fyrirboði flutning til Kuber, sem er enn í vinnslu. Samhliða aðstoð við að leysa nefnd vandamál býður Kubernetes aðferðir sínar við innviðastjórnun, þ.m.t svokölluð Leyndarmál и leiðir til að vinna með þeim. Vélbúnaðurinn er staðall og áreiðanlegur, svo það er bókstaflega synd að nota það ekki! En á sama tíma vil ég viðhalda núverandi sniði mínu til að vinna með stillingarnar: í fyrsta lagi að nota það einsleitt í mismunandi örþjónustum verkefnisins og í öðru lagi til að geta keyrt kóðann á staðbundinni vél með einni einföldu stillingarskrá.

Í þessu sambandi var vélbúnaðurinn til að smíða stillingarhlut breytt til að geta unnið bæði með klassísku stillingarskránni okkar og með leyndarmálum frá Kuber. Stífari stillingaruppbygging var einnig tilgreind, á tungumáli þriðja Python, sem hér segir:

Dict[str, Dict[str, Union[str, int, flot]]]

Það er að segja, síðasta tannhjólið er orðabók með nafngreindum hlutum, sem hver um sig er orðabók með gildum úr einföldum gerðum. Og hlutar lýsa uppsetningu og aðgangi að tilföngum af ákveðinni gerð. Dæmi um stykki af stillingum okkar:

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"

Á sama tíma, völlurinn engine gagnagrunna er hægt að setja upp á SQLite, og redis stillt á mock, tilgreinir einnig nafn skráarinnar sem á að vista - þessar færibreytur eru rétt viðurkenndar og unnar, sem gerir það auðvelt að keyra kóðann á staðnum fyrir villuleit, einingaprófun og hvers kyns aðrar þarfir. Þetta er sérstaklega mikilvægt fyrir okkur vegna þess að það eru margar aðrar þarfir - hluti af kóðanum okkar er ætlaður fyrir ýmsa greiningarútreikninga, hann keyrir ekki aðeins á netþjónum með hljómsveit, heldur einnig með ýmsum skriftum og á tölvum greiningaraðila sem þurfa að vinna í gegnum og kemba flóknar gagnavinnsluleiðslur án þess að hafa áhyggjur af bakendamálum. Við the vegur, það myndi ekki skaða að deila því að helstu verkfæri okkar, þar á meðal uppsetningarkóðann, eru sett upp í gegnum setup.py – saman sameinar þetta kóðann okkar í eitt vistkerfi, óháð vettvangi og notkunaraðferð.

Lýsingin á Kubernetes belg lítur svona út:

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

Það er, hvert leyndarmál lýsir einum hluta. Leyndarmálin sjálf eru búin til svona:

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

Saman leiðir þetta til þess að YAML skrár eru búnar til á leiðinni /etc/secrets/db-main/section_name.yaml

Og fyrir staðbundnar ræsingar er stillingin notuð, staðsett í rótarskrá verkefnisins eða meðfram slóðinni sem tilgreind er í umhverfisbreytunni. Kóðann sem ber ábyrgð á þessum þægindum má sjá í spoilernum.

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

Rökfræðin hér er frekar einföld: við sameinum stórar stillingar úr verkefnaskránni og slóðir eftir umhverfisbreytu, og litla stillingarhluta úr Kuber-leyndarmálum, og forvinnum þær síðan aðeins. Plús nokkrar breytur. Ég tek það fram að þegar leitað er að skrám úr leyndarmálum er dýptartakmörkun notuð, því K8s býr til falda möppu í hverju leyndarmáli þar sem leyndarmálin sjálf eru geymd og bara hlekkur er staðsettur á hærra stigi.

Ég vona að það sem lýst er komi einhverjum að gagni :) Allar athugasemdir og ráðleggingar varðandi öryggi eða önnur svæði til úrbóta eru samþykkt. Álit samfélagsins er líka áhugavert, kannski er það þess virði að bæta við stuðningi við ConfigMaps (verkefnið okkar notar þau ekki ennþá) og birta kóðann á GitHub / PyPI? Persónulega finnst mér svona hlutir vera of einstaklingsbundnir til að verkefni séu almenn, og smá að kíkja á útfærslur annarra eins og hér kemur fram og umfjöllun um blæbrigði, ábendingar og bestu vinnubrögð sem ég vonast til að sjá í athugasemdum , er nóg 😉

Aðeins skráðir notendur geta tekið þátt í könnuninni. Skráðu þig inn, takk.

Ætti ég að gefa út sem verkefni/safn?

  • 0,0%Já, ég myndi nota /contribution0

  • 33,3%Já, það hljómar vel4

  • 41,7%Nei, hver þarf að gera það sjálfur í sínu eigin formi og eftir þörfum5

  • 25,0%Ég mun ekki svara 3

12 notendur greiddu atkvæði. 3 notendur sátu hjá.

Heimild: www.habr.com

Bæta við athugasemd