Cyfluniad y prosiect y tu mewn a'r tu allan i Kubernetes

Ysgrifennais yn ddiweddar ateb am fywyd prosiect yn Docker a chod dadfygio y tu allan iddo, lle soniodd yn fyr y gallwch chi wneud eich system ffurfweddu eich hun fel bod y gwasanaeth yn gweithio'n dda yn Kuber, yn tynnu cyfrinachau i fyny, ac yn rhedeg yn gyfleus yn lleol, hyd yn oed y tu allan i Docker yn gyfan gwbl. Dim byd cymhleth, ond efallai y bydd y “rysáit” a ddisgrifir yn ddefnyddiol i rywun :) Mae'r cod yn Python, ond nid yw'r rhesymeg ynghlwm wrth yr iaith.

Cyfluniad y prosiect y tu mewn a'r tu allan i Kubernetes

Y cefndir i'r cwestiwn yw hyn: unwaith ar y tro roedd un prosiect, ar y dechrau roedd yn fonolith bach gyda chyfleustodau a sgriptiau, ond dros amser fe dyfodd, wedi'i rannu'n wasanaethau, a ddechreuodd yn ei dro gael ei rannu'n ficrowasanaethau, a yna graddedig. Ar y dechrau, gwnaed hyn i gyd ar VPS noeth, a chafodd y prosesau o sefydlu a defnyddio cod eu hawtomeiddio gan ddefnyddio Ansible, a lluniwyd pob gwasanaeth gyda chyfluniad YAML gyda'r gosodiadau a'r allweddi angenrheidiol, a defnyddiwyd ffeil ffurfweddu debyg ar gyfer lansiadau lleol, a oedd yn gyfleus iawn, oherwydd .k mae'r ffurfwedd hon wedi'i llwytho i mewn i wrthrych byd-eang, sy'n hygyrch o unrhyw le yn y prosiect.

Fodd bynnag, mae'r twf yn nifer y microwasanaethau, eu cysylltiadau, a angen am logio a monitro canolog, rhagwelodd symud i Kuber, sy'n dal i fynd rhagddo. Ynghyd â chymorth i ddatrys y problemau a grybwyllwyd, mae Kubernetes yn cynnig ei ddulliau o reoli seilwaith, gan gynnwys Cyfrinachau fel y'u gelwir и ffyrdd o weithio gyda nhw. Mae'r mecanwaith yn safonol ac yn ddibynadwy, felly yn llythrennol mae'n bechod peidio â'i ddefnyddio! Ond ar yr un pryd, hoffwn gynnal fy fformat presennol ar gyfer gweithio gyda'r config: yn gyntaf, i'w ddefnyddio'n unffurf mewn gwahanol ficrowasanaethau o'r prosiect, ac yn ail, i allu rhedeg y cod ar y peiriant lleol gan ddefnyddio un syml ffeil ffurfweddu.

Yn hyn o beth, addaswyd y mecanwaith ar gyfer adeiladu gwrthrych cyfluniad i allu gweithio gyda'n ffeil ffurfweddu clasurol a gyda chyfrinachau gan Kuber. Pennwyd strwythur cyfluniad mwy anhyblyg hefyd, yn iaith y trydydd Python, fel a ganlyn:

Dict[str, Dict[str, Undeb[str, int, arnofio]]]

Hynny yw, mae'r cogfig olaf yn eiriadur gydag adrannau a enwir, pob un ohonynt yn eiriadur gyda gwerthoedd o fathau syml. Ac mae adrannau'n disgrifio ffurfweddiad a mynediad at adnoddau o fath penodol. Enghraifft o ddarn o'n ffurfwedd:

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"

Ar yr un pryd, y maes engine gellir gosod cronfeydd data ar SQLite, a redis gosod i mock, gan nodi hefyd enw'r ffeil i'w harbed - mae'r paramedrau hyn yn cael eu cydnabod a'u prosesu'n gywir, sy'n ei gwneud hi'n hawdd rhedeg y cod yn lleol ar gyfer dadfygio, profi uned ac unrhyw anghenion eraill. Mae hyn yn arbennig o bwysig i ni oherwydd bod yna lawer o anghenion eraill - mae rhan o'n cod wedi'i fwriadu ar gyfer cyfrifiadau dadansoddol amrywiol, mae'n rhedeg nid yn unig ar weinyddion gydag offeryniaeth, ond hefyd gyda sgriptiau amrywiol, ac ar gyfrifiaduron dadansoddwyr y mae angen iddynt weithio drwyddynt. a dadfygio piblinellau prosesu data cymhleth heb boeni am faterion ôl-gefn. Gyda llaw, ni fyddai'n brifo rhannu bod ein prif offer, gan gynnwys y cod gosodiad ffurfweddu, yn cael eu gosod trwyddo setup.py – gyda’i gilydd mae hyn yn uno ein cod yn un ecosystem, yn annibynnol ar lwyfan a dull o ddefnyddio.

Mae'r disgrifiad o goden Kubernetes yn edrych fel hyn:

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

Hynny yw, mae pob cyfrinach yn disgrifio un adran. Mae'r cyfrinachau eu hunain yn cael eu creu fel hyn:

apiVersion: v1
kind: Secret
metadata:
  name: db-main-secret
type: Opaque
stringData:
  db_main.yaml: |
    engine: sqlite
    filename: main.sqlite3

Gyda'i gilydd mae hyn yn arwain at greu ffeiliau YAML ar hyd y llwybr /etc/secrets/db-main/section_name.yaml

Ac ar gyfer lansiadau lleol, defnyddir y ffurfweddiad, sydd wedi'i leoli yng nghyfeiriadur gwraidd y prosiect neu ar hyd y llwybr a nodir yn y newidyn amgylchedd. Mae'r cod sy'n gyfrifol am y cyfleusterau hyn i'w weld yn y sbwyliwr.

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()

Mae'r rhesymeg yma yn eithaf syml: rydym yn cyfuno cyfluniadau mawr o gyfeiriadur y prosiect a llwybrau yn ôl newidyn amgylchedd, ac adrannau ffurfweddu bach o gyfrinachau Kuber, ac yna'n eu rhagbrosesu ychydig. Ynghyd â rhai newidynnau. Sylwaf, wrth chwilio am ffeiliau o gyfrinachau, bod cyfyngiad dyfnder yn cael ei ddefnyddio, oherwydd bod K8s yn creu ffolder cudd ym mhob cyfrinach lle mae'r cyfrinachau eu hunain yn cael eu storio, a dim ond dolen sydd wedi'i lleoli ar lefel uwch.

Rwy'n gobeithio y bydd yr hyn a ddisgrifir yn ddefnyddiol i rywun :) Derbynnir unrhyw sylwadau ac argymhellion ynghylch diogelwch neu feysydd eraill i'w gwella. Mae barn y gymuned hefyd yn ddiddorol, efallai ei bod yn werth ychwanegu cefnogaeth i ConfigMaps (nid yw ein prosiect yn eu defnyddio eto) a chyhoeddi'r cod ar GitHub / PyPI? Yn bersonol, credaf fod pethau o'r fath yn rhy unigol i brosiectau fod yn gyffredinol, ac ychydig yn edrych ar weithrediadau pobl eraill, fel yr un a roddir yma, a thrafodaeth ar arlliwiau, awgrymiadau ac arferion gorau, yr wyf yn gobeithio eu gweld yn y sylwadau , yn ddigon 😉

Dim ond defnyddwyr cofrestredig all gymryd rhan yn yr arolwg. Mewngofnodios gwelwch yn dda.

A ddylwn i gyhoeddi fel prosiect/llyfrgell?

  • 0,0%Byddwn, byddwn yn defnyddio /cyfraniad0

  • 33,3%Ydy, mae hynny'n swnio'n wych4

  • 41,7%Na, pwy sydd angen ei wneud eu hunain yn eu fformat eu hunain ac i weddu i'w hanghenion5

  • 25,0%ymatalaf rhag ateb3

Pleidleisiodd 12 o ddefnyddwyr. Ymataliodd 3 o ddefnyddwyr.

Ffynhonnell: hab.com

Ychwanegu sylw