{"id":36331,"date":"2019-10-31T22:10:58","date_gmt":"2019-10-31T19:10:58","guid":{"rendered":"https:\/\/prohoster.info\/blog\/kubernetes-operator-na-python-bez-frejmvorkov-i-sdk\/"},"modified":"2019-10-31T22:10:58","modified_gmt":"2019-10-31T19:10:58","slug":"kubernetes-operator-na-python-bez-frejmvorkov-i-sdk","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kubernetes-operator-na-python-bez-frejmvorkov-i-sdk","title":{"rendered":"Kubernetes-Operator auf Python ohne Frameworks und SDK","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Kubernetes Operator \u043d\u0430 Python \u0431\u0435\u0437 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0438 SDK\" src=\"\/wp-content\/uploads\/2019\/07\/da979d1b8a5908d341b420c209178487.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nGo \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u043e\u043d\u043e\u043f\u043e\u043b\u0438\u0441\u0442\u043e\u043c \u0441\u0440\u0435\u0434\u0438 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u044e\u0434\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f Kubernetes. \u0422\u043e\u043c\u0443 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044b, \u043a\u0430\u043a:<\/p>\n<ol>\n<li> \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043e\u0449\u043d\u0435\u0439\u0448\u0438\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0430 Go \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/operator-framework\/operator-sdk\">Operator SDK<\/a><\/noindex>.<\/li>\n<li> \u041d\u0430 Go \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u0430\u043a\u0438\u0435 \u00ab\u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0432\u0448\u0438\u0435 \u0438\u0433\u0440\u0443\u00bb \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u0430\u043a Docker \u0438 Kubernetes. \u041f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0430 Go \u2014 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0441 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u044f\u0437\u044b\u043a\u0435.<\/li>\n<li> \u0412\u044b\u0441\u043e\u043a\u0430\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 Go \u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 concurrency \u00ab\u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438\u00bb.<\/li>\n<\/ol>\n<p>\n<i><b>NB<\/b>: \u041a\u0441\u0442\u0430\u0442\u0438, \u043a\u0430\u043a \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0430 Go, \u043c\u044b <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/337698\/\">\u0443\u0436\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0438<\/a><\/noindex> \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043d\u0430\u0448\u0438\u0445 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u043e\u0432 \u0437\u0430\u0440\u0443\u0431\u0435\u0436\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u0440\u043e\u0432.<\/i><\/p>\n<p>\u041d\u043e \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u0438\u0437\u0443\u0447\u0430\u0442\u044c Go \u0432\u0430\u043c \u043c\u0435\u0448\u0430\u0435\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438\u043b\u0438, \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e, \u043c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u0438? \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043e\u0431\u0440\u043e\u0442\u043d\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u043d\u0430\u0435\u0442 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 DevOps-\u0438\u043d\u0436\u0435\u043d\u0435\u0440, \u2014 <b>Python<\/b>.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>\u0412\u0441\u0442\u0440\u0435\u0447\u0430\u0439\u0442\u0435: \u041a\u043e\u043f\u0438\u0440\u0430\u0442\u043e\u0440 \u2014 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440!<\/h2>\n<p>\n\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u043b\u044f \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f ConfigMap \u043b\u0438\u0431\u043e \u043f\u0440\u0438 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e namespace, \u043b\u0438\u0431\u043e \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439: ConfigMap \u0438 Secret. \u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u0435\u043d \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043f\u0443\u0442\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f ConfigMap) \u0438\u043b\u0438 \u0436\u0435 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043b\u044e\u0447\u0435\u0439 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Docker Registry (\u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 Secret&#8217;\u0430 \u0432 namespace). <\/p>\n<p>\u0418\u0442\u0430\u043a, <b>\u0447\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0443 \u0445\u043e\u0440\u043e\u0448\u0435\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430<\/b>:<\/p>\n<ol>\n<li> \u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u043c \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/access-kubernetes-api\/custom-resources\/custom-resource-definitions\/\">Custom Resource Definitions<\/a><\/noindex> (\u0434\u0430\u043b\u0435\u0435 \u2014 CRD).<\/li>\n<li> \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c\u0441\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u043b\u0430\u0433\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f.<\/li>\n<li> \u0421\u0431\u043e\u0440\u043a\u0430 Docker-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0438 Helm-\u0447\u0430\u0440\u0442\u0430 \u043f\u0440\u043e\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u043b\u0438 \u043b\u0435\u0433\u043a\u043e (\u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439) \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0432 \u0441\u0432\u043e\u0439 Kubernetes-\u043a\u043b\u0430\u0441\u0442\u0435\u0440.<\/li>\n<\/ol>\n<p><\/p>\n<h2>CRD<\/h2>\n<p>\n\u0427\u0442\u043e\u0431\u044b \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0437\u043d\u0430\u043b, \u043a\u0430\u043a\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0438 \u0433\u0434\u0435 \u0435\u043c\u0443 \u0438\u0441\u043a\u0430\u0442\u044c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e. \u041a\u0430\u0436\u0434\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u0432\u0438\u0434\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 CRD. \u041a\u0430\u043a\u0438\u0435 \u043f\u043e\u043b\u044f \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0443 \u044d\u0442\u043e\u0433\u043e CRD?<\/p>\n<ol>\n<li> <b>\u0422\u0438\u043f \u0440\u0435\u0441\u0443\u0440\u0441\u0430<\/b>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c (ConfigMap \u0438\u043b\u0438 Secret).<\/li>\n<li> <b>\u0421\u043f\u0438\u0441\u043e\u043a namespace&#8217;\u043e\u0432<\/b>, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u044b.<\/li>\n<li> <b>Selector<\/b>, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0432 namespace&#8217;\u0435.<\/li>\n<\/ol>\n<p>\n\u041e\u043f\u0438\u0448\u0435\u043c CRD:<\/p>\n<pre><code class=\"plaintext\">apiVersion: apiextensions.k8s.io\/v1beta1\nkind: CustomResourceDefinition\nmetadata:\n  name: copyrator.flant.com\nspec:\n  group: flant.com\n  versions:\n  - name: v1\n    served: true\n    storage: true\n  scope: Namespaced\n  names:\n    plural: copyrators\n    singular: copyrator\n    kind: CopyratorRule\n    shortNames:\n    - copyr\n  validation:\n    openAPIV3Schema:\n      type: object\n      properties:\n        ruleType:\n          type: string\n        namespaces:\n          type: array\n          items:\n            type: string\n        selector:\n          type: string<\/code><\/pre>\n<p>\n\u0418 \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <b>\u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e<\/b> \u2014 \u043d\u0430 \u043f\u043e\u0438\u0441\u043a \u0432 namespace&#8217;\u0435 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c <code>default<\/code> \u0432\u0441\u0435\u0445 ConfigMap c label&#8217;\u0430\u043c\u0438 \u0432\u0438\u0434\u0430 <code>copyrator: \"true\"<\/code>:<\/p>\n<pre><code class=\"plaintext\">apiVersion: flant.com\/v1\nkind: CopyratorRule\nmetadata:\n  name: main-rule\n  labels:\n    module: copyrator\nruleType: configmap\nselector:\n  copyrator: \"true\"\nnamespace: default<\/code><\/pre>\n<p>\n\u0413\u043e\u0442\u043e\u0432\u043e! \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0435. \u0421\u0440\u0430\u0437\u0443 \u043e\u0433\u043e\u0432\u043e\u0440\u044e\u0441\u044c, \u0447\u0442\u043e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a API Server \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0433\u043e\u0442\u043e\u0432\u043e\u0439 Python-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kubernetes-client\/python\">kubernetes-client<\/a><\/noindex>:<\/p>\n<pre><code class=\"python\">import kubernetes\nfrom contextlib import suppress\n\n\nCRD_GROUP = 'flant.com'\nCRD_VERSION = 'v1'\nCRD_PLURAL = 'copyrators'\n\n\ndef load_crd(namespace, name):\n    client = kubernetes.client.ApiClient()\n    custom_api = kubernetes.client.CustomObjectsApi(client)\n\n    with suppress(kubernetes.client.api_client.ApiException):\n        crd = custom_api.get_namespaced_custom_object(\n            CRD_GROUP,\n            CRD_VERSION,\n            namespace,\n            CRD_PLURAL,\n            name,\n        )\n    return {x: crd[x] for x in ('ruleType', 'selector', 'namespace')}<\/code><\/pre>\n<p>\n\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"json\">{'ruleType': 'configmap', 'selector': {'copyrator': 'true'}, 'namespace': ['default']}<\/code><\/pre>\n<p>\n\u041e\u0442\u043b\u0438\u0447\u043d\u043e: \u043d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430. \u0418 \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u043c\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b\u0438, \u0447\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, Kubernetes way.<\/p>\n<h2>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0444\u043b\u0430\u0433\u0438? \u0411\u0435\u0440\u0435\u043c \u0432\u0441\u0451!<\/h2>\n<p>\n\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430. \u0415\u0441\u0442\u044c \u0434\u0432\u0430 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043a \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439:<\/p>\n<ol>\n<li> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438;<\/li>\n<li> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. <\/li>\n<\/ol>\n<p>\n\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0431\u043e\u043b\u0435\u0435 \u0433\u0438\u0431\u043a\u043e, \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0435\u0439 \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Python&#8217;\u0430 \u0435\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c <code>argparser<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0435\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.python.org\/3\/library\/argparse.html\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a><\/noindex>.<\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0444\u043b\u0430\u0433\u043e\u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<pre><code class=\"python\">   parser = ArgumentParser(\n        description='Copyrator - copy operator.',\n        prog='copyrator'\n    )\n    parser.add_argument(\n        '--namespace',\n        type=str,\n        default=getenv('NAMESPACE', 'default'),\n        help='Operator Namespace'\n    )\n    parser.add_argument(\n        '--rule-name',\n        type=str,\n        default=getenv('RULE_NAME', 'main-rule'),\n        help='CRD Name'\n    )\n    args = parser.parse_args()<\/code><\/pre>\n<p>\n\u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 Kubernetes \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e pod&#8217;\u0435 \u0432\u043d\u0443\u0442\u0440\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e namespace, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0437\u0430\u043f\u0443\u0449\u0435\u043d pod, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439:<\/p>\n<pre><code class=\"plaintext\">env:\n- name: NAMESPACE\n  valueFrom:\n     fieldRef:\n         fieldPath: metadata.namespace <\/code><\/pre>\n<p><\/p>\n<h2>\u041b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430<\/h2>\n<p>\n\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 ConfigMap \u0438 Secret, \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u0430\u0440\u0442\u0430\u043c\u0438. \u0422\u043e\u0433\u0434\u0430 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0441\u043b\u0435\u0436\u0435\u043d\u0438\u044f \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430:<\/p>\n<pre><code class=\"plaintext\">LIST_TYPES_MAP = {\n    'configmap': 'list_namespaced_config_map',\n    'secret': 'list_namespaced_secret',\n}\n\nCREATE_TYPES_MAP = {\n    'configmap': 'create_namespaced_config_map',\n    'secret': 'create_namespaced_secret',\n}<\/code><\/pre>\n<p>\n\u0414\u0430\u043b\u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0442 API server. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u044d\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"python\">def handle(specs):\n    kubernetes.config.load_incluster_config()\n    v1 = kubernetes.client.CoreV1Api()\n\n    # \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043b\u0435\u0436\u0435\u043d\u0438\u044f \u0437\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438\n    method = getattr(v1, LIST_TYPES_MAP[specs['ruleType']])\n    func = partial(method, specs['namespace'])\n\n    w = kubernetes.watch.Watch()\n    for event in w.stream(func, _request_timeout=60):\n        handle_event(v1, specs, event)<\/code><\/pre>\n<p>\n\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0435 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/p>\n<pre><code class=\"python\"># \u0422\u0438\u043f\u044b \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c\nALLOWED_EVENT_TYPES = {'ADDED', 'UPDATED'}\n\n\ndef handle_event(v1, specs, event):\n    if event['type'] not in ALLOWED_EVENT_TYPES:\n        return\n\n    object_ = event['object']\n    labels = object_['metadata'].get('labels', {})\n\n    # \u0418\u0449\u0435\u043c \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u043f\u043e selector'\u0443\n    for key, value in specs['selector'].items():\n        if labels.get(key) != value:\n            return\n    # \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 namespace'\u044b\n    namespaces = map(\n        lambda x: x.metadata.name,\n        filter(\n            lambda x: x.status.phase == 'Active',\n            v1.list_namespace().items\n        )\n    )\n    for namespace in namespaces:\n        # \u041e\u0447\u0438\u0449\u0430\u0435\u043c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c namespace\n        object_['metadata'] = {\n            'labels': object_['metadata']['labels'],\n            'namespace': namespace,\n            'name': object_['metadata']['name'],\n        }\n        # \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f\/\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430\n        methodcaller(\n            CREATE_TYPES_MAP[specs['ruleType']],\n            namespace,\n            object_\n        )(v1)<\/code><\/pre>\n<p>\n\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0433\u043e\u0442\u043e\u0432\u0430! \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0451 \u044d\u0442\u043e \u0432 \u043e\u0434\u0438\u043d Python package. \u041e\u0444\u043e\u0440\u043c\u043b\u044f\u0435\u043c \u0444\u0430\u0439\u043b <code>setup.py<\/code>, \u043f\u0438\u0448\u0435\u043c \u0442\u0443\u0434\u0430 \u043c\u0435\u0442\u0430\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0435:<\/p>\n<pre><code class=\"python\">from sys import version_info\n\nfrom setuptools import find_packages, setup\n\nif version_info[:2] &lt; (3, 5):\n    raise RuntimeError(\n        'Unsupported python version %s.' % '.'.join(version_info)\n    )\n\n\n_NAME = 'copyrator'\nsetup(\n    name=_NAME,\n    version='0.0.1',\n    packages=find_packages(),\n    classifiers=[\n        'Development Status :: 3 - Alpha',\n        'Programming Language :: Python',\n        'Programming Language :: Python :: 3',\n        'Programming Language :: Python :: 3.5',\n        'Programming Language :: Python :: 3.6',\n        'Programming Language :: Python :: 3.7',\n    ],\n    author='Flant',\n    author_email='maksim.nabokikh@flant.com',\n    include_package_data=True,\n    install_requires=[\n        'kubernetes==9.0.0',\n    ],\n    entry_points={\n        'console_scripts': [\n            '{0} = {0}.cli:main'.format(_NAME),\n        ]\n    }\n)<\/code><\/pre>\n<p>\n<i><b>NB<\/b>: \u041a\u043b\u0438\u0435\u043d\u0442 kubernetes \u0434\u043b\u044f Python \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0451 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u0432\u0435\u0440\u0441\u0438\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0432\u0435\u0440\u0441\u0438\u0439 Kubernetes \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u0438\u0437 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kubernetes-client\/python#compatibility-matrix\">\u043c\u0430\u0442\u0440\u0438\u0446\u044b \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0435\u0439<\/a><\/noindex>.<\/i><\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"plaintext\">copyrator\n\u251c\u2500\u2500 copyrator\n\u2502   \u251c\u2500\u2500 cli.py # \u041b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439\n\u2502   \u251c\u2500\u2500 constant.py # \u041a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043b\u0438 \u0432\u044b\u0448\u0435\n\u2502   \u251c\u2500\u2500 load_crd.py # \u041b\u043e\u0433\u0438\u043a\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 CRD\n\u2502   \u2514\u2500\u2500 operator.py # \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430\n\u2514\u2500\u2500 setup.py # \u041e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430<\/code><\/pre>\n<p><\/p>\n<h2>Docker \u0438 Helm<\/h2>\n<p>\nDockerfile \u0431\u0443\u0434\u0435\u0442 \u0434\u043e \u0431\u0435\u0437\u043e\u0431\u0440\u0430\u0437\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u043c: \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 python-alpine \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u043d\u0430\u0448 \u043f\u0430\u043a\u0435\u0442. \u0415\u0433\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e \u043e\u0442\u043b\u043e\u0436\u0438\u043c \u0434\u043e \u043b\u0443\u0447\u0448\u0438\u0445 \u0432\u0440\u0435\u043c\u0435\u043d:<\/p>\n<pre><code class=\"plaintext\">FROM python:3.7.3-alpine3.9\n\nADD . \/app\n\nRUN pip3 install \/app\n\nENTRYPOINT [\"copyrator\"]<\/code><\/pre>\n<p>\nDeployment \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0442\u043e\u0436\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442:<\/p>\n<pre><code class=\"plaintext\">apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: {{ .Chart.Name }}\nspec:\n  selector:\n    matchLabels:\n      name: {{ .Chart.Name }}\n  template:\n    metadata:\n      labels:\n        name: {{ .Chart.Name }}\n    spec:\n      containers:\n      - name: {{ .Chart.Name }}\n        image: privaterepo.yourcompany.com\/copyrator:latest\n        imagePullPolicy: Always\n        args: [\"--rule-type\", \"main-rule\"]\n        env:\n        - name: NAMESPACE\n          valueFrom:\n            fieldRef:\n              fieldPath: metadata.namespace\n      serviceAccountName: {{ .Chart.Name }}-acc<\/code><\/pre>\n<p>\n\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0440\u043e\u043b\u044c \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u0430\u043c\u0438:<\/p>\n<pre><code class=\"plaintext\">apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: {{ .Chart.Name }}-acc\n\n---\napiVersion: rbac.authorization.k8s.io\/v1beta1\nkind: ClusterRole\nmetadata:\n  name: {{ .Chart.Name }}\nrules:\n  - apiGroups: [\"\"]\n    resources: [\"namespaces\"]\n    verbs: [\"get\", \"watch\", \"list\"]\n  - apiGroups: [\"\"]\n    resources: [\"secrets\", \"configmaps\"]\n    verbs: [\"*\"]\n---\napiVersion: rbac.authorization.k8s.io\/v1beta1\nkind: ClusterRoleBinding\nmetadata:\n  name: {{ .Chart.Name }}\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: {{ .Chart.Name }}\nsubjects:\n- kind: ServiceAccount\n  name: {{ .Chart.Name }}<\/code><\/pre>\n<p><\/p>\n<h2>\u0418\u0442\u043e\u0433<\/h2>\n<p>\n\u0412\u043e\u0442 \u0442\u0430\u043a, \u0431\u0435\u0437 \u0441\u0442\u0440\u0430\u0445\u0430, \u0443\u043f\u0440\u0435\u043a\u0430 \u0438 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f Go, \u043c\u044b \u0441\u043c\u043e\u0433\u043b\u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u0435\u0433\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0434\u043b\u044f Kubernetes \u043d\u0430 Python. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0435\u043c\u0443 \u0435\u0449\u0451 \u0435\u0441\u0442\u044c \u043a\u0443\u0434\u0430 \u0440\u0430\u0441\u0442\u0438: \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043e\u043d \u0441\u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0430\u0432\u0438\u043b, \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 CRD\u2026<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u0431\u043b\u0438\u0436\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043a\u043e\u0434\u043e\u043c, \u043c\u044b \u0441\u043b\u043e\u0436\u0438\u043b\u0438 \u0435\u0433\u043e \u0432 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/k8s-python-operator-example\"><b>\u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/b><\/a><\/noindex>. \u0415\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0431\u043e\u043b\u0435\u0435 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Python, \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0441\u0432\u043e\u0451 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u0432\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f mongodb (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Ultimaker\/k8s-mongo-operator\">\u043f\u0435\u0440\u0432\u044b\u0439<\/a><\/noindex> \u0438 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kbst\/mongodb\">\u0432\u0442\u043e\u0440\u043e\u0439<\/a><\/noindex>).<\/p>\n<p>P.S. \u0410 \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043b\u0435\u043d\u044c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c\u0438 Kubernetes \u0438\u043b\u0438 \u0436\u0435 \u0432\u0430\u043c \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Bash \u2014 \u043d\u0430\u0448\u0438 \u043a\u043e\u043b\u043b\u0435\u0433\u0438 \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438 \u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/shell-operator\">shell-operator<\/a><\/noindex> (\u043c\u044b <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/447442\/\">\u0430\u043d\u043e\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043b\u0438<\/a><\/noindex> \u0435\u0433\u043e \u0432 \u0430\u043f\u0440\u0435\u043b\u0435). <\/p>\n<h2>P.P.S.<\/h2>\n<p>\n\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u0442\u0430\u043a\u0436\u0435 \u0432 \u043d\u0430\u0448\u0435\u043c \u0431\u043b\u043e\u0433\u0435:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/455543\/\">\u0413\u043e\u0442\u043e\u0432\u0438\u0442\u044c Kubernetes-\u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u043f\u0440\u043e\u0441\u0442\u043e \u0438 \u0443\u0434\u043e\u0431\u043d\u043e? \u0410\u043d\u043e\u043d\u0441\u0438\u0440\u0443\u0435\u043c addon-operator<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/447442\/\">\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c shell-operator: \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0434\u043b\u044f Kubernetes \u0441\u0442\u0430\u043b\u043e \u0435\u0449\u0451 \u043f\u0440\u043e\u0449\u0435<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/449096\/\">\u0420\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u043c Kubernetes (\u043e\u0431\u0437\u043e\u0440 \u0438 \u0432\u0438\u0434\u0435\u043e \u0434\u043e\u043a\u043b\u0430\u0434\u0430)<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/337698\/\">\u041f\u0438\u0448\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0434\u043b\u044f Kubernetes \u043d\u0430 Golang<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/326414\/\">\u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0434\u043b\u044f Kubernetes: \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c stateful-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/459320\/\">habr.com<\/a><\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>Go \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u043e\u043d\u043e\u043f\u043e\u043b\u0438\u0441\u0442\u043e\u043c \u0441\u0440\u0435\u0434\u0438 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u044e\u0434\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f Kubernetes. \u0422\u043e\u043c\u0443 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044b, \u043a\u0430\u043a: \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043e\u0449\u043d\u0435\u0439\u0448\u0438\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0430 Go \u2014 Operator SDK. \u041d\u0430 Go \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u0430\u043a\u0438\u0435 \u00ab\u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0432\u0448\u0438\u0435 \u0438\u0433\u0440\u0443\u00bb \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u0430\u043a Docker \u0438 Kubernetes. \u041f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0430 Go \u2014 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0441 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043d\u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":27179,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-36331","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"Go \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u043e\u043d\u043e\u043f\u043e\u043b\u0438\u0441\u0442\u043e\u043c \u0441\u0440\u0435\u0434\u0438 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u044e\u0434\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f Kubernetes. \u0422\u043e\u043c\u0443 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044b, \u043a\u0430\u043a: \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043e\u0449\u043d\u0435\u0439\u0448\u0438\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0430 Go \u2014 Operator SDK. \u041d\u0430 Go \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u0430\u043a\u0438\u0435 \u00ab\u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0432\u0448\u0438\u0435 \u0438\u0433\u0440\u0443\u00bb \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u0430\u043a Docker \u0438 Kubernetes. \u041f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0430 Go \u2014 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0441 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043d\u0430\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kubernetes-operator-na-python-bez-frejmvorkov-i-sdk\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Kubernetes Operator \u043d\u0430 Python \u0431\u0435\u0437 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0438 SDK | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"Go \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u043e\u043d\u043e\u043f\u043e\u043b\u0438\u0441\u0442\u043e\u043c \u0441\u0440\u0435\u0434\u0438 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u044e\u0434\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f Kubernetes. \u0422\u043e\u043c\u0443 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044b, \u043a\u0430\u043a: \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043e\u0449\u043d\u0435\u0439\u0448\u0438\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0430 Go \u2014 Operator SDK. \u041d\u0430 Go \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u0430\u043a\u0438\u0435 \u00ab\u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0432\u0448\u0438\u0435 \u0438\u0433\u0440\u0443\u00bb \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u0430\u043a Docker \u0438 Kubernetes. \u041f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0430 Go \u2014 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0441 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043d\u0430\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kubernetes-operator-na-python-bez-frejmvorkov-i-sdk\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:10:58+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:10:58+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Kubernetes-Operator in Python ohne Frameworks und SDK | ProHoster","description":"Go ist derzeit die dominierende Sprache unter den Programmiersprachen, die f\u00fcr die Entwicklung von Operatoren f\u00fcr Kubernetes gew\u00e4hlt wird. Daf\u00fcr gibt es objektive Gr\u00fcnde, wie: Es gibt ein leistungsstarkes Framework f\u00fcr die Entwicklung von Operatoren in Go \u2013 das Operator SDK. Solche \"spielver\u00e4ndernden\" Anwendungen wie Docker und Kubernetes sind in Go geschrieben. Einen eigenen Operator in Go zu schreiben, bedeutet, mit der Ecosystem zu kommunizieren.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kubernetes-operator-na-python-bez-frejmvorkov-i-sdk","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Kubernetes Operator \u043d\u0430 Python \u0431\u0435\u0437 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0438 SDK | ProHoster","og:description":"Go \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u043e\u043d\u043e\u043f\u043e\u043b\u0438\u0441\u0442\u043e\u043c \u0441\u0440\u0435\u0434\u0438 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u044e\u0434\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f Kubernetes. \u0422\u043e\u043c\u0443 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044b, \u043a\u0430\u043a: \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043e\u0449\u043d\u0435\u0439\u0448\u0438\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0430 Go \u2014 Operator SDK. \u041d\u0430 Go \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u0430\u043a\u0438\u0435 \u00ab\u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0432\u0448\u0438\u0435 \u0438\u0433\u0440\u0443\u00bb \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u0430\u043a Docker \u0438 Kubernetes. \u041f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0430 Go \u2014 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0441 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043d\u0430","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kubernetes-operator-na-python-bez-frejmvorkov-i-sdk","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:10:58+00:00","article:modified_time":"2019-10-31T19:10:58+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"36331","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 02:54:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:46:26","updated":"2026-01-22 02:54:19"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/36331","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=36331"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/36331\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/27179"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=36331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=36331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=36331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}