በጎላንግ ውስጥ ለኩበርኔትስ ኦፕሬተር እንጽፋለን።

ማስታወሻ. ትርጉምኦፕሬተሮች ለኩበርኔትስ ረዳት ሶፍትዌሮች ናቸው ። ስለ ኦፕሬተሮች አስቀድመን ጽፈናል። ይህ ጽሑፍስለ ሥራቸው መሠረታዊ ሀሳቦች እና መርሆዎች የተናገሩበት ። ነገር ግን ያ ቁሳቁስ ለኩበርኔትስ ዝግጁ-የተሰሩ አካላት አሠራር ከጎን እይታ ከሆነ ፣ አሁን የቀረበው የአዲሱ ጽሑፍ ትርጉም የገንቢ / DevOps መሐንዲስ ራዕይ ነው ፣ በአዲሱ ኦፕሬተር ትግበራ ግራ ተጋብቷል ። .

በጎላንግ ውስጥ ለኩበርኔትስ ኦፕሬተር እንጽፋለን።

ለኩበርኔትስ ኦፕሬተር ለመፍጠር ሰነዶችን ለማግኘት ከሞከርኩ በኋላ ይህንን ጽሑፍ በእውነተኛ የሕይወት ምሳሌ ለመጻፍ ወሰንኩኝ ፣ በኮዱ ጥናት ውስጥ አልፈዋል።

የሚገለፀው ምሳሌ ይህ ነው-በእኛ 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

(ሚናቢንዲንግ.yaml, በ ውስጥ ጥሬ)

እንደዚህ አይነት ይፍጠሩ RoleBinding በእጅ ሊሰሩት ይችላሉ፣ ግን አንዴ ከመቶ በላይ የስም ቦታዎችን ካገኙ፣ አሰልቺ ስራ ይሆናል። ይህ የኩበርኔትስ ኦፕሬተሮች ምቹ ሆነው የሚመጡበት ነው - በሀብቶች ላይ በተደረጉ ለውጦች ላይ በመመስረት የ 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()   // Ожидаем, что все остановлено
}

(ዋና.ሂድ, በ ውስጥ ጥሬ)

የሚከተለውን እናደርጋለን።

  1. ኦፕሬተሩ በሚያምር ሁኔታ እንዲወጣ ለማድረግ ለተወሰኑ የስርዓተ ክወና ምልክቶች ተቆጣጣሪ አዘጋጅተናል።
  2. እንጠቀማለን WaitGroupአፕሊኬሽኑ ከማለቁ በፊት ሁሉንም ጎሮቲኖች በጸጋ ለማቆም።
  3. በመፍጠር ወደ ክላስተር መዳረሻ እንሰጣለን። clientset.
  4. አስጀምር 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ጎሮቲንን እንደጀመርን እና ከዚያም እንደደወልን namespaceInformerቀደም ሲል የተገለፀው. የማቆሚያ ምልክት ሲመጣ ተግባሩን ያበቃል ፣ ያሳውቁ WaitGroup, እሱም ከአሁን በኋላ እየፈጸመ አይደለም, እና ይህ ተግባር ይወጣል.

ይህንን መግለጫ በ Kubernetes ክላስተር ላይ ስለመገንባት እና ስለማስኬድ መረጃ በ ላይ ይገኛል። በ GitHub ላይ ማከማቻዎች.

በዚህ መግለጫ ላይ, ይህም ይፈጥራል RoleBinding መቼ Namespace በ Kubernetes ክላስተር ውስጥ ፣ ዝግጁ።

ምንጭ: hab.com

አስተያየት ያክሉ