当前位置: 首页 > 知识库问答 >
问题:

k8s 如何使用 ClusterIP + ingress 从集群外部访问内部的 mysql?

施洛城
2023-12-04

我搭建了一个 minikube 环境

pod 和 service、ingress 的声明如下:

apiVersion: v1kind: PersistentVolumemetadata:  name: mysql-pvspec:  capacity:    storage: 1Gi  accessModes:    - ReadWriteOnce  hostPath:    path: "/data/mysql-data" # Change this path to your desired host path---apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: mysql-pv-claimspec:  accessModes:    - ReadWriteOnce  resources:    requests:      storage: 1Gi---apiVersion: apps/v1kind: Deploymentmetadata:  name: mysql8spec:  replicas: 1  selector:    matchLabels:      app: mysql8  template:    metadata:      labels:        app: mysql8    spec:      containers:        - name: mysql8          image: mysql:8.0.34          env:            - name: MYSQL_ROOT_PASSWORD              value: "123456"          ports:            - containerPort: 3306          volumeMounts:            - name: mysql-persistent-storage              mountPath: /var/lib/mysql            - name: custom-config              mountPath: /etc/mysql/conf.d          resources:            limits:              memory: "512Mi"              cpu: "500m"            requests:              memory: "256Mi"              cpu: "250m"      volumes:        - name: mysql-persistent-storage          persistentVolumeClaim:            claimName: mysql-pv-claim        - name: custom-config          configMap:            name: mysql-custom-config # Create a ConfigMap with your custom configuration---apiVersion: v1kind: Servicemetadata:  name: mysql8-servicespec:  selector:    app: mysql8  ports:    - protocol: TCP      port: 3306      targetPort: 3306  type: ClusterIP---apiVersion: networking.k8s.io/v1kind: Ingressmetadata:  name: mysql8-ingressspec:  rules:    - host: mysql.example.com      http:        paths:          - path: /            pathType: Prefix            backend:              service:                name: mysql8-service                port:                  number: 3306

然后应用他们

minikube kubectl -- apply -f application/stateful/mysql.yaml

查看 pod 状态正常

─➤  minikube kubectl get pods                                                                                                                                                                                                                           130 ↵NAME                            READY   STATUS    RESTARTS        AGEmysql8-5db94fb5d5-22nhc         1/1     Running   2 (3d16h ago)   53d

查看 services 状态正常

╰─➤  minikube kubectl get servicesNAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGEkubernetes             ClusterIP   10.96.0.1        <none>        443/TCP          53dmysql8-service         ClusterIP   10.110.118.91    <none>        3306/TCP         53d

查看 ingress 状态正常

─➤  minikube kubectl get ingress NAME             CLASS    HOSTS               ADDRESS   PORTS   AGEmysql8-ingress   <none>   mysql.example.com             80      33m

修改本地的 /etc/hosts

╰─➤  cat /etc/hosts                                                                                                                                                                                                                                        1 ↵127.0.0.1 localhost127.0.1.1 vobiler740# The following lines are desirable for IPv6 capable hosts::1     ip6-localhost ip6-loopbackfe00::0 ip6-localnetff00::0 ip6-mcastprefixff02::1 ip6-allnodesff02::2 ip6-allrouters192.168.49.2  mysql.example.com

我的 minikube 的 ip 就是 192.168.49.2

╭─pon@T4GPU ~/code/me/k8s-console  ‹master*› ╰─➤  minikube ip                  192.168.49.2

然后从宿主机访问, 但是连接失败

╰─➤  mycli -uroot -p123456 -hmysql.example.com -P3306(2003, "Can't connect to MySQL server on 'mysql.example.com' ([Errno 111] Connection refused)")

然后我把 ClusterIP 改成 NodePort 却可以

apiVersion: v1kind: PersistentVolumemetadata:  name: mysql-pvspec:  capacity:    storage: 1Gi  accessModes:    - ReadWriteOnce  hostPath:    path: "/data/mysql-data" # Change this path to your desired host path---apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: mysql-pv-claimspec:  accessModes:    - ReadWriteOnce  resources:    requests:      storage: 1Gi---apiVersion: apps/v1kind: Deploymentmetadata:  name: mysql8spec:  replicas: 1  selector:    matchLabels:      app: mysql8  template:    metadata:      labels:        app: mysql8    spec:      containers:        - name: mysql8          image: mysql:8.0.34          env:            - name: MYSQL_ROOT_PASSWORD              value: "123456"          ports:            - containerPort: 3306          volumeMounts:            - name: mysql-persistent-storage              mountPath: /var/lib/mysql            - name: custom-config              mountPath: /etc/mysql/conf.d          resources:            limits:              memory: "512Mi"              cpu: "500m"            requests:              memory: "256Mi"              cpu: "250m"      volumes:        - name: mysql-persistent-storage          persistentVolumeClaim:            claimName: mysql-pv-claim        - name: custom-config          configMap:            name: mysql-custom-config # Create a ConfigMap with your custom configuration---apiVersion: v1kind: Servicemetadata:  name: mysql8-servicespec:  selector:    app: mysql8  ports:    - protocol: TCP      port: 3306      targetPort: 3306      nodePort: 30001  type: NodePort---apiVersion: networking.k8s.io/v1kind: Ingressmetadata:  name: mysql8-ingressspec:  rules:    - host: mysql.example.com # 设置你想要的域名      http:        paths:          - path: /            pathType: Prefix            backend:              service:                name: mysql8-service # 这里填写你的 Service 名称                port:                  number: 3306 # 这里填写 Service 的端口号

然后应用

minikube kubectl -- apply -f application/stateful/mysql.yaml

再次从宿主机连接 mysql, 就成功了

─➤  mycli -uroot -p123456 -hmysql.example.com -P30001                                                                                                                                                                                                     1 ↵MySQL mycli 1.27.0Home: http://mycli.netBug tracker: https://github.com/dbcli/mycli/issuesThanks to the contributor - chainkiteMySQL root@mysql.example.com:(none)>

所以为什么呢?为什么 ClusterIP 不行,但是 NodePort 却可以呢?

共有1个答案

甄伟兆
2023-12-04

我看懂了,这样的,你使用Ingress其实已经是已经把80端口映射到3306了
( mysql.example.com:80 => mysql8-service:3306 ), 所以如果这样方案能行的话,正确的访问应该是 mycli -uroot -p123456 -hmysql.example.com -P80 (不过这样理论也也不能用,一个是http协议一个是tcp协议, Ingress实现tcp的转发是要额外配置的)

至于为什么NodePort可以使用, 因为你使用 NodePort 已经把 3306 的端口映射到宿主机的30001了,你使用 mycli -uroot -p123456 -hmysql.example.com -P30001 通过 ip 访问到数据库了,根本没有通过 Ingress 进行访问, 也就是 -hmysql.example.com 是把域名解析成 ip 也就是你宿主机 ip , mysql 客户端再通过 ip+端口 访问到数据库,不知道我说清楚了没

至于你想通过 Ingress 来转发tcp协议 我没玩过,不过可以参考一下这篇文章 https://blog.csdn.net/w851685279/article/details/115911686

 类似资料:
  • 问题内容: 是否可以从Java内部类中获取对它的引用? 即 问题答案: 您可以像这样访问外部类的实例:

  • 问题内容: 这不是直截了当的问题。在我的情况下,外部类变量和内部类setter方法的参数名称相同。喜欢: 现在,我无法初始化外部类实例变量p,因为它指示内部类。再次,我做不到它得到一个错误。现在如何分配外部p,同时将内部Class方法的参数命名为p? 问题答案: 这是您可以/应该这样做的方式:

  • 这不是直截了当的问题。在我的例子中,外部类变量和内部类setter方法的参数名称是相同的。比如: 现在我不能用初始化外部类实例变量p,因为它指示内部类。同样,我不能执行会出现错误。现在,我如何分配外部p,使内部类方法的参数与名称p相同?

  • 问题内容: 如何从内部类访问外部类? 我正在重写一种使它在不同线程上运行的方法。从内联线程中,我需要调用原始方法,但是当然只要调用就会变成无限递归。 具体来说,我在扩展BufferedReader: 这个地方给了我我找不到的NullPointerException。 谢谢。 问题答案: 像这样: 上面的测试在执行时显示:

  • 我有一个Kubernetes群集,它有一个主节点和两个其他节点: 它们中的每一个都在VirtualBox Ubuntu VM上运行,可从来宾计算机访问: 我部署了一个带有两个副本的nginx服务器,每个kubernetes-node-x有一个pod: 接下来,我将nginx部署的服务公开为节点端口,以便从集群外部访问它: 我可以直接使用节点IP访问节点中的每个pod 但是,我认为K8s提供了某种外

  • 我正在尝试访问库伯内特斯集群部署的Spring Boot微服务并尝试测试REST API。我在部署脚本中配置了节点端口方法。但是当我尝试使用Postman工具访问时,我只得到“无法获得任何响应”的响应。 我配置了服务。yaml脚本类似于以下结构, 我的部署。yaml如下所示:, 当我使用时,输出如下所示, 我正在尝试通过以下方式访问我部署的API, 更新 当我为我的部署运行命令时,我得到如下响应: