Конфигуратсияи лоиҳа дар дохил ва берун аз Kubernetes

Ман ба наздикӣ навиштам ҷавоб дар бораи ҳаёти лоиҳа дар Docker ва коди ислоҳи берун аз он, ки дар он ҷо ӯ ба таври мухтасар қайд кард, ки шумо метавонед системаи конфигуратсияи худро созед, то хидмат дар Кубер хуб кор кунад, асрорро кашад ва ба таври қулай кор кунад, ҳатто берун аз Docker. Ҳеҷ чиз мураккаб нест, аммо "рецепт" -и тавсифшуда метавонад барои касе муфид бошад :) Рамз дар Python аст, аммо мантиқ ба забон вобаста нест.

Конфигуратсияи лоиҳа дар дохил ва берун аз Kubernetes

Заминаи савол ин аст: як вақтҳо як лоиҳа вуҷуд дошт, дар аввал он як монолити хурд бо хидматрасонӣ ва скриптҳо буд, аммо бо мурури замон он калон шуд, ба хидматҳо тақсим шуд, ки дар навбати худ ба микросервисҳо тақсим карда шуд. баъд васеъ карда шуд. Дар аввал, ҳамаи ин дар VPS луч анҷом дода шуд, ки равандҳои насб ва ҷойгиркунии код дар он бо истифода аз Ansible автоматӣ карда шуданд ва ҳар як хидмат бо конфигуратсияи YAML бо танзимот ва калидҳои зарурӣ тартиб дода шуд ва як файли конфигуратсияи шабеҳ барои ифтитоҳи маҳаллӣ, ки хеле қулай буд, зеро .k ин конфигуратсия ба объекти глобалӣ бор карда шудааст, ки аз ҳар ҷои лоиҳа дастрас аст.

Бо вуҷуди ин, афзоиши шумораи микросервисҳо, пайвастҳои онҳо ва зарурати ба қайдгирии марказонидашуда ва мониторинг, пешгӯии ҳаракат ба Кубер, ки ҳоло ҳам идома дорад. Якҷоя бо кӯмак дар ҳалли мушкилоти зикршуда, Кубернетес усулҳои худро ба идоракунии инфрасохтор пешниҳод мекунад, аз ҷумла ба ном Сирри и роххои кор бо онхо. Механизм стандартӣ ва боэътимод аст, бинобар ин истифода накардани он айнан гуноҳ аст! Аммо дар айни замон, ман мехоҳам формати кунунии худро барои кор бо конфигуратсия нигоҳ дорам: якум, онро дар микросервисҳои гуногуни лоиҳа яксон истифода барам ва дуюм, тавонистам кодро дар мошини маҳаллӣ бо истифода аз як содда иҷро кунам. файли конфигуратсия.

Дар робита ба ин, механизми сохтани объекти конфигуратсия тағир дода шуд, то тавонанд ҳам бо файли конфигуратсияи классикии мо ва ҳам бо сирри Кубер кор кунад. Сохтори конфигуратсияи сахттар низ бо забони 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 - якҷоя ин рамзи моро ба як экосистемаи ягона муттаҳид мекунад, новобаста аз платформа ва усули истифода.

Тавсифи pod 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()

Мантиқ дар ин ҷо хеле содда аст: мо конфигуратсияҳои калонро аз феҳристи лоиҳа ва роҳҳоро аз рӯи тағирёбандаи муҳити зист ва қисмҳои хурди конфигуратсияро аз сирри Кубер муттаҳид мекунем ва сипас онҳоро каме пештар коркард мекунем. Илова бар ин, баъзе тағирёбандаҳо. Ман қайд мекунам, ки ҳангоми ҷустуҷӯи файлҳо аз асрор, маҳдудияти умқ истифода мешавад, зеро K8s дар ҳар як махфӣ папкаи пинҳонӣ эҷод мекунад, ки дар он сирҳо худашон нигоҳ дошта мешаванд ва танҳо як пайванд дар сатҳи баландтар ҷойгир аст.

Ман умедворам, ки он чизе, ки тавсиф шудааст, барои касе муфид хоҳад буд :) Ҳама шарҳҳо ва тавсияҳо дар бораи амният ё дигар соҳаҳои такмилдиҳӣ қабул карда мешаванд. Андешаи ҷомеа низ ҷолиб аст, шояд илова кардани дастгирӣ ба ConfigMaps (лоиҳаи мо ҳоло онҳоро истифода намебарад) ва интишори код дар GitHub / PyPI лозим аст? Шахсан, ман фикр мекунам, ки чунин чизҳо хеле фардӣ ҳастанд, ки лоиҳаҳо универсалӣ бошанд ва каме дидан ба татбиқи дигарон, ба монанди амали дар ин ҷо овардашуда ва муҳокимаи нозукиҳо, маслиҳатҳо ва таҷрибаҳои беҳтарин, ки ман умедворам, ки дар шарҳҳо бубинам. , бас аст 😉

Танҳо корбарони сабтиномшуда метавонанд дар пурсиш иштирок кунанд. даромад, Лутфан.

Оё ман бояд ҳамчун лоиҳа/китобхона нашр кунам?

  • 0,0%Бале, ман /contribution0 -ро истифода мебарам

  • 33,3%Бале, ин олиҷаноб садо медиҳад4

  • 41,7%Не, ба кӣ лозим аст, ки онро худаш дар формати худ ва мувофиқи ниёзҳои худ анҷом диҳад5

  • 25,0%Ман аз ҷавоб додан худдорӣ мекунам3

12 корбар овоз доданд. 3 корбар худдорӣ карданд.

Манбаъ: will.com

Илова Эзоҳ