第四课 Docker践行DevOps理念-数据持久化和数据共享
tags:
- Docker
- 慕课网
categories:
- 持久化储存
- Data Volume
- Bind Mouting
- 调试利器实战
文章目录
第一节 持久化存储和实验环境
1.1 持久化数据的介绍
- 回顾:container 是在image之上的层,container可写,image不可写。
- 如果我们把容器删除,那么容器中所有的数据都没了。
- 但是我们有需求比如一个数据库的容器,需要保留数据库的文件。
- docker 就引入了持久化数据的机制。(即使删除容器外挂的存储依然存在)
1.2 持久化数据的方案
- 基于本地文件系统的Volume。可以在执行Docker create或Docker run时,通过**-v参数**将主机的目录作为容器的数据卷。这部分功能便是基于本地文件系统的volume管理。
- 基于plugin的Volume ,支持第三方的存储方案,比如NAS、aws(本章没有实验环境演示这种存储方案)
- volume的类型。
- 受管理的data Volume ,由docker后台自动创建。(加不加-v,都帮我们创建)
- 绑定挂载的Volume ,具体挂载位置可以由用户指定。
1.3 实验环境
- 安装插件
- vagrant plugin install vagrant-scp --plugin-clean-sources --plugin-source https://gems.ruby-china.com/
- 开启vagrant, 直接使用vagrant scp labs ~
- Dockerfile文件。
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.require_version ">= 1.6.0"
boxes = [
{
:name => "docker-host",
:eth1 => "192.168.205.10",
:mem => "1024",
:cpu => "1"
}
]
Vagrant.configure(2) do |config|
config.vm.box = "centos/7"
boxes.each do |opts|
config.vm.define opts[:name] do |config|
config.vm.hostname = opts[:name]
config.vm.provider "vmware_fusion" do |v|
v.vmx["memsize"] = opts[:mem]
v.vmx["numvcpus"] = opts[:cpu]
end
config.vm.provider "virtualbox" do |v|
v.customize ["modifyvm", :id, "--memory", opts[:mem]]
v.customize ["modifyvm", :id, "--cpus", opts[:cpu]]
end
config.vm.network :private_network, ip: opts[:eth1]
end
end
# config.vm.synced_folder "./labs", "/home/vagrant/labs"
config.vm.provision "shell", privileged: true, path: "./setup.sh"
end
- setup.sh
# 配置阿里镜像
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://eyzd1v97.mirror.aliyuncs.com"]
}
EOF
# 更新源
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum clean all
sudo yum makecache fast
sudo yum update
# 安装依赖包和docker
sudo yum install -y yum-utils device-mapper-persistent-data lvm2 git vim gcc glibc-static telnet bridge-utils net-tools
sudo yum install docker-ce-17.12.0.ce -y
sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker
# 添加vagrant到docker组中
sudo gpasswd -a vagrant docker # 把当前用户添加到docker组中
sudo systemctl restart docker.service # 重启docker服务
第二节 持久化存储Data Volume
2.1 数据持久化之Volume基本用法
- 进入docker官网,查看mysql的Dockerfile。发现有挂载磁盘VOLUME /var/1ib/mysq1
- 给挂载磁盘起别名:docker run -d -v mysql:/var/lib/mysql --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
- 它比较适用于:容器本身是产生数据源的地方,不想让这些文件随着容器的消失而消失。
- 实验如下:
# 创建一个mysql的容器 输入环境变量MYSQL_ALLOW_EMPTY_PASSWORD
docker run -d --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD mysql
# 发现没有运行 看下情况
docker logs mysql1 # 少了些约束
# 删除容器 可以看到volume并不会被删除
docker rm mysql1
# 查看挂载磁盘并删除
docker volume ls
docker volume rm 390715b872ba54f2376de929e7dcc79dd609d8d07a9ace544696a0dbd7c43f6a
# 重新创建容器
docker run -d --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
# 发现重新多了个volume
docker volume ls
# 查看具体挂载信息 比如目录
docker volume inspect 22a99451145736d9d12eb8ebf53681e63359ada264a32829ee2eb6bd97e19b80
# 这里删除容器后 可以看到volume并不会被删除 上面实验已经验证过
# 这里volume的名称 不太友好(太长不容易区分) 如果在启动一个mysql2 就更加混乱
# 解决办法起别名
docker rm -f mysql1 # 停止并删除容器
docker volume rm 22a99451145736d9d12eb8ebf53681e63359ada264a32829ee2eb6bd97e19b80
docker run -d -v mysql:/var/lib/mysql --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
# 查看挂载磁盘 只有一个mysql
docker volume ls
# 进入容器写数据进mysql,并删除容器
docker exec -it mysql1 /bin/bash
mysql
show databases;
create database docker;
show databases;
exit
exit
docker rm -f mysql1
# 重新指定volume mysql:/var/lib/mysql 创建新容器mysq12
docker exec -it mysql2 /bin/bash
mysql
# 发现之前创建mysql1的docker的数据库还存在在mysql2容器中
show databases;
2.2 数据持久化之Bind Mouting
- 它适用于:本地文件和容器的文件是同步的。
- docker run -v /home/aaa:/root/aaa
- 实验如下:
# 构建image
cd labs/docker-nginx/
docker build -t qnhyn/my-nginx .
more Dockerfile
# 把当前目录的文件 和 容器的/usr/share/nginx/html 同步
docker run -d -v $(pwd):/usr/share/nginx/html -p 80:80 --name web qnhyn/my-nginx
# 在容器的/usr/share/nginx/html 目录下创建文件
docker exec -it web /bin/bash
touch test.sh
exit
# 发现本地文件也多了个test.sh 他们本来就是一个文件
more test.sh
第三节 开发者利器Docker+Bind Mouting实战
- 作为开发,有时候调试非常不方便。因为代码在liunx上默认流程->修改完本地文件->传到linux上,运行看结果。
- 这里推荐docker的Bind Mouting来调试。
- vagrant 会同步修改本机到虚拟机代码。
- docker 会同步修改虚拟机到容器代码。(虽然好像不用docker也可以实现,但是环境不能独立。)
- 实验如下:
FROM python:2.7
LABEL maintainer="QnHyn<[email protected]>"
COPY . /skeleton
WORKDIR /skeleton
RUN pip install -r requirements.txt -i https://pypi.douban.com/simple
EXPOSE 5000
ENTRYPOINT ["scripts/dev.sh"]
#!/usr/bin/env bash
export APP_SETTINGS="skeleton.server.config.ProductionConfig"
python manage.py create_db
python manage.py create_admin
python manage.py create_data
python manage.py runserver -h 0.0.0.0
- 然后启动一个web服务。
# 这里虚拟机的80端口对外暴露 把容器服务的5000端口映射到虚拟机的80端口 虚拟机代码同步与容器的/skeleton代码 vagrant外代码同步到虚拟机代码
docker run -d -p 80:5000 -V $(pwd):/skeleton --name flask qnhyn/flask-skeleton