Minikube 使用host.minikube.internal访问宿主机
如果使用Minikube搭建的本地K8s集群,那么事情变得很容易,因为MiniKube默认提供了映射外部主机网络的hostname:host.minikube.internal.使用这个hostname即可访问宿主机上的所有服务了。例如MySQL服务,使用如下url即可:jdbc:mysql://host.minikube.internal:3306/
minikube ssh进入虚拟机,查看hosts文件。
$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 minikube
172.20.32.1 host.minikube.internal
172.20.34.234 control-plane.minikube.internal
使用Service Endpoints映射外部IP
Endpoints 是实现实际服务的端点的集合
集群内部应用通过Service互相访问,Service通过Selector选择带有相同标签的Pod。这些选择的Pod就是Service的Endpoints。如果未设置 selector,则需要通过手动构造 Endpoints 或 EndpointSlice 的对象来确定。
我们这个场景显然不是通过Selector来选择Pod,而是使用无头服务自定义Endpoints访问外部IP地址。
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
spec:
clusterIP: None
ports:
- port: 3306
targetPort: 3306
protocol: TCP
---
kind: Endpoints
apiVersion: v1
metadata:
name: mysql-svc
subsets:
- addresses:
# 外部网络IP
- ip: 192.168.3.63
ports:
- port: 3306
使用Service externalName访问外部hostname
类型为 ExternalName 的服务将服务映射到 DNS 名称,而不是典型的选择算符。查找Service时,集群DNS返回CNAME记录,其值即为externalName指定的值。访问此类服务的方式与其他服务的方式相同,但主要区别在于重定向发生在 DNS 级别,而不是通过代理或转发。
由于 ExternalName使用 CNAME 重定向,因此无法执行端口重映射。
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
spec:
# minikube 可用 externalName:host.minikube.internal
externalName: mysql–instance1.123456789012.us-east-1.rds.amazonaws.com
type: ExternalName
Spring Boot访问外部MySQL示例
bootstrap.yaml
spring:
cloud:
kubernetes:
reload:
enabled: true
config:
name: extenal-mysql
secrets:
enabled: true
name: extenal-mysql
MySQL数据库用户名和密码从Secrets读取,其它配置从ConfigMap读取.
ConfigMap配置
metadata:
name: ${project.artifactId}
data:
application.properties: |-
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
spring.datasource.url = jdbc:mysql://mysql-svc:3306/ecp?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
Secrets配置
metadata:
name: ${project.artifactId}
data:
spring.datasource.username : cm9vdA==
spring.datasource.password : cm9vdA==
Secrets中的数据转换成环境变量。
spec:
template:
spec:
serviceAccount: ${project.artifactId}
containers:
- env:
- name: spring.datasource.username
valueFrom:
secretKeyRef:
name: ${project.artifactId}
key: spring.datasource.username
- name: spring.datasource.password
valueFrom:
secretKeyRef:
name: ${project.artifactId}
key: spring.datasource.password
这种方式缺点很明显,配置量大了将是一场灾难。此时可以选择使用envFrom来将某个Secrets中所有数据加载到容器环境中:
spec:
template:
spec:
serviceAccount: ${project.artifactId}
containers:
- envFrom:
- secretRef:
name: ${project.artifactId}
MySQL.yml
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
spec:
clusterIP: None
ports:
- port: 3306
targetPort: 3306
protocol: TCP
---
kind: Endpoints
apiVersion: v1
metadata:
name: mysql-svc
subsets:
- addresses:
# 外部网络IP
- ip: 192.168.3.63
ports:
- port: 3306