本文主要是以实例来说明:
如下所示为一个提供web 服务的Pod 集合,由两个Tomcat 容器副本组成,每个容器提供的服务端口号都为8080:
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: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
创建该Deployment:
[root@k8s-master ~]# kubectl create -f webapp-deployment.yaml
deployment.apps/webapp created
查看每个Pod 的IP地址:
[root@k8s-master ~]# kubectl get pods -l app=webapp -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
webapp-8554f77548-cbs6r 1/1 Running 0 99s 10.244.140.119 k8s-node-2 <none> <none>
webapp-8554f77548-mvn89 1/1 Running 0 99s 10.244.109.119 k8s-node-1 <none> <none>
客户端应用可以通过这两个Pod的IP 地址和端口号8080 访问web服务:
[root@k8s-master ~]# curl 10.244.140.119:8080
<!DOCTYPE html>
<html lang="en">
....
[root@k8s-master ~]# curl 10.244.140.119:8080
<!DOCTYPE html>
<html lang="en">
.....
但是呢,提供服务的容器应用通常是分布式的,通过多个Pod 副本共同提供服务。而Pod 副本的数量动态变化(例如执行了水平缩容),单个PO的的IP 地址也可能发生变化(例如故障恢复)。
应对如上变化我们可以采用Servcie 动态监控Pod 副本的各个变化。
创建一个Service:
[root@k8s-master ~]# kubectl expose deployment webapp
service/webapp exposed
查看新创建的Service ,可以看到系统为它分配了一个虚拟IP地址(ClusterIP 地址),Service 的端口号则从Pod中的containerPort 复制而来:
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
webapp ClusterIP 10.1.183.185 <none> 8080/TCP 104s
接下来就可以童工Service 的IP 地址和Service 的端口号访问该Service 了:
[root@k8s-master ~]# curl 10.1.183.185:8080
<!DOCTYPE html>
<html lang="en">
.....
客户端应用对Service地址10.1.183.185:8080的访问被自动负载分发到了后端两个Pod之一:10.244.140.119:8080或10.244.140.119:8080。
当然除了以上创建Service,还可以使用yaml 文件创建Service:
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
selector:
app: webapp
ports:
- protocol: TCP
port: 8080
targetPort: 8080
使用创建命令,出现如下现象:
[root@k8s-master ~]# kubectl create -f webapp-service.yaml
Error from server (AlreadyExists): error when creating "webapp-service.yaml": services "webapp" already exists
就说明你已经创建成功了,但是得先删除它 才能再次创建。
也可以使用如下命令查看有哪些service 正在运行:
[root@k8s-master ~]# kubectl get svc -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
webapp ClusterIP 10.1.183.185 <none> 8080/TCP 15m
上面也可以看到我的webapp service 已经创建成功了,可以使用如下命令删除:
[root@k8s-master ~]# kubectl delete svc webapp -n default
service "webapp" deleted
创建:
[root@k8s-master ~]# kubectl create -f webapp-service.yaml
service/webapp created
查看:
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
webapp ClusterIP 10.1.50.201 <none> 8080/TCP 5m5s
访问:
[root@k8s-master ~]# curl 10.1.50.201:8080
<!DOCTYPE html>
<html lang="en">
....
在提供服务的Pod的副本运行过程中,如果Pod发生变化,则kubernetes 的service 控制器会 持续监控后端pod 列表的变化,实时更新service 对应的后端pod 列表。
一个service 对应的后端 由pod 的ip 和容器端口号组成,即一个完整的IP:port访问地址,这在Kubernetes 系统中叫做Endpoint 。通过查看service 的详细信息,可以看到其后端endpoint 列表:
[root@k8s-master ~]# kubectl describe svc webapp
Name: webapp
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=webapp
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.1.50.201
IPs: 10.1.50.201
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
Endpoints: 10.244.109.119:8080,10.244.140.119:8080
Session Affinity: None
Events: <none>
实际上,可以使用如下命令查看EndPoint 对象:
[root@k8s-master ~]# kubectl get endpoints
NAME ENDPOINTS AGE
webapp 10.244.109.119:8080,10.244.140.119:8080 11m
后面的内容更精彩哦。