diff options
author | Miloslav Trmač <mitr@redhat.com> | 2021-11-19 09:52:23 +0100 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2021-11-30 22:13:52 +0100 |
commit | ec686d68ddf326c8f4e50f2770be3ed7d250c6d0 (patch) | |
tree | 51971fe466cf0f282c76c076c2655ed14f8fc4de | |
parent | d48c00418ae7f6efcfe45d92f3c5e08b9c8afacd (diff) | |
download | podman-ec686d68ddf326c8f4e50f2770be3ed7d250c6d0.tar.gz podman-ec686d68ddf326c8f4e50f2770be3ed7d250c6d0.tar.bz2 podman-ec686d68ddf326c8f4e50f2770be3ed7d250c6d0.zip |
Don't use the global math/rand RNG for service ports
Use a private RNG with the desired seed, don't interfere
with the other uses.
Introducing the servicePortState type is rather overkill
for the single member, but we'll add another one immediately.
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
-rw-r--r-- | libpod/kube.go | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/libpod/kube.go b/libpod/kube.go index 30a3b069c..73d219fbc 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -79,7 +79,8 @@ func (p *Pod) GenerateForKube(ctx context.Context) (*v1.Pod, []v1.ServicePort, e if err != nil { return nil, servicePorts, err } - servicePorts = containerPortsToServicePorts(ports) + spState := newServicePortState() + servicePorts = spState.containerPortsToServicePorts(ports) hostNetwork = infraContainer.NetworkMode() == string(namespaces.NetworkMode(specgen.Host)) } pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork) @@ -265,13 +266,26 @@ func GenerateKubeServiceFromV1Pod(pod *v1.Pod, servicePorts []v1.ServicePort) YA return service } +// servicePortState allows calling containerPortsToServicePorts for a single service +type servicePortState struct { + // A program using the shared math/rand state with the default seed will produce the same sequence of pseudo-random numbers + // for each execution. Use a private RNG state not to interfere with other users. + rng *rand.Rand +} + +func newServicePortState() servicePortState { + return servicePortState{ + rng: rand.New(rand.NewSource(time.Now().UnixNano())), + } +} + // containerPortsToServicePorts takes a slice of containerports and generates a // slice of service ports -func containerPortsToServicePorts(containerPorts []v1.ContainerPort) []v1.ServicePort { +func (state *servicePortState) containerPortsToServicePorts(containerPorts []v1.ContainerPort) []v1.ServicePort { sps := make([]v1.ServicePort, 0, len(containerPorts)) for _, cp := range containerPorts { // Legal nodeport range is 30000-32767 - nodePort := 30000 + rand.Intn(32767-30000+1) + nodePort := 30000 + state.rng.Intn(32767-30000+1) servicePort := v1.ServicePort{ Protocol: cp.Protocol, Port: cp.ContainerPort, @@ -287,13 +301,10 @@ func containerPortsToServicePorts(containerPorts []v1.ContainerPort) []v1.Servic // containersToServicePorts takes a slice of v1.Containers and generates an // inclusive list of serviceports to expose func containersToServicePorts(containers []v1.Container) []v1.ServicePort { - // Without the call to rand.Seed, a program will produce the same sequence of pseudo-random numbers - // for each execution. - rand.Seed(time.Now().UnixNano()) - + state := newServicePortState() sps := make([]v1.ServicePort, 0, len(containers)) for _, ctr := range containers { - sps = append(sps, containerPortsToServicePorts(ctr.Ports)...) + sps = append(sps, state.containerPortsToServicePorts(ctr.Ports)...) } return sps } |