Kikọ oniṣẹ ẹrọ kan fun Kubernetes ni Golang

Akiyesi. itumọ.Awọn oniṣẹ jẹ sọfitiwia oluranlọwọ fun Kubernetes, ti a ṣe apẹrẹ lati ṣe adaṣe adaṣe ti awọn iṣe deede lori awọn nkan iṣupọ nigbati awọn iṣẹlẹ kan waye. A ti kọ tẹlẹ nipa awọn oniṣẹ ninu Arokọ yi, nibiti wọn ti sọrọ nipa awọn imọran ipilẹ ati awọn ilana ti iṣẹ wọn. Ṣugbọn ti ohun elo yẹn ba jẹ wiwo diẹ sii lati ẹgbẹ ti ṣiṣiṣẹ awọn ohun elo ti a ti ṣetan fun Kubernetes, lẹhinna itumọ ti nkan tuntun ti a dabaa ti tẹlẹ iran ti olupilẹṣẹ / ẹlẹrọ DevOps kan daamu nipasẹ imuse ti oniṣẹ tuntun kan.

Kikọ oniṣẹ ẹrọ kan fun Kubernetes ni Golang

Mo pinnu lati kọ ifiweranṣẹ yii pẹlu apẹẹrẹ igbesi aye gidi lẹhin awọn igbiyanju mi ​​lati wa iwe lori ṣiṣẹda oniṣẹ kan fun Kubernetes, eyiti o lọ nipasẹ kikọ koodu naa.

Apẹẹrẹ ti yoo ṣe apejuwe ni eyi: ninu iṣupọ Kubernetes wa, ọkọọkan Namespace duro fun agbegbe iyanrin ti ẹgbẹ kan, ati pe a fẹ lati ṣe idinwo iwọle si wọn ki awọn ẹgbẹ le ṣere nikan ni awọn apoti iyanrin tiwọn.

O le ṣaṣeyọri ohun ti o fẹ nipa yiyan olumulo kan ẹgbẹ ti o ni RoleBinding si pato Namespace и ClusterRole pẹlu awọn ẹtọ atunṣe. Aṣoju YAML yoo dabi eleyi:

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

(ipa-ipa.yamlninu aise)

Ṣẹda ọkan RoleBinding O le ṣe pẹlu ọwọ, ṣugbọn lẹhin ti o ti kọja aami awọn aaye orukọ ọgọrun, o di iṣẹ apọn. Eyi ni ibi ti awọn oniṣẹ Kubernetes wa ni ọwọ-wọn gba ọ laaye lati ṣe adaṣe ẹda ti awọn orisun Kubernetes ti o da lori awọn iyipada si awọn orisun. Ninu ọran wa a fẹ ṣẹda RoleBinding nigba ṣiṣẹda Namespace.

Ni akọkọ, jẹ ki a ṣalaye iṣẹ naa maineyiti o ṣe iṣeto ti o nilo lati ṣiṣe alaye naa lẹhinna pe iṣẹ alaye naa:

(Akiyesi. itumọ.: nibi ati ni isalẹ awọn asọye ninu koodu ti wa ni itumọ si Russian. Ni afikun, a ti ṣatunṣe ifisi si awọn aaye dipo awọn taabu [a ṣeduro ni Go] nikan fun idi kika kika to dara julọ laarin ifilelẹ Habr. Lẹhin atokọ kọọkan awọn ọna asopọ wa si atilẹba lori GitHub, nibiti a ti fipamọ awọn asọye ede Gẹẹsi ati awọn taabu.)

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

(akọkọ.goninu aise)

A ṣe awọn wọnyi:

  1. A tunto olutọju kan fun awọn ifihan agbara ẹrọ ṣiṣe kan pato lati fa ifopinsi oore-ọfẹ ti oniṣẹ.
  2. A nlo WaitGrouplati fi ore-ọfẹ da gbogbo awọn gorutines ṣaaju ki o to fopin si ohun elo naa.
  3. A pese iraye si iṣupọ nipa ṣiṣẹda clientset.
  4. Ifilọlẹ NamespaceController, ninu eyiti gbogbo ọgbọn wa yoo wa.

Bayi a nilo ipilẹ kan fun imọran, ati ninu ọran wa eyi ni eyi ti a mẹnuba 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
}

(oludari.goninu aise)

Nibi ti a tunto SharedIndexInformer, eyi ti yoo munadoko (lilo kaṣe) duro fun awọn ayipada ninu awọn aaye orukọ (ka diẹ sii nipa awọn olufunni ninu nkan naa "Bawo ni oluṣeto Kubernetes n ṣiṣẹ gangan?"- - isunmọ. itumọ). Lẹhin eyi a sopọ EventHandler si olufunni, nitorinaa nigbati o ba ṣafikun aaye orukọ kan (Namespace) iṣẹ ni a npe ni createRoleBinding.

Igbesẹ ti o tẹle ni lati ṣalaye iṣẹ yii 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))
  }
}

(oludari.goninu aise)

A gba aaye orukọ bi obj ki o si yi pada si ohun kan Namespace. Lẹhinna a ṣalaye RoleBinding, da lori faili YAML ti a mẹnuba ni ibẹrẹ, ni lilo ohun elo ti a pese Namespace ati ṣiṣẹda RoleBinding. Nikẹhin, a wọle boya ẹda naa ṣaṣeyọri.

Awọn ti o kẹhin iṣẹ lati wa ni telẹ ni 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
}

(oludari.goninu aise)

Nibi a n sọrọ WaitGroupti a lọlẹ awọn goroutine ati ki o si pe namespaceInformer, eyi ti a ti sọ tẹlẹ. Nigbati ifihan iduro ba de, yoo pari iṣẹ naa, sọfun WaitGroup, eyi ti a ko ti ṣiṣẹ mọ, ati pe iṣẹ yii yoo jade.

Alaye nipa kikọ ati ṣiṣiṣẹ alaye yii lori iṣupọ Kubernetes ni a le rii ninu awọn ibi ipamọ lori GitHub.

Iyẹn ni fun oniṣẹ ti o ṣẹda RoleBinding Nigbawo Namespace ni Kubernetes iṣupọ, setan.

orisun: www.habr.com

Fi ọrọìwòye kun