Duela gutxi idatzi dut
Galderaren atzeko planoa hau da: garai batean proiektu bat zegoen, hasieran utilitateak eta script-ak zituen monolito txiki bat zen, baina denborarekin haziz joan zen, zerbitzuetan banatuz, eta, aldi berean, mikrozerbitzuetan banatzen hasi ziren, eta gero eskalatu. Hasieran, hori guztia VPS hutsean egiten zen, Ansible erabiliz kodea konfiguratzeko eta zabaltzeko prozesuak automatizatu ziren, eta zerbitzu bakoitza YAML konfigurazio batekin konpilatu zen beharrezko ezarpen eta gakoekin, eta antzeko konfigurazio fitxategi bat erabili zen. tokiko abiarazteak, oso erosoa izan zen, zeren .k konfigurazio hau objektu global batean kargatzen da, proiektuko edozein lekutatik eskuragarria.
Hala ere, mikrozerbitzuen kopuruaren hazkundea, haien konexioak eta
Zentzu honetan, konfigurazio-objektu bat eraikitzeko mekanismoa aldatu egin zen, gure konfigurazio-fitxategi klasikoarekin zein Kuber-en sekretuekin lan egin ahal izateko. Konfigurazio-egitura zurrunago bat ere zehaztu zen, hirugarren Python-en hizkuntzan, honela:
Dict[str, Dict[str, Batasuna[str, int, float]]]
Hau da, azken cogfig atal izendunen hiztegi bat da, eta horietako bakoitza mota sinpleetako balioak dituen hiztegi bat da. Eta atalek mota jakin bateko baliabideetarako konfigurazioa eta sarbidea deskribatzen dituzte. Gure konfigurazioaren zati baten adibidea:
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"
Aldi berean, zelaia engine
datu-baseak SQLite-n instalatu daitezke, eta redis
ezarri mock
, gorde beharreko fitxategiaren izena ere zehaztuz - parametro hauek behar bezala ezagutzen eta prozesatzen dira, eta horri esker, kodea lokalean exekutatzeko erraza da arazketa, unitate-probak eta beste edozein beharretarako. Hau bereziki garrantzitsua da guretzat, beste behar asko daudelako: gure kodearen zati bat kalkulu analitiko ezberdinetarako dago pentsatuta, orkestrazioa duten zerbitzarietan ez ezik, hainbat scriptekin ere exekutatzen da eta lan egin behar duten analistaren ordenagailuetan. eta arazketa datuak prozesatzeko kanalizazio konplexuak backend-arazoak kezkatu gabe. Bide batez, ez legoke kalterik gure tresna nagusiak, konfigurazio diseinu-kodea barne, bidez instalatuta daudela partekatzea. setup.py
– elkarrekin honek gure kodea ekosistema bakar batean batzen du, plataforma eta erabilera metodotik independentea.
Kubernetes pod baten deskribapena honelakoa da:
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
Hau da, sekretu bakoitzak atal bat deskribatzen du. Sekretuak berak honela sortzen dira:
apiVersion: v1
kind: Secret
metadata:
name: db-main-secret
type: Opaque
stringData:
db_main.yaml: |
engine: sqlite
filename: main.sqlite3
Horrek batera, YAML fitxategiak sortzen ditu bidean zehar /etc/secrets/db-main/section_name.yaml
Eta tokiko abiarazteetarako, konfigurazioa erabiltzen da, proiektuaren erro-direktorioan edo ingurune-aldagaian zehaztutako bidetik. Erosotasun horien ardura duen kodea spoilerrean ikus daiteke.
konfig.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()
Hemen logika nahiko sinplea da: proiektuaren direktorioko konfigurazio handiak eta bideak ingurune-aldagaiaren arabera konbinatzen ditugu eta Kuber-eko sekretuetako konfigurazio atal txikiak konbinatzen ditugu eta, ondoren, apur bat aldez aurretik prozesatzen ditugu. Gainera aldagai batzuk. Kontuan izan dut sekretuetatik fitxategiak bilatzean, sakontasun-muga bat erabiltzen dela, K8s-ek sekretuak gordeta dauden sekretu bakoitzean ezkutuko karpeta bat sortzen duelako eta esteka bat besterik ez dago maila altuago batean.
Deskribatzen dena norbaitentzat erabilgarria izatea espero dut :) Segurtasunari edo hobetzeko beste arlo batzuei buruzko iruzkinak eta gomendioak onartzen dira. Komunitatearen iritzia ere interesgarria da, agian merezi du ConfigMaps-en laguntza gehitzea (gure proiektuak oraindik ez ditu erabiltzen) eta kodea GitHub / PyPI-n argitaratzea? Pertsonalki, uste dut horrelako gauzak indibidualegiak direla proiektuak unibertsalak izateko, eta besteen inplementazioei begirada pixka bat, hemen ematen den moduan, eta ñabardura, aholku eta jardunbide egokien eztabaida, iruzkinetan ikustea espero dut. , nahikoa da 😉
Erregistratutako erabiltzaileek soilik parte hartu dezakete inkestan.
Proiektu/liburutegi gisa argitaratu behar al dut?
-
0,0%Bai, /contribution0 erabiliko nuke
-
33,3%Bai, oso ona dirudi horrek4
-
41,7%Ez, nork bere formatuan eta beharretara egokitzeko egin behar duena5
-
25,0%Ez dut erantzunik3
12 erabiltzailek eman dute botoa. 3 erabiltzaile abstenitu ziren.
Iturria: www.habr.com