Combine ironic-inspector deployments into one pod

For the ironic-inspector service to operate correctly it must run on the
same host as its TFTP and DNSmasq service. This is because the
ironic-inspector service needs to manage iptables for DNSmasq to prevent
node that are not in inspection from receiving DHCP responses from
DNSmasq. To achieve this, we should combine the containers providing
those services into the same deployment as the ironic-inspector service
to ensure they are always deployed together.

Change-Id: Ib3af723a2c8b2cffb6eacec6293c5ea7860ba72f
This commit is contained in:
Sam Betts 2017-05-23 15:25:07 +01:00
parent 7fce504dc9
commit 9dc4087c81
11 changed files with 218 additions and 222 deletions

View File

@ -14,5 +14,12 @@
"perm": "0600",
"optional": true
}
],
"permissions": [
{
"path": "/var/log/kolla/ironic",
"owner": "ironic:ironic",
"recurse": true
}
]
}

View File

@ -1104,7 +1104,6 @@ ironic-inspector-svc:
port_external: true
node_port_enabled: false
ironic_provision: true
ironic_inspector_provision_vip: 172.22.0.10
ironic-api-create-db-job:
global:
@ -1162,19 +1161,10 @@ ironic-inspector-deployment:
all:
port: 5050
ironic_interface: net2
ironic-dnsmasq-daemonset:
global:
kolla:
ironic:
all:
ironic_inspection_cidr: 172.22.0.0/24
dnsmasq:
all:
initramfs_url:
kernel_url:
ironic_interface: net2
ironic_dhcp_range:
ironic_inspection_cidr: 172.22.0.0/24
ironic-create-keystone-user-job:
global:

View File

@ -1,12 +0,0 @@
name: ironic-dnsmasq-daemonset
version: 0.7.0-1
description: ironic dnsmask daemonset microservice package
keywords:
- openstack
- ironic
- inspector
- dnsmask
sources:
- http://github.com/openstack
engine: gotpl
#icon: A URL to an SVG or PNG image to be used as an icon (optional). make this point to the new project icons when ready

View File

@ -1,4 +0,0 @@
dependencies:
- name: kolla-common
repository: file://../../kolla-common
version: 0.7.0-1

View File

@ -1,165 +0,0 @@
{{- $searchPath := ":global.kolla.ironic.dnsmasq.daemonset:global.kolla.ironic.dnsmasq.all:global.kolla.ironic.all:global.kolla.all" }}
{{- $resourceName := "ironic-dnsmasq" }}
{{- $netHostTrue := true }}
{{- $podTypeBootstrap := false }}
{{- $serviceName := "ironic" }}
{{- $serviceType := "dnsmasq" }}
{{- $privileged := true }}
{{- $c := dict "searchPath" $searchPath "Values" .Values }}
{{- $_ := set $c "contName" "dnsmasq" }}
{{- $_ := set $c "imageName" "image_full" }}
{{- $_ := set $c "tagName" "image_tag" }}
{{- $imageFull := include "kolla_build_image_full" $c }}
{{- $c := dict "searchPath" $searchPath "Values" .Values }}
{{- $_ := set $c "contName" "ironic-pxe" }}
{{- $_ := set $c "imageName" "image_full" }}
{{- $_ := set $c "tagName" "image_tag" }}
{{- $imageFullPXE := include "kolla_build_image_full" $c }}
{{- $imagePullPolicy := include "kolla_val_get_str" (dict "key" "image_pull_policy" "searchPath" $searchPath "Values" .Values ) }}
{{- $containerConfigDirectory := include "kolla_val_get_str" (dict "key" "container_config_directory" "searchPath" $searchPath "Values" .Values ) }}
{{- $selectorKey := include "kolla_val_get_str" (dict "key" "selector_key" "searchPath" $searchPath "Values" .Values ) }}
{{- $selectorValue := include "kolla_val_get_str" (dict "key" "selector_value" "searchPath" $searchPath "Values" .Values ) }}
{{- $ironicInterface := include "kolla_val_get_str" (dict "key" "ironic_interface" "searchPath" $searchPath "Values" .Values ) }}
{{- $elementName := .Values.element_name | default $resourceName }}
{{- $url1 := include "kolla_val_get_str" (dict "key" "initramfs_url" "searchPath" $searchPath "Values" .Values )}}
{{- $url2 := include "kolla_val_get_str" (dict "key" "kernel_url" "searchPath" $searchPath "Values" .Values )}}
{{- $ironicInterface := include "kolla_val_get_str" (dict "key" "ironic_interface" "searchPath" $searchPath "Values" .Values )}}
{{- $ironicInspectionCIDR := include "kolla_val_get_str" (dict "key" "ironic_inspection_cidr" "searchPath" $searchPath "Values" .Values )}}
{{- $ironicDHCPrange := include "kolla_val_get_str" (dict "key" "ironic_dhcp_range" "searchPath" $searchPath "Values" .Values )}}
{{- with $env := dict "netHostTrue" $netHostTrue "podTypeBootstrap" $podTypeBootstrap "imageFull" $imageFull "resourceName" $resourceName "serviceName" $serviceName "serviceType" $serviceType "privileged" $privileged "Values" .Values "Release" .Release "searchPath" $searchPath }}
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: {{ $elementName }}
labels:
component: {{ $serviceName }}
system: {{ $elementName }}
spec:
template:
metadata:
labels:
component: {{ $serviceName }}
system: {{ $elementName }}
annotations:
pod.beta.kubernetes.io/init-containers: '[
{{- include "common_dependency_container_multi" $env | indent 10 }}
{
"name": "initialize-ironic-dnsmasq",
"image": {{ include "kolla_toolbox_image_full" . | quote }},
"imagePullPolicy": {{ $imagePullPolicy | quote }},
"command": [
"sh",
"-xec",
"IP=$(ip addr show dev {{ $ironicInterface }} to {{ $ironicInspectionCIDR }} | grep -m1 -G ''inet'' | awk ''{print $2}'' | cut -d ''/'' -f 1);
if test -z $IP; then exit 1; fi;
cp -a /config/dnsmasq/..data/* /dnsmasq/;
cp -a /config/pxe/..data/* /pxe/;
curl -L {{ $url1 }} -o /tftpboot/ironic-agent.initramfs;
curl -L {{ $url2 }} -o /tftpboot/ironic-agent.kernel;
jq ''.command = \"in.tftpd -v -L -u root -a ''$IP'':69 --map-file /map-file /tftpboot\"'' /config/pxe/..data/config.json > /pxe/config.json;
sed -i ''s|ironic-inspector|''$IP''|g'' /pxe/default;
sed -i ''s|interface=.*|interface={{ $ironicInterface }}|g'' /dnsmasq/dnsmasq.conf;
sed -i ''s|dhcp-option=option:tftp-server,.*|dhcp-option=option:tftp-server,''$IP''|g'' /dnsmasq/dnsmasq.conf;
sed -i ''s|dhcp-option=option:server-ip-address,.*|dhcp-option=option:server-ip-address,''$IP''|g'' /dnsmasq/dnsmasq.conf;
sed -i ''s|dhcp-range=.*|dhcp-range={{ $ironicDHCPrange }}|g'' /dnsmasq/dnsmasq.conf;
"],
"volumeMounts": [
{
"name": "kolla-logs",
"mountPath": "/var/log/kolla/"
},
{
"name": "dnsmasq-config",
"mountPath": "/config/dnsmasq"
},
{
"name": "ironic-pxe-config",
"mountPath": "/pxe/"
},
{
"name": "pxe-config",
"mountPath": "/config/pxe"
},
{
"name": "ironic-dnsmasq-config",
"mountPath": "/dnsmasq/"
},
{
"name": "tftpboot",
"mountPath": "/tftpboot/"
}
]
},
{
"name": "pxelinux",
"image": {{ $imageFullPXE | quote }},
"imagePullPolicy": {{ $imagePullPolicy | quote }},
"command": [
"sh",
"-xec",
"if [ -f /var/lib/tftpboot/pxelinux.0 ]; then
cp /var/lib/tftpboot/pxelinux.0 /tftpboot;
fi;
if [ -f /usr/share/syslinux/chain.c32 ]; then
cp /usr/share/syslinux/chain.c32 /tftpboot;
fi;
if [ -f /usr/lib/PXELINUX/pxelinux.0 ]; then
cp /usr/lib/PXELINUX/pxelinux.0 /tftpboot;
fi;
if [ -f /usr/lib/syslinux/modules/bios/chain.c32 ]; then
cp /usr/lib/syslinux/modules/bios/chain.c32 /tftpboot;
fi;
"],
"volumeMounts": [
{
"name": "tftpboot",
"mountPath": "/tftpboot/"
}
]
}
]'
spec:
hostNetwork: True
nodeSelector:
{{ $selectorKey }}: {{ $selectorValue | quote }}
containers:
- name: pxe
imagePullPolicy: {{ $imagePullPolicy | quote }}
image: "{{ $imageFullPXE }}"
volumeMounts:
{{- include "common_volume_mounts" $env | indent 12 }}
- mountPath: {{ $containerConfigDirectory }}
name: ironic-pxe-config
- mountPath: /tftpboot
name: tftpboot
env:
{{- include "common_env_vars" $env | indent 12 }}
- name: main
securityContext:
privileged: true
imagePullPolicy: {{ $imagePullPolicy | quote }}
image: "{{ $imageFull }}"
volumeMounts:
{{- include "common_volume_mounts" $env | indent 12 }}
- mountPath: {{ $containerConfigDirectory }}
name: ironic-dnsmasq-config
- mountPath: /tftpboot
name: tftpboot
env:
{{- include "common_env_vars" $env | indent 12 }}
{{- include "common_containers" $env | indent 8 }}
volumes:
{{- include "common_volumes" $env | indent 8 }}
- name: dnsmasq-config
configMap:
name: {{ $elementName }}
- name: ironic-dnsmasq-config
emptyDir: {}
- name: tftpboot
emptyDir: {}
- name: pxe-config
configMap:
name: ironic-pxe
- name: ironic-pxe-config
emptyDir: {}
{{- end }}

View File

@ -1,10 +1,11 @@
name: ironic-inspector-deployment
version: 0.7.0-1
description: ironic inspector deployment microservice package
description: ironic inspector dnsmasq deployment microservice package
keywords:
- openstack
- ironic
- inspector
- dnsmasq
sources:
- http://github.com/openstack
engine: gotpl

View File

@ -1,21 +1,212 @@
{{- $searchPath := ":global.kolla.ironic.inspector.deployment:global.kolla.ironic.inspector.all:global.kolla.ironic.all:global.kolla.all" }}
{{- $c := dict "searchPath" $searchPath "Values" .Values }}
{{- $_ := set $c "contName" "ironic-inspector" }}
{{- $_ := set $c "imageName" "image_full" }}
{{- $_ := set $c "tagName" "image_tag" }}
{{- $imageFull := include "kolla_build_image_full" $c }}
{{- $imagePullPolicy := include "kolla_val_get_str" (dict "key" "image_pull_policy" "searchPath" $searchPath "Values" .Values ) }}
{{- $containerConfigDirectory := include "kolla_val_get_str" (dict "key" "container_config_directory" "searchPath" $searchPath "Values" .Values ) }}
{{- $selectorKey := include "kolla_val_get_str" (dict "key" "selector_key" "searchPath" $searchPath "Values" .Values ) }}
{{- $selectorValue := include "kolla_val_get_str" (dict "key" "selector_value" "searchPath" $searchPath "Values" .Values ) }}
{{- $replicas := include "kolla_val_get_str" (dict "key" "replicas" "searchPath" .searchPath "Values" .Values ) }}
{{- $port := include "kolla_val_get_str" (dict "key" "port" "searchPath" .searchPath "Values" .Values ) }}
{{- $portName := "inspector" }}
{{- $resourceName := "ironic-inspector" }}
{{- $netHostTrue := true }}
{{- $podTypeBootstrap := false }}
{{- $serviceName := "ironic" }}
{{- $serviceType := "inspector" }}
{{- $portName := "inspector" }}
{{- $privileged := true }}
{{- $configFileName := "inspector.conf" }}
{{- $configSectionName := "DEFAULT" }}
{{- $configListenHostParameter := "listen_address" }}
{{- $configListenPortParameter := "listen_port" }}
{{- $checkPath := "/" }}
{{- with $env := dict "netHostTrue" $netHostTrue "podTypeBootstrap" $podTypeBootstrap "resourceName" $resourceName "serviceName" $serviceName "serviceType" $serviceType "configFileName" $configFileName "configSectionName" $configSectionName "configListenHostParameter" $configListenHostParameter "configListenPortParameter" $configListenPortParameter "portName" $portName "imageFull" $imageFull "checkPath" $checkPath "privileged" $privileged "Values" .Values "Release" .Release "searchPath" $searchPath }}
{{- include "common_api_python_deployment" $env }}
{{- $c := dict "searchPath" $searchPath "Values" .Values }}
{{- $_ := set $c "contName" "dnsmasq" }}
{{- $_ := set $c "imageName" "image_full" }}
{{- $_ := set $c "tagName" "image_tag" }}
{{- $imageFullDnsmasq := include "kolla_build_image_full" $c }}
{{- $c := dict "searchPath" $searchPath "Values" .Values }}
{{- $_ := set $c "contName" "ironic-pxe" }}
{{- $_ := set $c "imageName" "image_full" }}
{{- $_ := set $c "tagName" "image_tag" }}
{{- $imageFullPXE := include "kolla_build_image_full" $c }}
{{- $c := dict "searchPath" $searchPath "Values" .Values }}
{{- $_ := set $c "contName" "ironic-inspector" }}
{{- $_ := set $c "imageName" "image_full" }}
{{- $_ := set $c "tagName" "image_tag" }}
{{- $imageFull := include "kolla_build_image_full" $c }}
{{- $ironicInterface := include "kolla_val_get_str" (dict "key" "ironic_interface" "searchPath" $searchPath "Values" .Values ) }}
{{- $elementName := .Values.element_name | default $resourceName }}
{{- $url1 := include "kolla_val_get_str" (dict "key" "initramfs_url" "searchPath" $searchPath "Values" .Values )}}
{{- $url2 := include "kolla_val_get_str" (dict "key" "kernel_url" "searchPath" $searchPath "Values" .Values )}}
{{- $ironicInterface := include "kolla_val_get_str" (dict "key" "ironic_interface" "searchPath" $searchPath "Values" .Values )}}
{{- $ironicInspectionCIDR := include "kolla_val_get_str" (dict "key" "ironic_inspection_cidr" "searchPath" $searchPath "Values" .Values )}}
{{- $ironicDHCPrange := include "kolla_val_get_str" (dict "key" "ironic_dhcp_range" "searchPath" $searchPath "Values" .Values )}}
{{- with $env := dict "netHostTrue" $netHostTrue "podTypeBootstrap" $podTypeBootstrap "imageFull" $imageFull "resourceName" $resourceName "serviceName" $serviceName "serviceType" $serviceType "privileged" $privileged "Values" .Values "Release" .Release "searchPath" $searchPath }}
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: {{ $resourceName }}
labels:
component: {{ $serviceName }}
system: {{ $elementName }}
spec:
replicas: {{ $replicas }}
template:
metadata:
labels:
service: {{ $serviceName }}
type: {{ $serviceType }}
annotations:
pod.beta.kubernetes.io/init-containers: '[
{{- include "common_dependency_container_multi" $env | indent 10 }}
{
"name": "initialize-ironic-dnsmasq",
"image": {{ include "kolla_toolbox_image_full" . | quote }},
"imagePullPolicy": {{ $imagePullPolicy | quote }},
"command": [
"sh",
"-xec",
"IP=$(ip addr show dev {{ $ironicInterface }} to {{ $ironicInspectionCIDR }} | grep -m1 -G ''inet'' | awk ''{print $2}'' | cut -d ''/'' -f 1);
if test -z $IP; then exit 1; fi;
cp -a /config/dnsmasq/..data/* /dnsmasq/;
cp -a /config/pxe/..data/* /pxe/;
curl -L {{ $url1 }} -o /tftpboot/ironic-agent.initramfs;
curl -L {{ $url2 }} -o /tftpboot/ironic-agent.kernel;
jq ''.command = \"in.tftpd -v -L -u root -a ''$IP'':69 --map-file /map-file /tftpboot\"'' /config/pxe/..data/config.json > /pxe/config.json;
sed -i ''s|ironic-inspector|''$IP''|g'' /pxe/default;
sed -i ''s|interface=.*|interface={{ $ironicInterface }}|g'' /dnsmasq/dnsmasq.conf;
sed -i ''s|dhcp-option=option:tftp-server,.*|dhcp-option=option:tftp-server,''$IP''|g'' /dnsmasq/dnsmasq.conf;
sed -i ''s|dhcp-option=option:server-ip-address,.*|dhcp-option=option:server-ip-address,''$IP''|g'' /dnsmasq/dnsmasq.conf;
sed -i ''s|dhcp-range=.*|dhcp-range={{ $ironicDHCPrange }}|g'' /dnsmasq/dnsmasq.conf;
"],
"volumeMounts": [
{
"name": "kolla-logs",
"mountPath": "/var/log/kolla/"
},
{
"name": "dnsmasq-config",
"mountPath": "/config/dnsmasq"
},
{
"name": "ironic-pxe-config",
"mountPath": "/pxe/"
},
{
"name": "pxe-config",
"mountPath": "/config/pxe"
},
{
"name": "ironic-dnsmasq-config",
"mountPath": "/dnsmasq/"
},
{
"name": "tftpboot",
"mountPath": "/tftpboot/"
}
]
},
{
"name": "pxelinux",
"image": {{ $imageFullPXE | quote }},
"imagePullPolicy": {{ $imagePullPolicy | quote }},
"command": [
"sh",
"-xec",
"if [ -f /var/lib/tftpboot/pxelinux.0 ]; then
cp /var/lib/tftpboot/pxelinux.0 /tftpboot;
fi;
if [ -f /usr/share/syslinux/chain.c32 ]; then
cp /usr/share/syslinux/chain.c32 /tftpboot;
fi;
if [ -f /usr/lib/PXELINUX/pxelinux.0 ]; then
cp /usr/lib/PXELINUX/pxelinux.0 /tftpboot;
fi;
if [ -f /usr/lib/syslinux/modules/bios/chain.c32 ]; then
cp /usr/lib/syslinux/modules/bios/chain.c32 /tftpboot;
fi;
"],
"volumeMounts": [
{
"name": "tftpboot",
"mountPath": "/tftpboot/"
}
]
},
{
"name": "update-inspector-config",
"image": {{ include "kolla_toolbox_image_full" . | quote }},
"imagePullPolicy": {{ $imagePullPolicy | quote }},
"command": [
"/bin/sh",
"-c",
"cp -a /srv/configmap/..data/* /srv/pod-main-config/;
CONF=/srv/pod-main-config/{{ .configFileName }};
sed -i ''s|dnsmasq_interface=.*|dnsmasq_interface={{ $ironicInterface }}|g'' /srv/pod-main-config/inspector.conf;
"],
"volumeMounts": [
{
"name": "inspector-config",
"mountPath": "/srv/configmap"
},
{
"name": "ironic-inspector-config",
"mountPath": "/srv/pod-main-config"
}
]
}
]'
spec:
hostNetwork: True
nodeSelector:
{{ $selectorKey }}: {{ $selectorValue | quote }}
containers:
- name: pxe
imagePullPolicy: {{ $imagePullPolicy | quote }}
image: "{{ $imageFullPXE }}"
volumeMounts:
{{- include "common_volume_mounts" $env | indent 12 }}
- mountPath: {{ $containerConfigDirectory }}
name: ironic-pxe-config
- mountPath: /tftpboot
name: tftpboot
env:
{{- include "common_env_vars" $env | indent 12 }}
- name: dnsmasq
securityContext:
privileged: true
imagePullPolicy: {{ $imagePullPolicy | quote }}
image: "{{ $imageFullDnsmasq }}"
volumeMounts:
{{- include "common_volume_mounts" $env | indent 12 }}
- mountPath: {{ $containerConfigDirectory }}
name: ironic-dnsmasq-config
- mountPath: /tftpboot
name: tftpboot
env:
{{- include "common_env_vars" $env | indent 12 }}
- name: main
securityContext:
privileged: true
imagePullPolicy: {{ $imagePullPolicy | quote }}
image: "{{ $imageFull }}"
volumeMounts:
{{- include "common_volume_mounts" $env | indent 12 }}
- mountPath: {{ $containerConfigDirectory }}
name: ironic-inspector-config
env:
{{- include "common_env_vars" $env | indent 12 }}
{{- include "common_containers" $env | indent 8 }}
volumes:
{{- include "common_volumes" $env | indent 8 }}
- name: dnsmasq-config
configMap:
name: ironic-dnsmasq
- name: ironic-dnsmasq-config
emptyDir: {}
- name: tftpboot
emptyDir: {}
- name: pxe-config
configMap:
name: ironic-pxe
- name: ironic-pxe-config
emptyDir: {}
- name: ironic-inspector-config
emptyDir: {}
- name: inspector-config
configMap:
name: ironic-inspector
{{- end }}

View File

@ -16,13 +16,8 @@
{{- $_ := set $c2 "retDict" $localVals }}
{{- $_ := set $c2 "retKey" "port_external" }}
{{- $_ := include "kolla_val_get_raw" $c2 }}
{{- $c3 := dict "key" $localVals.ironicProvision "searchPath" $searchPath "Values" .Values }}
{{- $_ := set $c3 "retDict" $localVals }}
{{- $_ := set $c3 "retKey" "ironic_provision" }}
{{- $_ := include "kolla_val_get_raw" $c3 }}
{{- $nodePort := include "kolla_val_get_str" (dict "key" $localVals.nodePort "searchPath" $searchPath "Values" .Values) }}
{{- $externalVip := include "kolla_val_get_str" (dict "key" "external_vip" "searchPath" $searchPath "Values" .Values) }}
{{- $ironicVip := include "kolla_val_get_str" (dict "key" "ironic_inspector_provision_vip" "searchPath" $searchPath "Values" .Values) }}
apiVersion: v1
kind: Service
spec:
@ -35,9 +30,6 @@ spec:
{{- else if $localVals.port_external }}
externalIPs:
- {{ $externalVip }}
{{- if $localVals.ironic_provision }}
- {{ $ironicVip }}
{{- end }}
{{- end }}
selector:
service: {{ $elementService | quote }}

View File

@ -27,11 +27,11 @@ function common_iscsi_config {
echo " kernel_url: http://tarballs.openstack.org/ironic-python-agent/tinyipa/files/tinyipa-stable-newton.vmlinuz"
echo " ironic_api_ip: 172.21.0.10"
echo " ironic_provision_cidr: 172.21.0.0/24"
echo " dnsmasq:"
echo " inspector:"
echo " all:"
echo " initramfs_url: http://tarballs.openstack.org/ironic-python-agent/tinyipa/files/tinyipa-stable-newton.gz"
echo " kernel_url: http://tarballs.openstack.org/ironic-python-agent/tinyipa/files/tinyipa-stable-newton.vmlinuz"
echo " ironic_dhcp_range: net2,172.22.0.10,172.22.0.20,255.255.255.0,24h"
echo " ironic_dhcp_range: net2,172.22.0.10,172.22.0.20,255.255.255.0"
echo " horizon:"
echo " all:"
echo " image_tag: 4.0.0"

View File

@ -35,11 +35,11 @@ function common_workflow_config {
echo " kernel_url: http://tarballs.openstack.org/ironic-python-agent/tinyipa/files/tinyipa-stable-newton.vmlinuz"
echo " ironic_api_ip: 172.21.0.10"
echo " ironic_provision_cidr: 172.21.0.0/24"
echo " dnsmasq:"
echo " inspector:"
echo " all:"
echo " initramfs_url: http://tarballs.openstack.org/ironic-python-agent/tinyipa/files/tinyipa-stable-newton.gz"
echo " kernel_url: http://tarballs.openstack.org/ironic-python-agent/tinyipa/files/tinyipa-stable-newton.vmlinuz"
echo " ironic_dhcp_range: net2,172.22.0.10,172.22.0.20,255.255.255.0,24h"
echo " ironic_dhcp_range: net2,172.22.0.10,172.22.0.20,255.255.255.0"
echo " helm-repo:"
echo " all:"
echo " image_tag: 3.0.3-beta.1"

View File

@ -138,10 +138,6 @@ helm install kolla/ironic-inspector-deployment --version $VERSION \
--namespace kolla --name ironic-inspector-deployment \
--values /tmp/general_config.yaml --values /tmp/iscsi_config.yaml
helm install kolla/ironic-dnsmasq-daemonset --version $VERSION \
--namespace kolla --name ironic-dnsmasq-daemonset \
--values /tmp/general_config.yaml --values /tmp/iscsi_config.yaml
$DIR/tools/wait_for_pods.sh kolla
helm install kolla/nova-api-cell-discover-host-job --debug --version $VERSION \