เบเบฒเบ™เบ‚เบฝเบ™เบ•เบปเบงเบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบชเปเบฒเบฅเบฑเบš Kubernetes เปƒเบ™ Golang

เบซเบกเบฒเบโ€‹เป€เบซเบ”โ€‹. เปเบ›.: เบ•เบปเบงเบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เปเบกเปˆเบ™เบŠเบญเบšเปเบงเบŠเปˆเบงเบเป€เบซเบผเบทเบญเบชเปเบฒเบฅเบฑเบš Kubernetes, เบญเบญเบเปเบšเบšเบกเบฒเป€เบžเบทเปˆเบญเบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบ›เบปเบเบเบฐเบ•เบดเบเปˆเบฝเบงเบเบฑเบšเบงเบฑเบ”เบ–เบธ cluster เป€เบกเบทเปˆเบญเบกเบตเป€เบซเบ”เบเบฒเบ™เบชเบฐเป€เบžเบฒเบฐเปƒเบ”เบซเบ™เบถเปˆเบ‡เป€เบเบตเบ”เบ‚เบถเป‰เบ™. เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบ‚เบฝเบ™เปเบฅเป‰เบงเบเปˆเบฝเบงเบเบฑเบšเบœเบนเป‰เบ›เบฐเบเบญเบšเบเบฒเบ™เปƒเบ™ เบšเบปเบ”เบ‚เบฝเบ™เบ™เบตเป‰, เบšเปˆเบญเบ™เบ—เบตเปˆเป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเบชเบปเบ™เบ—เบฐเบ™เบฒเบเปˆเบฝเบงเบเบฑเบšเปเบ™เบงเบ„เบงเบฒเบกเบ„เบดเบ”เบžเบทเป‰เบ™เบ–เบฒเบ™เปเบฅเบฐเบซเบผเบฑเบเบเบฒเบ™เบ‚เบญเบ‡เบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบ‚เบญเบ‡เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒ. เปเบ•เปˆเบ–เป‰เบฒเบญเบธเบ›เบฐเบเบญเบ™เบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเป€เบ›เบฑเบ™เบกเบธเบกเป€เบšเบดเปˆเบ‡เบซเบผเบฒเบเบเบงเปˆเบฒเบ”เป‰เบฒเบ™เบ‚เบญเบ‡เบญเบปเบ‡เบ›เบฐเบเบญเบšเบ—เบตเปˆเบเบฝเบกเบžเป‰เบญเบกเบชเปเบฒเบฅเบฑเบš Kubernetes, เบเบฒเบ™เปเบ›เบšเบปเบ”เบ„เบงเบฒเบกเปƒเบซเบกเปˆเบ—เบตเปˆเบชเบฐเป€เบซเบ™เบตเปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เปเบกเปˆเบ™เป€เบ›เบฑเบ™เบงเบดเป„เบชเบ—เบฑเบ”เบ‚เบญเบ‡เบœเบนเป‰เบžเบฑเบ”เบ—เบฐเบ™เบฒ / เบงเบดเบชเบฐเบงเบฐเบเบญเบ™ DevOps เบ—เบตเปˆเบชเบฑเบšเบชเบปเบ™เบเบฑเบšเบเบฒเบ™เบˆเบฑเบ”เบ•เบฑเป‰เบ‡เบ›เบฐเบ•เบดเบšเบฑเบ”เบ•เบปเบงเบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เปƒเบซเบกเปˆ.

เบเบฒเบ™เบ‚เบฝเบ™เบ•เบปเบงเบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบชเปเบฒเบฅเบฑเบš Kubernetes เปƒเบ™ Golang

เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบ•เบฑเบ”เบชเบดเบ™เปƒเบˆเบ‚เบฝเบ™เบ‚เปเป‰เบ„เบงเบฒเบกเบ™เบตเป‰เบ”เป‰เบงเบเบ•เบปเบงเบขเปˆเบฒเบ‡เบŠเบตเบงเบดเบ”เบˆเบดเบ‡เบซเบผเบฑเบ‡เบˆเบฒเบเบ„เบงเบฒเบกเบžเบฐเบเบฒเบเบฒเบกเบ‚เบญเบ‡เบ‚เป‰เบญเบเป€เบžเบทเปˆเบญเบŠเบญเบเบซเบฒเป€เบญเบเบฐเบชเบฒเบ™เบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบชเป‰เบฒเบ‡เบ•เบปเบงเบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบชเปเบฒเบฅเบฑเบš Kubernetes, เป€เบŠเบดเปˆเบ‡เป„เบ”เป‰เบœเปˆเบฒเบ™เบเบฒเบ™เบชเบถเบเบชเบฒเบฅเบฐเบซเบฑเบ”.

เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเปˆเบˆเบฐเบ–เบทเบเบญเบฐเบ—เบดเบšเบฒเบเบ™เบตเป‰เปเบกเปˆเบ™: เปƒเบ™เบเบธเปˆเบก Kubernetes เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ, เปเบ•เปˆเบฅเบฐเบ„เบปเบ™ Namespace เป€เบ›เบฑเบ™เบ•เบปเบงเปเบ—เบ™เบ‚เบญเบ‡เบชเบฐเบžเบฒเบšเปเบงเบ”เบฅเป‰เบญเบก sandbox เบ‚เบญเบ‡เบ—เบตเบกเบ‡เบฒเบ™, เปเบฅเบฐเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบˆเปเบฒเบเบฑเบ”เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เปƒเบซเป‰เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเป€เบžเบทเปˆเบญเปƒเบซเป‰เบ—เบตเบกเบ‡เบฒเบ™เบชเบฒเบกเบฒเบ”เบซเบผเบดเป‰เบ™เปƒเบ™ sandbox เบ‚เบญเบ‡เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเป€เบญเบ‡เป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™.

เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบšเบฑเบ™เบฅเบธเบชเบดเปˆเบ‡เบ—เบตเปˆเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เป‚เบ”เบเบเบฒเบ™เบกเบญเบšเบซเบกเบฒเบเปƒเบซเป‰เบœเบนเป‰เปƒเบŠเป‰เบเบธเปˆเบกเบ—เบตเปˆเบกเบต 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 เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เป€เบฎเบฑเบ”เป„เบ”เป‰เบ”เป‰เบงเบเบ•เบปเบ™เป€เบญเบ‡, เปเบ•เปˆเบซเบผเบฑเบ‡เบˆเบฒเบเบ‚เป‰เบฒเบกเบฎเป‰เบญเบ namespaces, เบกเบฑเบ™เบเบฒเบเป€เบ›เบฑเบ™เบงเบฝเบเบ‡เบฒเบ™เบ—เบตเปˆเบซเบ™เป‰เบฒเป€เบšเบทเปˆเบญ. เบ™เบตเป‰เปเบกเปˆเบ™เบšเปˆเบญเบ™เบ—เบตเปˆเบœเบนเป‰เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™ Kubernetes เบกเบตเบ›เบฐเป‚เบซเบเบ” - เบžเบงเบเป€เบ‚เบปเบฒเบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ—เปˆเบฒเบ™เบชเป‰เบฒเบ‡เบŠเบฑเบšเบžเบฐเบเบฒเบเบญเบ™ Kubernetes เป‚เบ”เบเบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เป‚เบ”เบเบญเบตเบ‡เปƒเบชเปˆเบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบŠเบฑเบšเบžเบฐเบเบฒเบเบญเบ™. เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบชเป‰เบฒเบ‡ RoleBinding เปƒเบ™เบ‚เบฐเบ™เบฐเบ—เบตเปˆเบชเป‰เบฒเบ‡ Namespace.

เบเปˆเบญเบ™เบญเบทเปˆเบ™ เปเบปเบ”, เปƒเบซเป‰ เบเบณ เบ™เบปเบ” เปœเป‰เบฒ เบ—เบตเปˆ mainเป€เบŠเบดเปˆเบ‡เป€เบฎเบฑเบ”เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ—เบตเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™เป€เบžเบทเปˆเบญเปเบฅเปˆเบ™เบ„เบณเบ–เบฐเปเบซเบผเบ‡ เปเบฅเบฐเบˆเบฒเบเบ™เบฑเป‰เบ™เป€เบญเบตเป‰เบ™เบ„เบณเบชเบฑเปˆเบ‡เบ„เบณเบชเบฑเปˆเบ‡:

(เบซเบกเบฒเบโ€‹เป€เบซเบ”โ€‹. เปเบ›.: เบ—เบตเปˆเบ™เบตเป‰เปเบฅเบฐเบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰เบ„เปเบฒเป€เบซเบฑเบ™เปƒเบ™เบฅเบฐเบซเบฑเบ”เป„เบ”เป‰เบ–เบทเบเปเบ›เป€เบ›เบฑเบ™เบžเบฒเบชเบฒเบฅเบฑเบ”เป€เบŠเบ. เบ™เบญเบเบˆเบฒเบเบ™เบฑเป‰เบ™, เบเบฒเบ™เบซเบเปเป‰เปœเป‰เบฒเป„เบ”เป‰เบ–เบทเบเปเบเป‰เป„เบ‚เปƒเบชเปˆเบŠเปˆเบญเบ‡เบซเบงเปˆเบฒเบ‡เปเบ—เบ™เบ—เบตเปˆเบˆเบฐเป€เบ›เบฑเบ™เปเบ–เบš [เปเบ™เบฐเบ™เปเบฒเปƒเบ™ Go] เป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™เป€เบžเบทเปˆเบญเบˆเบธเบ”เบ›เบฐเบชเบปเบ‡เบ‚เบญเบ‡เบเบฒเบ™เบญเปˆเบฒเบ™เบ—เบตเปˆเบ”เบตเบ‚เบถเป‰เบ™เบžเบฒเบเปƒเบ™เบฎเบนเบšเปเบšเบš 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เป€เบžเบทเปˆเบญเบขเบธเบ”เป€เบŠเบปเบฒเบเบฒเบ™ goroutines เบ—เบฑเบ‡เบซเบกเบปเบ”เบขเปˆเบฒเบ‡เบชเบฐเบซเบ‡เปˆเบฒเบ‡เบฒเบกเบเปˆเบญเบ™เบ—เบตเปˆเบˆเบฐเบ›เบดเบ”เบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบ.
  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, เปƒเบ™ เบงเบฑเบ”เบ–เบธเบ”เบดเบš)

เบ—เบตเปˆเบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒ configure SharedIndexInformer, เป€เบŠเบดเปˆเบ‡เบˆเบฐเบกเบตเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบš (เปƒเบŠเป‰ cache) เบฅเปเบ–เป‰เบฒเบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เปƒเบ™ namespaces (เบญเปˆเบฒเบ™เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบเปˆเบฝเบงเบเบฑเบšเบœเบนเป‰เปƒเบซเป‰เบ‚เปเป‰เบกเบนเบ™เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบก "เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เป€เบงเบฅเบฒ Kubernetes เป€เบฎเบฑเบ”เบงเบฝเบเปเบ™เบงเปƒเบ”?"- เบ›เบฐเบกเบฒเบ™ เบเบฒเบ™เปเบ›). เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเป€เบŠเบทเปˆเบญเบกเบ•เปเปˆ EventHandler เบ•เปเปˆเบเบฑเบšเบœเบนเป‰เปƒเบซเป‰เบ‚เปเป‰เบกเบนเบ™, เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เป€เบกเบทเปˆเบญเป€เบžเบตเปˆเบก namespace (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, เปƒเบ™ เบงเบฑเบ”เบ–เบธเบ”เบดเบš)

เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบฎเบฑเบš namespace เป€เบ›เบฑเบ™ 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เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเป€เบ›เบตเบ” goroutine เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เป‚เบ—เบซเบฒ namespaceInformer, เป€เบŠเบดเปˆเบ‡เป„เบ”เป‰เบ–เบทเบเบเปเบฒเบ™เบปเบ”เป„เบงเป‰เบเปˆเบญเบ™เบซเบ™เป‰เบฒเบ™เบตเป‰. เป€เบกเบทเปˆเบญเบชเบฑเบ™เบเบฒเบ™เบขเบธเบ”เบกเบฒเบฎเบญเบ”, เบกเบฑเบ™เบˆเบฐเบชเบดเป‰เบ™เบชเบธเบ”เบเบฒเบ™เบ—เปเบฒเบ‡เบฒเบ™, เปเบˆเป‰เบ‡ WaitGroup, เป€เบŠเบดเปˆเบ‡เบšเปเปˆเบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”เบญเบตเบเบ•เปเปˆเป„เบ›, เปเบฅเบฐเบŸเบฑเบ‡เบŠเบฑเบ™เบ™เบตเป‰เบˆเบฐเบญเบญเบ.

เบ‚เปเป‰เบกเบนเบ™เบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบชเป‰เบฒเบ‡ เปเบฅเบฐเปเบฅเปˆเบ™เบ„เบณเบ–เบฐเปเบซเบผเบ‡เบ™เบตเป‰เบขเบนเปˆเปƒเบ™เบเบธเปˆเบก Kubernetes เบชเบฒเบกเบฒเบ”เบžเบปเบšเป„เบ”เป‰เปƒเบ™ repositories เปƒเบ™ GitHub.

เบ™เบฑเป‰เบ™เปเบกเปˆเบ™เบกเบฑเบ™เบชเปเบฒเบฅเบฑเบšเบœเบนเป‰เบ›เบฐเบเบญเบšเบเบฒเบ™เบ—เบตเปˆเบชเป‰เบฒเบ‡ RoleBinding เป€เบกเบทเปˆเบญโ€‹เปƒเบ”โ€‹ Namespace เปƒเบ™เบเบธเปˆเบก Kubernetes, เบžเป‰เบญเบกเปเบฅเป‰เบง.

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™