Service
Kubernetes最重要的三个组成部分,Pod、Pod控制器和Service,Kubernetes的所有服务以Service的形式提供,为集群提供统一的服务访问节点。
Service的工作模式随着Kubernetes的版本迭代,共经历了三种模式:
- userspace: 1.1版本之前
- iptables: 1.10版本之前
- ipvs: 1.11版本之后,但是没有特殊指定,会降级到iptables
1
~]# vim /etc/sysconfig/kubelet
2
KUBE_PROXY_MODE=ipvs
3
~]# lsmod | grep ip_vs # 查看内核加载了ipvs模块
Service的类型分四种:
- ClusterIP: 默认ClusterIP,仅拥有集群内部通信
- NodePort: 可以被外部访问
- ExternalName: 把集群外部的服务引入到集群内部来访问,通过域名
- LoadBalancer: 云环境使用
ClusterIP
1 | apiVersion: v1 |
2 | kind: Service |
3 | metadata: |
4 | name: myapp |
5 | namespace: default |
6 | spec: |
7 | selector: |
8 | app: myapp |
9 | clusterIP: 10.97.97.97 # 不指定会自动分配 |
10 | type: ClusterIP |
11 | ports: |
12 | - port: 80 # svc的端口 |
13 | targetPort: 80 # pod上的端口 |
Kubernetes中的pod可以通过名称进行访问,默认域名搜索域namespace.svc.cluster.local,所以在pod中可以直接通过myapp就可以访问到Service上的服务。
NodePort
1 | apiVersion: v1 |
2 | kind: Service |
3 | metadata: |
4 | name: myapp-node |
5 | namespace: default |
6 | spec: |
7 | selector: |
8 | app: myapp |
9 | clusterIP: 10.99.99.99 |
10 | type: NodePort |
11 | ports: |
12 | - port: 80 |
13 | targetPort: 80 |
14 | nodePort: 30080 # 不指定,nodeport也会被自动分配 |
可以在任何节点上的访问30080就可以被外部网络访问,整个访问过程:
node:30080 -> svc:80 -> pod:80
会话粘性
1 | kubectl patch svc myapp-node -p '{"spec": {"sessionAffinity": "ClientIP"}}' # 默认none,根据源ip始终被分配到同一个pod上 |
Headless
在这其中有一种特殊的存在,无头服务headless。
1 | apiVersion: v1 |
2 | kind: Service |
3 | metadata: |
4 | name: myapp-headless |
5 | namespace: default |
6 | spec: |
7 | selector: |
8 | app: myapp |
9 | clusterIP: None |
10 | ports: |
11 | - port: 80 |
12 | targetPort: 80 |
区别
1 | ~]# dig -t A myapp.default.svc.cluster.local @10.96.0.10 |
2 | |
3 | ; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> -t A myapp.default.svc.cluster.local @10.96.0.10 |
4 | ;; global options: +cmd |
5 | ;; Got answer: |
6 | ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19112 |
7 | ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 |
8 | |
9 | ;; OPT PSEUDOSECTION: |
10 | ; EDNS: version: 0, flags:; udp: 4096 |
11 | ;; QUESTION SECTION: |
12 | ;myapp.default.svc.cluster.local. IN A |
13 | |
14 | ;; ANSWER SECTION: |
15 | myapp.default.svc.cluster.local. 5 IN A 10.97.97.97 |
16 | |
17 | ;; Query time: 2 msec |
18 | ;; SERVER: 10.96.0.10#53(10.96.0.10) |
19 | ;; WHEN: 一 9月 17 05:29:28 EDT 2018 |
20 | ;; MSG SIZE rcvd: 107 |
1 | ~]# dig -t A myapp-headless.default.svc.cluster.local @10.96.0.10 |
2 | |
3 | ; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> -t A myapp-headless.default.svc.cluster.local @10.96.0.10 |
4 | ;; global options: +cmd |
5 | ;; Got answer: |
6 | ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43678 |
7 | ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1 |
8 | |
9 | ;; OPT PSEUDOSECTION: |
10 | ; EDNS: version: 0, flags:; udp: 4096 |
11 | ;; QUESTION SECTION: |
12 | ;myapp-headless.default.svc.cluster.local. IN A |
13 | |
14 | ;; ANSWER SECTION: |
15 | myapp-headless.default.svc.cluster.local. 5 IN A 10.244.1.24 |
16 | myapp-headless.default.svc.cluster.local. 5 IN A 10.244.1.28 |
17 | myapp-headless.default.svc.cluster.local. 5 IN A 10.244.1.31 |
18 | myapp-headless.default.svc.cluster.local. 5 IN A 10.244.2.31 |
19 | |
20 | ;; Query time: 0 msec |
21 | ;; SERVER: 10.96.0.10#53(10.96.0.10) |
22 | ;; WHEN: 一 9月 17 05:30:52 EDT 2018 |
23 | ;; MSG SIZE rcvd: 293 |
可以很清楚的看到区别,无头service是直接pod与pod之间通信了。