Service:
在kubernetes中,需要每个pod都有ip地址,但是其ip会随着 pod的启停而改变,但我们怎么才能稳定的访问其pod提供的服务呢,kubernetes
设计了Service,其目的是为了让用户能够通过访问Service 来 稳定访问 pod
一个Service作用了哪些pod是通过Label Selector来定义的
在pod正常启动后,系统将会根据Service的定义创建出与pod对应的Endpoint(端点)对象,以建立起Service与后端Pod的对应关系,随着pod的创建,销毁,
Endpoint对象也将被更新。Endpoint对象主要由Pod的IP 地址和容器需要监听的端口号组成,通过 kebectl get endpoints命令可以查看,显示为IP:Port 的格式
在kubernetes中,Service是分布式集群架构的核心,一个Service对象拥有如下关键特征
1 拥有一个唯一指定的名字
2 拥有一个虚拟IP(cluster ip,service ip 和 vip) 和 端口号
3 能够提供某种远程服务能力
4 被映射到了提供这种服务能力的一组容器应用上
Service的服务进程目前都基于socket通信方式对外提供服务,比如redis,memcache,mysql, web server,或者是实现了某个具体业务的一个特定的tcp server 进程。通常一个服务,可能会依赖很多服务,但kubernetes能够让我们通过service 连接 指定的service上。
kubernetes有很好的故障恢复机制,当服务以外停止时,kubernetes 会重启他们
kubernetes通过kube-proxy进程可以简单实现服务间的 服务均衡
这些操作都是kubernetes自动化完成,对于用户来说都是透明的
kind: Service
apiVersion: v1
metadata:
name: jxc-service
spec:
selector:
app: jxc-web
ports:
- protocol: TCP
port: 80
targetPort: 8080
创建Service
[root@linux-node1 kubefile]# kubectl create -f jxc-service-1.yaml
查看 Service
[root@linux-node1 kubefile]# kubectl get service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
jxc-service 10.254.35.198 <none> 80/TCP 12s
kubernetes 10.254.0.1 <none> 443/TCP 10d
查看Service 的 yaml 定义文件
[root@linux-node1 kubefile]# kubectl get svc jxc-service -o yaml
上述配置将创建一个名词为 "jxc-service"的Service对象,它会将请求代理到 使用TCP端口8080 并且
使用具有标签"app=jxc-web"的pod上。这个Service将指派一个IP地址(通常为"cluster ip")。Service 能够将一个
接收端口映射到任意的targetPort。默认情况下,targetPort将被设置与port字段相同的值。kubernetes Service
能够支持TCP 和 UDP协议,默认是TCP协议
2 外部访问 Service
[root@linux-node1 kubefile]# vim jxc-service.yaml
apiVersion: v1
kind: Service
metadata:
name: jxc
labels:
name: jxc
spec:
type: NodePort
ports:
- port: 80
nodePort: 30001
selector:
name: jxc
上述 演示的 是一个 外部 访问Service
如果 这个Service 作为前端服务,我们就需要 让该 Service 能 让 外网访问到
我们可以通过 NodePort 为 该Service 打开一个 主机上的真实端口号
3 没有 selector 的 Service
Service 抽象了如何访问kubernetes pod,但也能够 抽象其它 类型的backend
例如:
1 希望 在生产环境中使用外部的数据库集群
2 希望服务指向 另一个Namespace 中或其他集群中的服务
3 正在将工作负载同时转移到kubernetes集群和运行在kubernetes 集群之外的backend
3 多端口 Service
kind: Service
apiVersion: v1
metadata:
name: jxc-service
spec:
selector:
app: jxc-web
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9337
很多Service 需要暴露 多个端口。对于这种情况,kubernetes 支持 在Service 对象中 定义 多个端口。当使用多个端口时,必须给出所有 的端口名称
,这样 endpoint 就不会产生歧义
Volume(存储卷)
volume 是pod中能够被多个容器访问的共享目录。kubernetes的volume概念与docker的volume比较类似,但并不完全相同。kubernetes中的
volume 与pod生命周期相同,但与容器的生命周期不相关。当容器终止或者重启时,volume的数据也不会丢失。
默认情况下容器中的磁盘文件是非持久化的,对于运行在容器中的应用来说 面临两个问题,
第一: 当容器挂掉 kubectl 将重新启动它时,文件将会丢失;
第二: 当pod中同时运行多个容器,容器之间需要共享文件时。
kubernetes 的 volume 解决了这两个问题。
kubernetes volume 具有 明确的生命周期。与pod相同。因此。volume 的生命周期比pod中运行的任何容器要 持久化,在容器重新启动时能可以保留数据,当然,当pod被删除时,volume 也随着 消失
(1) hostPath 类型
hostPath 允许挂载 Node上的文件系统到 pod里面去。如果pod需要使用Node上的文件,可以使用 hostPath.
通常有以下两种 使用场景:
a 容器应用程序生成的日志文件需要永久保存时,可以使用 宿主机的文件系统进行存储
b 需要访问宿主机上docker 引擎内部数据结构的容器应用时,可以通过定义hostPath 为宿主机 /var/lib/docker目录,使容器内部应用
可以直接访问docker的文件系统
使用 hostPath 的注意事项:
a 在不同的Node上具有相同配置的pod,可能会因为 宿主机上的目录 和文件 不同而 导致对volume 上目录和文件的访问 结果不一致
b 如果使用了资源配额管理,则 k8s 无法将hostPath在宿主机上 使用的资源纳入管理
使用案例
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jxc-deployment
labels:
web: jxc
spec:
replicas: 1
selector:
matchLabels:
web: jxc
template:
metadata:
labels:
web: jxc
spec:
containers:
- name: jxc
image: 192.168.255.128:5000/jxc:0.0.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /data
将 , 宿主机的 /data 被挂载到容器的 /test-pd
(2) NFS
kubernetes 中通过简单地配置 就可以挂载到NFS到Pod中,而NFS中的数据时可以永久保存的,同时NFS支持同时写操作。
pod被删除时,volume 被卸载,内容被保留。这就意味这NFS能够允许我们提前对数据进行处理,而且这些数据可以在pod
之间相互传递
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jxc-deployment
labels:
web: jxc
spec:
replicas: 1
selector:
matchLabels:
web: jxc
template:
metadata:
labels:
web: jxc
spec:
containers:
- name: jxc
image: 192.168.255.128:5000/jxc:0.0.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
volumeMounts:
- name: nfs
mountPath: "/usr/share/"
volumes:
- name: nfs
nfs:
server: nfs-server.localhost #nfs 服务器地址
path: "/"
Label (标签), Label Selector(选择器)
Label 是 kubernetes 系统中的一个核心概念。Label 以 key/value 键值对的形式附加到各种对象上。如pod,Service,RC,Node等。Label定义了这些对象的
可识别属性,用来对他们进行管理和选择。Label可以在创建对象时附加在对象上,也可以在对象创建后通过API进行管理
在为对象定义好Label后,其他对象就可以使用 Label Selector (选择器) 来定义其作用的对象了
Label Selector 的定义 由多个逗号分隔的条件组成
"labels" : {
"key1" : "value1",
"key2" : "value2"
}
一般来说,我们会 给 一个 Pod 定义多个Labels,以便于配置,部署等管理工作。
"environment" : "dev","environment" : "qa","environment" : "production"
"tier" : "frontend","tier" : "backend","tier" : "cache"
当前有两种Label Selector :
基于等式的(equality-based) 和 基于 集合的 (Set-based)
基于等式 的 示例:
name = redis-slave
env != production
基于集合的 示例 :
name in (redis-master,redis-salve)
name not in (frontend)
Label Selector 的几个重要使用场景:
- kube-controller进程,通过资源对象RC上定义的Label Selector 来筛选 和 管理 的 Pod 副本的数量
- kebe-proxy 进程,通过Service 的 Label Selector 来选择对应的Pod,建立起每个 Service 到对应Pod的
请求转发路由表,进而实现Service 的智能负载均衡机制
- kube-scheduler 进程,通过为某些Node定义特定的Label,然后在Pod 定义文件中使用NodeSelector 进行筛选,
进而实现Pod 的定向 调度功能