Merge pull request #731 from GLYASAI/goodrain.me

create imagePullSecret for rainbond namespace
This commit is contained in:
barnettZQG 2020-04-14 10:13:03 +08:00 committed by GitHub
commit 794b1cf40c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 150 additions and 19 deletions

View File

@ -273,10 +273,10 @@ func (s *slugBuild) runBuildJob(re *Request) error {
name := fmt.Sprintf("%s-%s", re.ServiceID, re.DeployVersion)
namespace := "rbd-system"
envs := []corev1.EnvVar{
corev1.EnvVar{Name: "SLUG_VERSION", Value: re.DeployVersion},
corev1.EnvVar{Name: "SERVICE_ID", Value: re.ServiceID},
corev1.EnvVar{Name: "TENANT_ID", Value: re.TenantID},
corev1.EnvVar{Name: "LANGUAGE", Value: re.Lang.String()},
{Name: "SLUG_VERSION", Value: re.DeployVersion},
{Name: "SERVICE_ID", Value: re.ServiceID},
{Name: "TENANT_ID", Value: re.TenantID},
{Name: "LANGUAGE", Value: re.Lang.String()},
}
for k, v := range re.BuildEnvs {
envs = append(envs, corev1.EnvVar{Name: k, Value: v})
@ -301,7 +301,7 @@ func (s *slugBuild) runBuildJob(re *Request) error {
}
podSpec := corev1.PodSpec{RestartPolicy: corev1.RestartPolicyOnFailure} // only support never and onfailure
podSpec.Volumes = []corev1.Volume{
corev1.Volume{
{
Name: "slug",
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
@ -309,7 +309,7 @@ func (s *slugBuild) runBuildJob(re *Request) error {
},
},
},
corev1.Volume{
{
Name: "app",
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
@ -325,17 +325,17 @@ func (s *slugBuild) runBuildJob(re *Request) error {
sourceTarPath := strings.TrimPrefix(sourceTarFileName, "/cache/")
cacheSubPath := strings.TrimPrefix(re.CacheDir, "/cache/")
container.VolumeMounts = []corev1.VolumeMount{
corev1.VolumeMount{
{
Name: "app",
MountPath: "/tmp/cache",
SubPath: cacheSubPath,
},
corev1.VolumeMount{
{
Name: "slug",
MountPath: "/tmp/slug",
SubPath: slugSubPath,
},
corev1.VolumeMount{
{
Name: "app",
MountPath: "/tmp/app-source.tar",
SubPath: sourceTarPath,
@ -346,6 +346,7 @@ func (s *slugBuild) runBuildJob(re *Request) error {
podSpec.HostAliases = append(podSpec.HostAliases, corev1.HostAlias{IP: ha.IP, Hostnames: ha.Hostnames})
}
job.Spec = podSpec
s.setImagePullSecretsForPod(&job)
writer := re.Logger.GetWriter("builder", "info")
reChan := channels.NewRingChannel(10)
err = jobc.GetJobController().ExecJob(&job, writer, reChan)
@ -510,6 +511,17 @@ func (s *slugBuild) runBuildContainer(re *Request) error {
return nil
}
func (s *slugBuild) setImagePullSecretsForPod(pod *corev1.Pod) {
imagePullSecretName := os.Getenv("IMAGE_PULL_SECRET")
if imagePullSecretName == "" {
return
}
pod.Spec.ImagePullSecrets = []corev1.LocalObjectReference{
{Name: imagePullSecretName},
}
}
//ErrorBuild build error
type ErrorBuild struct {
Code int

View File

@ -54,7 +54,6 @@ type Config struct {
LeaderElectionIdentity string
RBDNamespace string
GrdataPVCName string
RBDDNSName string
}
//Worker worker server
@ -95,7 +94,6 @@ func (a *Worker) AddFlags(fs *pflag.FlagSet) {
flag.StringVar(&a.LeaderElectionIdentity, "leader-election-identity", "", "Unique idenity of this attcher. Typically name of the pod where the attacher runs.")
flag.StringVar(&a.RBDNamespace, "rbd-system-namespace", "rbd-system", "rbd components kubernetes namespace")
flag.StringVar(&a.GrdataPVCName, "grdata-pvc-name", "rbd-cpt-grdata", "The name of grdata persistent volume claim")
flag.StringVar(&a.RBDDNSName, "rbd-dns", "rbd-dns", "rbd dns endpoint name")
}
//SetLog 设置log

View File

@ -5,4 +5,6 @@ const (
DefImageRepository = "goodrain.me"
// GrdataLogPath -
GrdataLogPath = "/grdata/logs"
// ImagePullSecretKey the key of environment IMAGE_PULL_SECRET
ImagePullSecretKey = "IMAGE_PULL_SECRET"
)

View File

@ -132,7 +132,8 @@ func initTenant(as *v1.AppService, tenant *dbmodel.Tenants) error {
}
namespace := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: tenant.UUID,
Name: tenant.UUID,
Labels: map[string]string{"creator": "Rainbond"},
},
}
as.SetTenant(namespace)

View File

@ -69,10 +69,11 @@ func TenantServiceVersion(as *v1.AppService, dbmanager db.Manager) error {
Name: as.ServiceID + "-pod-spec",
},
Spec: corev1.PodSpec{
Volumes: dv.GetVolumes(),
Containers: []corev1.Container{*container},
NodeSelector: createNodeSelector(as, dbmanager),
Affinity: createAffinity(as, dbmanager),
ImagePullSecrets: setImagePullSecrets(),
Volumes: dv.GetVolumes(),
Containers: []corev1.Container{*container},
NodeSelector: createNodeSelector(as, dbmanager),
Affinity: createAffinity(as, dbmanager),
Hostname: func() string {
if nodeID, ok := as.ExtensionSet["hostname"]; ok {
return nodeID
@ -719,3 +720,14 @@ func createPodAnnotations(as *v1.AppService) map[string]string {
}
return annotations
}
func setImagePullSecrets() []corev1.LocalObjectReference {
imagePullSecretName := os.Getenv("IMAGE_PULL_SECRET")
if imagePullSecretName == "" {
return nil
}
return []corev1.LocalObjectReference{
{Name: imagePullSecretName},
}
}

View File

@ -24,6 +24,7 @@ import (
//Informer kube-api client cache
type Informer struct {
Namespace cache.SharedIndexInformer
Ingress cache.SharedIndexInformer
Service cache.SharedIndexInformer
Secret cache.SharedIndexInformer
@ -42,6 +43,7 @@ type Informer struct {
//Start statrt
func (i *Informer) Start(stop chan struct{}) {
go i.Namespace.Run(stop)
go i.Ingress.Run(stop)
go i.Service.Run(stop)
go i.Secret.Run(stop)
@ -60,7 +62,7 @@ func (i *Informer) Start(stop chan struct{}) {
//Ready if all kube informers is syncd, store is ready
func (i *Informer) Ready() bool {
if i.Ingress.HasSynced() && i.Service.HasSynced() && i.Secret.HasSynced() &&
if i.Namespace.HasSynced() && i.Ingress.HasSynced() && i.Service.HasSynced() && i.Secret.HasSynced() &&
i.StatefulSet.HasSynced() && i.Deployment.HasSynced() && i.Pod.HasSynced() &&
i.ConfigMap.HasSynced() && i.Nodes.HasSynced() && i.Events.HasSynced() &&
i.HorizontalPodAutoscaler.HasSynced() && i.StorageClass.HasSynced() && i.Claims.HasSynced() {

View File

@ -21,6 +21,9 @@ package store
import (
"context"
"fmt"
"github.com/goodrain/rainbond/util/constants"
"k8s.io/apimachinery/pkg/types"
"os"
"sync"
"time"
@ -140,8 +143,11 @@ func NewStore(clientset kubernetes.Interface,
podUpdateListeners: make(map[string]chan<- *corev1.Pod, 1),
}
// create informers factory, enable and assign required informers
infFactory := informers.NewFilteredSharedInformerFactory(conf.KubeClient, time.Second, corev1.NamespaceAll,
func(options *metav1.ListOptions) {})
infFactory := informers.NewSharedInformerFactoryWithOptions(conf.KubeClient, 10*time.Second,
informers.WithNamespace(corev1.NamespaceAll))
store.informers.Namespace = infFactory.Core().V1().Namespaces().Informer()
store.informers.Deployment = infFactory.Apps().V1().Deployments().Informer()
store.listers.Deployment = infFactory.Apps().V1().Deployments().Lister()
@ -264,6 +270,7 @@ func NewStore(clientset kubernetes.Interface,
},
}
store.informers.Namespace.AddEventHandler(store.nsEventHandler())
store.informers.Deployment.AddEventHandlerWithResyncPeriod(store, time.Second*10)
store.informers.StatefulSet.AddEventHandlerWithResyncPeriod(store, time.Second*10)
store.informers.Pod.AddEventHandlerWithResyncPeriod(store.podEventHandler(), time.Second*10)
@ -1241,6 +1248,24 @@ func (a *appRuntimeStore) evtEventHandler() cache.ResourceEventHandlerFuncs {
}
}
func (a *appRuntimeStore) nsEventHandler() cache.ResourceEventHandlerFuncs {
return cache.ResourceEventHandlerFuncs{
UpdateFunc: func(old, cur interface{}) {
ns := cur.(*corev1.Namespace)
logrus.Debugf("Received update event. Namespace: %s", ns.Name)
// check if the namespace is created by Rainbond
if !filterOutNotRainbondNamespace(ns) {
return
}
if err := a.createOrUpdateImagePullSecret(ns.Name); err != nil {
logrus.Errorf("create or update imagepullsecret: %v", err)
}
},
}
}
func (a *appRuntimeStore) scalingRecordServiceAndRuleID(evt *corev1.Event) (string, string) {
var ruleID, serviceID string
switch evt.InvolvedObject.Kind {
@ -1285,3 +1310,82 @@ func (a *appRuntimeStore) UnRegistPodUpdateListener(name string) {
defer a.podUpdateListenerLock.Unlock()
delete(a.podUpdateListeners, name)
}
func (a *appRuntimeStore) createOrUpdateImagePullSecret(ns string) error {
imagePullSecretName := os.Getenv(constants.ImagePullSecretKey)
if imagePullSecretName == "" {
return nil
}
// get secret in namespace rbd-system
rawSecret, err := a.secretByKey(types.NamespacedName{Namespace: a.conf.RBDNamespace, Name: imagePullSecretName})
if err != nil {
return fmt.Errorf("get secret %s: %v",
types.NamespacedName{Namespace: a.conf.RBDNamespace, Name: imagePullSecretName}.String(), err)
}
// get secret in current namespace
curSecret, err := a.secretByKey(types.NamespacedName{Namespace: ns, Name: imagePullSecretName})
if err != nil {
// current secret not exists. create a new one.
if errors.IsNotFound(err) {
curSecret = &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: rawSecret.Name,
Namespace: ns,
},
Data: rawSecret.Data,
Type: rawSecret.Type,
}
_, err := a.clientset.CoreV1().Secrets(ns).Create(curSecret)
if err != nil {
return fmt.Errorf("create secret for pulling images: %v", err)
}
return nil
}
return fmt.Errorf("get secret %s: %v", types.NamespacedName{Namespace: ns, Name: imagePullSecretName}.String(), err)
}
// check if the raw secret is different from the current one
if isImagePullSecretEqual(rawSecret, curSecret) {
return nil
}
// if the raw secret is different from the current one, then update the current one.
curSecret.Data = rawSecret.Data
if _, err := a.clientset.CoreV1().Secrets(ns).Update(curSecret); err != nil {
return fmt.Errorf("update secret for pulling images: %v", err)
}
return nil
}
func (a *appRuntimeStore) secretByKey(key types.NamespacedName) (*corev1.Secret, error) {
return a.listers.Secret.Secrets(key.Namespace).Get(key.Name)
}
func isImagePullSecretEqual(a, b *corev1.Secret) bool {
if len(a.Data) != len(b.Data) {
return false
}
for key, av := range a.Data {
bv, ok := b.Data[key]
if !ok {
return false
}
if string(av) != string(bv) {
return false
}
}
return true
}
func filterOutNotRainbondNamespace(ns *corev1.Namespace) bool {
// compatible with pre-5.2 versions
oldVersion := len(ns.Name) == 32
curVersion := func() bool {
if ns.Labels == nil {
return false
}
return ns.Labels["creator"] == "Rainbond"
}()
return curVersion || oldVersion
}