ืคึผืจืึธื™ืขืงื˜ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ื™ืŸ ืื•ืŸ ืึทืจื•ื™ืก Kubernetes

ืื™ืš ื”ืื‘ ืœืขืฆื˜ื ืก ื’ืขืฉืจื™ื‘ืŸ ืขื ื˜ืคึฟืขืจืŸ ื•ื•ืขื’ืŸ ืคึผืจื•ื™ืขืงื˜ ืœืขื‘ืŸ ืื™ืŸ ื“ืึธืงืงืขืจ ืื•ืŸ ื“ื™ื‘ืึทื’ื™ื ื’ ืงืึธื“ ืึทืจื•ื™ืก ืขืก, ื•ื•ื•ึผ ืขืจ ื”ืึธื˜ ืงื•ืจืฅ ื“ืขืจืžืื ื˜ ืึทื– ืื™ืจ ืงืขื ืขืŸ ืžืึทื›ืŸ ื“ื™ื™ืŸ ืื™ื™ื’ืขื ืข ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ืกื™ืกื˜ืขื ืึทื–ื•ื™ ืึทื– ื“ื™ ื“ื™ื ืกื˜ ืึทืจื‘ืขื˜ ื’ืขื–ื•ื ื˜ ืื™ืŸ ืงื•ื‘ืขืจ, ืคึผื•ืœื– ืึทืจื•ื™ืฃ ืกื™ืงืจื™ืฅ ืื•ืŸ ืœื•ื™ืคื˜ ืงืึทื ื•ื•ื™ื ื™ืึทื ื˜ืœื™ ืœืึธื•ืงืึทืœื™, ืืคื™ืœื• ืึทืจื•ื™ืก ืคื•ืŸ ื“ืึธืงืงืขืจ ื‘ืขืกืึทื›ืึทืงืœ. ื’ืึธืจื ื™ืฉื˜ ืงืึธืžืคึผืœื™ืฆื™ืจื˜, ืึธื‘ืขืจ ื“ื™ ื“ื™ืกืงืจื™ื™ื‘ื“ "ืจืขืฆืขืคึผื˜" ืงืขืŸ ื–ื™ื™ืŸ ื ื•ืฆื™ืง ืคึฟืึทืจ ืขืžืขืฆืขืจ :) ื“ื™ ืงืึธื“ ืื™ื– ืื™ืŸ ืคึผื™ื˜ื”ืึธืŸ, ืึธื‘ืขืจ ื“ื™ ืœืึธื’ื™ืง ืื™ื– ื ื™ืฉื˜ ื˜ื™ื™ื“ ืฆื• ื“ื™ ืฉืคึผืจืึทืš.

ืคึผืจืึธื™ืขืงื˜ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ื™ืŸ ืื•ืŸ ืึทืจื•ื™ืก Kubernetes

ื“ืขืจ ื”ื™ื ื˜ืขืจื’ืจื•ื ื˜ ืคื•ืŸ ื“ื™ ืงืฉื™ื ืื™ื– ื“ืึธืก: ืึทืžืึธืœ ืขืก ืื™ื– ื’ืขื•ื•ืขืŸ ืื™ื™ืŸ ืคึผืจื•ื™ืขืงื˜, ืื™ืŸ ืขืจืฉื˜ืขืจ ืขืก ืื™ื– ื’ืขื•ื•ืขืŸ ืึท ืงืœื™ื™ืŸ ืžืึธื ืึธืœื™ื˜ ืžื™ื˜ ื™ื•ื˜ื™ืœืึทื˜ื™ื– ืื•ืŸ ืกืงืจื™ืคึผืก, ืึธื‘ืขืจ ืžื™ื˜ ื“ื™ ืฆื™ื™ึทื˜ ืขืก ืื™ื– ื’ืขื•ื•ืืงืกืŸ, ืฆืขื˜ื™ื™ืœื˜ ืื™ืŸ ืกืขืจื•ื•ื™ืกืขืก, ื•ื•ืึธืก ืื™ืŸ ืงืขืจ ืื ื’ืขื”ื•ื™ื‘ืŸ ืฆื• ื–ื™ื™ืŸ ืฆืขื˜ื™ื™ืœื˜ ืื™ืŸ ืžื™ืงืจืึธ ืกืขืจื•ื•ื™ืกืขืก, ืื•ืŸ ื“ืขืžืึธืœื˜ ืกืงื™ื™ืœื“ ืึทืจื•ื™ืฃ. ืื™ืŸ ืขืจืฉื˜ืขืจ, ืึทืœืข ื“ืขื ืื™ื– ื’ืขื•ื•ืขืŸ ื’ืขื˜ืืŸ ืื•ื™ืฃ ื ืึทืงืขื˜ VPS, ื“ื™ ืคึผืจืึทืกืขืกืึทื– ืคื•ืŸ ื‘ืึทืฉื˜ืขื˜ื™ืงืŸ ืื•ืŸ ื“ื™ืคึผืœื•ื™ื™ื ื’ ืงืึธื“ ืื•ื™ืฃ ื•ื•ืึธืก ื–ืขื ืขืŸ ืึธื˜ืึทืžื™ื™ื˜ื™ื“ ื ื™ืฆืŸ Ansible, ืื•ืŸ ื™ืขื“ืขืจ ื“ื™ื ืกื˜ ืื™ื– ื’ืขื•ื•ืขืŸ ืงืึทืžืคึผื™ื™ืœื“ ืžื™ื˜ ืึท YAML ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ืžื™ื˜ ื“ื™ ื ื•ื™ื˜ื™ืง ืกืขื˜ื˜ื™ื ื’ืก ืื•ืŸ ืฉืœื™ืกืœืขืŸ, ืื•ืŸ ืึท ืขื ืœืขืš ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ื˜ืขืงืข ืื™ื– ื’ืขื ื™ืฆื˜ ืคึฟืึทืจ ื”ื™ื’ืข ืœืึธื ื˜ืฉื™ื–, ื•ื•ืึธืก ืื™ื– ื’ืขื•ื•ืขืŸ ื–ื™ื™ืขืจ ื‘ืึทืงื•ื•ืขื, ื•ื•ื™ื™ึทืœ .ืง ื“ืขื ืงืึธื ืคื™ื’ ืื™ื– ืœืึธื•ื“ื™ื“ ืื™ืŸ ืึท ื’ืœืื‘ืืœืข ื›ื™ื™ืคืขืฅ, ืฆื•ื˜ืจื™ื˜ืœืขืš ืคึฟื•ืŸ ืขืจื’ืขืฅ ืื™ืŸ ื“ื™ ืคึผืจื•ื™ืขืงื˜.

ืึธื‘ืขืจ, ื“ืขืจ ื•ื•ื•ึผืงืก ืื™ืŸ ื“ื™ ื ื•ืžืขืจ ืคื•ืŸ ืžื™ืงืจืึธ ื‘ืึทื“ื™ื ื•ื ื’ืก, ื–ื™ื™ืขืจ ืงืึทื ืขืงืฉืึทื ื–, ืื•ืŸ ื ื•ื™ื˜ ืคึฟืึทืจ ืกืขื ื˜ืจืึทืœื™ื™ื–ื“ ืœืึธื’ื™ื ื’ ืื•ืŸ ืžืึธื ื™ื˜ืึธืจื™ื ื’, ื”ื ื˜ ืคืืจืื•ื™ืกื’ืขื–ืื’ ื˜ ื ื‘ืืฐืขื’ื•ื  ื’ ืงืฒ ืŸ ืงื•ื‘ืขืจ , ืฐืขืœื›ืข ืจ ืื™ ื– ื ื ืš ืื™ ืŸ ืคืจืื’ืจืขื . ืฆื•ื–ืึทืžืขืŸ ืžื™ื˜ ื”ื™ืœืฃ ืื™ืŸ ืกืึทืœื•ื•ื™ื ื’ ื“ื™ ื“ืขืจืžืื ื˜ ืคึผืจืึธื‘ืœืขืžืก, Kubernetes ืึธืคืคืขืจืก ื–ื™ื™ึทืŸ ืึทืคึผืจืึธื•ื˜ืฉื™ื– ืฆื• ื™ื ืคืจืึทืกื˜ืจืึทืงื˜ืฉืขืจ ืคืึทืจื•ื•ืึทืœื˜ื•ื ื’, ืึทืจื™ื™ึทื ื’ืขืจืขื›ื ื˜ ืึทื–ื•ื™ ื’ืขืจื•ืคืขื ืข ืกืขืงืจืขืฅ ะธ ื•ื•ืขื’ืŸ ืฆื• ืึทืจื‘ืขื˜ืŸ ืžื™ื˜ ื–ื™ื™. ื“ืขืจ ืžืขืงืึทื ื™ื–ืึทื ืื™ื– ื ืึธืจืžืึทืœ ืื•ืŸ ืคืึทืจืœืึธื–ืœืขืš, ืึทื–ื•ื™ ืขืก ืื™ื– ืžืžืฉ ืึท ื–ื™ื ื“ ื ื™ืฉื˜ ืฆื• ื ื•ืฆืŸ ืขืก! ืึธื‘ืขืจ ืื™ืŸ ื“ืขืจ ื–ืขืœื‘ื™ืงืขืจ ืฆื™ื™ื˜, ืื™ืš ื•ื•ืึธืœื˜ ื•ื•ื™ ืฆื• ื”ืึทืœื˜ืŸ ืžื™ื™ืŸ ืงืจืึทื ื˜ ืคึฟืึธืจืžืึทื˜ ืคึฟืึทืจ ืืจื‘ืขื˜ืŸ ืžื™ื˜ ื“ื™ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ: ืขืจืฉื˜ืขืจ, ืฆื• ื ื•ืฆืŸ ืขืก ื™ื•ื ืึทืคืึธืจืžืœื™ ืื™ืŸ ืคืึทืจืฉื™ื“ืขื ืข ืžื™ืงืจืึธ ืกืขืจื•ื•ื™ืกืขืก ืคื•ืŸ ื“ื™ ืคึผืจื•ื™ืขืงื˜, ืื•ืŸ ืฆื•ื•ื™ื™ื˜ื ืก, ืฆื• ืœื•ื™ืคืŸ ื“ื™ ืงืึธื“ ืื•ื™ืฃ ื“ื™ ื”ื™ื’ืข ืžืึทืฉื™ืŸ ืžื™ื˜ ืื™ื™ืŸ ืคึผืฉื•ื˜. ืงืึธื ืคื™ื’ ื˜ืขืงืข.

ืื™ืŸ ื“ืขื ืึทื›ื˜ื•ื ื’, ื“ื™ ืžืขืงืึทื ื™ื–ืึทื ืคึฟืึทืจ ืงืึทื ืกื˜ืจืึทืงื˜ื™ื ื’ ืึท ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ื›ื™ื™ืคืขืฅ ืื™ื– ื’ืขื•ื•ืขืŸ ืžืึทื“ืึทืคื™ื™ื“ ืฆื• ืงืขื ืขืŸ ืฆื• ืึทืจื‘ืขื˜ืŸ ื‘ื™ื™ื“ืข ืžื™ื˜ ืื•ื ื“ื–ืขืจ ืงืœืึทืกื™ืฉ ืงืึธื ืคื™ื’ ื˜ืขืงืข ืื•ืŸ ืžื™ื˜ ืกื™ืงืจื™ืฅ ืคื•ืŸ ืงื•ื‘ืขืจ. ื ืžืขืจ ืฉื˜ืจืขื ื’ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ืกื˜ืจื•ืงื˜ื•ืจ ืื™ื– ืื•ื™ืš ืกืคึผืขืกื™ืคื™ืขื“, ืื™ืŸ ื“ืขืจ ืฉืคึผืจืึทืš ืคื•ืŸ ื“ื™ ื“ืจื™ื˜ ืคึผื™ื˜ื”ืึธืŸ, ื•ื•ื™ ื’ื™ื™ื˜:

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

ื“ืึธืก ืื™ื–, ื“ื™ ืœืขืฆื˜ ืงืึธื’ืคื™ื’ ืื™ื– ืึท ื•ื•ืขืจื˜ืขืจื‘ื•ืš ืžื™ื˜ ื’ืขืจื•ืคึฟืŸ ืกืขืงืฉืึทื ื–, ื™ืขื“ืขืจ ืคื•ืŸ ื•ื•ืึธืก ืื™ื– ืึท ื•ื•ืขืจื˜ืขืจื‘ื•ืš ืžื™ื˜ ื•ื•ืึทืœื•ืขืก ืคื•ืŸ ืคึผืฉื•ื˜ ื˜ื™ื™ืคึผืก. ืื•ืŸ ืกืขืงืฉืึทื ื– ื‘ืึทืฉืจื™ื™ึทื‘ืŸ ื“ื™ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ืื•ืŸ ืึทืงืกืขืก ืฆื• ืจืขืกื•ืจืกืŸ ืคื•ืŸ ืึท ื–ื™ื›ืขืจ ื˜ื™ืคึผ. ื ื‘ื™ื™ืฉืคึผื™ืœ ืคื•ืŸ ืึท ืฉื˜ื™ืง ืคื•ืŸ ืื•ื ื“ื–ืขืจ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ:

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

ื“ื™ ืœืึธื’ื™ืง ื“ืึธ ืื™ื– ื’ืึทื ืฅ ืคึผืฉื•ื˜: ืžื™ืจ ืคืึทืจื‘ื™ื ื“ืŸ ื’ืจื•ื™ืก ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทื ื– ืคื•ืŸ ื“ื™ ืคึผืจื•ื™ืขืงื˜ ื•ื•ืขื’ื•ื•ื™ื™ึทื–ืขืจ ืื•ืŸ ืคึผืึทื˜ืก ื“ื•ืจืš ื™ื ื•ื•ื™ื™ืจืึทื ืžืขื ืึทืœ ื•ื•ืขืจื™ืึทื‘ืึทืœื–, ืื•ืŸ ืงืœื™ื™ืŸ ืงืึทื ืคื™ื’ื™ืขืจ ืกืขืงืฉืึทื ื– ืคื•ืŸ ืงื•ื‘ืขืจ ืกื™ืงืจื™ืฅ, ืื•ืŸ ื“ืขืžืึธืœื˜ ืคึผืจื™ืคึผืจืึธืกืขืกืก ื–ื™ื™ ืึท ื‘ื™ืกืœ. ืคึผืœื•ืก ืขื˜ืœืขื›ืข ื•ื•ืขืจื™ืึทื‘ืึทืœื–. ืื™ืš ื˜ืึธืŸ ืึทื– ื•ื•ืขืŸ ืื™ืจ ื–ื•ื›ื˜ ืคึฟืึทืจ ื˜ืขืงืขืก ืคึฟื•ืŸ ืกื™ืงืจื™ืฅ, ืึท ื˜ื™ืฃ ื‘ืึทื’ืจืขื ืขืฆื•ื ื’ ืื™ื– ื’ืขื ื™ืฆื˜, ื•ื•ื™ื™ึทืœ K8s ืงืจื™ื™ื™ืฅ ืึท ืคืึทืจื‘ืึธืจื’ืŸ ื˜ืขืงืข ืื™ืŸ ื™ืขื“ืขืจ ืกื•ื“ ื•ื•ื• ื“ื™ ืกื™ืงืจื™ืฅ ื–ื™ืš ื–ืขื ืขืŸ ืกื˜ืึธืจื“, ืื•ืŸ ื ืึธืจ ืึท ืœื™ื ืง ืื™ื– ืœื™ื’ืŸ ืื•ื™ืฃ ืึท ื”ืขื›ืขืจ ืžื“ืจื’ื”.

ืื™ืš ื”ืึธืคึฟืŸ ื•ื•ืึธืก ืื™ื– ื“ื™ืกืงืจื™ื™ื‘ื“ ื•ื•ืขื˜ ื–ื™ื™ืŸ ื ื•ืฆื™ืง ืคึฟืึทืจ ืขืžืขืฆืขืจ :) ืงื™ื™ืŸ ื‘ืึทืžืขืจืงื•ื ื’ืขืŸ ืื•ืŸ ืจืขืงืึทืžืึทื ื“ื™ื™ืฉืึทื ื– ื•ื•ืขื’ืŸ ื–ื™ื›ืขืจื”ื™ื™ื˜ ืึธื“ืขืจ ืื ื“ืขืจืข ื’ืขื‘ื™ื˜ืŸ ืคึฟืึทืจ ืคึฟืึทืจื‘ืขืกืขืจื•ื ื’ ื–ืขื ืขืŸ ืื ื’ืขื ื•ืžืขืŸ. ื“ื™ ืžื™ื™ื ื•ื ื’ ืคื•ืŸ ื“ื™ ืงื”ืœ ืื™ื– ืื•ื™ืš ื˜ืฉื™ืงืึทื•ื•ืข, ืืคึฟืฉืจ ืขืก ืื™ื– ื•ื•ืขืจื˜ ืฆื• ืœื™ื™ื’ืŸ ืฉื˜ื™ืฆืŸ ืคึฟืึทืจ ConfigMaps (ืื•ื ื“ื–ืขืจ ืคึผืจื•ื™ืขืงื˜ ื˜ื•ื˜ ื ื™ืฉื˜ ื ื•ืฆืŸ ื–ื™ื™ ื ืึธืš) ืื•ืŸ ืืจื•ื™ืกื’ืขื‘ืŸ ื“ื™ ืงืึธื“ ืื•ื™ืฃ GitHub / PyPI? ืคึผืขืจืกื ืึทืœื™, ืื™ืš ื˜ืจืึทื›ื˜ืŸ ืึทื– ืึทื–ืึท ื˜ื™ื ื’ื– ื–ืขื ืขืŸ ืฆื• ื™ื ื“ื™ื•ื•ื™ื“ื–ืฉื•ืึทืœื™ ืคึฟืึทืจ ืคึผืจืึทื“ื–ืฉืขืงืก ืฆื• ื–ื™ื™ืŸ ื•ื ื™ื•ื•ืขืจืกืึทืœ, ืื•ืŸ ืึท ื‘ื™ืกืœ ืคึผื™ืงื™ื ื’ ืื•ื™ืฃ ืื ื“ืขืจืข ืžืขื ื˜ืฉืŸ ืก ื™ืžืคึผืœืึทืžืขื ื˜ื™ื™ืฉืึทืŸ, ื•ื•ื™ ื“ื™ ื“ืึธ, ืื•ืŸ ืึท ื“ื™ืกืงื•ืกื™ืข ืคื•ืŸ โ€‹โ€‹ื ื•ืึทื ืกื™ื–, ืขืฆื•ืช ืื•ืŸ ื‘ืขืกื˜ืขืจ ืคึผืจืึทืงื˜ื™ืกื™ื–, ื•ื•ืึธืก ืื™ืš ื”ืึธืคึฟืŸ ืฆื• ื–ืขืŸ ืื™ืŸ ื“ื™ ื‘ืึทืžืขืจืงื•ื ื’ืขืŸ , ืื™ื– ื’ืขื ื•ื’ ๐Ÿ˜‰

ื‘ืœื•ื™ื– ืจืขื’ื™ืกื˜ืจื™ืจื˜ ื ื™ืฆืขืจืก ืงืขื ืขืŸ ืึธื ื˜ื™ื™ืœ ื ืขืžืขืŸ ืื™ืŸ ื“ื™ ื™ื‘ืขืจื‘ืœื™ืง. ืกื™ื™ืŸ ืืจื™ื™ืŸื‘ื™ื˜ืข.

ื–ืึธืœ ืื™ืš ืึทืจื•ื™ืกื’ืขื‘ืŸ ื•ื•ื™ ืึท ืคึผืจื•ื™ืขืงื˜ / ื‘ื™ื‘ืœื™ืึธื˜ืขืง?

  • ืงืกื ื•ืžืงืก%ื™ืึธ, ืื™ืš ื•ื•ืึธืœื˜ ื ื•ืฆืŸ / contribution0

  • ืงืกื ื•ืžืงืก%ื™ืึธ, ื“ืึธืก ืกืึธื•ื ื“ืก ื’ืจื•ื™ืก 4

  • ืงืกื ื•ืžืงืก%ื ื™ื™ืŸ, ื•ื•ืขืจ ื“ืึทืจืฃ ื“ืึธืก ืึทืœื™ื™ืŸ ื˜ืึธืŸ ืื™ืŸ ื–ื™ื™ืขืจ ืื™ื™ื’ืŸ ืคึฟืึธืจืžืึทื˜ ืื•ืŸ ืฆื• ืคึผืึทืกืŸ ื–ื™ื™ืขืจ ื‘ืื“ืขืจืคืขื ื™ืฉืŸ5

  • ืงืกื ื•ืžืงืก%ืื™ืš ื•ื•ืขืœ ื–ื™ืš ืืคื”ื™ื˜ืŸ ืคื•ืŸ ืขื ื˜ืคืขืจืŸ 3

12 ื‘ืื ื•ืฆืขืจ ื”ืื‘ืŸ ื’ืขืฉื˜ื™ืžื˜. 3 ื‘ืื ื•ืฆืขืจ ื”ืื‘ืŸ ื–ื™ืš ืืคื’ืขื”ืืœื˜ืŸ.

ืžืงื•ืจ: www.habr.com

ืœื™ื™ื’ืŸ ืึท ื‘ืึทืžืขืจืงื•ื ื’