Долбоордун конфигурациясы Kubernetes ичинде жана сыртында

Мен жакында жаздым Докердеги долбоордун жашоосу жана анын сыртындагы мүчүлүштүктөрдү оңдоо коду жөнүндө жооп, анда ал кызмат Куберде жакшы иштеши, сырларды ачышы жана Dockerден тышкары жерде да ыңгайлуу иштеши үчүн өзүңүздүн конфигурация системаңызды түзө аларыңызды кыскача айтты. Эч нерсе татаал эмес, бирок сүрөттөлгөн "рецепт" кимдир бирөө үчүн пайдалуу болушу мүмкүн :) Код Python тилинде, бирок логика тилге байланган эмес.

Долбоордун конфигурациясы Kubernetes ичинде жана сыртында

Суроонун негизи мындай: бир жолу бир долбоор болгон, адегенде бул коммуналдык жана сценарийлери бар кичинекей монолит болчу, бирок убакыттын өтүшү менен ал чоңоюп, кызматтарга бөлүнүп, алар өз кезегинде микросервистерге жана андан кийин масштабдуу. Адегенде мунун баары жылаңач VPSде жасалды, кодду орнотуу жана жайылтуу процесстери Ansible аркылуу автоматташтырылган жана ар бир кызмат керектүү орнотуулары жана ачкычтары бар YAML конфигурациясы менен түзүлгөн жана окшош конфигурация файлы үчүн колдонулган. жергиликтүү ишке киргизүү, бул абдан ыңгайлуу болду, анткени .k бул конфигурация глобалдык объектке жүктөлүп, долбоордун каалаган жеринен жеткиликтүү.

Бирок, микросервистердин санынын өсүшү, алардын байланыштары жана борборлоштурулган каттоо жана мониторинг жүргүзүү зарыл, дагы эле жүрүп жаткан Куберге көчүүнү алдын ала билдирген. Белгиленген көйгөйлөрдү чечүүгө жардам берүү менен бирге, Kubernetes инфраструктураны башкарууга өзүнүн ыкмаларын сунуш кылат, анын ичинде сырлар деп аталган и алар менен иштөөнүн жолдору. Механизм стандарттуу жана ишенимдүү, ошондуктан аны колдонбоо күнөө! Бирок ошол эле учурда мен конфигурация менен иштөө үчүн учурдагы форматымды сактап калгым келет: биринчиден, аны долбоордун ар кандай микросервистеринде бирдей колдонуу, экинчиден, кодду бир жөнөкөй колдонуу менен жергиликтүү машинада иштете алуу конфигурация файлы.

Ушуга байланыштуу, конфигурация объектин куруу механизми биздин классикалык конфигурация файлыбыз менен да, Kuber сырлары менен да иштей ала тургандай кылып өзгөртүлгөн. Үчүнчү Python тилинде дагы катаал конфигурация структурасы төмөнкүчө көрсөтүлгөн:

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

Башкача айтканда, акыркы cogfig - бул ар бири жөнөкөй түрлөрдүн баалуулуктары бар сөздүк болуп саналган бөлүмдөрү бар сөздүк. Ал эми бөлүмдөр конфигурацияны жана белгилүү бир түрдөгү ресурстарга жетүүнү сүрөттөйт. Биздин конфигурациянын бир бөлүгүнүн мисалы:

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 колдонуучу добуш берүүдөн баш тартты.

Source: www.habr.com

Комментарий кошуу