Skip to content

Commit

Permalink
Search for agent image from controller spec (#229)
Browse files Browse the repository at this point in the history
  • Loading branch information
anjmao authored Mar 12, 2024
1 parent 96f78c4 commit 30bc53c
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 57 deletions.
1 change: 0 additions & 1 deletion charts/kvisor/templates/controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ spec:
args:
- "--http-listen-port={{.Values.controller.httpListenPort}}"
- "--castai-secret-ref-name={{ include "kvisor.castaiSecretName" . }}"
- "--agent-daemonset-name={{ include "kvisor.agent.fullname" . }}"
- "--image-scan-blobs-cache-url=http://{{ include "kvisor.controller.fullname" . }}.{{.Release.Namespace}}"
{{- if eq .Values.mockServer.enabled true }}
- "--castai-server-insecure=true"
Expand Down
5 changes: 2 additions & 3 deletions cmd/controller/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ type Config struct {

// Current running pod metadata.
PodNamespace string `validate:"required"`

AgentDaemonSetName string
PodName string `validate:"required"`

// HTTPListenPort is internal http servers listen port.
HTTPListenPort int `validate:"required"`
Expand Down Expand Up @@ -110,7 +109,7 @@ func (a *App) Run(ctx context.Context) error {
if err != nil {
return err
}
kubeClient := kube.NewClient(log, cfg.AgentDaemonSetName, cfg.PodNamespace, k8sVersion, clientset)
kubeClient := kube.NewClient(log, cfg.PodName, cfg.PodNamespace, k8sVersion, clientset)
kubeClient.RegisterHandlers(informersFactory)

// Run all components.
Expand Down
69 changes: 35 additions & 34 deletions cmd/controller/kube/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package kube
import (
"context"
"reflect"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -41,17 +42,17 @@ type KubernetesChangeEventListener interface {
}

type Client struct {
log *logging.Logger
kvisorNamespace string
kvisorAgentDaemonSetName string
kvisorAgentContainerName string
client kubernetes.Interface

mu sync.RWMutex
replicaSets map[types.UID]metav1.ObjectMeta
jobs map[types.UID]metav1.ObjectMeta
deployments map[types.UID]*appsv1.Deployment
kvisorAgentDsSpec *appsv1.DaemonSetSpec
log *logging.Logger
kvisorNamespace string
podName string
kvisorControllerContainerName string
client kubernetes.Interface

mu sync.RWMutex
replicaSets map[types.UID]metav1.ObjectMeta
jobs map[types.UID]metav1.ObjectMeta
deployments map[types.UID]*appsv1.Deployment
kvisorControllerPodSpec *corev1.PodSpec

changeListenersMu sync.RWMutex
changeListeners []*eventListener
Expand All @@ -60,20 +61,20 @@ type Client struct {

func NewClient(
log *logging.Logger,
kvisorAgentDaemonSetName, kvisorNamespace string,
podName, kvisorNamespace string,
version Version,
client kubernetes.Interface,
) *Client {
return &Client{
log: log.WithField("component", "kube_watcher"),
kvisorNamespace: kvisorNamespace,
kvisorAgentDaemonSetName: kvisorAgentDaemonSetName,
kvisorAgentContainerName: "kvisor",
client: client,
replicaSets: map[types.UID]metav1.ObjectMeta{},
jobs: map[types.UID]metav1.ObjectMeta{},
deployments: map[types.UID]*appsv1.Deployment{},
version: version,
log: log.WithField("component", "kube_watcher"),
kvisorNamespace: kvisorNamespace,
podName: podName,
kvisorControllerContainerName: "controller",
client: client,
replicaSets: map[types.UID]metav1.ObjectMeta{},
jobs: map[types.UID]metav1.ObjectMeta{},
deployments: map[types.UID]*appsv1.Deployment{},
version: version,
}
}

Expand Down Expand Up @@ -271,21 +272,21 @@ func (c *Client) GetOwnerUID(obj Object) string {
}

type ImageDetails struct {
ImageName string
AgentImageName string
ImagePullSecrets []corev1.LocalObjectReference
}

// GetKvisorAgentImageDetails returns kvisor image details.
// GetKvisorAgentImageDetails returns kvisor agent image details.
// This is used for image analyzer and kube-bench dynamic jobs to schedule using the same image.
func (c *Client) GetKvisorAgentImageDetails() (ImageDetails, bool) {
spec, found := c.getKvisorAgentDaemonSpec()
spec, found := c.getKvisorControllerPodSpec()
if !found {
c.log.Warn("kvisor agent daemon set not found")
c.log.Warn("kvisor controller pod spec not found")
return ImageDetails{}, false
}
var imageName string
for _, container := range spec.Template.Spec.Containers {
if container.Name == c.kvisorAgentContainerName {
for _, container := range spec.Containers {
if container.Name == c.kvisorControllerContainerName {
imageName = container.Image
break
}
Expand All @@ -295,31 +296,31 @@ func (c *Client) GetKvisorAgentImageDetails() (ImageDetails, bool) {
return ImageDetails{}, false
}
return ImageDetails{
ImageName: imageName,
ImagePullSecrets: spec.Template.Spec.ImagePullSecrets,
AgentImageName: strings.Replace(imageName, "-controller", "-agent", 1),
ImagePullSecrets: spec.ImagePullSecrets,
}, true
}

func (c *Client) getKvisorAgentDaemonSpec() (*appsv1.DaemonSetSpec, bool) {
func (c *Client) getKvisorControllerPodSpec() (*corev1.PodSpec, bool) {
c.mu.RLock()
spec := c.kvisorAgentDsSpec
spec := c.kvisorControllerPodSpec
c.mu.RUnlock()
if spec != nil {
return spec, true
}

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
ds, err := c.client.AppsV1().DaemonSets(c.kvisorNamespace).Get(ctx, c.kvisorAgentDaemonSetName, metav1.GetOptions{})
pod, err := c.client.CoreV1().Pods(c.kvisorNamespace).Get(ctx, c.podName, metav1.GetOptions{})
if err != nil {
return nil, false
}

c.mu.Lock()
c.kvisorAgentDsSpec = &ds.Spec
c.kvisorControllerPodSpec = &pod.Spec
c.mu.Unlock()

return &ds.Spec, true
return &pod.Spec, true
}

func (c *Client) RegisterKubernetesChangeListener(l KubernetesChangeEventListener) {
Expand Down
20 changes: 9 additions & 11 deletions cmd/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ var (

pyroscopeAddr = pflag.String("pyroscope-addr", "", "Enable pyroscope tracing")

agentDaemonSetName = pflag.String("agent-daemonset-name", "", "Agent DaemonSet name")

castaiSecretRefName = pflag.String("castai-secret-ref-name", "castai-kvisor", "CASTAI k8s secret name")
castaiConfigSyncDuration = pflag.Duration("castai-config-sync-duration", 1*time.Minute, "CASTAI remote config sync duration")
castaiServerInsecure = pflag.Bool("castai-server-insecure", false, "Use insecure connection to castai grpc server. Used for e2e.")
Expand Down Expand Up @@ -106,15 +104,15 @@ func main() {

podNs := os.Getenv("POD_NAMESPACE")
appInstance := app.New(&app.Config{
LogLevel: *logLevel,
LogRateInterval: *logRateInterval,
LogRateBurst: *logRateBurst,
PodNamespace: podNs,
AgentDaemonSetName: *agentDaemonSetName,
Version: Version,
PyroscopeAddr: *pyroscopeAddr,
HTTPListenPort: *httpListenPort,
CastaiEnv: castaiClientCfg,
LogLevel: *logLevel,
LogRateInterval: *logRateInterval,
LogRateBurst: *logRateBurst,
PodName: os.Getenv("POD_NAME"),
PodNamespace: podNs,
Version: Version,
PyroscopeAddr: *pyroscopeAddr,
HTTPListenPort: *httpListenPort,
CastaiEnv: castaiClientCfg,
CastaiController: state.CastaiConfig{
RemoteConfigSyncDuration: *castaiConfigSyncDuration,
},
Expand Down
4 changes: 2 additions & 2 deletions cmd/controller/state/imagescan/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func TestSubscriber(t *testing.T) {
Architecture: defaultImageArch,
Os: defaultImageOs,
ScanImageDetails: kube.ImageDetails{
ImageName: "kvisor",
AgentImageName: "kvisor",
ImagePullSecrets: nil,
},
}, ngnxImage)
Expand Down Expand Up @@ -594,7 +594,7 @@ func (m *mockKubeController) GetOwnerUID(obj kube.Object) string {

func (m *mockKubeController) GetKvisorAgentImageDetails() (kube.ImageDetails, bool) {
return kube.ImageDetails{
ImageName: "kvisor",
AgentImageName: "kvisor",
ImagePullSecrets: nil,
}, true
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/controller/state/imagescan/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ func scanJobSpec(
AllowPrivilegeEscalation: lo.ToPtr(false),
},
Name: "collector",
Image: params.ScanImageDetails.ImageName,
Image: params.ScanImageDetails.AgentImageName,
Command: []string{
"/usr/local/bin/kvisor-agent",
},
Expand Down
6 changes: 3 additions & 3 deletions cmd/controller/state/imagescan/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestScanner(t *testing.T) {
Architecture: "amd64",
Os: "linux",
ScanImageDetails: kube.ImageDetails{
ImageName: "imgcollector:1.0.0",
AgentImageName: "imgcollector:1.0.0",
},
})
r.NoError(err)
Expand Down Expand Up @@ -268,7 +268,7 @@ func TestScanner(t *testing.T) {
ResourceIDs: []string{"p1", "p2"},
DeleteFinishedJob: true,
ScanImageDetails: kube.ImageDetails{
ImageName: "imgcollector:1.0.0",
AgentImageName: "imgcollector:1.0.0",
},
})
r.NoError(err)
Expand Down Expand Up @@ -320,7 +320,7 @@ func TestScanner(t *testing.T) {
ResourceIDs: []string{"p1", "p2"},
WaitForCompletion: true,
ScanImageDetails: kube.ImageDetails{
ImageName: "imgcollector:1.0.0",
AgentImageName: "imgcollector:1.0.0",
},
})
r.ErrorContains(err, "[type=Ready, status=False, reason=no cpu], [type=PodScheduled, status=False, reason=no cpu]")
Expand Down
2 changes: 1 addition & 1 deletion cmd/controller/state/kubebench/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ func (c *Controller) createKubebenchJob(ctx context.Context, node *corev1.Node,
return nil, errors.New("kvisor image details not found")
}
cont := jobSpec.Spec.Template.Spec.Containers[0]
cont.Image = imageDetails.ImageName
cont.Image = imageDetails.AgentImageName
cont.ImagePullPolicy = corev1.PullPolicy(c.cfg.JobImagePullPolicy)
jobSpec.Spec.Template.Spec.Containers[0] = cont
jobSpec.Spec.Template.Spec.ImagePullSecrets = imageDetails.ImagePullSecrets
Expand Down
2 changes: 1 addition & 1 deletion cmd/controller/state/kubebench/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ type mockKubeController struct {

func (m *mockKubeController) GetKvisorAgentImageDetails() (kube.ImageDetails, bool) {
return kube.ImageDetails{
ImageName: "kvisor",
AgentImageName: "kvisor",
ImagePullSecrets: nil,
}, true
}
Expand Down

0 comments on commit 30bc53c

Please sign in to comment.