குறிப்பு. மொழிபெயர்: ஆபரேட்டர்கள் என்பது குபெர்னெட்ஸிற்கான துணை மென்பொருளாகும், சில நிகழ்வுகள் நிகழும்போது கிளஸ்டர் பொருள்களில் வழக்கமான செயல்களை தானியங்குபடுத்துவதற்காக வடிவமைக்கப்பட்டுள்ளது. ஆபரேட்டர்களைப் பற்றி ஏற்கனவே எழுதியுள்ளோம்
குபெர்னெட்டஸுக்கு ஒரு ஆபரேட்டரை உருவாக்குவதற்கான ஆவணங்களைக் கண்டறியும் எனது முயற்சிகளுக்குப் பிறகு, நிஜ வாழ்க்கை உதாரணத்துடன் இந்த இடுகையை எழுத முடிவு செய்தேன், இது குறியீட்டைப் படித்தது.
விவரிக்கப்படும் உதாரணம் இதுதான்: எங்கள் குபெர்னெட்ஸ் கிளஸ்டரில், ஒவ்வொன்றும் 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
அறிக்கையை இயக்க தேவையான அமைப்பைச் செய்து, பின்னர் அறிக்கை செயலை அழைக்கிறது:
(குறிப்பு. மொழிபெயர்: இங்கே மற்றும் கீழே உள்ள குறியீட்டில் உள்ள கருத்துகள் ரஷ்ய மொழியில் மொழிபெயர்க்கப்பட்டுள்ளன. கூடுதலாக, ஹப்ர் தளவமைப்பிற்குள் சிறந்த வாசிப்புத்திறனுக்காக மட்டுமே [Go இல் பரிந்துரைக்கப்பட்ட] தாவல்களுக்குப் பதிலாக இடைவெளிகளுக்கு உள்தள்ளல் சரி செய்யப்பட்டது. ஒவ்வொரு பட்டியலுக்குப் பிறகும் 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
விண்ணப்பத்தை நிறுத்துவதற்கு முன் அனைத்து goroutine களையும் மனதார நிறுத்த. - உருவாக்குவதன் மூலம் கிளஸ்டருக்கான அணுகலை வழங்குகிறோம்
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
நாங்கள் goroutine ஐ துவக்கி பின்னர் அழைக்கிறோம் namespaceInformer
, இது முன்னர் வரையறுக்கப்பட்டது. ஸ்டாப் சிக்னல் வந்ததும், அது செயல்பாட்டை முடிக்கும், தெரிவிக்கும் WaitGroup
, இது இனி செயல்படுத்தப்படாது, மேலும் இந்த செயல்பாடு வெளியேறும்.
குபெர்னெட்ஸ் கிளஸ்டரில் இந்த அறிக்கையை உருவாக்குவது மற்றும் இயக்குவது பற்றிய தகவல்களைக் காணலாம்
ஆபரேட்டருக்கு அதுதான் உருவாக்குகிறது RoleBinding
எப்பொழுது Namespace
Kubernetes கிளஸ்டரில், தயார்.
ஆதாரம்: www.habr.com