如果分布式的应用之间有依赖关系,例如主从关系、主备关系或者数据存储类关系,那简单的Deployment的控制机制就无法保证,Deployment控制的Pod必须是stateless的

拓扑定义

Service是Kubernetes项目中将一组Pod暴露给外界访问的一种机制,Service有以下的方式被用户访问到:

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