Docker使用和MySQL安装
Docker介绍
Docker是什么?
Docker是一个基于虚拟化技术的平台,利用容器能将操作系统层虚拟化,容器可以表示软件的一个标准化单元,加上自身隔离于宿主机,具有便携性和灵活性[1]。
Docker为什么会流行
In conclusion, Docker is popular because it has revolutionized development
Docker, and the containers it makes possible, has revolutionized the software industry and in five short years their popularity as a tool and platform has skyrocketed.The main reason is that containers create vast economies of scale. Systems that used to require expensive, dedicated hardware resources can now share hardware with other systems. Another is that containers are self-contained and portable. If a container works on one host, it will work just as well on any other, as long as that host provides a compatible runtime.[2]
docker优势:
- 便携的和自我隔离的;
- docker的应用使系统(尤其是那些需要昂贵和专用硬件资源的系统)可以分享硬件资源给其他系统。
第一点你可以理解为docker在OS层虚拟化[3]。如果说虚拟机是虚拟化硬件,那么docker是让服务/应用虚拟化。就虚拟机,我的理解是操作系统的运行是依托硬件,因此我说虚拟机是虚拟化硬件。比如你可以把Linux装在VM中,然后打包放在其他机器上运行,只要你拥有VM和VMware Workstation。就docker,以MySQL为例,你可以将使用了很久的MySQL的docker镜像打包,然后到其他机器,只要你拥有Docker应用。因此便携性和隔离性都体现出虚拟化技术的优势。
再讲一点,虚拟化可以保证运行的程式隔离于宿主机。比如XXX同学MySQL装不上,可能是错误的安装步骤,或者参数设置有问题,端口占用等等因素,从OS运行环境看,每台宿主机的环境都是不一样的,而docker可以将docker内的服务与外界隔离,这样就排除了外界环境的干扰。如果每个同学都用docker安装MySQL,安装干扰会少很多。
这点可以延伸了提高了企业交付速度,比如XXX应用经过测试OK,就应用放到docker,然后发给甲方(付款方),或者跑到甲方运行docker然后测试,不管如何从速度上,都是有优势的。
第二点更能带来经济优势。
See also: Top Reasons Why Docker is Popular | by Binal Prajapati | JavaScript in Plain English。
名词Docker有两种含义[4]:
- Docker项目,指的是整一个Docker平台,可用于开发者和管理员开发,打包和运行应用。
- Docker引擎,指的是docker守护进程,用于管理镜像和容器。
Container(容器)[4:1]:
容器指的是Docker镜像的一个运行实例。这个术语需要注意两点:实例来自Docker镜像;实例是正在运行的。
Docker如何运作
Docker是C/S架构的。
Docker客户端是用来与Docker Daemon进行沟通的。Docker Daemon又叫Docker Sever。
Docker客户端实际上是docker CLI,用于与Docker Daemon进行沟通。
比如"docker run", "docker push"等命令都是由docker CLI提供。docker开头的命令都是Docker CLI。
用层级关系表示,图解大概是这样:
下图展示了Docker客户端如何与Docker主机进行沟通:
docker pull命令通过Docker CLI发送给Docker daemon,然后Docker daemon从远端拉取镜像到Docker主机。
Refer:Understanding How the Docker Daemon and Docker CLI Work Together — Nick Janetakis。
Linux安装Docker
可以使用yum安装或者离线安装[4:2],我使用yum安装。
1 | yum list installed | grep docker #坚持本地是否安装docker |
Docker中安装MySQL
可以在MySQL docker镜像库查找要拉取的MySQL版本:https://hub.docker.com/_/mysql?tab=tags&page=1&ordering=last_updated。
由于在国内拉取速度太慢了,我们需要选择国内docker镜像源。
我选择的是阿里云进行镜像源加速。实现步骤:
登录阿里云容器镜像服务:https://cr.console.aliyun.com/
创建容器仓库后,获得镜像加速地址。
按照说明文档提示配置/etc/docker/daemon.json后,然后执行
1 | sudo systemctl daemon-reload |
这样就成功了。
我选择安装MySQL 5.7.33 Docker镜像
1 | docker pull mysql:5.7.33 |
查看镜像
1 | [root@localhost /]# docker images |
运行Docker中的MySQL实例
基本的docker run命令格式如下
1 | docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...] |
-i
: Keep STDIN open even if not attached。开放标准输入流。
-t
: Allocate a pseudo-tty。允许终端通信。
-it
: 允许我们通过命令行的方式与容器进行沟通。
-d
: Detached。-d=true
与-d
等价,表示让容器允许在独立(隔离)模式。
--name
: 标识一个容器,就简单地就是给容器取一个独一无二的名称。因此该选项后面紧跟着名称(identifier)。如果不设置该选项,那么docker run后会自动为这个容器生成一个名称。
-p
: Publish a container’s port or a range of ports to the host。主机端口与容器端口绑定。比如:-p 3312:3306表示主机3312端口与容器3306绑定。
-e
: Set any environment variable in the container。为容器设置环境变量。若要设置多个环境变量,格式为:-e key1=value1 -e key2=value2。
-v
: 绑定挂载卷。使用该选项可以让主机指定目录挂载到实例的某个目录,这与mount命令类似。'-v’的使用方法如下
1 -v, --volume=[host-src:]container-dest[:<options>]比如:-v /opt/docker_v/mysql/conf:/etc/mysql/conf.d等价于–volume=/opt/docker_v/mysql/conf:/etc/mysql/conf.d。意思是将主机指定的文件(/opt/docker_v/mysql/conf)挂载到容器指定的文件(/etc/mysql/conf.d)中
See also: docker run | Docker Documentation
为了让你更好理解这些选项,我们看下面一个例子
1 | docker run -itd --name test_mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql |
上述命令运行一个mysql实例,“IMAGE"为mysql”,允许命令行通信,容器名称"test_mysql",容器端口3307映射到主机端口3307,设置一个环境变量MYSQL_ROOT_PASSWORD,相等于为MySQL设置管理员密码。
接下来我们运行一个MySQL容器:
首先创建目录
1 | mkdir -p /storage/docker/mysql-data |
运行容器
1 | docker run \ |
"–privileged"保证MySQL有权限读写挂载文件。
"–volume"将mysql自定义配置和数据库数据持久化到Docker主机,这样删除容器后不会出现数据丢失的情况。
See also: How to Set Up & Configure a MySQL Docker Container {Tutorial}。
查看容器信息,默认以JSON格式打印出来:
1 | [root@localhost ~]# docker inspect test_mysql |
使用docker ps查看容器运行情况:
1 | [root@localhost ~]# docker ps |
"0.0.0.0:3306->3306/tcp"表示本机的3306端口绑定到容器的3306端口。
利用"docker port [容器] 容器的端口号"查询容器端口是否绑定了主机的端口:
1 | [root@localhost ~]# docker port test_mysql |
连接MySQL实例
本地连接MySQL实例
docker exec用于运行命令行来与容器进行通信。
docker exec命令格式如下:
1 | docker exec [OPTIONS] CONTAINER COMMAND [ARG...] |
[OPTIONS]
- 请参考docker exec | Docker Documentation。
CONTAINER
- 容器名称。
COMMAND
- 命令。这里应该是宿主机上的可用命令。对于Linux来说,可使用pwd,bash等等。
下面例子展示如何本地连接MySQL实例。
1 | [root@localhost /work/blog]# docker exec -it test_mysql bash |
远程连接MySQL实例(使用Navicat)
我们先查看哪些用户允许远程登录:
1 | mysql> use mysql; |
我们看host一列:'%'表示允许任何主机连接到MySQL;"localhost"表示只允许本地连接到MySQL。
由user表可知,root用户可用于远程登录。不过我还是记录下创建普通用户用于远程登录:
先在本地连接的MySQL的命令行中创建一个远程用户。首先,进入mysql数据库:
1 | use mysql; |
然后,创建远程用户:
格式为
1 | grant all privileges on *.* to 用户名@"%" identified by "密码" with grant option; |
我创建的远程用户如下:
1 | mysql> grant all privileges on *.* to violet@"%" identified by "123456" with grant option; |
最后,刷新权限:
1 | mysql> flush privileges; |
再次查看user表
1 | mysql> select user, host from user; |
接着我们使用Navicat连接MySQL实例:
Docker管理
列出,停止,删除容器/镜像
下面例子展示如何列出,停止删除容器以及列出,删除镜像:
1 | [root@localhost /]# docker container ls -a |
如何运行停止的容器
1 | docker start `docker ps -q -l` |
-l
- 显示最新创建的容器
-q
- 只显示容器ID
See also: https://stackoverflow.com/questions/21928691/how-to-continue-a-docker-container-which-has-exited。
挂载权限问题解决
1 | [root@localhost ~]# systemctl status docker |
Refer: https://github.com/docker-library/mysql/issues/714。
更换挂载目录权限,因为docker mysql需要更高的权限。
删除出问题的容器,然后加入"–privileged"选项:
1 | docker run \ |
1 | [root@localhost ~/docker/test_mysql/conf.d]# docker ps |
第二种解决方法:
修改挂载文件的读写权限。
友情提示:为了避免莫名其妙的错误,请把swap分区和RAM加大。
常用命令Doc
参考 | 描述 |
---|---|
docker ps | Docker Documentation | 列出容器信息 |
docker run | Docker Documentation | 运行一个新的容器 |
docker network | Docker Documentation | 管理Docker网络 |