ืืขืจื. ืชืจืืื: ืืคืขืืืื ืื ืชืืื ืช ืขืืจ ืขืืืจ 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
ืืชื ืืืื ืืขืฉืืช ืืช ืื ืืื ืืช, ืืื ืืืืจ ืืฆืืืช ืืื ืืจืืื ืืฉืืืช, ืื ืืืคื ืืืฉืืื ืืืืืขืช. ืื ืืืงืื ืฉืื ืืคืขืืื 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() // ะะถะธะดะฐะตะผ, ััะพ ะฒัะต ะพััะฐะฝะพะฒะปะตะฝะพ
}
ืื ื ืขืืฉืื ืืช ืืคืขืืืืช ืืืืืช:
- ืื ื ืืืืืจืื ืืืคื ืืืืชืืช ืกืคืฆืืคืืื ืฉื ืืขืจืืช ืืคืขืื ืืื ืืืจืื ืืกืืื ืืื ื ื ืฉื ืืืคืขืื.
- ืืฉืชืืฉ
WaitGroup
ืืืคืกืืง ืืื ืืช ืื ืืืืจืืืื ืืคื ื ืกืืื ืืืืฉืื. - ืื ื ืืกืคืงืื ืืืฉื ืืืฉืืื ืขื ืืื ืืฆืืจื
clientset
. - ืจืืฅ
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
}
(
ืืื ืื ื ืืืืืจืื SharedIndexInformer
, ืืฉืจ ืืืขืฉื (ืืืืฆืขืืช ืืืืื) ืืืชืื ืืฉืื ืืืื ืืืจืืื ืืฉืืืช (ืงืจื ืขืื ืขื ืืืฉืื ืื ืืืืืจ "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))
}
}
(
ืื ืื ื ืืงืืืื ืืช ืืจืื ืืฉืืืช ื 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
}
(
ืืื ืื ืื ื ืืืืจืื WaitGroup
ืฉื ืคืขืื ืืช ืืืืจืืืื ืืื ื ืชืงืฉืจ namespaceInformer
, ืฉืืืืืจ ืืขืืจ. ืืืฉืจ ืืืช ืืขืฆืืจื ืืืืข, ืืื ืืกืืื ืืช ืืคืื ืงืฆืื, ืืืืข WaitGroup
, ืืฉืจ ืืื ื ืืืืฆืข ืืืชืจ, ืืืคืื ืงืฆืื ืืื ืชืฆื.
ืืืืข ืขื ืื ืืื ืืืคืขืื ืฉื ืืฆืืจื ืื ืืืฉืืื Kubernetes ื ืืชื ืืืฆืื ื
ืื ืืื ืขืืืจ ืืืคืขืื ืฉืืืฆืจ RoleBinding
ืืชื Namespace
ืืืฉืืื Kubernetes, ืืืื.
ืืงืืจ: www.habr.com