ฉันเพิ่งเขียน
เบื้องหลังของคำถามคือ กาลครั้งหนึ่งมีโครงการหนึ่ง ในตอนแรกมันเป็นโครงการขนาดใหญ่ขนาดเล็กที่มียูทิลิตี้และสคริปต์ แต่เมื่อเวลาผ่านไปมันก็เติบโตขึ้น โดยแบ่งออกเป็นบริการ ซึ่งในทางกลับกันก็เริ่มถูกแบ่งออกเป็นไมโครเซอร์วิส และ จากนั้นจึงขยายขนาด ในตอนแรก ทั้งหมดนี้ทำบน VPS เปลือย กระบวนการตั้งค่าและปรับใช้โค้ดที่ทำงานอัตโนมัติโดยใช้ Ansible และแต่ละบริการได้รับการคอมไพล์ด้วยการกำหนดค่า YAML พร้อมการตั้งค่าและคีย์ที่จำเป็น และใช้ไฟล์กำหนดค่าที่คล้ายกัน การเปิดตัวในท้องถิ่นซึ่งสะดวกมาก เนื่องจาก .k การกำหนดค่านี้ถูกโหลดลงในอ็อบเจ็กต์ส่วนกลาง ซึ่งสามารถเข้าถึงได้จากทุกที่ในโปรเจ็กต์
อย่างไรก็ตาม การเติบโตของจำนวนไมโครเซอร์วิส การเชื่อมต่อ และ
ในเรื่องนี้ กลไกในการสร้างออบเจ็กต์การกำหนดค่าได้รับการแก้ไขเพื่อให้สามารถทำงานได้ทั้งกับไฟล์กำหนดค่าแบบคลาสสิกของเราและกับความลับจาก Kuber โครงสร้างการกำหนดค่าที่เข้มงวดยิ่งขึ้นได้รับการระบุในภาษาของ Python ตัวที่สามดังนี้:
Dict[str, Dict[str, ยูเนี่ยน[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
โดยระบุชื่อของไฟล์ที่จะบันทึกด้วย - พารามิเตอร์เหล่านี้ได้รับการยอมรับและประมวลผลอย่างถูกต้อง ซึ่งทำให้ง่ายต่อการเรียกใช้โค้ดในเครื่องสำหรับการดีบัก การทดสอบหน่วย และความต้องการอื่น ๆ นี่เป็นสิ่งสำคัญอย่างยิ่งสำหรับเราเนื่องจากมีความต้องการอื่นๆ มากมาย - ส่วนหนึ่งของโค้ดของเรามีไว้สำหรับการคำนวณเชิงวิเคราะห์ที่หลากหลาย ซึ่งไม่เพียงทำงานบนเซิร์ฟเวอร์ที่มีการเรียบเรียงเท่านั้น แต่ยังทำงานบนสคริปต์ต่างๆ ด้วย และบนคอมพิวเตอร์ของนักวิเคราะห์ที่ต้องทำงานผ่าน และดีบักไปป์ไลน์การประมวลผลข้อมูลที่ซับซ้อนโดยไม่ต้องกังวลกับปัญหาแบ็กเอนด์ อย่างไรก็ตาม การแชร์ว่าเครื่องมือหลักของเรา รวมถึงโค้ดเค้าโครงการกำหนดค่าได้รับการติดตั้งผ่านทางนั้นไม่ใช่เรื่องเสียหาย 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()
ตรรกะที่นี่ค่อนข้างง่าย: เรารวมการกำหนดค่าขนาดใหญ่จากไดเร็กทอรีโปรเจ็กต์และเส้นทางตามตัวแปรสภาพแวดล้อม และส่วนการกำหนดค่าขนาดเล็กจากความลับของ Kuber จากนั้นจึงประมวลผลล่วงหน้าเล็กน้อย บวกกับตัวแปรบางอย่าง ฉันทราบว่าเมื่อค้นหาไฟล์จากความลับ จะมีการจำกัดความลึก เนื่องจาก K8s สร้างโฟลเดอร์ที่ซ่อนอยู่ในแต่ละความลับซึ่งเก็บความลับไว้ และมีเพียงลิงก์เท่านั้นที่อยู่ในระดับที่สูงกว่า
ฉันหวังว่าสิ่งที่อธิบายไว้จะเป็นประโยชน์กับใครบางคน :) ยอมรับความคิดเห็นและคำแนะนำเกี่ยวกับการรักษาความปลอดภัยหรือด้านอื่น ๆ ที่ต้องปรับปรุง ความคิดเห็นของชุมชนก็น่าสนใจเช่นกัน บางทีอาจคุ้มค่าที่จะเพิ่มการรองรับ ConfigMaps (โครงการของเรายังไม่ได้ใช้) และการเผยแพร่โค้ดบน GitHub / PyPI โดยส่วนตัวแล้ว ฉันคิดว่าสิ่งเหล่านี้เป็นเรื่องเฉพาะตัวเกินไปสำหรับโครงการที่เป็นสากล และแอบดูการใช้งานของผู้อื่น เช่นเดียวกับที่ให้ไว้ที่นี่ และการอภิปรายเกี่ยวกับความแตกต่าง เคล็ดลับ และแนวปฏิบัติที่ดีที่สุด ซึ่งฉันหวังว่าจะเห็นในความคิดเห็น , ก็พอแล้ว 😉
เฉพาะผู้ใช้ที่ลงทะเบียนเท่านั้นที่สามารถเข้าร่วมในการสำรวจได้
ฉันควรเผยแพร่เป็นโครงการ/ห้องสมุดหรือไม่?
-
ลด 0,0%ใช่ ฉันจะใช้ /contribution0
-
ลด 33,3%ใช่ มันฟังดูดีมาก4
-
ลด 41,7%ไม่ ใครบ้างที่ต้องดำเนินการด้วยตนเองในรูปแบบของตนเองและเพื่อให้เหมาะกับความต้องการของตนเอง5
-
ลด 25,0%ฉันจะงดตอบ3
ผู้ใช้ 12 คนโหวต ผู้ใช้ 3 รายงดออกเสียง
ที่มา: will.com