Мен жакында жаздым
Суроонун негизи мындай: бир жолу бир долбоор болгон, адегенде бул коммуналдык жана сценарийлери бар кичинекей монолит болчу, бирок убакыттын өтүшү менен ал чоңоюп, кызматтарга бөлүнүп, алар өз кезегинде микросервистерге жана андан кийин масштабдуу. Адегенде мунун баары жылаңач VPSде жасалды, кодду орнотуу жана жайылтуу процесстери Ansible аркылуу автоматташтырылган жана ар бир кызмат керектүү орнотуулары жана ачкычтары бар YAML конфигурациясы менен түзүлгөн жана окшош конфигурация файлы үчүн колдонулган. жергиликтүү ишке киргизүү, бул абдан ыңгайлуу болду, анткени .k бул конфигурация глобалдык объектке жүктөлүп, долбоордун каалаган жеринен жеткиликтүү.
Бирок, микросервистердин санынын өсүшү, алардын байланыштары жана
Ушуга байланыштуу, конфигурация объектин куруу механизми биздин классикалык конфигурация файлыбыз менен да, 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