Docker

目录

Docker 简介

Docker特征

Docker与虚拟机的区别

namespace的六项隔离

Docker核心概念

安装 Docker

docker 信息查看详解

Docker 镜像操作

搜索镜像:

获取镜像:

镜像加速下载:

查看镜像信息:

为本地的镜像添加新的标签:

删除镜像:

存储镜像:

载入镜像:

上传镜像:

Docker 的数据管理

1.数据卷

2.数据卷容器

端口映射

容器互联(使用centos镜像)

Docker 镜像的创建

镜像加载原理

为什么Docker里的centos的大小才200M?

Dockerfile

Docker 镜像结构的分层

Dockerfile 配置(指令)


Docker 简介

Docker 是一种开源的容器化平台,可以轻松地创建、部署和运行应用程序。通过 Docker,用户可以将应用程序及其依赖项封装在一个独立的容器中,并在任何环境中运行这个容器,而不需要担心环境差异导致的问题。

Docker 可以被认为是一种让应用程序“打包”成容器的技术,使得这些容器可以在不同的环境中快速部署和运行,从而提高了开发效率、降低了维护成本。

Docker特征


灵活:即使是最复杂的应用也可以集装箱化。
轻量级:容器利用并共享主机内核。
可互换:可以即时部署更新和升级。
便携式:可以在本地构建,部署到云,并在任何地方运行。
可扩展:可以增加并自动分发容器副本。
可堆叠:可以垂直和即时堆叠服务。

Docker与虚拟机的区别

  1. 启动速度:Docker容器的启动速度通常为秒级,而虚拟机的启动速度通常为分钟级。

  2. 计算能力损耗:Docker容器几乎没有计算能力损耗,而虚拟机的计算能力损耗通常在50%左右。

  3. 性能:Docker容器的性能接近于原生环境,而虚拟机的性能弱于原生环境。

  4. 系统支持量(单机):Docker容器可以在一台主机上运行上千个容器,而虚拟机通常只能支持几十个虚拟机实例。

  5. 隔离性:Docker容器提供资源隔离和限制,但并不是完全隔离,虚拟机则可以实现完全隔离。


namespace的六项隔离

  1. UTS (CLONE_NEWUTS):这个 namespace 隔离了主机名和域名。在不同的 UTS namespace 中,可以有不同的主机名和域名。

  2. IPC (CLONE_NEWIPC):这个 namespace 隔离了系统中的信号量、消息队列和共享内存。不同的 IPC namespace 中的进程无法相互访问对方的 IPC 对象。

  3. PID (CLONE_NEWPID):这个 namespace 隔离了进程编号。在不同的 PID namespace 中,每个进程都有自己的独立的进程编号空间,因此进程在不同的 PID namespace 中可以使用相同的进程编号。

  4. Network (CLONE_NEWNET):这个 namespace 隔离了网络设备、网络栈、端口等。不同的 Network namespace 中的进程拥有各自独立的网络资源,可以有不同的网络配置和连接。

  5. Mount (CLONE_NEWNS):这个 namespace 隔离了挂载点(文件系统)。不同的 Mount namespace 中的进程拥有自己独立的挂载点层次结构,可以有不同的文件系统视图。

  6. User (CLONE_NEWUSER):这个 namespace 隔离了用户和用户组。不同的 User namespace 中的进程拥有各自独立的用户和用户组映射,可以实现不同的用户权限和身份隔离。


Docker核心概念


镜像:
Docker的镜像是创建容器的基础,类似虚拟机的快照,可以理解为一个面向 Docker 容器引擎的只读模板。
通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括运行应用程序所需要的所有内容包含代码,运行时间,库、环境变量、和配置文件。
Docker镜像也是一个压缩包,只是这个压缩包不只是可执行文件,环境部署脚本,它还包含了完整的操作系统。因为大部分的镜像都是基于某个操作系统来构建,所以很轻松的就可以构建本地和远端一样的环境,这也是Docker镜像的精髓。

各种环境   或者服务(tomcat/nginx) 一个模版

容器:
Docker的容器是从镜像创建的运行实例,它可以被启动、停止和删除。所创建的每一个容器都是相互隔离、互不可见,以保证平台的安全性。
可以把容器看做是一个简易版的linux环境(包括root用户权限、镜像空间、用户空间和网络空间等)和运行在其中的应用程序。

镜像 nginx  (run) 起来之后的一个实例,可以把容器看做时一个简易版的linux环境容器 就是集装箱(logo上的集装箱)

仓库:
Docker仓库是用来集中保存镜像的地方,当创建了自己的镜像之后,可以使用push命令将它上传到公有仓库(Public)或者私有仓库(Private)。当下次要在另外一台机器上使用这个镜像时,只需从仓库获取。

Docker 的镜像、容器、日志等内容全部都默认存储在 /var/lib/docker 


仓库就是放镜像的场所,做大的公开库 docker hub


安装 Docker

安装前提:目前 Docker 只能支持 64 位系统。

systemctl stop firewalld.service
setenforce 0
yum install -y yum-utils device-mapper-persistent-data lvm2                             #安装依赖包
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo                                                                                                                              #设置阿里云镜像源
yum install -y docker-ce docker-ce-cli containerd.io                                           #安装 Docker-CE
docker-ce-20.10.18
yum install -y docker-ce-20.10.18 docker-ce-cli containerd.io

systemctl start docker.service
systemctl enable docker.service 


docker version                        #查看 docker 版本信息
docker info                             #docker 信息查看

docker 信息查看详解


Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)

Server:
 Containers: 0                        # 容器数量
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 1                                   # 镜像数量
 Server Version: 20.10.3            # server 版本
 Storage Driver: overlay2            # docker 使用的是 overlay2 文件驱动
  Backing Filesystem: xfs            # 宿主机上的底层文件系统
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs            # Cgroups 驱动
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runtime.v1.linux runc io.containerd.runc.v2
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 269548fa27e0089a8b8278fc4fc781d7f65a939b
 runc version: ff819c7e9184c13b7c2607fe6c30ae19403a7aff
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 3.10.0-693.el7.x86_64        # 宿主机的相关信息
 Operating System: CentOS Linux 7 (Core)
 OSType: linux
 Architecture: x86_64
 CPUs: 1
 Total Memory: 976.3MiB
 Name: localhost.localdomain
 ID: Y4ES:FTH2:ZJL7:MRVE:RJVB:WJIB:S7BV:C5IZ:LMBR:E4G5:QWSM:SNDT
 Docker Root Dir: /var/lib/docker            # docker 数据存储目录
 Debug Mode: false
 Registry: https://index.docker.io/v1/        # registry 地址
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:                            # 加速站点
  https://6ijb8ubo.mirror.aliyuncs.com/
 Live Restore Enabled: false

Docker 镜像操作


搜索镜像:


docker search 关键字

获取镜像:


docker pull 仓库名称[:标签]

镜像加速下载:


浏览器访问 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 获取镜像加速器配置

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

查看镜像信息:


镜像下载后存放在 /var/lib/docker 。
Docker 相关的本地资源存放在 /var/lib/docker/ 目录下,其中 containers 目录存放容器信息,image 目录存放镜像信息,overlay2 目录下存放具体的镜像底层文件。


cat /var/lib/docker/image/overlay2/repositories.json        #查看下载的镜像文件信息
docker images        #查看下载到本地的所有镜像

REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    ae2feff98a0c   9 days ago   133MB

REPOSITORY:镜像属于的仓库;
TAG:镜像的标签信息,标记同一个仓库中的不同镜像;
IMAGE ID:镜像的唯一ID 号,唯一标识一个镜像;
CREATED:镜像创建时间;
VIRTUAL SIZE:镜像大小;
 

根据镜像的唯一标识 ID 号,获取镜像详细信息:
docker inspect 镜像ID号
 

为本地的镜像添加新的标签:


docker tag 名称:[标签] 新名称:[新标签]
例子:docker tag nginx:latest nginx:web

docker images | grep nginx

删除镜像:


docker rmi 仓库名称:标签                #当一个镜像有多个标签时,只是删除其中指定的标签

docker rmi 镜像ID号                        #会彻底删除该镜像

注意:如果该镜像已经被容器使用,正确的做法是先删除依赖该镜像的所有容器,再去删除镜像。

存储镜像:


docker save -o 存储文件名 存储的镜像
例子:docker save -o nginx nginx:latest            #存出镜像命名为nginx存在当前目录下
ls -lh

载入镜像:


格式:
docker load < 存出的文件
或者
docker load -i 存出的文件

上传镜像:


默认上传到 docker Hub 官方公共仓库,需要注册使用公共仓库的账号。https://hub.docker.com
可以使用 docker login 命令来输入用户名、密码和邮箱来完成注册和登录。
在上传镜像之前,还需要先对本地镜像添加新的标签,然后再使用 docker push 命令进行上传。

docker tag nginx:latest abcefgh/nginx:web        #添加新的标签时必须在前面加上自己的dockerhub的username
docker login                                                       #登录公共仓库
Username:abcdefgh
password:123456
docker push aabcdefgh/nginx:web                    #上传镜像

Docker 的数据管理


管理 Docker 容器中数据主要有两种方式:数据卷(Data Volumes)和数据卷容器(DataVolumes Containers)。


1.数据卷


数据卷是一个供容器使用的特殊目录,位于容器中。可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立刻可见,并且更新数据不会影响镜像,从而实现数据在宿主机与容器之间的迁移。数据卷的使用类似于 Linux 下对目录进行的 mount 操作。

docker pull centos:7                                                    #从 Docker 镜像仓库中拉取 CentOS 7 镜像

注意:宿主机本地目录的路径必须是使用绝对路径。如果路径不存在,Docker会自动创建相应的路径。
例子:docker run -v /var/www:/data1 --name web1 -it centos:7 /bin/bash                                        #宿主机目录/var/www 挂载到容器中的/data1。

-v 选项可以在容器内创建数据卷

验证:
echo "this is web1" > /data1/abc.txt
exit

#返回宿主机进行查看
cat  /var/www/abc.txt

2.数据卷容器


如果需要在容器之间共享一些数据,最简单的方法就是使用数据卷容器。数据卷容器是一个普通的容器,专门提供数据卷给其他容器挂载使用。
#创建一个容器作为数据卷容器
docker run --name web2 -v /data1 -v /data2 -it centos:7 /bin/bash

--name web2:指定容器的名称为 web2

-v /data1 -v /data2:将本地主机的 /data1 /data2 目录挂载到容器中。

-it:以交互模式启动容器,并分配一个伪终端 (pseudo-TTY)。

centos:7:指定要运行的镜像为 CentOS 7。

/bin/bash:在容器中启动 Bash 终端。

echo "this is web2" > /data1/abc.txt
echo "THIS IS WEB2" > /data2/ABC.txt

#使用 --volumes-from 来挂载 web2 容器中的数据卷到新的容器
docker run -it --volumes-from web2 --name web3 centos:7 /bin/bash

--volumes-from web2:从名为 web2 的容器中继承挂载的卷。

--name web3:指定新容器的名称为 web3

cat /data1/abc.txt
cat /data2/ABC.txt


端口映射

为什么要做端口映射呢?
在启动容器的时候,如果不指定对应的端口,在容器外是无法通过网络来访问容器内的服务。端口映射机制将容器内的服务提供给外部网络访问,实质上就是将宿主机的端口映射到容器中,使得外部网络访问宿主机的端口便可访问容器内的服务。


docker run -d --name test1 -P nginx                        #随机映射端口(从32768开始)

docker run -d --name test2 -p 43000:80 nginx        #指定映射端口

docker ps -a                                                             #列出所有容器 -a指所有,包括停止的容器

浏览器访问:http://192.168.90.10:43000   


容器互联(使用centos镜像)

什么是容器互联:
容器互联是通过容器的名称在容器间建立一条专门的网络通信隧道。简单点说,就是会在源容器和接收容器之间建立一条隧道,接收容器可以看到源容器指定的信息。


docker run -itd -P --name web1 centos:7 /bin/bash            #创建并运行源容器取名web1
    
docker run -itd -P --name web2 --link web1:web1 centos:7 /bin/bash          

#创建并运行接收容器取名web2,  

--link web1:web1    #将容器连接到名为 web1 的容器,同时在容器内部设置一个别名为 web1 的环境变量。

进web2 容器, ping web1
docker exec -it web2 bash
ping web1

Docker 镜像的创建


创建镜像有三种方法,分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。
1.基于现有镜像创建
(1)首先启动一个镜像,在容器里做修改
docker create -it centos:7 /bin/bash

(2)然后将修改后的容器提交为新的镜像,需要使用该容器的 ID 号创建新镜像
docker commit -m "new" -a "centos" 000550eb36da centos:test

-m 说明信息;
-a 作者信息;
-p 生成过程中停止容器的运行。

docker images

2.基于本地模板创建
通过导入操作系统模板文件可以生成镜像,模板可以从 OPENVZ 开源项目下载

wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz
cat debian-7.0-x86-minimal.tar.gz | docker import - debian:test        #导入为镜像

3.基于Dockerfile 创建

UnionFS(联合文件系统)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来叠加多层文件系统。Docker镜像就是基于UnionFS实现的,它由多个只读层和一个可读写层组成。可读写层包含镜像中添加或修改的内容,只读层包含原始镜像中的内容。当一个容器启动时,Docker会根据镜像中指定的只读层,以及容器中的可读写层,创建一个新的联合文件系统,这个文件系统包含了所有层的内容,但看起来好像只有一个文件系统。

使用联合文件系统的好处是容器的启动和运行快速,因为只需要加载必要的层,而不是复制整个文件系统。同时,多个容器可以共享一个只读层,从而节省磁盘空间。

我们下载的时候看到的一层层的就是联合文件系统。AUFS、OverlayFS 及 Devicemapper 都是一种 UnionFS。


镜像加载原理

Docker的镜像加载遵循一种层级化的文件系统结构,这就是UnionFS(联合文件系统)。

在Docker镜像中,最底层是bootfs,包含了引导加载器和内核。当系统启动时,bootfs会被加载到内存中,然后系统会卸载bootfs。

在bootfs之上是rootfs,它包含了典型Linux系统中的标准目录和文件,如/dev、/proc、/bin、/etc等。rootfs可以是不同的操作系统发行版,如Ubuntu、Centos等。

我们可以将镜像的加载过程理解为一层一层地叠加。初始状态下,内核中没有任何内容。当执行下载Debian等命令时,会在内核上添加一个基础镜像层。接着安装Emacs,又会在基础镜像层上叠加一层镜像。再安装Apache时,又会在前面的镜像层上叠加一层镜像。最终,这些层看起来就像一个完整的文件系统,即容器的rootfs。在Docker体系中,这些rootfs被称为Docker的镜像。

需要注意的是,这些rootfs层都是只读的,不能对其进行更改。当创建一个容器时,系统会在一层或多层只读的rootfs之上分配一层空的可读写rootfs,用于容器运行时的文件系统操作。这样,容器就可以在可读写的rootfs层上进行文件的修改和操作。


为什么Docker里的centos的大小才200M?


因为对于精简的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用宿主机的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

Dockerfile

Docker镜像是一个特殊的文件夹,里面包含了程序、库、资源和配置文件等,可以用来创建容器并运行应用程序。镜像的构建和定制可以通过编写一个叫做Dockerfile的文本文件来完成。

Dockerfile中的每一条指令都代表镜像的一层,每一层都是在前一层的基础上进行修改和添加。我们可以把每一层的操作命令都写在Dockerfile中,通过这个文件来构建和定制镜像。

使用Dockerfile可以方便地生成自定义的镜像。当我们有额外的需求时,只需要在Dockerfile中添加或修改指令,然后重新生成镜像即可,省去了手动输入一系列命令的麻烦。

Dockerfile的结构包括基础镜像信息、维护者信息、镜像操作指令和容器启动时执行的指令。每一行指令可以带有多个参数,并且可以使用注释以“#”号开头进行说明。

Docker 镜像结构的分层

Docker镜像的结构是由多个层构成的,而不是一个单一的文件。容器实际上是在镜像的最上面添加了一层可读写的层。当在容器中进行文件改动时,这些改动都会被写入这个可读写层。如果删除了容器,那么最上面的可读写层也会被删除,文件改动也就丢失了。Docker使用存储驱动来管理镜像的每一层以及容器层的可读写层。

(1)Dockerfile中的每个指令都会创建一个新的镜像层。

(2)镜像层会被缓存和复用,以提高构建效率。

(3)当Dockerfile的指令发生变化、复制的文件发生变化,或者构建镜像时指定的变量不同,对应的镜像层的缓存就会失效。

(4)如果某一层的镜像缓存失效,那么它之后的镜像层的缓存也会失效。

(5)镜像层是不可变的,如果在某一层中添加了一个文件,然后在下一层中删除了它,那么镜像中仍然会包含该文件,只是在Docker容器中无法看到。

Dockerfile 配置(指令)


(1)FROM 镜像
指定新镜像所基于的基础镜像,第一条指令必须为FROM 指令,每创建一个镜像就需要一条 FROM 指令

(2)MAINTAINER 名字
说明新镜像的维护人信息

(3)RUN 命令
在所基于的镜像上执行命令,并提交到新的镜像中
cd cp

(4)ENTRYPOINT ["要运行的程序", "参数 1", "参数 2"]
设定容器启动时第一个运行的命令及其参数。
可以通过使用命令docker run --entrypoint 来覆盖镜像中的ENTRYPOINT指令的内容。

ENTRYPOINT ["rm", "-rf", "/*"]

(5)CMD ["要运行的程序", "参数1", "参数2"] 
上面的是exec形式,shell形式:CMD 命令 参数1 参数2
启动容器时默认执行的命令或者脚本,Dockerfile只能有一条CMD命令。如果指定多条命令,只执行最后一条命令。
如果在docker run时指定了命令或者镜像中有ENTRYPOINT,那么CMD就会被覆盖。
CMD 可以为 ENTRYPOINT 指令提供默认参数。

ENTRYPOINT ["rm"]
CMD ["cp" ,"-rf",“*”]

java -jar    xxxxxxx.jar  8090

docker run指定的命令----》ENTRYPOINT---》CMD

(6)EXPOSE 端口号
指定新镜像加载到 Docker 时要开启的端口  EXPOSE 8090

(7)ENV 环境变量 变量值
设置一个环境变量的值,会被后面的 RUN 使用
linxu PATH=$PATH:/opt
  ENV PATH $PATH:/opt
(8)ADD 源文件/目录 目标文件/目录
将源文件复制到镜像中,源文件要与 Dockerfile 位于相同目录中,或者是一个 URL  
有如下注意事项:
1、如果源路径是个文件,且目标路径是以 / 结尾, 则docker会把目标路径当作一个目录,会把源文件拷贝到该目录下。
如果目标路径不存在,则会自动创建目标路径。
/home/ky26/zhaichen.txt    /home/ky26/

2、如果源路径是个文件,且目标路径是不以 / 结尾,则docker会把目标路径当作一个文件。
如果目标路径不存在,会以目标路径为名创建一个文件,内容同源文件;
如果目标文件是个存在的文件,会用源文件覆盖它,当然只是内容覆盖,文件名还是目标文件名。
如果目标文件实际是个存在的目录,则会源文件拷贝到该目录下。 注意,这种情况下,最好显示的以 / 结尾,以避免混淆。

3、如果源路径是个目录,且目标路径不存在,则docker会自动以目标路径创建一个目录,把源路径目录下的文件拷贝进来。
如果目标路径是个已经存在的目录,则docker会把源路径目录下的文件拷贝到该目录下。


4、如果源文件是个归档文件(压缩文件),则docker会自动帮解压。    
URL下载和解压特性不能一起使用。任何压缩文件通过URL拷贝,都不会自动解压。

(9)COPY 源文件/目录 目标文件/目录
只复制本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile 在相同的目录中

(10)VOLUME [“目录”]   
在容器中创建一个挂载点

(11)USER 用户名/UID
指定运行容器时的用户

(12)WORKDIR 路径   /home
为后续的 RUN、CMD、ENTRYPOINT 指定工作目录

(13)ONBUILD 命令
指定所生成的镜像作为一个基础镜像时所要运行的命令。
当在一个Dockerfile文件中加上ONBUILD指令,该指令对利用该Dockerfile构建镜像(比如为A镜像)不会产生实质性影响。
但是当编写一个新的Dockerfile文件来基于A镜像构建一个镜像(比如为B镜像)时,这时构造A镜像的Dockerfile文件中的ONBUILD指令就生效了,在构建B镜像的过程中,首先会执行ONBUILD指令指定的指令,然后才会执行其它指令。


OBuild rm - rf /*

注:请各位注意在生产中如果有的是别的dockerfile 请自习阅读,否则后果自付

(14)HEALTHCHECK
健康检查


在编写 Dockerfile 时,有严格的格式需要遵循:
●第一行必须使用 FROM 指令指明所基于的镜像名称;
●之后使用 MAINTAINER 指令说明维护该镜像的用户信息;
●然后是镜像操作相关指令,如 RUN 指令。每运行一条指令,都会给基础镜像添加新的一层。
●最后使用 CMD 指令指定启动容器时要运行的命令操作。


 

你可能感兴趣的:(docker,eureka,容器)