k8s-Service
k8s-Service
一 service概念
Kubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略 —— 通常称为微
服务。 这一组 Pod 能够被 Service 访问到,通常是通过 Label Selecto
Service能够提供负载均衡的能力,但是在使用上有以下限制:
只提供 4 层负载均衡能力,而没有 7 层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层
负载均衡是不支持的
二 servce类型
Service 在 K8s 中有以下四种类型
-
ClusterIp:默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟 IP
-
NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 : NodePort 来访问该服务
-
LoadBalancer:在 NodePort 的基础上,借助 cloud provider(云供应商,收费的) 创建一个外部负载均衡器,并将请求转发到: NodePort
-
ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 kubernetes 1.7 或更高版本的 kube-dns 才支持
2.1 clusterip
2.1.1 概念
clusterIP 主要在每个 node 节点使用 iptables,将发向 clusterIP 对应端口的数据,转发到 kube-proxy 中。然后 kube-proxy 自己内部实现有负载均衡的方法,并可以查询到这个 service 下对应 pod 的地址和端口,进而把数据转发给对应的 pod 的地址和端口
大致架构:
svc如何和后端pod通信,是通过后端pod的标签等信息
2.2.2 实例
创建三个pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: stabel
template:
metadata:
labels:
app: myapp
release: stabel
env: test
spec:
containers:
- name: myapp
image: wangyanglinux/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
开启svc clusterip
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: ClusterIP
selector:
app: myapp
release: stabel
ports:
- name: http
port: 80
targetPort: 80
查看cluseterip
[root@k8s-master01 yaml]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7h8m
myapp ClusterIP 10.99.48.182 <none> 80/TCP 8m14s
访问 10.99.48.182 下面绑定了三个pod的ip
2.2.3 无头服务(headless service)
headless service也属于clausterip的一种,不会分配clusterip,也不会进行负载和路由
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
selector:
app: nginx
clusterIP: "None"
ports:
- port: 80
targetPort: 80
2.2 nodeport
nodePort 的原理在于在 node 上开了一个端口,将向该端口的流量导入到 kube-proxy,然后由 kube-proxy 进一步到给对应的 pod
实例:
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: NodePort
selector:
app: myapp
release: stabel
ports:
- name: http
port: 80
targetPort: 80
2.3 ExternalName
这种类型的 Service 通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容( 例如:
hub.atguigu.com )。ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何的端口和
Endpoint。相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务
实例;
apiVersion: v1
kind: Service
metadata:
name: myapp-headless
namespace: default
spec:
selector:
app: myapp
clusterIP: "None"
ports:
- port: 80
targetPort: 80
查看:
验证:
dig -t A my-service-1.default.svc.cluster.local. @10.244.2.9
dig -t A my-service-1.default.svc.cluster.local. @10.244.2.9
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> -t A my-service-1.default.svc.cluster.local. @10.244.2.9
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36528
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;my-service-1.default.svc.cluster.local. IN A
;; ANSWER SECTION:
my-service-1.default.svc.cluster.local. 30 IN CNAME hub.atguigu.com.
;; Query time: 36 msec
;; SERVER: 10.244.2.9#53(10.244.2.9)
;; WHEN: 二 3月 17 21:13:47 CST 2020
;; MSG SIZE rcvd: 134
三 注意
svc必须和pod在同一个命名空间里面,否则不会自动绑定