اخیرا نوشتم
پیشینه سوال این است: روزی روزگاری یک پروژه وجود داشت، در ابتدا یک تکپارچه کوچک با ابزارها و اسکریپت ها بود، اما با گذشت زمان رشد کرد، به خدمات تقسیم شد، که به نوبه خود به میکروسرویس ها تقسیم شد و سپس بزرگ شد. در ابتدا، همه این کارها بر روی VPS خالی انجام شد، فرآیندهای راه اندازی و استقرار کد روی آن با استفاده از Ansible به صورت خودکار انجام شد و هر سرویس با یک پیکربندی YAML با تنظیمات و کلیدهای لازم کامپایل شد و از یک فایل کانفیگ مشابه برای راه اندازی محلی، که بسیار راحت بود، زیرا .k این پیکربندی در یک شی سراسری بارگذاری می شود که از هر نقطه از پروژه قابل دسترسی است.
با این حال، رشد تعداد میکروسرویس ها، اتصالات آنها و
در این راستا، مکانیسم ساخت یک شیء پیکربندی اصلاح شد تا بتوان هم با فایل پیکربندی کلاسیک ما و هم با اسرار Kuber کار کرد. یک ساختار پیکربندی سفت و سخت تر نیز در زبان پایتون سوم به شرح زیر مشخص شد:
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
با مشخص کردن نام فایل برای ذخیره - این پارامترها به درستی شناسایی و پردازش می شوند، که اجرای کد به صورت محلی برای اشکال زدایی، تست واحد و هر نیاز دیگری را آسان می کند. این به ویژه برای ما مهم است زیرا نیازهای بسیار دیگری نیز وجود دارد - بخشی از کد ما برای محاسبات تحلیلی مختلف در نظر گرفته شده است، نه تنها بر روی سرورهای دارای هماهنگی، بلکه با اسکریپت های مختلف و روی رایانه های تحلیلگرانی که نیاز به کار دارند اجرا می شود. و خطوط لوله پردازش داده های پیچیده را بدون نگرانی مشکلات backend اشکال زدایی کنید. به هر حال، به اشتراک گذاشتن اینکه ابزارهای اصلی ما، از جمله کد طرح بندی پیکربندی، از طریق نصب شده اند، ضرری ندارد. 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()
منطق اینجا بسیار ساده است: پیکربندیهای بزرگ را از دایرکتوری پروژه و مسیرها بر اساس متغیر محیطی و بخشهای پیکربندی کوچک از Secrets Kuber را با هم ترکیب میکنیم و سپس آنها را کمی پیش پردازش میکنیم. به علاوه برخی از متغیرها. توجه دارم که هنگام جستجوی فایلها از اسرار، از محدودیت عمق استفاده میشود، زیرا K8s یک پوشه مخفی در هر مخفی ایجاد میکند که در آن اسرار خود ذخیره میشوند و فقط یک پیوند در سطح بالاتری قرار دارد.
امیدوارم آنچه شرح داده شده برای کسی مفید باشد :) هر گونه نظر و توصیه در مورد امنیت یا سایر زمینه های بهبود پذیرفته می شود. نظر جامعه نیز جالب است، شاید ارزش افزودن پشتیبانی از ConfigMaps را داشته باشد (پروژه ما هنوز از آنها استفاده نمی کند) و انتشار کد در GitHub / PyPI؟ شخصاً فکر میکنم که چنین چیزهایی برای پروژهها بسیار فردی هستند که نمیتوانند جهانی باشند، و کمی نگاه کردن به پیادهسازیهای افراد دیگر، مانند آنچه در اینجا ارائه شد، و بحث در مورد تفاوتهای ظریف، نکات و بهترین شیوهها، که امیدوارم در نظرات ببینم. ، کافی است 😉
فقط کاربران ثبت نام شده می توانند در نظرسنجی شرکت کنند.
آیا باید به عنوان پروژه/کتابخانه منتشر کنم؟
-
٪۱۰۰بله، من از /contribution0 استفاده می کنم
-
٪۱۰۰بله، عالی به نظر می رسد4
-
٪۱۰۰نه، چه کسی باید این کار را خودش در قالب خودش و مطابق با نیازهایش انجام دهد
-
٪۱۰۰از پاسخ دادن خودداری می کنم3
12 کاربر رای دادند. 3 کاربر رای ممتنع دادند.
منبع: www.habr.com