Kubectl không thể connect đến database ở host machine

Chào mọi người, em hiện đang học kubernetes, chạy một service authentication trong kubernetes, service này connect tới postgres database ở host machine (docker). Nhưng em connect mãi không được, (hôm qua cũng ko connect được nhưng xóa ra xóa vô cái pods không hiểu sao một hồi lại connect đc, hôm nay start lại không đc) nhờ các anh (chị) xem qua giúp em ạ, em cảm ơn.

authentication.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: authentication-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: authentication-service
  template:
    metadata:
      labels:
        app: authentication-service
    spec:
      containers:
      - name: authentication-service
        image: ".../authentication-service:1.0.0"
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        env:
          - name: DSN
            value: "host=host.minikube.internal port=5432 user=postgres password=password dbname=users sslmode=disable timezone=UTC connect_timeout=5"
        ports:
          - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: authentication-service
spec:
  selector:
    app: authentication-service
  ports:
    - protocol: TCP
      name: main-port
      port: 80
      targetPort: 80

Thêm service vào kube:

kubectl apply -f authentication.yml 

Config postgres database:

version: '3'

services:

  postgres:
    image: 'postgres:14.2'
    ports:
      - "5432:5432"
    restart: always
    deploy:
      mode: replicated
      replicas: 1
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: users
    volumes:
      - ./db-data/postgres/:/var/lib/postgresql/data/

Start postgres:

docker-compose -f postgres.yml up -d

Đã khởi tạo database users và test connect thành công qua beekeeper trên window.
Còn service trong kube không thể connect:

kubectl logs authentication-service-....
>>
2022/06/02 09:20:24 failed to connect to `host=host.minikube.internal user=postgres database=users`: dial error (timeout: dial tcp 192.168.49.1:5432: i/o timeout)
2022/06/02 09:20:24 Can't connect to Postgres!
panic: Can't connect to Postgres!

Cậu đang dùng minikube phải không?
Về cơ bản, container trong minikube (thực ra là trong máy ảo) không nhìn được container được deploy ở docker trên local của cậu (vì cậu dùng windows, nên thực ra đây cũng là máy ảo :sweat:). Đó là lý do app của cậu không kết nối được tới DB.
kubectl là khái niệm khác không liên quan nha :smile:

Tớ thấy lạ là sao cậu không tạo deployment mới cho database của cậu nhỉ? :smile: Cậu có thể deploy database lên pod mới cùng với service riêng, rồi connect từ pod chứa app sang pod đó.

5 Likes

Vâng, đúng r anh.

Theo như em hiểu thì nó có thể connect ra container thông qua host.minikube.internal. Em thấy mentor hướng dẫn làm được á.
Lý do em không deploy cho cho database vì ổng khuyên là database thì nên dùng service riêng của database để deploy chứ không nên gộp vào một cluster trong kube, nên mới tạo một container để mô phỏng trường hợp như vậy.
Em cũng có hỏi ông mentor là gặp vấn đề như thế, mentor trả lời:

Everything looks good in the repo; this is weird. One other thing you can check: on your Windows machine, is your service bound to all IPs? This is from the Minikube documentation (https://minikube.sigs.k8s.io/docs/handbook/host-access/#hostminikubeinternal):

The service running on your host must either be bound to all IP’s (0.0.0.0) and interfaces, or to the IP and interface your VM is bridged against. If the service is bound only to localhost (127.0.0.1), this will not work.

host.minikube.internal

Also, and this might sound stupid, but have you tried rebooting your machine and running the code again?

Em có thử chạy:

minikube ssh
nc -vz host.minikube.internal 5432

nhưng response:

nc: connect to host.minikube.internal port 5432 (tcp) failed: Connection timed out

Hiện em vẫn chưa biết phải làm sao hết, :sweat_smile: :sweat_smile:

Lý do em không deploy cho cho database vì ổng khuyên là database thì nên dùng service riêng của database để deploy chứ không nên gộp vào một cluster trong kube, nên mới tạo một container để mô phỏng trường hợp như vậy.

Ổng khuyên đúng đó. Thực tế database thường, hoặc được deploy trên stateful set ở k8s (do cậu cần giữ trạng thái của DB), hoặc được deploy ở một nơi nào khác ngoài network của k8s và cậu gọi tới đó.
Việc cậu deploy DB ra ngoài network của minikube có thể mô phỏng TH này, cơ mà cậu cần có setup network policy của pod, và network giữa docker và minikube phù hợp.

Về network policy trong pod, cậu cần khai báo egress để service có thể access được vào database bên ngoài (trong TH của cậu, cậu dùng host.minikube.internal như là địa chỉ để app nhìn ra bên ngoài minikube - mặc dù tớ không nghĩ DNS phân giải được domain name đó trong container của cậu đâu. Xem cuộc thảo luận này để hiểu thêm). Cậu có thể thử dùng ConfigMap và khai báo địa chỉ đó, rồi dùng alias từ config map ở app của cậu, vì theo logic, DNS nên resolve được domain name kia ở ngoài container.

Cậu cũng cần config network giữa docker container và minikube. Việc bound docker container với 0.0.0.0 là cách hack đơn giản nhất để làm việc đó (về cơ bản, lắng nghe ở 0.0.0.0 có nghĩa là lắng nghe từ mọi IP ở local machine). Cậu nên inspect để xem cậu có đang bound docker container với địa chỉ đó không nhé! :smile:

Hope it helps!

2 Likes


Cho em hỏi là có phải cái 127.0.0.1 trên hình cần phải chuyển về 0.0.0.0 phải không ạ. :sweat_smile:

Tớ nghĩ là không đâu cậu @No_name01
Cơ mà nếu cậu vẫn không kết nối được, cậu có thể thử :smile:

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?