J'ai un fichier de composition Docker avec les entrées suivantes
version: '2.1'
services:
mysql:
container_name: mysql
image: mysql:latest
volumes:
- ./mysqldata:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: 'password'
ports:
- '3306:3306'
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3306"]
interval: 30s
timeout: 10s
retries: 5
test1:
container_name: test1
image: test1:latest
ports:
- '4884:4884'
- '8443'
depends_on:
mysql:
condition: service_healthy
links:
- mysql
Le conteneur Test-1 dépend de mysql et doit être opérationnel.
Dans Docker, cela peut être contrôlé à l'aide de la vérification de l'état et des attributs depend_on. L'équivalent du bilan de santé dans kubernetes est readinessprobe que j'ai déjà créé, mais comment contrôler le démarrage du conteneur dans le pod ?????
Toutes les directions à ce sujet sont grandement appréciées.
Mon fichier Kubernetes:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: deployment
spec:
replicas: 1
template:
metadata:
labels:
app: deployment
spec:
containers:
- name: mysqldb
image: "dockerregistry:mysqldatabase"
imagePullPolicy: Always
ports:
- containerPort: 3306
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 15
periodSeconds: 10
- name: test1
image: "dockerregistry::test1"
imagePullPolicy: Always
ports:
- containerPort: 3000
Cela a été délibérément laissé de côté. La raison en est que les applications doivent être responsables de leur logique de connexion/reconnexion pour se connecter à des services tels qu'une base de données. Cela sort du cadre de Kubernetes.
C'est la beauté de Docker Compose et Docker Swarm ... Leur simplicité.
Nous avons rencontré cette même lacune de Kubernetes lors du déploiement de la pile ELK. Nous l'avons résolu en utilisant un side-car (initContainer), qui est juste un autre conteneur dans le même pod qui s'exécute en premier, et quand il est terminé, kubernetes démarre automatiquement le conteneur [principal]. Nous en avons fait un simple script Shell qui est en boucle jusqu'à ce qu'Elasticsearch soit opérationnel, puis il se ferme et le conteneur de Kibana démarre.
Ci-dessous, un exemple de side-car qui attend que Grafana soit prêt.
Ajoutez ce bloc 'initContainer' juste au-dessus de vos autres conteneurs dans le Pod:
spec:
initContainers:
- name: wait-for-grafana
image: darthcabs/tiny-tools:1
args:
- /bin/bash
- -c
- >
set -x;
while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' http://grafana:3000/login)" != "200" ]]; do
echo '.'
sleep 15;
done
containers:
.
.
(your other containers)
.
.
Bien que je ne connaisse pas la réponse directe à votre question, sauf ce lien (k8s-AppController) , je ne pense pas qu'il soit sage d'utiliser le même déploiement pour la base de données et l'application. Parce que vous couplez étroitement votre base de données avec l'application et que vous perdez la superbe option k8s pour mettre à l'échelle l'une d'entre elles selon vos besoins. De plus, si votre db pod meurt, vous perdez également vos données.
Personnellement, ce que je ferais, c'est d'avoir un StatefulSet séparé avec Volume persistant pour la base de données et le déploiement pour l'application et utiliser Service pour assurer leur communication.
Oui, je dois exécuter quelques commandes différentes et j'ai peut-être besoin d'au moins deux fichiers de déploiement distincts, mais de cette façon, je les découplent et je peux les mettre à l'échelle selon les besoins. Et mes données sont également persistantes!
Il n'y a pas d'équivalent à l'essaim docker depend_on dans kubernetes. La solution à un tel scénario consiste à utiliser graphiques helm pour les déploiements kubernetes Dans Helm, vous pouvez spécifier la liste des dépendances. Helm gagne maintenant en popularité et est un excellent outil pour gérer les déploiements complexes de kubernetes.
Comme mentionné, vous devez exécuter la base de données et les conteneurs d'application dans des modules distincts et les connecter à un service.
Malheureusement, Kubernetes et Helm ne proposent pas de fonctionnalités similaires à ce que vous avez décrit. Nous avons eu beaucoup de problèmes avec cela et avons essayé quelques approches jusqu'à ce que nous ayons décidé de développer un petit utilitaire qui a résolu ce problème pour nous.
Voici le lien vers l'outil que nous avons développé: https://github.com/Opsfleet/depends-on
Vous pouvez faire attendre les pods jusqu'à ce que d'autres pods soient prêts en fonction de leur configuration readinessProbe. Il est très proche de la fonctionnalité depend_on de Docker.
Dans la terminologie de Kubernetes, votre ensemble de docker-compose est un Pod .
Donc, il n'y a pas de depends_on
équivalent là-bas. Kubernetes vérifiera tous les conteneurs dans un pod et ils doivent tous être en vie pour une marque que le pod est sain et les exécutera toujours ensemble.
Dans votre cas, vous devez préparer la configuration de déploiement comme ça:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1
template:
metadata:
labels:
app: app-and-db
spec:
containers:
- name: app
image: nginx
ports:
- containerPort: 80
- name: db
image: mysql
ports:
- containerPort: 3306
Après le démarrage du pod, votre base de données sera disponible sur l'interface localhost
pour votre application, en raison de conception du résea :
Les conteneurs d'un pod partagent une adresse IP et un espace de port et peuvent se trouver via l'hôte local. Ils peuvent également communiquer entre eux à l'aide de communications inter-processus standard comme les sémaphores SystemV ou la mémoire partagée POSIX.
Mais, comme @leninhasda l'a mentionné, ce n'est pas une bonne idée d'exécuter la base de données et l'application dans votre module et sans volume persistant. Voici un bon tutoriel sur la façon d'exécuter une application avec état dans Kubernetes .