linux运维、架构之路-K8s数据管理
一、Volume介绍
容器和Pod是短暂的,它们的生命周期可能很短,会被频繁的销毁和创建,存在容器中的数据会被清除,为了持久化保存容器的数据,k8s提供了Volume。
Volume的生命周期独立于容器,它是一个目录,Volume会被mount到Pod,Pod中的所有容器都可以访问这个Volume,和Docker Volume类似。
Volume支持的类型:emptyDir、hostPath、AWS Elastic Block Store、NFS、Ceph等。
1、emptyDir
emptyDir是最基础的Volume类型,它对于容器来说是持久的,对于Pod刚不是,当Pod从节点删除时Volume中的数据也会被删除,如果只是容器被销毁而Pod还在,则Volume不受影响。
①创建示例应用
apiVersion: v1
kind: Pod
metadata:
name: hello-world
spec:
containers:
- image: busybox
name: hello
volumeMounts:
- mountPath: /hello_dir #②hello容器将shared-volume mount到/hello_dir目录
name: shared-volume
args:
- /bin/sh #③hello通过echo将数据写到文件hello里
- -c
- echo "hello world" >/hello_dir/hello; sleep - image: busybox
name: world #④world容器将 shared-volume mount到 /world_dir目录
volumeMounts:
- mountPath: /world_dir
name: shared-volume
args:
- /bin/sh #⑤world通过cat从文件hello读取数据
- -c
- cat /world_dir/hello; sleep volumes:
- name: shared-volume #①定义了一个emptyDir类型的Volume shared-volume
emptyDir: {}
②查看验证
[root@k8s-node1 volume]# kubectl apply -f emptyDir.yaml
pod "hello-world" created [root@k8s-node1 volume]# kubectl get pod
NAME READY STATUS RESTARTS AGE
hello-world / Running 36s [root@k8s-node1 volume]# kubectl logs hello-world world
hello world
上述显示容器world成功读到了hello容器写入的数据,验证了两个容器共享emptyDir Volume,其效果相当于执行了docker run -v /hello_dir 和/docker run -v /world_dir
emptyDir是Host主机上创建的临时目录,其优点能够方便地为Pod中的容器提供共享存储,但不具有持久性,如果Pod不存在了,emptyDir也就没有了,适合Pod中容器需要临时共享存储空间的应用场景
2、HostPath
hostPath Volume的作用是将Docker Host文件系统中已经存在的目录mount给Pod的容器,大部分应用不会使用此类型,因为这实际上增加上了Pod与节点的耦合,有些需要访问k8s内部数据,比如配置文件和二进制库这样的应用需要使用hostPath,例如k8s自身的应用kube-apiserver和kube-controller-manager。
3、外部Storage Provider
如果k8s部署在AWS、GCE、Azure等公有云上,可以直接使用云盘作为Volume。因资源有限,此处无法演示。
二、PV & PVC
- PV是外部存储系统中的一块存储空间,由管理员创建,与Volume一样具有持久性,生命周期独立于Pod。
- PVC刚是对PV的申请,PVC通常由普通用户创建,需要为Pod分配存储资源时,用户可以创建一个PVC,指明存储资源的容量大小和访问权限等,k8s会查找并提供满足条件的PV。
- k8s支持多种类型的PV,比如AWS EBS、Ceph、NFS等
1、NFS PV
①在k8s-master节点搭建一个NFS服务,目录为/nfsdata
[root@k8s-node1 ~]# showmount -e
Export list for k8s-node1:
/nfsdata *
NFS服务具体部署请参照:https://www.cnblogs.com/yanxinjiang/p/7419469.html
②创建应用示例
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv
spec:
capacity:
storage: 1Gi #指定PV的容量为1GB
accessModes:
- ReadWriteOnce #表示PV能为read-write模式mount到单个节点,ReadOnlyMany表示只读,mount到多个节点,ReadWriteMany表示读写可以mount到多节点
persistentVolumeReclaimPolicy: Recycle #PV的回收策略,清除PV中的数据,Retain表示管理员手工回收
storageClassName: nfs #指定PV的class为nfs,相当于为PV设置了一个分类,PVC可以指定class申请相应的PV
nfs:
path: /nfsdata/pv1 #指定PV在NFS服务器上对应的目录
server: 192.168.56.11
[root@k8s-node1 nfs-pv]# kubectl apply -f nfs-pv1.yaml
persistentvolume "mypv1" created
[root@k8s-node1 nfs-pv]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE #STATUS为Available,表示mypv1就绪,可以被PVC申请
mypv1 1Gi RWO Recycle Available nfs 4s
③创建PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mypv
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
[root@k8s-node1 nfs-pv]# kubectl apply -f nfs-pvc1.yaml
persistentvolumeclaim "mypvc1" created
[root@k8s-node1 nfs-pv]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mypvc1 Bound mypv1 1Gi RWO nfs 13s
[root@k8s-node1 nfs-pv]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv1 1Gi RWO Recycle Bound default/mypvc1 nfs 22m
结果:mypvc1已经成功绑定到mypv1上面
④在Pod中使用存储
kind: Pod
apiVersion: v1
metadata:
name: mypod1
spec:
containers:
- name: mypod1
image: busybox
args:
- /bin/sh
- -c
- sleep
volumeMounts:
- mountPath: "/mydata"
name: mypv
volumes:
- name: mypv
persistentVolumeClaim:
claimName: mypv
⑤测试验证
[root@k8s-node1 nfs-pv]# kubectl apply -f pod1.yaml
[root@k8s-node1 nfs-pv]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
mypod1 / Running 11m 10.2.83.14 192.168.56.12
[root@k8s-node1 nfs-pv]# kubectl exec mypod1 touch /mydata/readme.md
[root@k8s-node1 nfs-pv]# ls /nfsdata/pv1/
readme.md
在Pod中创建的文件/mydata已经存储到了NFS服务器目录/nfsdata/pv1中。
⑥回收PV
- 当不需要使用PV时,可用删除PVC回收PV
[root@k8s-node1 nfs-pv]# kubectl delete pvc mypvc1
persistentvolumeclaim "mypvc1" deleted
因PV的回收策略设置为Recycle,所以数据会被清除,如想保存数据,可以将策略设置为Retain
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain #Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.168.56.11
[root@k8s-node1 nfs-pv]# kubectl apply -f nfs-pv1.yaml
persistentvolume "mypv1" configured
[root@k8s-node1 nfs-pv]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv1 1Gi RWO Retain Bound default/mypvc1 nfs
⑦验证
[root@k8s-node1 nfs-pv]# kubectl apply -f nfs-pvc1.yaml
[root@k8s-node1 nfs-pv]# kubectl exec mypod1 touch /mydata/hello.world
[root@k8s-node1 nfs-pv]# ls /nfsdata/pv1/
hello.world
[root@k8s-node1 nfs-pv]# kubectl delete pvc mypvc1
persistentvolumeclaim "mypvc1" deleted
[root@k8s-node1 nfs-pv]# ls /nfsdata/pv1/
hello.world
2、PV动态供给
- 静态供给:我们提前创建PV,通过PVC申请PV并在Pod中使用
- 动态供给:如果没有满足PVC条件的PV,会动态创建PV,不需要提前创建PV,效率高,通过StorageClass实现。
3、k8s中MySQL数据持久化存储
①创建PV和PVC
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
server: 192.168.56.11
path: /data/k8s/mysql-pv ---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: nfs
查看pv,pvc状态
[root@k8s-node1 mysql]# kubectl apply -f mysql_pv.yaml
persistentvolume "mysql-pv" created
persistentvolumeclaim "mysql-pvc" created [root@k8s-node1 mysql]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/mysql-pv 2Gi RWO Retain Bound default/mysql-pvc nfs 4s NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/mysql-pvc Bound mysql-pv 2Gi RWO nfs 4s
②部署MySQL
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.6
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- name: mysql
containerPort:
volumeMounts:
- mountPath: /var/lib/mysql
name: mysql-persistent-storage
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port:
selector:
app: mysql
创建应用查看
[root@k8s-node1 mysql]# kubectl apply -f mysql.yaml
deployment.apps "mysql" created
[root@k8s-node1 k8s]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
mysql-57c44d9d5f-5v7qc / Running 7m 10.2.8.25 192.168.56.13
③进入MySQL数据库创建测试数据
kubectl exec -it mysql-57c44d9d5f-5v7qc /bin/bash
root@mysql-57c44d9d5f-5v7qc:/# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is
Server version: 5.6. MySQL Community Server (GPL) Copyright (c) , , Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
mysql>
mysql>
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
mysql> create database test;
Query OK, row affected (0.01 sec) mysql> use test;
Database changed mysql> create table my_id(id int());
Query OK, rows affected (0.03 sec) mysql> insert my_id values();
Query OK, row affected (0.01 sec) mysql> select * from my_id;
+------+
| id |
+------+
| |
+------+
row in set (0.00 sec)
④模拟k8s-node3节点故障
此时node3节点变为不可用
[root@k8s-node1 mysql]# kubectl get node
NAME STATUS ROLES AGE VERSION
192.168.56.12 Ready <none> 6d v1.10.3
192.168.56.13 NotReady <none> 6d v1.10.3
⑤等待一段时间后,k8s会将MySQL迁移至node2节点
[root@k8s-node1 mysql]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
mysql-57c44d9d5f-5v7qc / Unknown 47m 10.2.8.25 192.168.56.13
mysql-57c44d9d5f-6gvh5 / Running 18m 10.2.93.74 192.168.56.12
[root@k8s-node1 mysql]# kubectl exec -it mysql-57c44d9d5f-6gvh5 /bin/bash
⑥再次登录MySQL验证数据的一致性
root@mysql-57c44d9d5f-6gvh5:/# mysql -uroot -ppassword
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is
Server version: 5.6. MySQL Community Server (GPL) Copyright (c) , , Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
rows in set (0.02 sec)
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| my_id |
+----------------+
row in set (0.00 sec) mysql> select * from my_id;
+------+
| id |
+------+
| |
+------+
row in set (0.00 sec)
结果:MySQL服务恢复,数据无丢失
linux运维、架构之路-K8s数据管理的更多相关文章
- linux运维架构师职业规划
1.假如你从来未接触过Linux的话,首先要做的就找一本指导书来学习.现在公认的Linux的入门书籍是“鸟哥的私房菜”,讲的很全面,鸟哥的私房菜一共分为两部,一部是基础篇,一部是服务器篇.“鸟哥的私房 ...
- 从苦逼到牛逼,详解Linux运维工程师的打怪升级之路
做运维也快四年多了,就像游戏打怪升级,升级后知识体系和运维体系也相对变化挺大,学习了很多新的知识点. 运维工程师是从一个呆逼进化为苦逼再成长为牛逼的过程,前提在于你要能忍能干能拼,还要具有敏锐的嗅觉感 ...
- Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Discuz!
Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Disc ...
- Linux运维企业架构实战系列
Linux运维企业架构项目实战系列 项目实战1-LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2-LVS.nginx实现负载均衡系列 2.1 项目实战2.1-实现基于LVS负载均衡集 ...
- Linux运维企业架构项目实战系列
Linux运维企业架构项目实战系列 项目实战1—LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2—LVS.nginx实现负载均衡系列2.1 项目实战2.1—实现基于LVS负载均衡集群 ...
- Linux 运维入门到跑路书单推荐
一.基础入门 <鸟哥的Linux私房菜基础学习篇>:最具知名度的Linux入门书<鸟哥的Linux私房菜基础学习篇>,全面而详细地介绍了Linux操作系统. https://b ...
- linux运维工程师面试题收集
面试必考 mysql5和mysql6 有什么区别 mysql-server-5.5:默认引擎改为Innodb,提高了性能和扩展性,提高实用性(中继日志自动恢复) mysql-server-5.6:In ...
- Linux运维工程师成长必经之路
本路线图是从0基础开始,全方位由浅入深,按照多年Linux培训经验和优秀教学方法制定的学习思路和学习方法,路线图包括初级入门.中级进阶.高级提升和资深冲刺四个阶段,每阶段对应着不同优秀的课程和学习方法 ...
- 面试 Linux 运维工作至少需要知道哪些知识?
前言 我们已经发过不少 Linux 面试题,但是单独的面试题总感觉会过于零碎,没有体系化内容给人的帮助大. 知乎上有这样一个问题:一个新手面试 Linux 运维工作至少需要知道哪些知识?其中有一个答案 ...
随机推荐
- 使用foreach的禁忌
List<String> list = new ArrayList<>(); Iterator<String> iterator = list.iterator() ...
- SetIcon(m_hIcon, TRUE);的作用
SetIcon(m_hIcon, FALSE);// Set small icon 这条语句,程序显示时,左上角就会显示定义了的图标,生成的EXE程序也显示了这个图标 SetIcon(m_hIcon, ...
- Lucky Sorting(CodeForces-109D)【思维】
题意:给出一组数,要求从小到大排序,并且排序的过程中,发生交换的两个数至少一个为幸运数(十进制位均为4或7),问能否在(2×n)次交换内完成排序,如果能,输出交换的方案(不要求步骤数最少). 思路:首 ...
- E.Magic Master(The 2019 Asia Nanchang First Round Online Programming Contest)
直接模拟orhttps://blog.csdn.net/liufengwei1/article/details/100643831
- Laravel-admin 消息提醒、播放音频、点击跳转
jquery-toastr 消息提醒.播放音频.点击跳转 应用情景,有新的订单生成,后台进行消息提醒并播放音频(这里用到轮询简单实现):下面附代码 1.找到laravel-admin 中的 index ...
- GitHub访问及git工具克隆慢问题解决
一.查询合适的DNS服务器 1.站长工具DNS查询服务器 github.com github.global.ssl.fastly.net 2.选择TTL值最小的记录,记录下对应服务器IP地址 例如 g ...
- drf框架的模块分析
请求模块 请求模块是个什么鬼 ''' 1.drf的request是在wsgi的request基础上再次封装 2.wsgi的request作为drf的request一个属性:_request 3.新的r ...
- Spring Boot源码分析-启动过程
Spring Boot作为目前最流行的Java开发框架,秉承"约定优于配置"原则,大大简化了Spring MVC繁琐的XML文件配置,基本实现零配置启动项目. 本文基于Spring ...
- 牛客 70E 乌龟跑步 (bitset优化dp)
有一只乌龟,初始在0的位置向右跑. 这只乌龟会依次接到一串指令,指令T表示向后转,指令F表示向前移动一个单位.乌龟不能忽视任何指令.现在我们要修改其中正好n个指令(一个指令可以被改多次,一次修改定义为 ...
- 美团2017年CodeM大赛-初赛B轮 黑白树 (树形dp)
大意: 给定树, 初始每个点全为白色, 点$i$有权值$k_i$, 表示选择$i$后, 所有距离$i$小于$k_i$的祖先(包括i)会变为黑色, 求最少选多少个点能使所有点变为黑色. 链上情况的话, ...