Scríobh oibreoir do Kubernetes i Golang

Nóta. aistrigh.: Is bogearraí cúnta iad oibreoirí do Kubernetes, atá deartha chun feidhmiú gnáthghníomhaíochtaí ar réada braisle a uathoibriú nuair a tharlaíonn imeachtaí áirithe. Scríobhamar cheana faoi oibreoirí i an t-alt seo, áit ar labhair siad faoi bhunsmaointe agus faoi phrionsabail a gcuid oibre. Ach dá mba mhó an dearcadh a bhí ag an ábhar sin ó thaobh oibriúcháin na gcomhpháirteanna réamhdhéanta do Kubernetes, is é an t-aistriúchán ar an ailt nua atá molta anois ná fís an fhorbróra/innealtóra DevOps a bhfuil cur i bhfeidhm oibreora nua ag baint leis.

Scríobh oibreoir do Kubernetes i Golang

Chinn mé an post seo a scríobh le sampla fíor-saoil tar éis mo chuid iarrachtaí doiciméadú a aimsiú maidir le hoibreoir a chruthú do Kubernetes, a chuaigh trí staidéar a dhéanamh ar an gcód.

Is é seo an sampla a ndéanfar cur síos air: inár mbraisle Kubernetes, gach ceann acu Namespace is ionann é agus timpeallacht bosca gainimh foirne, agus theastaigh uainn rochtain orthu a theorannú ionas nach bhféadfadh foirne imirt ach ina mboscaí gainimh féin.

Is féidir leat an méid a theastaíonn uait a bhaint amach trí ghrúpa a bhfuil úsáideoir aige a shannadh RoleBinding go sonrach Namespace и ClusterRole le cearta eagarthóireachta. Beidh cuma mar seo ar an léiriú 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

(rólcheangal.yamlI amh)

Cruthaigh ceann RoleBinding Is féidir leat é a dhéanamh de láimh, ach tar éis an marc céad spásanna a thrasnú, bíonn sé ina tasc tedious. Seo an áit a mbíonn oibreoirí Kubernetes áisiúil - ligeann siad duit cruthú acmhainní Kubernetes a uathoibriú bunaithe ar athruithe ar acmhainní. In ár gcás ba mhaith linn a chruthú RoleBinding agus iad ag cruthú Namespace.

Ar an gcéad dul síos, déanaimis an fheidhm a shainiú maina dhéanann an socrú riachtanach chun an ráiteas a rith agus a ghlaonn ansin gníomh an ráitis:

(Nóta. aistrigh.: anseo agus thíos aistrítear na tuairimí sa chód go Rúisis. Ina theannta sin, ceartaíodh an eangú go spásanna in ionad cluaisíní [a mholtar in Go] chun críche inléiteacht níos fearr laistigh de leagan amach Habr amháin. Tar éis gach liostú tá naisc leis an gceann bunaidh ar GitHub, áit a stóráiltear tuairimí agus cluaisíní Béarla.)

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.goI amh)

Déanaimid na rudaí seo a leanas:

  1. Déanaimid láimhseálaí a chumrú le haghaidh comharthaí córais oibriúcháin ar leith chun an t-oibreoir a fhoirceannadh go galánta.
  2. úsáidimid WaitGroupchun stop a chur le gach goroutines roimh fhoirceannadh an iarratais.
  3. Cuirimid rochtain ar an mbraisle ar fáil trí chruthú clientset.
  4. Seoladh NamespaceController, ina mbeidh ár loighic go léir suite.

Anois ní mór dúinn bunús le haghaidh loighic, agus inár gcás is é seo an ceann atá luaite 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
}

(rialtóir.goI amh)

Anseo táimid ag cumrú SharedIndexInformer, a fhanfaidh go héifeachtach (ag baint úsáide as taisce) le hathruithe ar spásanna ainmneacha (léigh tuilleadh faoi fhaisnéiseoirí san alt “Conas a oibríonn sceidealóir Kubernetes i ndáiríre?"- thart. aistriúchán). Tar éis seo déanaimid ceangal EventHandler chuig an bhfaisnéiseoir, ionas gur féidir nuair a chuirtear ainmspás (Namespace) feidhm a thugtar air createRoleBinding.

Is é an chéad chéim eile an fheidhm seo a shainiú 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))
  }
}

(rialtóir.goI amh)

Faighimid an t-ainmspás mar obj agus é a thiontú go réad Namespace. Ansin muid a shainiú RoleBinding, bunaithe ar an gcomhad YAML a luadh ag an tús, ag baint úsáide as an réad ar fáil Namespace agus ag cruthú RoleBinding. Ar deireadh, déanaimid logáil isteach cibé an raibh an cruthú rathúil.

Is é an fheidhm dheireanach atá le sainiú 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
}

(rialtóir.goI amh)

Anseo táimid ag caint WaitGroupgo seolfaimid an goroutine agus ansin glaoch namespaceInformer, atá sainmhínithe roimhe seo. Nuair a thagann an comhartha stad, cuirfidh sé deireadh leis an bhfeidhm, cuir in iúl WaitGroup, nach ndéantar a thuilleadh, agus scoirfidh an fheidhm seo.

Tá faisnéis maidir leis an ráiteas seo a thógáil agus a rith ar bhraisle Kubernetes le fáil i stórtha ar GitHub.

Sin é don oibreoir a chruthaíonn RoleBinding Cathain Namespace i mbraisle Kubernetes, réidh.

Foinse: will.com

Add a comment