github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/pkg/kubernetes/orbiter.go (about)

     1  package kubernetes
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/caos/orbos/mntr"
     7  	"github.com/caos/orbos/pkg/labels"
     8  	apps "k8s.io/api/apps/v1"
     9  	core "k8s.io/api/core/v1"
    10  	"k8s.io/apimachinery/pkg/api/resource"
    11  	mach "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"k8s.io/apimachinery/pkg/util/intstr"
    13  )
    14  
    15  func EnsureOrbiterArtifacts(
    16  	monitor mntr.Monitor,
    17  	apiLabels *labels.API,
    18  	client *Client,
    19  	pprof bool,
    20  	orbiterversion string,
    21  	imageRegistry string,
    22  ) error {
    23  
    24  	monitor.WithFields(map[string]interface{}{
    25  		"orbiter": orbiterversion,
    26  	}).Debug("Ensuring orbiter artifacts")
    27  
    28  	if orbiterversion == "" {
    29  		return nil
    30  	}
    31  
    32  	nameLabels := toNameLabels(apiLabels, "orbiter")
    33  	k8sNameLabels := labels.MustK8sMap(nameLabels)
    34  	k8sPodSelector := labels.MustK8sMap(labels.DeriveNameSelector(nameLabels, false))
    35  
    36  	cmd := []string{"/orbctl", "--gitops", "--orbconfig", "/etc/orbiter/orbconfig", "start", "orbiter", "--recur"}
    37  	if pprof {
    38  		cmd = append(cmd, "--pprof")
    39  	}
    40  
    41  	if _, _, analyticsEnabled := mntr.Environment(); !analyticsEnabled {
    42  		cmd = append(cmd, "--disable-analytics")
    43  	}
    44  
    45  	deployment := &apps.Deployment{
    46  		ObjectMeta: mach.ObjectMeta{
    47  			Name:      nameLabels.Name(),
    48  			Namespace: "caos-system",
    49  			Labels:    k8sNameLabels,
    50  		},
    51  		Spec: apps.DeploymentSpec{
    52  			Replicas: int32Ptr(1),
    53  			Selector: &mach.LabelSelector{
    54  				MatchLabels: k8sPodSelector,
    55  			},
    56  			Template: core.PodTemplateSpec{
    57  				ObjectMeta: mach.ObjectMeta{
    58  					Labels: labels.MustK8sMap(labels.AsSelectable(nameLabels)),
    59  				},
    60  				Spec: core.PodSpec{
    61  					Containers: []core.Container{{
    62  						Name:            "orbiter",
    63  						ImagePullPolicy: core.PullIfNotPresent,
    64  						Image:           fmt.Sprintf("%s/caos/orbos:%s", imageRegistry, orbiterversion),
    65  						Command:         cmd,
    66  						VolumeMounts: []core.VolumeMount{{
    67  							Name:      "keys",
    68  							ReadOnly:  true,
    69  							MountPath: "/etc/orbiter",
    70  						}},
    71  						Ports: []core.ContainerPort{{
    72  							Name:          "metrics",
    73  							ContainerPort: 9000,
    74  						}},
    75  						Resources: core.ResourceRequirements{
    76  							Limits: core.ResourceList{
    77  								"cpu":    resource.MustParse("500m"),
    78  								"memory": resource.MustParse("500Mi"),
    79  							},
    80  							Requests: core.ResourceList{
    81  								"cpu":    resource.MustParse("250m"),
    82  								"memory": resource.MustParse("250Mi"),
    83  							},
    84  						},
    85  						LivenessProbe: &core.Probe{
    86  							Handler: core.Handler{
    87  								HTTPGet: &core.HTTPGetAction{
    88  									Path:        "/health",
    89  									Port:        intstr.FromInt(9000),
    90  									Scheme:      core.URISchemeHTTP,
    91  									HTTPHeaders: make([]core.HTTPHeader, 0, 0),
    92  								},
    93  							},
    94  							InitialDelaySeconds: 10,
    95  							TimeoutSeconds:      1,
    96  							PeriodSeconds:       20,
    97  							SuccessThreshold:    1,
    98  							FailureThreshold:    3 * 5,
    99  						},
   100  					}},
   101  					Volumes: []core.Volume{{
   102  						Name: "keys",
   103  						VolumeSource: core.VolumeSource{
   104  							Secret: &core.SecretVolumeSource{
   105  								SecretName: "caos",
   106  								Optional:   boolPtr(false),
   107  							},
   108  						},
   109  					}},
   110  					NodeSelector: map[string]string{
   111  						"node-role.kubernetes.io/master": "",
   112  					},
   113  					Tolerations: []core.Toleration{{
   114  						Key:      "node-role.kubernetes.io/master",
   115  						Effect:   "NoSchedule",
   116  						Operator: "Exists",
   117  					}, {
   118  						Key:      fmt.Sprintf("%s%s", TaintKeyPrefix, Rebooting),
   119  						Operator: "Exists",
   120  						Effect:   "NoSchedule",
   121  					}},
   122  				},
   123  			},
   124  		},
   125  	}
   126  
   127  	if err := client.ApplyDeployment(deployment, true); err != nil {
   128  		return err
   129  	}
   130  	monitor.WithFields(map[string]interface{}{
   131  		"version": orbiterversion,
   132  	}).Debug("Orbiter deployment ensured")
   133  
   134  	if err := client.ApplyService(&core.Service{
   135  		ObjectMeta: mach.ObjectMeta{
   136  			Name:      nameLabels.Name(),
   137  			Namespace: "caos-system",
   138  			Labels:    k8sPodSelector,
   139  		},
   140  		Spec: core.ServiceSpec{
   141  			Ports: []core.ServicePort{{
   142  				Name:       "metrics",
   143  				Protocol:   "TCP",
   144  				Port:       9000,
   145  				TargetPort: intstr.FromInt(9000),
   146  			}},
   147  			Selector: k8sPodSelector,
   148  			Type:     core.ServiceTypeClusterIP,
   149  		},
   150  	}); err != nil {
   151  		return err
   152  	}
   153  	monitor.Debug("Orbiter service ensured")
   154  
   155  	patch := `
   156  {
   157    "spec": {
   158      "template": {
   159        "spec": {
   160          "affinity": {
   161            "podAntiAffinity": {
   162              "preferredDuringSchedulingIgnoredDuringExecution": [{
   163                "weight": 100,
   164                "podAffinityTerm": {
   165                  "topologyKey": "kubernetes.io/hostname"
   166                }
   167              }]
   168            }
   169          }
   170        }
   171      }
   172    }
   173  }`
   174  	if err := client.PatchDeployment("kube-system", "coredns", patch); err != nil {
   175  		return err
   176  	}
   177  
   178  	monitor.Debug("CoreDNS deployment patched")
   179  	return nil
   180  }