阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Kubernetes数据持久化方案

185次阅读
没有评论

共计 6868 个字符,预计需要花费 18 分钟才能阅读完成。

在开始介绍 k8s 持久化存储前,我们有必要了解一下 k8s 的 emptydir 和 hostpath、configmap 以及 secret 的机制和用途。

1、Emptydir
EmptyDir 是一个空目录,他的生命周期和所属的 Pod 是完全一致的,EmptyDir 主要作用可以在同一 Pod 内的不同容器之间共享工作过程中产生的文件。如果 Pod 配置了 emptyDir 类型 Volume,Pod 被分配到 Node 上时候,会创建 emptyDir,只要 Pod 运行在 Node 上,emptyDir 都会存在(容器挂掉不会导致 emptyDir 丢失数据),但是如果 Pod 从 Node 上被删除(Pod 被删除,或者 Pod 发生迁移),emptyDir 也会被删除,并且永久丢失。

# cat emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  – name : busybox
    image: registry.fjhb.cn/busybox
    imagePullPolicy: IfNotPresent
    command:
      – sleep
      – “3600”
    volumeMounts:
      – mountPath: /busybox-data
        name: data
  volumes:
  – name: data
    emptyDir: {}

Kubernetes 数据持久化方案
2、Hostpath
Hostpath 会把宿主机上的指定卷加载到容器之中,如果 Pod 发生跨主机的重建,其内容就难保证了。这种卷一般和 DaemonSet 搭配使用。hostPath 允许挂载 Node 上的文件系统到 Pod 里面去。如果 Pod 有需要使用 Node 上的东西,可以使用 hostPath,不过不过建议使用,因为理论上 Pod 不应该感知 Node 的。

# cat hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  – name : busybox
    image: registry.fjhb.cn/busybox
    imagePullPolicy: IfNotPresent
    command:
      – sleep
      – “3600”
    volumeMounts:
      – mountPath: /busybox-data
        name: data
  volumes:
  – hostPath:
      path: /tmp
    name: data

Kubernetes 数据持久化方案
emptyDir 和 hostPat 很多场景是无法满足持久化需求,因为在 Pod 发生迁移的时候,数据都无法进行转移的,这就需要分布式文件系统的支持。

3、Configmap
镜像使用的过程中,经常需要利用配置文件、启动脚本等方式来影响容器的运行方式,如果仅有少量配置,我们可以使用环境变量的方式来进行配置。然而对于一些较为复杂的配置,k8s 提供了 configmap 解决方案。
ConfigMap API 资源存储键 / 值对配置数据,这些数据可以在 pods 里使用。
ConfigMap 跟 Secrets 类似,但是 ConfigMap 可以更方便的处理不包含敏感信息的字符串。
当 ConfigMap 以数据卷的形式挂载进 Pod 的时,这时更新 ConfigMap(或删掉重建 ConfigMap),Pod 内挂载的配置信息会热更新。这时可以增加一些监测配置文件变更的脚本,然后 reload 对应服务
ConfigMap 的 API 概念上来说是很简单的。从数据角度来看,ConfigMap 的类型只是键值组。应用可以从不同角度来配置。在一个 pod 里面使用 ConfigMap 大致有三种方式:
1、命令行参数
2、环境变量
3、数据卷文件

将变量做成 configmap
Kubernetes 数据持久化方案

将 nginx 配置文件做成 configmap

# cat nginx.conf   
user nginx;
worker_processes auto;
error_log /etc/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  ‘$remote_addr – $remote_user [$time_local] “$request” ‘
                      ‘$status $body_bytes_sent “$http_referer” ‘
                      ‘”$http_user_agent” “$http_x_forwarded_for”‘;
    server_tokens    off;
    access_log        /usr/share/nginx/html/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay        on;
    keepalive_timeout  65;
    types_hash_max_size 2048;

    include            /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    server {
[root@vm1 ~]# cat nginx.conf 
user nginx;
worker_processes auto;
error_log /etc/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  ‘$remote_addr – $remote_user [$time_local] “$request” ‘
                      ‘$status $body_bytes_sent “$http_referer” ‘
                      ‘”$http_user_agent” “$http_x_forwarded_for”‘;
    server_tokens    off;
    access_log        /usr/share/nginx/html/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay        on;
    keepalive_timeout  65;
    types_hash_max_size 2048;

    include            /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen      80 default_server;
        listen      [::]:80 default_server;
        server_name  _;
        root        /usr/share/nginx/html;

        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

}# kubectl create configmap nginxconfig –from-file nginx.conf 
# kubectl get configmap
# kubectl get configmap -o yaml

Kubernetes 数据持久化方案
Kubernetes 数据持久化方案
在 rc 配置文件中使用 configmap

# cat nginx-rc-configmap.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
  labels:
    name: nginx
spec:
  replicas: 2
  selector:
    name: nginx
  template:
    metadata:
      labels:
      name: nginx
    spec:
      containers:
      – name: nginx
        image: docker.io/nginx
        volumeMounts:
        – name: nginx-etc
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
        ports:
        – containerPort: 80
      volumes:
      – name: nginx-etc
        configMap:
        name: nginxconfig
        items:
          – key: nginx.conf
            path: nginx.conf# kubectl create -f nginx-rc-configmap.yaml

Kubernetes 数据持久化方案
Kubernetes 数据持久化方案
configmap 的信息实际是存储在 etcd 中的,可以使用 kubectl edit configmap xxx 来对 configmap 进行修改

# etcdctl ls /registry/configmaps/default
# etcdctl get /registry/configmaps/default/nginxconfig

Kubernetes 数据持久化方案
4、Secret
Kubemetes 提供了 Secret 来处理敏感数据,比如密码、Token 和密钥,相比于直接将敏感数据配置在 Pod 的定义或者镜像中,Secret 提供了更加安全的机制(Base64 加密),防止数据泄露。Secret 的创建是独立于 Pod 的,以数据卷的形式挂载到 Pod 中,Secret 的数据将以文件的形式保存,容器通过读取文件可以获取需要的数据。
目前 Secret 的类型有 3 种:
Opaque(default): 任意字符串 
kubernetes.io/service-account-token: 作用于 ServiceAccount
kubernetes.io/dockercfg: 作用于 Docker registry,用户下载 docker 镜像认证使用
secert 的具体配置在前文 serviceaccount 中已经介绍过了,本文不再赘述。

下面我们来介绍一下 k8s 的持久化存储方案,目前 k8s 支持的存储方案主要如下:
分布式文件系统:NFS/GlusterFS/CephFS
公有云存储方案:AWS/GCE/Auzre

Nfs 存储方案
NFS 是 Network File System 的缩写,即网络文件系统。Kubernetes 中通过简单地配置就可以挂载 NFS 到 Pod 中,而 NFS 中的数据是可以永久保存的,同时 NFS 支持同时写操作。

1、首先安装 nfs

# yum -y install nfs-util*
# cat /etc/exports
/home 192.168.115.0/24(rw,sync,no_root_squash)
# systemctl start rpcbind
# systemctl start nfs
# showmount -e 127.0.0.1
Export list for 127.0.0.1:
/home 192.168.115.0/24

Kubernetes 数据持久化方案

2、使用 pod 直接挂载 nfs
要保证集群内所有的 node 节点都可以挂载 nfs

# cat nfs.yaml
apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  – name : busybox
    image: registry.fjhb.cn/busybox
    imagePullPolicy: IfNotPresent
    command:
      – sleep
      – “3600”
    volumeMounts:
      – mountPath: /busybox-nfsdata
        name: nfsdata
  volumes:
  – name: nfsdata
    nfs:
      server: 192.168.115.6
      path: /home

Kubernetes 数据持久化方案
Kubernetes 数据持久化方案
3、使用 PV 和 PVC
在实际的使用中,我们通常会将各存储划分成 PV,然后和 PVC 绑定给 pod 使用。
PV:PersistentVolume
PVC:PersistentVolumeClaim

PV 和 PVC 的生命周期:
供应准备:通过集群外的存储系统或者公有云存储方案来提供存储持久化支持。
静态提供:管理员手动创建多个 PV,供 PVC 使用。
动态提供:动态创建 PVC 特定的 PV,并绑定。

绑定:用户创建 pvc 并指定需要的资源和访问模式。在找到可用 pv 之前,pvc 会保持未绑定状态。

使用:用户可在 pod 中像使用 volume 一样使用 pvc。

释放:用户删除 pvc 来回收存储资源,pv 将变成“released”状态。由于还保留着之前的数据,这些数据需要根据不同的策略来处理,否则这些存储资源无法被其他 pvc 使用。

回收 (Reclaiming):pv 可以设置三种回收策略:保留(Retain),回收(Recycle)和删除(Delete)
保留策略:允许人工处理保留的数据。
删除策略:将删除 pv 和外部关联的存储资源,需要插件支持。
回收策略:将执行清除操作,之后可以被新的 pvc 使用,需要插件支持。

PV 卷阶段状态:
Available – 资源尚未被 PVC 使用
Bound – 卷已经被绑定到 PVC 了
Released – PVC 被删除,PV 卷处于释放状态,但未被集群回收。
Failed – PV 卷自动回收失败

PV 卷的访问模式
ReadWriteOnce – 单 node 的读写 
ReadOnlyMany – 多 node 的只读 
ReadWriteMany – 多 node 的读写

创建 pv 与 pvc

# cat nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-001
spec:
  capacity:
    storage: 5Gi
  accessModes:
  – ReadWriteMany
  nfs:
    path: /home
    server: 192.168.115.6
  persistentVolumeReclaimPolicy: Recycle

Kubernetes 数据持久化方案

# cat nfs-pvc.yaml                 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nfs-data
spec:
  accessModes:
    – ReadWriteMany
  resources:
    requests:
      storage: 5Gi

Kubernetes 数据持久化方案
在 PVC 绑定 PV 时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。
Kubernetes 数据持久化方案

在 rc 文件中使用 PVC

# cat nginx-rc-configmap.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
  labels:
    name: nginx
spec:
  replicas: 2
  selector:
    name: nginx
  template:
    metadata:
      labels:
      name: nginx
    spec:
      containers:
      – name: nginx
        image: docker.io/nginx
        volumeMounts:
        – name: nginx-data
          mountPath: /usr/share/nginx/html
        – name: nginx-etc
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
        ports:
        – containerPort: 80
      volumes:
      – name: nginx-data
        persistentVolumeClaim:
        claimName: nfs-data
      – name: nginx-etc
        configMap:
        name: nginxconfig
        items:
          – key: nginx.conf
            path: nginx.conf

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计6868字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中