Catetan. narjamahkeun.: Operator mangrupakeun software bantu pikeun Kubernetes, dirancang pikeun ngajadikeun otomatis palaksanaan lampah rutin dina objék klaster lamun kajadian tangtu lumangsung. Kami parantos nyerat ngeunaan operator di
Kuring mutuskeun nulis pos ieu kalawan conto real-hirup sanggeus usaha kuring pikeun manggihan dokuméntasi dina nyieun hiji operator pikeun Kubernetes, nu indit ngaliwatan diajar kode.
Conto anu bakal dijelaskeun nyaéta kieu: dina klaster Kubernetes kami, masing-masing Namespace
ngagambarkeun lingkungan sandbox tim urang, sarta kami hayang ngawatesan aksés ka aranjeunna supados tim ngan bisa maénkeun dina sandboxes sorangan.
Anjeun tiasa ngahontal naon anu anjeun pikahoyong ku masihan pangguna grup anu gaduh RoleBinding
pikeun husus Namespace
и ClusterRole
kalawan hak ngédit. Perwakilan YAML bakal katingali sapertos kieu:
---
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
(
Jieun hiji RoleBinding
Anjeun tiasa ngalakukeunana sacara manual, tapi saatos nyebrang saratus nami rohangan, éta janten tugas anu pikasieuneun. Ieu tempat operator Kubernetes tiasa dianggo-aranjeunna ngamungkinkeun anjeun pikeun ngajadikeun otomatis nyiptakeun sumber daya Kubernetes dumasar kana parobihan sumber. Bisi kami urang rék nyieun RoleBinding
bari nyieun Namespace
.
Anu mimiti, hayu urang nangtukeun fungsi main
anu ngalakukeun pangaturan anu diperyogikeun pikeun ngajalankeun pernyataan teras nyauran tindakan pernyataan:
(Catetan. narjamahkeun.: Ieuh jeung handap komentar dina kode nu ditarjamahkeun kana Rusia. Sajaba ti éta, indentation geus dilereskeun kana spasi tinimbang [dianjurkeun dina Go] tab solely pikeun kaperluan readability hadé dina perenah Habr. Saatos unggal daptar aya tautan kana anu asli dina GitHub, dimana koméntar sareng tab dina basa Inggris disimpen.)
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() // Ожидаем, что все остановлено
}
Urang ngalakukeun ieu:
- Urang ngonpigurasikeun pawang pikeun sinyal sistem operasi husus pikeun ngabalukarkeun terminasi anggun operator.
- Urang make
WaitGroup
pikeun gracefully ngeureunkeun sagala goroutine saméméh terminating aplikasi. - Urang nyadiakeun aksés ka klaster ku nyieun
clientset
. - Ngaluncurkeun
NamespaceController
, dimana sadaya logika urang bakal aya.
Ayeuna urang peryogi dasar pikeun logika, sareng dina hal urang ieu anu disebatkeun 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
}
(
Di dieu urang ngonpigurasikeun SharedIndexInformer
, nu bakal éféktif (ngagunakeun cache a) ngantosan parobahan dina spasi ngaran (baca langkung seueur ngeunaan informan dina tulisan "EventHandler
ka informer, ku kituna lamun nambahkeun spasi ngaran (Namespace
) fungsi disebut createRoleBinding
.
Lengkah saterusna nyaéta nangtukeun fungsi ieu 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))
}
}
(
Simkuring meunang ngaranspasi salaku obj
sarta ngarobahna kana hiji obyék Namespace
. Teras we ngartikeun RoleBinding
, dumasar kana file YAML disebutkeun di awal, ngagunakeun objék disadiakeun Namespace
jeung nyiptakeun RoleBinding
. Tungtungna, urang log naha kreasi éta suksés.
Fungsi anu terakhir anu ditetepkeun nyaéta 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
}
(
Di dieu urang ngobrol WaitGroup
yén urang ngajalankeun goroutine lajeng nelepon namespaceInformer
, nu geus didefinisikeun saméméhna. Nalika sinyal eureun datang, éta bakal mungkas fungsi, ngawartosan WaitGroup
, nu geus euweuh dieksekusi, sarta fungsi ieu bakal kaluar.
Inpormasi ngeunaan ngawangun sareng ngajalankeun pernyataan ieu dina klaster Kubernetes tiasa dipendakan dina
Éta pikeun operator anu nyiptakeun RoleBinding
iraha Namespace
dina klaster Kubernetes, siap.
sumber: www.habr.com