Yaqinda yozdim
Savolning foni quyidagicha: bir vaqtlar bitta loyiha bor edi, dastlab u yordamchi dasturlar va skriptlarga ega kichik monolit edi, lekin vaqt o'tishi bilan u o'sib bordi, xizmatlarga bo'lindi, ular o'z navbatida mikroservislarga bo'linishni boshladilar va keyin kattalashtirildi. Avvaliga bularning barchasi yalang'och VPS-da amalga oshirildi, kodni o'rnatish va joylashtirish jarayonlari Ansible yordamida avtomatlashtirilgan va har bir xizmat kerakli sozlamalar va kalitlarga ega YAML konfiguratsiyasi bilan tuzilgan va shunga o'xshash konfiguratsiya fayli uchun ishlatilgan. mahalliy ishga tushirildi, bu juda qulay edi, chunki .k ushbu konfiguratsiya global ob'ektga yuklangan, loyihaning istalgan joyidan foydalanish mumkin.
Biroq, mikroservislar sonining o'sishi, ularning ulanishlari va
Shu munosabat bilan, konfiguratsiya ob'ektini yaratish mexanizmi klassik konfiguratsiya faylimiz bilan ham, Kuber sirlari bilan ham ishlash imkoniyatiga ega bo'lishi uchun o'zgartirildi. Uchinchi Python tilida yanada qattiqroq konfiguratsiya tuzilishi ham quyidagicha belgilandi:
Dict[str, Dict[str, Union[str, int, float]]]
Ya'ni, yakuniy tishli lug'at nomli bo'limlari bo'lgan lug'at bo'lib, ularning har biri oddiy turdagi qiymatlardan iborat lug'atdir. Va bo'limlar konfiguratsiya va ma'lum turdagi resurslarga kirishni tavsiflaydi. Konfiguratsiyamizning bir qismiga misol:
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"
Shu bilan birga, dala engine
ma'lumotlar bazalari SQLite-ga o'rnatilishi mumkin va redis
sozlang mock
, shuningdek, saqlash uchun fayl nomini ko'rsatish - bu parametrlar to'g'ri tan olinadi va qayta ishlanadi, bu esa disk raskadrovka, birlik testi va boshqa ehtiyojlar uchun kodni mahalliy sifatida ishlatishni osonlashtiradi. Bu biz uchun ayniqsa muhimdir, chunki boshqa ko'plab ehtiyojlar mavjud - bizning kodimizning bir qismi turli xil analitik hisob-kitoblar uchun mo'ljallangan, u nafaqat orkestratsiyalangan serverlarda, balki turli xil skriptlar bilan ishlaydi va tahlilchilarning kompyuterlarida ishlaydi. va murakkab ma'lumotlarni qayta ishlash quvurlarini disk raskadrovka bilan bog'liq muammolarsiz disk raskadrovka. Aytgancha, bizning asosiy vositalarimiz, jumladan, konfiguratsiya tartibi kodi orqali o'rnatilganligini baham ko'rish zarar qilmaydi. setup.py
β birgalikda bu bizning kodimizni platforma va foydalanish usulidan mustaqil yagona ekotizimga birlashtiradi.
Kubernetes podining tavsifi quyidagicha ko'rinadi:
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
Ya'ni, har bir sir bir qismni tasvirlaydi. Sirlarning o'zi quyidagicha yaratilgan:
apiVersion: v1
kind: Secret
metadata:
name: db-main-secret
type: Opaque
stringData:
db_main.yaml: |
engine: sqlite
filename: main.sqlite3
Birgalikda bu yo'l bo'ylab YAML fayllarini yaratishga olib keladi /etc/secrets/db-main/section_name.yaml
Mahalliy ishga tushirish uchun esa loyihaning asosiy katalogida yoki muhit o'zgaruvchisida ko'rsatilgan yo'lda joylashgan konfiguratsiya ishlatiladi. Ushbu qulayliklar uchun javobgar kodni spoylerda ko'rish mumkin.
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()
Bu erda mantiq juda oddiy: biz loyiha katalogidagi katta konfiguratsiyalarni va atrof-muhit o'zgaruvchisi bo'yicha yo'llarni va Kuber sirlaridan kichik konfiguratsiya bo'limlarini birlashtiramiz va keyin ularni biroz oldindan qayta ishlaymiz. Bundan tashqari, ba'zi o'zgaruvchilar. Shuni ta'kidlaymanki, sirlardan fayllarni qidirishda chuqurlik chegarasi qo'llaniladi, chunki K8s har bir sirda sirlarning o'zi saqlanadigan yashirin papkani yaratadi va shunchaki havola yuqori darajada joylashgan.
Umid qilamanki, tasvirlangan narsa kimgadir foydali bo'ladi :) Xavfsizlik yoki yaxshilash uchun boshqa sohalarga oid har qanday sharh va tavsiyalar qabul qilinadi. Jamiyatning fikri ham qiziq, ehtimol ConfigMaps-ni qo'shish (bizning loyihamiz hali ulardan foydalanmaydi) va kodni GitHub / PyPI-da nashr qilish kerakmi? Shaxsan menimcha, bunday narsalar loyihalar universal bo'lishi uchun juda individualdir va bu erda keltirilgan kabi boshqa odamlarning amalga oshirishlariga biroz nazar tashlash va sharhlarda ko'rishga umid qilaman. , yetarli π
So'rovda faqat ro'yxatdan o'tgan foydalanuvchilar ishtirok etishlari mumkin.
Loyiha/kutubxona sifatida nashr qilishim kerakmi?
-
0,0%Ha, men /contribution0 dan foydalanardim
-
33,3%Ha, bu ajoyib eshitiladi4
-
41,7%Yo'q, kim buni o'z formatida va ehtiyojlariga mos ravishda qilish kerak5
-
25,0%Men javob berishdan tiyilaman3
12 nafar foydalanuvchi ovoz berdi. 3 nafar foydalanuvchi betaraf qolgan.
Manba: www.habr.com