一、Docker简介
1、Docker是什么?
是一个开源的容器引擎,基于go语言开发
2、特点
轻量级,可移植的
沙箱机制
开销极低
几个重要的名词概念:
镜像
容器
映射-容器连接
3、架构
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器
Docker 容器通过 Docker 镜像来创建
容器与镜像的关系类似于面向对象编程中的对象与类
二、Docker 安装部署(centos7 vm)
1、安装docker环境
Centos系统为例:
要求:centos 7
Docker 软件包和依赖包已经包含在默认的 CentOS-Extras 软件源里,
2、安装命令如下
2.1可以连接外网条件下安装
Yum –y install docker
安装完成后启动docker服务
Service docker start
2.2 无法连接外网条件下安装
https://gitee.com/kennylee/install-docker
直接运行 install-docker-offline.sh安装docker即可
3、查看docker服务状态
Service docker status
Docker服务运行正常
三、镜像管理(mysql为例)
从docker架构中得知,docker镜像可以从docker镜像仓库下载,类似于maven中下载相关jar包,docker的镜像仓库:Docker Hub(https://hub.docker.com)
1、镜像查询
Docker search mysql
查询结果:
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/mysql MySQL is a widely used, open-source relati... 5122 [OK]
docker.io docker.io/mariadb MariaDB is a community-developed fork of M... 1588 [OK]
docker.io docker.io/mysql/mysql-server OptimizedMySQL Server Docker images. Crea... 358 [OK]
docker.io docker.io/percona Percona Server is a fork of the MySQL rela... 297 [OK]
docker.io docker.io/hypriot/rpi-mysql RPi-compatible Docker Image with Mysql 70
docker.io docker.io/zabbix/zabbix-server-mysql Zabbix Server withMySQL database support 62 [OK]
docker.io docker.io/centurylink/mysql Imagecontaining mysql. Optimized to be li... 53 [OK]
docker.io docker.io/sameersbn/mysql 47 [OK]
docker.io docker.io/zabbix/zabbix-web-nginx-mysql Zabbix frontend basedon Nginx web-server ... 35 [OK]
docker.io docker.io/tutum/mysql Base docker image to run a MySQL database ... 27
docker.io docker.io/1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5 ubuntu-16-nginx-php-phpmyadmin-mysql-5 16 [OK]
docker.io docker.io/schickling/mysql-backup-s3 Backup MySQL to S3(supports periodic back... 16 [OK]
docker.io docker.io/centos/mysql-57-centos7 MySQL 5.7 SQLdatabase server 12
docker.io docker.io/linuxserver/mysql A Mysqlcontainer, brought to you by Linux... 12
docker.io docker.io/openshift/mysql-55-centos7 DEPRECATED: ACentos7 based MySQL v5.5 ima... 6
docker.io docker.io/centos/mysql-56-centos7 MySQL 5.6 SQLdatabase server 5
docker.io docker.io/dsteinkopf/backup-all-mysql backup all DBs in amysql server 3 [OK]
docker.io docker.io/frodenas/mysql ADocker Image for MySQL 3 [OK]
docker.io docker.io/circleci/mysql MySQLis a widely used, open-source relati... 2
docker.io docker.io/ansibleplaybookbundle/rhscl-mysql-apb An APB which deploys RHSCL MySQL 0 [OK]
docker.io docker.io/astronomerio/mysql-sink MySQL sink 0 [OK]
docker.io docker.io/astronomerio/mysql-source MySQL source 0 [OK]
docker.io docker.io/cloudfoundry/cf-mysql-ci Image used in CIof cf-mysql-release 0
docker.io docker.io/cloudposse/mysql Improved`mysql` service with support for ... 0 [OK]
docker.io docker.io/jenkler/mysql Docker Mysql package 0
2、创建镜像
2.1、拉取镜像(docker pull)
docker pull mysql:tag
Tag的获取方式:直接从docker hub上获取
Docker pull mysql:latest
下载镜像
2.2、dockerFile创建镜像(docker build)
在宿主机/mysql/dockerfile目录下创建dockerfile文件
Mkdir –p /mysql/docker
Cd /mysql/dockerfile
Touch Dockerfile
Dockerfile文件内容:
#由于本机已经pull了tag为latest的mysql镜像,以mysql:latest镜像为基础
ROM mysql:latest
#设置免密登录
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
#将所需文件放到容器中
COPY setup.sh /mysql/setup.sh
COPY schema.sql /mysql/schema.sql
COPY privileges.sql /mysql/privileges.sql
#设置容器启动时执行的命令
CMD ["sh", "/mysql/setup.sh"]
和Dockerfile相同目录下的三个文件
Setup.sh
#!/bin/bash
#如果语句执行失败就退出
set -e
#查看mysql服务的状态,方便调试,这条语句可以删除
echo `service mysql status`
echo '1.启动mysql....'
#启动mysql
service mysql start
sleep 3
echo `service mysql status`
echo '2.开始导入数据....'
#导入数据
mysql
echo '3.导入数据完毕....'
sleep 3
echo `service mysql status`
#重新设置mysql密码
echo '4.开始修改密码....'
mysql
echo '5.修改密码完毕....'
#sleep 3
echo `service mysql status`
echo `mysql容器启动完毕,且数据导入成功`
schema.sql:
-- 创建数据库
DROP DATABASE IF EXISTS `docker_mysql`;
create database `docker_mysql` defaultcharacter set utf8 collate utf8_general_ci;
use docker_mysql;
-- 建表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id`bigint(20) NOT NULL,
`created_at` bigint(40) DEFAULT NULL,
`last_modified` bigint(40) DEFAULT NULL,
`email`varchar(255) DEFAULT NULL,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
`username` varchar(255) DEFAULT NULL,
PRIMARYKEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- 插入数据
replace INTO `user` (`id`, `created_at`,`last_modified`, `email`, `first_name`, `last_name`, `username`)
VALUES
(0,1490257904,1490257904,'[email protected]','John','Doe','user');
privileges.sql:
use mysql;
DELETE from userwhere User='docker';
select host, userfrom user;
-- 新建可以远程访问的用户docker:
GRANT USAGE ON *.*TO 'docker'@'localhost' IDENTIFIED BY '123456' WITH GRANT OPTION;
-- 将docker_mysql数据库的权限授权给创建的docker用户,密码为123456:
GRANT ALL PRIVILEGESON *.* TO 'docker'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
-- 这一条命令一定要有:
flush privileges;
总结:数据初始化脚本包括sql语句一定要可以重复使用的语句,去重操作一定要有,否则后面容器做启停操作的时候会导致容器无法正常运行退出
创建镜像:
docker build -t qh-mysql . 使用当前目录的docker File创建镜像
2.3、从容器生成镜像(docker
commit)
第一步:查看我们本地的镜像:
Docker images
只有一个mysql的镜像,详细信息如下
第二步:查看本地的容器
有一个在运行的mysql容器,id为:f25a0d544a82
第三步:使用该容器创建新的mysql镜像-mysql-new
Commit命令语法:
dockercommit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS说明:
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
-p :在commit时,将容器暂停
详细命令:docker commit -a"qh" -m "my new mysql image" f25a0d544a82 mysq-new:v1
运行结果如下:
3、查看本地镜像
docker
images
4、删除镜像
docker rmi qh-mysql(名称或者id)
四、容器管理(mysql容器)
1、生成容器
镜像生成成功后,使用镜像生成容器并运行
docker run -d -p 13306:3306 --name qh2 qh-mysql
使用qh-mysql镜像创建容器qh2
-d:在后台运行
-p 13306:3306 端口映射,使用宿主机的13306端口映射容器的3306端口,其他机器访问容器的端口为13306,例如要想访问qh2的mysql,使用数据库工具Navicat配置信息如下:
--name:容器的命名
qh-mysql:生成容器使用的镜像名称
2、查看容器
2.1、查询运行中的容器
docker ps
①、容器的id
②、创建容器的镜像名称
③、容器启动时运行的脚本
④、端口映射关系及协议
⑤、容器名称
其中1和5在容器生命周期管理时会经常用到,例如容器的启停,删除,容器连接,查看容器详情等
2.2、查询所有容器包括未运行的
docker ps –a
1:未运行的容器qh-nginx
2.3 查看某容器的详细信息
Docker
inspect xxx
2.4 查看容器日志
Docker logs qh1
3.在容器中运行命令
docker exec -it qh3 /bin/bash(要在处于运行状态的容器中)
退出:exit
4、启动/停止容器
Docker start qh-mysql
Docker stop qh-mysql
5、删除容器docker
Docker rm qh-mysql
五、数据持久化
1、踩坑-commit命令
先说下自己最开始的解决数据持久化的思路:通过commit命令
看下docker官网的 commit命令的详解
上面有写到基于容器的变化新建一个镜像,既然如此,那我在容器中对数据的修改应该会保存到新生成的镜像中,然后我再用新镜像new一个容器出来,数据更新部分不就保存到新容器中了?
于是我在5.6版本mysql的镜像上new了一个容器出来:
docker run -p 3306:3306 --name qh1 -e MYSQL_ROOT_PASSWORD=123456-d mysql:5.6
查看容器docker ps
使用navigator连接mysql容器
配置信息如下:
新建数据库test,并在test中新建表user
创建完数据,运行commit命令把容器生成镜像
docker commit qh1 qh-mysql1
查看镜像docker images
从结果看镜像确实生成了,那来看看创建的数据是否有保存
马上使用新镜像new一个容器出来
连接qh-user容器
发现创建的库并没有保存下来
是时候求助官方文档了,查阅了docker commit的官方文档说明后,发现了在扩展说明中有这么一句话:
意思是commit操作并不会包含容器内挂载数据卷中的数据变化。难道是因为mysql容器的挂载数据卷引起的?
马上查看容器信息,是否有data mount相关信息:
Docker inspect qh1
结果如下:
这个信息的意思就是使用volume的方式mount,把载体机的Source目录挂载到容器的Destination目录,下面来看如何挂载数据即如何实现数据持久化
2、三种数据持久化方式
2.1、volume(重点介绍mysql实例)
2.1.1直接挂载
前提条件:qh1是一个mysql容器,基于mysql:5.6镜像生成,在qh1中手动添加了一个数据库test,在数据库中手动添加一个表user,表中有三个字段:
我们的目的是把qh1的volume挂载到新容器中的/var/lib/mysql目录下
首先我们要知道qh1的volume的路径
Docker
inspect qh1查看容器
或者是docker inspect -f "{{.Mounts}}" qh1,切记区分大小写
找到qh1的volume路径为:/var/lib/docker/volumes/1de10c2b4efb8a3f8a64eb20ab44f916544ca782fa49956c7c87825aa064e179/_data
新建名称为qh2的mysql新容器,命令如下;
docker run -it -p 23306:3306 --name qh2 -v/var/lib/docker/volumes/1de10c2b4efb8a3f8a64eb20ab44f916544ca782fa49956c7c87825aa064e179/_data:/var/lib/mysql-e MYSQL_ROOT_PASSWORD=123456 --privileged=true -d mysql:5.6
容器创建成功后查看日志,看是否存在异常
Docker logs qh2
出现以下异常信息:
是两个库使用相同的数据文件导致的,解决:
关掉qh1,重新启动qh2容器,再次查看qh2日志
启动正常,使用navigator连接qh2数据库
注意端口号是23306
Test库和user表已经在新容器中了。
2.1.2共享方式
先看下docker官网的说明
只需要指定共享源,命令如下:
docker run --name qh3 --volumes-from qh1 -d-p 33306:3306 mysql:5.6
使用navigator查看
Test库和user也出现在了新容器中
2.2、bind mount
2.3、tmpfs