Жақында жаздым
Сұрақтың негізі мынада: бір кездері бір жоба болды, ол бастапқыда утилиталары мен сценарийлері бар шағын монолит болды, бірақ уақыт өте келе ол өсіп, қызметтерге бөлінді, олар өз кезегінде микросервистерге бөліне бастады және содан кейін масштабталды. Бастапқыда мұның бәрі 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