Konfigurasi proyek ing jero lan njaba Kubernetes

Aku bubar nulis njawab babagan urip proyek ing Docker lan kode debugging ing njaba, ing ngendi dheweke sedhela nyatakake yen sampeyan bisa nggawe sistem konfigurasi dhewe supaya layanan kasebut bisa digunakake kanthi apik ing Kuber, narik rahasia, lan bisa mlaku kanthi lokal, sanajan ing njaba Docker kabeh. Boten rumit, nanging diterangake "resep" bisa migunani kanggo wong :) Kode ing Python, nanging logika ora disambungake menyang basa.

Konfigurasi proyek ing jero lan njaba Kubernetes

Latar mburi pitakonan iki: biyen ana siji proyek, ing kawitan iku monolit cilik karo utilitas lan skrip, nanging liwat wektu iku tuwuh, dipérang dadi layanan, kang banjur wiwit dipérang dadi microservices lan. banjur digedhekake. Kaping pisanan, kabeh iki ditindakake ing VPS kosong, proses nyetel lan nyebarake kode sing otomatis nggunakake Ansible, lan saben layanan dikompilasi karo konfigurasi YAML kanthi setelan lan tombol sing dibutuhake, lan file konfigurasi sing padha digunakake kanggo Bukak lokal, kang banget trep, amarga .k config iki dimuat menyang obyek global, diakses saka ngendi wae ing project.

Nanging, wutah ing nomer microservices, sambungan, lan perlu kanggo logging lan ngawasi terpusat, foreshadowed pamindhahan kanggo Kuber, kang isih ing proses. Bebarengan karo pitulungan kanggo ngrampungake masalah kasebut, Kubernetes nawakake pendekatan kanggo manajemen infrastruktur, kalebu supaya disebut-Rahasia и cara kanggo bisa karo wong-wong mau. Mekanisme kasebut standar lan dipercaya, mula sejatine dosa ora digunakake! Nanging ing wektu sing padha, aku pengin njaga format saiki kanggo nggarap konfigurasi: pisanan, nggunakake seragam ing macem-macem microservices proyek, lan liya, supaya bisa mbukak kode ing mesin lokal nggunakake siji prasaja. file config.

Ing babagan iki, mekanisme kanggo mbangun obyek konfigurasi diowahi supaya bisa digunakake karo file konfigurasi klasik lan rahasia saka Kuber. Struktur konfigurasi sing luwih kaku uga ditemtokake, ing basa Python katelu, kaya ing ngisor iki:

Dict[str, Dict[str, Union[str, int, float]]]

Yaiku, cogfig pungkasan yaiku kamus kanthi bagean sing dijenengi, saben-saben minangka kamus kanthi nilai saka jinis sing prasaja. Lan bagean nggambarake konfigurasi lan akses menyang sumber daya saka jinis tartamtu. Conto bagean saka konfigurasi kita:

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"

Ing wektu sing padha, lapangan engine database bisa diinstal ing SQLite, lan redis disetel kanggo mock, nemtokake uga jeneng file kanggo nyimpen - paramèter iki bener dikenali lan diproses, kang ndadekake iku gampang kanggo mbukak kode lokal kanggo debugging, testing unit lan kabutuhan liyane. Iki penting banget kanggo kita amarga ana akeh kabutuhan liyane - bagean saka kode kita dimaksudake kanggo macem-macem kalkulasi analitis, mlaku ora mung ing server kanthi orkestrasi, nanging uga nganggo macem-macem skrip, lan ing komputer analis sing kudu digarap. lan debug pipa pangolahan data sing kompleks tanpa kuwatir masalah backend. Miturut cara, iku ora babras kanggo nuduhake yen alat utama kita, kalebu kode tata letak konfigurasi, diinstal liwat setup.py - bebarengan iki nggabungake kode kita dadi siji ekosistem, ora gumantung saka platform lan cara panggunaan.

Katrangan saka pod Kubernetes katon kaya iki:

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

Sing, saben rahasia nggambarake siji bagean. Rahasia dhewe digawe kaya iki:

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

Bareng iki nyebabake nggawe file YAML ing sadawane dalan /etc/secrets/db-main/section_name.yaml

Lan kanggo peluncuran lokal, konfigurasi digunakake, dumunung ing direktori root proyek utawa ing dalan sing ditemtokake ing variabel lingkungan. Kode sing tanggung jawab kanggo kenyamanan kasebut bisa dideleng ing spoiler.

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

Logika kene cukup prasaja: kita gabungke configs gedhe saka direktori project lan path dening variabel lingkungan, lan bagean config cilik saka Rahasia Kuber, lan banjur preprocessed sethitik. Plus sawetara variabel. Aku Wigati sing nalika nggoleki file saka Rahasia, watesan ambane digunakake, amarga K8s nggawe folder didhelikake ing saben rahasia ngendi Rahasia dhewe disimpen, lan mung link dumunung ing tingkat sing luwih dhuwur.

Mugi apa sing diterangake bakal migunani kanggo wong :) Sembarang komentar lan Rekomendasi babagan keamanan utawa wilayah liyane kanggo dandan ditampa. Mratelakake panemume komunitas uga menarik, bisa uga kudu nambah dhukungan kanggo ConfigMaps (proyek kita durung digunakake) lan nerbitake kode kasebut ing GitHub / PyPI? Secara pribadi, aku mikir manawa prekara-prekara kaya ngono pancen individu kanggo proyek dadi universal, lan rada ngintip babagan implementasine wong liya, kaya sing diwenehake ing kene, lan diskusi babagan nuansa, tips lan praktik paling apik, sing dakkarepake bisa dideleng ing komentar. , wis cukup 😉

Mung pangguna pangguna sing bisa melu survey. mlebunggih.

Apa aku kudu nerbitake minangka proyek / perpustakaan?

  • 0,0%Ya, aku bakal nggunakake /contribution0

  • 33,3%Ya, sing muni apik4

  • 41,7%Ora, sing kudu nindakake dhewe ing format dhewe lan cocog karo kabutuhan5

  • 25,0%Aku ora bakal mangsuli3

12 pangguna milih. 3 pangguna abstain.

Source: www.habr.com

Add a comment