āĻ†āĻŽāĻ°āĻž āĻ—ā§‹āĻ˛āĻ‚-āĻ Kubernetes-āĻāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻ° āĻ˛āĻŋāĻ–āĻŋ

āĻŦāĻŋāĻƒāĻĻā§āĻ°āĻƒ. āĻ…āĻ¨ā§āĻŦāĻžāĻĻ: āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻ° āĻšāĻ˛ Kubernetes-āĻāĻ° āĻœāĻ¨ā§āĻ¯ āĻ¸āĻšāĻžāĻ¯āĻŧāĻ• āĻ¸āĻĢā§āĻŸāĻ“āĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻ¯āĻž āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ‡āĻ­ā§‡āĻ¨ā§āĻŸā§‡āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ° āĻ…āĻŦāĻœā§‡āĻ•ā§āĻŸā§‡ āĻ°ā§āĻŸāĻŋāĻ¨ āĻ…ā§āĻ¯āĻžāĻ•āĻļāĻ¨āĻ—ā§āĻ˛āĻŋ āĻ¸ā§āĻŦāĻ¯āĻŧāĻ‚āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻ­āĻžāĻŦā§‡ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻĄāĻŋāĻœāĻžāĻ‡āĻ¨ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤ āĻ†āĻŽāĻ°āĻž āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻ° āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ˛āĻŋāĻ–ā§‡āĻ›āĻŋ āĻāĻ‡ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻŸāĻŋāĻ¯ā§‡āĻ–āĻžāĻ¨ā§‡ āĻ¤āĻžāĻ°āĻž āĻ¤āĻžāĻĻā§‡āĻ° āĻ•āĻžāĻœā§‡āĻ° āĻŽā§ŒāĻ˛āĻŋāĻ• āĻ§āĻžāĻ°āĻŖāĻž āĻāĻŦāĻ‚ āĻ¨ā§€āĻ¤āĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ•āĻĨāĻž āĻŦāĻ˛ā§‡āĻ›ā§‡āĻ¨āĨ¤ āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ¯āĻĻāĻŋ āĻ¸ā§‡āĻ‡ āĻ‰āĻĒāĻžāĻĻāĻžāĻ¨āĻŸāĻŋ āĻŦāĻ°āĻ‚ āĻ•ā§āĻŦāĻžāĻ°āĻ¨ā§‡āĻŸāĻ¸ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ¤ā§ˆāĻ°āĻŋ āĻ‰āĻĒāĻžāĻĻāĻžāĻ¨āĻ—ā§āĻ˛āĻŋāĻ° āĻ…āĻĒāĻžāĻ°ā§‡āĻļāĻ¨ā§‡āĻ° āĻĻāĻŋāĻ• āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻĻā§ƒāĻˇā§āĻŸāĻŋāĻ­āĻ™ā§āĻ—āĻŋ āĻ›āĻŋāĻ˛, āĻ¤āĻžāĻšāĻ˛ā§‡ āĻāĻ–āĻ¨ āĻĒā§āĻ°āĻ¸ā§āĻ¤āĻžāĻŦāĻŋāĻ¤ āĻ¨āĻ¤ā§āĻ¨ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻŸāĻŋāĻ° āĻ…āĻ¨ā§āĻŦāĻžāĻĻāĻŸāĻŋ āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡āĻ‡ āĻāĻ•āĻœāĻ¨ āĻŦāĻŋāĻ•āĻžāĻļāĻ•āĻžāĻ°ā§€/āĻĄāĻŋāĻ“āĻ…āĻĒāĻ¸ āĻ‡āĻžā§āĻœāĻŋāĻ¨āĻŋāĻ¯āĻŧāĻžāĻ°ā§‡āĻ° āĻĻā§ƒāĻˇā§āĻŸāĻŋāĻ­āĻ™ā§āĻ—āĻŋ, āĻ¯āĻž āĻāĻ•āĻŸāĻŋ āĻ¨āĻ¤ā§āĻ¨ āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§‡ āĻŦāĻŋāĻ­ā§āĻ°āĻžāĻ¨ā§āĻ¤āĨ¤ .

āĻ†āĻŽāĻ°āĻž āĻ—ā§‹āĻ˛āĻ‚-āĻ Kubernetes-āĻāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻ° āĻ˛āĻŋāĻ–āĻŋ

āĻ•ā§āĻŦāĻžāĻ°āĻ¨ā§‡āĻŸāĻ¸ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻ° āĻ¤ā§ˆāĻ°āĻŋāĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧā§‡ āĻĄāĻ•ā§āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāĻ¨ āĻ–ā§‹āĻāĻœāĻžāĻ° āĻšā§‡āĻˇā§āĻŸāĻž āĻ•āĻ°āĻžāĻ° āĻĒāĻ°ā§‡, āĻ•ā§‹āĻĄā§‡āĻ° āĻ…āĻ§ā§āĻ¯āĻ¯āĻŧāĻ¨ā§‡āĻ° āĻŽāĻ§ā§āĻ¯ āĻĻāĻŋāĻ¯āĻŧā§‡ āĻ¯āĻžāĻ“āĻ¯āĻŧāĻžāĻ° āĻĒāĻ°ā§‡ āĻ†āĻŽāĻŋ āĻāĻ•āĻŸāĻŋ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦ āĻœā§€āĻŦāĻ¨ā§‡āĻ° āĻ‰āĻĻāĻžāĻšāĻ°āĻŖ āĻ¸āĻš āĻāĻ‡ āĻĒā§‹āĻ¸ā§āĻŸāĻŸāĻŋ āĻ˛ā§‡āĻ–āĻžāĻ° āĻ¸āĻŋāĻĻā§āĻ§āĻžāĻ¨ā§āĻ¤ āĻ¨āĻŋāĻ¯āĻŧā§‡āĻ›āĻŋāĨ¤

āĻ¯ā§‡ āĻ‰āĻĻāĻžāĻšāĻ°āĻŖāĻŸāĻŋ āĻŦāĻ°ā§āĻŖāĻ¨āĻž āĻ•āĻ°āĻž āĻšāĻŦā§‡ āĻ¤āĻž āĻšāĻ˛: āĻ†āĻŽāĻžāĻĻā§‡āĻ° Kubernetes āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°ā§‡, āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ Namespace āĻāĻ•āĻŸāĻŋ āĻĻāĻ˛ā§‡āĻ° āĻ¸ā§āĻ¯āĻžāĻ¨ā§āĻĄāĻŦāĻ•ā§āĻ¸ āĻĒāĻ°āĻŋāĻŦā§‡āĻļā§‡āĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻ¨āĻŋāĻ§āĻŋāĻ¤ā§āĻŦ āĻ•āĻ°ā§‡, āĻāĻŦāĻ‚ āĻ†āĻŽāĻ°āĻž āĻ¤āĻžāĻĻā§‡āĻ° āĻ…ā§āĻ¯āĻžāĻ•ā§āĻ¸ā§‡āĻ¸ āĻ¸ā§€āĻŽāĻžāĻŦāĻĻā§āĻ§ āĻ•āĻ°āĻ¤ā§‡ āĻšā§‡āĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛āĻžāĻŽ āĻ¯āĻžāĻ¤ā§‡ āĻĻāĻ˛āĻ—ā§āĻ˛āĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ¤āĻžāĻĻā§‡āĻ° āĻ¨āĻŋāĻœāĻ¸ā§āĻŦ āĻ¸ā§āĻ¯āĻžāĻ¨ā§āĻĄāĻŦāĻ•ā§āĻ¸ā§‡ āĻ–ā§‡āĻ˛āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ā§ˇ

āĻ†āĻĒāĻ¨āĻŋ āĻāĻ•āĻŸāĻŋ āĻ—ā§‹āĻˇā§āĻ ā§€āĻ¤ā§‡ āĻāĻ•āĻœāĻ¨ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€āĻ•ā§‡ āĻŦāĻ°āĻžāĻĻā§āĻĻ āĻ•āĻ°ā§‡ āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻž āĻšāĻžāĻ¨ āĻ¤āĻž āĻ…āĻ°ā§āĻœāĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨ RoleBinding āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ Namespace и ClusterRole āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨āĻžāĻ° āĻ…āĻ§āĻŋāĻ•āĻžāĻ° āĻ¸āĻšāĨ¤ YAML āĻĒā§āĻ°āĻ¤āĻŋāĻ¨āĻŋāĻ§āĻŋāĻ¤ā§āĻŦ āĻāĻ‡ āĻŽāĻ¤ āĻĻā§‡āĻ–āĻžāĻŦā§‡:

---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: kubernetes-team-1
  namespace: team-1
subjects:
- kind: Group
  name: kubernetes-team-1
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: edit
apiGroup: rbac.authorization.k8s.io

(rolebinding.yaml, āĻ‡āĻ¨ āĻ•āĻžāĻāĻšāĻž)

āĻāĻ°āĻ•āĻŽ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°ā§āĻ¨ RoleBinding āĻ†āĻĒāĻ¨āĻŋ āĻāĻŸāĻŋ āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¯āĻŧāĻžāĻ˛āĻŋ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ•āĻŦāĻžāĻ° āĻ†āĻĒāĻ¨āĻŋ āĻāĻ•āĻļā§‹āĻ° āĻŦā§‡āĻļāĻŋ āĻ¨āĻžāĻŽāĻ¸ā§āĻĨāĻžāĻ¨ āĻĒā§‡āĻ¯āĻŧā§‡ āĻ—ā§‡āĻ˛ā§‡, āĻāĻŸāĻŋ āĻāĻ•āĻŸāĻŋ āĻ•ā§āĻ˛āĻžāĻ¨ā§āĻ¤āĻŋāĻ•āĻ° āĻ•āĻžāĻœ āĻšāĻ¯āĻŧā§‡ āĻ¯āĻžāĻ¯āĻŧāĨ¤ āĻāĻ–āĻžāĻ¨ā§‡āĻ‡ Kubernetes āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻ°āĻĻā§‡āĻ° āĻ•āĻžāĻœā§‡ āĻ†āĻ¸ā§‡ - āĻ¤āĻžāĻ°āĻž āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ¸āĻŽā§āĻĒāĻĻā§‡āĻ° āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ā§‡āĻ° āĻ‰āĻĒāĻ° āĻ­āĻŋāĻ¤ā§āĻ¤āĻŋ āĻ•āĻ°ā§‡ Kubernetes āĻ¸āĻ‚āĻ¸ā§āĻĨāĻžāĻ¨āĻ—ā§āĻ˛āĻŋ āĻ¸ā§āĻŦāĻ¯āĻŧāĻ‚āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻ­āĻžāĻŦā§‡ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻ¤ā§‡ āĻĻā§‡āĻ¯āĻŧāĨ¤ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡, āĻ†āĻŽāĻ°āĻž āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻžāĻ‡ RoleBinding āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ Namespace.

āĻĒā§āĻ°āĻĨāĻŽāĻ¤, āĻĢāĻžāĻ‚āĻļāĻ¨āĻŸāĻŋ āĻ¸āĻ‚āĻœā§āĻžāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻ•āĻ°āĻž āĻ¯āĻžāĻ• main, āĻ¯āĻž āĻ¸ā§āĻŸā§‡āĻŸāĻŽā§‡āĻ¨ā§āĻŸ āĻšāĻžāĻ˛āĻžāĻ¨ā§‹āĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§€āĻ¯āĻŧ āĻ¸ā§‡āĻŸāĻ†āĻĒ āĻ•āĻ°ā§‡ āĻāĻŦāĻ‚ āĻ¤āĻžāĻ°āĻĒāĻ° āĻ¸ā§āĻŸā§‡āĻŸāĻŽā§‡āĻ¨ā§āĻŸ āĻ…ā§āĻ¯āĻžāĻ•āĻļāĻ¨ āĻ†āĻšā§āĻŦāĻžāĻ¨ āĻ•āĻ°ā§‡:

(āĻŦāĻŋāĻƒāĻĻā§āĻ°āĻƒ. āĻ…āĻ¨ā§āĻŦāĻžāĻĻ: āĻāĻ°āĻĒāĻ°ā§‡, āĻ•ā§‹āĻĄā§‡āĻ° āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻ°āĻžāĻļāĻŋāĻ¯āĻŧāĻžāĻ¨ āĻ­āĻžāĻˇāĻžāĻ¯āĻŧ āĻ…āĻ¨ā§āĻŦāĻžāĻĻ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤ āĻ‰āĻĒāĻ°āĻ¨ā§āĻ¤ā§, āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° Habr āĻāĻ° āĻ˛ā§‡āĻ†āĻ‰āĻŸā§‡āĻ° āĻ•āĻžāĻ āĻžāĻŽā§‹āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻ†āĻ°āĻ“ āĻ­āĻžāĻ˛ āĻĒāĻ āĻ¨āĻ¯ā§‹āĻ—ā§āĻ¯āĻ¤āĻžāĻ° āĻ‰āĻĻā§āĻĻā§‡āĻļā§āĻ¯ā§‡ [āĻ—ā§‹āĻ¤ā§‡ āĻĒā§āĻ°āĻ¸ā§āĻ¤āĻžāĻŦāĻŋāĻ¤] āĻŸā§āĻ¯āĻžāĻŦā§‡āĻ° āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤ā§‡ āĻ¸ā§āĻĒā§‡āĻ¸āĻ—ā§āĻ˛āĻŋāĻ° āĻœāĻ¨ā§āĻ¯ āĻ‡āĻ¨ā§āĻĄā§‡āĻ¨ā§āĻŸā§‡āĻļāĻ¨ āĻ¸āĻ‚āĻļā§‹āĻ§āĻ¨ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤ āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻ¤āĻžāĻ˛āĻŋāĻ•āĻžāĻ° āĻĒāĻ°ā§‡, GitHub-āĻ āĻ†āĻ¸āĻ˛ āĻ˛āĻŋāĻ™ā§āĻ• āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡, āĻ¯ā§‡āĻ–āĻžāĻ¨ā§‡ āĻ‡āĻ‚āĻ°ā§‡āĻœāĻŋ-āĻ­āĻžāĻˇāĻžāĻ° āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻāĻŦāĻ‚ āĻŸā§āĻ¯āĻžāĻŦāĻ—ā§āĻ˛āĻŋ āĻ¸āĻ‚āĻ°āĻ•ā§āĻˇāĻŋāĻ¤ āĻšāĻ¯āĻŧāĨ¤)

func main() {
  // ĐŖŅŅ‚Đ°ĐŊавĐģиваĐĩĐŧ вŅ‹Đ˛ĐžĐ´ ĐģĐžĐŗОв в ĐēĐžĐŊŅĐžĐģŅŒĐŊŅ‹Đš STDOUT
  log.SetOutput(os.Stdout)

  sigs := make(chan os.Signal, 1) // ХОСдаĐĩĐŧ ĐēĐ°ĐŊĐ°Đģ Đ´ĐģŅ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиŅ ŅĐ¸ĐŗĐŊĐ°ĐģОв ОС
  stop := make(chan struct{})     // ХОСдаĐĩĐŧ ĐēĐ°ĐŊĐ°Đģ Đ´ĐģŅ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиŅ ŅŅ‚ĐžĐŋ-ŅĐ¸ĐŗĐŊĐ°ĐģĐ°

  // Đ ĐĩĐŗиŅŅ‚Ņ€Đ¸Ņ€ŅƒĐĩĐŧ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиĐĩ SIGTERM в ĐēĐ°ĐŊĐ°ĐģĐĩ sigs
  signal.Notify(sigs, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) 

  // Goroutines ĐŧĐžĐŗŅƒŅ‚ ŅĐ°Đŧи дОйавĐģŅŅ‚ŅŒ ŅĐĩĐąŅ в WaitGroup,
 // Ņ‡Ņ‚ОйŅ‹ СавĐĩŅ€ŅˆĐĩĐŊиŅ иŅ… вŅ‹ĐŋĐžĐģĐŊĐĩĐŊиŅ Đ´ĐžĐļидаĐģиŅŅŒ
  wg := &sync.WaitGroup{} 

  runOutsideCluster := flag.Bool("run-outside-cluster", false, "Set this flag when running outside of the cluster.")
  flag.Parse()
  // ХОСдаĐĩĐŧ clientset Đ´ĐģŅ вСаиĐŧОдĐĩĐšŅŅ‚виŅ Ņ ĐēĐģĐ°ŅŅ‚ĐĩŅ€ĐžĐŧ Kubernetes
  clientset, err := newClientSet(*runOutsideCluster)

  if err != nil {
    panic(err.Error())
  }

  controller.NewNamespaceController(clientset).Run(stop, wg)

  <-sigs // ЖдĐĩĐŧ ŅĐ¸ĐŗĐŊĐ°ĐģОв (Đ´Đž ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиŅ ŅĐ¸ĐŗĐŊĐ°ĐģĐ° йОĐģĐĩĐĩ ĐŊиŅ‡ĐĩĐŗĐž ĐŊĐĩ ĐŋŅ€ĐžĐ¸ŅŅ…ОдиŅ‚)
  log.Printf("Shutting down...")

  close(stop) // ГовоŅ€Đ¸Đŧ goroutines ĐžŅŅ‚Đ°ĐŊОвиŅ‚ŅŒŅŅ
  wg.Wait()   // ОĐļидаĐĩĐŧ, Ņ‡Ņ‚Đž вŅĐĩ ĐžŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž
}

(main.go, āĻ‡āĻ¨ āĻ•āĻžāĻāĻšāĻž)

āĻ†āĻŽāĻ°āĻž āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻ•āĻ°āĻŋ:

  1. āĻ†āĻŽāĻ°āĻž āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻŋāĻ‚ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ¸āĻŋāĻ—āĻ¨ā§āĻ¯āĻžāĻ˛ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻšā§āĻ¯āĻžāĻ¨ā§āĻĄāĻ˛āĻžāĻ° āĻ¸ā§‡āĻŸ āĻ†āĻĒ āĻ•āĻ°āĻŋ āĻ¯āĻžāĻ¤ā§‡ āĻ…āĻĒāĻžāĻ°ā§‡āĻŸāĻ°āĻ•ā§‡ āĻ¸ā§āĻ¨ā§āĻĻāĻ°āĻ­āĻžāĻŦā§‡ āĻĒā§āĻ°āĻ¸ā§āĻĨāĻžāĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĨ¤
  2. āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° WaitGroupāĻ†āĻŦā§‡āĻĻāĻ¨ āĻļā§‡āĻˇ āĻšāĻ“āĻ¯āĻŧāĻžāĻ° āĻ†āĻ—ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ—āĻ°āĻ‰āĻŸāĻŋāĻ¨āĻ—ā§āĻ˛āĻŋ āĻ•āĻ°ā§āĻŖāĻ­āĻžāĻŦā§‡ āĻŦāĻ¨ā§āĻ§ āĻ•āĻ°āĻ¤ā§‡āĨ¤
  3. āĻ†āĻŽāĻ°āĻž āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°ā§‡ āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ° āĻ…ā§āĻ¯āĻžāĻ•ā§āĻ¸ā§‡āĻ¸ āĻĒā§āĻ°āĻĻāĻžāĻ¨ clientset.
  4. āĻšāĻžāĻ˛āĻžāĻ¨ NamespaceController, āĻ¯ā§‡āĻ–āĻžāĻ¨ā§‡ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ¯ā§āĻ•ā§āĻ¤āĻŋ āĻ…āĻŦāĻ¸ā§āĻĨāĻŋāĻ¤ āĻšāĻŦā§‡āĨ¤

āĻāĻ–āĻ¨ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ¯ā§āĻ•ā§āĻ¤āĻŋāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻ­āĻŋāĻ¤ā§āĻ¤āĻŋ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨, āĻāĻŦāĻ‚ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡ āĻāĻŸāĻŋ āĻ‰āĻ˛ā§āĻ˛ā§‡āĻ– āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ NamespaceController:

// NamespaceController ŅĐģĐĩдиŅ‚ Ņ‡ĐĩŅ€ĐĩС Kubernetes API Са иСĐŧĐĩĐŊĐĩĐŊиŅĐŧи
// в ĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊŅŅ‚ваŅ… иĐŧĐĩĐŊ и ŅĐžĐˇĐ´Đ°ĐĩŅ‚ RoleBinding Đ´ĐģŅ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŗĐž namespace.
type NamespaceController struct {
  namespaceInformer cache.SharedIndexInformer
  kclient           *kubernetes.Clientset
}

// NewNamespaceController ŅĐžĐˇĐ´Đ°ĐĩŅ‚ ĐŊОвŅ‹Đš NewNamespaceController
func NewNamespaceController(kclient *kubernetes.Clientset) *NamespaceController {
  namespaceWatcher := &NamespaceController{}

  // ХОСдаĐĩĐŧ иĐŊŅ„ĐžŅ€ĐŧĐĩŅ€ Đ´ĐģŅ ŅĐģĐĩĐļĐĩĐŊиŅ Са Namespaces
  namespaceInformer := cache.NewSharedIndexInformer(
    &cache.ListWatch{
      ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
        return kclient.Core().Namespaces().List(options)
      },
      WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
        return kclient.Core().Namespaces().Watch(options)
      },
    },
    &v1.Namespace{},
    3*time.Minute,
    cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
  )

  namespaceInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
    AddFunc: namespaceWatcher.createRoleBinding,
  })

  namespaceWatcher.kclient = kclient
  namespaceWatcher.namespaceInformer = namespaceInformer

  return namespaceWatcher
}

(controller.go, āĻ‡āĻ¨ āĻ•āĻžāĻāĻšāĻž)

āĻāĻ–āĻžāĻ¨ā§‡ āĻ†āĻŽāĻ°āĻž āĻ¸ā§‡āĻŸ āĻ•āĻ°āĻ›āĻŋ SharedIndexInformer, āĻ¯āĻž āĻĻāĻ•ā§āĻˇāĻ¤āĻžāĻ° āĻ¸āĻžāĻĨā§‡ (āĻ•ā§āĻ¯āĻžāĻļā§‡ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡) āĻ¨āĻžāĻŽāĻ¸ā§āĻĨāĻžāĻ¨ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ…āĻĒā§‡āĻ•ā§āĻˇāĻž āĻ•āĻ°āĻŦā§‡ (āĻĒā§āĻ°āĻŦāĻ¨ā§āĻ§ā§‡ āĻ¤āĻĨā§āĻ¯āĻĻāĻžāĻ¤āĻžāĻĻā§‡āĻ° āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ†āĻ°āĻ“ āĻĒāĻĄāĻŧā§āĻ¨ "Kubernetes āĻ¸āĻŽāĻ¯āĻŧāĻ¸ā§‚āĻšā§€ āĻ†āĻ¸āĻ˛ā§‡ āĻ•āĻŋāĻ­āĻžāĻŦā§‡ āĻ•āĻžāĻœ āĻ•āĻ°ā§‡?"- āĻĒā§āĻ°āĻžāĻ¯āĻŧ. āĻ…āĻ¨ā§āĻŦāĻžāĻĻ). āĻāĻ° āĻĒāĻ°ā§‡ āĻ†āĻŽāĻ°āĻž āĻ¸āĻ‚āĻ¯ā§‹āĻ— āĻ•āĻ°āĻŋ EventHandler āĻ¤āĻĨā§āĻ¯āĻĻāĻžāĻ¤āĻžāĻ•ā§‡, āĻ§āĻ¨ā§āĻ¯āĻŦāĻžāĻĻ āĻ¯āĻžāĻ° āĻœāĻ¨ā§āĻ¯, āĻāĻ•āĻŸāĻŋ āĻ¨āĻžāĻŽāĻ¸ā§āĻĨāĻžāĻ¨ āĻ¯ā§‹āĻ— āĻ•āĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ (Namespace) āĻĢāĻžāĻ‚āĻļāĻ¨ āĻŦāĻ˛āĻž āĻšāĻ¯āĻŧ createRoleBinding.

āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§€ āĻ§āĻžāĻĒ āĻāĻ‡ āĻĢāĻžāĻ‚āĻļāĻ¨ āĻ¸āĻ‚āĻœā§āĻžāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧ createRoleBinding:

func (c *NamespaceController) createRoleBinding(obj interface{}) {
  namespaceObj := obj.(*v1.Namespace)
  namespaceName := namespaceObj.Name

  roleBinding := &v1beta1.RoleBinding{
    TypeMeta: metav1.TypeMeta{
      Kind:       "RoleBinding",
      APIVersion: "rbac.authorization.k8s.io/v1beta1",
    },
    ObjectMeta: metav1.ObjectMeta{
      Name:      fmt.Sprintf("ad-kubernetes-%s", namespaceName),
      Namespace: namespaceName,
    },
    Subjects: []v1beta1.Subject{
      v1beta1.Subject{
        Kind: "Group",
        Name: fmt.Sprintf("ad-kubernetes-%s", namespaceName),
      },
    },
    RoleRef: v1beta1.RoleRef{
      APIGroup: "rbac.authorization.k8s.io",
        Kind:     "ClusterRole",
        Name:     "edit",
    },
  }

  _, err := c.kclient.Rbac().RoleBindings(namespaceName).Create(roleBinding)

  if err != nil {
    log.Println(fmt.Sprintf("Failed to create Role Binding: %s", err.Error()))
  } else {
    log.Println(fmt.Sprintf("Created AD RoleBinding for Namespace: %s", roleBinding.Name))
  }
}

(controller.go, āĻ‡āĻ¨ āĻ•āĻžāĻāĻšāĻž)

āĻ†āĻŽāĻ°āĻž āĻ¨āĻžāĻŽāĻ¸ā§āĻĨāĻžāĻ¨ āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻĒā§‡āĻ¤ā§‡ obj āĻāĻŦāĻ‚ āĻāĻŸāĻŋāĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻŦāĻ¸ā§āĻ¤ā§āĻ¤ā§‡ āĻ°ā§‚āĻĒāĻžāĻ¨ā§āĻ¤āĻ° āĻ•āĻ°ā§āĻ¨ Namespace. āĻ¤āĻžāĻ°āĻĒāĻ° āĻ†āĻŽāĻ°āĻž āĻ¸āĻ‚āĻœā§āĻžāĻžāĻ¯āĻŧāĻŋāĻ¤ RoleBinding, āĻĒā§āĻ°āĻĻāĻ¤ā§āĻ¤ āĻŦāĻ¸ā§āĻ¤ā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻļā§āĻ°ā§āĻ¤ā§‡ āĻ‰āĻ˛ā§āĻ˛āĻŋāĻ–āĻŋāĻ¤ YAML āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻ‰āĻĒāĻ° āĻ­āĻŋāĻ¤ā§āĻ¤āĻŋ āĻ•āĻ°ā§‡ Namespace āĻāĻŦāĻ‚ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻž RoleBinding. āĻ…āĻŦāĻļā§‡āĻˇā§‡, āĻ†āĻŽāĻ°āĻž āĻ¸ā§ƒāĻˇā§āĻŸāĻŋ āĻ¸āĻĢāĻ˛ āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ āĻ•āĻŋāĻ¨āĻž āĻ˛āĻ—.

āĻ¸āĻ‚āĻœā§āĻžāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻ•āĻ°āĻž āĻļā§‡āĻˇ āĻĢāĻžāĻ‚āĻļāĻ¨ āĻšāĻ˛ - Run:

// Run СаĐŋŅƒŅĐēĐ°ĐĩŅ‚ ĐŋŅ€ĐžŅ†ĐĩŅŅ ĐžĐļидаĐŊиŅ иСĐŧĐĩĐŊĐĩĐŊиК в ĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊŅŅ‚ваŅ… иĐŧŅ‘ĐŊ
// и Đ´ĐĩĐšŅŅ‚виŅ в ŅĐžĐžŅ‚вĐĩŅ‚ŅŅ‚вии Ņ ŅŅ‚иĐŧи иСĐŧĐĩĐŊĐĩĐŊиŅĐŧи.
func (c *NamespaceController) Run(stopCh <-chan struct{}, wg *sync.WaitGroup) {
  // КоĐŗĐ´Đ° ŅŅ‚Đ° Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ СавĐĩŅ€ŅˆĐĩĐŊĐ°, ĐŋĐžĐŧĐĩŅ‚иĐŧ ĐēĐ°Đē вŅ‹ĐŋĐžĐģĐŊĐĩĐŊĐŊŅƒŅŽ
  defer wg.Done()

  // ИĐŊĐēŅ€ĐĩĐŧĐĩĐŊŅ‚иŅ€ŅƒĐĩĐŧ wait group, Ņ‚.Đē. ŅĐžĐąĐ¸Ņ€Đ°ĐĩĐŧŅŅ вŅ‹ĐˇĐ˛Đ°Ņ‚ŅŒ goroutine
  wg.Add(1)

  // ВŅ‹ĐˇŅ‹Đ˛Đ°ĐĩĐŧ goroutine
  go c.namespaceInformer.Run(stopCh)

  // ОĐļидаĐĩĐŧ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиŅ ŅŅ‚ĐžĐŋ-ŅĐ¸ĐŗĐŊĐ°ĐģĐ°
  <-stopCh
}

(controller.go, āĻ‡āĻ¨ āĻ•āĻžāĻāĻšāĻž)

āĻāĻ–āĻžāĻ¨ā§‡ āĻ†āĻŽāĻ°āĻž āĻ•āĻĨāĻž āĻŦāĻ˛āĻ›āĻŋ WaitGroupāĻ¯ā§‡ āĻ†āĻŽāĻ°āĻž āĻ—ā§‹āĻ°ā§āĻŸāĻŋāĻ¨ āĻļā§āĻ°ā§ āĻ•āĻ°āĻŋ āĻāĻŦāĻ‚ āĻ¤āĻžāĻ°āĻĒāĻ° āĻ•āĻ˛ āĻ•āĻ°āĻŋ namespaceInformerāĻ¯āĻž āĻĒā§‚āĻ°ā§āĻŦā§‡ āĻ¸āĻ‚āĻœā§āĻžāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤ āĻ¯āĻ–āĻ¨ āĻāĻ•āĻŸāĻŋ āĻ¸ā§āĻŸāĻĒ āĻ¸āĻŋāĻ—āĻ¨ā§āĻ¯āĻžāĻ˛ āĻ†āĻ¸ā§‡, āĻāĻŸāĻŋ āĻĢāĻžāĻ‚āĻļāĻ¨āĻŸāĻŋ āĻļā§‡āĻˇ āĻ•āĻ°āĻŦā§‡, āĻœāĻžāĻ¨āĻŋāĻ¯āĻŧā§‡ āĻĻā§‡āĻŦā§‡ WaitGroup, āĻ¯āĻž āĻ†āĻ° āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ° āĻšāĻšā§āĻ›ā§‡ āĻ¨āĻž āĻāĻŦāĻ‚ āĻāĻ‡ āĻĢāĻžāĻ‚āĻļāĻ¨āĻŸāĻŋ āĻĒā§āĻ°āĻ¸ā§āĻĨāĻžāĻ¨ āĻ•āĻ°āĻŦā§‡āĨ¤

āĻāĻ•āĻŸāĻŋ Kubernetes āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°ā§‡ āĻāĻ‡ āĻŦāĻŋāĻŦā§ƒāĻ¤āĻŋāĻŸāĻŋ āĻ¨āĻŋāĻ°ā§āĻŽāĻžāĻŖ āĻāĻŦāĻ‚ āĻšāĻžāĻ˛āĻžāĻ¨ā§‹ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ¤āĻĨā§āĻ¯ āĻāĻ–āĻžāĻ¨ā§‡ āĻĒāĻžāĻ“āĻ¯āĻŧāĻž āĻ¯āĻžāĻŦā§‡ GitHub āĻ āĻ¸āĻ‚āĻ—ā§āĻ°āĻšāĻ¸ā§āĻĨāĻ˛.

āĻāĻ‡ āĻŦāĻŋāĻŦā§ƒāĻ¤āĻŋāĻ¤ā§‡, āĻ¯āĻž āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°ā§‡ RoleBinding āĻ•āĻ–āĻ¨ Namespace āĻāĻ•āĻŸāĻŋ Kubernetes āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°ā§‡, āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤āĨ¤

āĻ‰āĻ¤ā§āĻ¸: www.habr.com

āĻāĻ•āĻŸāĻŋ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻœā§āĻĄāĻŧā§āĻ¨