Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Online Boutique's Helm chart #1353

Merged
merged 19 commits into from Dec 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/helm-chart-ci.yaml
@@ -0,0 +1,68 @@
# Copyright 2022 Google LLC
mathieu-benoit marked this conversation as resolved.
Show resolved Hide resolved
#
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
# 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.

name: helm-chart-ci
on:
push:
branches:
- main
paths:
- 'helm-chart/**'
- '.github/workflows/helm-chart-ci.yaml'
pull_request:
paths:
- 'helm-chart/**'
- '.github/workflows/helm-chart-ci.yaml'
jobs:
helm-chart-ci:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: helm lint
run: |
cd helm-chart/
helm lint
- name: helm template default
run: |
cd helm-chart/
helm template . > helm-template.yaml
cat helm-template.yaml
- name: kustomize build default
run: |
cd helm-chart/
kustomize create --resources helm-template.yaml
kustomize build .
- name: helm template advanced
run: |
cd helm-chart/
helm template . \
--set images.repository=us-docker.pkg.dev/my-project/containers/onlineboutique \
--set frontend.externalService=false \
--set redis.create=false \
--set cartservice.database.type=spanner \
--set cartservice.database.connectionString=projects/my-project/instances/onlineboutique/databases/carts \
--set serviceAccounts.create=true \
--set authorizationPolicies.create=true \
--set networkPolicies.create=true \
--set sidecars.create=true \
--set frontend.virtualService.create=true \
--set 'serviceAccounts.annotations.iam\.gke\.io/gcp-service-account=spanner-db-user@my-project.iam.gserviceaccount.com' \
--set serviceAccounts.annotationsOnlyForCartservice=true \
-n onlineboutique \
> helm-template.yaml
cat helm-template.yaml
- name: kustomize build advanced
run: |
cd helm-chart/
kustomize build .
33 changes: 33 additions & 0 deletions hack/make-helm-chart.sh
@@ -0,0 +1,33 @@
#!/usr/bin/env bash

# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
# 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.

# Packages and pushes Online Boutique's Helm chart in public Artifact Registry.

set -euo pipefail
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

log() { echo "$1" >&2; }

TAG="${TAG:?TAG env variable must be specified}"
HELM_CHART_REPO="us-docker.pkg.dev/online-boutique-ci/charts"

cd helm-chart
sed -i "s/^appVersion:.*/appVersion: \"${TAG}\"/" Chart.yaml
sed -i "s/^version:.*/version: ${TAG:1}/" Chart.yaml
helm package .
helm push onlineboutique-$TAG.tgz oci://$HELM_CHART_REPO
mathieu-benoit marked this conversation as resolved.
Show resolved Hide resolved

log "Successfully built and pushed the Helm chart."
mathieu-benoit marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions hack/make-release.sh
Expand Up @@ -50,10 +50,14 @@ git pull
# update yaml
"${SCRIPTDIR}"/make-release-artifacts.sh

# build and push images
"${SCRIPTDIR}"/make-helm-chart.sh

# create git release / push to new branch
git checkout -b "release/${TAG}"
git add "${SCRIPTDIR}/../release/"
git add "${SCRIPTDIR}/../kustomize/base/"
git add "${SCRIPTDIR}/../helm-chart/"
git commit --allow-empty -m "Release $TAG"
log "Pushing k8s manifests to release/${TAG}..."
git tag "$TAG"
Expand Down
24 changes: 24 additions & 0 deletions helm-chart/Chart.yaml
@@ -0,0 +1,24 @@
apiVersion: v2
name: onlineboutique
description: A Helm chart for Kubernetes for Online Boutique

# A chart can be either an 'application' or a 'library' chart.
mathieu-benoit marked this conversation as resolved.
Show resolved Hide resolved
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.4.2

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "v0.4.2"
Copy link
Collaborator

@NimJay NimJay Dec 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue:
Please add automation to /hack/make-release.sh such that:

  1. the versions inside this Chart.yaml file are updated.
  2. the file is git commit-ed.

Ideally, we would simplify the release process (such that the automation is no longer required), but that would require an audit of docs/demos using Online Boutique.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

30 changes: 30 additions & 0 deletions helm-chart/README.md
@@ -0,0 +1,30 @@
# Helm chart for Online Boutique

If you'd like to deploy Online Boutique via its Helm chart, you could leverage the following instructions.

**Warning:** Online Boutique's Helm chart is currently experimental. If you have feedback or run into issues, let us know inside [GitHub Issue #1319](https://github.com/GoogleCloudPlatform/microservices-demo/issues/1319) or by creating a [new GitHub Issue](https://github.com/GoogleCloudPlatform/microservices-demo/issues/new/choose).
mathieu-benoit marked this conversation as resolved.
Show resolved Hide resolved

Deploy the default setup of Online Boutique:
```sh
helm install onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique
```

Deploy advanced scenario of Online Boutique:
```sh
helm install onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \
--set images.repository=us-docker.pkg.dev/my-project/containers/onlineboutique \
--set frontend.externalService=false \
--set redis.create=false \
--set cartservice.database.type=spanner \
--set cartservice.database.connectionString=projects/my-project/instances/onlineboutique/databases/carts \
--set serviceAccounts.create=true \
--set authorizationPolicies.create=true \
--set networkPolicies.create=true \
--set sidecars.create=true \
--set frontend.virtualService.create=true \
--set 'serviceAccounts.annotations.iam\.gke\.io/gcp-service-account=spanner-db-user@my-project.iam.gserviceaccount.com' \
--set serviceAccounts.annotationsOnlyForCartservice=true \
-n onlineboutique
```

For the full list of configurations, see [values.yaml](./values.yaml).
13 changes: 13 additions & 0 deletions helm-chart/templates/NOTES.txt
@@ -0,0 +1,13 @@
{{- if and .Values.frontend.create .Values.frontend.externalService }}
Note: It may take a few minutes for the LoadBalancer IP to be available.

Watch the status of the frontend IP address with:
kubectl get --namespace {{ .Release.Namespace }} svc -w {{ .Values.frontend.name }}-external

Get the external IP address of the frontend:
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ .Values.frontend.name }}-external --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP
{{- end }}
{{- if .Values.frontend.virtualService.create }}

{{- end }}
mathieu-benoit marked this conversation as resolved.
Show resolved Hide resolved
184 changes: 184 additions & 0 deletions helm-chart/templates/adservice.yaml
@@ -0,0 +1,184 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
# 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.

{{- if .Values.adService.create }}
{{- if .Values.serviceAccounts.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.adService.name }}
namespace: {{.Release.Namespace}}
{{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }}
{{- with .Values.serviceAccounts.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
---
{{- end }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.adService.name }}
namespace: {{ .Release.Namespace }}
spec:
selector:
matchLabels:
app: {{ .Values.adService.name }}
template:
metadata:
labels:
app: {{ .Values.adService.name }}
spec:
{{- if .Values.serviceAccounts.create }}
serviceAccountName: {{ .Values.adService.name }}
{{- else }}
serviceAccountName: default
{{- end }}
terminationGracePeriodSeconds: 5
securityContext:
fsGroup: 1000
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
{{- if .Values.seccompProfile.enable }}
seccompProfile:
type: {{ .Values.seccompProfile.type }}
{{- end }}
containers:
- name: server
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
privileged: false
readOnlyRootFilesystem: true
image: {{ .Values.images.repository }}/{{ .Values.adService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }}{{ .Values.images.tagSuffix }}
ports:
- containerPort: 9555
env:
- name: PORT
value: "9555"
resources:
requests:
cpu: 200m
memory: 180Mi
limits:
cpu: 300m
memory: 300Mi
readinessProbe:
initialDelaySeconds: 20
periodSeconds: 15
{{- if .Values.nativeGrpcHealthCheck }}
grpc:
port: 9555
{{- else }}
exec:
command: ["/bin/grpc_health_probe", "-addr=:9555"]
{{- end }}
livenessProbe:
initialDelaySeconds: 20
periodSeconds: 15
{{- if .Values.nativeGrpcHealthCheck }}
grpc:
port: 9555
{{- else }}
exec:
command: ["/bin/grpc_health_probe", "-addr=:9555"]
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.adService.name }}
namespace: {{ .Release.Namespace }}
spec:
type: ClusterIP
selector:
app: {{ .Values.adService.name }}
ports:
- name: grpc
port: 9555
targetPort: 9555
{{- if .Values.networkPolicies.create }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ .Values.adService.name }}
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
app: {{ .Values.adService.name }}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: {{ .Values.frontend.name }}
ports:
- port: 9555
protocol: TCP
egress:
- {}
{{- end }}
{{- if .Values.sidecars.create }}
---
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: {{ .Values.adService.name }}
namespace: {{ .Release.Namespace }}
spec:
workloadSelector:
labels:
app: {{ .Values.adService.name }}
egress:
- hosts:
- istio-system/*
{{- end }}
{{- if .Values.authorizationPolicies.create }}
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: {{ .Values.adService.name }}
namespace: {{ .Release.Namespace }}
spec:
selector:
matchLabels:
app: {{ .Values.adService.name }}
rules:
- from:
- source:
principals:
{{- if .Values.serviceAccounts.create }}
- cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.frontend.name }}
{{- else }}
- cluster.local/ns/{{ .Release.Namespace }}/sa/default
{{- end }}
to:
- operation:
paths:
- /hipstershop.AdService/GetAds
methods:
- POST
ports:
- "9555"
{{- end }}
{{- end }}