一、理论
service将多个pod整合为一个集群,service对外提供一个统一的IP地址。
kube proxy四种代理方式
UserSpace,已弃用,用户态转为内核态的过程消耗资源过大。
Iptables,kube proxy不转发,只维护iptables的规则。数据包通过iptables的规则转发,这种效率略低,当iptables的规则多的时候,读取规则相当于读取一张没有索引的表。
IpVs,kube proxy不转发,只维护iptables的规则,数据包通过iptables的规则转发,使用ipset来存储iptables的规则,可直接更新iptables规则。
KernelSpace,windows环境下的,这里不做介绍。
service的四种类型
Cluster IP(内部访问使用这个)
NodePort(让外部访问使用这个)
LoadBalancer(云环境的NodePort)
externalName(无头服务使用该类型)
无头服务是指服务没有入口地址(clusterIP),但是它有pod的地址,访问无头服务通过固定的服务名进行访问。
固定格式:无头服务名.命名空间.svc.cluster.local
二、实践
bash
-- Cluster IP(外网访问不了) --
1、编写web服务资源清单
[root@k8s-master ~]# vim webapp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 2
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nginx:1.7.9
ports:
- name: http
containerPort: 80
protocol: TCP
2、创建、查看pod
[root@k8s-master ~]# ku apply -f webapp-deployment.yaml
deployment.apps/webapp created
[root@k8s-master ~]# ku get pod
NAME READY STATUS RESTARTS AGE
webapp-84dc98755d-lp6st 1/1 Running 0 2m18s
webapp-84dc98755d-m6qfp 1/1 Running 0 2m18s
[root@k8s-master ~]# ku get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
webapp-84dc98755d-lp6st 1/1 Running 0 2m30s 10.244.85.196 k8s-node01 <none> <none>
webapp-84dc98755d-m6qfp 1/1 Running 0 2m30s 10.244.58.193 k8s-node02 <none> <none>
3、访问
[root@k8s-master ~]# curl -I 10.244.85.196
HTTP/1.1 200 OK
[root@k8s-master ~]# curl -I 10.244.58.193
HTTP/1.1 200 OK
浏览器无法访问。
4、创建service,使用expose方式
[root@k8s-master ~]# ku expose deployment webapp
service/webapp exposed
[root@k8s-master ~]# ku get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d22h
webapp ClusterIP 10.99.72.173 <none> 80/TCP 3s
[root@k8s-master ~]# curl -I 10.99.72.173
HTTP/1.1 200 OK
[root@k8s-master ~]# curl -I 10.99.72.173
HTTP/1.1 200 OK
浏览器无法访问。
5、使用资源清单方式创建service,编写service的资源清单
[root@k8s-master ~]# vim webapp-service.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- protocol: TCP
port: 80 # service的端口
targetPort: 80 # pod中容器的端口
selector:
app: webapp
6、创建service
[root@k8s-master ~]# ku create -f webapp-service.yaml
Error from server (AlreadyExists): error when creating "webapp-service.yaml": services "webapp" already exists
[root@k8s-master ~]# ku get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d23h
webapp ClusterIP 10.99.72.173 <none> 80/TCP 37m
[root@k8s-master ~]# ku delete svc webapp
service "webapp" deleted
[root@k8s-master ~]# ku create -f webapp-service.yaml
service/webapp created
[root@k8s-master ~]# ku get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d23h
webapp ClusterIP 10.106.101.137 <none> 80/TCP 50s
7、查看详细信息
[root@k8s-master ~]# ku describe svc webapp
Endpoints: 10.244.58.193:80,10.244.85.196:80
8、访问
[root@k8s-master ~]# curl -I 10.106.101.137
HTTP/1.1 200 OK
[root@k8s-master ~]# curl -I 10.106.101.137
HTTP/1.1 200 OK
-- NodePort(外部可访问) --
1、编写资源清单
[root@k8s-master ~]# vim webapp-svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
type: NodePort # 指定类型为NodePort
ports:
- port: 80 # service的端口
targetPort: 80 # pod中容器的端口
nodePort: 30008 # 节点端口
selector:
app: webapp
2、创建
[root@k8s-master ~]# ku apply -f webapp-svc-nodeport.yaml
service/webapp created
[root@k8s-master ~]# ku get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d23h
webapp NodePort 10.104.14.137 <none> 80:30008/TCP 3s
3、访问
内部客户端
[root@k8s-master ~]# curl -I 10.104.14.137
HTTP/1.1 200 OK
外部客户端
浏览器访问 http://192.168.10.101:30008/
http://192.168.10.102:30008/
http://192.168.10.103:30008/
-- LoadBalancer (外部可访问) --
1、编写资源清单
[root@k8s-master ~]# vim webapp-svc-loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: default
labels:
app: webapp
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: http # 未指定端口,端口随机分配。
protocol: TCP
name: http
selector:
app: webapp
2、创建
[root@k8s-master ~]# ku apply -f webapp-svc-loadbalancer.yaml
service/webapp created
[root@k8s-master ~]# ku get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d23h
webapp LoadBalancer 10.108.130.185 <pending> 80:31654/TCP 5s
31654就是随机分配的端口
3、访问
内部客户端
[root@k8s-master ~]# curl -I 10.108.130.185
HTTP/1.1 200 OK
外部客户端
http://192.168.10.101:31654/
http://192.168.10.102:31654/
http://192.168.10.103:31654/
更改service的类型及端口
[root@k8s-master ~]# ku edit svc webapp
type: LoadBalancer
nodePort: 31654
[root@k8s-master ~]# ku get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d23h
webapp LoadBalancer 10.108.130.185 <pending> 80:31654/TCP 5s
[root@k8s-master ~]# ku edit svc webapp
service/webapp edited
nodePort: 30000
[root@k8s-master ~]# ku get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d23h
webapp LoadBalancer 10.108.130.185 <pending> 80:30000/TCP 6m22s
[root@k8s-master ~]# ku edit svc webapp
type: NodePort
[root@k8s-master ~]# ku edit svc webapp
service/webapp edited
[root@k8s-master ~]# ku get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
webapp NodePort 10.108.130.185 <none> 80:30000/TCP 8m20s
[root@k8s-master ~]# ku edit svc webapp
type: ClusterIP
[root@k8s-master ~]# ku edit svc webapp
service/webapp edited
[root@k8s-master ~]# ku get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
webapp ClusterIP 10.108.130.185 <none> 80/TCP 9m6s
-- ExternalName(不同命名空间之间的pod通过域名互联) --
1、创建命名空间
[root@k8s-master ~]# ku create ns test01
namespace/test01 created
[root@k8s-master ~]# ku create ns test02
namespace/test02 created
2、创建pod
[root@k8s-master ~]# vim myapp01.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp01
namespace: test01
spec:
replicas: 1
selector: #标签选择器
matchLabels: #匹配的标签为
app: myapp01
release: canary
template:
metadata:
labels:
app: myapp01 #和上面的myapp要匹配
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http01
containerPort: 80
[root@k8s-master ~]# ku create -f myapp01.yaml
deployment.apps/myapp01 created
[root@k8s-master ~]# ku get pod -n test01
NAME READY STATUS RESTARTS AGE
myapp01-696c886d6b-b5pz2 1/1 Running 0 75s
[root@k8s-master ~]# vim myapp02.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp02
namespace: test02
spec:
replicas: 1
selector: #标签选择器
matchLabels: #匹配的标签为
app: myapp02
release: canary
template:
metadata:
labels:
app: myapp02 #和上面的myapp要匹配
release: canary
spec:
containers:
- name: myapp02
image: ikubernetes/myapp:v1
ports:
- name: http02
containerPort: 80
[root@k8s-master ~]# ku get pod -n test02
NAME READY STATUS RESTARTS AGE
myapp02-55ffcd5f64-22t52 1/1 Running 0 81s
3、创建service(本地的)
[root@k8s-master ~]# vim myapp-svc-headless01.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc01
namespace: test01
spec:
selector:
app: myapp01 #挑选的pod还是myapp01。一个pod可以有多个service
release: canary
clusterIP: None #None表示是无头service
ports:
- port: 39320 #service ip中的端口
targetPort: 80 #容器ip中的端口
[root@k8s-master ~]# ku create -f myapp-svc-headless01.yaml
service/myapp-svc01 created
[root@k8s-master ~]# ku get svc -n test01
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-svc01 ClusterIP None <none> 39320/TCP 7s
[root@k8s-master ~]# vim myapp-svc-headless02.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc02
namespace: test02
spec:
selector:
app: myapp02 #挑选的pod还是myapp。一个pod可以有多个service
release: canary
clusterIP: None #None表示是无头service
ports:
- port: 39320 #service ip中的端口
targetPort: 80 #容器ip中的端口
[root@k8s-master ~]# ku create -f myapp-svc-headless02.yaml
service/myapp-svc01 created
[root@k8s-master ~]# ku get svc -n test02
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-svc02 ClusterIP None <none> 39320/TCP 2m15s
4、创建service(让对方使用的)
[root@k8s-master ~]# vim myapp-svc-extername01.yaml
kind: Service
apiVersion: v1
metadata:
name: myapp-svcname02
namespace: test01
spec:
type: ExternalName
externalName: myapp-svc02.test02.svc.cluster.local
myapp-svc02是对方服务的名称
test02是对方的表空间
svc.cluster.local 是后缀格式,不能更改。
[root@k8s-master ~]# ku create -f myapp-svc-extername01.yaml
service/myapp-svcname02 created
[root@k8s-master ~]# vim myapp-svc-extername02.yaml
kind: Service
apiVersion: v1
metadata:
name: myapp-svcname01
namespace: test02
spec:
type: ExternalName
externalName: myapp-svc01.test01.svc.cluster.local
[root@k8s-master ~]# ku create -f myapp-svc-extername02.yaml
service/myapp-svcname01 created
5、访问测试
进入test01的pod
[root@k8s-master ~]# ku exec -it myapp01-696c886d6b-b5pz2 -n test01 -- /bin/sh
/ # nslookup myapp-svcname02
nslookup: can't resolve '(null)': Name does not resolve
Name: myapp-svcname02
Address 1: 10.244.85.197 10-244-85-197.myapp-svc02.test02.svc.cluster.local
/ # ping myapp-svcname02
PING myapp-svcname02 (10.244.85.197): 56 data bytes
64 bytes from 10.244.85.197: seq=0 ttl=62 time=2.172 ms
64 bytes from 10.244.85.197: seq=1 ttl=62 time=1.467 ms
^C
--- myapp-svcname02 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 1.467/1.819/2.172 ms
/ # ping 10.244.85.197
PING 10.244.85.197 (10.244.85.197): 56 data bytes
64 bytes from 10.244.85.197: seq=0 ttl=62 time=0.949 ms
64 bytes from 10.244.85.197: seq=1 ttl=62 time=0.760 ms
^C
--- 10.244.85.197 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.760/0.854/0.949 ms
进入test02的pod
[root@k8s-master ~]# ku exec -it myapp02-55ffcd5f64-22t52 -n test02 -- /bin/sh
/ # nslookup myapp-svcname01
nslookup: can't resolve '(null)': Name does not resolve
Name: myapp-svcname01
Address 1: 10.244.58.194 10-244-58-194.myapp-svc01.test01.svc.cluster.local
/ # ping myapp-svcname01
PING myapp-svcname01 (10.244.58.194): 56 data bytes
64 bytes from 10.244.58.194: seq=0 ttl=62 time=0.954 ms
64 bytes from 10.244.58.194: seq=1 ttl=62 time=1.092 ms
^C
--- myapp-svcname01 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.954/1.023/1.092 ms
/ # ping 10.244.58.194
PING 10.244.58.194 (10.244.58.194): 56 data bytes
64 bytes from 10.244.58.194: seq=0 ttl=62 time=0.969 ms
64 bytes from 10.244.58.194: seq=1 ttl=62 time=5.512 ms
64 bytes from 10.244.58.194: seq=2 ttl=62 time=5.082 ms
^C
--- 10.244.58.194 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.969/3.854/5.512 ms