apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
meta.helm.sh/release-name: name
meta.helm.sh/release-namespace: namespace
nginx.ingress.kubernetes.io/configuration-snippet: |
#avoid 5xx errors displayed to user / retry backend servers
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_429 non_idempotent;
nginx.ingress.kubernetes.io/proxy-body-size: 256m
labels:
app.kubernetes.io/managed-by: Helm
name: app-ing
namespace: namespace
spec:
rules:
- host: monsite.com
http:
paths:
- backend:
service:
name: monsite
port:
number: 80
path: /
pathType: Prefix
Cette directive de configuration Nginx détermine comment le serveur proxy doit traiter les erreurs renvoyées par les serveurs de destination lors de la transmission de la requête du client.
Les erreurs de type « timeout », « invalid_header », « http_500 », « http_502 », « http_503 », « http_504 », « http_429 » sont considérées comme des erreurs temporaires et ne sont pas renvoyées directement au client. Au lieu de cela, Nginx essaie de renvoyer la requête à un autre serveur de destination.
Les erreurs « non_idempotent » sont des erreurs permanentes et sont renvoyées directement au client. Les requêtes « non-idempotentes » sont celles qui ne peuvent pas être répétées plusieurs fois sans provoquer de résultats indésirables ou différents.
En utilisant cette directive, on peut configurer Nginx pour qu’il gère les erreurs de manière à minimiser les temps d’arrêt et les erreurs pour les clients qui accèdent aux serveurs proxy.
Cette configuration YAML crée une ConfigMap Kubernetes nommée php-fpm-healthcheck contenant un script Bash nommé php-fpm-healthcheck.sh.
Le script vérifie si les ports 9000 et 8080 sont tous les deux ouverts sur l’adresse IP 127.0.0.1 en utilisant la commande nc (netcat). Si l’un des ports n’est pas ouvert, le script renvoie un code d’erreur 1, sinon il renvoie un code de réussite 0. Cette ConfigMap peut être utilisée pour déployer le script dans un conteneur Kubernetes et exécuter le script en tant que point de contrôle de santé (liveness ou readiness) pour vérifier l’état de l’application.
livenessProbe:
exec:
command:
- /scripts/php-fpm-healthcheck
failureThreshold: 3
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 3
readinessProbe:
exec:
command:
- /scripts/php-fpm-healthcheck
failureThreshold: 3
initialDelaySeconds: 3
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 3
apiVersion: v1
kind: ConfigMap
metadata:
name: php-fpm-healthcheck
data:
php-fpm-healthcheck.sh: |
#!/bin/bash
if ! nc -zv 127.0.0.1 9000 >/dev/null 2>&1; then
exit 1
elif ! nc -zv 127.0.0.1 8080 >/dev/null 2>&1; then
exit 1
else
exit 0
fi
En gros, on créé un conteneur avec Redis et aws cli, qui va lire le nombre d’événements et envoyer l’info en tant que métrique personnalisée à CloudWatch. Ensuite on peut créer une alarme qui sera déclenchée à partir d’un certain seuil et comme action possible augmenter le nombre d’instances dans un groupe asg …
Commençons par construire une image Docker minimale:
FROM ubuntu:22.04
RUN apt-get update; DEBIAN_FRONTEND=noninteractive apt-get install wget curl jq zip unzip -y \
&& curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" \
&& unzip awscliv2.zip && bash ./aws/install \
&& apt autoclean \
&& apt autoremove
RUN apt-get install redis less -y
Ceci est le Dockerfile
docker build -t xxx.dkr.ecr.eu-central-1.amazonaws.com/docker-images:queue-monitor-v1 -f Dockerfile .
docker push xxx.dkr.ecr.eu-central-1.amazonaws.com/docker-images:queue-monitor-v1
Ensuite notre manifest pour k8s:
apiVersion: apps/v1
kind: Deployment
metadata:
name: queue-monitor-prod
namespace: queue-monitor
annotations:
reloader.stakater.com/auto: "true"
spec:
replicas: 1
selector:
matchLabels:
app: queue-monitor-prod
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: queue-monitor-prod
spec:
terminationGracePeriodSeconds: 0
containers:
- name: app
securityContext:
runAsUser: 0
runAsGroup: 0
command: [ "/bin/bash", "-c" ]
args: [ "/etc/queue-monitor/startup.sh" ]
image: xxx.dkr.ecr.eu-central-1.amazonaws.com/docker-images:queue-monitor-v1
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "cp -a /etc/.aws /root/.aws"]
env:
- name: AWS_PROFILE
value: prod
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 1m
memory: 1Mi
livenessProbe:
exec:
command:
- /bin/bash
- -c
- /etc/queue-monitor/health.sh
failureThreshold: 1
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
exec:
command:
- /bin/bash
- -c
- /etc/queue-monitor/health.sh
initialDelaySeconds: 3
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- name: config
mountPath: "/etc/queue-monitor"
- name: awsconfig
mountPath: "/etc/.aws"
volumes:
- name: config
projected:
defaultMode: 0755
sources:
- configMap:
name: queue-monitor-config-prod
- name: awsconfig
secret:
secretName: queue-monitor-sec
items:
- key: credentials
path: credentials
mode: 0600
---
apiVersion: v1
kind: ConfigMap
metadata:
name: queue-monitor-config-prod
namespace: queue-monitor
data:
health.sh: |
exit 0
startup.sh: |
#!/bin/bash
#
#loop starting
while true
do
queue=$(redis-cli -h cluster-queue.xxxxxxxx.0001.euc1.cache.amazonaws.com LLEN queues:default | awk '{print $1}')
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
aws cloudwatch put-metric-data --metric-name queue-monitoring-prod --namespace queue-monitoring --value "$queue" --timestamp "$TIMESTAMP"
sleep 15
done
Je vous laisse personnaliser le vôtre, ce setup n’est pas parfait car a dû être machiné en une dizaine de minutes seulement.
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/proxy-body-size: 256m
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
nginx.ingress.kubernetes.io/enable-cors: "true"
host: ***.org
path: "/"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
nginx.ingress.kubernetes.io/enable-cors: "true"
CORS (Cross-Origin Resource Sharing) est un mécanisme qui permet aux navigateurs web d’accéder aux ressources d’un serveur situé sur un domaine différent. Sans CORS, les navigateurs appliquent la même politique de même origine (same-origin policy) qui interdit l’accès à des ressources provenant de domaines différents pour des raisons de sécurité.
Dans ce contexte, les annotations « nginx.ingress.kubernetes.io/cors-allow-origin » et « nginx.ingress.kubernetes.io/enable-cors » sont utilisées pour activer la prise en charge de CORS par le contrôleur Ingress Nginx dans Kubernetes. La première annotation spécifie la valeur de l’en-tête « Access-Control-Allow-Origin » à utiliser pour toutes les requêtes entrantes, qui est ici définie sur « * ». La seconde annotation active la prise en charge de CORS pour cette ressource Ingress.
En activant CORS, cela permet aux applications web d’envoyer des requêtes à partir de n’importe quel domaine, ce qui est souvent utile pour les API. Cependant, il est important de noter que cela peut également présenter des risques de sécurité si la configuration n’est pas correctement gérée. Par conséquent, il est recommandé de mettre en place des politiques de sécurité appropriées pour contrôler l’accès aux ressources.
This command will create a new pod named « mysql-client » and start a bash session inside the container running the MySQL client image.
kubectl run mysql-client --image=mysql:8.0 -it --rm --restart=Never -- /bin/bash
Here’s a breakdown of the command:
kubectl run
: This command is used to create a new pod or deployment in Kubernetes.
mysql-client
: This is the name of the pod that will be created.
--image=mysql:8.0
: This specifies the Docker image to use for the container.
-it
: This starts an interactive terminal session inside the container.
--rm
: This flag specifies that the container should be removed after it exits.
--restart=Never
: This specifies that the pod should not be restarted if it stops running for any reason.
-- /bin/bash
: This starts a bash session inside the container.
Once the command is executed, you should see a bash prompt inside the container. From there, you can run MySQL commands to interact with your MySQL server.