Docker基础

Docker基础概念

Docker核心概念

Docker大部分的操作都围绕着它的三大核心概念:镜像、容器和仓库。因此,准确把握这三大核心概念对于掌握Docker技术尤为重要。

Docker底层原理

为什么docker会比vm虚拟机快。

1.docker比虚拟机有更少的抽象层。

  • docker并不是通过虚拟了硬件资源,而是直接使用物理机的硬件资源,所以速度很快。

2.docker使用了宿主机的内核,而不需要加载操作系统。

  • vm创建虚拟机时直接创建整个操作系统。但docker不是,他是直接利用宿主机的操作系统,省略了返回过程。

Docker和虚拟机之间的不同

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

DevOps(开发,运维)

应用更快速的交付和部署

更快捷的升级和缩容

跟简单的系统运维

更高效的资源利用

Docker镜像的分层概念

  • 镜像是什么
    • 是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
  • 分层的镜像
    • 以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载。
  • UnionFS(联合文件系统)
    • UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
    • 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
  • Docker镜像加载原理
    • docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
  • Docker镜像层都是只读的,容器层是可写的
    • 当容器启动时,一个新的可写层被加载到镜像的顶部。 这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”

Docker基础 - 图1

Docker的安装

Linux下载安装
http://get.daocloud.io/

安装docker环境依赖

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

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

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

启动docker

systemctl start docker && systemctl enable docker

索引缓存

yum makecache fast

设置内核

  1. net.bridge.bridge-nf-call-ip6tables = 1
  2. net.bridge.bridge-nf-call-iptables = 1
  3. net.ipv4.ip_forward = 1

一键安装

  1. curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

阿里云镜像加速器

如果不进行配置,很有可能会卡顿。这里建议使用阿里云镜像加速,免费的。

在阿里云中找到镜像加速,在路径/etc/docker/daemon.json 复制进去。

{
“registry-mirrors”: [“https://zamu0pih.mirror.aliyuncs.com“]
}

Docker run hello-world

当docker run 执行后,这个run都干了什么。

Docker基础 - 图2

Docker命令

可以使用命令在dockerhub上进行搜索,默认也是dockerhub上搜索。

帮助类命令

  1. docker version #镜像信息
  2. docker 命令 --help #查看帮助文档
  3. docker info #docker信息

镜像命令

  1. docker images #列出本地镜像
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. wuhu/nginx v1 04066b822951 24 hours ago 375MB

REPOSITORY:镜像仓库名称
TAG:镜像标签
IMAGE:镜像ID
CREATED:镜像创建时间
SIZE:大小

-a 列出所有镜像

-q 只显示镜像的ID

  1. docker search centos #搜索镜像
  2. --filter=START=3000
  3. docker pull centos:tag #拉取/下载镜像
  4. docker rmi -f neginx #删除镜像
  5. docker rmi -f ${docker images -aq} #递归删除所有镜像
  6. systemctl daemon-reload && systemctl restart docker #重启docker
  7. docker load -i /root/centos.tar.gz #解压镜像
  8. docker save -o test.tar.gz centos:latest #打包镜像

查看docker统计信息

  1. docker system df
  2. TYPE TOTAL ACTIVE SIZE RECLAIMABLE
  3. Images 3 1 185.5MB 185.5MB (99%)
  4. Containers 3 0 0B 0B
  5. Local Volumes 0 0 0B 0B
  6. Build Cache 0 0 0B 0B

容器类命令

拉取和运行

  1. docker pull centos #拉取镜像,有镜像才能运行容器
  2. docker run [可选参数] images
  3. #参数说明
  4. --name="Name" 容器名称,nginxtomcat1
  5. -d 后台运行
  6. -it 使用交互方式运行/进入容器查看内容
  7. -p 指定容器端口, 80:80
  8. -P 随机指定端口
  9. docker run -it centos /bin/bash #以前台交互的模式启动并进入容器
  10. docker run -d centos #以后台守护式启动
  11. Ctrl + P + Q #退出容器并在后台运行

列出运行的容器

  1. docker ps #列出当前正在运行的容器
  2. -a #列出全部容器
  3. -n [数字] #列出最近的n个容器
  4. -q #只显示容器的编号

退出容器

  1. exit #退出容器
  2. ctrl+P+Q #退出并继续运行容器

删除容器

  1. docker rmi 容器id #删除指定容器,但无法删除正在运行的容器
  2. docker rmi -rf 容器id #强制删除
  3. docker rmi -f $(docker ps -aq) #递归删除所有启动/启动过的容器
  4. docker ps -a|xargs docker rmi #递归删除所有容器

启动和停止容器

  1. docker start|restart|stop|kill 容器id #启动|重启|停止|杀掉 容器

后台部署应用

  1. docker run -d centos
  2. #docker ps 会发现centos停止了!!!
  3. #docker容器后台运行必须要有一个前台进程,docker发现没有应用就会自动停止。
  4. #例如:nginx容器启动后,发现自己没有提供服务,就会立刻停止。

查看日志

  1. docker logs 容器ID #查看容器日志
  2. docker logs -tf --tail 10 容器ID #查看容器前10行的日志
  3. --tail number #显示日志条数

查看容器的进程信息

  1. docker top 容器ID

查看镜像的源数据

  1. docker inspect 容器ID

进入当前正在运行的容器

  1. docker exec -it 容器ID /bin/bash #以交互形式进入容器,类似新开一个界面
  2. #exec 使用exit进入退出不会停止
  3. docker attach -it 5d8e48e4b792 #进入正在运行的容器命令行
  4. #attach 退出了会停止容器

镜像的保存与导入

  1. docker save -o test.tar myapp:v0.1 #保存镜像
  2. docker save fe8c52043b39 > test.tar #保存镜像
  3. #此时就会创建一个tar包,其中就是镜像文件
  4. docker load < test.tar #导入镜像
  5. docker load -i test.tar #导入镜像
  6. #将tar包导入,就可以运行使用了。

容器文件拷贝到主机上

  1. #在主机上输入该命令
  2. docker cp 容器ID:文件路径 目的主机路径

容器备份与解压

备份运行时的容器镜像

  1. docker export 517d619c4d55 > test.tar #将你的整个容器做成tar备份
  2. cat test.tar | docker import - test/redis:0.1 #将tar备份文件转换为可用镜像

Docker基础 - 图3

命令总结

命令 作用
attach 当前 shell 下 attach 连接指定运行镜像
build 过 Dockerfile 定制镜像
commit 提交当前容器为新的镜像
cp 容器中拷贝指定文件或者目录到宿主机中
create 创建一个新的容器,同 run,但不启动容器
diff 查看 docker 容器变化
events 从 docker 服务获取容器实时事件
exec 在已存在的容器上运行命令
export 导出容器的内容流作为一个 tar 归档文件
history 展示一个镜像形成历史
images 列出系统当前镜像
import 从tar包中的内容创建一个新的文件系统映像
info 显示系统相关信息
inspect 查看容器/数据卷/网卡的详细信息
kill kill 指定 docker 容器
load 从一个 tar 包中加载一个镜像
login 注册或者登陆一个 docker 源服务器
logout 从当前 Docker registry 退出
logs 输出当前容器日志信息
port 查看映射端口对应的容器内部源端口
pause 暂停容器
ps 列出容器列表
pull 从docker镜像源服务器拉取指定镜像或者库镜像
push 推送指定镜像或者库镜像至docker源服务器
restart 重启运行的容器
rm 移除一个或者多个容器
rmi 移除一个或多个镜像
run 创建一个新的容器并运行一个命令
save 存一个镜像为一个 tar 包
search 在 docker hub 中搜索镜像
start 启动容器
stop 停止容器
tag 给源中镜像打标签
top 查看容器中运行的进程信息
unpause 取消暂停容器
version 查看 docker 版本号
wait 截取容器停止时的退出状态值
volume 数据卷

Dockerfile

1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数

2:指令按照从上到下,顺序执行

3:#表示注释

4:每条指令都会创建一个新的镜像层并对镜像进行提交

构建流程:

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

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,

  • Dockerfile是软件的原材料

  • Docker镜像是软件的交付品

  • Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

dockerfile命令

命令 命令的作用 常见用法
FROM 指定基础镜像 FROM centos
MAINTAINER 指定镜像作者,姓名+邮箱 MAINTAINER liao
RUN 镜像构建时需要运行的命令 RUN yum install vim -y
ADD 添加文件,比如添加一个tomcat压缩包 ADD test.tar /root/
WORKDIR 设置镜像的工作目录 WORKDIR /usr/local
VOLUME 设置容器卷,设置挂载目录位置
EXPOSE 指定对外的端口。和-p一样。 EXPOSE 80
CMD 指定容器启动时候要运行的命令,只有最后一个生效,并且可被替代 CMD [“catalina.sh”,”run”]
ENTRYPOINT 和CMD一样,可以直接追加命令。 ENTRYPOINT[‘ps’]
docker run —rm test -ef
ONBUILD 当构建一个被继承dockerfile这个时候会运行 ONBUILD 的指令 触发指令
COPY 类似ADD,将文件拷贝到镜像中 CMD /bin/bash
ENV 构建时设置环境变量 ENV MY_PATH /usr/mytest
ARG 设置编译变量

Docker基础 - 图4

CMD和ENTRYPOINT的区别

CMD:追加命令是直接占用了CMD整个占位符

CMD常用来写在最后,然后用来启动服务。比如安装好了tomcat,最后用CMD启动脚本。

  1. #运行完镜像后,执行ls -a命令
  2. FROM centos
  3. CMD ["ls","-a"]
  4. docker build -t centos-test:v0.1 -f Dockerfile . #构建镜像
  5. docker run -d 7149c87c748f #此时运行就是启动了centos 并且在其中执行命令ls -a
  6. docker run -d 7149c87c748f /bin/bash #此时运行就是启动了centos,并且在其中执行命令 /bin.bash

ENTRYPOINT:追加命令只是占用了“-a”的占位符

  1. FROM centos
  2. ENTRYPOINT ["mc.sh","start"]
  3. docker run -d 7149c87c748f #此时运行就是启动了centos,并且默认执行mc.sh的start内部脚本 mc.sh start
  4. docker run -d 7149c87c748f log #此时运行就是启动centos,并且执行了mc.sh的log内部脚本 mc.sh log

实例:构建centos

1.创建文件并准备需要用到的安装包

  1. mkdir -p /root/dockerfile #创建文件夹
  2. cd /root/dockerfile
  3. vim Dockerfile #创建Dockerfile,这里D要大写
  4. FROM centos #指定使用的镜像
  5. MAINTAINER liao #指定作者
  6. ENV MYPATH /usr/local #创建变量
  7. WORKDIR $MYPATH #设置工作路径
  8. RUN yum install -y vim net-tools glibc.i686 #安装工具包
  9. RUN mkdir /usr/local/java #创建文件夹
  10. ADD jdk-17_linux-x64_bin.tar.gz /usr/local/java #添加并解压压缩包到指定文件夹
  11. ENV JAVA_HOME /usr/local/java/jdk-17.0.2 #设置变量
  12. ENV JRE_HOME /usr/local/java/jre
  13. ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
  14. ENV PATH $JAVA_HOME/bin:$PATH
  15. EXPOSE 80 #设置端口
  16. CMD echo $MYPATH
  17. CMD echo "success-----------ok"
  18. CMD /bin/bash

虚悬镜像node

在构建或者删除镜像的时候出现了错误,导致镜像仓库和标签都为none。

docker images ls -f dangling=true #查看所有的虚悬镜像

docker image prune #删除所有的虚悬镜像

实例:构建tomcat

  1. 准备tomcat压缩包和jdk压缩包
    Docker基础 - 图5
  2. 编写dockerfile文件
    ```shell FROM centos #指定基础包 MAINTAINER liao1182350036@qq.com #作者信息 COPY readme.txt /usr/local/readm.txt #复制文件到容器路径 /usr/local/readm.txt

ADD jdk-8u301-linux-x64.tar.gz /usr/local/ #添加并解压文件到 /usr/local/ ADD apache-tomcat-8.5.70.tar.gz /usr/local/

RUN yum install vim net-tools -y

ENV MYPATH /usr/local #配置环境变量 WORKDIR $MYPATH #设置工作目录

ENV JAVA_HOME /usr/local/jdk1.8.0_301 #设置变量 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.70 ENV CATLINA_BASH /usr/local/apache-tomcat-8.5.70 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-8.5.70/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.70.tar.gz/bin/logs/catalina.out

  1. 3. 启动镜像
  2. ```shell
  3. docker run -d -p 9090:8080 --name tomcats123 -v /dockers1/tomcat/:/usr/local/apache-tomcat-8.5.70/webapps/tomcat -v /dockers1/tomcatlogs/:/usr/local/apache-tomcat-8.5.70/logs da668652083f

web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
  5. http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  6. version="4.0">
  7. </web-app>

index.jsp

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>docker</title>
  5. </head>
  6. <body>
  7. <h3>hello,docker</h3>
  8. <%
  9. System.out.println("hello, dockerlogs");
  10. %>
  11. </body>
  12. </html>