系列
在使用k8s
过程中,个人总结了一些个人认为的最佳实践,分享出来,供大家参考
概述
我们的服务经常需要请求第三方服务,如各种sdk,还包括 Redis
、数据库
等
我们的开发环境和生产环境可能用的还不一样,
在Java
里一般做法是,把不同的信息配置到 application-dev.yaml
和 application-prod.yaml
里
但是思考一个场景:
当服务非常多之后,万一这些服务的host
变了(我能想到的场景有:数据库迁移,更换服务提供商,服务提供商更换域名等)(场景不多,此实践价值需要自行斟酌),那么要改的地方就很多了,所以我们在使用之初就可以借助 k8s
的 service
来避免这些问题
Service
k8s 的 Service
一般会配置一个选择器(selector
),去选择提供服务的一组 pod
但是也可以不使用选择器,直接指定 ip
、 域名(host)
等
注意:当 Service
不用选择器的时候,默认指向 同名 Endpoints
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: 192.0.2.42
ports:
- port: 9376
假设你在 dev
和 prod
都搭建了 redis
, 他们在不同集群的 ip 一般不一样
这时候你就需要到配置文件去配置了,比较繁琐,这时候,借助 Endpoints
可以屏蔽各种环境的差异
Endpoints
我们公司的 redis
和 mongodb
都是买的阿里云的,阿里提供的是 域名
所以仅仅配置 ip
满足不了我们的需求(使用ping
得到ip,然后再去配ip
的方案是行不通的,谁知道这个域名对应的ip
会不会变)
在网上找了一圈没有得到 Endpoints 是否支持 host
这个问题的答案
最后去github
翻了翻源码,得到了答案:支持
首先看下源码
源码
注意:行号可能会变,搜索 Endpoints
即可
看下结构定义
type Endpoints struct {
metav1.TypeMeta
// +optional
metav1.ObjectMeta
// The set of all endpoints is the union of all subsets.
Subsets []EndpointSubset
}
type EndpointSubset struct {
Addresses []EndpointAddress
NotReadyAddresses []EndpointAddress
Ports []EndpointPort
}
// EndpointAddress is a tuple that describes single IP address.
type EndpointAddress struct {
// The IP of this endpoint.
// IPv6 is also accepted but not fully supported on all platforms. Also, certain
// kubernetes components, like kube-proxy, are not IPv6 ready.
// TODO: This should allow hostname or IP, see #4447.
IP string
// Optional: Hostname of this endpoint
// Meant to be used by DNS servers etc.
// +optional
Hostname string
// Optional: Node hosting this endpoint. This can be used to determine endpoints local to a node.
// +optional
NodeName *string
// Optional: The kubernetes object related to the entry point.
TargetRef *ObjectReference
}
我们可以看到 对于 ip
字段的注释是
// TODO: This should allow hostname or IP, see #4447.
IP string
所以这个字段既可以写ip
, 也可以填 域名(host)
hostname
貌似是规划给 DNS 服务器
用的
2019年12月25日 10:53:22 更新
ip
字段只能使用 ip
, 虽然注释写着应该支持host
,但是其实没有支持(k8s版本 1.12.6)
详见 issue
但是可以使用 ExternalName
类型的 service, 见 doc
如
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
mongodb
对于mongodb
连接的时候一般会同时连上 Primary
和 Secondary
所以 最好是新建两个 Service
网友评论