Docker架构、镜像及容器

tech2022-08-06  130

docker概述

Docker是什么?

是一种轻量级的“虚拟机” 在Linux容器里运行应用的开源工具

Docker与虚拟机的区别

docker容器与传统虚拟化的比较 特性docker容器虚拟机启动速度秒级分钟级计算能力损耗几乎无损耗50%左右性能接近原生弱于系统支持量上千个几十个隔离性资源限制完全隔离

docker与传统虚拟机架构区别 传统虚拟机需要有额外的虚拟机管理程序和虚拟机操作系统层,而docker容器时直接在操作系统层面上实现虚拟化 说明: server – 表示真实电脑。 Host OS – 真实电脑的操作系统,例如:Windows,Linux Hypervisor – 虚拟机平台,模拟硬件,如VMWare,VirtualBox Guest OS – 虚拟机平台上安装的操作系统,例如CentOS Linux App – 虚拟机操作系统上的应用,例如nginx Docker Engine – 新一代虚拟化技术,不需要包含单独的操作系统。 App – 所有的应用程序现在都作为Docker容器运行。

Docker的使用场景 打包应用程序简化部署 可脱离底层硬件任意迁移 例:服务器从腾讯云迁移到阿里云

Docker核心概念及安装

Docker的核心概念

镜像 docker镜像是创建容器的基础,类似于虚拟机的快照。 dockers提供了简单的机制来创建和更新现有的镜像,用户也可以从网上下载已经做好的应用镜像来直接使用容器 docker容器是从镜像创建的运行实例,可以被启动、停止和删除 docker利用容器来运行和隔离应用,每个容器都是相互隔离、互不可见,可以保证平台的安全性仓库 docker仓库是用来集中保存镜像的地方。 创建镜像后,可以用push命令将其上传到公共仓库(public)或者私有仓库(private) 仓库注册服务器是存放仓库的地方,其中包含多个库,每个仓库集中存放一类镜像,并使用不同的标签(tag)进行区分。 目前最大的公共仓库是docker hub

安装Docker

如果之前已经安装docker,需要先提前卸载掉 官方安装参考网址:https://docs.docker.com/install/linux/docker-ce/centos/ 安装依赖包 [root@localhost ~]# yum install -y yum-utils device-mapper-persistent-data lvm2 部署docker安装源仓库 [root@localhost ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 添加阿里云到docker源仓库,提高安装速度 [root@localhost ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 安装docker [root@localhost ~]# yum install docker-ce 启动docker并查看版本及信息 [root@localhost ~]# systemctl start docker [root@localhost ~]# systemctl enable docker [root@localhost ~]# docker version //查看docker版本 [root@localhost ~]# docker info //查看docker信息 配置阿里云镜像加速器 mkdir -p /etc/docker tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://l2f1ikye.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker

Docker镜像操作

搜索镜像

在下载镜像前,可以使用docker search命令,搜索远端官方仓库中的共享镜像。 命令格式:docker search 关键字

[root@localhost ~]# docker search dhcp NAME DESCRIPTION STARS OFFICIAL AUTOMATED #镜像名 #描述 #星级 #是否官方创建 #是否主动创建 networkboot/dhcpd Suitable for running a DHCP server for your … 49 [OK] joebiellik/dhcpd DHCP server running on Alpine Linux 18 [OK] gns3/dhcp A DHCP container for GNS3 using dnsmasq 4 [OK] ......

默认的输出结果会按照星级评价进行排序,表示该镜像受欢迎程度,在下载镜像时,可以参考这一项,在搜索时还可以使用-s或者--stars=x显示指定星级以上的镜像

[root@localhost ~]# docker search dhcp -s 40 Flag --stars has been deprecated, use --filter=stars=3 instead NAME DESCRIPTION STARS OFFICIAL AUTOMATED networkboot/dhcpd Suitable for running a DHCP server for your … 49 [OK] [root@localhost ~]#

获取镜像

搜索到符合需求的镜像,可以使用docker pull命令从网络下载镜像到本地使用 命令格式:docker pull 仓库名称[:标签] 对于Docker镜像来说,如果下载镜像时不指定标签,则默认会下载仓库中最新版本的镜像,即选择latest标签,也可通过指定的标签来下载特定版本的某一镜像。这里的标签(tag)就是用来区分镜像版本的。

[root@localhost ~]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx bf5952930446: Pull complete cb9a6de05e5a: Pull complete 9513ea0afb93: Pull complete b49ea07d2e93: Pull complete a5e4a503d449: Pull complete Digest: sha256:b0ad43f7ee5edbc0effbc14645ae7055e21bc1973aee5150745632a24a752661 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest

从整个下载的过程可以看出,镜像文件由若干层(Layer)组成,我们称之为AUFS(联合文件系统),是实现增量保存与更新的基础,下载过程中会输出镜像的各层信息。镜像下载到本地之后就可以随时使用该镜像了 用户也可以选择从其他注册服务器仓库下载,这时需要在仓库名称前指定完整的仓库注册服务器地址

[root@localhost ~]# docker pull zeng1274194886/mytest:hello-world hello-world: Pulling from zeng1274194886/mytest 0e03bdcc26d7: Already exists Digest: sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc042 Status: Downloaded newer image for zeng1274194886/mytest:hello-world docker.io/zeng1274194886/mytest:hello-world

查看镜像信息

用户可以使用docker images命令查看下载到本地的所有镜像 命令用法:docker images 仓库名称:[标签] 例如:查看本地所有镜像

[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 4bb46517cac3 2 weeks ago 133MB zeng1274194886/mytest hello-world bf756fb1ae65 8 months ago 13.3kB networkboot/dhcpd latest 52cbff801df2 17 months ago 105MB

输出字段含义: REPOSITORY :镜像属于的仓库 TAG :镜像的标签信息,标记同一个仓库中不同的镜像 IMAGE ID :镜像的唯一ID号,唯一标识了该镜像 CREATED :镜像创建时间 SIZE :镜像大小

用户还可以根据镜像的唯一标识ID号。获取镜像详细信息 命令格式:docker inspect 镜像ID号

[root@localhost ~]# docker inspect 4bb46517cac3 [ { "Id": "sha256:4bb46517cac397bdb0bab6eba09b0e1f8e90ddd17cf99662997c3253531136f8", "RepoTags": [ "nginx:latest" ], "RepoDigests": [ "nginx@sha256:b0ad43f7ee5edbc0effbc14645ae7055e21bc1973aee5150745632a24a752661" ], "Parent": "", "Comment": "", "Created": "2020-08-14T00:36:48.610531148Z", ......

为了在后续工作中使用这个镜像,可以使用docker tag命令来为本地的镜像添加新的标签 命令格式:docker tag 名称:[标签] 新名称:[新标签]

[root@localhost ~]# docker tag nginx nginx:mytest [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 4bb46517cac3 2 weeks ago 133MB nginx mytest 4bb46517cac3 2 weeks ago 133MB

删除镜像

可以使用docker rmi命令删除多余的镜像 删除镜像的操作有两种方法:使用镜像的标签删除镜像;使用镜像的ID删除镜像 命令格式:docekr rmi 仓库名称:标签 或者docker rmi 镜像ID

[root@localhost ~]# docker rmi nginx:mytest Untagged: nginx:mytest

当有一个镜像有多个标签的时候,docker rmi命令只是删除该镜像多个标签中的指定标签,不会影响镜像文件,相当于只删除了镜像的一个标签而已。但当该镜像只剩下一个标签的时候就要小心了,再使用删除命令就会彻底删除该镜像 当使用docker rmi 命令后面跟上镜像的ID号时,必须确保该镜像没有被容器使用,删除时系统会先删除掉指向该镜像的所有标签,然后删除该镜像文件本身,如果该镜像已经被容器使用,正确的做法是先删除依赖该镜像的所有容器,再删除镜像

存出和载入镜像

当需要把一台机器上的镜像迁移到另一台机器上的时候,需要将镜像保存成本地文件,这一过程叫做存出镜像,可以使用docker save命令进行存出操作,之后就可以拷贝该文件到其他机器 命令格式:docker save -o 存出文件名 存出的镜像

[root@localhost ~]# docker save -o mynginx nginx:latest [root@localhost ~]# ls anaconda-ks.cfg docker mynginx nginx

将存出的镜像从A机器拷贝到B机器,需要在B机器上使用该镜像,就可以将该导出文件导入到B机器的镜像库中,这一过程叫做载入镜像。使用docker load或者docker --input进行载入操作 命令格式:docker load < 存出的文件 或者 docker --input 存出的文件

[root@localhost ~]# docker load < mynginx d0f104dc0a1f: Loading layer [==================================================>] 72.49MB/72.49MB 0338db614b95: Loading layer [==================================================>] 64.31MB/64.31MB a4d893caa5c9: Loading layer [==================================================>] 3.072kB/3.072kB 22ea89b1a816: Loading layer [==================================================>] 4.096kB/4.096kB 550333325e31: Loading layer [==================================================>] 3.584kB/3.584kB Loaded image: nginx:latest

上传镜像

本地存储的镜像越来越多,就需要指定一个专门的地方存放这些镜像——仓库。目前比较方便的就是公共仓库,默认上传到Docker Hub官方仓库,需要注册使用公共仓库的帐号,可以使用docker login命令来输入用户名、密码和邮箱来完成注册和登录。在上传镜像之前还需要对本地镜像添加新的标签,然后再使用docekr push命令进行上传 命令格式:docker push 仓库名称:标签 比如,我们在公共仓库已经成功注册了一个帐号docker,新增nginx的标签为docker/mytest:nginx

[root@localhost ~]# docker tag nginx docker/mytest:nginx [root@localhost ~]# docker login Username: docker Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded

成功登录后就可以上传镜像

[root@localhost ~]# docker push docker/mytest:nginx

Docker容器操作

容器是Docker的另一个核心概念。简单说,容器是镜像的一个运行实例,是独立运行的一个或一组应用以及他们所必需的的运行环境,包括文件系统、系统类库、shell环境等。镜像是只读模版,而容器会给这个只读模版一个额外的可写层

容器的创建与启动

容器的创建就是将镜像加载到容器的过程,Docker的容器十分轻量级,用户可以随时创建或者删除。新创建的容器默认处于停止状态,不运行任何程序,需要在其中发起一个进程来启动容器,这个进程时该容器的唯一进程,所以当该进程结束的时候,容器也会完全停止。停止的容器可以重新启动并保留原来的修改。 使用docker create命令可以新建一个容器 命令格式docker create [选项] 镜像 运行的程序

常用选项 -i 让容器的输入保持打开 -t 让Docker分配一个伪终端

[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker/mytest nginx 4bb46517cac3 2 weeks ago 133MB nginx latest 4bb46517cac3 2 weeks ago 133MB zeng1274194886/mytest hello-world bf756fb1ae65 8 months ago 13.3kB networkboot/dhcpd latest 52cbff801df2 17 months ago 105MB [root@localhost ~]# docker create -it nginx:latest /bin/bash 06be5298d3b3296beadad2e2899c9f7743ded8e22107843c3842436150e0ae9d

使用docker命令创建新容器会返回一个唯一的ID 可以使用docker ps -a命令来查看所有容器的运行状态,添加 -a 选项可以列出系统最近一次启动的容器

[root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 06be5298d3b3 nginx:latest "/docker-entrypoint.…" 2 minutes ago Created serene_newton

输出信息包括容器的ID号、加载的镜像、运行的程序、创建时间、目前所处的转态、端口映射。其中状态一栏若为空表示当前容器处于停止状态 启动停止的容器可以使用docker start命令 命令格式:docker start 容器的ID/名称

[root@localhost ~]# docker start 06be5298d3b3 06be5298d3b3 [root@localhost ~]# docker ps -a | grep 06be5298d3b3 06be5298d3b3 nginx:latest "/docker-entrypoint.…" 7 minutes ago Up 32 seconds 80/tcp serene_newton

容器启动后,可以看到状态一栏已经变为UP,表示容器已经处于启动状态 如果用户想创建并启动容器,可以直接执行docker run命令,等同于先执行docker create命令,再执行docker start命令。需要注意只要后面的命令运行结束,容器就会停止。 当利用docker run来创建容器时,Docker在后头的标准运行过程是:检查本地是否存在指定的镜像,当镜像不存在时,会先从公共仓库下载;利用镜像创建并启动一个容器;分配一个文件系统给容器,在只读的镜像层外面挂载一层可读写层;从宿主主机配置的网桥接口中桥接一个虚拟机到容器中;分配一个地址池中的IP给容器;执行用户指定的应用程序;执行完毕后容器被终止运行

[root@localhost ~]# docker run nginx:latest /usr/bin/bash -c ls / /docker-entrypoint.sh: 38: exec: /usr/bin/bash: not found [root@localhost ~]# docker run nginx:latest /bin/bash -c ls / bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c2f90ce55438 nginx:latest "/docker-entrypoint.…" About a minute ago Exited (0) About a minute ago elastic_cannon

查看容器的运行状态,可以看出容器在执行完"/bin/bash -c ls"命令之后就停止了 有时候需要在后台持续运行这个容器,就需要让Docker容器以守护进程形式在后台运行。可以在docker run命令之后添加-d选项来实现,但是需要注意容器所运行的程序不能结束

容器的运行与终止

如果需要终止运行的容器,可以使用docker stop命令完成 命令格式:docker stop 容器的ID/名称

[root@localhost ~]# docker stop 5beb54c3455f 5beb54c3455f [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5beb54c3455f nginx "/docker-entrypoint.…" About a minute ago Exited (0) 5 seconds ago zealous_moore

容器的进入

需要进入容器进行相应操作时,可以使用docker exec命令进入运行着的容器 命令格式:docker exec -it 容器ID /bin/bash

[root@localhost ~]# docker exec -it 5beb54c3455f /bin/bash root@5beb54c3455f:/# ls bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var 用户可以通过所创建的终端来输入命令,通过exit命令退出容器 root@5beb54c3455f:/# exit exit

容器的导出与导入

1.导出 命令格式:docker export 容器ID > 文件名

[root@localhost ~]# docker export 5beb54c3455f > docker-nginx [root@localhost ~]# ls anaconda-ks.cfg docker docker-nginx mynginx nginx

导出的文件从A机器拷贝到B机器,之后使用docker import命令导入,称为镜像 命令格式:cat 文件名 | docker import - 生成的镜像名称:标签

[root@localhost ~]# cat docekr-ngixn | docker import - docker-nginx:test sha256:325563723f992465b903c2b8159598e23729962a6bb2830ddc76c35d6b107606 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker-nginx test 325563723f99 23 seconds ago 0B

容器的删除

可以使用docker rm命令讲一个已经处于终止状态的容器删除 命令格式:docker rm 容器ID

[root@localhost ~]# docker rm 41dd0f88afca 41dd0f88afca [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

如果要删除一个正在运行的容器,可以添加-f选项强制删除 Docker默认的存储目录在/var/lib/docker,Docker的镜像、容器、日志等内容全部都存储在此,也可以单独使用大容量的分区来存储这些内容,并且一般选择建立LVM逻辑卷,从而避免出现Docker运行过程中存储目录容量不足的问题

Docker资源控制

Cgorup是Control group的简写,是Linux内核提供的一种限制所使用的物理资源的机制,这些资源主要包括CPU、内存、blkio

对CPU的控制

限制CPU使用率 在多cpu机器上,将一组运行时限制为2个cpu。 500ms的周期和1000ms的配额,组可以得到2个cpu的价值 运行时每500毫秒 echo 1000000 > /sys/fs/cgroup/cpu/docker/cpu.cfs_quota_us ##quota = 1000ms## echo 500000 > /sys/fs/cgroup/cpu/docker/cpu.cfs_period_us ##period = 500ms##

限制一个组为1个CPU的20%。 对于50ms的周期,10ms的配额相当于一个CPU的20%

echo 10000 > /sys/fs/cgroup/cpu/docker/cpu.cfs_quota_us echo 50000 > /sys/fs/cgroup/cpu/docker/cpu.cfs_period_us 多任务按比例分享 CPU 当有多个容器任务运行时,很难计算CPU的使用率。为了使容器合理使用 CPU资源,可以通过 “–cpu-share ” 选项设置 CPU按比例共享 CPU资源,还可以实现 CPU使用率的动态调整。 比如:运行三个容器A、B、C,占用CPU资源的比例为 1:1:2,可以执行。 docker run --cpu-share 1024 容器A docker run --cpu-share 1024 容器B docker run --cpu-share 2048 容器C 限制 CPU内核使用 使用 “–cpuset-cpus” 选项来使某些程序独享 CPU内核,以提高其处理速度。 对应的 Cgroup 配置文件为 /sys/fs/cgroup/cpuset/docker/容器编号/cpuset.cpus。 docker run --cpuset-cpus 0,1,2,3 容器名 #那么该容器内的进程只会在编号 1、2、3、4、的 CPU上运行。

尽量使用绑定内核的方式分配 CPU资源给容器进程使用,然后再配合 “–cpu-share”选项动态调整 CPU使用资源比例。

对内存使用的限制

#限制容器内存为 512M docker run -m 512m 容器名 #对应的Cgroup配置文件 /sys/fs/cgroup/memory/memory.limit_in_bytes 注意:一旦容器 Cgroup使用的内存超过了限制的容量,Linux内核将会尝试收回这些内存,如果仍旧没法控制内存使用在限制范围之内,进程将会被杀死。

对 blkio 的限制

在一台服务器上进行容器的混合部署,会有同时出现几个程序写磁盘数据的情况, #限制写入的 iops --device-write-iops #限制读取的 iops --device-read-bps #相应 Cgroup配置文件 /sys/fs/cgroup/blkio/docker/容器ID/blkio.throttle.write_iops_device

这种方法只能针对 blkio限制的是设备(device),而不是分区。

示例 #限制容器的 /dev/sda1 的写入 ipos为 1MB. dockers run --device-write-bps /dev/sda1:1mb 容器名

总结

Docker 镜像的操作有:搜索、获取、查看、删除、存出、载入、上传。Docker 容器是镜像的一个运行实例,是独立运行的一个或一组应用以及它们所必需的运行环境,包括文件系统、系统类库、shell环境等。Cgroup(Control group),是Linux内核提供的一种限制所使用物理资源的机制,这些资源主要包括 CPU、内存、blkio。
最新回复(0)