J'essaie de vérifier que mon pod postgres est accessible via le service que je viens de configurer. Pour l'instant, je ne peux pas le vérifier. Ce que je peux faire, c'est me connecter au conteneur exécutant postgres lui-même et tenter de parler au serveur postgres via l'adresse IP du service. Cela ne réussit pas. Cependant, je ne sais pas s'il s'agit d'un test valide pour savoir si d'autres pods du cluster peuvent parler à postgres via le service ou s'il y a un problème avec la façon dont je fais le test, ou s'il y a un problème fondamental dans mon configurations de service ou de pod.
Je fais tout cela sur un cluster minikube.
Configurez le pod et le service :
$> kubectl create -f postgres-pod.yml
$> kubectl create -f postgres-service.yml
postgres-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: postgres
labels:
env: prod
creation_method: manual
domain: infrastructure
spec:
containers:
- image: postgres:13-alpine
name: kubia-postgres
ports:
- containerPort: 5432
protocol: TCP
env:
- name: POSTGRES_PASSWORD
value: dave
- name: POSTGRES_USER
value: dave
- name: POSTGRES_DB
value: tmp
# TODO:
# volumes:
# - name: postgres-db-volume
postgres-service.yml
apiVersion: v1
kind: Service
metadata:
name: postgres-service
spec:
ports:
- port: 5432
targetPort: 5432
selector:
name: postgres
Vérifiez que le service est opérationnel kubectl get services
:
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 35d
postgres-service ClusterIP 10.110.159.21 <none> 5432/TCP 71m
Ensuite, connectez-vous au conteneur postgres :
$> kubectl exec --stdin --tty postgres -- /bin/bash
from there, attempt to hit the service's IP:
bash-5.1# psql -U dave -h 10.110.159.21 -p 5432 tmp
psql: error: could not connect to server: Connection refused
Is the server running on host "10.110.159.21" and accepting
TCP/IP connections on port 5432?
Donc, en utilisant cette approche, je ne peux pas me connecter au serveur postgres en utilisant l'adresse IP du service.
Je ne suis pas sûr de plusieurs étapes de ce processus :
Le bloc de sélection par nom dans la configuration du service yaml est-il correct ?Pouvez-vous accéder à l'adresse IP d'un service à partir de pods situés "derrière" le service ?Est-ce, en fait, un moyen valide de vérifier que le serveur de base de données est accessible via le service, ou existe-t-il un autre moyen ? Solution du problème
Bonjour, j'espère que vous envoyez votre voyage Kubernetes !
Je voulais essayer ceci sur mon cluster type (Kubernetes dans docker) localement. Alors voilà ce que j'ai fait:
J'ai d'abord configuré un cluster kind localement avec cette configuration (info ici: https://kind.sigs.k8s.io/docs/user/quick-start/ ):
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: so-cluster-1
nodes:
- role: control-plane
image: kindest/node:v1.23.5
- role: control-plane
image: kindest/node:v1.23.5
- role: control-plane
image: kindest/node:v1.23.5
- role: worker
image: kindest/node:v1.23.5
- role: worker
image: kindest/node:v1.23.5
- role: worker
image: kindest/node:v1.23.5
after this I created my cluster with this command:
kind create cluster --config=config.yaml
Ensuite, j'ai créé un espace de noms de test (manifeste obtenu avec : kubectl create ns so-tests -o yaml --dry-run) :
apiVersion: v1
kind: Namespace
metadata:
name: so-tests
À partir de là, j'ai configuré mon environnement, j'ai donc dû déployer un postgres dessus, mais voici ce que j'ai changé :
1- Au lieu de créer un pod singleton, j'ai créé un statefulset (dont le but est de déployer des bases de données)
2- J'ai décidé de continuer à utiliser votre image docker "postgres:13-alpine" et j'ai ajouté un contexte de sécurité à exécuter en tant qu'utilisateur postgres natif (pas dave ni root) - pour savoir quel est l'identifiant de l'utilisateur postgres, j'ai d'abord déployé le statefulset sans le contexte de sécurité et exécuté ces commandes :
❯ k exec -it postgres-0 -- bash
bash-5.1# whoami
root
bash-5.1# id
uid=0(root) gid=0(root) groups=1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
bash-5.1# id postgres
uid=70(postgres) gid=70(postgres) groups=70(postgres),70(postgres)
bash-5.1# exit
donc, une fois que j'ai su que l'id de l'utilisateur postgres était 70, j'ai juste ajouté ceci dans le manifeste statefulset:
securityContext:
runAsUser: 70
fsGroup: 70
3- Au lieu d'ajouter la configuration et les secrets comme variable d'environnement directement dans la configuration du pod du statefulset, je décide de créer un secret et un configmap :
Commençons par créer un secret kubernetes avec votre mot de passe, voici le manifeste (obtenu à partir de cette commande : "k create secret generic --from-literal password=dave postgres-secret -o yaml --dry-run=client"):
apiVersion: v1
data:
password: ZGF2ZQ==
kind: Secret
metadata:
name: postgres-secret
Après cela, j'ai créé un configmap pour stocker notre configuration postgres, voici le manifeste (obtenu en exécutant: kubectl create configmap postgres-config --from-literal user=dave --from-literal db=tmp --dry-run=client -o yaml )
apiVersion: v1
data:
db: tmp
user: dave
kind: ConfigMap
metadata:
name: postgres-config
Comme c'est juste à des fins de test, je n'ai pas configuré de provisionnement de volume dynamique pour l'ensemble d'états, ni de volume pré-provisionné. Au lieu de cela, j'ai configuré un simple emptyDir pour stocker les données postgres (/var/lib/postgresql/data).
NB: Par défaut, les volumes emptyDir sont stockés sur n'importe quel support qui sauvegarde le nœud - qui peut être un disque ou un SSD ou un stockage réseau, selon votre environnement. Cependant, vous pouvez définir le champ emptyDir.medium sur "Mémoire" pour dire à Kubernetes de monter un tmpfs (système de fichiers basé sur RAM) pour vous à la place. (cela vient d'ici Créer un nouveau volume lors du redémarrage du pod dans un statefulset )
Comme il s'agit d'un statefulset, il doit être exposé par un service kubernetes headless ( https://kubernetes.io/fr/docs/concepts/services-networking/service/#headless-services )
Voici les manifestes :
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: "postgres"
replicas: 2
selector:
matchLabels:
env: prod
domain: infrastructure
template:
metadata:
labels:
env: prod
domain: infrastructure
spec:
terminationGracePeriodSeconds: 20
securityContext:
runAsUser: 70
fsGroup: 70
containers:
- name: kubia-postgres
image: postgres:13-alpine
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
- name: POSTGRES_USER
valueFrom:
configMapKeyRef:
name: postgres-config
key: user
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
name: postgres-config
key: db
ports:
- containerPort: 5432
protocol: TCP
volumeMounts:
- name: postgres-test-volume
mountPath: /var/lib/postgresql
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
volumes:
- name: postgres-test-volume
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: postgres-service
labels:
env: prod
domain: infrastructure
spec:
ports:
- port: 5432
protocol: TCP
targetPort: 5432
name: pgsql
clusterIP: None
selector:
env: prod
domain: infrastructure
---
apiVersion: v1
data:
password: ZGF2ZQ==
kind: Secret
metadata:
name: postgres-secret
---
apiVersion: v1
data:
db: tmp
user: dave
kind: ConfigMap
metadata:
name: postgres-config
---
J'ai déployé ceci en utilisant:
kubectl apply -f postgres.yaml
J'ai testé pour me connecter au pod postgres-0 pour connecter ma base de données avec les informations d'identification $POSTGRES_USER et $POSTGRES_PASSWORD :
❯ k exec -it pod/postgres-0 -- bash
bash-5.1$ psql --username=$POSTGRES_USER -W --host=localhost --port=5432 --dbname=tmp
Password:
psql (13.6)
Type "help" for help.
tmp=#
J'ai listé les bases de données:
tmp=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-------+----------+------------+------------+-------------------
postgres | dave | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | dave | UTF8 | en_US.utf8 | en_US.utf8 | =c/dave +
| | | | | dave=CTc/dave
template1 | dave | UTF8 | en_US.utf8 | en_US.utf8 | =c/dave +
| | | | | dave=CTc/dave
tmp | dave | UTF8 | en_US.utf8 | en_US.utf8 |
(4 rows)
et je me suis connecté à la base de données "tmp":
tmp=# \c tmp
Password:
You are now connected to database "tmp" as user "dave".
réussi.
J'ai également essayé de connecter la base de données à l'aide de l'adresse IP, comme vous avez essayé :
bash-5.1$ ip a | grep /24
inet 10.244.4.8/24 brd 10.244.4.255 scope global eth0
bash-5.1$ psql --username=$POSTGRES_USER -W --host=10.244.4.8 --port=5432 --dbname=tmp
Password:
psql (13.6)
Type "help" for help.
tmp=#
réussi.
J'ai ensuite téléchargé dbeaver (d'ici https://dbeaver.io/download/ ) pour tester l'accès depuis l'extérieur de mon cluster :
avec un transfert de port kubectl :
kubectl port-forward statefulset/postgres 5432:5432
Forwarding from 127.0.0.1:5432 -> 5432
Forwarding from [::1]:5432 -> 5432
J'ai créé la connexion sur dbeaver et j'ai pu accéder facilement à la base de données "tmp" de localhost: 5361 avec dave: dave informations d'identification
kubectl port-forward statefulset/postgres 5432:5432
Forwarding from 127.0.0.1:5432 -> 5432
Forwarding from [::1]:5432 -> 5432
Handling connection for 5432
Handling connection for 5432
parfait.

idem qu'avant (avec dbeaver), j'ai essayé de connecter la db en utilisant un port forward, non pas du pod, mais du service:
❯ kubectl port-forward service/postgres-service 5432:5432
Forwarding from 127.0.0.1:5432 -> 5432
Forwarding from [::1]:5432 -> 5432
Handling connection for 5432
Handling connection for 5432
Ça a marché aussi!
J'ai également créé un pod autonome, basé sur notre config pour accéder à la db qui se trouve dans un autre pod (via le nom servine comme nom d'hôte), voici le manifeste du pod:
apiVersion: v1
kind: Pod
metadata:
name: postgres
labels:
app: test
spec:
terminationGracePeriodSeconds: 20
securityContext:
runAsUser: 70
fsGroup: 70
containers:
- name: kubia-postgres
image: postgres:13-alpine
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
- name: POSTGRES_USER
valueFrom:
configMapKeyRef:
name: postgres-config
key: user
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
name: postgres-config
key: db
ports:
- containerPort: 5432
protocol: TCP
volumeMounts:
- name: postgres-test-volume
mountPath: /var/lib/postgresql
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
volumes:
- name: postgres-test-volume
emptyDir: {}
voici le résultat de la connexion depuis l'intérieur du podtest:
bash-5.1$ psql --username=$POSTGRES_USER -W --host=postgres-service --port=5432 --dbname=tmp
Password:
psql (13.6)
Type "help" for help.
tmp=#
- Voici comment vous pouvez y accéder depuis l'extérieur du pod/espace de noms (assurez-vous qu'aucune règle réseau ne bloque la connexion) :
StatefulSetName-Ordinal.Service.Namespace.svc.cluster.local
i.e: postgres-0.postgres-service.so-tests.svc.cluster.local
- Pour accéder aux charges de travail statefulsets depuis l'extérieur du cluster, voici un bon début : Comment exposer un service sans tête pour un StatefulSet en externe dans Kubernetes
J'espère que cela vous aidera. Merci pour votre question. Devinez