αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‚αž˜αŸ’αžšαŸ„αž„αžαžΆαž„αž€αŸ’αž“αž»αž„ αž“αž·αž„αžαžΆαž„αž€αŸ’αžšαŸ… Kubernetes

αžαŸ’αž˜αžΈαŸ—αž“αŸαŸ‡αžαŸ’αž‰αž»αŸ†αž”αžΆαž“αžŸαžšαžŸαŸαžš αž†αŸ’αž›αžΎαž™αž’αŸ†αž–αžΈαž‡αžΈαžœαž·αžαž‚αž˜αŸ’αžšαŸ„αž„αž“αŸ…αž€αŸ’αž“αž»αž„ Docker αž“αž·αž„αž€αžΆαžšαž”αŸ†αž”αžΆαžαŸ‹αž€αŸ†αž αž»αžŸαž“αŸ…αžαžΆαž„αž€αŸ’αžšαŸ…αžœαžΆαŸ”αžŠαŸ‚αž›αž‡αžΆαž€αž“αŸ’αž›αŸ‚αž„αžŠαŸ‚αž›αž‚αžΆαžαŸ‹αž”αžΆαž“αž“αž·αž™αžΆαž™αž™αŸ‰αžΆαž„αžαŸ’αž›αžΈαžαžΆ αž’αŸ’αž“αž€αž’αžΆαž…αž”αž„αŸ’αž€αžΎαžαž”αŸ’αžšαž–αŸαž“αŸ’αž’αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž•αŸ’αž‘αžΆαž›αŸ‹αžαŸ’αž›αž½αž“αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αžŠαžΎαž˜αŸ’αž”αžΈαž±αŸ’αž™αžŸαŸαžœαžΆαž€αž˜αŸ’αž˜αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αžΆαž“αž›αŸ’αž’αž“αŸ…αž€αŸ’αž“αž»αž„ Kuber αž‘αžΆαž‰αž’αžΆαžαŸŒαž€αŸ†αž”αžΆαŸ†αž„ αž“αž·αž„αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž™αŸ‰αžΆαž„αž„αžΆαž™αžŸαŸ’αžšαž½αž›αž€αŸ’αž“αž»αž„αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“ αžŸαžΌαž˜αŸ’αž”αžΈαžαŸ‚αž“αŸ…αžαžΆαž„αž€αŸ’αžšαŸ… Docker αž€αŸαžŠαŸ„αž™αŸ” αž‚αŸ’αž˜αžΆαž“αž’αŸ’αžœαžΈαžŸαŸ’αž˜αž»αž‚αžŸαŸ’αž˜αžΆαž‰αž‘αŸ αž”αŸ‰αž»αž“αŸ’αžαŸ‚ "αžšαžΌαž”αž˜αž“αŸ’αž" αžŠαŸ‚αž›αž”αžΆαž“αž–αž·αž–αžŽαŸŒαž“αžΆαž’αžΆαž…αž˜αžΆαž“αž”αŸ’αžšαž™αŸ„αž‡αž“αŸαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž“αžšαžŽαžΆαž˜αŸ’αž“αžΆαž€αŸ‹ :) αž€αžΌαžŠαž‚αžΊαž“αŸ…αž€αŸ’αž“αž»αž„ Python αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžαž€αŸ’αž€αžœαž·αž‡αŸ’αž‡αžΆαž˜αž·αž“αž‡αžΆαž”αŸ‹αž“αžΉαž„αž—αžΆαžŸαžΆαž‘αŸαŸ”

αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‚αž˜αŸ’αžšαŸ„αž„αžαžΆαž„αž€αŸ’αž“αž»αž„ αž“αž·αž„αžαžΆαž„αž€αŸ’αžšαŸ… Kubernetes

αžŸαžΆαžœαžαžΆαž“αŸƒαžŸαŸ†αžŽαž½αžšαž‚αžΊαž“αŸαŸ‡αŸ– αž™αžΌαžšαŸ—αž˜αŸ’αžαž„αž˜αžΆαž“αž‚αž˜αŸ’αžšαŸ„αž„αž˜αž½αž™ αžŠαŸ‚αž›αžŠαŸ†αž”αžΌαž„αž‘αžΎαž™αžœαžΆαž‡αžΆ monolith αžαžΌαž…αž˜αž½αž™αžŠαŸ‚αž›αž˜αžΆαž“αž§αž”αž€αžšαžŽαŸαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹ αž“αž·αž„αžŸαŸ’αž‚αŸ’αžšαžΈαž” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž™αžΌαžšαŸ—αž‘αŸ…αžœαžΆαž”αžΆαž“αžšαžΈαž€αž’αŸ†αž‘αžΎαž„ αž”αŸ‚αž„αž…αŸ‚αž€αž‡αžΆαžŸαŸαžœαžΆαž€αž˜αŸ’αž˜ αžŠαŸ‚αž›αž“αŸ…αž€αŸ’αž“αž»αž„αžœαŸαž“αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αž”αŸ‚αž„αž…αŸ‚αž€αž‘αŸ…αž‡αžΆ microservices αž“αž·αž„ αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž–αž„αŸ’αžšαžΈαž€αŸ” αžŠαŸ†αž”αžΌαž„ αž’αŸ’αžœαžΈαŸ—αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž“αŸαŸ‡αžαŸ’αžšαžΌαžœαž”αžΆαž“αž’αŸ’αžœαžΎαž“αŸ…αž›αžΎ VPS αž‘αž‘αŸ αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž“αŸƒαž€αžΆαžšαžŠαŸ†αž‘αžΎαž„ αž“αž·αž„αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™αž€αžΌαžŠαžŠαŸ‚αž›αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αžŠαŸ„αž™αž”αŸ’αžšαžΎ Ansible αž αžΎαž™αžŸαŸαžœαžΆαž€αž˜αŸ’αž˜αž“αžΈαž˜αž½αž™αŸ—αžαŸ’αžšαžΌαžœαž”αžΆαž“αž…αž„αž€αŸ’αžšαž„αž‡αžΆαž˜αž½αž™αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’ YAML αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹ αž“αž·αž„αžŸαŸ„αž…αžΆαŸ†αž”αžΆαž…αŸ‹ αž αžΎαž™αž―αž€αžŸαžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžŸαŸ’αžšαžŠαŸ€αž„αž‚αŸ’αž“αžΆαž“αŸαŸ‡αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎαžŸαž˜αŸ’αžšαžΆαž”αŸ‹ αž€αžΆαžšαž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αŸ’αž“αž»αž„αžŸαŸ’αžšαž»αž€ αžŠαŸ‚αž›αž„αžΆαž™αžŸαŸ’αžšαž½αž›αžŽαžΆαžŸαŸ‹ αž–αžΈαž–αŸ’αžšαŸ„αŸ‡ .k αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž“αŸαŸ‡αžαŸ’αžšαžΌαžœαž”αžΆαž“αž•αŸ’αž‘αž»αž€αž‘αŸ…αž€αŸ’αž“αž»αž„αžœαžαŸ’αžαž»αžŸαž€αž› αžŠαŸ‚αž›αž’αžΆαž…αž…αžΌαž›αž”αŸ’αžšαžΎαž”αžΆαž“αž–αžΈαž‚αŸ’αžšαž”αŸ‹αž‘αžΈαž€αž“αŸ’αž›αŸ‚αž„αž€αŸ’αž“αž»αž„αž‚αž˜αŸ’αžšαŸ„αž„αŸ”

αž‘αŸ„αŸ‡αž‡αžΆαž™αŸ‰αžΆαž„αžŽαžΆαž€αŸαžŠαŸ„αž™ αž€αžΆαžšαž€αžΎαž“αž‘αžΎαž„αž“αŸƒαž…αŸ†αž“αž½αž“αžŸαŸαžœαžΆαž˜αžΈαž€αŸ’αžšαžΌ αž€αžΆαžšαžαž—αŸ’αž‡αžΆαž”αŸ‹αžšαž”αžŸαŸ‹αž–αž½αž€αž‚αŸ αž“αž·αž„ αžαž˜αŸ’αžšαžΌαžœαž€αžΆαžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž€αžΆαž”αŸ‹αžˆαžΎ αž“αž·αž„αž€αžΆαžšαžαŸ’αžšαž½αžαž–αž·αž“αž·αžαŸ’αž™αž€αžŽαŸ’αžαžΆαž›αž”αžΆαž“αž”αž„αŸ’αž αžΆαž‰αž–αžΈαž€αžΆαžšαž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαž‘αŸ…αž€αžΆαž“αŸ‹ Kuber αžŠαŸ‚αž›αž€αŸ†αž–αž»αž„αžαŸ‚αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž“αŸ…αž‘αžΎαž™αŸ” αžšαž½αž˜αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž‡αŸ†αž“αž½αž™αž€αŸ’αž“αž»αž„αž€αžΆαžšαžŠαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž”αž‰αŸ’αž αžΆαžŠαŸ‚αž›αž”αžΆαž“αž›αžΎαž€αž‘αžΎαž„ Kubernetes αž•αŸ’αžαž›αŸ‹αž“αžΌαžœαžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžšαŸ’αžαžšαž”αžŸαŸ‹αžαŸ’αž›αž½αž“αž…αŸ†αž–αŸ„αŸ‡αž€αžΆαžšαž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’ αžšαž½αž˜αž‘αžΆαŸ†αž„ αž’αŸ’αžœαžΈαžŠαŸ‚αž›αž‚αŸαž αŸ…αžαžΆαž’αžΆαžαŸŒαž€αŸ†αž”αžΆαŸ†αž„ ΠΈ αžœαž·αž’αžΈαž’αŸ’αžœαžΎαž€αžΆαžšαž‡αžΆαž˜αž½αž™αž–αž½αž€αž‚αŸαŸ”. αž™αž“αŸ’αžαž€αžΆαžšβ€‹αž“αŸαŸ‡β€‹αž˜αžΆαž“β€‹αžŸαŸ’αžαž„αŸ‹αžŠαžΆαžš αž“αž·αž„β€‹αž’αžΆαž…β€‹αž‘αž»αž€β€‹αž…αž·αžαŸ’αžβ€‹αž”αžΆαž“ αžŠαžΌαž…αŸ’αž“αŸαŸ‡β€‹αžœαžΆβ€‹αž‡αžΆβ€‹αž’αŸ†αž–αžΎβ€‹αž”αžΆαž”β€‹αžŠαŸ‚αž›β€‹αž˜αž·αž“β€‹αžαŸ’αžšαžΌαžœβ€‹αž”αŸ’αžšαžΎβ€‹αžœαžΆ! αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž“αŸ…αž–αŸαž›αž‡αžΆαž˜αž½αž™αž‚αŸ’αž“αžΆαž“αŸαŸ‡ αžαŸ’αž‰αž»αŸ†αž…αž„αŸ‹αžšαž€αŸ’αžŸαžΆαž‘αž˜αŸ’αžšαž„αŸ‹αž”αž…αŸ’αž…αž»αž”αŸ’αž”αž“αŸ’αž“αžšαž”αžŸαŸ‹αžαŸ’αž‰αž»αŸ†αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž’αŸ’αžœαžΎαž€αžΆαžšαž‡αžΆαž˜αž½αž™αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αŸ– αž‘αžΈαž˜αž½αž™ αž”αŸ’αžšαžΎαžœαžΆαž±αŸ’αž™αžŸαŸ’αž˜αžΎαž—αžΆαž–αž‚αŸ’αž“αžΆαž€αŸ’αž“αž»αž„αžŸαŸαžœαžΆαž€αž˜αŸ’αž˜αž˜αžΈαž€αŸ’αžšαžΌαž•αŸ’αžŸαŸαž„αŸ—αž“αŸƒαž‚αž˜αŸ’αžšαŸ„αž„ αž“αž·αž„αž‘αžΈαž–αžΈαžš αžŠαžΎαž˜αŸ’αž”αžΈαž’αžΆαž…αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αžΌαžŠαž“αŸ…αž›αžΎαž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αžŠαŸ„αž™αž”αŸ’αžšαžΎαžŸαžΆαž˜αž‰αŸ’αž‰αž˜αž½αž™αŸ” αž―αž€αžŸαžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αŸ”

αž€αŸ’αž“αž»αž„αž“αŸαž™αž“αŸαŸ‡ αž™αž“αŸ’αžαž€αžΆαžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαžŸαžΆαž„αžŸαž„αŸ‹αžœαžαŸ’αžαž»αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžαŸ’αžšαžΌαžœαž”αžΆαž“αž€αŸ‚αž”αŸ’αžšαŸ‚ αžŠαžΎαž˜αŸ’αž”αžΈαž’αžΆαž…αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž‘αžΆαŸ†αž„αž‡αžΆαž˜αž½αž™αž―αž€αžŸαžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž”αž»αžšαžΆαžŽαžšαž”αžŸαŸ‹αž™αžΎαž„ αž“αž·αž„αžŠαŸ„αž™αž’αžΆαžαŸŒαž€αŸ†αž”αžΆαŸ†αž„αž–αžΈ Kuber αŸ” αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžšαžΉαž„αž‡αžΆαž„αž“αŸαŸ‡αž€αŸαžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž•αž„αžŠαŸ‚αžš αž‡αžΆαž—αžΆαžŸαžΆαžšαž”αžŸαŸ‹ Python αž‘αžΈαž”αžΈαžŠαžΌαž…αžαžΆαž„αž€αŸ’αžšαŸ„αž˜αŸ–

Dict[str, Dict[str, Union[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αžŠαŸ„αž™αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž•αž„αžŠαŸ‚αžšαž“αžΌαžœαžˆαŸ’αž˜αŸ„αŸ‡αž―αž€αžŸαžΆαžšαžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαžšαž€αŸ’αžŸαžΆαž‘αž»αž€ - αž”αŸ‰αžΆαžšαŸ‰αžΆαž˜αŸ‰αŸ‚αžαŸ’αžšαž‘αžΆαŸ†αž„αž“αŸαŸ‡αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‘αž‘αž½αž›αžŸαŸ’αž‚αžΆαž›αŸ‹ αž“αž·αž„αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž™αŸ‰αžΆαž„αžαŸ’αžšαžΉαž˜αžαŸ’αžšαžΌαžœ αžŠαŸ‚αž›αž’αŸ’αžœαžΎαž±αŸ’αž™αžœαžΆαž„αžΆαž™αžŸαŸ’αžšαž½αž›αž€αŸ’αž“αž»αž„αž€αžΆαžšαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αžΌαžŠαž€αŸ’αž“αž»αž„αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž€αŸ‚αž€αŸ†αž αž»αžŸ αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαž―αž€αžαžΆ αž“αž·αž„αžαž˜αŸ’αžšαžΌαžœαž€αžΆαžšαž•αŸ’αžŸαŸαž„αŸ—αž‘αŸ€αžαŸ” αž“αŸαŸ‡αž˜αžΆαž“αžŸαžΆαžšαŸˆαžŸαŸ†αžαžΆαž“αŸ‹αž‡αžΆαž–αž·αžŸαŸαžŸαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž™αžΎαž„ αž–αžΈαž–αŸ’αžšαŸ„αŸ‡αž˜αžΆαž“αžαž˜αŸ’αžšαžΌαžœαž€αžΆαžšαž‡αžΆαž…αŸ’αžšαžΎαž“αž‘αŸ€αž - αž•αŸ’αž“αŸ‚αž€αž“αŸƒαž€αžΌαžŠαžšαž”αžŸαŸ‹αž™αžΎαž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αž˜αŸ’αžšαž»αž„αž‘αž»αž€αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž‚αžŽαž“αžΆαžœαž·αž—αžΆαž‚αž•αŸ’αžŸαŸαž„αŸ— αžœαžΆαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž˜αž·αž“αžαŸ’αžšαžΉαž˜αžαŸ‚αž›αžΎαž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸαžŠαŸ‚αž›αž˜αžΆαž“αž€αžΆαžš orchestration αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αž‘αŸ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž€αŸαž˜αžΆαž“αžŸαŸ’αž‚αŸ’αžšαžΈαž”αž•αŸ’αžŸαŸαž„αŸ— αž“αž·αž„αž“αŸ…αž›αžΎαž€αž»αŸ†αž–αŸ’αž™αžΌαž‘αŸαžšαžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αžœαž·αž—αžΆαž‚αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž€αžΆαžšαž’αŸ’αžœαžΎαž€αžΆαžšαžαžΆαž˜αžšαž™αŸˆ αž“αž·αž„αž”αŸ†αž”αžΆαžαŸ‹αž€αŸ†αž αž»αžŸαž”αŸ†αž–αž„αŸ‹αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž‘αž·αž“αŸ’αž“αž“αŸαž™αžŸαŸ’αž˜αž»αž‚αŸ’αžšαžŸαŸ’αž˜αžΆαž‰αžŠαŸ„αž™αž˜αž·αž“αž”αžΆαžšαž˜αŸ’αž—αž–αžΈαž”αž‰αŸ’αž αžΆαž•αŸ’αž“αŸ‚αž€αžαžΆαž„αž€αŸ’αžšαŸ„αž™αŸ” αž“αž·αž™αžΆαž™αž’αž‰αŸ’αž…αžΉαž„ αžœαžΆαž“αžΉαž„αž˜αž·αž“αžˆαžΊαž…αžΆαž”αŸ‹αž‘αŸαž€αŸ’αž“αž»αž„αž€αžΆαžšαž…αŸ‚αž€αžšαŸ†αž›αŸ‚αž€αžαžΆαž§αž”αž€αžšαžŽαŸαžŸαŸ†αžαžΆαž“αŸ‹αŸ—αžšαž”αžŸαŸ‹αž™αžΎαž„ αžšαž½αž˜αž‘αžΆαŸ†αž„αž€αžΌαžŠαž”αŸ’αž›αž„αŸ‹αž€αŸ†αžŽαžαŸ‹αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŠαŸ†αž‘αžΎαž„αžαžΆαž˜αžšαž™αŸˆ setup.py - αžšαž½αž˜αž‚αŸ’αž“αžΆαž“αŸαŸ‡αž”αž„αŸ’αžšαž½αž”αž”αž„αŸ’αžšαž½αž˜αž›αŸαžαž€αžΌαžŠαžšαž”αžŸαŸ‹αž™αžΎαž„αž‘αŸ…αž‡αžΆαž”αŸ’αžšαž–αŸαž“αŸ’αž’αž’αŸαž€αžΌαž‘αžΌαžŸαŸŠαžΈαžαŸ‚αž˜αž½αž™ αž―αž€αžšαžΆαž‡αŸ’αž™αž“αŸƒαžœαŸαž‘αž·αž€αžΆ αž“αž·αž„αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžšαŸ’αžαž“αŸƒαž€αžΆαžšαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αŸ”

αž€αžΆαžšαž–αžŽαŸŒαž“αžΆαžšαž”αžŸαŸ‹ Kubernetes pod αž˜αžΎαž›αž‘αŸ…αžŠαžΌαž…αž“αŸαŸ‡αŸ–

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

αž αžΎαž™αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αŸ’αž“αž»αž„αžαŸ†αž”αž“αŸ‹ αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎ αžŠαŸ‚αž›αž˜αžΆαž“αž‘αžΈαžαžΆαŸ†αž„αž“αŸ…αž€αŸ’αž“αž»αž„αžαžαž«αžŸαž“αŸƒαž‚αž˜αŸ’αžšαŸ„αž„ αž¬αžαžΆαž˜αž•αŸ’αž›αžΌαžœαžŠαŸ‚αž›αž”αžΆαž“αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αž’αžαŸαžšαž”αžšαž·αžŸαŸ’αžαžΆαž“αŸ” αž›αŸαžαž€αžΌαžŠαžŠαŸ‚αž›αž‘αž‘αž½αž›αžαž»αžŸαžαŸ’αžšαžΌαžœαž…αŸ†αž–αŸ„αŸ‡αž—αžΆαž–αž„αžΆαž™αžŸαŸ’αžšαž½αž›αž‘αžΆαŸ†αž„αž“αŸαŸ‡αž’αžΆαž…αž˜αžΎαž›αžƒαžΎαž‰αž“αŸ…αž€αŸ’αž“αž»αž„ 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()

αžαž€αŸ’αž€αžœαž·αž‡αŸ’αž‡αžΆαž“αŸ…αž‘αžΈαž“αŸαŸ‡αž‚αžΊαžŸαžΆαž˜αž‰αŸ’αž‰αžŽαžΆαžŸαŸ‹αŸ– αž™αžΎαž„αžšαž½αž˜αž”αž‰αŸ’αž…αžΌαž›αž‚αŸ’αž“αžΆαž“αžΌαžœαž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž’αŸ†αŸ—αž–αžΈαžαžαž‚αž˜αŸ’αžšαŸ„αž„ αž“αž·αž„αž•αŸ’αž›αžΌαžœαžŠαŸ„αž™αž’αžαŸαžšαž”αžšαž·αžŸαŸ’αžαžΆαž“ αž“αž·αž„αž•αŸ’αž“αŸ‚αž€αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžαžΌαž…αŸ—αž–αžΈ Kuber secrets αž αžΎαž™αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž–αž½αž€αžœαžΆαž‡αžΆαž˜αž»αž“αž”αž“αŸ’αžαž·αž…αŸ” αž”αžΌαž€αž’αžαŸαžšαž˜αž½αž™αž…αŸ†αž“αž½αž“αŸ” αžαŸ’αž‰αž»αŸ†αž€αžαŸ‹αžŸαž˜αŸ’αž‚αžΆαž›αŸ‹αžαžΆαž“αŸ…αž–αŸαž›αžŸαŸ’αžœαŸ‚αž„αžšαž€αž―αž€αžŸαžΆαžšαž–αžΈαž’αžΆαžαŸŒαž€αŸ†αž”αžΆαŸ†αž„ αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž‡αž˜αŸ’αžšαŸ…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎ αž–αžΈαž–αŸ’αžšαŸ„αŸ‡ K8s αž”αž„αŸ’αž€αžΎαžαžαžαžŠαŸ‚αž›αž›αžΆαž€αŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αž’αžΆαžαŸŒαž€αŸ†αž”αžΆαŸ†αž„αž“αžΈαž˜αž½αž™αŸ— αžŠαŸ‚αž›αž’αžΆαžαŸŒαž€αŸ†αž”αžΆαŸ†αž„αžαŸ’αž›αž½αž“αž―αž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αžšαž€αŸ’αžŸαžΆαž‘αž»αž€ αž αžΎαž™αž‚αŸ’αžšαžΆαž“αŸ‹αžαŸ‚αžαŸ†αžŽαž˜αž½αž™αžŸαŸ’αžαž·αžαž“αŸ…αž€αž˜αŸ’αžšαž·αžαžαŸ’αž–αžŸαŸ‹αž‡αžΆαž„αŸ”

αžαŸ’αž‰αž»αŸ†αžŸαž„αŸ’αžƒαžΉαž˜αžαžΆαž’αŸ’αžœαžΈαžŠαŸ‚αž›αž”αžΆαž“αž–αž·αž–αžŽαŸŒαž“αžΆαž“αžΉαž„αž˜αžΆαž“αž”αŸ’αžšαž™αŸ„αž‡αž“αŸαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž“αžšαžŽαžΆαž˜αŸ’αž“αžΆαž€αŸ‹ :) αžšαžΆαž›αŸ‹αž˜αžαž·αž™αŸ„αž”αž›αŸ‹ αž“αž·αž„αž’αž“αž»αžŸαžΆαžŸαž“αŸαž‘αžΆαž€αŸ‹αž‘αž„αž“αžΉαž„αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž– αž¬αž•αŸ’αž“αŸ‚αž€αž•αŸ’αžŸαŸαž„αž‘αŸ€αžαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž€αŸ‚αž›αž˜αŸ’αž’αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‘αž‘αž½αž›αž™αž€αŸ” αž˜αžαž·αžšαž”αžŸαŸ‹αžŸαž αž‚αž˜αž“αŸαž€αŸαž‚αž½αžšαž±αŸ’αž™αž…αžΆαž”αŸ‹αž’αžΆαžšαž˜αŸ’αž˜αžŽαŸαž•αž„αžŠαŸ‚αžš αž”αŸ’αžšαž αŸ‚αž›αž‡αžΆαžœαžΆαž˜αžΆαž“αžαž˜αŸ’αž›αŸƒαž”αž“αŸ’αžαŸ‚αž˜αž€αžΆαžšαž‚αžΆαŸ†αž‘αŸ’αžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹ ConfigMaps (αž‚αž˜αŸ’αžšαŸ„αž„αžšαž”αžŸαŸ‹αž™αžΎαž„αž˜αž·αž“αž‘αžΆαž“αŸ‹αž”αŸ’αžšαžΎαž–αž½αž€αžœαžΆαž‘αŸ) αž“αž·αž„αž€αžΆαžšαž”αŸ„αŸ‡αž–αž»αž˜αŸ’αž–αž€αžΌαžŠαž“αŸ…αž›αžΎ GitHub / PyPI? αžŠαŸ„αž™αž•αŸ’αž‘αžΆαž›αŸ‹ αžαŸ’αž‰αž»αŸ†αž‚αž·αžαžαžΆαžšαžΏαž„αž”αŸ‚αž”αž“αŸαŸ‡αž˜αžΆαž“αž›αž€αŸ’αžαžŽαŸˆαž”αž»αž‚αŸ’αž‚αž›αž–αŸαž€αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‚αž˜αŸ’αžšαŸ„αž„αž‡αžΆαžŸαž€αž› αž αžΎαž™αž€αžΆαžšαžŸαž˜αŸ’αž›αžΉαž„αž˜αžΎαž›αž€αžΆαžšαž’αž“αž»αžœαžαŸ’αžαžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αžŠαŸαž‘αŸƒαž”αž“αŸ’αžαž·αž… αžŠαžΌαž…αž‡αžΆαž’αŸ’αžœαžΈαžŠαŸ‚αž›αž”αžΆαž“αž•αŸ’αžαž›αŸ‹αž±αŸ’αž™αž“αŸ…αž‘αžΈαž“αŸαŸ‡ αž“αž·αž„αž€αžΆαžšαž–αž·αž—αžΆαž€αŸ’αžŸαžΆαž’αŸ†αž–αžΈαž—αžΆαž–αžαž»αžŸαž‚αŸ’αž“αžΆ αž‚αž“αŸ’αž›αžΉαŸ‡ αž“αž·αž„αž€αžΆαžšαž’αž“αž»αžœαžαŸ’αžαž›αŸ’αž’αž”αŸ†αž•αž»αž αžŠαŸ‚αž›αžαŸ’αž‰αž»αŸ†αžŸαž„αŸ’αžƒαžΉαž˜αžαžΆαž“αžΉαž„αžƒαžΎαž‰αž“αŸ…αž€αŸ’αž“αž»αž„αž˜αžαž·αž™αŸ„αž”αž›αŸ‹ αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαžΆαž“αŸ‹αž αžΎαž™ πŸ˜‰

αž˜αžΆαž“αžαŸ‚αž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αžŠαŸ‚αž›αž”αžΆαž“αž…αž»αŸ‡αžˆαŸ’αž˜αŸ„αŸ‡αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αžŠαŸ‚αž›αž’αžΆαž…αž…αžΌαž›αžšαž½αž˜αž€αŸ’αž“αž»αž„αž€αžΆαžšαžŸαŸ’αž‘αž„αŸ‹αž˜αžαž·αž“αŸαŸ‡αŸ” αž…αžΌαž›αžŸαžΌαž˜αŸ”

αžαžΎαžαŸ’αž‰αž»αŸ†αž‚αž½αžšαž”αŸ„αŸ‡αž–αž»αž˜αŸ’αž–αž‡αžΆαž‚αž˜αŸ’αžšαŸ„αž„/αž”αžŽαŸ’αžŽαžΆαž›αŸαž™αž‘αŸ?

  • 0,0%αž”αžΆαž‘/αž…αžΆαžŸ αžαŸ’αž‰αž»αŸ†αž“αžΉαž„αž”αŸ’αžšαžΎ /contribution0

  • 33,3%αž”αžΆαž‘ αžŸαŸ’αžαžΆαž”αŸ‹αž‘αŸ…αž›αŸ’αž’αžŽαžΆαžŸαŸ‹ ៀ

  • 41,7%αž‘αŸ αž’αŸ’αž“αž€αžŽαžΆαžαŸ’αžšαžΌαžœαž€αžΆαžšαž’αŸ’αžœαžΎαžœαžΆαžŠαŸ„αž™αžαŸ’αž›αž½αž“αž―αž„αžαžΆαž˜αž‘αž˜αŸ’αžšαž„αŸ‹αžšαž”αžŸαŸ‹αž–αž½αž€αž‚αŸ αž“αž·αž„αžŸαž˜αžŸαŸ’αžšαž”αžαžΆαž˜αžαž˜αŸ’αžšαžΌαžœαž€αžΆαžšαžšαž”αžŸαŸ‹αž–αž½αž€αž‚αŸ αŸ₯

  • 25,0%αžαŸ’αž‰αž»αŸ†αž“αžΉαž„αž”αžŠαž·αžŸαŸαž’αž˜αž·αž“αž†αŸ’αž›αžΎαž™ ៣

αž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹ 12 αž“αžΆαž€αŸ‹αž”αžΆαž“αž”αŸ„αŸ‡αž†αŸ’αž“αŸ„αžαŸ” αž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹ ៦៣ αž“αžΆαž€αŸ‹αžαŸ’αžšαžΌαžœαž”αžΆαž“αž αžΆαž˜αžƒαžΆαžαŸ‹αŸ”

αž”αŸ’αžšαž—αž–: www.habr.com

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹