如果分布式的应用之间有依赖关系,例如主从关系、主备关系或者数据存储类关系,那简单的Deployment的控制机制就无法保证,Deployment控制的Pod必须是stateless的
- 拓扑状态:应用实例必须按照某种顺序启动(主从节点)
- 存储状态:一个数据库应用的多个存储实例
拓扑定义
Service是Kubernetes项目中将一组Pod暴露给外界访问的一种机制,Service有以下的方式被用户访问到:
- virtual IP(VIP)
- DNS方式
- Normal Service:访问域名解析到的其实是Service的VIP,后续的访问方式和VIP方式一样
- Headless Service(在创建Service的时候指定clusterIP字段为None,这种方式解析到的是某一个Pod的IP地址
Headless Service的方式创建了Service之后,它所代理的所有Pod的IP地址都变被绑定一个DNS记录,这个DNS记录正是Kubernetes为Pod分配的唯一可解析身份
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
创建一个StatefulSet交给Headless Service来管理:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx: 1.9.1
ports:
- containerPort: 80
name: web
这样Kubernetes的控制循环就会保证Pod的启动按照某种特定的顺序,且每个Pod的DNS解析是在重启后是保持不变的(通过特定的域名访问到的Pod永远是同一个Pod),但需要注意的是并不保证IP地址不变,所以对StatefulSet实例的访问,必须使用DNS记录或者hostname的方式
存储定义
管理和远程持久化(例如Ceph、GlusterFS等)的Volume不仅需要专业知识,并且还有可能暴露公司基础设施秘密,作为有状态服务的持久化插件,Kubernetes提供了PV和PVC这样的API对象来实现。PVC是一种特殊的Volume,至于 其具体是什么类型的Volume,需要跟某个PV绑定之后才知道。Kubernetes中PVC和PV的设计,实际上类似于“接口“和”实现”的思想,开发者只需要知道并会使用“接口“,即PVC;而运维人员负责给”接口“绑定具体的实现,即PV。
PersistentVolume(持久化卷定义) -> PersistentVolumeClaim(声明): 配置参数
PersistentVolumeClaim(声明) -> StatefulSet(设置挂载点): 动态绑定
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pv-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
kind: PersistentVolume
apiVersion: v1
metadata:
name: pv-volume
labels:
type: local
spec:
capacity:
storage: 10Gi
rbd:
monitors:
- '10.16.154.78:6789'
- '10.16.154.82:6789'
- '10.16.154.83:6789'
pool: kube
image: foo
fsType: ext4
readOnly: true
user: admin
keyring: /etc/ceph/keyring
imageformat: "2"
imagefeatures: "layering"
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx: 1.9.1
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi