Kubernetes ішіндегі және сыртындағы жоба конфигурациясы

Жақында жаздым Докердегі жобаның өмір сүру мерзімі және оның сыртындағы кодты түзету туралы жауап, онда ол қызмет Kuber-те жақсы жұмыс істеуі, құпияларды ашуы және тіпті Docker-тен тыс жерде де ыңғайлы жұмыс істеуі үшін жеке конфигурация жүйесін жасай алатыныңызды қысқаша айтты. Ештеңе күрделі емес, бірақ сипатталған «рецепт» біреуге пайдалы болуы мүмкін :) Код Python тілінде, бірақ логика тілге байланысты емес.

Kubernetes ішіндегі және сыртындағы жоба конфигурациясы

Сұрақтың негізі мынада: бір кездері бір жоба болды, ол бастапқыда утилиталары мен сценарийлері бар шағын монолит болды, бірақ уақыт өте келе ол өсіп, қызметтерге бөлінді, олар өз кезегінде микросервистерге бөліне бастады және содан кейін масштабталды. Бастапқыда мұның бәрі VPS-те жасалды, кодты орнату және орналастыру процестері Ansible көмегімен автоматтандырылған және әрбір қызмет қажетті параметрлер мен кілттері бар YAML конфигурациясымен құрастырылған және ұқсас конфигурация файлы үшін пайдаланылған. жергілікті іске қосулар, бұл өте ыңғайлы болды, себебі .k бұл конфигурация жобаның кез келген жерінен қолжетімді жаһандық нысанға жүктеледі.

Дегенмен, микросервистердің санының өсуі, олардың қосылымдары және орталықтандырылған каротажды және бақылауды қажет етеді, әлі жүріп жатқан Куберге көшуді болжады. Жоғарыда аталған мәселелерді шешуге көмектесумен бірге Кубернетес инфрақұрылымды басқаруға өз тәсілдерін ұсынады, соның ішінде құпиялар деп аталады и олармен жұмыс істеу тәсілдері. Механизм стандартты және сенімді, сондықтан оны қолданбау күнә! Бірақ сонымен бірге мен конфигурациямен жұмыс істеудің қазіргі форматын сақтағым келеді: біріншіден, оны жобаның әртүрлі микросервистерінде біркелкі пайдалану, екіншіден, кодты бір қарапайым құрылғы арқылы жергілікті машинада іске қосу мүмкіндігі. конфигурация файлы.

Осыған байланысты конфигурация объектісін құру механизмі классикалық конфигурация файлымен де, Kuber құпияларымен де жұмыс істей алатындай етіп өзгертілді. Неғұрлым қатаң конфигурация құрылымы үшінші Python тілінде келесідей көрсетілді:

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

Яғни, соңғы когфиг - бұл аталған бөлімдері бар сөздік, олардың әрқайсысы қарапайым түрлердің мәндері бар сөздік. Ал бөлімдер конфигурацияны және белгілі бір түрдегі ресурстарға қол жеткізуді сипаттайды. Біздің конфигурацияның бір бөлігінің мысалы:

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"

Сонымен қатар, өріс engine дерекқорларды SQLite жүйесінде орнатуға болады және redis деп орнатыңыз mock, сонымен қатар сақталатын файлдың атын көрсету - бұл параметрлер дұрыс танылады және өңделеді, бұл отладтау, бірлік сынағы және кез келген басқа қажеттіліктер үшін кодты жергілікті түрде іске қосуды жеңілдетеді. Бұл біз үшін өте маңызды, өйткені басқа да көптеген қажеттіліктер бар - біздің кодтың бір бөлігі әртүрлі аналитикалық есептеулерге арналған, ол тек оркестрі бар серверлерде ғана емес, сонымен қатар әртүрлі сценарийлермен және талдаушылардың компьютерлерінде жұмыс істейді. және серверлік мәселелерге алаңдамай күрделі деректерді өңдеу құбырларын жөндеу. Айтпақшы, біздің негізгі құралдарымыз, соның ішінде конфигурациялық орналасу коды арқылы орнатылғанын бөлісу зиян емес. setup.py – бірге бұл біздің кодты платформа мен пайдалану әдісіне тәуелсіз бір экожүйеге біріктіреді.

Kubernetes қосқышының сипаттамасы келесідей:

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

Яғни, әрбір құпия бір бөлімді сипаттайды. Құпиялардың өзі былай жасалады:

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

Бұл бірге YAML файлдарын жол бойында жасауға әкеледі /etc/secrets/db-main/section_name.yaml

Жергілікті іске қосулар үшін жобаның түбірлік каталогында немесе орта айнымалысында көрсетілген жол бойында орналасқан конфигурация қолданылады. Бұл ыңғайлылыққа жауапты кодты спойлерден көруге болады.

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

Мұндағы логика өте қарапайым: біз жоба каталогындағы үлкен конфигурацияларды және орта айнымалысы бойынша жолдарды және Kuber құпияларынан кіші конфигурация бөлімдерін біріктіреміз, содан кейін оларды сәл алдын ала өңдейміз. Оған қоса, кейбір айнымалылар. Құпиялардан файлдарды іздеу кезінде тереңдік шектеуі қолданылатынын ескертемін, себебі K8s құпиялардың өзі сақталатын әрбір құпияда жасырын қалтаны жасайды және жай ғана сілтеме жоғары деңгейде орналасқан.

Сипатталған нәрсе біреуге пайдалы болады деп үміттенемін :) Қауіпсіздікке немесе жақсартуға арналған басқа салаларға қатысты кез келген ескертулер мен ұсыныстар қабылданады. Қауымдастықтың пікірі де қызықты, мүмкін ConfigMaps қолдауын қосу керек (біздің жоба оларды әлі қолданбайды) және кодты GitHub / PyPI сайтында жариялау керек пе? Жеке менің ойымша, жобалар әмбебап болуы үшін мұндай нәрселер тым жеке болып табылады және осы жерде берілген сияқты басқа адамдардың іске асыруларына аздап қарау және түсініктемелерде көремін деп үміттенемін. , жеткілікті 😉

Сауалнамаға тек тіркелген пайдаланушылар қатыса алады. Кіру, өтінемін.

Жоба/кітапхана ретінде жариялауым керек пе?

  • 0,0%Иә, мен /contribution0 қолданар едім

  • 33,3%Иә, бұл керемет естіледі4

  • 41,7%Жоқ, кімге оны өз форматында және қажеттіліктеріне сәйкес жасау керек5

  • 25,0%Мен жауап беруден аулақ боламын3

12 пайдаланушы дауыс берді. 3 пайдаланушы қалыс қалды.

Ақпарат көзі: www.habr.com

пікір қалдыру