服务定义
服务注册与发现
- ClusterIP:默认类型,自动分配一个仅
Cluster 内部可以访问的虚拟IP 。 - NodePort:在
ClusterIP 基础上为Service 在每台机器上绑定一个端口,这样就可以通过<NodeIP>:NodePort
来访问该服务。 - LoadBalancer:在
NodePort 的基础上,借助Cloud Provider 创建一个外部的负载均衡器,并将请求转发到<NodeIP>:NodePort
。 - ExternalName:通过返回
CNAME 和它的值,可以将服务映射到externalName 字段的内容(例如,foo.bar.example.com) 。没有任何类型代理被创建,这只有Kubernetes 1.7 或更高版本的kube-dns 才支持。
Service 定义
一个
kind: Service
apiVersion: v1
metadata:
name: hostname-service
spec:
# Expose the service on a static port on each node
# so that we can access the service from outside the cluster
type: NodePort
# When the node receives a request on the static port (30163)
# "select pods with the label 'app' set to 'echo-hostname'"
# and forward the request to one of them
selector:
app: echo-hostname
ports:
# Three types of ports for a service
# nodePort - a static port assigned on each the node
# port - port exposed internally in the cluster
# targetPort - the container port to send requests to
- nodePort: 30163
port: 8080
targetPort: 80
这里需要对于
port 表示Service 暴露在Cluster IP 上的端口,<cluster ip>:port
是提供给集群内部客户访问Service 的入口。nodePort 是K8s 提供给集群外部客户访问Service 入口的一种方式(另一种方式是LoadBalancer ) ,所以,<nodeIP>:nodePort
是提供给集群外部客户访问Service 的入口。targetPort 是Pod 上的端口,从port 和nodePort 上到来的数据最终经过kube-proxy 流入到后端Pod 的targetPort 上进入容器。
总的来说,
多端口Service
很多
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9377
应用选择
NodePort 类型
如果设置spec.ports[*].nodePort
字段被指定。如果需要指定的端口号,可以配置spec.ports[*].nodePort
和 spec.clusterIp:spec.ports[*].port
而对外可见。
运行以下命令,使用
$ kubectl expose pods nginx --type=NodePort --port=80
service/nginx exposed
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29m
nginx NodePort 10.101.42.230 <none> 80:31858/TCP 5s
$ kubectl delete svc nginx
service "nginx" deleted
现在我们要创建一个
vim primeiro-service-nodeport.yaml
apiVersion : v1
kind : Service
metadata :
labels :
run : nginx
name : nginx-nodeport
namespace : default
spec :
externalTrafficPolicy : Cluster
ports :
- nodePort : 31111
port : 80
protocol : TCP
targetPort : 80
selector :
run : nginx
sessionAffinity : None
type : NodePort
然后创建服务:
$ kubectl create -f primeiro-service-nodeport.yaml
service/nginx-nodeport created
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30m
nginx-nodeport NodePort 10.102.91.81 <none> 80:31111/TCP 7s
$ kubectl describe service nginx
Name: nginx-nodeport
Namespace: default
Labels: run=nginx
Annotations: <none>
Selector: run=nginx
Type: NodePort
IP: 10.102.91.81
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 31111/TCP
Endpoints: 10.46.0.1:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
$ kubectl delete -f primeiro-service-nodeport.yaml
service "nginx-nodeport" deleted
LoadBalancer 类型
使用支持外部负载均衡器的云提供商的服务,设置
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
nodePort: 30061
clusterIP: 10.0.171.239
loadBalancerIP: 78.11.24.19
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 146.148.47.155
来自外部负载均衡器的流量将直接打到后端
其他类型的服务后端
- 希望在生产环境中使用外部的数据库集群,但测试环境使用自己的数据库。
- 希望服务指向另一个
Namespace 中或其它集群中的服务。 - 正在将工作负载转移到
Kubernetes 集群,和运行在Kubernetes 集群之外的后端。
在任何这些场景中,都能够定义没有
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
由于这个
kind: Endpoints
apiVersion: v1
metadata:
name: my-service
subsets:
- addresses:
- ip: 1.2.3.4
ports:
- port: 9376
注意,
kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
当查询主机