Skip to content

docs: Improve helm for Version 3 #1340

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

Merged
merged 27 commits into from
Oct 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e3f49a6
improve documentation for helm v. 3 (WIP)
Chris53897 Apr 6, 2021
cac4368
improve documentation for helm v. 3 (WIP)
Chris53897 Apr 6, 2021
cf5a7dd
remove infos about local registry
Chris53897 Apr 7, 2021
990aeb1
fix markdown lint errors
Chris53897 Apr 7, 2021
2305404
Update deployment/kubernetes.md
Chris53897 Apr 8, 2021
bdda36e
Update deployment/kubernetes.md
Chris53897 Apr 8, 2021
f99b377
Update deployment/kubernetes.md
Chris53897 Apr 8, 2021
6c7e22f
Update deployment/kubernetes.md
Chris53897 Apr 8, 2021
e810333
Update deployment/kubernetes.md
Chris53897 Apr 8, 2021
36e13c4
removed tiller infos, simplify docker build tags
Chris53897 Apr 8, 2021
0403163
improved helm doku
Chris53897 Apr 11, 2021
0dcb2f2
improved helm doku, add images
Chris53897 Apr 11, 2021
18958ec
improved helm doku (access the container)
Chris53897 Apr 27, 2021
26839ea
Update deployment/kubernetes.md
Chris53897 May 20, 2021
b1ff45a
Update deployment/kubernetes.md
Chris53897 May 20, 2021
cba8b23
Update deployment/kubernetes.md
Chris53897 May 20, 2021
fb4eb03
fix parameter ".image.pullPolicy", add GitHub Actions example infos, …
Chris53897 May 20, 2021
1e606de
fix name of image in helm upgrade. change install command to "helm up…
Chris53897 May 29, 2021
15ed0ee
Update deployment/kubernetes.md
Chris53897 Oct 27, 2021
418263d
Update deployment/kubernetes.md
Chris53897 Oct 27, 2021
69dc7b3
Update deployment/kubernetes.md
Chris53897 Oct 27, 2021
bebac3d
Update deployment/kubernetes.md
Chris53897 Oct 27, 2021
b276a5a
Update deployment/kubernetes.md
Chris53897 Oct 27, 2021
c518976
Update deployment/kubernetes.md
Chris53897 Oct 27, 2021
108da31
Update deployment/kubernetes.md
Chris53897 Oct 27, 2021
c54bf54
Update deployment/kubernetes.md
Chris53897 Oct 27, 2021
54b0047
Merge branch '2.6' into improve-helm
Chris53897 Oct 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added deployment/images/deploy-result.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added deployment/images/google-image-caddy-details.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added deployment/images/google-image-overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
178 changes: 123 additions & 55 deletions deployment/kubernetes.md
Original file line number Diff line number Diff line change
@@ -1,103 +1,171 @@
# Deploying to a Kubernetes Cluster

[Kubernetes](https://kubernetes.io/) has become the most popular way to deploy, run and manage containers in production.
Both [Google Cloud Platform](https://cloud.google.com/kubernetes-engine/), [Microsoft Azure](https://azure.microsoft.com/en-us/services/container-service/kubernetes/)
and [Amazon Web Services](https://aws.amazon.com/eks/) provide managed Kubernetes environment.
[Google Cloud Platform](https://cloud.google.com/kubernetes-engine/), [Microsoft Azure](https://azure.microsoft.com/en-us/services/container-service/kubernetes/)
and [Amazon Web Services](https://aws.amazon.com/eks/) and many more companies provide managed Kubernetes environment.

[The official API Platform distribution](../distribution/index.md) contains a built-in [Helm](https://helm.sh/) (the k8s
package manager) chart to deploy in a wink on any of these platforms.

This guide is based on Helm 3.

If you want to deploy API Platform on a local Kubernetes cluster, check out [our Minikube tutorial](minikube.md)!

## Preparing Your Cluster and Your Local Machine

1. Create a Kubernetes cluster on your preferred Cloud provider or install Kubernetes locally on your servers
2. Install [Helm](https://helm.sh/) locally and on your cluster following their documentation
3. Be sure to be connected to the right Kubernetes container e.g. running: `gcloud config get-value core/project`
4. Update the Helm repo: `helm repo update`
1. Create a Kubernetes cluster on your preferred Cloud provider or install Kubernetes locally on your server, for example with [kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)
2. Install [Helm 3](https://helm.sh/) `locally` following their [documentation](https://helm.sh/docs/intro/install/)
3. Be sure to be connected to the right Kubernetes cluster
`kubectl config view` [Details](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)
e.g. for Google Cloud running: `gcloud config get-value core/project`

Working-Dir: Your local installation of api-platform. Default /api-platform/

## Creating and Publishing the Docker Images

1. Build the PHP and NGINX Docker images:
### Example with the [Google Container Registry](https://cloud.google.com/container-registry/) and [Google Cloud Platform](https://cloud.google.com/kubernetes-engine/)

Change the name "test-api-platform" to your Google project ID (not the project name).
[Quickstart Google Cloud](https://cloud.google.com/sdk/docs/quickstart?hl=de)
If you do not have gcloud yet, install it with these command.

curl https://sdk.cloud.google.com | bash

#### 1. Build the PHP and Caddy Docker images and tag them

Versioning: The 0.1.0 is the version. This value should be the same as the attribute `appVersion` in `Chart.yaml`.
Infos for [Google Container pulling and pushing](https://cloud.google.com/container-registry/docs/pushing-and-pulling)

docker build -t gcr.io/test-api-platform/php:0.1.0 -t gcr.io/test-api-platform/php:latest api --target api_platform_php
docker build -t gcr.io/test-api-platform/caddy:0.1.0 -t gcr.io/test-api-platform/caddy:latest api --target api_platform_caddy
docker build -t gcr.io/test-api-platform/pwa:0.1.0 -t gcr.io/test-api-platform/pwa:latest pwa --target api_platform_pwa_prod

#### 2. Push your images to your Docker registry

gcloud auth configure-docker
docker push gcr.io/test-api-platform/php
docker push gcr.io/test-api-platform/caddy
docker push gcr.io/test-api-platform/pwa

Optional push the version images:

docker push gcr.io/test-api-platform/php:0.1.0
docker push gcr.io/test-api-platform/caddy:0.1.0
docker push gcr.io/test-api-platform/pwa:0.1.0

docker build -t gcr.io/test-api-platform/php -t gcr.io/test-api-platform/php:latest api --target api_platform_php
docker build -t gcr.io/test-api-platform/nginx -t gcr.io/test-api-platform/nginx:latest api --target api_platform_nginx
docker build -t gcr.io/test-api-platform/varnish -t gcr.io/test-api-platform/varnish:latest api --target api_platform_varnish
The result should look similar to these images.

2. Push your images to your Docker registry, example with [Google Container Registry](https://cloud.google.com/container-registry/):
![Example of Google Images - Overview](images/google-image-overview.png)
![Example of Google Caddy Image - Details](images/google-image-caddy-details.png)

Docker client versions <= 18.03:
## Deploying with Helm 3

gcloud docker -- push gcr.io/test-api-platform/php
gcloud docker -- push gcr.io/test-api-platform/nginx
gcloud docker -- push gcr.io/test-api-platform/varnish
### 1. Check the Helm version

Docker client versions > 18.03:
helm version

gcloud auth configure-docker
docker push gcr.io/test-api-platform/php
docker push gcr.io/test-api-platform/nginx
docker push gcr.io/test-api-platform/varnish
If you are using version 2.x follow this [guide to migrate Helm to v3](https://helm.sh/docs/topics/v2_v3_migration/#helm)

## Deploying
### 2. Firstly you need to update helm dependencies by running

Firstly you need to update helm dependencies by running:
helm dependency update ./helm/api-platform
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it work on your install? On api-platform/demo, I had to do the following;

helm repo add bitnami https://charts.bitnami.com/bitnami/
helm repo add stable https://charts.helm.sh/stable/
helm dependency build ./helm/api-platform

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It worked for us. It will update chart.lock and add the /charts/postgresql-10.3.18.tgz
But i need to check it. The gitlab-ci File has a part that scans dependencies and add it dynamically.

local pc:
➜ project git:(main) ✗ helm repo list
Error: no repositories to show
➜ project git:(main) ✗ helm dependency update ./helm/api-platform
Getting updates for unmanaged Helm repositories...
...Successfully got an update from the "https://charts.bitnami.com/bitnami/" chart repository
Saving 1 charts
Downloading postgresql from repo https://charts.bitnami.com/bitnami/
Deleting outdated charts


helm dependency update ./api/helm/api
This will create a folder helm/api-platform/charts/ and add all dependencies there.
Actual this is [bitnami/postgresql](https://bitnami.com/stack/postgresql/helm), a file postgresql-[VERSION].tgz is created.
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand the first part of this sentence...


You are now ready to deploy the API!
### 3. Optional: If you made changes to the Helm chart, check if its format is correct

Deploy your API to the container:
helm lint ./helm/api-platform

helm install ./api/helm/api --namespace=baz --name baz \
--set php.repository=gcr.io/test-api-platform/php \
--set nginx.repository=gcr.io/test-api-platform/nginx \
--set secret=MyAppSecretKey \
--set postgresql.postgresPassword=MyPgPassword \
### 4. Deploy your API to the container

helm upgrade main ./helm/api-platform --namespace=default --create-namespace --wait \
--install \
Copy link
Contributor

Choose a reason for hiding this comment

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

What about the ingress and mercure?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The Company does not use mercure right know. (We removed vulcain and mercure for faster build times) So i do not have much knowledge here. The Domain for ingress was hardcodet. I have to compare Company code to api-platform code.

--set "php.image.repository=gcr.io/test-api-platform/php" \
--set php.image.tag=latest \
--set "caddy.image.repository=gcr.io/test-api-platform/caddy" \
--set caddy.image.tag=latest \
--set "pwa.image.repository=gcr.io/test-api-platform/pwa" \
--set pwa.image.tag=latest \
--set php.appSecret='!ChangeMe!' \
--set postgresql.postgresqlPassword='!ChangeMe!' \
--set postgresql.persistence.enabled=true \
--set corsAllowOrigin='^https?://[a-z\]*\.mywebsite.com$'
--set "corsAllowOrigin=^https?:\/\/[a-z]*\.mywebsite.com$"

The `"` are necessary for Windows. Use ^ on Windows instead of \ to split commands into multiple lines.
You can add the parameter `--dry-run` to check upfront if anything is correct.
Replace the values with the image parameters from the stage above.
The parameter `php.appSecret` is the `AppSecret` from ./.env
Fill the rest of the values with the correct settings.
For available options see /helm/api-platform/values.yaml.
If you want a test deploy you can set corsAllowOrigin='*'

After a successful installation, there is a message at the end.
You can copy these commands and execute them to set a port-forwarding and
get access on your local machine to the deploy. See image below.

![Deploy Result](images/deploy-result.png)

If you prefer to use a managed DBMS like [Heroku Postgres](https://www.heroku.com/postgres) or
[Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/) (recommended):

helm install --name api ./api/helm/api \
helm upgrade api-platform ./helm/api-platform \
# ...
--set postgresql.enabled=false \
--set postgresql.url=pgsql://username:password@host/database?serverVersion=9.6
--set postgresql.url=pgsql://username:password@host/database?serverVersion=13

Finally, build the `pwa` (client and admin) JavaScript apps and [deploy them on a static
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't use static version built of the PWA on api-platform, now we're using Next.js static generation. You can have a look at the demo PWA as an example.

But in a sense, you're still right as building the PWA and deploying it on a static server is still possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you please make a suggestion on how to change this? We are using an Angular Frontend not tied to API-Platform. I do not have knowledge in this topic.

website hosting service](https://create-react-app.dev/docs/deployment/).

If you want to use a managed Varnish such as [Fastly](https://www.fastly.com) for the invalidation cache mechanism
provided by API Platform:
## Access the container

helm install --name api ./api/helm/api \
# ...
--set varnish.enabled=false \
--set varnish.url=https://myvarnish.com
You can access the php container of the pod with the following command.
In this example the symfony console is called.

Finally, build the `client` and `admin` JavaScript apps and [deploy them on a static
website hosting service](https://create-react-app.dev/docs/deployment/).
CADDY_PHP_POD=$(kubectl --namespace=default get pods -l app.kubernetes.io/name=api-platform -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace=default exec -it $CADDY_PHP_POD -c api-platform-php -- bin/console

## Caution for system architecture

If the pods do not run, and you get the following error from google kubernetes engine logs,
there is probably a problem with the system architecture.
`standard_init_linux.go:211: exec user process caused "exec format error`
Build the images with the same system architecture as the cluster runs.
Example: Building with Mac M1 with arm64 leads to problems. Most cluster will run with x86_64.
Solution: <https://blog.jaimyn.dev/how-to-build-multi-architecture-docker-images-on-an-m1-mac/>

## Initializing the Database
## Updates

Before running your application for the first time, be sure to create the database schema:
There are 2 main upgrade strategies.

PHP_POD=$(kubectl --namespace=bar get pods -l app=php -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace=bar exec -it $PHP_POD -- bin/console doctrine:schema:create
### 1. Always version your images (recommended)

## Tiller RBAC Issue
Change the version in the attribut "appVersion" in Chart.yaml and tag the images with this version.
You can upgrade with the same command from the installation and pass all parameters.

We noticed that some tiller RBAC trouble occurred. You can usually resolve it by running:
### 2. Use :latest tags

kubectl create serviceaccount --namespace kube-system tiller
serviceaccount "tiller" created
Infos about [best practices for tagging images for kubernetes](https://kubernetes.io/docs/concepts/containers/images/)
You have to use the *.image.pullPolicy=Always see the last 3 parameters.

kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
clusterrolebinding "tiller-cluster-rule" created
helm upgrade api-platform ./helm/api-platform --namespace=default \
--set "php.image.repository=gcr.io/test-api-platform/php" \
--set php.image.tag=latest \
--set "caddy.image.repository=gcr.io/test-api-platform/caddy" \
--set caddy.image.tag=latest \
--set "pwa.image.repository=gcr.io/test-api-platform/pwa" \
--set pwa.image.tag=latest \
--set php.appSecret='!ChangeMe!' \
--set postgresql.postgresqlPassword='!ChangeMe!' \
Copy link
Contributor

Choose a reason for hiding this comment

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

While updating an existing database, this might cause issues. I don't recommend to change the database password on update. That's why I had to do the following on api-platform/demo:

if ! kubectl get namespace $GITHUB_REF_SLUG > /dev/null 2>&1; then
    // install
else
    // update
fi

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i do not recommend to change the database password with the upgrade. We have an Database on a server outside of kubernetes and the password stays the same. with upgrade --install there is only one command needed.

--set postgresql.persistence.enabled=true \
--set "corsAllowOrigin=^https?://[a-z\]*\.mywebsite.com$" \
--set php.image.pullPolicy=Always \
--set caddy.image.pullPolicy=Always \
--set pwa.image.pullPolicy=Always

kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
deployment "tiller-deploy" patched
## GitHub Actions Example for deployment

Please, see the [related issue](https://github.com/kubernetes/helm/issues/3130) for further details / information.
You can also take a look at the [related documentation](https://github.com/kubernetes/helm/blob/master/docs/rbac.md)
You can find a [complete deploy command for GKE](https://github.com/api-platform/demo/blob/main/.github/workflows/deploy.yml) on the [demo project](https://github.com/api-platform/demo/):

## Symfony Messenger

Expand Down