Docker入门教程

Docker

1.为什么会出现docker这个技术

一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心许多东西,这也是很多互联网公司不得不面对的问题,特别是各个版本迭代之后,不同版本环境的兼容,对运维人员都是考验。

Docker之所以会发展如此迅速,是因为它对以上问题给出了一个标准的解决方案。

环境配置如此麻烦,换一台机器就要重新来一次,费时费力。很多人想到,能不能从根本解决问题,软件可以带环境一起安装?也就是说,安装的时候,把原始的环境一模一样的复制过来。开发人员的利用Docker可以消除协作编码时“在我的机器上可以正常运行”的问题。

Docker可以将能运行一个应用程序的所有环境及配置一起打包,形成一个镜像。将这个镜像通过docker复制到另一台机器上,那么这台机器也就具有了原始机器上的环境和配置。那么这个应用程序也将可以运行在当前这台机器上。

2.docker的理念、概念

Docker是基于Go语言实现的云开源项目。

Docker的主要目标是:”Build,Ship and Run Any App,Anywhere“,也就是通过对应用组件的封装,分发,部署,运行等生命周期的管理,使用户的App(可以是一个Web应用或数据库应用等等)及其运行的环境能够做到“一次封装,到处运行”。

Linux容器技术的出现解决了这样的一个问题,而Docker就是在它的基础上发展过来的。将应用运行在Docker容器上面,而Docker容器在任何操作系统上都是一致的,这就实现了跨平台,跨服务器。只需要一次配置好环境,换到别的机器上就可以一键部署好。大大简化了操作。
在这里插入图片描述

2.1 docker能干什么

  • 更快速的交付和部署
  • 更快捷的升级和扩缩容
  • 更简单的系统维护

2.2 一句话描述docker

docker是解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。

2.3 docker容器虚拟化对比传统虚拟机

在这里插入图片描述

传统虚拟机docker容器
磁盘占用几个GB到几十个GB左右几十MB到几百MB左右
CPU内存占用虚拟操作系统非常占用CPU和内存Docker引擎占用极低
启动速度(从开机到运行项目)几分钟从开启容器到运行项目)几秒
安装管理需要专门的运维技术安装、管理方便
应用部署每次部署都费时费力从第二次部署开始轻松简捷
耦合性多个应用服务安装到一起,容易互相影响每个应用服务一个容器,达成隔离
系统依赖需求相同或相似的内核,目前推荐是Linux

3.docker的三大要素

  • 镜像:一台机器上打包好的应用程序和其依赖的环境配置。镜像可以创建容器,相当于模板,一个镜像可以创建多个容器
  • 容器:Docker利用容器独立运行 一个或一组应用。容器是由镜像创建的运行实例。
  • 仓库:仓库是集中存放镜像的地方。类似Maven的中心仓库,或者github一样。

镜像和容器的关系类似于面向对象编程中的类和对象的关系

docker面向对象思想
镜像
容器对象

4.docker的安装

centOS中Docker的安装要求必须在6.5版本以上。这里是以centOS7.2作为演示
1.如果之前安装过docker要先卸载之前安装过的。执行以下命令

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
**注意:\在此没有特别大的含义,就是换行的意思,为了让我们看到此处都卸载了什么东西

2.安装docker所需要的包和一些存储驱动程序

yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

3.使用以下命令设置稳定存储库

yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

4.安装最新版本的 docker社区版(Docker CE)这一步会需要较长的时间,请耐心等待

yum install -y docker-ce docker-ce-cli containerd.io

5.启动docker

systemctl start docker

6.通过运行 hello-world 镜像验证是否正确安装了Docker CE 。

docker run hello-world

看到如下效果表名docker安装完成无误
在这里插入图片描述
附:配置阿里云镜像(加速)
针对Docker客户端版本大于 1.10.0 的用户
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
添加如下配置文件
{
“registry-mirrors”: [“https://jj77rbsb.mirror.aliyuncs.com”]
}
systemctl daemon-reload
systemctl restart docker
阿里云配置说明:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
docker官网安装教程:https://docs.docker.com/install/linux/docker-ce/centos/
此处的安装步骤也是摘自docker官网

5.docker run的运行流程

在这里插入图片描述33在这里插入图片描述

6.docker的常用命令

6.1 辅助命令

docker version	--------------------------	查看docker的信息
docker info		--------------------------	查看更详细的信息
docker --help	--------------------------	帮助命令

6.2 镜像命令

docker images	--------------------------	列出本地所有镜像
	-a			列出所有镜像(包含中间映像层)
    -q			只显示镜像id
    --digests	显示镜像摘要信息
    --no-trunc	显示完整的镜像信息
docker search [options] 镜像名	-------------------	去dockerhub上查询当前镜像
	-s 指定值    列出收藏数不少于指定值的镜像
    --no-trunc	显示完整的镜像信息
ocker pull 镜像名[:TAG|@DIGEST]	----------------- 下载镜像
docker rmi 镜像名	--------------------------  删除镜像
	-f	   强制删除

6.3 容器命令

docker run 镜像名	--------------------------	根据镜像新建并启动容器
	-i							以交互模式运行容器,通常与-t同时使用
	-t							为容器重新分配一个伪终端,通常与-i同时使用
	--name 别名				    为容器起一个名字
	-d							启动守护式容器(在后台启动容器)
	-p 映射端口号:原始端口号		指定端口号启动
	-P							主机自动分配端口号
例:docker run -it --name myTomcat -p 8888:8080 tomcat
    docker run -d --name myTomcat -P tomcat
docker ps	--------------------------	列出所有正在运行的容器
	-a			正在运行的和历史运行过的容器
	-l			显示最近创建的一个容器
	-n 数值	    显示最近n个创建的容器
	-q			静默模式,只显示容器编号
	--no-trunc	不截断输出(默认截断过长的列)
docker rm -f $(docker ps -aq)	--------------------------	删除所有容器
此处是命令的嵌套,类似于sql的嵌套查询
docker start 容器名字或者容器id  --------------- 开启容器
docker restart 容器名或者容器id  --------------- 重启容器
exit		--------------------------	容器停止退出
Ctrl+q+p	--------------------------	容器不停止退出 
docker stop 容器名或者容器id 	 ------------------ 正常停止容器运行
docker kill  容器名或者容器id     ------------------ 立即停止容器运行
docker logs [OPTIONS] 容器id或容器名	------------------ 查看容器日志
	-t			 加入时间戳
	-f			 跟随最新的日志打印
	--tail 数字	 显示最后多少条
docker top 容器id或者容器名 ------------------ 查看容器内的进程
docker inspect 容器id ------------------ 查看容器内部细节
docker attach 容器id ------------------  重新进入容器
docker exec [options] 容器id 容器内命令 ------------------ 进入容器执行命令
	-i		以交互模式运行容器,通常与-t一起使用
	-t		分配一个伪终端
这个命令较为常用,通常使用"docker exec -it 容器名/容器id"进入到该容器中查看一些重要信息
docker cp 容器id:容器内资源路径 宿主机目录路径  -----------------   将容器内资源拷贝到主机上
这个命令可是完成双向拷贝,从容器到宿主机和从宿主机到容器,只需将两个路径交换位置即可
docker commit -a="作者" -m="描述信息" 容器ID 目标镜像名称:TAG
把一个容器副本打包镜像
例:docker commit -a="zk" -m="witout docs" b35d35f72b8d zk/mytomcat:1.2
	1.充dockerHub上下载tomcat镜像到本地并成功运行
	2.故意删除上一步镜像产生的容器的doc目录
	3.以当前没有doc目录的tomcat为模板commit生成一个新的镜像
	4.启动新的镜像并和原来的对比
这个命令也较为重要,根据容器去自定义镜像

7.docker的镜像原理

7.1 镜像是什么

镜像是一种轻量级的,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时所需的库、环境变量和配置文件。

7.2 为什么一个镜像会那么大

镜像是一个千层饼。

7.3 UnionFS(联合文件系统)

Union文件系统是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

7.4 Docker镜像加载原理

docker的镜像实际是由一层一层的文件系统组成。

bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。在docker镜像的最底层就是bootfs。这一层与Linux/Unix 系统是一样的,包含boot加载器(bootloader)和内核(kernel)。当boot加载完后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时会卸载bootfs。

rootfs(root file system),在bootfs之上,包含的就是典型的linux系统中的/dev,/proc,/bin,/etc等标准的目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu/CentOS等等。

我们平时安装进虚拟机的centos都有1到几个GB,为什么docker这里才200MB?对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令,工具,和程序库就可以了,因为底层直接使用Host的Kernal,自己只需要提供rootfs就行了。由此可见不同的linux发行版,他们的bootfs是一致的,rootfs会有差别。因此不同的发行版可以共用bootfs。
在这里插入图片描述

7.5 为什么docker镜像要采用这种分层结构

最大的一个好处就是资源共享。比如:有多个镜像都是从相同的base镜像构建而来的,那么宿主机只需在磁盘中保存一份base镜像。同时内存中也只需要加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

特点:Docker镜像都是只读的。当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称为容器层,容器层之下都叫镜像层。

8.docker的数据卷

8.1 数据卷是什么

简单来说就是做数据持久化的。类似磁带,移动硬盘或者U盘。或者类似Redis中的rdb和aof文件。主要做容器数据的持久化和容器之间数据共享。卷就是目录或者文件,存在一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System 提供一些用于持久储存或者共享数据的特性。卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此docker不会在容器删除时删除其挂载的数据卷

8.2 数据卷的特点

  • 数据卷可在容器之间共享或重用数据。
  • 卷中的更改可以直接生效。
  • 数据卷中的更改不会包含在镜像的更新中。
  • 数据卷的生命周期一直持续到没有容器使用它为止。
  • 数据卷也可以完成主机到容器或容器到主机之间的数据共享。

8.3 添加数据卷

容器内添加数据卷有两种办法。第一种直接命令添加。第二种是用DockerFile添加。

8.3.1 命令添加

1.添加

命令:docker run -it -v /宿主机的路径:/容器内的路径 镜像名
例子:docker run -it -v /hostDataValueme:/containerDataValueme centos

2.查看数据卷是否挂成功
运行 docker inspect 容器id 命令 检查json串里有没有以下内容,如果有则证明卷挂载成功。

"Mounts": [
            {
                "Type": "bind",
                "Source": "/hostDataValueme",
                "Destination": "/containerDataValueme",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ]

之后可检查容器与主机是否可以共享资源。或者容器关闭之后,再开启容器之后能不能读取并加载主机的卷中数据。
设置容器内数据卷只读

命令:docker run -it -v /主机路径:/容器内路径:ro 镜像名
例子:docker run -it -v /hostDataValueme:/containerDataValueme:ro centos

检查容器相关信息

"Mounts": [
            {
                "Type": "bind",
                "Source": "/hostDataValueme",
                "Destination": "/containerDataValueme",
                "Mode": "ro",
                "RW": false,
                "Propagation": "rprivate"
            }
        ]
8.3.2 Dockerfile添加

什么是Dockerfile
简单来说就是一个镜像的描述文件。
1. 在某个目录下新建一个file(Dockerfile),在该file中添加以下脚本
例如:在/目录下创建一个mydocker的文件夹,在该文件夹下创建Dockerfile文件,并添加如下内容

# volume test
FROM centos
VOLUME ["/containerDataValueme1","/containerDataValueme2"]
CMD echo "finished,-------success!"
CMD /bin/bash

备注:可在dockerfile中使用volume指令来给镜像添加一个或多个数据卷。
2.build后生产镜像 (用编写好的Dockerfile文件构建镜像)

docker build -f /mydocker/dockerfile -t zk/centos .
	-f	指定dockerfile文件路径 
	-t	指定目标镜像名称
	.	在当前文件夹

当镜像创建出来后,以当前镜像运行一个容器实例。这时会发现,容器中已经有了我们之前写好的数据卷,但是容器里数据卷要和主机进行数据共享。那么主机的数据卷体现在哪里?别急,虽然我们不能用dockerfile指定主机的卷。但是docker会为我们提供了默认的主机数据卷。
运行docker inspect 检查一下,就会发现:

"Mounts": [
         {
             "Type": "volume",
             "Name": "459e7a4be53a96eee859f11d10bc0b26a6a91bbd6754ecb8e355e9fe4a31e0b9",
             "Source": "/var/lib/docker/volumes/459e7a4be53a96eee859f11d10bc0b26a6a91bbd6754ecb8e355e9fe4a31e0b9/_data",
             "Destination": "/containerDataValueme2",
             "Driver": "local",
             "Mode": "",
             "RW": true,
             "Propagation": ""
         },
         {
             "Type": "volume",
             "Name": "4bf41829e4afaebbb40cf3d0d4725343980afffa04f09a30680fa957d80b6af4",
             "Source": "/var/lib/docker/volumes/4bf41829e4afaebbb40cf3d0d4725343980afffa04f09a30680fa957d80b6af4/_data",
             "Destination": "/containerDataValueme1",
             "Driver": "local",
             "Mode": "",
             "RW": true,
             "Propagation": ""
         }

在这里插入图片描述
使用Dockerfile构建镜像的好处
出于可移植性的分享的考虑,用-v这种方式不能够直接在Dockerfile中实现。
由于宿主机目录是依赖于特定宿主机的,并不能保证在所有的宿主机上都存在这样的特定目录。

9.Dockerfile解析

9.1 什么是Dockerfile

Dockerfile是用来构建docker镜像的构建文件,是由一系列命令和参数构成的脚本。
Dockerfile内容基础知识

  • 指令都必须为大写,且后面都要跟至少一个参数。
  • 指令按照从上到下,顺序执行。
  • #表示注释。
  • 每条指令都会创建一个新的镜像层,并对镜像进行提交。

Dockerfile中的保留字

保留字作用
FROM当前镜像是基于哪个镜像的
MAINTAINER镜像维护者的姓名和邮箱地址
RUN容器构建时需要运行的指令
EXPOSE当前容器对外暴露出的端口号
WORKDIR指定在创建容器后,终端默认登录进来的工作目录,一个落脚点
ENV用来在构建镜像过程中设置环境变量
ADD将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar包
COPY类似于ADD,拷贝文件和目录到镜像中
将从构建上下文目录中<原路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
VOLUME容器数据卷,用于数据保存和持久化工作
CMD指定一个容器启动时要运行的命令
Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
ENTRYPOINT指定一个容器启动时要运行的命令
ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及其参数
ONBUILD当构建一个被继承的Dockerfile时运行命令,父镜像在被继承后父镜像的onbuild被触发

9.2 Dockerfile构建过程解析

1.Docker从基础镜像运行一个容器
2.执行一条命令并对容器进行修改
3.执行类似docker commit的操作提交一个新的镜像层
4.docker再基于刚提交的镜像运行一个新容器
5.执行dockerfile中的下一条指令直到所有指令都执行完毕

9.3 小总结

1.从应用软件的角度来看,Dockerfile、docker镜像、docker容器分别代表软件的三个不同阶段
Dockerfile 是软件的原材料
docker镜像是软件的交付品
docker容器可以认为是软件的运行状态
2.Dockerfile面向开发,docker镜像成为交付标准,docker容器则涉及部署与运维,三者缺一不可,合力充当docker体系的基石。
在这里插入图片描述
1.Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、进程服务和内核进程(当应用就进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等
2.docker镜像,在用Dockerfile定义一个文件之后,docker build 时会产生一个docker镜像,当运行docker镜像时,会真正开始提供服务
3.docker容器,容器是直接提供服务的

10.Dockerfile案例

Base镜像(scratch): Docker Hub中99%的镜像都是由base镜像中安装和配置需要的软件构建出来的。

10.1 自定义镜像mycentos

1.先了解dockerhub上的centos镜像时什么样的
Hub上的centos镜像默认落脚点是/,默认不支持vim。那么现在我们想自定义一个centos,改变其默认落脚点,让其支持vim。
2.编写Dockerfile

FROM centos
MAINTAINER ZK<15010102217@163.com>
ENV MYPATH /tmp
WORKDIR $MYPATH
RUN yum -y install vim
EXPOSE 80
CMD echo $MYPATH
CMD echo "build-------success"
CMD /bin/bash

3.构建镜像

docker build -f /mydocker/dockerfile -t zk/mycentos .

4.运行容器

docker run -it zk/mycentos

10.2 自定义镜像mytomcat

1. 先创建/mydocekrfile/tomcat这个目录
将tomcat和jdk8的tar包放进此目录下。然后创建一个Dockerfile文件。
2.编写Dockerfile

FROM centos
MAINTAINER zk<15010102217@163.com>
#把宿主机当前上下文的c.txt拷贝进容器的/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
#把tomcat和jdk的tar包拷贝到容器中
ADD apache-tomcat-9.0.22.tar.gz /usr/local/
ADD jdk-8u171-linux-x64.tar.gz /usr/local/
#安装vim编辑器
Run yum -y install vim
#设置登录落脚点/usr/local
ENV MYPATH /usr/local/
WORKDIR $MYPATH
#配置java和tomcat的环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.22/bin/startup.sh"]
# CMD ["/usr/local/apache-tomcat-9.0.22/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out

3.构建镜像

docker build -t zk/mytomcat .
这里没写-f是因为如果在当前目录下并且file文件名为正统的Dockerfile 那么-f可以省略不写

4.运行容器

docekr run -d -p 8888:8080 --name mytomcat -v /zk/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v /zk/tomcat/logs:/usr/local/apache-tomcat-9.0.22/logs --privileged=true zk/mytomcat
##这个命令有点长,你可以将其复制下去仔细看一下,共挂载了连个数据卷
##解释:创建数据卷,让容器中的webapps目录中的项目目录和主机中test目录做一个映射

10.3 总结

在这里插入图片描述

11.docker安装mysql

11.1 在DockerHub上查找mysql镜像

docker search mysql

11.2 将mysql拉取到本地

docker pull mysql:5.6

11.3 运行mysql容器

docker run -p 12345:3306 --name mysql -v /zk/mysql/conf:/etc/mysql/conf.d -v /zk/mysql/logs:/logs -v /zk/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6

11.4 具体操作

进入这个容器 。 docker exec -it 容器id /bin/bash

进入mysql 。  mysql -u root -p 

输入密码 123456

查询mysql的库  。  show databases

创建数据库  。  create database db01;

切换到db01.     use db01;

建表 。  create table t_book(id int not null primary key, name varchar(20));

查询所有表。  show tables;

向表中插入一条数据。  insert into t_book values(1,'java');

查询这张表的数据 。select * from t_book;

用我们外部win10的大黄navcat尝试连接这个mysql

数据备份测试 。docker exec mysql容器id sh -c 'exec mysqldump --all-database -u root -p "123456"' > /gzcusr/all-databases.sql

12.docker安装redis

12.1 在DockerHub上查找redis镜像

docker search redis

12.2 将redis拉去到本地

docker pull redis:4.0.14

12.3 运行redis容器

docker run -p 6379:6379 --name redis -v /zk/redis/data:/data -v /zk/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis:4.0.14 redis-server /usr/local/etc/redis/redis.conf --appendonly yes

12.4 具体操作

在主机的/zk/redis/conf/redis.conf目录下新建redis.conf文件,
vim /zk/redis/conf/redis.conf/redis.conf

在里面写入redis配置。(去虚拟机redis中找到相关的配置文件拷贝一下就OK了)

连接redis 。 docker exec -it 容器id redis-cli

在里面写入几个键值。关闭走人。

回到主机/zk/redis/data目录下检查有没有aof文件。

13.远程仓库的使用

具体参见阿里云即可
https://cr.console.aliyun.com/cn-hangzhou/instances/repositories

14.docker集成idea

参见笔者另外一篇博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

难过的风景

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值