首页>软件资讯>常见问题

常见问题

Docker入门到精通

发布时间:2025-02-18 22:03:12人气:184


Docker容器

一、Docker简介

1.1、Docker是什么

Docker 最初是 dotCloud 公司创始人Solomon Hykes在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于2013 年 3 月以 Apache 2.0 授权协议开源 ,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 [开放容器联盟(OCI)。


Docker 自开源后受到广泛的关注和讨论,至今其GitHub 项目已经超过 5 万 7 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。


Docker 使用 Google 公司推出的 Go 语言进行开发实现,基于 Linux 内核的cgroup,namespace,以及 OverlayFS类的Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 版本开始,则进一步演进为使用runC和containerd。

Docker入门到精通.png

1.2、我们为什么要用Docker

#更高效的利用系统资源

由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。


#更快速的启动时间

传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。


#一致的运行环境

开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。


#持续交付和部署

对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration)系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment)系统进行自动部署。而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。


#更轻松的迁移

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。


#更轻松的维护和扩展

Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像 (opens new window),既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

1.3、与传统虚拟机对比

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个


二、Docker基本概念

2.1、基本概念

Docker三个重要的概念


镜像 (Image)


容器 (Container)


仓库 (Repository)


2.2、Docker镜像

镜像内包含操作系统,提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含 任何动态数据,其内容在构建之后也不会被改变

2.3、Docker容器

镜像(Image)和容器(Container)的关系,就像是QQ软件跟QQ进程一样,镜像是静态的,容器是镜像运行时的实体。

容器可以被创建、启动、停止、删除、暂停等


容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的空间,因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。

2.4、Docker仓库

仓库类似于应用商店,存放的是docker镜像,分为公开仓库跟私有仓库


通常,仓库可以包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <镜像名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。


以 Ubuntu 镜像为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如,16.04, 18.04。我们可以通过 ubuntu:16.04,或者 ubuntu:18.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 ubuntu,那将视为 ubuntu:latest。

三、安装Docker

3.1、系统初始化

0.系统版本

[root@docker ~]# cat /etc/redhat-release

CentOS Linux release 7.8.2003 (Core)

[root@docker ~]# uname -r

3.10.0-1127.el7.x86_64


1.更改主机名

[root@docker ~]# hostnamectl set-hostname docker


2.禁用Selinux

[root@docker ~]# sed -i 's/SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config  永久关闭,重启系统后生效

[root@docker ~]# setenforce 0 临时关闭

setenforce: SELinux is disabled

[root@docker ~]# getenfoce

Disabled


3.关闭防火墙(firewalld)

[root@docker ~]# systemctl stop firewalld 停止

[root@docker ~]# systemctl disable firewalld 禁止开机自启


4.YUM配置

[root@docker ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 下载yum源

[root@docker ~]# yum clean all 清除缓存

[root@docker ~]# yum makecache 生成缓存

[root@docker ~]# yum install epel-release -y 安装额外源

[root@docker ~]# yum install wget  vim gcc gcc-c++ lsof lrzsz bash-completion net-tools tree -y 安装常用命令及工具

[root@docker ~]# systemctl reboot


3.2、安装Docker前置操作

1.卸载Centos7默认的docker

[root@docker ~]# yum remove docker                 

docker-client

docker-client-latest                    

docker-common                    

docker-latest                  

docker-latest-logrotate                   

docker-logrotate                   

docker-engine


2.安装Docker依赖并且配置阿里云docker源

[root@docker ~]# yum install lvm2 device-mapper-persistent-data yum-utils -y  安装依赖相关

[root@docker ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 配置docker下载源

[root@docker ~]# yum makecache fast

3.3、安装Docker并启动

1.安装Docker 

[root@docker ~]# yum install docker-ce docker-ce-cli containerd.io -y


2.配置AliYun加速

[root@docker ~]# mkdir -p /etc/docker

[root@docker ~]# cat >/etc/docker/daemon.json<<EOF

{

  "registry-mirrors": ["https://ncw0pf4i.mirror.aliyuncs.com"]

}

EOF

[root@docker ~]# systemctl daemon-reload


3.设置开机自启并启动

[root@docker ~]# systemctl enable --now docker

3.4、启动第一个Docker容器

[root@docker ~]# docker run hello-world


1.查找本地镜像仓库

2.拉取docker hub中的hello-world镜像

3.下载完成

4.启动镜像为容器

Hello from Docker!

四、Docker常见操作

4.1、查看版本信息

Docker版本信息


[root@docker ~]# docker version

Client: Docker Engine - Community 客户端版本信息

 Version:           20.10.6

 API version:       1.41

 Go version:        go1.13.15

......

Server: Docker Engine - Community 服务端版本信息

 Engine:

  Version:          20.10.6

  API version:      1.41 (minimum version 1.12)

  Go version:       go1.13.15

.....


解析:

Docker客户端与服务端版本默认为一致,Docker底层用Golang语言开发的

Docker是C/S架构,分为客户端与服务端

客户端敲命令---->服务端运行解析命令并且展示结果



Docker详细信息(包含全面,建议使用此命令)

[root@docker ~]# docker info

Client:

......


Server:

 Containers: 1 容器数量

  Running: 0 有几个正在运行

  Paused: 0 有几个暂停啦

  Stopped: 1 有几个停止了

 Images: 2 有几个镜像

 Kernel Version: 3.10.0-1127.el7.x86_64 系统内核版本

 Operating System: CentOS Linux 7 (Core) 系统版本

 OSType: linux 

 Architecture: x86_64

 CPUs: 1

 Total Memory: 972.3MiB

 Name: docker

 Registry Mirrors:

  https://ncw0pf4i.mirror.aliyuncs.com/ 阿里云docker镜像地址,可以加速docker下载

4.2、镜像相关命令

0.获取帮助

[root@docker ~]# docker image --help


Usage:  docker image COMMAND

Commands:

  build       Build an image from a Dockerfile

  history     Show the history of an image

  import      Import the contents from a tarball to create a filesystem image

  inspect     Display detailed information on one or more images

  load        Load an image from a tar archive or STDIN

  ls          List images

  prune       Remove unused images

  pull        Pull an image or a repository from a registry

  push        Push an image or a repository to a registry

  rm          Remove one or more images

  save        Save one or more images to a tar archive (streamed to STDOUT by default)

  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE



1.查看镜像

docker image ls 显示本地镜像

docker images 显示本地镜像

docker image ls 简写为 docker images


-q 只显示镜像id


[root@docker ~]# docker image ls

REPOSITORY    TAG       IMAGE ID       CREATED        SIZE

redis         latest    bc8d70f9ef6c   2 weeks ago    105MB

hello-world   latest    d1165f221234   2 months ago   13.3kB

镜像名    版本(latest最新版本) 镜像ID       创建时间(官方)  镜像大小



2.下载镜像

docker pull 镜像名:版本号 ---> 下载指定镜像及版本

docker pill 镜像名 ---> 下载指定镜像(最新版本-latest)


[root@docker ~]# docker pull redis:6.0   下载redis6.0镜像

6.0: Pulling from library/redis  拉取镜像信息

69692152171a: Pull complete  下载相关镜像内容

......

d040d72a588c: Pull complete 

Digest: sha256:71909943bb7ca4b34b6b151e7b29c608ddae654cdc9a1d2d15f30df666b3a805 镜像签名

Status: Downloaded newer image for redis:6.0  告诉你下载一个新的镜像

docker.io/library/redis:6.0


3.删除镜像

docker image rm 镜像名:版本

docker image rm 镜像ID

docker rmi 镜像名:版本

docker rmi 镜像ID

docker image rm 简写 docker rmi


删除hello-world镜像

[root@docker ~]# docker image rm hello-world:latest 

Untagged: hello-world:latest

......

Deleted: sha256:f22b99068db93900abe17f7f5e09ec775c2826ecfe9db961fea68293744144bd


删除redis镜像

[root@docker ~]# docker rmi 5f6517031937

Untagged: redis:6.0

......

Deleted: sha256:02c055ef67f5904019f43a41ea5f099996d8e7633749b6e606c400526b2c4b33


如何强制删除镜像,不管有没有容器在运行


无法删除镜像,因为有容器在依赖于这个镜像

[root@docker ~]# docker rmi -f d1a364dc548d

Error response from daemon: conflict: unable to delete d1a364dc548d (cannot be forced) - image is being used by running container ff53779c6e49


只是删了镜像的名称跟id跟版本号,但是镜像本身并没有被删除

[root@docker ~]# docker image rm -f nginx:latest 

Untagged: nginx:latest

Untagged: nginx@sha256:6d75c99af15565a301e48297fa2d121e15d80ad526f8369c526324f0f7ccb750


总结:容器在运行中的状态无法强制删除镜像



4.搜索镜像

docker search 镜像名称


[root@docker ~]# docker search redis

NAME                             DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED

redis                            Redis is an open source key-value store that…   9491      [OK]  

不推荐使用docker search,无法显示详细版本信息,推荐浏览器访问 docker hub(hub.docker.com)去搜索 

4.3、容器相关操作

1.运行镜像为容器

docker run 镜像名:版本

docker run 镜像id

-d 把容器放入后台执行(默认是一直在终端显示的)

-p 宿主机端口映射至容器内(默认容器不能跟外部连接的) -p 宿主机端口:容器内部端口

--name 自定义容器名称(默认是docker创建的)

-P 宿主机 随机暴露端口


[root@docker ~]# docker run nginx:latest 

[root@docker ~]# docker run -d -p 1192:80 nginx:latest  运行nginx:latest镜像为容器80端口映射至宿主机为1192,并且放到后台运行

[root@docker ~]# docker run -d -p 1721:80 --name nginx01 nginx:latest 运行nginx:latest镜像为容器80端口映射至宿主机为1721,容器名称为nginx01并且放到后台运行


2.查看容器信息

docker ps 查看容器(默认只能显示已启动的容器)

-a 显示全部容器

-q 只显示容器id


[root@docker ~]# docker ps 

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS     NAMES

ff53779c6e49   nginx:latest   "/docker-entrypoint.…"   23 seconds ago   Up 21 seconds   80/tcp    relaxed_goldwasser

容器id          次容器使用的镜像    容器内使用的命令            容器创建时间      容器状态         容器内端口    容器名


[root@docker ~]# docker ps -a

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                      PORTS     NAMES

2df897bd6df2   nginx:latest   "/docker-entrypoint.…"   29 seconds ago   Exited (0) 13 seconds ago             blissful_kepler

7be3ab768824   nginx:latest   "/docker-entrypoint.…"   2 minutes ago    Up About a minute           80/tcp    kind_shannon


[root@docker ~]# docker ps -aq

2df897bd6df2

7be3ab768824


3.启动停止重启容器

启动

docker start 容器名称/容器id


停止

docker stop 容器名称/容器id


重启

docker restart 容器名称/容器id


杀死

docker kill 容器名称/容器id


停止容器

[root@docker ~]# docker stop nginx01

nginx01


重启容器

[root@docker ~]# docker restart 88a13d4d8563

88a13d4d8563

[root@docker ~]# docker ps

88a13d4d8563   nginx:latest   "/docker-entrypoint.…"   15 minutes ago   Up 2 minutes    0.0.0.0:1192->80/tcp, :::1192->80/tcp                                          adoring_kapitsa

启动容器

[root@docker ~]# docker start kind_shannon

kind_shannon


杀死容器

[root@docker ~]# docker kill 5e571d75a8a1

5e571d75a8a1



4.删除容器

docker rm 容器名/容器id

-f 强制删除(不管容器是不是在运行)

[root@docker ~]# docker rm 5e571d75a8a1

[root@docker ~]# docker rm nervous_chaplygin 提示容器在运行中,无法删除

Error response from daemon: You cannot remove a running container 8b8a79ae102b78ca80d5a1c118c94a943dcdd1a22b890d0f4799cbfc7ad9a261. Stop the container before attempting removal or force remove

[root@docker ~]# docker rm -f nervous_chaplygin

nervous_chaplygin


删除所有容器,不管是不是在运行中

[root@docker ~]# docker rm -f $(docker ps -qa)

d0f474399e44

e5d9a0b71fd8

88a13d4d8563

80f537b47ffe

2df897bd6df2

7be3ab768824

[root@docker ~]# docker ps -qa

五、Docker高级操作

5.1、容器命令高级操作

1.宿主机与容器进行交互

docker exec 容器名称/容器的ID CMD

-i 交互模式(始终保持标准输入STDIN打开)

-t 分配一个虚拟终端


[root@docker ~]# docker exec -it nginxtest bash

root@574d9d59f4c8:/# ls

bin   dev   docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var

boot  docker-entrypoint.d  etc lib   media  opt  root  sbin  sys  usr



2.容器中的进程

docker top 容器id/容器名称

[root@docker ~]# docker top 574d9d59f4c8

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD

root                1686                1667                0                   10:04               ?                   00:00:00            nginx: master process nginx -g daemon off;

101                 1740                1686                0                   10:04               ?                   00:00:00            nginx: worker process



3.容器启动命令高阶

docker run 选项 镜像名称/镜像id

—P 随机分配端口

-h 指定容器内主机名    格式: -h "ngx"

-i 以交互模式运行容器

-t 为容器分配一个虚拟终端


3.1随机分配一个端口

[root@docker ~]# docker run -d -P --name test01 nginx:latest

09808471f276ab4dcb52554a1019c521a1f88f11be408c37fdc7cc1a348ff8c7

[root@docker ~]# docker ps -a

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                     NAMES

09808471f276   nginx:latest   "/docker-entrypoint.…"   8 seconds ago    Up 6 seconds    0.0.0.0:49153->80/tcp, :::49153->80/tcp   test01


3.2随机分配一个端口并且指定容器主机名为ngx

[root@docker ~]# docker run -d -P -h "ngx" --name test02 nginx:latest

614b6f37cde9afcd98ea48711f9250d2ee168995754a9edf7f6a5bf4c45c278e

[root@docker ~]# docker exec -it test02 bash

root@ngx:/# exit

exit


3.3以交互模式运行一个容器

[root@docker ~]# docker run -it nginx:latest bash

root@e645897cd8f3:/# ls

bin   dev   docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var

boot  docker-entrypoint.d  etc lib   media  opt  root  sbin  sys  usr

[root@docker ~]# docker ps -a

CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS                     PORTS                                     NAMES

e645897cd8f3   nginx:latest   "/docker-entrypoint.…"   17 seconds ago       Exited (0) 6 seconds ago                                             mystifying_rosalind

如果退出,对应的容器也就结束运行



4.宿主机与容器复制

docker cp

4.1容器文件复制到宿主机

docker cp 容器id/容器名:容器内的文件路径 宿主机存放位置  


[root@docker ~]# docker cp nginxtest:/usr/share/nginx/html/index.html /root/

[root@docker ~]# ls

index.html  init.sh


4.2宿主机复制到容器内

docker cp 宿主机文件 容器id/容器名:容器存放目录 

[root@docker ~]# docker cp /root/test.html nginxtest:/usr/share/nginx/html

root@574d9d59f4c8:/usr/share/nginx/html# pwd

/usr/share/nginx/html

root@574d9d59f4c8:/usr/share/nginx/html# ls

50x.html  index.html  test.html



5.查看运行容器的日志

docker logs

docker logs 容器id/容器名

-f 实时刷新

-t 日志显示系统时间戳

--tail N 查看后几行日志,N表示数字


5.1实时刷新显示容器日志内容

[root@docker ~]# docker logs -f nginxtest

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration

/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/

/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh

10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf

10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf



5.2显示容器的后5行内容

[root@docker ~]# docker logs --tail 2 nginxtest

2021/05/28 03:36:25 [error] 31#31: *3 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.20.100.2, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "172.20.100.4", referrer: "http://172.20.100.4/"

172.20.100.2 - - [28/May/2021:03:36:25 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://172.20.100.4/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36" "-"


6.查看容器详细信息

docker inspect 容器名/容器ID


[root@docker ~]# docker inspect nginxtest | less

5.2、Docker数据卷基本操作

1.数据卷的作用 volume

可以实现宿主机跟容器之间文件共享,可供一个或多个容器使用,与cp命令不一样


场景

希望宿主机内的/test/app 跟容器内的/html 目录进行实时同步,分享,有项目上新 直接更改宿主机的目录即可,无需使用cp命令复制

Docker官方要求数据卷的使用需要在启动时指定


特性:

数据卷可以再宿主机跟容器之间共享文件,多个容器使用一个数据卷

数据卷修改可以直接生效,无需重启容器

数据卷的修改不会干扰镜像本身

数据卷的生命周期,不会被容器启停删除干扰



数据卷命令选项及格式

docker run 

-v 使用数据卷

-v 宿主机目录:容器内目录 

-v 数据卷名称:容器内目录


将宿主机目录直接映射到容器

自定义数据源目录(会清空容器数据卷目录下面的内容)

[root@docker ~]# docker run -d -P -v /html:/usr/share/nginx/html nginx:latest 

7693cfc076994602a522b199dc84cd6a18c49fc7530a0ae86c4e84d5c968028e


在宿主机内进行操作,查看容器映射的目录下有没有改变

[root@docker html]# cat index.html 

<h1>hello,nginx,centos</h1>

<h2>12121</h2>


宿主机进行查看

[root@docker ~]# docker exec -it 7693c bash

root@7693cfc07699:/usr/share/nginx/html# pwd

/usr/share/nginx/html

root@7693cfc07699:/usr/share/nginx/html# cat index.html 

<h1>hello,nginx,centos</h1>

<h2>12121</h2>



自动数据卷目录(不会清空容器数据卷目录下的原始内容,自动拷贝到宿主机数据卷目录下)

宿主机进行查看

[root@docker ~]# docker run -d -P -v wb:/usr/share/nginx/html nginx:latest 

cd7d68ae095e119b9d616bad63b56b4f926533faa8b589519ee5e56bfb59f9fa

[root@docker ~]# cd `find / -name wb -type d`

[root@docker wb]# cd _data/

[root@docker _data]# ls

50x.html  index.html

[root@docker ~]# docker inspect nginx03 | grep html_date

                "html_date:/usr/share/nginx/html"

                "Name": "html_date",

                "Source": "/var/lib/docker/volumes/html_date/_data",



容器内数据卷映射目录查看

[root@docker _data]# docker exec -it cd7d68ae095 bash

root@cd7d68ae095e:/# cd /usr/share/nginx/html/

root@cd7d68ae095e:/usr/share/nginx/html# ls

50x.html  index.html


对文件数据进行修改

[root@docker _data]# echo '<h1>12111111</h1>' > index.html 


容器内查看

root@cd7d68ae095e:/usr/share/nginx/html# cat index.html 

<h1>12111111</h1>

5.2.1、删除容器查看数据卷

1.启动容器并且挂载

[root@docker ~]# docker run -d -P --name ngx01 -v ngx:/usr/share/nginx/html nginx:latest 

6348b2dc90fdaa2827f39bb1eda5f75ea27fd13fb19b6c61d1d420857c7e8375


2.宿主机新增文件

[root@docker _data]# echo  '<h1>abc</h1>' > abc.html

[root@docker _data]# ls

50x.html  abc.html  index.html


3.容器内查看

[root@docker _data]# docker exec -it ngx01 bash

root@6348b2dc90fd:/# cd /usr/share/nginx/html/ && ls

50x.html  abc.html  index.html


4.删除容器,查看数据卷有没有被删除

[root@docker _data]# docker rm -f ngx01

ngx01

[root@docker _data]# pwd

/var/lib/docker/volumes/ngx/_data

[root@docker _data]# ls

50x.html  abc.html  index.html

5.3、打包、导出、导入

docker commit 把容器打包为镜像(运行中的容器会暂停)

-m 描述选项

-a 作者信息


docker commit -m "描述" -a "作者信息" 容器id/容器名称 镜像名称


打包

[root@docker ~]# docker commit -m "ngx-test" -a "xwx" 152c041dc3ea ngx-01

sha256:5e8145edd814197961acb03ef80b62685f0273321d346724f551879a86b5436a


查看本地镜像仓库

[root@docker ~]# docker images

REPOSITORY   TAG       IMAGE ID       CREATED         SIZE

ngx-01       latest    5e8145edd814   8 seconds ago   133MB


尝试运行

[root@docker ~]# docker run -d -P --name ngx0000  ngx-01

51419a9ff948c77371d4ad7f2593bdf425daf494e27c1f0afd52c4a129b9d324

[root@docker html]# docker ps

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                     NAMES

51419a9ff948   ngx-01         "/docker-entrypoint.…"   8 seconds ago    Up 7 seconds    0.0.0.0:49164->80/tcp, :::49164->80/tcp   ngx0000



把镜像保存成tar包

docker save

-o 保存成为文件

docker save 镜像名称/镜像id -o 文件名


[root@docker html]# docker save ngx-01 -o ngx-01.tar

[root@docker html]# ls

123.ht  index.html  jjjj.html  ngx-01.tar



导入使用save命令导出的镜像

docker load [选项]

-i 指定导入的文件


[root@docker html]# docker images

REPOSITORY   TAG       IMAGE ID       CREATED         SIZE

ngx-01       latest    5e8145edd814   5 minutes ago   133MB

nginx        latest    d1a364dc548d   2 days ago      133MB

tomcat       latest    c43a65faae57   2 weeks ago     667MB

[root@docker html]# docker rmi -f 5e8145edd814

Untagged: ngx-01:latest

Deleted: sha256:5e8145edd814197961acb03ef80b62685f0273321d346724f551879a86b5436a

[root@docker html]# docker images

REPOSITORY   TAG       IMAGE ID       CREATED       SIZE

nginx        latest    d1a364dc548d   2 days ago    133MB

tomcat       latest    c43a65faae57   2 weeks ago   667MB

[root@docker html]# docker load -i ngx-01.tar 

Loaded image: ngx-01:latest

[root@docker html]# docker images

REPOSITORY   TAG       IMAGE ID       CREATED         SIZE

ngx-01       latest    5e8145edd814   7 minutes ago   133MB



docker export 导出容器为文件

-o 指定保存的系统名称


docker export -o xxxx container_name



$ docker ps 

CONTAINER ID   IMAGE                  COMMAND                  CREATED        STATUS        PORTS                                                  NAMES

85af44245e8c   prom/mysqld-exporter   "/bin/mysqld_exporte…"   22 hours ago   Up 22 hours   0.0.0.0:9104->9104/tcp, :::9104->9104/tcp              mysql_exporter

f74499bd0e3a   mysql:8.0.31           "docker-entrypoint.s…"   44 hours ago   Up 44 hours   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql


$ docker export -o mysql_exporter.tar mysql_exporter


$ ls

mysql_exporter.tar



docker import 导入文件为镜像

docker import 文件名称 新的镜像名


$ docker import mysql_exporter.tar mysqld_exporter 

sha256:3789516bde5a75a86d192b02da2fbc664a657dded7843ed5fd768901a14185f2

$ docker images | grep exporter

mysqld_exporter        latest    3789516bde5a   10 seconds ago   19.2MB



区别:

docker save保存的是镜像(image),docker export保存的是容器(container);

docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;

docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。

5.4、镜像分层原理

UNiOSFS -- 联合文件系统


0.什么是docker镜像

镜像就是软件,可以独立运行的软件包(已经把软件运行时候需要依赖的各种库,配置文件都已经打包进行)


1.docker镜像为什么这么大

镜像包含了软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时所需的库、环境变量和配置文件。


2.Docker镜像分层原理

如果不使用分层原理的话,相同的软件不同版本,下载的话会非常占用系统空间,因为每个软件都需要自己的依赖跟操作系统支撑

镜像构建的时候,尽量划分的层级细腻一点确保,公共层可以被更好的复用,同类型的软件,可以复用,比方用上个镜像的操作系统依赖,既可以完成本身的镜像构建,也可以被镜像复用


3.公共层

一般都被我们成为基础镜像,base镜像,把具有公共性的层抽取出来做成公共镜像,所有的镜像都是基于公共镜像去构建字节的,拆分越细,复用率越高,在宿主机上占用的空间越小,镜像运行必须依赖操作系统,因为docker镜像采用是系统级别的隔离,最小操作系统 bootfs 主引导操作系统文件,主要包含bootloader(引导操作系统内核)、kernel(操作系统的内核),rootfs典型的linux系统,包含常用目录及文件,精简版的os系统 

六、容器网络

6.1、Docker网络简介

当 Docker 启动时,会自动在主机上创建一个 docker0 虚拟网桥,实际上是 Linux 的一个 bridge,可以理解为一个路由。它会在挂载到它的网口之间进行转发。


同时,Docker 随机分配一个本地未占用的私有网段(在 RFC1918 中定义)中的一个地址给 docker0 接口。比如典型的 172.17.42.1,掩码为 255.255.0.0。此后启动的容器内的网口也会自动分配一个同一网段(172.17.0.0/16)的地址。


当创建一个 Docker 容器的时候,同时会创建了一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAA)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。

模式 简介 使用
Host 容器不会有网卡,IP等信息,而是直接使用宿主机的IP跟端口 –net=host
Bridge 每个容器都会有自己的网卡跟IP信息,容器会连接到docker0虚拟网桥上,通过虚拟网桥跟iptables跟宿主机进行通信 –net=bridge
None 关闭了容器的网络功能 –net=none
Container 容器不会创建网络跟IP,会跟指定的容器公用ip跟端口 –net=conatiner:name/id

6.1.1、为什么docker有网络

容器与容器之间是互相隔离的,如果想通信,第一种方式是公用一个数据卷,第二种方式是网络去进行访问

1.容器之间互联通信

2.外部宿主机可以访问容器数据

6.2、Docker网络相关操作

docker network 网络相关操作

ls 查看所有网桥

rm 删除某一个网桥

create 创建网桥

prune 删除未使用的网桥


docker启动容器模式使用的是网桥


1.查看docker所有网桥

[root@docker ~]# docker network ls

NETWORK ID     NAME      DRIVER    SCOPE

f108dc540f3a   test      bridge    local


2.创建网桥

[root@docker ~]# docker network create test

f108dc540f3ab9d241b0211e2410021b3c6afc6b69e139e6587f817958f5b9d2

[root@docker ~]# docker network ls

NETWORK ID     NAME      DRIVER    SCOPE

f108dc540f3a   test      bridge    local


3.如何使用网桥

--network 指定网桥,不能自动创建网桥

[root@docker ~]# docker run -d -P --name nginx02 --network test nginx:latest


4.删除网桥

[root@docker ~]# docker network rm test

test


5.查看网桥详细信息

[root@docker ~]# docker network inspect test

[

    {

        "Name": "test", 网桥名称

        "Id": "c38d9239253e5470ae2748f82e38d370dde714546de74ea1cd4fbbabd93cf7e9",

        ......

                    "Subnet": "172.25.0.0/16" IP网段/掩码

                    "Gateway": "172.25.0.1" 网关


]


6.host模式

容器不会虚拟的网卡,而是直接使用宿主机的ip跟端口号

[root@docker ~]# docker run -d --network host --name nginx04 -P nginx:latest


7.空模式

[root@docker ~]# docker run -d --network none --name nginx05 -P nginx:latest


8.container模式

不对网络进行任何配置,而是和指定的容器共享ip跟端口

[root@docker ~]# docker run -d -p 88:80 -p 6377:6379 --network test --name redis redis:latest

[root@docker ~]# docker run -d --network container:redis --name nginx nginx:latest

七、数据卷管理

7.1、数据卷特点

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:


数据卷 可以在容器之间共享和重用


对 数据卷 的修改会立马生效


对 数据卷 的更新,不会影响镜像


数据卷 默认会一直存在,即使容器被删除


注意:数据卷 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会复制到数据卷中(仅数据卷为空时会复制)。


7.2、数据卷操作

0.数据卷管理命令

docker volume COMMAND

create      创建数据卷

inspect     查看数据卷详细信息

ls          显示所有数据卷

prune       删除所有未使用的数据卷

rm          删除数据卷


1.创建数据卷

[root@docker ~]# docker volume create web001

web001

[root@docker ~]# docker volume ls | grep web001

local     web001


2.查看数据卷

[root@docker ~]# docker volume inspect web001

[

    {

        "CreatedAt": "2021-06-01T14:18:17+08:00",

        "Driver": "local",

        "Labels": {},

        "Mountpoint": "/var/lib/docker/volumes/web001/_data",

        "Name": "web001",

        "Options": {},

        "Scope": "local"

    }

]


3.挂载数据卷

[root@docker ~]# docker run -d -P -v web001:/usr/share/nginx/html --name nginx10 nginx:latest 

90a87cf3afd67d9565b58cba7ea2814eb650128e9951d8ed30295b0ae353dd37

[root@docker ~]# docker inspect nginx10 | grep volumes

                "Source": "/var/lib/docker/volumes/web001/_data",


4.删除数据卷

[root@docker ~]# docker volume rm web001 

web001

[root@docker ~]# docker volume ls | grep web001



上一条:在Linux中安装Docker

下一条:Anaconda是Python中最好用的数据科学环境管理库