diff --git a/cmd/helmChart.go b/cmd/helmChart.go index ee8b12119..4f4dbcc37 100644 --- a/cmd/helmChart.go +++ b/cmd/helmChart.go @@ -130,10 +130,6 @@ var hubPodMappings = map[string]interface{}{ "name": "NAMESPACES", "value": "{{ gt (len .Values.tap.namespaces) 0 | ternary (join \",\" .Values.tap.namespaces) \"\" }}", }, - { - "name": "STORAGE_LIMIT", - "value": "{{ .Values.tap.storagelimit }}", - }, { "name": "LICENSE", "value": "{{ .Values.license }}", @@ -162,6 +158,10 @@ var frontPodMappings = map[string]interface{}{ "spec.containers[0].imagePullPolicy": "{{ .Values.tap.docker.imagePullPolicy }}", } var frontServiceMappings = serviceAccountMappings +var persistentVolumeMappings = map[string]interface{}{ + "metadata.namespace": "{{ .Values.tap.selfnamespace }}", + "spec.resources.requests.storage": "{{ .Values.tap.storagelimit }}", +} var workerDaemonSetMappings = map[string]interface{}{ "metadata.namespace": "{{ .Values.tap.selfnamespace }}", "spec.template.spec.containers[0].image": "{{ .Values.tap.docker.registry }}/worker:{{ .Values.tap.docker.tag }}", @@ -187,6 +187,7 @@ func runHelmChart() { hubService, frontPod, frontService, + persistentVolume, workerDaemonSet, err := generateManifests() if err != nil { @@ -203,7 +204,8 @@ func runHelmChart() { "05-hub-service.yaml": template(hubService, hubServiceMappings), "06-front-pod.yaml": template(frontPod, frontPodMappings), "07-front-service.yaml": template(frontService, frontServiceMappings), - "08-worker-daemon-set.yaml": template(workerDaemonSet, workerDaemonSetMappings), + "08-persistent-volume.yaml": template(persistentVolume, persistentVolumeMappings), + "09-worker-daemon-set.yaml": template(workerDaemonSet, workerDaemonSetMappings), }) if err != nil { log.Error().Err(err).Send() diff --git a/cmd/manifests.go b/cmd/manifests.go index ce1b2ad35..a589d2a6f 100644 --- a/cmd/manifests.go +++ b/cmd/manifests.go @@ -49,6 +49,7 @@ func runManifests() { hubService, frontPod, frontService, + persistentVolume, workerDaemonSet, err := generateManifests() if err != nil { @@ -66,7 +67,8 @@ func runManifests() { "05-hub-service.yaml": hubService, "06-front-pod.yaml": frontPod, "07-front-service.yaml": frontService, - "08-worker-daemon-set.yaml": workerDaemonSet, + "08-persistent-volume.yaml": persistentVolume, + "09-worker-daemon-set.yaml": workerDaemonSet, }) } else { err = printManifests([]interface{}{ @@ -96,6 +98,7 @@ func generateManifests() ( hubService *v1.Service, frontPod *v1.Pod, frontService *v1.Service, + persistentVolumeClaim *v1.PersistentVolumeClaim, workerDaemonSet *kubernetes.DaemonSet, err error, ) { @@ -145,6 +148,11 @@ func generateManifests() ( frontService = kubernetesProvider.BuildFrontService(config.Config.Tap.SelfNamespace) + persistentVolumeClaim, err = kubernetesProvider.BuildPersistentVolumeClaim() + if err != nil { + return + } + workerDaemonSet, err = kubernetesProvider.BuildWorkerDaemonSet( docker.GetWorkerImage(), kubernetes.WorkerDaemonSetName, diff --git a/cmd/tapRunner.go b/cmd/tapRunner.go index b61008d6f..68237ce9d 100644 --- a/cmd/tapRunner.go +++ b/cmd/tapRunner.go @@ -432,10 +432,6 @@ func postHubStarted(ctx context.Context, kubernetesProvider *kubernetes.Provider log.Error().Err(err).Send() } } else { - - // Storage limit - connector.PostStorageLimitToHub(config.Config.Tap.StorageLimitBytes()) - // Pod regex connector.PostRegexToHub(config.Config.Tap.PodRegexStr, state.targetNamespaces) diff --git a/config/configStructs/tapConfig.go b/config/configStructs/tapConfig.go index bc07e01e1..40a528ac4 100644 --- a/config/configStructs/tapConfig.go +++ b/config/configStructs/tapConfig.go @@ -4,8 +4,6 @@ import ( "fmt" "regexp" - "github.com/kubeshark/kubeshark/utils" - "github.com/rs/zerolog/log" v1 "k8s.io/api/core/v1" ) @@ -83,7 +81,7 @@ type TapConfig struct { PodRegexStr string `yaml:"regex" default:".*"` Namespaces []string `yaml:"namespaces"` SelfNamespace string `yaml:"selfnamespace" default:"kubeshark"` - StorageLimit string `yaml:"storagelimit" default:"200MB"` + StorageLimit string `yaml:"storagelimit" default:"300Mi"` DryRun bool `yaml:"dryrun" default:"false"` Pcap string `yaml:"pcap" default:""` Resources ResourcesConfig `yaml:"resources"` @@ -101,24 +99,11 @@ func (config *TapConfig) PodRegex() *regexp.Regexp { return podRegex } -func (config *TapConfig) StorageLimitBytes() int64 { - storageLimitBytes, err := utils.HumanReadableToBytes(config.StorageLimit) - if err != nil { - log.Fatal().Err(err).Send() - } - return storageLimitBytes -} - func (config *TapConfig) Validate() error { _, compileErr := regexp.Compile(config.PodRegexStr) if compileErr != nil { return fmt.Errorf("%s is not a valid regex %s", config.PodRegexStr, compileErr) } - _, parseHumanDataSizeErr := utils.HumanReadableToBytes(config.StorageLimit) - if parseHumanDataSizeErr != nil { - return fmt.Errorf("Could not parse --%s value %s", StorageLimitLabel, config.StorageLimit) - } - return nil } diff --git a/go.mod b/go.mod index 5c311c56a..ffc9a48bf 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( github.com/creasty/defaults v1.5.2 github.com/docker/docker v20.10.24+incompatible github.com/docker/go-connections v0.4.0 - github.com/docker/go-units v0.4.0 github.com/fsnotify/fsnotify v1.5.1 github.com/gin-gonic/gin v1.7.7 github.com/google/go-github/v37 v37.0.0 @@ -40,6 +39,7 @@ require ( github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/distribution v2.8.0+incompatible // indirect + github.com/docker/go-units v0.4.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/fvbommel/sortorder v1.0.2 // indirect diff --git a/go.sum b/go.sum index 7b447e257..6c0d90a99 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,7 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= @@ -113,8 +114,10 @@ github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -522,6 +525,7 @@ github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/otiai10/copy v1.10.0 h1:znyI7l134wNg/wDktoVQPxPkgvhDfGCYUasey+h0rDQ= github.com/otiai10/copy v1.10.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= +github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -631,6 +635,7 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= @@ -645,6 +650,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= @@ -786,6 +792,8 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -818,6 +826,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -901,11 +910,17 @@ golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -917,6 +932,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1158,6 +1174,7 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= diff --git a/helm-chart/templates/04-hub-pod.yaml b/helm-chart/templates/04-hub-pod.yaml index d0d3cb938..5cf64f7c5 100644 --- a/helm-chart/templates/04-hub-pod.yaml +++ b/helm-chart/templates/04-hub-pod.yaml @@ -19,8 +19,6 @@ spec: value: '{{ .Values.tap.regex }}' - name: NAMESPACES value: '{{ gt (len .Values.tap.namespaces) 0 | ternary (join "," .Values.tap.namespaces) "" }}' - - name: STORAGE_LIMIT - value: '{{ .Values.tap.storagelimit }}' - name: LICENSE value: '{{ .Values.license }}' - name: SCRIPTING_ENV diff --git a/helm-chart/templates/08-persistent-volume.yaml b/helm-chart/templates/08-persistent-volume.yaml new file mode 100644 index 000000000..20db93116 --- /dev/null +++ b/helm-chart/templates/08-persistent-volume.yaml @@ -0,0 +1,20 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY KUBESHARK CLI. DO NOT EDIT! +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + creationTimestamp: null + labels: + kubeshark-cli-version: v1 + kubeshark-created-by: kubeshark + kubeshark-managed-by: kubeshark + name: kubeshark-persistent-volume-claim + namespace: '{{ .Values.tap.selfnamespace }}' +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: '{{ .Values.tap.storagelimit }}' + storageClassName: standard +status: {} diff --git a/helm-chart/templates/09-worker-daemon-set.yaml b/helm-chart/templates/09-worker-daemon-set.yaml new file mode 100644 index 000000000..8c9c18d38 --- /dev/null +++ b/helm-chart/templates/09-worker-daemon-set.yaml @@ -0,0 +1,90 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY KUBESHARK CLI. DO NOT EDIT! +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app: kubeshark-worker-daemon-set + kubeshark-created-by: kubeshark + kubeshark-managed-by: kubeshark + name: kubeshark-worker-daemon-set + namespace: '{{ .Values.tap.selfnamespace }}' +spec: + selector: + matchLabels: + app: kubeshark-worker-daemon-set + kubeshark-created-by: kubeshark + kubeshark-managed-by: kubeshark + template: + metadata: + creationTimestamp: null + labels: + app: kubeshark-worker-daemon-set + kubeshark-created-by: kubeshark + kubeshark-managed-by: kubeshark + name: kubeshark-worker-daemon-set + namespace: kubeshark + spec: + containers: + - command: + - '{{ .Values.tap.debug | ternary "./worker -debug" "./worker" }}' + - -i + - any + - -port + - "8897" + - -packet-capture + - '{{ .Values.tap.packetcapture }}' + - -servicemesh + - -tls + - -procfs + - /hostproc + image: '{{ .Values.tap.docker.registry }}/worker:{{ .Values.tap.docker.tag }}' + imagePullPolicy: '{{ .Values.tap.docker.imagePullPolicy }}' + name: kubeshark-worker-daemon-set + resources: + limits: + cpu: '{{ .Values.tap.resources.worker.limits.cpu }}' + memory: '{{ .Values.tap.resources.worker.limits.memory }}' + requests: + cpu: '{{ .Values.tap.resources.worker.requests.cpu }}' + memory: '{{ .Values.tap.resources.worker.requests.memory }}' + securityContext: + capabilities: + add: + - NET_RAW + - NET_ADMIN + - SYS_ADMIN + - SYS_PTRACE + - DAC_OVERRIDE + - SYS_RESOURCE + drop: + - ALL + volumeMounts: + - mountPath: /hostproc + name: proc + readOnly: true + - mountPath: /sys + name: sys + readOnly: true + - mountPath: /app/data + name: kubeshark-persistent-volume + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + serviceAccountName: kubeshark-service-account + terminationGracePeriodSeconds: 0 + tolerations: + - effect: NoExecute + operator: Exists + - effect: NoSchedule + operator: Exists + volumes: + - hostPath: + path: /proc + name: proc + - hostPath: + path: /sys + name: sys + - name: kubeshark-persistent-volume + persistentVolumeClaim: + claimName: kubeshark-persistent-volume-claim diff --git a/helm-chart/values.yaml b/helm-chart/values.yaml index e1c6bab34..2acb7b63e 100644 --- a/helm-chart/values.yaml +++ b/helm-chart/values.yaml @@ -18,7 +18,7 @@ tap: regex: .* namespaces: [] selfnamespace: kubeshark - storagelimit: 200MB + storagelimit: 300Mi dryrun: false pcap: "" resources: diff --git a/internal/connect/hub.go b/internal/connect/hub.go index 3e43783b6..0507c7b03 100644 --- a/internal/connect/hub.go +++ b/internal/connect/hub.go @@ -87,36 +87,6 @@ func (connector *Connector) PostWorkerPodToHub(pod *v1.Pod) { } } -type postStorageLimit struct { - Limit int64 `json:"limit"` -} - -func (connector *Connector) PostStorageLimitToHub(limit int64) { - payload := &postStorageLimit{ - Limit: limit, - } - postStorageLimitUrl := fmt.Sprintf("%s/pcaps/set-storage-limit", connector.url) - - if payloadMarshalled, err := json.Marshal(payload); err != nil { - log.Error().Err(err).Msg("Failed to marshal the storage limit:") - } else { - ok := false - for !ok { - var resp *http.Response - if resp, err = utils.Post(postStorageLimitUrl, "application/json", bytes.NewBuffer(payloadMarshalled), connector.client); err != nil || resp.StatusCode != http.StatusOK { - if _, ok := err.(*url.Error); ok { - break - } - log.Warn().Err(err).Msg("Failed sending the storage limit to Hub. Retrying...") - } else { - log.Debug().Int("limit", int(limit)).Msg("Reported storage limit to Hub:") - return - } - time.Sleep(DefaultSleep) - } - } -} - type postRegexRequest struct { Regex string `json:"regex"` Namespaces []string `json:"namespaces"` diff --git a/kubernetes/consts.go b/kubernetes/consts.go index 83c09a18f..1f57e63b8 100644 --- a/kubernetes/consts.go +++ b/kubernetes/consts.go @@ -14,6 +14,9 @@ const ( ServiceAccountName = SelfResourcesPrefix + "service-account" WorkerDaemonSetName = SelfResourcesPrefix + "worker-daemon-set" WorkerPodName = SelfResourcesPrefix + "worker" + PersistentVolumeName = SelfResourcesPrefix + "persistent-volume" + PersistentVolumeClaimName = SelfResourcesPrefix + "persistent-volume-claim" + PersistentVolumeHostPath = "/app/data" MinKubernetesServerVersion = "1.16.0" ) diff --git a/kubernetes/provider.go b/kubernetes/provider.go index 7c4ad29ac..4f7aa8a87 100644 --- a/kubernetes/provider.go +++ b/kubernetes/provider.go @@ -248,10 +248,6 @@ func (provider *Provider) BuildHubPod(opts *PodOptions) (*core.Pod, error) { Name: "NAMESPACES", Value: strings.Join(provider.GetNamespaces(), ","), }, - { - Name: "STORAGE_LIMIT", - Value: config.Config.Tap.StorageLimit, - }, { Name: "LICENSE", Value: "", @@ -680,6 +676,11 @@ func (provider *Provider) RemoveService(ctx context.Context, namespace string, s return provider.handleRemovalError(err) } +func (provider *Provider) RemovePersistentVolumeClaim(ctx context.Context, namespace string, persistentVolumeClaimName string) error { + err := provider.clientSet.CoreV1().PersistentVolumeClaims(namespace).Delete(ctx, persistentVolumeClaimName, metav1.DeleteOptions{}) + return provider.handleRemovalError(err) +} + func (provider *Provider) RemoveDaemonSet(ctx context.Context, namespace string, daemonSetName string) error { err := provider.clientSet.AppsV1().DaemonSets(namespace).Delete(ctx, daemonSetName, metav1.DeleteOptions{}) return provider.handleRemovalError(err) @@ -695,6 +696,38 @@ func (provider *Provider) handleRemovalError(err error) error { return err } +func (provider *Provider) BuildPersistentVolumeClaim() (*core.PersistentVolumeClaim, error) { + capacity, err := resource.ParseQuantity(config.Config.Tap.StorageLimit) + if err != nil { + return nil, fmt.Errorf("invalid capacity for the workers: %s", config.Config.Tap.StorageLimit) + } + + storageClassName := "standard" + + return &core.PersistentVolumeClaim{ + TypeMeta: metav1.TypeMeta{ + Kind: "PersistentVolumeClaim", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: PersistentVolumeClaimName, + Namespace: config.Config.Tap.SelfNamespace, + Labels: buildWithDefaultLabels(map[string]string{ + fmt.Sprintf("%s-cli-version", misc.Program): misc.RBACVersion, + }, provider), + }, + Spec: core.PersistentVolumeClaimSpec{ + Resources: core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceStorage: capacity, + }, + }, + AccessModes: []core.PersistentVolumeAccessMode{core.ReadWriteMany}, + StorageClassName: &storageClassName, + }, + }, nil +} + func (provider *Provider) BuildWorkerDaemonSet( podImage string, podName string, @@ -813,14 +846,32 @@ func (provider *Provider) BuildWorkerDaemonSet( ReadOnly: true, } + // Persistent volume and its mount + persistentVolume := core.Volume{ + Name: PersistentVolumeName, + VolumeSource: core.VolumeSource{ + PersistentVolumeClaim: &core.PersistentVolumeClaimVolumeSource{ + ClaimName: PersistentVolumeClaimName, + }, + }, + } + persistentVolumeMount := core.VolumeMount{ + Name: PersistentVolumeName, + MountPath: PersistentVolumeHostPath, + } + // Containers containers := []core.Container{ { Name: podName, Image: podImage, ImagePullPolicy: imagePullPolicy, - VolumeMounts: []core.VolumeMount{procfsVolumeMount, sysfsVolumeMount}, - Command: command, + VolumeMounts: []core.VolumeMount{ + procfsVolumeMount, + sysfsVolumeMount, + persistentVolumeMount, + }, + Command: command, Resources: core.ResourceRequirements{ Limits: core.ResourceList{ "cpu": cpuLimit, @@ -865,10 +916,14 @@ func (provider *Provider) BuildWorkerDaemonSet( }, provider), }, Spec: core.PodSpec{ - ServiceAccountName: ServiceAccountName, - HostNetwork: true, - Containers: containers, - Volumes: []core.Volume{procfsVolume, sysfsVolume}, + ServiceAccountName: ServiceAccountName, + HostNetwork: true, + Containers: containers, + Volumes: []core.Volume{ + procfsVolume, + sysfsVolume, + persistentVolume, + }, DNSPolicy: core.DNSClusterFirstWithHostNet, TerminationGracePeriodSeconds: new(int64), Tolerations: tolerations, @@ -909,6 +964,10 @@ func (provider *Provider) BuildWorkerDaemonSet( }, nil } +func (provider *Provider) CreatePersistentVolumeClaim(ctx context.Context, namespace string, persistentVolumeClaim *core.PersistentVolumeClaim) (*core.PersistentVolumeClaim, error) { + return provider.clientSet.CoreV1().PersistentVolumeClaims(namespace).Create(ctx, persistentVolumeClaim, metav1.CreateOptions{}) +} + func (provider *Provider) ApplyWorkerDaemonSet( ctx context.Context, namespace string, diff --git a/kubernetes/types.go b/kubernetes/types.go index fade8c2ae..275f9ab4b 100644 --- a/kubernetes/types.go +++ b/kubernetes/types.go @@ -111,7 +111,12 @@ func (d *DaemonSet) GenerateApplyConfiguration(name string, namespace string, po // Volumes for _, v := range p.Volumes { volume := applyconfcore.Volume() - volume.WithName(v.Name).WithHostPath(applyconfcore.HostPathVolumeSource().WithPath(v.HostPath.Path)) + if v.HostPath != nil { + volume.WithName(v.Name).WithHostPath(applyconfcore.HostPathVolumeSource().WithPath(v.HostPath.Path)) + } + if v.PersistentVolumeClaim != nil { + volume.WithName(v.Name).WithPersistentVolumeClaim(applyconfcore.PersistentVolumeClaimVolumeSource().WithClaimName(v.PersistentVolumeClaim.ClaimName)) + } podSpec.WithVolumes(volume) } diff --git a/kubernetes/workers.go b/kubernetes/workers.go index 5e1af2e2f..2246363db 100644 --- a/kubernetes/workers.go +++ b/kubernetes/workers.go @@ -21,6 +21,19 @@ func CreateWorkers( tls bool, debug bool, ) error { + persistentVolumeClaim, err := kubernetesProvider.BuildPersistentVolumeClaim() + if err != nil { + return err + } + + if _, err = kubernetesProvider.CreatePersistentVolumeClaim( + ctx, + namespace, + persistentVolumeClaim, + ); err != nil { + return err + } + image := docker.GetWorkerImage() var serviceAccountName string diff --git a/manifests/04-hub-pod.yaml b/manifests/04-hub-pod.yaml index bc98755b7..ea2ee5cc6 100644 --- a/manifests/04-hub-pod.yaml +++ b/manifests/04-hub-pod.yaml @@ -18,8 +18,6 @@ spec: - name: POD_REGEX value: .* - name: NAMESPACES - - name: STORAGE_LIMIT - value: 200MB - name: LICENSE - name: SCRIPTING_ENV value: '{}' diff --git a/manifests/08-persistent-volume.yaml b/manifests/08-persistent-volume.yaml new file mode 100644 index 000000000..15e1445c7 --- /dev/null +++ b/manifests/08-persistent-volume.yaml @@ -0,0 +1,20 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY KUBESHARK CLI. DO NOT EDIT! +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + creationTimestamp: null + labels: + kubeshark-cli-version: v1 + kubeshark-created-by: kubeshark + kubeshark-managed-by: kubeshark + name: kubeshark-persistent-volume-claim + namespace: kubeshark +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 300Mi + storageClassName: standard +status: {} diff --git a/manifests/09-worker-daemon-set.yaml b/manifests/09-worker-daemon-set.yaml new file mode 100644 index 000000000..53c7ae0fd --- /dev/null +++ b/manifests/09-worker-daemon-set.yaml @@ -0,0 +1,90 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY KUBESHARK CLI. DO NOT EDIT! +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app: kubeshark-worker-daemon-set + kubeshark-created-by: kubeshark + kubeshark-managed-by: kubeshark + name: kubeshark-worker-daemon-set + namespace: kubeshark +spec: + selector: + matchLabels: + app: kubeshark-worker-daemon-set + kubeshark-created-by: kubeshark + kubeshark-managed-by: kubeshark + template: + metadata: + creationTimestamp: null + labels: + app: kubeshark-worker-daemon-set + kubeshark-created-by: kubeshark + kubeshark-managed-by: kubeshark + name: kubeshark-worker-daemon-set + namespace: kubeshark + spec: + containers: + - command: + - ./worker + - -i + - any + - -port + - "8897" + - -packet-capture + - libpcap + - -servicemesh + - -tls + - -procfs + - /hostproc + image: docker.io/kubeshark/worker:latest + imagePullPolicy: Always + name: kubeshark-worker-daemon-set + resources: + limits: + cpu: 750m + memory: 1Gi + requests: + cpu: 50m + memory: 50Mi + securityContext: + capabilities: + add: + - NET_RAW + - NET_ADMIN + - SYS_ADMIN + - SYS_PTRACE + - DAC_OVERRIDE + - SYS_RESOURCE + drop: + - ALL + volumeMounts: + - mountPath: /hostproc + name: proc + readOnly: true + - mountPath: /sys + name: sys + readOnly: true + - mountPath: /app/data + name: kubeshark-persistent-volume + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + serviceAccountName: kubeshark-service-account + terminationGracePeriodSeconds: 0 + tolerations: + - effect: NoExecute + operator: Exists + - effect: NoSchedule + operator: Exists + volumes: + - hostPath: + path: /proc + name: proc + - hostPath: + path: /sys + name: sys + - name: kubeshark-persistent-volume + persistentVolumeClaim: + claimName: kubeshark-persistent-volume-claim diff --git a/resources/cleanResources.go b/resources/cleanResources.go index 7b95b90d5..1c8283938 100644 --- a/resources/cleanResources.go +++ b/resources/cleanResources.go @@ -108,6 +108,11 @@ func cleanUpRestrictedMode(ctx context.Context, kubernetesProvider *kubernetes.P handleDeletionError(err, resourceDesc, &leftoverResources) } + if err := kubernetesProvider.RemovePersistentVolumeClaim(ctx, selfResourcesNamespace, kubernetes.PersistentVolumeClaimName); err != nil { + resourceDesc := fmt.Sprintf("Persistent Volume %s in namespace %s", kubernetes.PersistentVolumeClaimName, selfResourcesNamespace) + handleDeletionError(err, resourceDesc, &leftoverResources) + } + if err := kubernetesProvider.RemoveDaemonSet(ctx, selfResourcesNamespace, kubernetes.WorkerDaemonSetName); err != nil { resourceDesc := fmt.Sprintf("DaemonSet %s in namespace %s", kubernetes.WorkerDaemonSetName, selfResourcesNamespace) handleDeletionError(err, resourceDesc, &leftoverResources) diff --git a/utils/units.go b/utils/units.go deleted file mode 100644 index 8b222a1f6..000000000 --- a/utils/units.go +++ /dev/null @@ -1,7 +0,0 @@ -package utils - -import "github.com/docker/go-units" - -func HumanReadableToBytes(humanReadableSize string) (int64, error) { - return units.FromHumanSize(humanReadableSize) -}