Projekti konfigureerimine Kuberneteses ja vÀljaspool seda

Hiljuti kirjutasin vastuse projekti elust Dockeri ja koodi silumise kohta selle vĂ€liselt, kus mainisin korra, et on vĂ”imalik luua oma konfiguratsioonisĂŒsteem, et teenus töötaks hĂ€sti ka Kubernetesis, tĂ”mbaks saladusi ja kĂ€ivitataks mugavalt ka lokaalselt, sealhulgas tĂ€iesti vĂ€ljaspool Dockeri. Midagi keerulist ei ole, aga kirjeldatud "retsept" vĂ”ib kellelegi abiks olla 🙂 Kood on Pythonis, kuid loogika ei ole keelele omane.

Projekti konfigureerimine Kuberneteses ja vÀljaspool seda

KĂŒsimuse taust on jĂ€rgmine: elas-oli ĂŒks projekt, alguses oli see vĂ€ike monoliit utiliitide ja skriptidega, kuid aja jooksul kasvas, jagunes teenusteks, mis omakorda hakkasid jagunema mikroteenusteks ja seejĂ€rel veel ka skaleeruma. Alguses tehti see kĂ”ik tĂŒhjades VPS-des, nende seadistamise ja koodi juurutamise protsessid olid automatiseeritud Ansible'i abil ning igale teenusele koostati YAML-konfiguratsioon vajalike seadistuste ja vĂ”tmetega, ja sarnast konfigureerimisfaili kasutati lokaalseteks kĂ€ivitamisteks, mis oli vĂ€ga mugav, kuna see konfigureerimisfail laaditi globaalsetesse objektidesse, mis on saadaval igas projekti kohas.

Kuid mikroteenuste arvu, nende omavaheliste seoste ja samuti keskse logimise ja monitooringu vajadus, eeldasid kolimist Kubernetesse, mis on endiselt protsessis. Kui abistatakse nende ĂŒlesannete lahendamisel, pakub Kubernetes ka oma lĂ€henemisviise infrastruktuuri haldamiseks, sealhulgas nn saladused ja nende kĂ€itlemise meetodid. Mehhanism on standardselt usaldusvÀÀrne, seega on tĂ”eliselt patt seda mitte kasutada! Kuid samas tahaks sĂ€ilitada oma praeguse töövormi konfiguratsiooni osas: esiteks, ĂŒhtlaselt kasutada seda erinevates projekti mikroteenustes, ja teiseks, saada kĂ€ivitada koodi kohaliku masina peal, kasutades ĂŒhte lihtsat konfigureerimisfaili.

SeetÔttu oli objekti konfiguratsiooni mehhanismi kohandatud nii, et see suudaks töötada nii meie klassikalise konfigureerimisfailiga kui ka Kubernetist saadud saladustega. Samuti kehtestati rangem konfiguratsiooni struktuur, rÀÀkides kolmandast Pythonist, selline:

Dict[str, Dict[str, Union[str, int, float]]]

See tĂ€hendab, et lĂ”plik konfiguratsioon on sĂ”nastik nimetatud sektsioonidega, millest igaĂŒks on sĂ”nastik lihtsate tĂŒĂŒpide vÀÀrtustega. Ja sektsioonid kirjeldavad konfiguratsiooni ja juurdepÀÀsu teatud tĂŒĂŒpi ressurssidele. NĂ€ide meie konfiguratsiooni osast:

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: info@test.com
  pw: "SuperHardPassword"

Sel juhul vĂ€li engine andmebaasi saab seadistada SQLite'le, kuid redis konfigureerida mock, mÀÀrates ka salvestamiseks faili nime – need parameetrid tuvastatakse ja töödeldakse Ă”igesti, mis vĂ”imaldab koodi lihtsalt kohapeal kĂ€ivitada, et debugida, teha ĂŒksusteste ja muid vajadusi. See on meile eriti oluline, kuna neid muid vajadusi on palju – osa meie koodist on mĂ”eldud mitmesuguste analĂŒĂŒtiliste arvutuste tegemiseks, seda kĂ€ivitatakse mitte ainult orkestreerimisega serverites, vaid ka erinevate skriptide ja analĂŒĂŒtikute arvutites, kes peavad tegelema ja debugima keerulisi andmete töötlemise torujuhtmeid, mitte muretsema backend-kĂŒsimustele. Üks huvitav asi, mida jagada, on see, et meie peamised tööriistad, sealhulgas konfi-kodeerimise kood, paigaldatakse lĂ€bi setup.py – need ĂŒhtlustavad meie koodi ĂŒheks ökosĂŒsteemiks, mis ei sĂ”ltu platvormist ja kasutusviisist.

Kuberneteses on poda kirjeldus jÀrgmine:

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

See tĂ€hendab, et iga saladuse sees on kirjas ĂŒks sektsioon. Saladusi luuakse nii:

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

See kÔik viib XML-failide loomisele teel /etc/secrets/db-main/section_name.yaml

Ja kohalike kÀivituste jaoks kasutatakse konfi, mis asub projekti juurkataloogis vÔi teel, mis on mÀÀratud keskkonnamuutuja kaudu. Kood, mis sellele mugavusele vastab, on nÀhtav spoileris.

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

Loogika on siin ĂŒsna lihtne: koondame suurte konfiguratsioonifailide sealt, kus on projekti direktor, ja teelt keskkonnamuutuja kaudu, ning vĂ€ikeste sektsioonide konfiguratsioonid Kuberneteisest, seejĂ€rel töötleme neid natuke ette. Lisaks mĂ”ned muutujad. Tahan mĂ€rkida, et salajaste failide otsimisel kasutatakse sĂŒgavuse piirangut, kuna K8s loob igas salas veel ĂŒhe peidetud kausta, kus saladused ise asuvad, ja ĂŒhe taseme vĂ”rra ĂŒlespoole asub lihtsalt link.

Loodan, et antud teave on kellelegi kasulik 🙂 Ootame igasuguseid kommentaare ja soovitusi turvalisuse vĂ”i muude parenduste osas. Samuti huvitab, mida arvab kogukond, kas vĂ”iks lisada ConfigMapide toe (meie projektis need hetkel ei ole kasutuses) ja kas koodi tuleks vormistada GitHubis / PyPI-s? Isiklikult arvan, et sellised asjad on projektide jaoks liiga individuaalsed, et olla universaalsed, ja piisab, kui heita pilk teiste elluviimisele, nagu siin toodud, ning arutada nĂŒansse, soovitusi ja parimaid praktikaid, mida loodan nĂ€ha kommentaarides 😉

Ainult registreeritud kasutajad saavad kĂŒsitluses osaleda. Logige sisse, palun.

Kas tasub avaldada projektina / teegina?

  • 0,0%Jah, ma kasutaksin / panustaksin

  • 33,3%Jah, see kĂ”lab hĂ€sti

  • 41,7%Ei, kellel on vajadus, teeb ise oma formaadis ja endale sobivalt

  • 25,0%Pean vastamata jÀÀma

HÀÀletas 12 kasutajat. 3 kasutajat hoidusid.

Allikas: habr.com

Osta usaldusvÀÀrne veebimajutus DDoS-kaitsega veebisaitidele, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebimajutus DDoS-kaitsega veebisaitidele, VPS VDS serverid - ProHoster