Docker 快速入门学习

Docker学习

阅读声明:
1.本文为个人学习笔记,内有多图,需要看图片中的控制台的代码,以便理解;
2.文中所出现的服务器ip地址与暴露端口均为无效地址。服务器实例已被注销,请 勿尝试连接或进行无效的攻击。维护网络秩序,你我有责;
3.文章中的图部分引用与网络,侵权请联系删除;
4.部分知识理解均为个人见解,若有不当之处,欢迎指出,共同交流学习。

1. Docker 为什么会出现?

一款产品必经之路 开发 -> 上线,dev 与 prod 是两个环境。配置端口、配置环境都不同,每一个机器都要部署环境,配置起来非常麻烦,还可能出错。

常常会出现这样一种情况:程序在我的电脑上可以运行,换了个地方就不行了。

环境版本更新,导致服务不可用

在服务器配置应用环境,不能跨平台(windows 开发 -> Linux 上线)

于是,我们希望,发布一个项目可以连带环境一起打包 jar ->(jar + (Redis MySQL jdk) 一起上线?

Docker 给以上的问题,提出了解决方案

Java — jar(环境)— 打包项目带上环境(镜像)— (Docker仓库)— 下载镜像即可运行

2. Docker能做什么

Docker与虚拟机技术的不同

  • 传统虚拟机,虚拟出一套硬件,运行一个完整的操作系统,然后再这个系统上安装和运行软件
  • 容器内的应用直接运行在宿主机的内容,容器时没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
  • 每个容器间时相互隔离,每个容器内都有一个属于自己的文件系统,互不影响。

DevOps(开发、运维)

应用更快速的交付和部署

传统:一堆帮助文件,安装程序

Docker:打包镜像发布测试,一键运行

更便捷的升级和扩缩容

使用Docker之后,部署应用就像搭积木

项目打包成一个镜像,拓展 服务器A 拓展服务器B

更简单的系统运维

在容器化之后,我们的开发,测试环境都是高度一致的,不存在说“我的电脑能运行的情况了”

更高效的计算机资源利用

Docker是内核级别的虚拟化,可以在一个物理机上运行很多个容器实例,服务器的性能可以被压榨到极致。

3. Docker的组成

Docker 快速入门学习_第1张图片

image: docker镜像就好比一个模板,可以通过这个模板来创建容器服务,tomcat镜像 -> run -> tomcat01容器(提供服务),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。

container: Docker 利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的

启动、停止、删除、基本命令

目前就可以把这个容器理解未就是一个建议的 linux 系统

repository: 仓库就是存放镜像的地方,仓库分为公有仓库和私有仓库

4. 环境准备

  1. 需要会Linux基础
  2. CentOS 7
  3. 使用 Xshell 连接远程服务器进行操作

5. Docker的安装

安装Docker

  1. 安装yum插件

    yum install -y yum-utils

Docker 快速入门学习_第2张图片

看到后面的Complete!即表示插件安装成功

  1. 设置镜像的仓库为阿里云镜像仓库

    yum-config-manager
    –add-repo
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

在这里插入图片描述

  1. 更新yum软件包索引

    yum makecache fast

Docker 快速入门学习_第3张图片

  1. 安装docker镜像 docker-ce 社区 docker-ee 企业版 默认安装最新版

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

安装的过程中有两个地方需要输入y

Docker 快速入门学习_第4张图片

等待片刻,最后出现Complete!即是安装完成

在这里插入图片描述

  1. 启动docker服务

    systemctl start docker

在这里插入图片描述

这样即表示启动成功

如果你还不相信的话,你可以输入个

docker version

来查看安装的版本号

在这里插入图片描述

  1. 运行Hello world程序

    docker run hello-world

Docker 快速入门学习_第5张图片

  1. 查看下载的镜像

    docker images

在这里插入图片描述

  1. 卸载docker

    1. 卸载依赖

    yum remove docker-ce docker-ce-cli containerd.io

    2. 删除资源

    rm -rf /var/lib/docker

    /var/lib/docker 是docker的默认资源路径

6. 配置阿里云镜像加速

配置阿里云镜像加速


Docker 快速入门学习_第6张图片
Docker 快速入门学习_第7张图片

Docker 快速入门学习_第8张图片

分别执行以下4个命令

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://jqwynzjh.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

在etc下创建docker目录

在这里插入图片描述

更换docker镜像

Docker 快速入门学习_第9张图片

重新加载配置文件 重启docker

在这里插入图片描述

7. 底层原理

简单的Hello-World程序是怎么执行的?

Docker 快速入门学习_第10张图片

底层原理

Docker 是怎么工作的?

Docker 是一个Client - Server 结构的系统,Docker的守护进程运行在主机上,通过Socker从客户端访问,DockerServer 接收到 Docker - Client 的指令,就会执行这个命令。

Docker 快速入门学习_第11张图片

Docker 为什么比VM快?

  1. Docker有着比虚拟机更少的抽象层,由于Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在Cpu、内存利用率上Docker将会在效率上有明显优势。

  2. Docker利用的是宿主机的内核,而不需要Guest OS,因此,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统,避免了引导、加载操作系统内核这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的,而Docker由于直接利用宿主机的操作系统则省略了这个过程,因此新建一个Docker容器只需要几秒钟。

Docker 快速入门学习_第12张图片

Docker 快速入门学习_第13张图片

8. docker 的常用命令

帮助命令

1. 帮助命令

docker version # 查看版本信息

Docker 快速入门学习_第14张图片

docker info # 显示docker的系统信息,包括镜像和容器的数量

Docker 快速入门学习_第15张图片

下面还有一些系统硬件配置的信息

docker <指令> --help # 帮助命令

当然,还需要帮助文档

https://docs.docker.com/reference/

Docker 快速入门学习_第16张图片

2. 镜像命令

docker images # 查看所有本地的主机上的镜像

在这里插入图片描述

  • REPOSITORY:镜像的仓库源

  • TAG:镜像的标签

  • IMAGE ID:镜像的ID

  • CREATED:创建的时间

  • SIZE:镜像的大小

    docker search # 从docker hub上搜索镜像

    可选操作

    –filter 过滤搜索结果
    docker search mysql --filter=STARS=3000 # 搜索STARS大于3000的结果

在这里插入图片描述

docker pull # 从docker hub上下载镜像

docker pull 镜像名 [:tag版本号] 不写的tag话默认就是最新版本

Docker 快速入门学习_第17张图片

指定版本下载

Docker 快速入门学习_第18张图片

可以看到上面的Already exists,已经下载好的文件就可以共用,而不用再次下载,可以极大的节省内存,这就是linux联合文件系统的优点。

docker rmi 删除镜像
docker rmi -f 镜像id # 删除指定的容器
docker rmi -f 镜像id 镜像id # 删除多个容器
docker rmi -f $(docker images -aq) # 删除全部的容器

9. 容器命令

说明:有了镜像才可以创建容器,Linux,下载一个centos镜像(75.4MB)来测试学习。

docker pull centos

Docker 快速入门学习_第19张图片

新建容器并启动

docker run [可选参数] image

# 参数
--name="Name" 容器名字 tomcat01 tomcat02,用来区分容器
-d            后台方式运行
-it           使用交互方式运行,进入容器查看内容
-p            指定容器的端口 -p 8080:8080
	-p ip:主机端口:容器端口
	-p 主机端口:容器端口
	-p 容器端口
	容器端口
-p            随机指定端口

docker run -it centos /bin/bash 启动并进入容器

Docker 快速入门学习_第20张图片

在容器内 使用 ls 指令发现和外部其实是一样的,这就是一个小型的服务器

服务器
在这里插入图片描述

镜像
在这里插入图片描述

退出并停止容器 exit

退出容器控制台 不停止容器 ctrl + p + q

在这里插入图片描述

查看运行中的容器

docker ps # 查看当前正在运行的容器
docker ps -a # 查看 当前 + 历史 运行的容器
docker ps -n=n # 显示最近创建的n个容器
-q # 只显示容器的编号

在这里插入图片描述

删除容器

docker rm 容器id # 不能删除正在运行的容器,如果要删除的话需要加 -f
docker rm -f $(docker ps -aq)

Docker 快速入门学习_第21张图片

启动和停止容器

docker start 容器id   # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id    # 停止当前正在运行的容器
docker kill 容器id    # 强制停止当前容器

Docker 快速入门学习_第22张图片

10. 常用的其它命令

1. 后台启动容器

# 命令 docker run -d 镜像名:
docker run -d centos

Docker 快速入门学习_第23张图片

我们发现 centos 停止了

原因: docker 容器使用后台运行,就必须要有一个前台进程(比如说 -it 的那个界面就是前台应用),docker发现没有应用,就会自动停止

2. 查看日志

docker logs
docker logs -tf -tail N 容器Id	# 查看指定容器的最新N条记录

# 参数解释
-t 			# 日志加时间
-f			# 保留打印窗口,持续打印
--tail N 	# 显示最后的N行

3. 查看容器中的进程信息

docker top 容器Id

在这里插入图片描述

UID

PID

PPID

C

STIME

TTY

当前用户

当前进程ID

父进程ID

CPU 使用率

开始时间

终端

4. 查看镜像的源数据

docker inspect 容器ID

Docker 快速入门学习_第24张图片

5. 进入当前正在运行的容器

# 我们通常容器都是使用后台方式运行的,需要进入,修改一些配置

# 方式一
docker exec -it 容器ID

在这里插入图片描述

# 方式二
docker attach 容器ID

在这里插入图片描述

区别:

docker exec 进入容器后开启一个新的终端,可以在里面操作(常用)

docker attach 进入容器正在进行的终端,不会启动新的进程

6. 容器内拷贝文件到主机上

docker cp 容器ID:/路径/文件 主机的位置

# 案例
[root@e9e64b2c885b /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@e9e64b2c885b /]# cd /home
[root@e9e64b2c885b home]# ls
[root@e9e64b2c885b home]# touch test.txt
[root@e9e64b2c885b home]# ls
test.txt
[root@e9e64b2c885b home]# exit
exit
[root@iZf8zflm213bcx02dl4vxeZ ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED        STATUS                     PORTS     NAMES
e9e64b2c885b   centos    "/bin/bash"   31 hours ago   Exited (0) 4 seconds ago             strange_kapitsa
[root@iZf8zflm213bcx02dl4vxeZ ~]# docker cp e9e64b2c885b:/home/test.txt /home
[root@iZf8zflm213bcx02dl4vxeZ ~]# cd /home
[root@iZf8zflm213bcx02dl4vxeZ home]# ls
test.txt

7. 常用的命令总结

命令图

Docker 快速入门学习_第25张图片

11. 案例一:安装Nginx

1. 寻找镜像 docker search Nginx

Docker 快速入门学习_第26张图片

2. 下载镜像docker pull Nginx (注意: 镜像名一定要小写)

Docker 快速入门学习_第27张图片

3. 查看镜像 docker images

Docker 快速入门学习_第28张图片

4.后台运行Nginx

docker run -d --name nginx01 -p 3344:80 nginx

-p 宿主机端口:容器内端口

Docker 快速入门学习_第29张图片

外网访问

Docker 快速入门学习_第30张图片

12. 案例二:安装Tomcat

# 官方文档的安装方式
docker run -it --rm tomcat:9.0

# 属性解释
-it # 后台运行
--rm # 运行之后立刻把容器删除,用于测试

Docker 快速入门学习_第31张图片

Docker 快速入门学习_第32张图片

用这种方式启动的容器,一旦退出就会被删除

CTRL C 停止服务,使用docker ps 查看记录,并无此记录,不过镜像还是在的

Docker 快速入门学习_第33张图片

docker images 查看镜像发现 tomcat 还在

Docker 快速入门学习_第34张图片

正常启动 tomcat

值得注意的是:当你的容器镜像不是最新版的时候,若不带版本号,docker就会到docker hub上面给你下载了最新版然后启动。

Docker 快速入门学习_第35张图片

访问tomcat

在这里插入图片描述

Docker 快速入门学习_第36张图片

为什么会是404页面而不是tomcat欢迎页面呢?

由于docker镜像默认是最小的镜像,所有不必要的文件都剔除了,保证最小可运行的环境,因此webapps目录下是空白的,我们可以通过手动往webapps目录中添加文件即可。项目的发布也是如此。

13. 可视化

portainer:Docker图形化界面管理工具

docker run -d -p 8088:9000 

–restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

Docker 快速入门学习_第37张图片

在外网中打开(http://Ip/端口号),第一次加载会比较久

加载出来后,第一次登录需要设置密码

Docker 快速入门学习_第38张图片

选择本地连接

Docker 快速入门学习_第39张图片

Docker 快速入门学习_第40张图片

14. Docker 镜像详解

1. 镜像是什么?

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

  • 所有的应用都可以直接打包成docker镜像,放到容器中运行

  • 镜像的获取可通过远程仓库下载或者自己制作(DockerFile)

2. 镜像加载原理

UnionFS (联合文件系统)

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

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

15. 创建镜像

docker commit 提交容器成为一个新的镜像

# 与git相似
docker commit -m="提交的描述信息" -a="读者" 容器id 新的镜像名:[tag]

案例:创建一个自己的tomcat

我们发现tomcat默认是没有欢迎页面的,我们需要加上去

Docker 快速入门学习_第41张图片

外网访问,出现欢迎页面,这就是我们想要的tomcat

Docker 快速入门学习_第42张图片

提交镜像

docker commit -a="Aldrich" -m="add an index for tomcat" 3397174e6c52 mytomcat

Docker 快速入门学习_第43张图片

原理:UnionFS,在原本的tomcat基础上加多了一层再发布

Docker 快速入门学习_第44张图片

docker 进阶

16. 容器数据卷

什么是容器数据卷?

思考:在前面的学习中,我们知道,当容器运行时,数据都是存储在了容器内部的文件系统。那么当你运行 docker rm 命令的时候,容器将会连同它的文件系统一并被销毁。若这部分是有用的数据呢?比如说,上面放的是一个MySQL容器,我不希望数据会在容器销毁时消失。那唯一的解决办法就是别让数据只存到容器的文件系统,还应该保存一份到了宿主机。也就是将容器中的数据同步到本地。

这就是卷技术,目录的挂载,将我们的容器内的目录,挂载到宿主机上面。

容器数据卷有什么作用?

容器的持久化与同步操作,容器间的数据共享。

方式一:直接使用命令来挂载 -v

docker run -it -v 主机目录:容器目录

在这里插入图片描述

使用 docker inspect 查看挂载信息

Docker 快速入门学习_第45张图片

已经实现了双向绑定

Docker 快速入门学习_第46张图片

在主机这边修改文件也可以同步到容器中

Docker 快速入门学习_第47张图片

以后修改配置文件只需要在本地修改,可以自动同步到容器中!

案例:安装MySQL

思考:MySQL的数据持久化,不能当容器摧毁时,数据也丢失

docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql01 mysql

#-d 后台启动
#-p 端口映射
# -v 可以写多个
# -e 配置环境
# mysql创建的时候需要配置密码

在这里插入图片描述

这时候服务已经启动成功了,我们来测试连接

Docker 快速入门学习_第48张图片

在测试连接的时候出现了一个小插曲,数据库可视化工具报密码错误,但是通过dos窗口确实是可以登录的,无奈之下,将密码修改了一遍,就可以了。

Docker 快速入门学习_第49张图片

我们来检查一下,是否已经将数据同步了

Docker 快速入门学习_第50张图片

可以看到数据已经同步过来了,接下来我们要做一个测试,新建一个数据库

Docker 快速入门学习_第51张图片

查看data中是否同步

在这里插入图片描述

思考:将mysql容器删除,数据是否还保留在宿主机?

在这里插入图片描述

数据依然保留在本地

具名挂载与匿名挂载

上面我们使用 -v 的挂载方式是属于 指定路径挂载 ,除此之后还有两种挂载的方式:具名挂载与匿名挂载

  • 匿名挂载

    # 匿名挂载
    -v 容器内路径
    docker run -d -P --name nginx01 -v /ect/nginx nginx

    属性讲解

    -P # 使用随机端口

使用docker volume ls 查看所有volume 的情况

在这里插入图片描述

可以看到没有名称,这就是匿名挂载

  • 具名挂载

    具名挂载

    -v 名称:容器内路径
    docker run -d -P --name nginx02 -v hasName-nginx:/etc/nginx nginx

在这里插入图片描述

可以在列表中看到是具体的名称

查看一下这个卷的详细信息

docker volume inspect hasName-nginx

Docker 快速入门学习_第52张图片

所有的Docker容器内的卷,在没有指定宿主机路径的情况下,都是放在/var/lib/docker/volumes/.../_data

我们通过具名挂载可以方便的找到我们定义的卷,大多数情况都是使用 具名挂载

拓展:

# 通过 -v 容器内路径:ro 或者 rw 可以改变读写权限
ro # readOnly 只读
rw # read write 读写

# 例如
docker run -d -P --name nginx03 -v hasName-nginx:/etc/nginx:ro nginx

注意的是:一旦设置了容器的权限,容器对挂载内容就有限制!

设置了 ro 表示这个路径只能通过宿主机来改修,容器内部无法修改!

17. Dockerfile

Dockerfile 是什么?

在之前,我们提交镜像是通过 docker commit 指令来手动创建的。Dockerfile 是一种命令脚本,用于创建 docker 镜像。

快速体验

创建一个Dockerfile文件

# 创建了一个dockerfile文件,名字随意
# 文件中的内容 指令(大写!) 参数
# 命令是分层的,如同UnionFS,一层一层的构建
FROM centos

# 挂载目录
VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash

执行Dockerfile文件

Docker 快速入门学习_第53张图片

镜像生成成功

Docker 快速入门学习_第54张图片

查看挂载的目录

Docker 快速入门学习_第55张图片

这属于匿名挂载,我们可以通过查看详细信息的方式来获取挂载的路径

Docker 快速入门学习_第56张图片

创建镜像是常有的操作,主要使用的方式是Dockerfile

详细介绍

1. Dockerfile 的构建步骤

  1. 编写一个Dockerfile文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(阿里云或者docker hup)

2. Dockerfile的注意事项

  1. 每个关键字都必须是大写字母!

  2. 从上到下的顺序执行

  3. # 表示注解

  4. 每个指令都会创建一个新的镜像层并提交

Docker 快速入门学习_第57张图片

3. Dockerfile中的指令

FROM          	# 基础镜像,一切从这里开始
MAINTAINER    	# 镜像是谁写的 姓名+邮箱
RUN 			# 镜像构建的时候需要运行的命令
ADD				# 需要添加的内容 如:centos + tomcat
WORKDIR			# 镜像的工作目录
VOLUME			# 挂载的目录
EXPOSE			# 暴露端口 -p
CMD				# 指定容器启动时进行的命令,指令会替换
ENTRYPOINT		# 指定容器启动时进行的命令,指令追加在后面
ONBUILD			# 当构建一个被继承 Dockerfile 时会运行ONBUILD指令,事件机制
COPY			# 类似ADD,将命令拷贝到镜像中
ENV				# 构建的时候设置环境变量

4. Dockerfile实战

# 由于默认的centos太纯净了,vim、clear 等常用指令都没有,我们需要手动创建一个
FROM centos		# 基于centos镜像进行包装
MAINTAINER aldrich	# 作者

ENV MYPATH /user/local	# 指定环境变量
WORKDIR $MYPATH			# 设置工作目录

RUN yum -y install vim	# 安装vim
RUN yum -y install net-tools	# 安装net-tools

EXPOSE 80				# 暴露端口

CMD echo $MYPATH		# 打印一下环境变量
CMD echo "----end-----"	# 提示结束
CMD /bin/bash			# 进入/bin/bash


docker build -f 文件路径 -t 镜像名:[tag] 生成路径
docker build -f mycentos -t mycentos:1.0 .

运行测试

Docker 快速入门学习_第58张图片

  • 默认的工作目录已经改变

在这里插入图片描述

  • vim 指令已经安装

在这里插入图片描述

可以通过 docker history 容器ID 的方式来查看镜像构建步骤

Docker 快速入门学习_第59张图片


18. 数据共享

前面有说到,容器数据卷可以作为容器间的数据共享。

  • 创建一个docker01容器

Docker 快速入门学习_第60张图片

  • 使用 volumes-from 与docker01容器建立数据共享

在这里插入图片描述

--volumes-from # 与其它容器建立数据共享关系
  • 测试在docker01中添加一个文件,docker02中是否会更新

docker01创建的内容同步到了docker02

Docker 快速入门学习_第61张图片

同理docker02创建的数据也可以同步到docker01

Docker 快速入门学习_第62张图片

**思考:**当docker01被删除之后,docker02中的数据会丢失吗?

Docker 快速入门学习_第63张图片

答案是不会,当还有一个容器使用该数据,共享的数据就不会丢失。

原理图:

Docker 快速入门学习_第64张图片

与Java中的引用类型赋值相似,所以当docker01被删除了,不影响docker02

结论:

容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止,一旦持久化到本地,本地的数据是不会删除的。

你可能感兴趣的:(java,后端,docker,学习,运维)