service的好处:
pod的地址是不可靠的,某个pod失效之后,它会被别的pod取代,新的pod拥有新的ip地址。service都拥有一个固定的cluster ip地址,固定的dns名称以及固定的端口。service还具有一定的负载均衡能力,将访问的流量分流到多个pod上。service也是通过提交yaml文件来部署最好,当然也可以通过提交命令式的操作来部署,但是并不推荐,因为不好维护。
编写svc.yaml文件:
apiVersion: v1
kind: Service
metadata:
name: hello-svc
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30025
targetPort: 8080
protocol: TCP
selector:
app: hello-world
metadata.name:定义service的名字
spec以下定义service相关内容:
type:定义service类型。k8s有3个常用service类型。clusterip:这是集群内部的ip地址,只能在集群内部通信。NodePort:可以让集群从外部访问,利用节点ip和端口就能访问。LoadBalancer:大部分只适用于支持外部负载均衡器的云提供商。
port:service针对内部请求监听的端口。
nodePort:针对外部请求的监听端口。
targetPort:pod应用的端口
selector:选择器,service和pod关联起来的重点。这里会筛选出pod标签为hello-world。
关于我的deployment的配置,关联起来看更容易懂:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hello-deploy
spec:
replicas: 10
selector:
matchLabels:
app: hello-world #这里定义的app: hello-world就和service selector对应,会被筛选出来
minReadySeconds: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-pod
image: nigelpoulton/k8sbook:edge
ports:
- containerPort: 8080 #这里和service的targetport对应
svc.yaml配置就是在集群中暴露了30025这个端口,我们可以通过集群中任何一个节点的ip和30025端口访问到这个应用。
也可以查看下节点上的端口:
查看该service相关信息:
可以看到Cluster ip默认是每个service都会有的。NodePort是在cluster ip的基础上增加了一个外部访问ip。
也可以查看hello-svc的详细信息,里面包含pod信息:
Endpoints:是pod的地址。随着pod的变化更新和随容,service会动态更新健康pod列表。具体来说就是通过Label筛选器和endpoint共同完成。每个service在被创建的时候,都会有一个endpoint对象,它就是一个动态的列表,里面是匹配到的pod信息。有新的就会加入,旧的就会删除。
众所周知,对应用的更新是运维的常态:修复bug,新增功能,性能提升等。比如我们需要上新的应用,但是不能停止服务,这时也能用service。原理就是利用标签选择器匹配到新的pod,endpoint会在线更新匹配到pod。
加入上面我们部署的版本4.1,现在有更改需要部署4.2版本。
4.2版本,我们给新的版本创建deployment:
deploy2.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hello-deploy2
spec:
replicas: 10
selector:
matchLabels:
app: hello-world
version: v4.2
minReadySeconds: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0
template:
metadata:
labels:
app: hello-world
version: v4.2
spec:
containers:
- name: hello-pod
image: nigelpoulton/k8sbook:latest
ports:
- containerPort: 8080
上面只是增加了一个标签4.2版本,让servcie匹配到它。
更改service:
svc.yaml
apiVersion: v1
kind: Service
metadata:
name: hello-svc
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30025
targetPort: 8080
protocol: TCP
selector:
app: hello-world
version: v4.2 #只增加了这一行