Merge pull request #958 from tompizmor/add_new_tf_resnet_chart

Add new TensorFlow ResNet helm chart
This commit is contained in:
Tomas Pizarro
2018-12-21 10:51:27 +01:00
committed by GitHub
9 changed files with 534 additions and 0 deletions
+1
View File
@@ -60,6 +60,7 @@ $ helm search bitnami
- [nginx-ingress-controller](https://github.com/bitnami/charts/tree/master/bitnami/nginx-ingress-controller)
- [NodeJS](https://github.com/bitnami/charts/tree/master/bitnami/node)
- [TensorFlow Inception](https://github.com/bitnami/charts/tree/master/bitnami/tensorflow-inception)
- [TensorFlow ResNet](https://github.com/bitnami/charts/tree/master/bitnami/tensorflow-resnet)
- [Tomcat](https://github.com/bitnami/charts/tree/master/bitnami/tomcat)
- [WildFly](https://github.com/bitnami/charts/tree/master/bitnami/wildfly)
- [ZooKeeper](https://github.com/bitnami/charts/tree/master/bitnami/zookeeper)
+21
View File
@@ -0,0 +1,21 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
+19
View File
@@ -0,0 +1,19 @@
name: tensorflow-resnet
version: 0.0.1
appVersion: 1.12.0
description: Open-source software library serving the ResNet machine learning model.
keywords:
- tensorflow
- serving
- resnet
- machine
- learning
- library
home: https://tensorflow.github.io/serving/
sources:
- https://github.com/bitnami/bitnami-docker-tensorflow-serving
- https://github.com/bitnami/bitnami-docker-tensorflow-resnet
maintainers:
- email: containers@bitnami.com
name: Bitnami
engine: gotpl
+126
View File
@@ -0,0 +1,126 @@
# TensorFlow Serving ResNet
TensorFlow Serving is an open-source software library for serving machine learning models. This chart will specifically serve the ResNet model with already trained data.
## TL;DR;
```console
$ helm install bitnami/tensorflow-resnet
```
## Introduction
This chart bootstraps a TensorFlow Serving ResNet deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
Bitnami charts can be used with [Kubeapps](https://kubeapps.com/) for deployment and management of Helm Charts in clusters.
## Prerequisites
- Kubernetes 1.4+ with Beta APIs enabled
- PV provisioner support in the underlying infrastructure
## Get this chart
Download the latest release of the chart from the [releases](../../../releases) page.
Alternatively, clone the repo if you wish to use the development snapshot:
```console
$ git clone https://github.com/bitnami/charts.git
```
## Installing the Chart
To install the chart with the release name `my-release`:
```console
$ helm install --name my-release bitnami/tensorflow-resnet
```
The command deploys Tensorflow Serving ResNet model on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
> **Tip**: List all releases using `helm list`
## Uninstalling the Chart
To uninstall/delete the `my-release` deployment:
```console
$ helm delete my-release
```
You can check your releases with:
```console
$ helm list
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
## Configuration
The following tables lists the configurable parameters of the TensorFlow ResNet chart and their default values.
| Parameter | Description | Default |
| ------------------------------------------ | -----------------------------------------------------| -------------------------------------------------------------|
| `global.imageRegistry` | Global Docker image registry | `nil` |
| `server.image.registry` | TensorFlow Serving image registry | `docker.io` |
| `server.image.repository` | TensorFlow Serving Image name | `bitnami/tensorflow-serving` |
| `server.image.tag` | TensorFlow Serving Image tag | `{VERSION}` |
| `server.image.pullPolicy` | TensorFlow Serving image pull policy | `Always` if `imageTag` is `latest`, else `IfNotPresent` |
| `server.image.pullSecrets` | Specify image pull secrets | `nil` (does not add image pull secrets to deployed pods) |
| `replicaCount` | Desired number of pods | `1` |
| `server.port` | Tensorflow server port | `8500` |
| `client.image.registry` | TensorFlow ResNet image registry | `docker.io` |
| `client.image.repository` | TensorFlow ResNet Image name | `bitnami/tensorflow-resnet` |
| `client.image.tag` | TensorFlow ResNet Image tag | `{VERSION}` |
| `client.image.pullPolicy` | TensorFlow ResNet image pull policy | `Always` if `imageTag` is `latest`, else `IfNotPresent` |
| `client.image.pullSecrets` | Specify image pull secrets | `nil` (does not add image pull secrets to deployed pods) |
| `imagePullPolicy` | Image pull policy | `Always` if `image` tag is `latest`, else `IfNotPresent` |
| `podAnnotations` | Pod annotations | `{}` |
| `livenessProbe.enabled` | Would you like a livessProbed to be enabled | `true` |
| `livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 30 |
| `livenessProbe.periodSeconds` | How often to perform the probe | 5 |
| `livenessProbe.timeoutSeconds` | When the probe times out | 5 |
| `livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded | 6 |
| `livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 |
| `readinessProbe.enabled` | Would you like a readinessProbe to be enabled | `true` |
| `readinessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 15 |
| `readinessProbe.periodSeconds` | How often to perform the probe | 5 |
| `readinessProbe.timeoutSeconds` | When the probe times out | 5 |
| `readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded | 6 |
| `readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 |
| `metrics.enabled` | Start a side-car Tensorflow prometheus exporter | `false` |
| `metrics.image.registry` | Tensorflow exporter image registry | `docker.io` |
| `metrics.image.repository` | Tensorflow exporter image name | `ynqa/tensorflow-serving-exporter` |
| `metrics.image.tag` | Tensorflow exporter image tag | `latest` |
| `metrics.image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `metrics.image.pullSecrets` | Specify docker-registry secret names as an array | `nil` |
| `metrics.port` | TensorFlow Exporter port | `9118` |
| `metrics.livenessProbe.enabled` | Would you like a livessProbed to be enabled (metrics) | `true` |
| `metrics.livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated (metrics) | 30 |
| `metrics.livenessProbe.periodSeconds` | How often to perform the probe (metrics) | 5 |
| `metrics.livenessProbe.timeoutSeconds` | When the probe times out (metrics) | 5 |
| `metrics.livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded (metrics) | 6 |
| `metrics.livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (metrics) | 1 |
| `metrics.readinessProbe.enabled` | Would you like a readinessProbe to be enabled (metrics) | `true` |
| `metrics.readinessProbe.initialDelaySeconds` | Delay before liveness probe is initiated (metrics) | 15 |
| `metrics.readinessProbe.periodSeconds` | How often to perform the probe (metrics) | 5 |
| `metrics.readinessProbe.timeoutSeconds` | When the probe times out (metrics) | 5 |
| `metrics.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded (metrics) | 6 |
| `metrics.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed (metrics) | 1 |
| `metrics.podAnnotations` | Additional annotations for Metrics exporter pod | `{prometheus.io/scrape: "true", prometheus.io/port: "9118"}` |
| `metrics.resources` | Exporter resource requests/limit | Memory: `256Mi`, CPU: `100m` |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
```console
$ helm install --name my-release bitnami/tensorflow-resnet --set imagePullPolicy=Always
```
Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example,
```console
$ helm install --name my-release -f values.yaml bitnami/tensorflow-resnet
```
> **Tip**: You can use the default [values.yaml](values.yaml)
+30
View File
@@ -0,0 +1,30 @@
*******************************************************************
*** Please be patient while the chart is being deployed. ***
*******************************************************************
1. Get the TensorFlow Serving URL by running:
{{- if contains "NodePort" .Values.serviceType }}
export APP_HOST=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
export APP_PORT=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath="{.spec.ports[0].nodePort}")
{{- else if contains "LoadBalancer" .Values.serviceType }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "fullname" . }}'
export APP_HOST=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
export APP_PORT=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath="{.spec.ports[0].port}")
{{- else if contains "ClusterIP" .Values.serviceType }}
export APP_HOST=127.0.0.1
export APP_PORT=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath="{.spec.ports[0].port}")
kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "tensorflow-resnet.fullname" . }} $APP_PORT:$APP_PORT &
{{- end }}
2. Test the server with a sample image.
docker run --rm -it bitnami/tensorflow-resnet bash -c "curl -Lo /tmp/cat.jpg https://tensorflow.org/images/blogs/serving/cat.jpg && resnet_client_cc --server_port=$APP_HOST:$APP_PORT --image_file=/tmp/cat.jpg"
@@ -0,0 +1,72 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "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).
*/}}
{{- define "fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Return the proper tensorflow-resnet server image name
*/}}
{{- define "tensorflow-resnet.server.image" -}}
{{- $registryName := .Values.server.image.registry -}}
{{- $repositoryName := .Values.server.image.repository -}}
{{- $tag := .Values.server.image.tag | toString -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic.
Also, we can't use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
{{- if .Values.global.imageRegistry }}
{{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}}
{{- else -}}
{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- else -}}
{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- end -}}
{{/*
Return the proper tensorflow-resnet client image name
*/}}
{{- define "tensorflow-resnet.client.image" -}}
{{- $registryName := .Values.client.image.registry -}}
{{- $repositoryName := .Values.client.image.repository -}}
{{- $tag := .Values.client.image.tag | toString -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic.
Also, we can't use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
{{- if .Values.global.imageRegistry }}
{{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}}
{{- else -}}
{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- else -}}
{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- end -}}
{{/*
Return the proper image name (for the metrics image)
*/}}
{{- define "metrics.image" -}}
{{- $registryName := .Values.metrics.image.registry -}}
{{- $repositoryName := .Values.metrics.image.repository -}}
{{- $tag := .Values.metrics.image.tag | toString -}}
{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
@@ -0,0 +1,125 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: {{ template "fullname" . }}
labels:
app: {{ template "name" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
spec:
selector:
matchLabels:
app: {{ template "name" . }}
release: "{{ .Release.Name }}"
replicas: {{ .Values.replicaCount }}
template:
metadata:
labels:
app: {{ template "name" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
{{- if or .Values.podAnnotations .Values.metrics.enabled }}
annotations:
{{- if .Values.podAnnotations }}
{{ toYaml .Values.podAnnotations | indent 8 }}
{{- end }}
{{- if .Values.metrics.podAnnotations }}
{{ toYaml .Values.metrics.podAnnotations | indent 8 }}
{{- end }}
{{- end }}
spec:
{{- if .Values.server.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.server.image.pullSecrets }}
- name: {{ . }}
{{- end}}
{{- end }}
initContainers:
- name: seed
image: "{{ template "tensorflow-resnet.client.image" . }}"
imagePullPolicy: {{ .Values.client.image.pullPolicy | quote }}
command:
- "/bin/sh"
- "-c"
- |
if [ -f /seed/.initialized ];then
echo "Already initialized. Skipping"
else
curl -o /seed/resnet_v2_fp32_savedmodel_NHWC_jpg.tar.gz http://download.tensorflow.org/models/official/20181001_resnet/savedmodels/resnet_v2_fp32_savedmodel_NHWC_jpg.tar.gz
cd /seed/ && tar -xzf resnet_v2_fp32_savedmodel_NHWC_jpg.tar.gz --strip-components=2
rm resnet_v2_fp32_savedmodel_NHWC_jpg.tar.gz
touch /seed/.initialized
fi
volumeMounts:
- name: seed
mountPath: /seed
containers:
- name: serving
image: "{{ template "tensorflow-resnet.server.image" . }}"
imagePullPolicy: {{ .Values.server.image.pullPolicy | quote }}
ports:
- name: tf-serving
containerPort: {{ .Values.server.port }}
{{- if .Values.livenessProbe.enabled }}
livenessProbe:
tcpSocket:
port: tf-serving
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
successThreshold: {{ .Values.livenessProbe.successThreshold }}
failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
{{- end }}
{{- if .Values.readinessProbe.enabled }}
readinessProbe:
tcpSocket:
port: tf-serving
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
successThreshold: {{ .Values.readinessProbe.successThreshold }}
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
{{- end }}
env:
- name: TENSORFLOW_SERVING_MODEL_NAME
value: "resnet"
volumeMounts:
- name: seed
mountPath: "/bitnami/model-data"
{{- if .Values.metrics.enabled }}
- name: metrics
image: {{ template "metrics.image" . }}
imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }}
command: ['python', 'tf_serving_exporter.py', '--tf_port', '{{ .Values.server.port }}', '--port', {{ .Values.metrics.port }}, '--model_name', 'resnet']
ports:
- name: metrics
containerPort: {{ .Values.metrics.port }}
{{- if .Values.metrics.livenessProbe.enabled }}
livenessProbe:
httpGet:
path: /metrics
port: metrics
initialDelaySeconds: {{ .Values.metrics.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.metrics.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.metrics.livenessProbe.timeoutSeconds }}
successThreshold: {{ .Values.metrics.livenessProbe.successThreshold }}
failureThreshold: {{ .Values.metrics.livenessProbe.failureThreshold }}
{{- end }}
{{- if .Values.metrics.readinessProbe.enabled }}
readinessProbe:
httpGet:
path: /metrics
port: metrics
initialDelaySeconds: {{ .Values.metrics.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.metrics.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.metrics.readinessProbe.timeoutSeconds }}
successThreshold: {{ .Values.metrics.readinessProbe.successThreshold }}
failureThreshold: {{ .Values.metrics.readinessProbe.failureThreshold }}
{{- end }}
resources:
{{ toYaml .Values.metrics.resources | indent 10 }}
{{- end }}
volumes:
- name: seed
emptyDir: {}
@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "fullname" . }}
labels:
app: {{ template "name" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
spec:
type: {{ .Values.serviceType }}
ports:
- port: {{ .Values.server.port }}
protocol: TCP
selector:
app: {{ template "name" . }}
+124
View File
@@ -0,0 +1,124 @@
## Global Docker image registry
## Please, note that this will override the image registry for all the images, including dependencies, configured to use the global value
##
# global:
# imageRegistry:
replicaCount: 1
## TensorFlow Serving server image version
## ref: https://hub.docker.com/r/bitnami/tensorflow-serving/tags/
##
server:
image:
registry: docker.io
repository: bitnami/tensorflow-serving
tag: 1.12.0
## Specify a imagePullPolicy
## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
##
pullPolicy: IfNotPresent
## Optionally specify an array of imagePullSecrets.
## Secrets must be manually created in the namespace.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
# pullSecrets:
# - myRegistrKeySecretName
port: 8500
## TensorFlow ResNet image version
## ref: https://hub.docker.com/r/bitnami/tensorflow-resnet/tags/
##
client:
image:
registry: docker.io
repository: bitnami/tensorflow-resnet
tag: 1.12.0
## Specify a imagePullPolicy
## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
##
pullPolicy: IfNotPresent
## Optionally specify an array of imagePullSecrets.
## Secrets must be manually created in the namespace.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
# pullSecrets:
# - myRegistrKeySecretName
## Specify a imagePullPolicy
## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
##
imagePullPolicy: IfNotPresent
## Kubernetes configuration
## For minikube, set this to NodePort, elsewhere use LoadBalancer
##
serviceType: LoadBalancer
## Pod annotations
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
##
podAnnotations: {}
## Configure extra options for liveness and readiness probes
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes)
livenessProbe:
enabled: true
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1
readinessProbe:
enabled: true
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1
## Prometheus Exporter / Metrics
##
metrics:
enabled: false
image:
registry: docker.io
repository: ynqa/tensorflow-serving-exporter
tag: latest
pullPolicy: IfNotPresent
## Optionally specify an array of imagePullSecrets.
## Secrets must be manually created in the namespace.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
# pullSecrets:
# - myRegistrKeySecretName
port: 9118
## Configure extra options for liveness and readiness probes
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes)
livenessProbe:
enabled: true
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 2
successThreshold: 1
readinessProbe:
enabled: true
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 6
successThreshold: 1
## Metrics exporter pod Annotation and Labels
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9118"
## Metrics exporter resource requests and limits
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
# resources: {}