Kumbuka. tafsiri.Waendeshaji ni programu saidizi ya Kubernetes iliyoundwa kugeuza vitendo vya kawaida kwenye vitu vya nguzo matukio fulani yanapotokea. Tayari tumeandika kuhusu waendeshaji katika , ambayo ilijadili mawazo ya msingi na kanuni za uendeshaji. Lakini ingawa nyenzo hiyo ilikuwa ya mtazamo zaidi kutoka kwa mtazamo wa uendeshaji wa vipengele vya Kubernetes vilivyotengenezwa tayari, tafsiri inayopendekezwa ya makala haya mapya ni mtazamo wa msanidi/mhandisi wa DevOps, aliyeshangazwa na utekelezaji wa opereta mpya.

Niliamua kuandika chapisho hili na mfano wa ulimwengu halisi baada ya majaribio yangu ya kupata hati juu ya kuunda opereta kwa Kubernetes, ambayo ilisababisha nisome msimbo.
Mfano ambao utaelezewa ni huu: katika nguzo yetu ya Kubernetes, kila moja Namespace inawakilisha mazingira ya kisanduku cha mchanga cha timu, na tulitaka kuzuia ufikiaji kwao ili timu zicheze tu katika visanduku vyao vya mchanga.
Matokeo yanayotarajiwa yanaweza kupatikana kwa kumpa mtumiaji kikundi ambacho kina RoleBinding kwa maalum Namespace и ClusterRole na haki za uhariri. Uwakilishi wa YAML utaonekana kama hii:
---
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(ndani )
Ili kuunda vile RoleBinding Unaweza kufanya hivi kwa mikono, lakini baada ya kuvuka alama ya nafasi ya majina 100, inakuwa ya kuchosha. Hapa ndipo waendeshaji wa Kubernetes huja kwa manufaa—wanakuruhusu kuhariri uundaji wa rasilimali za Kubernetes kulingana na mabadiliko ya rasilimali. Kwa upande wetu, tunataka kuunda RoleBinding wakati wa kuunda Namespace.
Kwanza kabisa, hebu tufafanue kazi main, ambayo hufanya usanidi unaohitajika ili kuendesha opereta na kisha kuomba kitendo cha mwendeshaji:
(Kumbuka. tafsiri.: Kuanzia hapa, maoni katika kanuni yametafsiriwa kwa Kirusi. Zaidi ya hayo, ujongezaji umebadilishwa hadi nafasi badala ya vichupo [inapendekezwa katika Go] kwa madhumuni ya kuboresha usomaji ndani ya mpangilio wa Habr. Kufuatia kila tangazo ni viungo vya msimbo asili wa GitHub, ambapo maoni na vichupo vya Kiingereza huhifadhiwa.
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() // Ожидаем, что все остановлено
}(ndani )
Tunafanya yafuatayo:
- Tunasanidi kidhibiti kwa mawimbi mahususi ya mfumo wa uendeshaji ili kusababisha kusitishwa kwa njia nzuri kwa opereta.
- Tunatumia
WaitGroupili kusimamisha kwa uzuri taratibu zote kabla ya programu kukomesha. - Tunatoa ufikiaji wa nguzo kwa kuunda
clientset. - Uzinduzi
NamespaceController, ambayo mantiki yetu yote itakuwa iko.
Sasa tunahitaji msingi wa mantiki, na kwa upande wetu ndio uliotajwa 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
}(ndani )
Hapa tunaweka SharedIndexInformer, ambayo itasubiri kwa ufanisi (kwa kutumia kache) mabadiliko katika nafasi za majina (soma zaidi kuhusu watoa habari katika makala ""- takriban. tafsiri)Baada ya hayo tunaunganisha EventHandler kwa mtoaji habari, ili wakati wa kuongeza nafasi ya jina (Namespace) kazi inaitwa createRoleBinding.
Hatua inayofuata ni kufafanua kazi hii 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))
}
}(ndani )
Tunapata nafasi ya majina kama obj na kuibadilisha kuwa kitu Namespace. Kisha tunaamua RoleBinding, kulingana na faili ya YAML iliyotajwa mwanzoni, kwa kutumia kitu kilichotolewa Namespace na kuunda RoleBindingHatimaye, tunaandika kama uumbaji ulifanikiwa.
Kazi ya mwisho ambayo inahitaji kufafanuliwa ni 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
}(ndani )
Hapa tunazungumza WaitGroup, kwamba tunaanza goroutine na kisha piga simu namespaceInformer, ambayo ilifafanuliwa hapo awali. Wakati ishara ya kuacha inapokelewa, itasitisha kazi, ripoti WaitGroup, ambayo haifanyi kazi tena, na chaguo la kukokotoa litakoma.
Taarifa juu ya kujenga na kuendesha opereta huyu katika nguzo ya Kubernetes inaweza kupatikana katika .
Juu ya operator hii, ambayo inajenga RoleBinding juu ya kuonekana Namespace katika kundi la Kubernetes, tayari.
Chanzo: mapenzi.com
