001-Docker学习笔记
概述
最近项目中,用到了Docker技术,之前没接触过,所以从B站找了一套课程来听听,学习一下。在此整理出自己觉得重要的知识点。
B站地址分享:【狂神说Java】Docker最新超详细版教程通俗易懂 对课程的讲解者表示感谢!
Docker官网:【Docker】
Docker文档:【DockerDoc】
Docker仓库:【DockerHub】
什么是Docker?
Docker是一种容器技术,用来虚拟运行环境,主要运用在Linux操作系统中。
Docker的核心思想是什么?
隔离——集装箱
Docker有什么特点?
1,虚拟运行环境,比虚拟机使用的资源更少
- 不需要虚拟硬件。
- 利用宿主机的内核,相当于跑在宿主机上的进程(运行时占用资源少)。
- 占用的空间特别小(物理占用少)。
2,易于增加和缩减操作
- 开启一个虚拟环境速度快,相当于启动一个程序一样。
- 销毁也极其方便。
- 这样便于互联网产品的扩缩容操作。
3,带着运行环境打包发布产品,上线部署更简单
- 生成程序部署包
- 编写Dockerfile
- 生成镜像
- 编写Compose配置文件
- 一键运行,极其方便
Docker的组成包含哪些内容?
客户端(Client):通过客户端可以连接与操作Docker的内容。
Docker服务(DOCKER_HOST):通过服务来管理镜像与容器。
- 镜像:相当于类,定义了内容;
- 容器:相当于类的实例,包含了运行时的数据和功能;
镜像仓库(Registry):用来存储发布的镜像。
Docker是如何运行的?
Docker安装
根据笔记与官网教程,把安装步骤记录下来,方便安装时,直接来执行。
# 【环境准备】根据官方的要求,要做前提环境准备:1,centos-extras 启用;2,overlay2 存储方式;3,清除旧的Docker安装,执行如下命令 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
# 【安装】安装方式,有三种:1,首选是直接yum安装(需要联网,执行下面的命令即可);2,下载RPM包,手动安装或升级(适合于没网的机器上安装);3,通过脚本安装; # 安装yum-utils sudo yum install -y yum-utils
# 设置Docker仓库地址(官网) sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo # 如果觉得官网的慢,可以使用阿里云或其它国内的仓库地址(以下为阿里云地址) sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 官网
- 阿里云
# 安装Docker引擎,如果要指定版本安装,则写成这种格式:docker-ce-<VERSION_STRING>。示例:docker-ce-18.09.1。通常我们安装最新的版本。 sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 解释安装的内容
# 【docker-ce】:docker-ce表示社区版,docker-ee表示企业版
安装过程中提示,输入y回车即可。最终安装完成显示如下:
#【启动服务】Docker的服务名:docker sudo systemctl start docker
【注意】
- 如果没有设置开机启动docker服务,每次开机后,要启动后才能使用。
- 如果是VMWare的虚拟机,如果暂停后,再开启,docker服务也要重新启动一下。不然访问容器中的映射端口,会访问不到
#【验证】通过hello-world容器验证安装是否成功 sudo docker run hello-world
#【成功】 至此,Docker安装成功!!!
Docker安装附录
-
官网的说明
说实话,找官网的说明也消耗了我一些的时间-_-|||,直接进入 Docker文档:【DockerDoc】
开始以为是这个,但进入看了才发现,Docker分为桌面版和引擎版,这个里面主要是介绍桌面版的安装。而引擎版的安装在下图所示链接位置。
最后一步,对于操作系统的不同,选择不同的链接即可。
-
CentOS 8 问题
学习的时候,使用的系统是CentOS 8,安装时,报了一些错,在此把错误信息及解决方式记录下来。
当执行 sudoyuminstall docker-ce docker-ce-cli containerd.io docker-compose-plugin 安装时,报以下错误
根据提示修改命令
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin --nobest --skip-broken
执行完上述命令后,安装是完成了,但是启动docker服务时报错:没有这个服务。说明安装还是有问题,于是又重新执行了命令,如下:
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin --allowerasing
之后便可以使用了。
-
Docker中安装Docker问题
在写这篇笔记的时候,因为虚拟机上已经部署过了,且运行了一些容器,于是想通过Docker跑一个CentOS 7的容器,基于容器来安装Docker整理笔记。前面的步骤执行都很顺利,但是到启动docker服务的时候,提示没有权限:Couldn't find an alternative telinit implementation to spawn。。
于是查资料,发现,在运行容器的时候,需要授予特权,且要把宿主机的目录进行挂载。运行容器的命令如下所示:
sudo docker run -it --name "CentOS7" --privileged=true -v /sys/fs/cgroup:/sys/fs/cgroup:ro centos:7 /usr/sbin/init
-
设置阿里云镜像加速器
登陆阿里云【控制台 】,打到容器镜像服务
找到镜像加速器,执行提供的命令即可
# 命令行 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://iuditmwr.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
Docker卸载
# 【卸载引擎】 sudo yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 【删除文件】 sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd
#【成功】 至此,Docker卸载完成!!!
Docker开机启动
# 设置Docker开机启动
systemctl enable docker
Docker存储目录
# Docker的存储目录跳转
cd /var/lib/docker && ll
- 【containres】:容器的存储目录 与 docker ps -a显示的容器是对应的。
- 【image】:镜像存储目录,因为镜像通过分层管理机制,所以直接看的话不太方便,但是有个repositories.json文件,可以通过该文件进行了解。文件中的镜像与 docker images显示的镜像是对对应的。
- 【network】:网络目录 docker network ls
- 【plugins】:插件目录 docker plugin ls
- 【swarm】:swarm集群目录
- 【volumes】:卷挂载目录 docker volume ls
Docker命令
Docker 基础命令
# Docker帮助命令
docker --help
# 显示Docker的版本信息
docker version
# 查看Docker的详细信息 docker info
# 查看Docker运行状态
docker stats
# 只取当下状态显示,不会一直刷新
docker stats --no-stream
Docker 镜像命令
# 查看镜像文件
docker images
# 【REPOSITROY】:镜像在仓库中的名字
# 【TAG】:镜像的版本,最新版本为:latest
# 【IMAGE ID】:镜像的id
# 【CREATED】:创建时间
# 【SIZE】:镜像大小
# 查看所有镜像文件(default hides intermediate images,这个没理解中间是指的什么?)
docker images -a
# 只显示镜像的id
docker images -q
# 搜索镜像(从镜像仓库)
docker search 镜像名
通常不建议通过命令来搜索,建议到DockerHub上搜索,DockerHub上能更清晰的看到镜像的信息,特别是版本。
点击进入后显示如下图
# 下载镜像 docker pull 镜像名[:版本号] (如果版本号不写的话,默认是latest,即最新版)
# 【Digets】:镜像签名
# 【Status】:对镜像的描述
# 【docker.io/library/mysql:8.0】:镜像的真实地址
# 【72a69066d2fe ……】:这些值,每一个代表一个层,目的是为了最大限度的复用文件与节省空间,思想来源于Linux的联合文件系统
# 删除镜像 docker rmi 镜像名[:版本号] (或者是镜像id)
# 强制删除镜像
docker rmi -f 镜像名[:版本号] (或者是镜像id)
当由镜像产生容器或一些其它原因导致镜像直接删除删不掉时,增加该参数,可以实现强制删除
# 删除全部镜像
docker rmi $(docker images -aq)
当想要删除全部镜像时,可以利用该命令,docker images -aq,表示取到所有镜像的id,$()表示参数,将其传递给docker rmi,即可删除全部的镜像
# 查看镜像历史
docker history 镜像名[:版本号] (或者镜像id)
镜像的构建过程,也可以看作是Dockerfile的制作逻辑
# 查看详细的记录
docker history --no-trunc 镜像名[:版本号] (或者镜像id)
# 给镜像打标签
docker tag 镜像名[:版本号] 新镜像名[:新版本号]
会产生一个新的镜像和版本
# 上传镜像到镜像仓库
docker push 镜像名[:版本号]
# 上传步骤
# 1,登陆 docker login 登陆查看后面章节的具体描述
# 2,通过 docker tag 给镜像打标签
# 3,调用 docker push 进行上传
# 遇到的问题
# 解决方式
即,需要先打标签
上传,最好是上传到阿里云服务器上,具体查看网站资料,不要直接上传docker hub,因为国外的服务器特别慢
# 上传到阿里云服务器步骤
# 1,登陆阿里云
# 2,打开容器镜像服务功能
# 3,创建个人实例
# 4,创建镜像仓库-选择本地仓库
# 5,上传镜像
# 保存镜像到压缩文件
docker save -o 文件路径 镜像名[:版本号]
# 加载压缩文件为镜像
docker load -i 压缩文件路径
Docker 容器命令
# 启动容器
docker run [参数] 镜像名[:版本号]
# 给容器指定名称
docker run --name 容器名
# 后台运行 需要注意的是,当容器中没有执行的程序时,会自动结束,有时会看起来刚启动就关掉了
docker run -d
# 以交互方式进入容器 (-it由 -i 和 -t 联合起来使用)
docker run -it
# 设置端口号
docker run -p 主机端口:容器端口
设置端口的几种方式:
-p ip:主机端口:容器端口
-p 主机端口:容器端口
-p 容器端口
# 自动分配端口映射
docker run -P
# 环境配置
docker run -e 键值对
# 运行结束后即删除容器,这个参数的使用场景,一种是测试,另一种是扩缩容的时候
docker run --rm
# 设置容器自动启动
docker run --restart 标记
标记值:no(不启动-默认)、always(总是启动)
# 卷挂载
docker run -v 主机目录:容器目录
卷挂载的详细说明会在后面的小节专门描述
# 继承卷挂载
docker run --volumes-from 其它容器(可多个)
# 通过容器名可以连接另一个容器
docker run --link 其它容器[:容器别名](可多个)
在容器中的 /etc/hosts 文件中存储了映射信息
别名示例
# 设置网络
docker run --net 网络名称
启动容器时,默认使用的网络是 --net bridge
tzlnet 是自定义通过 docker network create 创建的
# 以特权模式运行容器
docker run --privileged=true
设置为true可以使容器内使用 systemctl 等命令。比如在容器中安装 Docker 便需开启该权限
【注意】经过实测验证,直接使用该参数如果报错:Couldn't find an alternative telinit implementation to spawn。
可以设置卷挂载来解决:docker run -it --name "CentOS7" --privileged=true -v /sys/fs/cgroup:/sys/fs/cgroup:ro centos:7 /usr/sbin/init
# 退出容器 exit ctrl + p + q
当我们执行run命令,或者attach、exec命令后,会进入到容器内部的命令程序,如果想退出来,需要用到上面的两种方式
【exit】:退出时,容器当前运行的线程也会退出,如果容器内没有运行的线程,容器就会结束掉;
【ctrl + p + q】:退出容器内的命令行程序,不结束容器运行的线程;
# 显示容器 docker ps
当前只显示了运行中的容器
# 显示所有的容器
docker ps -a
# 显示只显示容器id
docker ps -q
# 删除容器 docker rm 容器名(或者容器id)
# 强制删除容器
docker rm -f 容器名(或者容器id)
# 启动容器
docker start 容器名
# 重启容器
docker restart 容器名
# 停止容器
docker stop 容器名
# 杀死容器 docker kill 容器名
# 查看容器日志
docker logs 容器名
# 跟踪输出日志
docker logs -f
# 输出时间戳
docker logs -t
# 只输出最近的n条日志
docker logs -n n
# 查看容器中的进程
docker top 容器名
# 查看容器的详细信息
docker inspect 容器名
# 进入容器
docker exec -it 容器名 命令
特点是进入后,会开启一个新的线程终端
# 进入容器
docker attach 容器名
特点是附加进入容器中的某个线程终端
# 文件拷贝 docker cp 容器名:容器内路径 主机路径
主机和容器的文件是可以互相拷贝的,也就是上面的路径可以互换登陆命令
# 登陆命令
docker login 用户名
回车后,输入密码即可
# 退出命令
docker logout
Docker 网络命令
# 列出网络配置
docker network ls
# 查看容器的网络
docker network inspect 网络名
# 创建网络 docker network create --subnet 134.34.0.0/16 --gateway 134.34.0.1 tzlnet2
# 将容器连接到某个网络 docker network connect tzlnet2 centos-004
Docker 镜像制作命令
# 将容器制作成镜像
docker commit -m 描述信息 -a 作者 容器名 目标镜像名[:版本号]
# 将 Dockerfile 构建成镜像
docker build -f dockerfile文件路径 -t 镜像名[:版本号] .
如果dockerfile文件在命令执行的当前路径下,则可以不写-f参数,但同时要求,文件名必须叫 Dockerfile
容器数据卷
- 容器数据卷是为了解决什么问题?
数据持久化到本地,不会随着容器的删除而删除
- 容器数据卷的本质是什么?
Docker容器产生的数据,同步到本地
- 卷挂载的方式
1,指定目录挂载
-v ~/CentOS7:/home
2,匿名挂载
-v /home
只写一个容器内路径,不写主机的任何信息,通过docker volume ls可以看到给了个随机数
3,具名挂载
-v CentOS7Data:/home
给卷指定了一个名称
- 挂载权限
通过 -v 容器内路径:ro(readonly 只读) 或 rw(默认:readwrite 可读可写) 改变读写权限,只能修改容器内目录的权限
docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx/:ro nginx
容器卷命令
# 创建容器卷
docker volume create 容器卷名
# 显示所有容器卷
docker volume ls
# 查看容器卷的详细信息
docker volume inspect 容器卷名
其实也可以直接通过 docker inspect 容器卷名 来查看
# 删除没有被容器使用的容器卷
docker volume prune
# 删除容器卷
docker volume rm 容器卷
如果要强制删除的话,可以增加 -f 参数
【备注】:如果进行了卷挂载,那么如果容器内的路径中有文件,会被外部的目录给冲掉。之前在搭一个tomcat的站点时,总是发现里面的配置是空的。
后来才查出原因,是自己把配置、站点目录、日志目录都给挂出来了,而宿主机上的目录是空的,导致将tomcat下的目录也给整空了。
细想一下原理,容器就是个运行的壳,给它装什么数据,就读取什么数据。
【备注】:volume中的卷,如果通过-v指定了相同路径的映射后,默认的映射还是会在mounts下创建,但是不会同步数据了,而是同步到-v指向的路径下
网络原理
网络名称解释
- lo(localhost简写)
本机回环地址
- ens33(eth0)
主机内网地址,是由外部的路由器分配的
- docker0
容器地址-路由器
容器的网络,相当于对容器配备了一个路由器一样
evth-pair技术
成对出现的虚拟端口,其实可以理解为底层通过socket协议,单独走了一种机制,容器与主机端口进行协议通信
宿主机
容器
ip 数量
ip 地址范围
0.0.0.0~255.255.255.255
ip 的值存储
00000000.00000000.00000000.00000000
255.255.0.1/16
16意思就是前面的2位是固定的,ip段为192.168.0.0~192.168.255.255
如果是24的话,那就是前面的3位是固定的
因此=255*255-2(全0的和全255的)=65023 (课堂讲的是65535)
容器互通(通过域名来访问)
原因是,域名可以写死,而ip会被随机分配,所以通过域名来相互访问是最好的解决方案
实现方式
- 通过 --link 来实现
- 通过创建自定义网络来实现
# docker 的网络模式
【bridge】:桥接 默认(自己创建的话,也采用这种方式)
【none】:不配置网络(无网络)
【host】:和宿主机共享网络
【container】:容器内网络连通(用的少,局限大)
创建网络时,指定的模式最优选择为 bridge ,创建网络命令,具体可查看上面的章节描述
通过自定义创建好的网络,可以直接通过域名(容器名)访问其它容器了,修复了docker0默认桥接模式的缺陷
示例
不同的集群使用不同的网络
redis 192.168.xx.xx
mysql 192.167.xx.xx
想要让两个容器连通,就是让容器连接到mynet中
通过docker network connect 实现,具体可查看上面的章节描述
原理
本质上是把容器放到了tzlnet(目标)网络里面了,即一个容器多个ip,注意:没有connect的依旧无法连通
Dockerfile
Dockerfile 是用来构建镜像文件的构建文件
Dockerfile初体验
# 最简单的Dockerfile体验 FROM centos VOLUME ["volume01","volume02"] CMD echo "------end------" CMD /bin/bash
【备注】volume中的卷,如果通过-v指定了相同路径的映射后,默认的映射还是会在mounts下创建,但是不会同步数据了,而是同步到-v指向的路径下
构造Dockerfile 查看上面章节的docker build命令说明
官网 Dockerfile
其实,官网点击版本就会跳到Dockerfile文件中
Dockerfile 结构
Dockerfile 命令
Dockerfile 编写规则
- 每个关键字都必须是全部大写
- 执行时,从上到下顺序执行
- # 表示注释
- 每一个指令都会创建提交一个新的镜像层
【 备注】
- DockerHub中 99%的镜像都是从scratch生成的,相当于一个引导加载
- 交付的标准-镜像
- 把文件命名成Dockerfile,运行命令,可以不用写-f路径,默认就会找到这个文件,当然必须是在当前目录下运行docker build命令
Tomcat Dockerfile 示例
# 下载安装包,tomcat和jdk
# 选择创建Dockerfile的目录
# 创建说明文档
# 编写Dockerfile
# 基于centos 7版本创建,如果是8.0的话,调用yum安装时,镜像路径需要进行配置
FROM centos:7
MAINTAINER tzl<451509092@qq.com>
COPY readme.txt /usr/local/readme.txt
# 添加jdk和tomcat安装包,指定解压路径
ADD jdk-8u333-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.22.tar.gz /usr/local/
# 安装vim工具和网络工具
RUN yum -y install vim
RUN yum -y install net-tools
# 设置卷挂载,将tomcat的web目录,配置目录,日志目录都挂到宿主机上,便于外部直接操作
VOLUME ["/usr/local/apache-tomcat-9.0.22/webapps","/usr/local/apache-tomcat-9.0.22/logs","/usr/local/apache-tomcat-9.0.22/conf"]
# 设置工作目录
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 设置环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_333
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 暴露端口
EXPOSE 8080
# 启动执行的命令,同时跟踪显示catalina.out中输出的日志
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/logs/catalina.out
# 编译镜像
docker build -t tzltomcat .
# 运行启动容器
略
Docker图形界面管理
有时候,为了让测试人员或者其它不了解Docker的人员能更便捷的管理容器,可以部署一套图形管理站点
# 搜索 docker search portainer |head -n 3 # 下载 docker pull portainer/portainer # 安装(单机版) docker run -d -p 9000:9000 --name portainer --restart=always -v /opt/portainer:/data -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer # 开放防火墙,linux外访问的话 # 访问
Docker-Compose
docker-compose 这块儿实在没时间写了,贴张图,记录概要信息,剩下的内容直接浏览官网吧
# 下载安装包 # sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 国内速度慢-->可替换链接https://get.daocloud.io sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 设置权限,应用可执行权限 sudo chmod +x /usr/local/bin/docker-compose # 添加软连接 sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose # 查看安装信息 docker-compose --version
遇到的问题
# 找不到 ip addr 命令 yum install -y iproute # 找不到 ifconfig 命令 yum install -y net-tools
最后声明
文档中,部分图片来源于网络,如涉及版权,请联系删除。