Ég skrifaði nýlega
Forsaga spurningarinnar er þessi: Einu sinni var eitt verkefni, fyrst var það lítill einleikur með tólum og skriftum, en með tímanum stækkaði það, skiptist í þjónustur, sem aftur fór að skipta í örþjónustur, og svo stækkað. Í fyrstu var allt þetta gert á berum VPS, ferlarnir við að setja upp og dreifa kóða sem voru sjálfvirkir með Ansible, og hver þjónusta var sett saman með YAML stillingum með nauðsynlegum stillingum og lyklum og svipuð stillingarskrá var notuð fyrir staðbundnar kynningar, sem var mjög þægilegt, vegna þess að .k þessi stilling er hlaðin inn í alþjóðlegan hlut, aðgengilegur hvar sem er í verkefninu.
Hins vegar fjölgar örþjónustum, tengingum þeirra og
Í þessu sambandi var vélbúnaðurinn til að smíða stillingarhlut breytt til að geta unnið bæði með klassísku stillingarskránni okkar og með leyndarmálum frá Kuber. Stífari stillingaruppbygging var einnig tilgreind, á tungumáli þriðja Python, sem hér segir:
Dict[str, Dict[str, Union[str, int, flot]]]
Það er að segja, síðasta tannhjólið er orðabók með nafngreindum hlutum, sem hver um sig er orðabók með gildum úr einföldum gerðum. Og hlutar lýsa uppsetningu og aðgangi að tilföngum af ákveðinni gerð. Dæmi um stykki af stillingum okkar:
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"
Á sama tíma, völlurinn engine
gagnagrunna er hægt að setja upp á SQLite, og redis
stillt á mock
, tilgreinir einnig nafn skráarinnar sem á að vista - þessar færibreytur eru rétt viðurkenndar og unnar, sem gerir það auðvelt að keyra kóðann á staðnum fyrir villuleit, einingaprófun og hvers kyns aðrar þarfir. Þetta er sérstaklega mikilvægt fyrir okkur vegna þess að það eru margar aðrar þarfir - hluti af kóðanum okkar er ætlaður fyrir ýmsa greiningarútreikninga, hann keyrir ekki aðeins á netþjónum með hljómsveit, heldur einnig með ýmsum skriftum og á tölvum greiningaraðila sem þurfa að vinna í gegnum og kemba flóknar gagnavinnsluleiðslur án þess að hafa áhyggjur af bakendamálum. Við the vegur, það myndi ekki skaða að deila því að helstu verkfæri okkar, þar á meðal uppsetningarkóðann, eru sett upp í gegnum setup.py
– saman sameinar þetta kóðann okkar í eitt vistkerfi, óháð vettvangi og notkunaraðferð.
Lýsingin á Kubernetes belg lítur svona út:
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
Það er, hvert leyndarmál lýsir einum hluta. Leyndarmálin sjálf eru búin til svona:
apiVersion: v1
kind: Secret
metadata:
name: db-main-secret
type: Opaque
stringData:
db_main.yaml: |
engine: sqlite
filename: main.sqlite3
Saman leiðir þetta til þess að YAML skrár eru búnar til á leiðinni /etc/secrets/db-main/section_name.yaml
Og fyrir staðbundnar ræsingar er stillingin notuð, staðsett í rótarskrá verkefnisins eða meðfram slóðinni sem tilgreind er í umhverfisbreytunni. Kóðann sem ber ábyrgð á þessum þægindum má sjá í spoilernum.
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()
Rökfræðin hér er frekar einföld: við sameinum stórar stillingar úr verkefnaskránni og slóðir eftir umhverfisbreytu, og litla stillingarhluta úr Kuber-leyndarmálum, og forvinnum þær síðan aðeins. Plús nokkrar breytur. Ég tek það fram að þegar leitað er að skrám úr leyndarmálum er dýptartakmörkun notuð, því K8s býr til falda möppu í hverju leyndarmáli þar sem leyndarmálin sjálf eru geymd og bara hlekkur er staðsettur á hærra stigi.
Ég vona að það sem lýst er komi einhverjum að gagni :) Allar athugasemdir og ráðleggingar varðandi öryggi eða önnur svæði til úrbóta eru samþykkt. Álit samfélagsins er líka áhugavert, kannski er það þess virði að bæta við stuðningi við ConfigMaps (verkefnið okkar notar þau ekki ennþá) og birta kóðann á GitHub / PyPI? Persónulega finnst mér svona hlutir vera of einstaklingsbundnir til að verkefni séu almenn, og smá að kíkja á útfærslur annarra eins og hér kemur fram og umfjöllun um blæbrigði, ábendingar og bestu vinnubrögð sem ég vonast til að sjá í athugasemdum , er nóg 😉
Aðeins skráðir notendur geta tekið þátt í könnuninni.
Ætti ég að gefa út sem verkefni/safn?
-
0,0%Já, ég myndi nota /contribution0
-
33,3%Já, það hljómar vel4
-
41,7%Nei, hver þarf að gera það sjálfur í sínu eigin formi og eftir þörfum5
-
25,0%Ég mun ekki svara 3
12 notendur greiddu atkvæði. 3 notendur sátu hjá.
Heimild: www.habr.com