传统虚拟机技术基于安装在主操作系统上的虚拟机管理系统,创建虚拟机(虚拟出各种硬件),在虚拟机上安装从操作系统,在从操作系统中安装和部署各种应用。这种方式占用资源很大并且步骤冗余。在此基础之上,Linux发展出了虚拟容器技术(LXC),不需要模拟出一个完整的操作系统,而是对进程与其他进程进行隔离。容器内的应用进程直接运行于宿主机的内核,不需要进行硬件虚拟,每个容器之间相互隔离,拥有独立的文件系统与隔离进程,可以区分计算资源。Docker应运而生,在操作系统层面上实现虚拟化,可以直接复用宿主机的操作系统,启动快,占用内存小。
在纯Linux环境下安装docker十分简单,使用apt或者yum安装后启动即可,但是在WSL2中安装需要注意,WSL中禁用了systemd命令,因此在安装Docker是需要使用原生方式安装,使用service方式启动
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
$ sudo service docker start
由于Docker Hub的网络连通性等问题,用户可以使用腾讯云或者阿里云等云服务提供商来进行Docker镜像加速。具体的操作此处不再赘述,腾讯云与阿里云的文档非常完整。
docker images
,用于列出本地宿主机上的镜像信息docker search 镜像名
, 在DockerHub中搜索镜像,可以使用--limit
限制显示数目docker pull 镜像名
,在DockerHub中下载拉取镜像文件docker system df
:查看镜像/容器/数据卷所占的空间docker rmi 镜像名/id
:在本地docker中删除某个镜像docker run
:新建 + 启动容器,该指令存在可选指令项
--name
为容器指定新名称-d
以守护方式(后台)运行容器并返回容器ID。当使用后台方式启动容器时,当容器执行的命令并不是那些一直挂起的命令,容器会自动退出。因此最佳解决方案是,以前台模式运行容器。-i
以交互模式运行容器,通常与-t
一起使用-t
为容器重新分配一个输入终端(前台运行容器,等待前台交互)-p ip:hostPort:containerPort
指定端口映射docker ps
,显示当前所有正在运行的容器exit
退出并关闭容器ctrl + p + q
退出但不关闭容器docker start
,启动已经停止的容器docker resatrt
,重启容器docker stop
,停止容器,docker stop -f
与docker kill
为强制停止容器docker rm
docker logs
,查看容器日志docker top
,查看容器内运行的进程docker inspect
,查看容器内部细节docker exec -it 容器id /bin/bash
,会创建一个新的进程供用户操作,并且用户在退出时只是关闭此终端,并不会影响容器的运行情况docker attach 容器id
,并不会创建新的进程,而是直接进入容器启动命令的终端,当exit退出终端时会导致容器的停止(后台运行)docker cp 容器id:容器内文件路径 宿主机目的路径
,将容器内文件拷贝到宿主机上docker export 容器id > 文件名.tar
,将容器内容留做一个tar归档文件,用于导出为镜像文件,如docker export 6241563ac8fca > jarvis.tar.gz
docker import - 镜像用户/镜像名:镜像版本号
,如cat jarvis.tar.gz | docker import - jarvis/ubuntu:3.0
docker commit
、docker diff
等,在此不进行赘述docker镜像是一种轻量级、可执行的独立软件包,包含了运行某个程序应用所需的所有内容。在使用时可以将应用程序和配置依赖等一起打包好形成一个可以交付的运行环境(代码、类库、环境变量、配置文件等),这个可交付的运行环境就是image镜像文件。
镜像分层
docker commit
将容器副本提交为一个新的镜像。如在Docker Hub上拉取到的Ubuntu镜像是不支持Vim指令的,我们可以在该镜像的容器中安装VIM,并且将该容器副本输出为一个新的镜像文件,这样就可以为我们所用了。镜像存储
docker push
将自己产出的镜像文件存放在该容器中了,使用docker pull
指令就可以将私有镜像仓库中的镜像拉取到本地运行。数据卷就是目录或者文件,存在于一个或者多个容器中,由docker挂载到容器,但是不属于UnionFS系统,因此可以绕过UnionFS提供一些用于持续存储或者共享数据的特性。数据卷的目的是实现数据的持久化,将完全独立于容器的生命周期,因此Docker不会在容器删除时删除其挂载的数据卷(类比Redis中的RDB或AOF文件,同时也可以类比VMWare中的共享文件夹),实现将Docker Container中的数据内容保存在宿主机的磁盘中。
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名或镜像ID
--privileged=true
docker inpect
命令查看容器数据卷的挂载情况docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:读写模式 镜像名或镜像ID
docker run -it --privileged=true --volumes-from c1 --name c2 ubuntu
使用Docker实现Mysql服务
docker pull mysql:5.7
(基于方便哥们整了个Mysql tag 5.7版本的,Mysql8用户密码加密策略更新过 用起来有点烦)$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
docker -p ip:Port:containerPort
即可完成docker -v /data/mysql/log:/var/log/mysql -v /data/msyql/data:/var/lib/mysql -v /data/mysql/conf:/etc/mysql/conf.d
使用Docker实现Mysql主从复制
使用Docker配置Mysql主从复制拢共分三步
docker run -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
创建,处理好数据卷挂载后,在宿主机上处理一下Mysql主机的配置后重启://mysql主机配置 my.cnf
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=101
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
//mysql从机配置 my.cnf
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=mall-mysql-slave1-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log配置中继日志
relay_log=mall-mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
## slave设置为只读(具有super权限的用户除外)
read_only=1
//在mysql主机中创建数据同步从机用户
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
//在Mysql从机中配置好主从复制后开启主从复制
change master to master_host='宿主机ip', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;
DockerFile是用来构建Docker镜像的文本文件,是由多条命令与参数组成的脚本。编写好DockerFile后,使用docker build
就可以构建出自定义镜像,使用docker run
就可以运行该镜像的容器实例。
docker commit
的操作提交一个新的镜像层FROM
第一条命令必须是FROM
,表示新镜像是基于那个基础镜像的,指定一个已经存在的镜像作为模版MAINTAINER
维护镜像的作者姓名与邮箱地址RUN
容器构建时需要运行的命令,分为两种格式(与CMD
不同,是在容器构建的时候运行)
RUN <命令行指令>
,如RUN apt-get install vim
RUN ["可执行文件","参数1","参数2"]
,如RUN ["./test.php","dev","offline"]
,等价于RUN ./test.php dev offline
EXPOSE
当前容器对外暴露出的端口WORKDIR
指定在创建容器后,终端默认登陆进来的工作目录USER
指定以什么样的用户身份执行,默认是RootENV
用来在构建镜像过程中设置环境变量。这个环境变量那个在后续的任何RUN
指令中都可以使用(真·环境变量),当然在其他指令中也可以直接使用,如ENV MY_PATH /var/log/testPath
,WORKDIR $MY_PATH
ADD
将宿主机目录下的文件拷贝进入镜像,并且会自动处理URL和解压tar压缩包COPY
类似ADD
,可以将宿主机目录下的文件复制到镜像中指定目录下,如COPY src dest
VOLUME
数据容器卷,用于数据保存和持久化工作CMD
指定容器在启动后要干的事情。DockerFile中可以有多个CMD
指令,但是只有最后一个生效,并且CMD
会被docker run
后面的参数替换(与RUN
不同,是在容器运行docker run
的时候运行)
CMD <命令>
CMD ["可执行文件","参数1","参数2"]
,在使用ENTRYPOINT
指定了指令后,使用CMD
指定具体的参数ENTRYPOINT
同样是用来指定一个容器在启动时要运行的命令,但是ENTRYPOINT
不会被docker run
后面的参数覆盖,而且这些命令行参数会被当作参数送给ENTRYPOINT
指令指定的程序ENTRYPOINT ["","",""]
。可以与CMD
一同使用,一般是在变参的时候才会使用CMD
,这时CMD
相当于在给ENTRYPOINT
传参。如果DockerFile中存在多个ENTRYPOINT
指令,只有最后一个生效。如:FROM nginx
ENTRYPOINT ["nginx","-c"]#定参
CMD ["/etc/nginx/nginx.conf"]#变参
当命令为docker run nginx:test 时,实际运行的是docker run nginx:test -c /etc/nginx/nginx.conf
当命令为docker run nginx:test -c /etc/nginx2.conf 时 实际运行的是 docker run nginx:test -c /etc/nginx2.conf
docker build -t 新镜像名:tag .
创建镜像FROM centos
MAINTAINER zephyer<jarwu@zynga.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash
的镜像为虚悬镜像(dangling image)。当用户创建一个复用一个tag或者在构建镜像失败时,有可能会产生虚悬镜像。虚悬镜像已经失去了存在的价值,可以直接删除。可以使用docker images ls -f dangling=true
查看所有虚悬镜像,使用docker image prune
删除所有虚悬镜像。