සටහන. පරිවර්තනය.: ක්රියාකරුවන් යනු Kubernetes සඳහා සහායක මෘදුකාංග වේ, ඇතැම් සිදුවීම් සිදු වූ විට පොකුරු වස්තු මත සාමාන්ය ක්රියාවන් ක්රියාත්මක කිරීම ස්වයංක්රීය කිරීමට නිර්මාණය කර ඇත. හි ක්රියාකරුවන් ගැන අපි දැනටමත් ලියා ඇත
මම මෙම ලිපිය ලිවීමට තීරණය කළේ කේතය අධ්යයනය කිරීම හරහා ගිය Kubernetes සඳහා ක්රියාකරුවෙකු නිර්මාණය කිරීම පිළිබඳ ලියකියවිලි සෙවීමට මගේ උත්සාහයෙන් පසුව සැබෑ ජීවිතයේ උදාහරණයක් සමඟිනි.
විස්තර කෙරෙන උදාහරණය මෙයයි: අපගේ 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
ඔබට එය අතින් කළ හැකි නමුත් නාම අවකාශ සියය ඉක්මවා ගිය පසු එය වෙහෙසකර කාර්යයක් බවට පත්වේ. Kubernetes ක්රියාකරුවන් ප්රයෝජනවත් වන්නේ මෙහිදීය - ඔවුන් ඔබට සම්පත් වල වෙනස්කම් මත පදනම්ව Kubernetes සම්පත් නිර්මාණය කිරීම ස්වයංක්රීය කිරීමට ඉඩ සලසයි. අපගේ නඩුවේදී අපි නිර්මාණය කිරීමට අවශ්යයි 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
යෙදුම අවසන් කිරීමට පෙර සියලුම goroutines අලංකාර ලෙස නතර කිරීමට. - අපි නිර්මාණය කිරීමෙන් පොකුරට ප්රවේශය ලබා දෙන්නෙමු
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
, එය තවදුරටත් ක්රියාත්මක නොවන අතර, මෙම ශ්රිතය පිටවේ.
Kubernetes පොකුරක් මත මෙම ප්රකාශය ගොඩනැගීම සහ ක්රියාත්මක කිරීම පිළිබඳ තොරතුරු සොයාගත හැකිය
නිර්මාණය කරන ක්රියාකරුට එයයි RoleBinding
කවදා ද Namespace
Kubernetes පොකුරේ, සූදානම්.
මූලාශ්රය: www.habr.com