Skip to content
Snippets Groups Projects
Commit 35b69ad6 authored by Raphael Defosseux's avatar Raphael Defosseux
Browse files

Merge branch 'feat/helm-repo' into 'master'

Major Update of Helm-Charts

See merge request !114
parents 6780b364 c3601664
No related branches found
No related tags found
1 merge request!114Major Update of Helm-Charts
Showing
with 783 additions and 112 deletions
...@@ -26,9 +26,9 @@ type: application ...@@ -26,9 +26,9 @@ type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
version: v1.5.0 version: v1.5.1
appVersion: v1.5.0 appVersion: develop-v1.5.1
keywords: keywords:
- EPC - EPC
......
# Helm Chart for OAI Serving and Packet Data Network Gateway User Plane (SPGW-U)
The helm-chart is tested on [Minikube](https://minikube.sigs.k8s.io/docs/) and [Red Hat Openshift](https://www.redhat.com/fr/technologies/cloud-computing/openshift) 4.10 and 4.12. There are no special resource requirements for SPGWU except `privileged` flag to be true. SPGWU needs to create tunnel interface for GTP and it creates NAT rules for packets to go towards internet from N6.
**NOTE**: All the extra interfaces/multus interfaces created inside the pod are using `macvlan` mode. If your environment does not allow using `macvlan` then you need to change the multus definations.
## Introduction
[OAI-SPGWU-TINY](https://github.com/OPENAIRINTERFACE/openair-spgwu-tiny) is the 4G CUPS S/PGWU. We modified it to work for 5G deployments with GTP-U extension header.
OAI [Jenkins Platform](https://jenkins-oai.eurecom.fr/job/OAI-CN-SPGWU-TINY/) publishes every `develop` and `master` branch image of OAI-SPGWU-TINY on [docker-hub](https://hub.docker.com/r/oaisoftwarealliance/oai-spgwu-tiny) with tag `develop` and `latest` respectively. Apart from that you can find tags for every release `VX.X.X`. We only publish Ubuntu 18.04/20.04/22.04 images. We do not publish RedHat/UBI images. These images you have to build from the source code on your RedHat systems or Openshift Platform. You can follow this [tutorial](../../../openshift/README.md) for that.
The helm chart of OAI-SPGWU-TINY creates multiples Kubernetes resources,
1. Service
2. Role Base Access Control (RBAC) (role and role bindings)
3. Deployment
4. Configmap (Contains the configuration file for SPGWU)
5. Service account
6. Network-attachment-definition (Optional only when multus is used)
The directory structure
```
├── Chart.yaml
├── README.md
├── templates
│ ├── configmap.yaml
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── multus.yaml
│ ├── NOTES.txt
│ ├── rbac.yaml
│ ├── serviceaccount.yaml
│ └── service.yaml
└── values.yaml (Parent file contains all the configurable parameters)
```
## Parameters
[Values.yaml](./values.yaml) contains all the configurable parameters. Below table defines the configurable parameters.
|Parameter |Allowed Values |Remark |
|--------------------------------|-------------------------------|-------------------------------------|
|kubernetesType |Vanilla/Openshift |Vanilla Kubernetes or Openshift |
|nfimage.repository |Image Name | |
|nfimage.version |Image tag | |
|nfimage.pullPolicy |IfNotPresent or Never or Always| |
|imagePullSecrets.name |String |Good to use for docker hub |
|serviceAccount.create |true/false | |
|serviceAccount.annotations |String | |
|serviceAccount.name |String | |
|podSecurityContext.runAsUser |Integer (0,65534) | |
|podSecurityContext.runAsGroup |Integer (0,65534) | |
|multus.n3Interface.create |true/false | |
|multus.n3Interface.Ipadd |Ip-Address | |
|multus.n3Interface.Netmask |Netmask | |
|multus.n3Interface.Gateway |Ip-Address | |
|multus.n3Interface.routes |Json |Routes if you want to add in your pod|
|multus.n3Interface.hostInterface|host interface |Host interface on which pod will run |
|multus.n4Interface.create |true/false | |
|multus.n4Interface.Ipadd |Ip-Address | |
|multus.n4Interface.Netmask |Netmask | |
|multus.n4Interface.Gateway |Ip-Address | |
|multus.n4Interface.routes |Json |Routes if you want to add in your pod|
|multus.n4Interface.hostInterface|host interface |Host interface on which pod will run |
|multus.n6Interface.create |true/false | |
|multus.n6Interface.Ipadd |Ip-Address | |
|multus.n6Interface.Netmask |Netmask | |
|multus.n6Interface.Gateway |Ip-Address | |
|multus.n6Interface.routes |Json |Routes if you want to add in your pod|
|multus.n6Interface.hostInterface|host interface |Host interface on which pod will run |
|multus.defaultGateway |Ip-Address |Default route inside pod |
### Configuration parameter
All the parameters in `config` block of values.yaml are explained with a comment.
## Advanced Debugging Parameters
|Parameter |Allowed Values |Remark |
|---------------------------------|-------------------------------|----------------------------------------------|
|start.spgwu |true/false |If true spgwu container will go in sleep mode |
|start.tcpdump |true/false |If true tcpdump container will go in sleepmode|
|includeTcpDumpContainer |true/false |If false no tcpdump container will be there |
|tcpdumpimage.repository |Image Name | |
|tcpdumpimage.version |Image tag | |
|tcpdumpimage.pullPolicy |IfNotPresent or Never or Always| |
|persistent.sharedvolume |true/false |Save the pcaps in a shared volume with NRF |
|resources.define |true/false | |
|resources.limits.tcpdump.cpu |string |Unit m for milicpu or cpu |
|resources.limits.tcpdump.memory |string |Unit Mi/Gi/MB/GB |
|resources.limits.nf.cpu |string |Unit m for milicpu or cpu |
|resources.limits.nf.memory |string |Unit Mi/Gi/MB/GB |
|resources.requests.tcpdump.cpu |string |Unit m for milicpu or cpu |
|resources.requests.tcpdump.memory|string |Unit Mi/Gi/MB/GB |
|resources.requests.nf.cpu |string |Unit m for milicpu or cpu |
|resources.requests.nf.memory |string |Unit Mi/Gi/MB/GB |
|readinessProbe |true/false |default true |
|livenessProbe |true/false |default false |
|terminationGracePeriodSeconds |5 |In seconds (default 5) |
|nodeSelector |Node label | |
|nodeName |Node Name | |
## Installation
Better to use the parent charts from:
1. [oai-5g-basic](../oai-5g-basic/README.md) for basic deployment of OAI-5G Core
2. [oai-5g-mini](../oai-5g-mini/README.md) for mini deployment (AMF, SMF, NRF, UPF) of OAI-5G Core. In this type of deployment AMF plays the role of AUSF and UDR
3. [oai-5g-slicing](../oai-5g-slicing/README.md) for basic deployment with NSSF extra
## Note
1. If you are using multus then make sure it is properly configured and if you don't have a gateway for your multus interface then avoid using gateway and defaultGateway parameter. Either comment them or leave them empty. Wrong gateway configuration can create issues with pod networking and pod will not be able to resolve service names.
2. If you are using tcpdump container to take pcaps automatically (`start.tcpdump` is true) you can enable `persistent.sharedvolume` and [presistent volume](./oai-nrf/values.yaml) in NRF. To store the pcaps of all the NFs in one location. It is to ease the automated collection of pcaps.
\ No newline at end of file
...@@ -10,6 +10,7 @@ data: ...@@ -10,6 +10,7 @@ data:
FQDN = "oai-spgwu-tiny-svc"; # only needed for 4g FQDN = "oai-spgwu-tiny-svc"; # only needed for 4g
INSTANCE = 0; # 0 is the default INSTANCE = 0; # 0 is the default
PID_DIRECTORY = "/var/run"; # /var/run is the default PID_DIRECTORY = "/var/run"; # /var/run is the default
LOG_LEVEL = "{{ .Values.config.logLevel }}"
INTERFACES : INTERFACES :
{ {
......
...@@ -15,13 +15,38 @@ spec: ...@@ -15,13 +15,38 @@ spec:
metadata: metadata:
labels: labels:
{{- include "oai-spgwu-tiny.selectorLabels" . | nindent 8 }} {{- include "oai-spgwu-tiny.selectorLabels" . | nindent 8 }}
{{- if .Values.multus.create }} {{- if .Values.multus.n3Interface.create }}
annotations: annotations:
k8s.v1.cni.cncf.io/networks: >- k8s.v1.cni.cncf.io/networks: >-
[{ [{
"name": "{{ .Chart.Name }}-n3-net1", "name": "{{ .Chart.Name }}-n3",
"default-route": ["{{ .Values.multus.n6Gw }}"] "interface": "n3"
}] {{- if .Values.multus.defaultGateway }}
,"default-route": ["{{ .Values.multus.defaultGateway }}"]
{{- end }}
{{- if .Values.multus.n3Interface.Gateway }}
,"gateway": "{{ .Values.multus.n3Interface.Gateway }}"
{{- end }}
}
{{- if .Values.multus.n4Interface.create }}
,{
"name": "{{ .Chart.Name }}-n4",
"interface": "n4"
{{- if .Values.multus.n4Interface.Gateway }}
,"gateway": "{{ .Values.multus.n4Interface.Gateway }}"
{{- end }}
}
{{- end }}
{{- if .Values.multus.n6Interface.create }}
,{
"name": "{{ .Chart.Name }}-n6",
"interface": "n6"
{{- if .Values.multus.n6Interface.Gateway }}
,"gateway": "{{ .Values.multus.n6Interface.Gateway }}"
{{- end }}
}
{{- end }}
]
{{- end }} {{- end }}
spec: spec:
securityContext: securityContext:
...@@ -31,35 +56,39 @@ spec: ...@@ -31,35 +56,39 @@ spec:
{{ toYaml .Values.imagePullSecrets | indent 8 }} {{ toYaml .Values.imagePullSecrets | indent 8 }}
{{- end }} {{- end }}
containers: containers:
{{- if .Values.includeTcpDumpContainer }}
- name: tcpdump - name: tcpdump
image: "{{ .Values.tcpdumpimage.repository }}:{{ .Values.tcpdumpimage.version }}" image: "{{ .Values.tcpdumpimage.repository }}:{{ .Values.tcpdumpimage.version }}"
imagePullPolicy: {{ .Values.tcpdumpimage.pullPolicy }} imagePullPolicy: {{ .Values.tcpdumpimage.pullPolicy }}
{{- if .Values.resources.define}}
resources:
requests:
memory: {{ .Values.resources.requests.tcpdump.memory | quote }}
cpu: {{ .Values.resources.requests.tcpdump.cpu | quote }}
limits:
memory: {{ .Values.resources.limits.tcpdump.memory | quote }}
cpu: {{ .Values.resources.limits.tcpdump.cpu | quote }}
{{- end}}
securityContext: securityContext:
{{- toYaml .Values.securityContext | nindent 12 }} {{- toYaml .Values.securityContext | nindent 12 }}
{{- if .Values.start.tcpdump}} {{- if .Values.start.tcpdump}}
command: command:
- /bin/sh - /bin/sh
- -c - -c
- /usr/sbin/tcpdump -i any -w /pcap/{{ .Chart.Name }}_`date +%Y-%m-%d_%H_%M-%S-%Z`.pcap - /usr/sbin/tcpdump -i any -w /tmp/pcap/{{ .Chart.Name }}_`date +%Y-%m-%d_%H_%M-%S-%Z`.pcap
{{- else}} {{- else}}
{{- if .Values.resources.define}}
resources:
requests:
memory: {{ .Values.resources.tcpdump.requests.memory | quote }}
cpu: {{ .Values.resources.tcpdump.requests.cpu | quote }}
limits:
memory: {{ .Values.resources.tcpdump.limits.memory | quote }}
cpu: {{ .Values.resources.tcpdump.limits.cpu | quote }}
{{- end}}
command: command:
- /bin/sleep - /bin/sleep
- infinity - infinity
{{- end}} {{- end}}
{{- if .Values.includeTcpDumpContainer}}
{{- if .Values.persistent.sharedvolume}} {{- if .Values.persistent.sharedvolume}}
volumeMounts: volumeMounts:
- mountPath: "/pcap" - mountPath: "/tmp/pcap"
name: cn5g-pvc name: cn5g-pvc
{{- end}} {{- end}}
{{- end}}
{{- end }}
- name: spgwu - name: spgwu
image: "{{ .Values.nfimage.repository }}:{{ .Values.nfimage.version }}" image: "{{ .Values.nfimage.repository }}:{{ .Values.nfimage.version }}"
imagePullPolicy: {{ .Values.nfimage.pullPolicy }} imagePullPolicy: {{ .Values.nfimage.pullPolicy }}
...@@ -105,18 +134,20 @@ spec: ...@@ -105,18 +134,20 @@ spec:
{{- if .Values.resources.define}} {{- if .Values.resources.define}}
resources: resources:
requests: requests:
memory: {{ .Values.resources.nf.requests.memory | quote }} memory: {{ .Values.resources.requests.nf.memory | quote }}
cpu: {{ .Values.resources.nf.requests.cpu | quote }} cpu: {{ .Values.resources.requests.nf.cpu | quote }}
limits: limits:
memory: {{ .Values.resources.nf.limits.memory | quote }} memory: {{ .Values.resources.limits.nf.memory | quote }}
cpu: {{ .Values.resources.nf.limits.cpu | quote }} cpu: {{ .Values.resources.limits.nf.cpu | quote }}
{{- end}} {{- end}}
volumes: volumes:
{{- if .Values.includeTcpDumpContainer}}
{{- if .Values.persistent.sharedvolume}} {{- if .Values.persistent.sharedvolume}}
- name: cn5g-pvc - name: cn5g-pvc
persistentVolumeClaim: persistentVolumeClaim:
claimName: cn5g-pvc claimName: cn5g-pvc
{{- end }} {{- end }}
{{- end }}
- configMap: - configMap:
name: {{ .Chart.Name }}-configmap name: {{ .Chart.Name }}-configmap
name: configuration name: configuration
......
--- ---
{{- if .Values.multus.create }} {{- if .Values.multus.n3Interface.create }}
apiVersion: "k8s.cni.cncf.io/v1" apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition kind: NetworkAttachmentDefinition
metadata: metadata:
name: {{ .Chart.Name }}-n3-net1 name: {{ .Chart.Name }}-n3
spec: spec:
config: '{ config: '{
"cniVersion": "0.3.0", "cniVersion": "0.3.1",
"type": "macvlan", "type": "macvlan",
"master": {{- cat .Values.multus.hostInterface | nospace | quote }}, "master": {{- cat .Values.multus.n3Interface.hostInterface | nospace | quote }},
"mode": "bridge", "mode": "bridge",
"ipam": { "ipam": {
"type": "static", "type": "static",
"addresses": [ "addresses": [
{ {
"address": {{- cat .Values.multus.n3Ip "/" .Values.multus.n3Netmask | nospace | quote }} "address": {{- cat .Values.multus.n3Interface.Ipadd "/" .Values.multus.n3Interface.Netmask | nospace | quote }}
} }
] ]
{{- if .Values.multus.n3Interface.routes }}
,"routes": {{- .Values.multus.n3Interface.routes | toJson }}
{{- end }}
} }
}' }'
{{- end }} {{- end }}
\ No newline at end of file ---
{{- if .Values.multus.n4Interface.create }}
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: {{ .Chart.Name }}-n4
spec:
config: '{
"cniVersion": "0.3.1",
"type": "macvlan",
"master": {{- cat .Values.multus.n4Interface.hostInterface | nospace | quote }},
"mode": "bridge",
"ipam": {
"type": "static",
"addresses": [
{
"address": {{- cat .Values.multus.n4Interface.Ipadd "/" .Values.multus.n4Interface.Netmask | nospace | quote }}
}
]
{{- if .Values.multus.n4Interface.routes }}
,"routes": {{- .Values.multus.n4Interface.routes | toJson }}
{{- end }}
}
}'
{{- end }}
---
{{- if .Values.multus.n6Interface.create }}
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: {{ .Chart.Name }}-n6
spec:
config: '{
"cniVersion": "0.3.1",
"type": "macvlan",
"master": {{- cat .Values.multus.n6Interface.hostInterface | nospace | quote }},
"mode": "bridge",
"ipam": {
"type": "static",
"addresses": [
{
"address": {{- cat .Values.multus.n6Interface.Ipadd "/" .Values.multus.n6Interface.Netmask | nospace | quote }}
}
]
{{- if .Values.multus.n6Interface.routes }}
,"routes": {{- .Values.multus.n6Interface.routes | toJson }}
{{- end }}
}
}'
{{- end }}
---
kubernetesType: Vanilla #Vanilla for community kubernetes distribution kubernetesType: Vanilla #Vanilla for community kubernetes distribution else Openshift for Openshift
## In case of using these charts on Openshift then please use UBI images
## To know more about them follow this tutorial https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/tree/master/openshift
nfimage: nfimage:
repository: docker.io/oaisoftwarealliance/oai-spgwu-tiny # dockerhub oaisoftwarealliance/oai-spgwu-tiny repository: docker.io/oaisoftwarealliance/oai-spgwu-tiny # dockerhub oaisoftwarealliance/oai-spgwu-tiny
version: v1.5.0 #image tag, develop tag for experimental features version: develop #image tag, develop tag for experimental features
# pullPolicy: IfNotPresent or Never or Always # pullPolicy: IfNotPresent or Never or Always
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
tcpdumpimage:
repository: docker.io/corfr/tcpdump
version: latest
#pullPolicy: IfNotPresent or Never or Always
pullPolicy: IfNotPresent
## good to use when pulling images from docker-hub ## good to use when pulling images from docker-hub
imagePullSecrets: imagePullSecrets:
- name: "regcred" - name: "regcred"
...@@ -27,37 +23,56 @@ podSecurityContext: ...@@ -27,37 +23,56 @@ podSecurityContext:
runAsUser: 0 runAsUser: 0
runAsGroup: 0 runAsGroup: 0
securityContext:
privileged: true
#service type is fixed to clusterIP, it is only support for non multus interface (eth0) #service type is fixed to clusterIP, it is only support for non multus interface (eth0)
service: service:
pfcpPort: 8805 # default port no need to change unless necessary pfcpPort: 8805 # default port no need to change unless necessary
gtpuPort: 2152 # default port no need to change unless necessary gtpuPort: 2152 # default port no need to change unless necessary
# Just for debugging
start:
spgwu: true
tcpdump: false
# create an extra interface for N3 incase the gNB is outside the cluster network or there is a need to have dedicated interface for N3 # create an extra interface for N3 incase the gNB is outside the cluster network or there is a need to have dedicated interface for N3
multus: ## Change these ip-addresses according to your environment
create: false ## N4, N6 are optional only if you want that UPF uses different subnets for different 3gpp interfaces.
n3Ip: "172.21.6.201"
n3Netmask: "22"
n6Gw: "172.21.7.254"
hostInterface: "bond0"
multus:
## If you don't want to add a default route in your pod then leave this field empty
defaultGateway: "172.21.7.254"
n3Interface:
create: false
Ipadd: "172.21.6.95"
Netmask: "22"
## If you do not have a gateway leave the field empty
Gateway: "172.21.7.254"
## If you do not want to add any routes in your pod then leave this field empty
routes: [{'dst': '10.8.0.0/24','gw': '172.21.7.254'}, {'dst': '10.9.0.0/24','gw': '172.21.7.254'}]
hostInterface: "bond0"
n4Interface:
create: false
Ipadd: "172.21.16.89"
Netmask: "22"
## If you do not have a gateway leave the field empty
Gateway: "172.21.19.254"
## If you do not want to add any routes in your pod then leave this field empty
routes:
hostInterface: "bond1"
n6Interface:
create: false
Ipadd: "172.21.8.80"
Netmask: "22"
## If you do not have a gateway leave the field empty
Gateway: "172.21.11.254"
## If you do not want to add any routes in your pod then leave this field empty
routes:
hostInterface: "bond2"
#NOTE: If the interface you selected for n6If is wrong then traffic will not be routed towards internet
config: config:
fqdn: "oai-spgwu-tiny-svc" fqdn: "oai-spgwu-tiny-svc"
n3If: "eth0" # net1 if gNB is outside the cluster network and multus creation is true else eth0 n3If: "eth0" # n3 if multus.n3Interface.create is true
n4If: "eth0" # use for SMF communication n4If: "eth0" # n4 if multus.n4Interface.create is true
n6If: "eth0" # net1 if gNB is outside the cluster network and multus creation is true else eth0 (important because it sends the traffic towards internet) n6If: "eth0" # n6 multus.n6Interface.create is true
threadsN3Ul: "1" threadsN3Ul: "1" #Multi threading is not properly supported
threadsN6Dl: "1" threadsN6Dl: "1" #Multi threading is not properly supported
threadsN6Prio: 99 threadsN6Prio: 99
threadsN3Prio: 98 threadsN3Prio: 98
threadsN4Prio: 88 threadsN4Prio: 88
netUeNatOption: "yes" netUeNatOption: "yes"
bypassUlPfcpRules: "no" #standart feature is no, put yes if you want less UL packet delay bypassUlPfcpRules: "no" #standart feature is no, put yes if you want less UL packet delay
...@@ -76,29 +91,49 @@ config: ...@@ -76,29 +91,49 @@ config:
dnn1: "ims" # should match with SMF information dnn1: "ims" # should match with SMF information
## currently only used by tcpdump container to store the tcpdump, this volume will be shared between all the network functions ## Debugging section
persistent: start:
sharedvolume: false # should be true when if wants to store the tcpdump of all the network functions at same place spgwu: true #If false the network function container will run in sleep mode for manually testing
volumneName: managed-nfs-storage tcpdump: false
size: 1Gi
includeTcpDumpContainer: false #If true it will add a tcpdump container inside network function pod for debugging
## For openshift you can use rhel8/support-tools:8.7-13
tcpdumpimage:
repository: docker.io/corfr/tcpdump
version: latest
#pullPolicy: IfNotPresent or Never or Always
pullPolicy: IfNotPresent
securityContext:
privileged: true
#To store PCAP of NF in a sharedVolume so it can be easily fetched (PVC is created with NRF charts so make sure in NRF it is true)
persistent:
sharedvolume: false
## NF is the network function and tcpdump is the tcpdump container.
## To know more about request and limit it is better to understand that how Kubernetes QoS works.
## https://kubernetes.io/docs/concepts/configuration/manage-resources-containers
## https://kubernetes.io/docs/concepts/workloads/pods/pod-qos
resources: resources:
define: false define: false
limits: limits:
tcpdump:
cpu: 100m
memory: 128Mi
nf: nf:
cpu: 100m cpu: 100m
memory: 128Mi memory: 128Mi
requests: #If tcpdump container is disabled this value will not be used
tcpdump: tcpdump:
cpu: 100m cpu: 100m
memory: 128Mi memory: 128Mi
requests:
nf: nf:
cpu: 100m cpu: 100m
memory: 128Mi memory: 128Mi
#If tcpdump container is disabled this value will not be used
tcpdump:
cpu: 100m
memory: 128Mi
readinessProbe: true readinessProbe: true
......
################################################################################
# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The OpenAirInterface Software Alliance licenses this file to You under
# the OAI Public License, Version 1.1 (the "License"); you may not use this file
# except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.openairinterface.org/?page_id=698
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#-------------------------------------------------------------------------------
# For more information about the OpenAirInterface (OAI) Software Alliance:
# contact@openairinterface.org
################################################################################
apiVersion: v2
name: oai-traffic-server
description: Helm chart for oai-traffic-server
type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
version: v1
appVersion: v1
keywords:
- iperf
sources:
- https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed
- https://openairinterface.org/
maintainers:
- name: OPENAIRINTERFACE
email: contact@openairinterface.org
1. Get the application name by running these commands:
export traffic_server_POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-traffic-server.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "oai-traffic-server.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oai-traffic-server.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oai-traffic-server.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "oai-traffic-server.labels" -}}
helm.sh/chart: {{ include "oai-traffic-server.chart" . }}
{{ include "oai-traffic-server.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "oai-traffic-server.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-traffic-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "oai-traffic-server.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-traffic-server.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
{{- if .Values.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: iperf-pod
data:
script.sh: |
#!/bin/bash
ip route add {{ .Values.config.ueroute }} via {{ .Values.config.upfIpadd }} dev net1
num_servers={{ .Values.config.noOfIperf3Server }}
base_port=5200
# Run iperf multiple times
for i in `seq 1 $num_servers`; do
# Set server port
server_port=$(($base_port+$i));
# Report file includes server port
report_file=iperf3-${server_port}.txt
# Run iperf
iperf3 -s --daemon -p $server_port
done
/bin/bash -c 'trap : TERM INT; sleep infinity & wait'
{{- end }}
{{- if .Values.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
app.kubernetes.io/version: "v1"
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Chart.Name }}
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Chart.Name }}
annotations:
k8s.v1.cni.cncf.io/networks: >-
[{
"name": "{{ .Chart.Name }}-net1",
"default-route": ["{{ .Values.multus.defaultGateway }}"]
}]
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: iperf3
volumeMounts:
- mountPath: /tmp/script.sh
name: scripts
subPath: script.sh
command: ["/tmp/script.sh"]
image: "{{ .Values.trafficServer.repository }}:{{ .Values.trafficServer.version }}"
imagePullPolicy: IfNotPresent
securityContext:
privileged: true
capabilities:
add:
- NET_ADMIN
drop:
- ALL
{{- if .Values.readinessProbe}}
readinessProbe:
exec:
command:
- pgrep
- iperf3
initialDelaySeconds: 5
periodSeconds: 3
{{- end}}
{{- if .Values.livenessProbe}}
livenessProbe:
exec:
command:
- pgrep
- iperf3
initialDelaySeconds: 10
periodSeconds: 5
{{- end}}
volumes:
- name: scripts
configMap:
name: iperf-pod
defaultMode: 0777
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: {{ .Values.serviceAccount.name }}
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
{{- if .Values.nodeSelector}}
nodeSelector:
{{- toYaml .Values.nodeSelector | nindent 12 }}
{{- end }}
{{- if .Values.nodeName}}
nodeName: {{ .Values.nodeName }}
{{- end }}
{{- end }}
--- {{- if .Values.enabled }}
{{- if .Values.multus.create }} {{- if .Values.multus.create }}
apiVersion: "k8s.cni.cncf.io/v1" apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: {{ .Chart.Name }}-n2-net1
spec:
config: '{
"cniVersion": "0.3.0",
"type": "macvlan",
"master": {{- cat .Values.multus.hostInterface | nospace | quote }},
"mode": "bridge",
"ipam": {
"type": "static",
"addresses": [
{
"address": {{- cat .Values.multus.n2IPadd "/" .Values.multus.n2Netmask | nospace | quote }}
}
]
}
}'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition kind: NetworkAttachmentDefinition
metadata: metadata:
name: {{ .Chart.Name }}-gtp-net2 name: {{ .Chart.Name }}-net1
spec: spec:
config: '{ config: '{
"cniVersion": "0.3.0", "cniVersion": "0.3.0",
"type": "macvlan", "type": "macvlan",
"master": {{- cat .Values.multus.hostInterface | nospace | quote }}, "master": {{- cat .Values.multus.hostInterface | nospace | quote }},
...@@ -34,10 +14,10 @@ spec: ...@@ -34,10 +14,10 @@ spec:
"type": "static", "type": "static",
"addresses": [ "addresses": [
{ {
"address": {{- cat .Values.multus.gtpIPadd "/" .Values.multus.gtpNetmask | nospace | quote }} "address": {{- cat .Values.multus.IPadd "/" .Values.multus.Netmask | nospace | quote }}
} }
] ]
} }
}' }'
--- {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
{{- if .Values.enabled }}
---
{{- if eq .Values.kubernetesType "Openshift" }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ .Chart.Name }}-{{ .Release.Namespace }}-role
rules:
- apiGroups:
- security.openshift.io
resourceNames:
- privileged
resources:
- securitycontextconstraints
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ .Chart.Name }}-{{ .Release.Namespace }}-binding
subjects:
- kind: ServiceAccount
name: {{ .Values.serviceAccount.name }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: Role
name: {{ .Chart.Name }}-{{ .Release.Namespace }}-role
apiGroup: rbac.authorization.k8s.io
{{- end }}
{{- end }}
{{- if .Values.enabled }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.serviceAccount.name }}
{{- end }}
kubernetesType: Vanilla # Vanilla (Community Kubernetes) or Openshift (For RedHat Openshift)
podSecurityContext:
runAsUser: 0
runAsGroup: 0
trafficServer:
repository: docker.io/oaisoftwarealliance/trf-gen-cn5g
version: latest
#pullPolicy: IfNotPresent or Never or Always
pullPolicy: IfNotPresent
serviceAccount:
# Specifies whether a service account should be created
create: true
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "oai-traffic-server"
multus:
create: false
IPadd: "172.21.6.99"
Netmask: "22"
defaultGateway: "172.21.7.254"
hostInterface: "bond0" # Interface of the host machine on which this pod will be scheduled
config:
ueroute: 12.1.1.0/24
upfIpadd: 172.21.6.95
noOfIperf3Server: 10
readinessProbe: true
livenessProbe: false
# Control if the charts will be deployed or not
enabled: true
terminationGracePeriodSeconds: 2
nodeSelector: {}
nodeName:
...@@ -27,9 +27,9 @@ type: application ...@@ -27,9 +27,9 @@ type: application
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
version: v1.5.0 version: v1.5.1
appVersion: v1.5.0 appVersion: develop-v1.5.1
keywords: keywords:
- 5GCN - 5GCN
......
# Helm Chart for OAI Unified Data Management (UDM)
The helm-chart is tested on [Minikube](https://minikube.sigs.k8s.io/docs/) and [Red Hat Openshift](https://www.redhat.com/fr/technologies/cloud-computing/openshift) 4.10 and 4.12. There are no special resource requirements for AMF.
## Introduction
OAI-UDM follows 3GPP release 16, more information about the feature set can be found on [UDMs WiKi page](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-udm/-/wikis/home). The source code be downloaded from [GitLab](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-udm)
OAI [Jenkins Platform](https://jenkins-oai.eurecom.fr/job/OAI-CN5G-UDM/) publishes every `develop` and `master` branch image of OAI-UDM on [docker-hub](https://hub.docker.com/r/oaisoftwarealliance/oai-udm) with tag `develop` and `latest` respectively. Apart from that you can find tags for every release `VX.X.X`. We only publish Ubuntu 18.04/20.04/22.04 images. We do not publish RedHat/UBI images. These images you have to build from the source code on your RedHat systems or Openshift Platform. You can follow this [tutorial](../../../openshift/README.md) for that.
The helm chart of OAI-UDM creates multiples Kubernetes resources,
1. Service
2. Role Base Access Control (RBAC) (role and role bindings)
3. Deployment
4. Configmap
5. Service account
The directory structure
```
├── Chart.yaml
├── README.md
├── templates
│ ├── configmap.yaml
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── NOTES.txt
│ ├── rbac.yaml
│ ├── serviceaccount.yaml
│ └── service.yaml
└── values.yaml (Parent file contains all the configurable parameters)
```
## Parameters
[Values.yaml](./values.yaml) contains all the configurable parameters. Below table defines the configurable parameters.
|Parameter |Allowed Values |Remark |
|-----------------------------|-------------------------------|-----------------------------------------|
|kubernetesType |Vanilla/Openshift |Vanilla Kubernetes or Openshift |
|nfimage.repository |Image Name | |
|nfimage.version |Image tag | |
|nfimage.pullPolicy |IfNotPresent or Never or Always| |
|imagePullSecrets.name |String |Good to use for docker hub |
|serviceAccount.create |true/false | |
|serviceAccount.annotations |String | |
|serviceAccount.name |String | |
|podSecurityContext.runAsUser |Integer (0,65534) |Mandatory to use 0 |
|podSecurityContext.runAsGroup|Integer (0,65534) |Mandatory to use 0 |
## Advanced Debugging Parameters
Only needed if you are doing advanced debugging
|Parameter |Allowed Values |Remark |
|---------------------------------|-------------------------------|----------------------------------------------|
|start.udm |true/false |If true udm container will go in sleep mode |
|start.tcpdump |true/false |If true tcpdump container will go in sleepmode|
|includeTcpDumpContainer |true/false |If false no tcpdump container will be there |
|tcpdumpimage.repository |Image Name | |
|tcpdumpimage.version |Image tag | |
|tcpdumpimage.pullPolicy |IfNotPresent or Never or Always| |
|persistent.sharedvolume |true/false |Save the pcaps in a shared volume with NRF |
|resources.define |true/false | |
|resources.limits.tcpdump.cpu |string |Unit m for milicpu or cpu |
|resources.limits.tcpdump.memory |string |Unit Mi/Gi/MB/GB |
|resources.limits.nf.cpu |string |Unit m for milicpu or cpu |
|resources.limits.nf.memory |string |Unit Mi/Gi/MB/GB |
|resources.requests.tcpdump.cpu |string |Unit m for milicpu or cpu |
|resources.requests.tcpdump.memory|string |Unit Mi/Gi/MB/GB |
|resources.requests.nf.cpu |string |Unit m for milicpu or cpu |
|resources.requests.nf.memory |string |Unit Mi/Gi/MB/GB |
|readinessProbe |true/false |default true |
|livenessProbe |true/false |default false |
|terminationGracePeriodSeconds |5 |In seconds (default 5) |
|nodeSelector |Node label | |
|nodeName |Node Name | |
## Installation
Better to use the parent charts from:
1. [oai-5g-basic](../oai-5g-basic/README.md) for basic deployment of OAI-5G Core
2. [oai-5g-slicing](../oai-5g-slicing/README.md) for basic deployment with NSSF extra
## Note
1. If you are using tcpdump container to take pcaps automatically (`start.tcpdump` is true) you can enable `persistent.sharedvolume` and [presistent volume](./oai-nrf/values.yaml) in NRF. To store the pcaps of all the NFs in one location. It is to ease the automated collection of pcaps.
\ No newline at end of file
...@@ -23,33 +23,44 @@ spec: ...@@ -23,33 +23,44 @@ spec:
{{ toYaml .Values.imagePullSecrets | indent 8 }} {{ toYaml .Values.imagePullSecrets | indent 8 }}
{{- end }} {{- end }}
containers: containers:
{{- if .Values.includeTcpDumpContainer }}
- name: tcpdump - name: tcpdump
image: "{{ .Values.tcpdumpimage.repository }}:{{ .Values.tcpdumpimage.version }}" image: "{{ .Values.tcpdumpimage.repository }}:{{ .Values.tcpdumpimage.version }}"
imagePullPolicy: {{ .Values.tcpdumpimage.pullPolicy }} imagePullPolicy: {{ .Values.tcpdumpimage.pullPolicy }}
{{- if .Values.resources.define}} {{- if .Values.resources.define}}
resources: resources:
requests: requests:
memory: {{ .Values.resources.tcpdump.requests.memory | quote }} memory: {{ .Values.resources.requests.tcpdump.memory | quote }}
cpu: {{ .Values.resources.tcpdump.requests.cpu | quote }} cpu: {{ .Values.resources.requests.tcpdump.cpu | quote }}
limits: limits:
memory: {{ .Values.resources.tcpdump.limits.memory | quote }} memory: {{ .Values.resources.limits.tcpdump.memory | quote }}
cpu: {{ .Values.resources.tcpdump.limits.cpu | quote }} cpu: {{ .Values.resources.limits.tcpdump.cpu | quote }}
{{- end}} {{- end}}
securityContext:
privileged: true
capabilities:
add:
- NET_ADMIN
drop:
- ALL
{{- if .Values.start.tcpdump}} {{- if .Values.start.tcpdump}}
command: command:
- /bin/sh - /bin/sh
- -c - -c
- /usr/sbin/tcpdump -i any -w /pcap/oai-udm_`date +%Y-%m-%d_%H_%M-%S-%Z`.pcap - /usr/sbin/tcpdump -i any -w /tmp/pcap/{{ .Chart.Name }}_`date +%Y-%m-%d_%H_%M-%S-%Z`.pcap
{{- else}} {{- else}}
command: command:
- /bin/sleep - /bin/sleep
- infinity - infinity
{{- end}} {{- end}}
{{- if .Values.persistence.sharedvolume}} {{- if .Values.includeTcpDumpContainer}}
{{- if .Values.persistent.sharedvolume}}
volumeMounts: volumeMounts:
- mountPath: "/pcap" - mountPath: "/tmp/pcap"
name: cn5g-pv name: cn5g-pvc
{{- end}}
{{- end}} {{- end}}
{{- end }}
- name: udm - name: udm
image: "{{ .Values.nfimage.repository }}:{{ .Values.nfimage.version }}" image: "{{ .Values.nfimage.repository }}:{{ .Values.nfimage.version }}"
imagePullPolicy: {{ .Values.nfimage.pullPolicy }} imagePullPolicy: {{ .Values.nfimage.pullPolicy }}
...@@ -69,6 +80,11 @@ spec: ...@@ -69,6 +80,11 @@ spec:
configMapKeyRef: configMapKeyRef:
name: {{ .Chart.Name }}-configmap name: {{ .Chart.Name }}-configmap
key: pidDirectory key: pidDirectory
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: {{ .Chart.Name }}-configmap
key: logLevel
- name: UDM_NAME - name: UDM_NAME
valueFrom: valueFrom:
configMapKeyRef: configMapKeyRef:
...@@ -142,11 +158,11 @@ spec: ...@@ -142,11 +158,11 @@ spec:
{{- if .Values.resources.define}} {{- if .Values.resources.define}}
resources: resources:
requests: requests:
memory: {{ .Values.resources.nf.requests.memory | quote }} memory: {{ .Values.resources.requests.nf.memory | quote }}
cpu: {{ .Values.resources.nf.requests.cpu | quote }} cpu: {{ .Values.resources.requests.nf.cpu | quote }}
limits: limits:
memory: {{ .Values.resources.nf.limits.memory | quote }} memory: {{ .Values.resources.limits.nf.memory | quote }}
cpu: {{ .Values.resources.nf.limits.cpu | quote }} cpu: {{ .Values.resources.limits.nf.cpu | quote }}
{{- end}} {{- end}}
{{- if .Values.readinessProbe}} {{- if .Values.readinessProbe}}
readinessProbe: readinessProbe:
...@@ -166,8 +182,6 @@ spec: ...@@ -166,8 +182,6 @@ spec:
initialDelaySeconds: 10 initialDelaySeconds: 10
periodSeconds: 5 periodSeconds: 5
{{- end}} {{- end}}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
ports: ports:
- containerPort: {{ .Values.config.sbiPortHttp1 }} - containerPort: {{ .Values.config.sbiPortHttp1 }}
name: http1 name: http1
...@@ -185,12 +199,14 @@ spec: ...@@ -185,12 +199,14 @@ spec:
- /bin/sleep - /bin/sleep
- infinity - infinity
{{- end}} {{- end}}
{{- if .Values.includeTcpDumpContainer}}
{{- if .Values.persistent.sharedvolume}}
volumes: volumes:
{{- if .Values.persistence.sharedvolume}} - name: cn5g-pvc
- name: cn5g-pv persistentVolumeClaim:
persistenceVolumeClaim:
claimName: cn5g-pvc claimName: cn5g-pvc
{{- end }} {{- end }}
{{- end }}
dnsPolicy: ClusterFirst dnsPolicy: ClusterFirst
restartPolicy: Always restartPolicy: Always
schedulerName: default-scheduler schedulerName: default-scheduler
......
...@@ -7,7 +7,7 @@ metadata: ...@@ -7,7 +7,7 @@ metadata:
rules: rules:
- apiGroups: - apiGroups:
- security.openshift.io - security.openshift.io
{{- if .Values.securityContext.privileged }} {{- if .Values.includeTcpDumpContainer }}
resourceNames: resourceNames:
- privileged - privileged
{{- else }} {{- else }}
...@@ -31,4 +31,4 @@ roleRef: ...@@ -31,4 +31,4 @@ roleRef:
kind: Role kind: Role
name: {{ .Chart.Name }}-{{ .Release.Namespace }}-role name: {{ .Chart.Name }}-{{ .Release.Namespace }}-role
apiGroup: rbac.authorization.k8s.io apiGroup: rbac.authorization.k8s.io
{{- end }} {{- end }}
\ No newline at end of file
kubernetesType: Vanilla #Vanilla for community kubernetes distribution kubernetesType: Vanilla #Vanilla for community kubernetes distribution else Openshift for Openshift
## In case of using these charts on Openshift then please use UBI images
## To know more about them follow this tutorial https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/tree/master/openshift
nfimage: nfimage:
repository: docker.io/oaisoftwarealliance/oai-udm repository: docker.io/oaisoftwarealliance/oai-udm
version: v1.5.0 #image tag, develop tag for experimental features version: develop #image tag, develop tag for experimental features
#pullPolicy: IfNotPresent or Never or Always
pullPolicy: IfNotPresent
tcpdumpimage:
repository: docker.io/corfr/tcpdump
version: latest
#pullPolicy: IfNotPresent or Never or Always #pullPolicy: IfNotPresent or Never or Always
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
...@@ -29,18 +25,12 @@ podSecurityContext: ...@@ -29,18 +25,12 @@ podSecurityContext:
#service type is fixed to clusterIP, it is only support for non multus interface (eth0) #service type is fixed to clusterIP, it is only support for non multus interface (eth0)
securityContext:
privileged: false
start:
udm: true
tcpdump: false
config: config:
tz: "Europe/Paris" tz: "Europe/Paris"
instance: 0 instance: 0
pidDirectory: "/var/run" pidDirectory: "/var/run"
udmName: "oai-udm" udmName: "oai-udm"
logLevel: "debug"
sbiIfName: "eth0" sbiIfName: "eth0"
sbiPortHttp1: "80" sbiPortHttp1: "80"
sbiPortHttp2: "8080" sbiPortHttp2: "8080"
...@@ -57,27 +47,46 @@ config: ...@@ -57,27 +47,46 @@ config:
nrfApiVersionNb: "v1" #Nb means northbound nrfApiVersionNb: "v1" #Nb means northbound
nrfFqdn: "oai-nrf-svc" nrfFqdn: "oai-nrf-svc"
persistence: ## Debugging section
start:
udm: true #If false the network function container will run in sleep mode for manually testing
tcpdump: false
includeTcpDumpContainer: false #If true it will add a tcpdump container inside network function pod for debugging
## For openshift you can use rhel8/support-tools:8.7-13
tcpdumpimage:
repository: docker.io/corfr/tcpdump
version: latest
#pullPolicy: IfNotPresent or Never or Always
pullPolicy: IfNotPresent
#To store PCAP of NF in a sharedVolume so it can be easily fetched (PVC is created with NRF charts so make sure in NRF it is true)
persistent:
sharedvolume: false sharedvolume: false
volumneName: managed-nfs-storage
size: 1Gi
## NF is the network function and tcpdump is the tcpdump container.
## To know more about request and limit it is better to understand that how Kubernetes QoS works.
## https://kubernetes.io/docs/concepts/configuration/manage-resources-containers
## https://kubernetes.io/docs/concepts/workloads/pods/pod-qos
resources: resources:
define: false define: false
limits: limits:
tcpdump:
cpu: 100m
memory: 128Mi
nf: nf:
cpu: 100m cpu: 100m
memory: 128Mi memory: 128Mi
requests: #If tcpdump container is disabled this value will not be used
tcpdump: tcpdump:
cpu: 100m cpu: 100m
memory: 128Mi memory: 128Mi
requests:
nf: nf:
cpu: 100m cpu: 100m
memory: 128Mi memory: 128Mi
#If tcpdump container is disabled this value will not be used
tcpdump:
cpu: 100m
memory: 128Mi
readinessProbe: true readinessProbe: true
...@@ -87,4 +96,4 @@ terminationGracePeriodSeconds: 5 ...@@ -87,4 +96,4 @@ terminationGracePeriodSeconds: 5
nodeSelector: {} nodeSelector: {}
nodeName: nodeName:
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment