نوٽ. ترجمو: آپريٽرز 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
توهان اهو دستي طور تي ڪري سگهو ٿا، پر سو نالو اسپيس جي نشان کي پار ڪرڻ کان پوء، اهو هڪ مشڪل ڪم بڻجي ويندو آهي. هي اهو آهي جتي ڪبرنيٽس آپريٽرز ڪم ۾ اچن ٿا- اهي توهان کي اجازت ڏين ٿا ته ڪبرنيٽس وسيلن جي تخليق کي خودڪار ڪرڻ جي بنياد تي وسيلن ۾ تبديليون. اسان جي صورت ۾ اسان ٺاهڻ چاهيون ٿا RoleBinding
ٺاهڻ دوران Namespace
.
سڀ کان پهريان، اچو ته فنڪشن جي وضاحت ڪريون main
جيڪو بيان کي هلائڻ لاءِ گهربل سيٽ اپ ڪري ٿو ۽ پوءِ بيان عمل کي سڏي ٿو:
(نوٽ. ترجمو: هتي ۽ هيٺ ڏنل تبصرا ڪوڊ ۾ ترجمو ڪيا ويا آهن روسي ۾. ان کان علاوه، انڊينٽيشن کي درست ڪيو ويو آهي خالن جي بجاءِ [گو ۾ تجويز ڪيل] ٽيب جي مقصد لاءِ صرف هيبر جي ترتيب ۾ بهتر پڙهڻ جي. هر لسٽنگ کان پوءِ 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
informer ڏانهن، ته جيئن هڪ نالي جي جاء شامل ڪرڻ وقت (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
, جنهن کي هاڻي جاري نه ڪيو ويو آهي، ۽ هي فنڪشن نڪرندو.
ڪبرنيٽس ڪلستر تي هن بيان جي تعمير ۽ هلائڻ بابت معلومات ملي سگهي ٿي
اھو اھو آھي جيڪو ٺاھيندڙ آپريٽر لاءِ RoleBinding
ڪڏهن Namespace
ڪبرنيٽس ڪلستر ۾، تيار.
جو ذريعو: www.habr.com