Docker笔记

基础篇

Docker的基本组成

  • 镜像(Image):只读模板,用来创建Docker容器,一个镜像可以创建很多容器。
  • 容器(Container):使用镜像创建出来的运行实例。
  • 仓库(Repository):集中存放镜像文件的场所。公开仓库(https://hub.docker.com)。

Docker架构图(入门版)
Alt
Docker总体架构图
在这里插入图片描述

Docker安装

参考官网文档(https://docs.docker.com/engine/install/centos/#prerequisites)

#1.更新yum软件包索引
yum makecache fast
#2.安装需要的软件包
yum install -y yum-utils
#3.设置stable镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#4.防止安装Docker引擎时报错Requires: fuse-overlayfs >= 0.7,将以下内容添加到/etc/yum.repos.d/docker-ce.repo
[centos-extras]
name=Centos extras - $basearch
baseurl=http://mirror.centos.org/centos/7/extras/x86_64
enabled=1
gpgcheck=0

#5.清除缓存中的所有文件并更新yum软件包索引
yum clean all
yum makecache fast
#6.安装Docker引擎
yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
#7.启动Docker
systemctl start docker

配置阿里云镜像加速

阿里云开发者平台:https://promotion.aliyun.com/ntms/act/kubernetes.html
在这里插入图片描述在这里插入图片描述在这里插入图片描述

docker run执行逻辑

在这里插入图片描述

Docker底层原理

Docker 和传统虚拟化方式的不同之处:

在这里插入图片描述

  1. 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
  2. 容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
  3. 每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。

为什么Docker会比VM虚拟机快

1. docker有着比虚拟机更少的抽象层
由于docker不需要实现硬件资源虚拟化,运行在docker容器上的程序直接使用的是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
2. docker利用的是宿主机的内核,而不需要加载操作系统OS内核
当新建一个容器时,docker不需要像虚拟机一样重新加载一个操作系统内核。进而避免引寻、加载操作系统内核返回等比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载OS,返回新建的过程是分钟级别的,而docker由于直接利用宿主机的操作系统,则省略了返回过程,因此新建一个docker容器只需要几秒钟。

对比总结

对比项Docker容器虚拟机(VM)
操作系统与宿主机共享OS宿主机OS上运行虚拟机OS
存储大小镜像小镜像大(vmdk、vdi等)
性能几乎无额外性能损失操作系统额外的CPU、内存消耗
移植性轻便、灵活,适用于Linux笨重,与虚拟化技术耦合度高
硬件亲和性面向软件开发者面向硬件运维者
部署速度快速较慢

Docker常用命令

帮助启动类命令

#启动docker
systemctl start docker
#停止docker
systemctl stop docker
#重启docker
systemctl restart docker
#查看docker状态
systemctl status docker
#开机启动
systemctl enable docker
#查看docker概要信息
docker info
#查看docker总体帮助文档
docker --help
#查看docker命令帮助文档
docker 具体命令 --help

镜像命令

#罗列本地镜像
docker images        #列出本地主机上的docker镜像
docker images -a     #列出本地所有的镜像(含历史映像层)
docker images -q     #列出本地主机上的docker镜像id
#查找镜像
docker search [OPTIONS] xx镜像名   #查找xx镜像
#拉取镜像
docker pull 镜像名[:TAG]   #下载镜像
#查看镜像/容器/数据卷所占空间
docker system df
#删除镜像
docker rmi 镜像名或id
docker rmi -f 镜像id1 镜像id2 镜像id3  #强制删除多个镜像
docker rmi -f $(docker images -qa)     #强制删除全部镜像
#虚悬镜像:仓库名、标签都是<none>的镜像俗称虚悬镜像(dangling image)

容器命令

常用命令
#列出容器
docker ps [OPTIONS]
docker ps      #列出运行中的容器
OPTIONS:
-a,--all       列出全部容器(正在运行+历史运行过的容器)
-l             显示最近创建的容器
-n             显示n个最近创建的容器
-q             只显示容器id
#新建+启动容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS说明(常用):
--name=容器名称        为容器指定一个名称(docker run -it --name=u01 ubuntu bash)--name=u01和--name u01等效
-d                     后台运行容器并返回容器id,也即启动守护式容器
-i                     以交互模式运行容器,通常与-t同时使用
-t                     为容器重新分配一个伪终端,通常与-i同时使用
-P                     随机端口映射,大写P
-p                     指定端口映射,小写p(hostPort:containerPort -p 8080:80)(ip:hostPort:containerPort -p 10.0.0.1:8080:80)
#退出容器
exit        run进去容器,exit退出,容器停止
ctrl+p+q    run进去容器,ctrl+p+q退出,容器不停止
#启动已停止运行的容器
docker start 容器id或容器名
#重启容器
docker restart 容器id或容器名
#停止容器
docker stop 容器id或容器名
#强制停止容器
docker kill 容器id或容器名
#删除容器
docker rm 容器id或容器名       #删除已停止的容器
docker rm -f 容器id或容器名    #强制删除容器(运行中或停止的)
docker rm -f $(docker ps -aq)        #删除所有容器
docker ps -aq | xargs docker rm -f   #删除所有容器
#查看容器日志
docker logs 容器id或容器名
#查看容器内运行的进程(类似linux中top命令)
docker top 容器id或容器名
#查看容器内部细节
docker inspect 容器id或容器名
进入正在运行的容器并以命令行交互
docker exec -it   容器id或容器名 bashShell
docker attach     容器id或容器名

exec和attach的区别
attach直接进入容器启动命令的终端,不会启动新的进程,用exit退出会导致容器停止。
exec是在容器并打开新的终端,并且可以启动新的进程,用exit退出不会导致容器停止。

启动守护式容器(后台服务器)

docker run -d redis
注意:使用镜像centos以后台模式启动一个容器 docker run -d centos
然后docker ps -a 进行查看,会发现刚启动的容器已经退出
原因:容器运行的命令如果不是那些一直挂起的命令(比如top,tail等),就会自动退出。
所以docker容器要后台运行,就必须有一个前台进程

容器和主机之间拷贝文件
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
使用'-'作为目的地,将容器源的tar存档传输到标准输出。
示例: docker cp 83e3d823369a:/root/abc.tar -
使用'-'作为源,从stdin读取tar存档,并将其解压缩到容器中的目标目录。
示例: cat abc.tar | docker cp - 83e3d823369a:/root
导出容器和创建容器镜像

docker export [OPTIONS] CONTAINER 导出容器为归档文件
下面两条命令等效

docker export -o abc.tar 容器id或容器名
docker export 容器id或容器名 > abc.tar

docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]] 从tar包中导入内容以创建文件系统镜像
下面两条命令等效

docker import abc.tar zjc/ubuntu1.0
cat abc.tar | docker import - zjc/ubuntu1.0

进阶篇

Docker镜像

简介

  • 镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包成一个可交付的运行环境(包括代码、运行时库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
  • Docker的镜像是分层的

联合文件系统UnionFS

  • UnionFS(联合文件系统)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。
  • UnionFS是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
    在这里插入图片描述
  • 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

Docker镜像加载原理

  • docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
  • bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
  • rootfs (root fle system),在bootfs之上。包含的就是典型Linux系统中的/dev,/proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu ,Centos等等。
    在这里插入图片描述
  • docker镜像层都是只读的,容器层是可写的
    当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称为“容器层”,“容器层”之下的都叫“镜像层”。
    所以对容器的改动(添加、删除、修改文件等)都只会发生在容器层中。

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

镜像分层最大的好处就是资源共享,方便复制迁移,就是为了复用。
比如说有多个镜像都是从相同的base镜像构建而来,那么Docker Host只需在磁盘上保存一份base镜像;同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

扩展镜像(commit操作)

Usage:  docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes

Options:
  -a, --author string    Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
  -c, --change list      Apply Dockerfile instruction to the created image
  -m, --message string   Commit message
  -p, --pause            Pause container during commit (default true)
  • 示例: docker commit -m="安装了vim" -a="zjc" 容器id或容器名 要创建的目标镜像名:[标签]
    docker commit -m "安装了vim" -a "zjc" 容器id或容器名 要创建的目标镜像名:[标签]
  • 小总结
    docker中的镜像分层,支持通过扩展现有镜像,创建新的镜像。
    新镜像是从base镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。
    在这里插入图片描述

容器数据卷(docker run -v选项)

是什么

  • 卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性。
  • 卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此docker不会在容器删除时删除其挂载的数据卷。
  • 容器数据卷就是将docker容器内的数据保存到宿主机的磁盘中

能干嘛

  • 将docker容器产生的数据持久化
  • 特点:
    1.数据卷可在容器之间共享或重用数据
    2.卷中的更改实时生效
    3.数据卷中的更改不会包含在镜像的更新中
    4.数据卷的生命周期一直持续到没有容器使用它为止

权限的坑

在SELinux里面docker挂载目录被禁止掉了,如果要开启,一般使用–privileged=true参数为这个容器提供扩展权限来解决挂载目录没有权限的问题,也即使用该参数,container内的root用户拥有真正的root权限,否则container内的root用户只有外部的普通用户权限。

案例

  • 宿主机和容器之间映射添加容器数据卷
docker run -it --privileged=true -v /tmp/host_data1:/tmp/docker_data1 -v /tmp/host_data2:/tmp/docker_data2 --name=u1 ubuntu
#查看卷映射规则
docker inspect u1

在这里插入图片描述

  • 读写规则映射添加说明
    • 读写(没有添加读写规则默认是rw可读写)
      下面命令和上面的案例等效
      docker run -it --privileged=true -v /tmp/host_data1:/tmp/docker_data1:rw -v /tmp/host_data2:/tmp/docker_data2:rw --name=u1 ubuntu
    • 只读(容器内只读)
      docker run -it --privileged=true -v /tmp/host_data1:/tmp/docker_data1:ro --name=u1 ubuntu
  • 卷的继承和共享
    1. 容器1完成和宿主机的卷映射
      docker run -it --privileged=true -v /tmp/host_data1:/tmp/docker_data1 --name=u1 ubuntu
    2. 容器2继承容器1的卷规则
      docker run -it --privileged=true --volumes-from u1 --name=u2 ubuntu
      查看卷映射规则
      docker inspect u2
      在这里插入图片描述

本地镜像发布到阿里云

本地镜像发布到阿里云流程

在这里插入图片描述

将本地镜像推送到阿里云

  1. 阿里云开发者平台:https://promotion.aliyun.com/ntms/act/kubernetes.html
  2. 创建仓库镜像
    (1). 选择控制台,进入容器镜像服务
    (2). 选择个人实例
    在这里插入图片描述
    (3). 命名空间
    在这里插入图片描述
    (4). 镜像仓库
    在这里插入图片描述
    在这里插入图片描述
    (5). 进入管理界面获得脚本
#1.登录阿里云Docker Registry
docker login --username=aly_zjc888 registry.cn-hangzhou.aliyuncs.com
#2.使用"docker tag"命令重命名镜像,并将它通过专有网络地址推送至Registry
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/zjc1/docker-zjc1:[镜像版本号]
#3.使用 "docker push" 命令将该镜像推送至远程
docker push registry.cn-hangzhou.aliyuncs.com/zjc1/docker-zjc1:[镜像版本号]

本地镜像发布到私有库

  1. 下载镜像docker registry
    docker pull registry
  2. 运行镜像registry,相当于本地有个私有Docker hub
    docker run -d -p 5000:5000 --privileged=true -v /dockerHub:/tmp/registry registry
  3. curl验证私服库上有什么镜像
    curl -XGET http://127.0.0.1:5000/v2/_catalog
  4. 将镜像zjc/ubuntu1.1修改符合私服库规范的TAG
    docker tag zjc/ubuntu1.1 127.0.0.1:5000/zjc/ubuntu1.1
  5. 修改配置文件使之支持http
    docker默认不允许http方式推送镜像,通过配置选项来取消这个限制。(修改完后如果不生效,重启docker)
    vi /etc/docker/daemon.json

    {
    “registry-mirrors”: [“https://v0l3see8.mirror.aliyuncs.com”],
    “insecure-registries”:[“192.168.80.13:5000”]
    }
    第一行是阿里云的镜像加速
    第二行是允许http方式推送镜像

  6. push推送到私服库
    docker push 127.0.0.1:5000/zjc/ubuntu1.1
  7. curl验证私服库上有什么镜像
    curl -XGET http://127.0.0.1:5000/v2/_catalog
  8. 拉取刚推送到本地的镜像
    docker pull 127.0.0.1:5000/zjc/ubuntu1.1

高级篇

Dockerfile

是什么

  • DockerFile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
  • 官网:https://docs.docker.com/engine/reference/builder/
  • 构建三步骤
    1. 编写Dockerfile文件
    2. docker build命令构建镜像
    3. docker run运行容器实例

Dockerfile构建过程解析

Dockerfile内容基础知识
  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  2. 指令按照从上到下顺序执行
  3. #表示注释
  4. 每条指令都会创建一个新的镜像层并对镜像进行提交
Docker执行Dockerfile的大致流程
  1. docker从基础镜像运行一个容器
  2. 执行一条指令并对容器做出修改
  3. 执行类似docker commit的操作提交一个新的镜像层
  4. docker再基于刚提交的镜像运行一个新容器
  5. 执行Dockerfile中的下一条指令直到所有指令都执行完成
Dockerfile、docker镜像和docker容器关系

在这里插入图片描述

Dockerfile常用保留字指令

参考tomcat8的Dockerfile: https://github.com/docker-library/tomcat/blob/master/8.5/jdk8/corretto-al2/Dockerfile
FROM

基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,有效的Dockerfile必须以FROM指令开始

MAINTAINER

镜像维护者的姓名和邮箱

RUN

构建(build)镜像时需要运行的命令(在docker build时运行)
两种格式

  • shell格式: RUN <命令行命令> 命令行命令等同于在终端操作的shell命令
    例如:RUN yum -y install vim
  • exec格式: RUN [“可执行文件”,“参数1”,“参数2”]
    例如: RUN ["./test.php","dev","offline"]等价于 RUN ./test.php dev offline
EXPOSE

当前容器对外暴露的端口

WORKDIR

指定在容器创建后,终端登录进来默认的工作目录

USER

指定该镜像以什么用户执行,如果不指定,默认是root

ENV

用来在构建工程中设置的环境变量

ADD

将宿主机的文件拷贝到镜像且会自动处理URL和解压缩,相当于COPY+解压

COPY

拷贝文件到镜像

VOLUME

容器数据卷,持久化数据

CMD

指定容器启动后要干的事情
CMD <容器启动命令>
CMD指令的格式和RUN相似,也有两种格式:

  • shell格式: CMD <命令>
  • exec格式: CMD ["可执行文件","参数1","参数2"...]
  • 参数列表格式:CMD [“参数1”,“参数2”…],在指定了ENTRYPOINT指令后,用CMD指定具体的参数
  • 注意:
    • Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数覆盖
    • CMD和RUN指令的区别:
      CMD是在docker run时运行
      RUN是在docker build时运行
ENTRYPOINT
  • 指定容器启动后要干的事情,类似于CMD指令,但是ENTRYPOINT不会被docker run后面的参数覆盖,而且这些命令行参数会被当作参数传递给ENTRYPOINT指令指定的程序

  • 指令格式:ENTRYPOINT ["可执行文件","参数1","参数2"...]

  • ENTRYPOINT可以和CMD一起用,一般有变参才会使用CMD,这时CMD等于给ENTRYPOINT传参。

  • 案例:假设构建nginx:test镜像的Dockerfile如下

    FROM nginx

    ENTRYPOINT [“nginx”,“-c”] #定参
    CMD [“/etc/nginx/nginx.conf”] #变参

    按照Dockerfile编写执行传参运行
    docker命令docker run nginx:testdocker run nginx:test -c /etc/nginx/new.conf
    实际执行命令nginx -c /etc/nginx/nginx.confnginx -c /etc/nginx/new.conf
小总结
buildbothrun
FROMWORKDIRCMD
MAINTAINERUSERENV
COPYEXPOSE
ADDVOLUME
RUNENTRYPOINT
ONBUILD
.dockerignore

案例

自定义镜像mycentosjava8
  1. 要求
    CentOS7镜像具备vim+ifconfig+jdk8
    JDK的下载地址:
    官网:https://www.oracle.com/java/technologies/downloads/#java8
    其他:https://mirrors.yangxingzhen.com/jdk/
  2. 编写Dockerfile
    vim Dockerfile
FROM centos:centos7.9.2009
MAINTAINER ZJC<1580739389@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令
RUN yum -y install net-tools
#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#把jdk-8u192-linux-x64.tar.gz添加到镜像中
ADD jdk-8u192-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_192
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JAR_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

CMD echo $MYPATH
CMD echo "success-----------ok"
CMD /bin/bash
  1. 构建(docker build -t 新镜像名字:TAG .)
    docker build -t mycentosjava8:1.0 .
虚悬镜像
  • 是什么
    仓库名、标签都是<none>的镜像俗称虚悬镜像(dangling image)
  • 写一个
    vim Dockerfile
FROM ubuntu
CMD "success"
  • 构建一个虚悬镜像
    docker build .
    在这里插入图片描述
  • 查看
    docker image ls -f dangling=true
    在这里插入图片描述
  • 删除
    虚悬镜像已经失去了存在的价值,可以删除
    docker image prune

Docker网络

#docker网络命令用法
docker network --help
#使用自定义的网络zjc_network启动容器tomcat81
docker run -d -p 8081:8080 --network zjc_network --name tomcat81 tomcat8-jdk8

详细参考:https://blog.csdn.net/q908544703/article/details/126226073?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-1-126226073-blog-128150150.235v39pc_relevant_anti_t3&spm=1001.2101.3001.4242.2&utm_relevant_index=4

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一点见解

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

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

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

打赏作者

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

抵扣说明:

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

余额充值