Nota. transl.: Operatores programmatis auxiliares sunt Kubernetes, qui automate constituunt executionem actionum usuum in glomeris obiectis cum certae res eveniunt. Iam de operariis in
Hanc epistulam scribere decrevi exemplo verae vitae, postquam conatus meos invenire documentum in creando operante Kubernetes, qui per studium codicis accessit.
Exemplum quod describendum est hoc est: in nostro botro Kubernetes Namespace
environment sandbox team repraesentat, et accessum ad eos limitare voluimus ut iugis in suis sandboxes tantum ludere posset.
Potes consequi quod vis, assignando usorem coetui qui habet RoleBinding
ad specifica Namespace
и ClusterRole
cum iura emendo. YAML repraesentatio sic erit:
---
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
(
Crea unum RoleBinding
Manually facere potes, sed post centum spatiorum nomina transmisso, longum fit negotium. Haec ubi operarii Kubernetes in promptu veniunt - te permittunt creandi Kubernetes facultates quae in mutationibus facultatum sunt. In casu nostro volumus creare RoleBinding
dum creando Namespace
.
Primum munus definiamus main
quae facit requiritur setup ut run enuntiatio et inde vocat actionem enuntiationis:
(Nota. transl.commenta in codice Russico translata hic et infra. Praeterea incisum correctum est ad spatia pro tabs unice ad melioris promptitudinis causa intra Habr layout. Post singulas enumeratas nexus sunt cum originali in GitHub, ubi in lingua Anglica commenta et tabs reponuntur.
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() // Ожидаем, что все остановлено
}
Facimus quae sequuntur;
- Nos tracto configuramus pro certis significationibus operandi rationi, ut jucundam efficiat operantis terminationem.
- Utimur
WaitGroup
ut lepide desinas omnes goroutines ante applicationem terminandi. - Botrus creando aditum praebemus
clientset
. - Launch
NamespaceController
in quo omnis nostra logica collocabitur.
Nunc logicae fundamento indigemus, et in casu nostro haec est mentio 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
}
(
Hic configuramus SharedIndexInformer
quae efficaciter (cache utendo) mutationes in spatiis nominalibus exspectant (Lege de indicibus in articulum "EventHandler
delatori, ut cum spatio addito (Namespace
) Munus dicitur createRoleBinding
.
Proximus gradus est definire hoc munus 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))
}
}
(
Nos adepto in spatio nominali ut obj
et convertam ad objectum Namespace
. Deinde definimus RoleBinding
, fundatur in YAML fasciculus, de quo in principio, utens objecto provisum Namespace
et creando RoleBinding
. Denique inspicimus utrum creatio felix fuerit.
Munus extremum definiendum est 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
}
(
Hic loquimur WaitGroup
quod deducunt goroutine et vocamus namespaceInformer
quod prius definitum est. Cum signum statur advenit, munus finiet, certiorem facit WaitGroup
quod iam non est, et hoc munus exibit.
Informationes de aedificatione et currendo hanc propositionem in botro Kubernetes inveniri possunt
Id enim auctor creat RoleBinding
quod Namespace
in Kubernetes botrum, paratum.
Source: www.habr.com