Browse Source

Merge pull request #319 from vcozzolino/feature-reid

Add missed files in ReID feature merge and fix Docker images name.
tags/v0.5.1
KubeEdge Bot GitHub 3 years ago
parent
commit
7d5aa0f2d0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 310 additions and 141 deletions
  1. +5
    -5
      examples/build_image.sh
  2. +0
    -0
      examples/multi-edge-inference-pedestrian-tracking-feature-extraction.Dockerfile
  3. +0
    -0
      examples/multi-edge-inference-pedestrian-tracking-gpu-feature-extraction.Dockerfile
  4. +0
    -0
      examples/multi-edge-inference-pedestrian-tracking-gpu-videoanalytics.Dockerfile
  5. +0
    -0
      examples/multi-edge-inference-pedestrian-tracking-reid.Dockerfile
  6. +0
    -0
      examples/multi-edge-inference-pedestrian-tracking-videoanalytics.Dockerfile
  7. +3
    -3
      examples/multiedgeinference/pedestrian_tracking/README.md
  8. +1
    -1
      examples/multiedgeinference/pedestrian_tracking/yaml/feature-extraction-service.yaml
  9. +2
    -2
      examples/multiedgeinference/pedestrian_tracking/yaml/reid-job.yaml
  10. +1
    -1
      examples/multiedgeinference/pedestrian_tracking/yaml/video-analytics-job.yaml
  11. +229
    -124
      pkg/globalmanager/runtime/storage_initializer_injector.go
  12. +69
    -5
      pkg/globalmanager/runtime/worker.go

+ 5
- 5
examples/build_image.sh View File

@@ -61,11 +61,11 @@ IMAGE_TAG=${IMAGE_TAG:-v0.5.0}
EXAMPLE_REPO_PREFIX=${IMAGE_REPO}/sedna-example-

dockerfiles_multiedgeinference=(
multi-edge-inference-feature-extraction.Dockerfile
# multi-edge-inference-gpu-feature-extraction.Dockerfile
# multi-edge-inference-gpu-videoanalytics.Dockerfile
multi-edge-inference-reid.Dockerfile
multi-edge-inference-videoanalytics.Dockerfile
multi-edge-inference-pedestrian-tracking-feature-extraction.Dockerfile
# multi-edge-inference-pedestrian-tracking-gpu-feature-extraction.Dockerfile
# multi-edge-inference-pedestrian-tracking-gpu-videoanalytics.Dockerfile
multi-edge-inference-pedestrian-tracking-reid.Dockerfile
multi-edge-inference-pedestrian-tracking-videoanalytics.Dockerfile
)

dockerfiles_federated_learning=(


examples/multi-edge-inference-feature-extraction.Dockerfile → examples/multi-edge-inference-pedestrian-tracking-feature-extraction.Dockerfile View File


examples/multi-edge-inference-gpu-feature-extraction.Dockerfile → examples/multi-edge-inference-pedestrian-tracking-gpu-feature-extraction.Dockerfile View File


examples/multi-edge-inference-gpu-videoanalytics.Dockerfile → examples/multi-edge-inference-pedestrian-tracking-gpu-videoanalytics.Dockerfile View File


examples/multi-edge-inference-reid.Dockerfile → examples/multi-edge-inference-pedestrian-tracking-reid.Dockerfile View File


examples/multi-edge-inference-videoanalytics.Dockerfile → examples/multi-edge-inference-pedestrian-tracking-videoanalytics.Dockerfile View File


+ 3
- 3
examples/multiedgeinference/pedestrian_tracking/README.md View File

@@ -32,14 +32,14 @@ The image below shows the system architecture and its simplified workflow:
- Available for CPU only.
- Folder with specific implementation `examples/multiedgeinference/pedestrian_tracking/reid`.
- Component specs in `lib/sedna/core/multi_edge_inference/components/reid.py`.
- Defined by the Dockerfile `multi-edge-inference-reid.Dockerfile`.
- Defined by the Dockerfile `multi-edge-inference-pedestrian-tracking-reid.Dockerfile`.

**Feature Extraction Service**: it performs the extraction of the features necessary for the ReID step.

- Available for CPU and GPU.
- Folder with specific implementation details `examples/multiedgeinference/pedestrian_tracking/feature_extraction`.
- Component specs in `lib/sedna/core/multi_edge_inference/components/feature_extraction.py`.
- Defined by the Dockerfile `multi-edge-inference-feature-extraction.Dockerfile` or `multi-edge-inference-gpu-feature-extraction.Dockerfile`.
- Defined by the Dockerfile `multi-edge-inference-pedestrian-tracking-feature-extraction.Dockerfile` or `multi-edge-inference-pedestrian-tracking-gpu-feature-extraction.Dockerfile`.
- It loads the model defined by the CRD in the YAML file `yaml/models/model_m3l.yaml`.

**VideoAnalytics Job**: it performs tracking of objects (pedestrians) in a video.
@@ -48,7 +48,7 @@ The image below shows the system architecture and its simplified workflow:
- Folder with specific implementation details `examples/multiedgeinference/pedestrian_tracking/detection`.
- AI model code in `examples/multiedgeinference/detection/estimator/bytetracker.py`.
- Component specs in `lib/sedna/core/multi_edge_inference/components/detection.py`.
- Defined by the Dockerfile `multi-edge-inference-videoanalytics.Dockerfile` or `multi-edge-inference-gpu-videoanalytics.Dockerfile`.
- Defined by the Dockerfile `multi-edge-inference-pedestrian-tracking-videoanalytics.Dockerfile` or `multi-edge-inference-pedestrian-tracking-gpu-videoanalytics.Dockerfile`.
- It loads the model defined by the CRD in the YAML file `yaml/models/model_detection.yaml`.

# Build Phase


+ 1
- 1
examples/multiedgeinference/pedestrian_tracking/yaml/feature-extraction-service.yaml View File

@@ -18,7 +18,7 @@ spec:
nodeSelector:
node-role.kubernetes.io/master: ''
containers:
- image: registry-cbu.huawei.com/kubeedge/sedna-example-multi-edge-inference-feature-extraction:v0.5.0
- image: kubeedge/sedna-example-multi-edge-inference-pedestrian-tracking-feature-extraction:v0.5.0
imagePullPolicy: Always
name: feature-extraction
env:


+ 2
- 2
examples/multiedgeinference/pedestrian_tracking/yaml/reid-job.yaml View File

@@ -1,4 +1,4 @@
apiVersion: sedna.io/v1alpha1
apiVersion: sedna.io/v1alpha1
kind: ReidJob
metadata:
name: reid
@@ -10,7 +10,7 @@ spec:
nodeSelector:
node-role.kubernetes.io/master: ''
containers:
- image: registry-cbu.huawei.com/kubeedge/sedna-example-multi-edge-inference-reid:v0.5.0
- image: kubeedge/sedna-example-multi-edge-inference-pedestrian-tracking-reid:v0.5.0
name: reid
imagePullPolicy: Always
env:


+ 1
- 1
examples/multiedgeinference/pedestrian_tracking/yaml/video-analytics-job.yaml View File

@@ -12,7 +12,7 @@ spec:
nodeSelector:
node-role.kubernetes.io/master: ''
containers:
- image: registry-cbu.huawei.com/kubeedge/sedna-example-multi-edge-inference-videoanalytics:sase
- image: kubeedge/sedna-example-multi-edge-inference-pedestrian-tracking-videoanalytics:v0.5.0
imagePullPolicy: Always
name: detection
env:


+ 229
- 124
pkg/globalmanager/runtime/storage_initializer_injector.go View File

@@ -21,6 +21,7 @@ import (
"path/filepath"
"strings"

appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/klog/v2"
@@ -171,58 +172,60 @@ func (m *MountURL) parseSecret() {
}

func injectHostPathMount(pod *v1.Pod, workerParam *WorkerParam) {
var volumes []v1.Volume
var volumeMounts []v1.VolumeMount
var initContainerVolumeMounts []v1.VolumeMount
volumes, volumeMounts, initContainerVolumeMounts := PrepareHostPath(workerParam)

uniqVolumeName := make(map[string]bool)
uniqMountPath := make(map[string]bool)
injectVolume(pod, volumes, volumeMounts)

hostPathType := v1.HostPathDirectory
if len(volumeMounts) > 0 {
hostPathEnvs := []v1.EnvVar{
{
Name: hostPathPrefixEnvKey,
Value: hostPathPrefix,
},
}
injectEnvs(pod, hostPathEnvs)
}

if len(initContainerVolumeMounts) > 0 {
initIdx := len(pod.Spec.InitContainers) - 1
pod.Spec.InitContainers[initIdx].VolumeMounts = append(
pod.Spec.InitContainers[initIdx].VolumeMounts,
initContainerVolumeMounts...,
)
}
}

func injectWorkerSecrets(pod *v1.Pod, workerParam *WorkerParam) {
var secretEnvs []v1.EnvVar
for _, mount := range workerParam.Mounts {
for _, m := range mount.URLs {
if m.HostPath == "" {
if m.Disable || m.DownloadByInitializer {
continue
}

volumeName := ConvertK8SValidName(m.HostPath)

if len(volumeName) == 0 {
volumeName = defaultVolumeName
klog.Warningf("failed to get name from url(%s), fallback to default name(%s)", m.URL, volumeName)
}

if _, ok := uniqVolumeName[volumeName]; !ok {
volumes = append(volumes, v1.Volume{
Name: volumeName,
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: m.HostPath,
Type: &hostPathType,
},
},
})
uniqVolumeName[volumeName] = true
if len(m.SecretEnvs) > 0 {
secretEnvs = MergeSecretEnvs(secretEnvs, m.SecretEnvs, false)
}
}
}
injectEnvs(pod, secretEnvs)
}

if _, ok := uniqMountPath[m.MountPath]; !ok {
vm := v1.VolumeMount{
MountPath: m.MountPath,
Name: volumeName,
}
func injectInitializerContainer(pod *v1.Pod, workerParam *WorkerParam) {
volumes, volumeMounts, initContainer := PrepareInitContainer(workerParam)

if m.Indirect {
initContainerVolumeMounts = append(initContainerVolumeMounts, vm)
} else {
volumeMounts = append(volumeMounts, vm)
}
uniqMountPath[m.MountPath] = true
}
}
if (len(volumes) > 0) && (len(volumeMounts) > 0) && &initContainer != nil {
pod.Spec.InitContainers = append(pod.Spec.InitContainers, *initContainer)
injectVolume(pod, volumes, volumeMounts)
}
}

injectVolume(pod, volumes, volumeMounts)
/*
Deployment Storage Hooks
*/

func injectHostPathMountDeployment(deployment *appsv1.Deployment, workerParam *WorkerParam) {
volumes, volumeMounts, initContainerVolumeMounts := PrepareHostPath(workerParam)
injectVolumeDeployment(deployment, volumes, volumeMounts)

if len(volumeMounts) > 0 {
hostPathEnvs := []v1.EnvVar{
@@ -231,19 +234,147 @@ func injectHostPathMount(pod *v1.Pod, workerParam *WorkerParam) {
Value: hostPathPrefix,
},
}
injectEnvs(pod, hostPathEnvs)
injectEnvsDeployment(deployment, hostPathEnvs)
}

if len(initContainerVolumeMounts) > 0 {
initIdx := len(pod.Spec.InitContainers) - 1
pod.Spec.InitContainers[initIdx].VolumeMounts = append(
pod.Spec.InitContainers[initIdx].VolumeMounts,
initIdx := len(deployment.Spec.Template.Spec.InitContainers) - 1
deployment.Spec.Template.Spec.InitContainers[initIdx].VolumeMounts = append(
deployment.Spec.Template.Spec.InitContainers[initIdx].VolumeMounts,
initContainerVolumeMounts...,
)
}
}

func injectWorkerSecrets(pod *v1.Pod, workerParam *WorkerParam) {
func injectWorkerSecretsDeployment(deployment *appsv1.Deployment, workerParam *WorkerParam) {
secretEnvs := PrepareSecret(workerParam)
injectEnvsDeployment(deployment, secretEnvs)
}

func injectInitializerContainerDeployment(deployment *appsv1.Deployment, workerParam *WorkerParam) {
volumes, volumeMounts, initContainer := PrepareInitContainer(workerParam)

if (len(volumes) > 0) && (len(volumeMounts) > 0) && &initContainer != nil {
deployment.Spec.Template.Spec.InitContainers = append(deployment.Spec.Template.Spec.InitContainers, *initContainer)
injectVolumeDeployment(deployment, volumes, volumeMounts)
}
}

// InjectStorageInitializer injects these storage related volumes and envs into deployment in-place
func InjectStorageInitializerDeployment(deployment *appsv1.Deployment, workerParam *WorkerParam) {
PrepareStorage(workerParam)

// need to call injectInitializerContainer before injectHostPathMount
// since injectHostPathMount could inject volumeMount to init container
injectInitializerContainerDeployment(deployment, workerParam)
injectHostPathMountDeployment(deployment, workerParam)
injectWorkerSecretsDeployment(deployment, workerParam)
}

func injectVolumeDeployment(deployment *appsv1.Deployment, volumes []v1.Volume, volumeMounts []v1.VolumeMount) {
if len(volumes) > 0 {
deployment.Spec.Template.Spec.Volumes = append(deployment.Spec.Template.Spec.Volumes, volumes...)
}

if len(volumeMounts) > 0 {
for idx := range deployment.Spec.Template.Spec.Containers {
// inject every containers
deployment.Spec.Template.Spec.Containers[idx].VolumeMounts = append(
deployment.Spec.Template.Spec.Containers[idx].VolumeMounts, volumeMounts...,
)
}
}
}

func injectEnvsDeployment(deployment *appsv1.Deployment, envs []v1.EnvVar) {
if len(envs) > 0 {
for idx := range deployment.Spec.Template.Spec.Containers {
// inject every containers
deployment.Spec.Template.Spec.Containers[idx].Env = append(
deployment.Spec.Template.Spec.Containers[idx].Env, envs...,
)
}
}
}

// InjectStorageInitializer injects these storage related volumes and envs into pod in-place
func InjectStorageInitializer(pod *v1.Pod, workerParam *WorkerParam) {
PrepareStorage(workerParam)

// need to call injectInitializerContainer before injectHostPathMount
// since injectHostPathMount could inject volumeMount to init container
injectInitializerContainer(pod, workerParam)
injectHostPathMount(pod, workerParam)
injectWorkerSecrets(pod, workerParam)
}

func injectVolume(pod *v1.Pod, volumes []v1.Volume, volumeMounts []v1.VolumeMount) {
if len(volumes) > 0 {
pod.Spec.Volumes = append(pod.Spec.Volumes, volumes...)
}

if len(volumeMounts) > 0 {
for idx := range pod.Spec.Containers {
// inject every containers
pod.Spec.Containers[idx].VolumeMounts = append(
pod.Spec.Containers[idx].VolumeMounts, volumeMounts...,
)
}
}
}

func injectEnvs(pod *v1.Pod, envs []v1.EnvVar) {
if len(envs) > 0 {
for idx := range pod.Spec.Containers {
// inject every containers
pod.Spec.Containers[idx].Env = append(
pod.Spec.Containers[idx].Env, envs...,
)
}
}
}

func PrepareStorage(workerParam *WorkerParam) {
var mounts []WorkerMount
// parse the mounts and environment key
for _, mount := range workerParam.Mounts {
var envPaths []string

if mount.URL != nil {
mount.URLs = append(mount.URLs, *mount.URL)
}

var mountURLs []MountURL
for _, m := range mount.URLs {
m.Parse()
if m.Disable {
continue
}
mountURLs = append(mountURLs, m)

if m.ContainerPath != "" {
envPaths = append(envPaths, m.ContainerPath)
} else {
// keep the original URL if no container path
envPaths = append(envPaths, m.URL)
}
}

if len(mountURLs) > 0 {
mount.URLs = mountURLs
mounts = append(mounts, mount)
}

if mount.EnvName != "" {
workerParam.Env[mount.EnvName] = strings.Join(
envPaths, urlsFieldSep,
)
}
}
workerParam.Mounts = mounts
}

func PrepareSecret(workerParam *WorkerParam) []v1.EnvVar {
var secretEnvs []v1.EnvVar
for _, mount := range workerParam.Mounts {
for _, m := range mount.URLs {
@@ -255,10 +386,59 @@ func injectWorkerSecrets(pod *v1.Pod, workerParam *WorkerParam) {
}
}
}
injectEnvs(pod, secretEnvs)
return secretEnvs
}

func injectInitializerContainer(pod *v1.Pod, workerParam *WorkerParam) {
func PrepareHostPath(workerParam *WorkerParam) ([]v1.Volume, []v1.VolumeMount, []v1.VolumeMount) {
var volumes []v1.Volume
var volumeMounts []v1.VolumeMount
var initContainerVolumeMounts []v1.VolumeMount

uniqVolumeName := make(map[string]bool)

hostPathType := v1.HostPathDirectory

for _, mount := range workerParam.Mounts {
for _, m := range mount.URLs {
if m.HostPath == "" {
continue
}

volumeName := ConvertK8SValidName(m.HostPath)

if len(volumeName) == 0 {
volumeName = defaultVolumeName
klog.Warningf("failed to get name from url(%s), fallback to default name(%s)", m.URL, volumeName)
}

if _, ok := uniqVolumeName[volumeName]; !ok {
volumes = append(volumes, v1.Volume{
Name: volumeName,
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: m.HostPath,
Type: &hostPathType,
},
},
})
uniqVolumeName[volumeName] = true
}

vm := v1.VolumeMount{
MountPath: m.MountPath,
Name: volumeName,
}
if m.Indirect {
initContainerVolumeMounts = append(initContainerVolumeMounts, vm)
} else {
volumeMounts = append(volumeMounts, vm)
}
}
}
return volumes, volumeMounts, initContainerVolumeMounts
}

func PrepareInitContainer(workerParam *WorkerParam) ([]v1.Volume, []v1.VolumeMount, *v1.Container) {
var volumes []v1.Volume
var volumeMounts []v1.VolumeMount

@@ -289,7 +469,7 @@ func injectInitializerContainer(pod *v1.Pod, workerParam *WorkerParam) {

// no need to download
if len(downloadPairs) == 0 {
return
return nil, nil, nil
}

envs := secretEnvs
@@ -343,80 +523,5 @@ func injectInitializerContainer(pod *v1.Pod, workerParam *WorkerParam) {
Env: envs,
}

pod.Spec.InitContainers = append(pod.Spec.InitContainers, initContainer)
injectVolume(pod, volumes, volumeMounts)
}

// InjectStorageInitializer injects these storage related volumes and envs into pod in-place
func InjectStorageInitializer(pod *v1.Pod, workerParam *WorkerParam) {
var mounts []WorkerMount
// parse the mounts and environment key
for _, mount := range workerParam.Mounts {
var envPaths []string

if mount.URL != nil {
mount.URLs = append(mount.URLs, *mount.URL)
}

var mountURLs []MountURL
for _, m := range mount.URLs {
m.Parse()
if m.Disable {
continue
}
mountURLs = append(mountURLs, m)

if m.ContainerPath != "" {
envPaths = append(envPaths, m.ContainerPath)
} else {
// keep the original URL if no container path
envPaths = append(envPaths, m.URL)
}
}

if len(mountURLs) > 0 {
mount.URLs = mountURLs
mounts = append(mounts, mount)
}

if mount.EnvName != "" {
workerParam.Env[mount.EnvName] = strings.Join(
envPaths, urlsFieldSep,
)
}
}

workerParam.Mounts = mounts

// need to call injectInitializerContainer before injectHostPathMount
// since injectHostPathMount could inject volumeMount to init container
injectInitializerContainer(pod, workerParam)
injectHostPathMount(pod, workerParam)
injectWorkerSecrets(pod, workerParam)
}

func injectVolume(pod *v1.Pod, volumes []v1.Volume, volumeMounts []v1.VolumeMount) {
if len(volumes) > 0 {
pod.Spec.Volumes = append(pod.Spec.Volumes, volumes...)
}

if len(volumeMounts) > 0 {
for idx := range pod.Spec.Containers {
// inject every containers
pod.Spec.Containers[idx].VolumeMounts = append(
pod.Spec.Containers[idx].VolumeMounts, volumeMounts...,
)
}
}
}

func injectEnvs(pod *v1.Pod, envs []v1.EnvVar) {
if len(envs) > 0 {
for idx := range pod.Spec.Containers {
// inject every containers
pod.Spec.Containers[idx].Env = append(
pod.Spec.Containers[idx].Env, envs...,
)
}
}
return volumes, volumeMounts, &initContainer
}

+ 69
- 5
pkg/globalmanager/runtime/worker.go View File

@@ -83,6 +83,48 @@ func GenerateWorkerSelector(object CommonInterface, workerType string) (labels.S
return metav1.LabelSelectorAsSelector(ls)
}

// CreateKubernetesService creates a k8s service for an object given ip and port
func CreateKubernetesService(kubeClient kubernetes.Interface, object CommonInterface, workerType string, inputPort int32, inputIP string) (int32, error) {
ctx := context.Background()
name := object.GetName()
namespace := object.GetNamespace()
kind := object.GroupVersionKind().Kind
targePort := intstr.IntOrString{
IntVal: inputPort,
}
serviceSpec := &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Namespace: object.GetNamespace(),
Name: strings.ToLower(name + "-" + workerType),
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(object, object.GroupVersionKind()),
},
Labels: generateLabels(object, workerType),
},
Spec: v1.ServiceSpec{
Selector: generateLabels(object, workerType),
ExternalIPs: []string{
inputIP,
},
Type: v1.ServiceTypeNodePort,
Ports: []v1.ServicePort{
{
Port: inputPort,
TargetPort: targePort,
},
},
},
}
service, err := kubeClient.CoreV1().Services(namespace).Create(ctx, serviceSpec, metav1.CreateOptions{})
if err != nil {
klog.Warningf("failed to create service for %v %v/%v, err:%s", kind, namespace, name, err)
return 0, err
}

klog.V(2).Infof("Service %s is created successfully for %v %v/%v", service.Name, kind, namespace, name)
return service.Spec.Ports[0].NodePort, nil
}

// injectWorkerParam modifies pod in-place
func injectWorkerParam(pod *v1.Pod, workerParam *WorkerParam, object CommonInterface) {
InjectStorageInitializer(pod, workerParam)
@@ -188,7 +230,9 @@ func CreateDeploymentWithTemplate(client kubernetes.Interface, object CommonInte
objectKind := object.GroupVersionKind()
objectName := object.GetNamespace() + "/" + object.GetName()
deployment := newDeployment(object, spec, workerParam)

injectDeploymentParam(deployment, workerParam, object, port)

createdDeployment, err := client.AppsV1().Deployments(object.GetNamespace()).Create(context.TODO(), deployment, metav1.CreateOptions{})
if err != nil {
klog.Warningf("failed to create deployment for %s %s, err:%s", objectKind, objectName, err)
@@ -221,7 +265,16 @@ func newDeployment(object CommonInterface, spec *appsv1.DeploymentSpec, workerPa
}

// injectDeploymentParam modifies deployment in-place
func injectDeploymentParam(deployment *appsv1.Deployment, workerParam *WorkerParam, object CommonInterface, port int32) {
func injectDeploymentParam(deployment *appsv1.Deployment, workerParam *WorkerParam, object CommonInterface, _port int32) {
var appLabelKey = "app.sedna.io"
var appLabelValue = object.GetName() + "-" + workerParam.WorkerType + "-" + "svc"

// Injection of the storage variables must be done before loading
// the environment variables!
if workerParam.Mounts != nil {
InjectStorageInitializerDeployment(deployment, workerParam)
}

// inject our labels
if deployment.Labels == nil {
deployment.Labels = make(map[string]string)
@@ -229,16 +282,27 @@ func injectDeploymentParam(deployment *appsv1.Deployment, workerParam *WorkerPar
if deployment.Spec.Template.Labels == nil {
deployment.Spec.Template.Labels = make(map[string]string)
}
if deployment.Spec.Selector.MatchLabels == nil {
deployment.Spec.Selector.MatchLabels = make(map[string]string)
}

for k, v := range generateLabels(object, workerParam.WorkerType) {
deployment.Labels[k] = v
deployment.Spec.Template.Labels[k] = v
deployment.Spec.Selector.MatchLabels[k] = v
}
deployment.Spec.Template.Spec.Containers[0].Ports = []v1.ContainerPort{
{
ContainerPort: port,
},

// Edgemesh part, useful for service mapping (not necessary!)
deployment.Labels[appLabelKey] = appLabelValue
deployment.Spec.Template.Labels[appLabelKey] = appLabelValue
deployment.Spec.Selector.MatchLabels[appLabelKey] = appLabelValue

// Env variables injection
envs := createEnvVars(workerParam.Env)
for idx := range deployment.Spec.Template.Spec.Containers {
deployment.Spec.Template.Spec.Containers[idx].Env = append(
deployment.Spec.Template.Spec.Containers[idx].Env, envs...,
)
}
}



Loading…
Cancel
Save