A’ sgrìobhadh gnìomhaiche airson Kubernetes ann an Golang

Thoir an aire. eadar-theangachadh.: Tha luchd-obrachaidh nam bathar-bog taice airson Kubernetes, air a dhealbhadh gus coileanadh ghnìomhan àbhaisteach air nithean cnuasachaidh a dhèanamh fèin-ghluasadach nuair a thachras tachartasan sònraichte. Tha sinn mu thràth air sgrìobhadh mu ghnìomhaichean ann an an artaigil seo, far an do bhruidhinn iad air bun-bheachdan agus prionnsapalan an cuid obrach. Ach nam biodh an stuth sin nas motha de shealladh bho thaobh a bhith ag obrachadh phàirtean deiseil airson Kubernetes, is e an eadar-theangachadh den artaigil ùr a tha air a mholadh a-nis lèirsinn leasaiche / innleadair DevOps a tha fo imcheist le buileachadh gnìomhaiche ùr.

A’ sgrìobhadh gnìomhaiche airson Kubernetes ann an Golang

Cho-dhùin mi am post seo a sgrìobhadh le eisimpleir fìor às deidh na h-oidhirpean agam sgrìobhainnean a lorg mu bhith a’ cruthachadh gnìomhaiche airson Kubernetes, a chaidh tro sgrùdadh a ’chòd.

Is e seo an eisimpleir a thèid a mhìneachadh: anns a’ bhuidheann Kubernetes againn, gach fear Namespace a’ riochdachadh àrainneachd bogsa gainmhich sgioba, agus bha sinn airson ruigsinneachd orra a chuingealachadh gus nach b’ urrainn do sgiobaidhean cluich ach anns na bogsaichean gainmhich aca fhèin.

Faodaidh tu na tha thu ag iarraidh a choileanadh le bhith a’ sònrachadh buidheann cleachdaiche aig a bheil RoleBinding gu sònraichte Namespace и ClusterRole le còraichean deasachaidh. Bidh riochdachadh YAML a’ coimhead mar seo:

---
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

(ròl-cheangail.yaml, ann amh)

Cruthaich aon RoleBinding Faodaidh tu a dhèanamh le làimh, ach às deidh dhut a dhol thairis air a’ chomharra ceud àite-ainm, bidh e na obair tedious. Seo far am bi gnìomhaichean Kubernetes feumail - leigidh iad leat cruthachadh ghoireasan Kubernetes a dhèanamh fèin-ghluasadach stèidhichte air atharrachaidhean air goireasan. Anns a 'chùis againn tha sinn airson a chruthachadh RoleBinding fhad 'sa tha e a' cruthachadh Namespace.

An toiseach, leig dhuinn an gnìomh a mhìneachadh maina nì an suidheachadh a tha a dhìth gus an aithris a ruith agus an uairsin gairm an aithris gnìomh:

(Thoir an aire. eadar-theangachadh.: an seo agus gu h-ìosal tha na beachdan sa chòd air an eadar-theangachadh gu Ruiseanach. A bharrachd air an sin, chaidh an indentation a cheartachadh gu àiteachan an àite tabaichean [air a mholadh ann an Go] a-mhàin airson a bhith furasta a leughadh taobh a-staigh cruth Habr. Às deidh gach liostadh tha ceanglaichean ris an fhear thùsail air GitHub, far a bheil beachdan agus tabaichean Beurla air an stòradh.)

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()   // Ожидаем, что все остановлено
}

(prìomh.go, ann amh)

Bidh sinn a’ dèanamh na leanas:

  1. Bidh sinn a’ rèiteachadh inneal-làimhseachaidh airson comharran siostam obrachaidh sònraichte gus crìoch gràsmhor a thoirt don ghnìomhaiche.
  2. Cleachd WaitGroupstad gu gràsmhor a h-uile goroutines mus cuir thu crìoch air an tagradh.
  3. Bidh sinn a’ toirt cothrom don bhuidheann le bhith a’ cruthachadh clientset.
  4. Cur air bhog NamespaceController, anns am bi ar loidsig uile air a suidheachadh.

A-nis feumaidh sinn bunait airson loidsig, agus anns a 'chùis againn is e seo am fear a chaidh ainmeachadh 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
}

(rianadair.go, ann amh)

An seo tha sinn a 'rèiteachadh SharedIndexInformer, a bhios gu h-èifeachdach (a’ cleachdadh tasgadan) a’ feitheamh ri atharraichean ann an ainmean-àite (leugh tuilleadh mu luchd-fiosrachaidh san artaigil"Ciamar a tha clàr-ama Kubernetes ag obair dha-rìribh?"- mu thuairmeas. eadar-theangachadh). Às deidh seo bidh sinn a 'ceangal EventHandler ris an neach-fiosrachaidh, gus nuair a chuireas tu àite-ainm (Namespace) theirear gnìomh createRoleBinding.

Is e an ath cheum an gnìomh seo a mhìneachadh 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))
  }
}

(rianadair.go, ann amh)

Gheibh sinn an t-ainm-àite mar obj agus tionndaidh e gu nì Namespace. An uairsin bidh sinn a 'mìneachadh RoleBinding, stèidhichte air an fhaidhle YAML a chaidh ainmeachadh aig an toiseach, a’ cleachdadh an nì a chaidh a thoirt seachad Namespace agus a' cruthachadh RoleBinding. Mu dheireadh, bidh sinn a 'clàradh an robh an cruthachadh soirbheachail.

Is e an gnìomh mu dheireadh a tha ri mhìneachadh 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
}

(rianadair.go, ann amh)

An seo tha sinn a 'bruidhinn WaitGroupgun cuir sinn air bhog an goroutine agus an uairsin gairm namespaceInformer, a chaidh a mhìneachadh roimhe seo. Nuair a ruigeas an comharra stad, cuiridh e crìoch air a’ ghnìomh, cuir fios WaitGroup, nach eil air a chur an gnìomh tuilleadh, agus falbhaidh an gnìomh seo.

Gheibhear fiosrachadh mu bhith a’ togail agus a’ ruith an aithris seo air cruinneachadh Kubernetes ann an stòran air GitHub.

Sin e airson a’ ghnìomhaiche a bhios a’ cruthachadh RoleBinding cuin Namespace ann an cruinneachadh Kubernetes, deiseil.

Source: www.habr.com

Cuir beachd ann