docker
Kubernetes是谷歌的一个开源项目,并且开源之后迅速成为容器编排领域的领头羊。有一种很流行的说法:Kubernetes是保证容器部署和运行的软件体系中很重要的一部分。
走进docker
Docker是一种运行于Linux和Windows上的软件,用于创建、管理和编排容器。
Docker公司位于旧金山,由法裔美籍开发者和企业家Solumon Hykes创立,其标志如图所示。

Docker引擎是用于运行和编排容器的基础设施工具。
Docker鼓励面向服务的架构和微服务架构。
Docker推荐单个容器只运行一个应用程序或进程,这样就形成了一个分布式的应用程序模型,在这种模型下,应用程序或服务都可以表示为一系列内部互联的容器,从而使分布式部署应用程序,扩展或调试应用程序都变得非常简单,同时也提高了程序的内省性。

Docker是一个客户端/服务器(C/S)架构的程序。Docker客户端只需向Docker服务器或守护进程发出请求,服务器或守护进程将完成所有工作并返回结果。Docker守护进程有时也称为Docker引擎。Docker提供了一个命令行工具docker以及一整套RESTful API来与守护进程交互。用户可以在同一台宿主机上运行Docker守护进程和客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守护进程。
容器生态
Docker公司的一个核心哲学通常被称为“含电池,但可拆卸”(Batteries included but removable)。
意思是许多Docker内置的组件都可以替换为第三方的组件,网络技术栈就是一个很好的例子。Docker核心产品内置有网络解决方案。但是网络技术栈是可插拔的,这意味着Docker内置的网络方案可以被替换为第三方的方案。许多人都会这样使用。
开放容器计划
如果不谈及开放容器计划(The Open Container Initiative, OCI)的话,对Docker和容器生态的探讨总是不完整的。图所示为OCI的Logo。

OCI是一个旨在对容器基础架构中的基础组件进行标准化的管理委员会。
Docker公司一家位于旧金山的立志于变更软件行业的科技创业公司。可以说他们是现今容器革命的先行者和推动者。但是现在已经形成了一个由作者和竞争者组成的大型生态。
Docker项目是开源的,其上游源码位于GitHub的moby/moby库。
开放容器计划(OCI)在容器运行时格式和容器镜像格式的标准化方面发挥了重要作用。
docker 技术组件
- 一个原生的Linux容器格式,Docker中称为libcontainer。
- Linxu内核的命名空间(namespace),用于隔离文件系统、进程和网络。
- 文件系统隔离:每个容器都有自己的root文件系统。
- 进程隔离:每个容器都运行在自己的进程环境中。
- 网络隔离:容器间的虚拟网络接口和IP地址都是分开的。
- 资源隔离和分组:使用cgroups(即control group,Linux的内核特性之一)将CPU和内存之类的资源独立分配给每个Docker容器。
- 写时复制:文件系统都是通过写时复制创建的,这就意味着文件系统是分层的、快速的,而且占用的磁盘空间更小。
- 日志:容器产生的STDOUT、STDERR和STDIN这些IO流都会被收集并记入日志,用来进行日志分析和故障排错。
- 交互式shell:用户可以创建一个伪tty终端,将其连接到STDIN,为容器提供一个交互式的shell。
Docker安装
docker --version
docker三个概念
镜像:一个特殊的文件系统
镜像是构建Docker世界的基石。用户基于镜像来运行自己的容器。
镜像也是Docker生命周期中的“构建”部分。镜像是基于联合(Union)文件系统的一种层式的结构,由一系列指令一步一步构建出来。例如:
- 添加一个文件;
- 执行一个命令;
- 打开一个端口。
也可以把镜像当作容器的“源代码”。
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的配置参数(如匿名卷、环境变量、用户等)。
镜像不包含任何动态数据,其内容在构建之后也不会被改变。我们可以使用“docker image ls”来列出本机的镜像。
在设计时,充分利用Union FS的技术,将Docker设计为分层存储的架构。镜像实际是由多层文件系统联合组成的。
镜像构建时会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。
在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。
分层存储的特征还使得镜像的复用、定制变得更为容易,甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容来构建新的镜像。
容器:镜像运行时的实体
Docker可以帮用户构建和部署容器,用户只需要把自己的应用程序或服务打包放进容器即可。我们刚刚提到,容器是基于镜像启动起来的,容器中可以运行一个或多个进程。我们可以认为,镜像是Docker生命周期中的构建或打包阶段,而容器则是启动或执行阶段。
总结起来,Docker容器就是:
- 一个镜像格式;
- 一系列标准的操作;
- 一个执行环境。
Docker借鉴了标准集装箱的概念。标准集装箱将货物运往世界各地,Docker将这个模型运用到自己的设计哲学中,唯一不同的是:集装箱运输货物,而Docker运输软件。
使用Docker,可以快速构建一个应用程序服务器、一个消息总线、一套实用工具、一个持续集成(continuous integration,CI)测试环境或者任意一种应用程序、服务或工具。可以在本地构建一个完整的测试环境,也可以为生产或开发快速复制一套复杂的应用程序栈。
镜像(Image)和容器(Container)的关系就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
我们可以使用命令“docker ps”来查看正在运行的容器列表,如图所示。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间中。前面讲过镜像使用的是分层存储,容器也是如此。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照Docker最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。
所有的文件写入操作,都应该使用数据卷(Volume)或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器可以随意删除、重新运行,数据却不会丢失。
仓库:集中存放镜像文件的地方
镜像构建完成后,可以很容易地在当前宿主上运行,但是如果需要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。
一个Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。所以说,镜像仓库是Docker用来集中存放镜像文件的地方,类似于我们之前常用的代码仓库。
Docker的主要应用场景
简化配置,无须处理复杂的环境依赖关系
容器镜像打包完成后就是一个独立的个体了,丢到符合要求的地方就能直接跑起来,而无须针对各个系统、平台再去独立配置,以及安装各种运行时和环境,也无须处理复杂的环境依赖关系。
搭建轻量、私有的PaaS环境、标准化开发、测试和生产环境
Docker占用资源非常小,一台服务器跑几十、上百个容器都绰绰有余。因此,Docker非常适合用于企业内部搭建轻量、私有的PaaS环境,并且不依赖于任何语言、框架或系统。
简化和标准化代码流水线,助力敏捷开发和DevOps实践
Docker镜像一次构建,即可到处运行,无须处理复杂的环境依赖关系,可以极大地简化整个代码流水线,并且可以标准化整个CI(持续集成)、CD(持续部署)流程,因此可以大大加速软件的开发进程,提高团队的敏捷性,保障产品持续快速交付。
隔离应用
我们需要在一台服务器上运行多个不同的应用,比如运行不同编程语言不同版本的多个应用。如果是部署在虚拟机,那么我们还需要考虑应用以及版本之间的兼容性,有时即使花费大量的精力也无法保障应用环境不起冲突。对于Docker来说,支持起来非常简单,利用其隔离功能即可:同一台机器,我们可以同时运行N个Docker应用,基于不同的运行时和版本(比如.NET Core、Java、Python的应用),托管到不同的Web服务器(Kestrel、Ngnix、Tomcat),而无须担心它们会搞起3Q大战(见图2-7),也往往无须担心开发、测试和生产机器会跑不起来。
整合服务器资源
Docker隔离应用的能力使得Docker可以整合多个服务器,以降低成本。没有多个操作系统的内存占用,并能在多个实例之间共享没有使用的内存,因此Docker可以比虚拟机提供更好的服务器整合解决方案。
现代应用
Docker非常适合于微服务架构、分布式架构和弹性架构,使用Docker会让架构师搭建现代架构时事半功倍!其适应性主要体现在以下几点:
- 应用隔离优势。
- 轻量和快,支持秒级启动、秒级伸缩。
- 低成本优势。
- 环境一致性。
- 一次编译,到处运行。
调试能力
Docker提供了很多工具,不一定只是针对容器,却适用于容器。它们提供了很多功能,包括可以为容器设置检查点、设置版本和查看两个容器之间的差别,以帮助调试Bug。
快速部署
在虚拟机之前,引入新的硬件资源需要消耗几天的时间。虚拟化(Virtualization)技术将这个时间缩短到了分钟级别。Docker为进程创建一个容器,而无须启动一个操作系统,再次将这个过程缩短到了秒级。
Docker除了支持秒级启动之外,部署时镜像的拉取还支持差异化更新,不仅能够减少镜像的拉取时间(节约部署时间),还可以降低更新部署时的流量使用。
混合云应用、跨环境应用、可移植应用
通过容器来交付的应用可以在任何基础设施之上灵活迁移,同时这些基础设施又可以提供不同层次的应用管理方式,当业务在多个服务供应商之中寻求混合云或全云模式时,还可以完美地避免被平台捆绑。因此,Docker在混合云应用、跨环境应用、可移植应用中大有可为。
docker 命令行基础
docker info :查看docker程序是否存在,功能是否正常
docker info
Client:
Debug Mode: false
Server:
Containers: 20
Running: 2
Paused: 0
Stopped: 18
Images: 21
Server Version: 19.03.12
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
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: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 4.19.76-linuxkit
Operating System: Docker Desktop
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 1.944GiB
Name: docker-desktop
ID: CMLP:FPTM:PKDJ:HY5N:JGIK:HOO5:CTDU:2U2G:W5VC:JFWG:BWVY:65A7
Docker Root Dir: /var/lib/docker
Debug Mode: true
File Descriptors: 56
Goroutines: 71
System Time: 2020-08-11T12:49:41.8997101Z
EventsListeners: 3
HTTP Proxy: gateway.docker.internal:3128
HTTPS Proxy: gateway.docker.internal:3129
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
http://hub-mirror.c.163.com/
Live Restore Enabled: false
Product License: Community Engine
docker image :列出所安装的镜像
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
dockerjava latest 454fd6093cab 2 hours ago 579MB
dockerdemo latest 91f1a34d6323 3 hours ago 113MB
centos latest 0d120b6ccaa8 18 hours ago 215MB
php latest 66d7351dcc61 4 days ago 405MB
python 3.8-slim-buster 07ea617545cd 6 days ago 113MB
java 9 1800de06a3eb 3 years ago 579MB
Docker执行docker run命令,并指定了-i和-t两个命令行参数。-i标志保证容器中STDIN是开启的,尽管我们并没有附着到容器中。持久的标准输入是交互式shell的“半边天”,-t标志则是另外“半边天”,它告诉Docker为要创建的容器分配一个伪tty终端。
docker run : 运行镜像
# 运行镜像
➜ ~ docker run -it centos
[root@b497e5fcff8a /]#
[root@b497e5fcff8a /]# hostname
b497e5fcff8a
[root@b497e5fcff8a /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1000
link/tunnel6 :: brd ::
52: eth0@if53: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
镜像安装vim
[root@b497e5fcff8a /]# yum install vim
Failed to set locale, defaulting to C.UTF-8
CentOS-8 - AppStream 966 kB/s | 5.8 MB 00:06
CentOS-8 - Base 1.1 MB/s | 2.2 MB 00:02
CentOS-8 - Extras 9.1 kB/s | 7.3 kB 00:00
Dependencies resolved.
============================================================================================================================================================================================================
Package Architecture Version Repository Size
============================================================================================================================================================================================================
Installing:
vim-enhanced x86_64 2:8.0.1763-13.el8 AppStream 1.4 M
Installing dependencies:
gpm-libs x86_64 1.20.7-15.el8 AppStream 39 k
vim-common x86_64 2:8.0.1763-13.el8 AppStream 6.3 M
vim-filesystem noarch 2:8.0.1763-13.el8 AppStream 48 k
which x86_64 2.21-12.el8 BaseOS 49 k
Transaction Summary
============================================================================================================================================================================================================
Install 5 Packages
Total download size: 7.8 M
Installed size: 31 M
Is this ok [y/N]: y
Downloading Packages:
CentOS-8 - Base 195% [====================================================================================================================(1/5): gpm-libs-1.20.7-15.el8.x86_64.rpm 132 kB/s | 39 kB 00:00
(2/5): vim-filesystem-8.0.1763-13.el8.noarch.rpm 178 kB/s | 48 kB 00:00
(3/5): which-2.21-12.el8.x86_64.rpm 356 kB/s | 49 kB 00:00
(4/5): vim-enhanced-8.0.1763-13.el8.x86_64.rpm 816 kB/s | 1.4 MB 00:01
(5/5): vim-common-8.0.1763-13.el8.x86_64.rpm 798 kB/s | 6.3 MB 00:08
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total 758 kB/s | 7.8 MB 00:10
warning: /var/cache/dnf/AppStream-02e86d1c976ab532/packages/gpm-libs-1.20.7-15.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS-8 - AppStream 644 kB/s | 1.6 kB 00:00
Importing GPG key 0x8483C65D:
Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>"
Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Is this ok [y/N]: y
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-12.el8.x86_64 1/5
Installing : vim-filesystem-2:8.0.1763-13.el8.noarch 2/5
Installing : vim-common-2:8.0.1763-13.el8.x86_64 3/5
Installing : gpm-libs-1.20.7-15.el8.x86_64 4/5
Running scriptlet: gpm-libs-1.20.7-15.el8.x86_64 4/5
Installing : vim-enhanced-2:8.0.1763-13.el8.x86_64 5/5
Running scriptlet: vim-enhanced-2:8.0.1763-13.el8.x86_64 5/5
Running scriptlet: vim-common-2:8.0.1763-13.el8.x86_64 5/5
Verifying : gpm-libs-1.20.7-15.el8.x86_64 1/5
Verifying : vim-common-2:8.0.1763-13.el8.x86_64 2/5
Verifying : vim-enhanced-2:8.0.1763-13.el8.x86_64 3/5
Verifying : vim-filesystem-2:8.0.1763-13.el8.noarch 4/5
Verifying : which-2.21-12.el8.x86_64 5/5
Installed:
gpm-libs-1.20.7-15.el8.x86_64 vim-common-2:8.0.1763-13.el8.x86_64 vim-enhanced-2:8.0.1763-13.el8.x86_64 vim-filesystem-2:8.0.1763-13.el8.noarch which-2.21-12.el8.x86_64
Complete!
[root@b497e5fcff8a /]#
docker inspect:查看镜像信息
➜ ~ docker inspect 454fd6093cab
[
{
"Id": "sha256:454fd6093cab999ef793e726439489e8f3a1ca9e25a49d73c7a36a21db244821",
"RepoTags": [
"dockerjava:latest"
],
"RepoDigests": [],
"Parent": "sha256:b9f2b6094e4770e4520c84284d1a25023ff3614f593c33e61befe8eed07e2127",
"Comment": "",
"Created": "2020-08-11T10:49:55.694758961Z",
"Container": "00d424026d9e1852fd4002efd2628fb0d3a0636932793cc44a3454882b710a6f",
"ContainerConfig": {
"Hostname": "601410a29ab0",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-9-openjdk-amd64/bin",
"LANG=C.UTF-8",
"JAVA_HOME=/usr/lib/jvm/java-9-openjdk-amd64",
"JAVA_VERSION=9~b149",
"JAVA_DEBIAN_VERSION=9~b149-1",
"JRE_HOME=/usr/lib/jvm/java-9-openjdk-amd64/jre",
"CLASSPATH=.:/usr/lib/jvm/java-9-openjdk-amd64/lib:/usr/lib/jvm/java-9-openjdk-amd64/jre/lib"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"ENTRYPOINT [\"/usr/lib/jvm/java-9-openjdk-amd64/bin/java\" \"hello\"]"
],
"Image": "sha256:b9f2b6094e4770e4520c84284d1a25023ff3614f593c33e61befe8eed07e2127",
"Volumes": null,
"WorkingDir": "/app",
"Entrypoint": [
"/usr/lib/jvm/java-9-openjdk-amd64/bin/java",
"hello"
],
"OnBuild": [],
"Labels": {}
},
"DockerVersion": "19.03.12",
"Author": "",
"Config": {
"Hostname": "601410a29ab0",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-9-openjdk-amd64/bin",
"LANG=C.UTF-8",
"JAVA_HOME=/usr/lib/jvm/java-9-openjdk-amd64",
"JAVA_VERSION=9~b149",
"JAVA_DEBIAN_VERSION=9~b149-1",
"JRE_HOME=/usr/lib/jvm/java-9-openjdk-amd64/jre",
"CLASSPATH=.:/usr/lib/jvm/java-9-openjdk-amd64/lib:/usr/lib/jvm/java-9-openjdk-amd64/jre/lib"
],
"Cmd": null,
"Image": "sha256:b9f2b6094e4770e4520c84284d1a25023ff3614f593c33e61befe8eed07e2127",
"Volumes": null,
"WorkingDir": "/app",
"Entrypoint": [
"/usr/lib/jvm/java-9-openjdk-amd64/bin/java",
"hello"
],
"OnBuild": [],
"Labels": {}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 579084338,
"VirtualSize": 579084338,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/8a96f380484ac9cc2b1c2700f8ec0f3906d16b450219860f6f56bc1071a2ce69/diff:/var/lib/docker/overlay2/686078b44370c97cfba2cdb9a4e0356aa740ca083059890ab964505b13412091/diff:/var/lib/docker/overlay2/577da6749fafc6f58c9a4eca90ca3acf56236c4ed149cd6f286b7b9d92c5856c/diff:/var/lib/docker/overlay2/5277fb3eedd60fe4f2e91dd1257595e46916b34e7836a4dcfe8590d219f9bdb5/diff:/var/lib/docker/overlay2/a18752292f921d6e8688d51c8786c969c863096f29d0332e1c9ee2f827af9c1f/diff:/var/lib/docker/overlay2/dc76911e625ba10d537e56b6cb491f7dc64b9ca57b65ebbfb6084ac5a52700f0/diff:/var/lib/docker/overlay2/ea40224206bf351b208dad9066281b93e52037dea5cc4a1eabb26b9bc74a4f77/diff:/var/lib/docker/overlay2/3373ddcadefb05c167e3722c7adbcdc14dfceee76c7561265aec9baea278ce60/diff:/var/lib/docker/overlay2/216df96307e9e1df508ede7935e0b68896db1ced3cfc46499da9eefa4f2ab30e/diff",
"MergedDir": "/var/lib/docker/overlay2/273081ce63d00fe9a8e56221b0b07ac50b6802124005bca1ad2a293adc3746cf/merged",
"UpperDir": "/var/lib/docker/overlay2/273081ce63d00fe9a8e56221b0b07ac50b6802124005bca1ad2a293adc3746cf/diff",
"WorkDir": "/var/lib/docker/overlay2/273081ce63d00fe9a8e56221b0b07ac50b6802124005bca1ad2a293adc3746cf/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:c301ef700312b3eed0c7071f18aabcc8cedda550c417cf0b26886c75ed607641",
"sha256:88d64f1e569a24ddd8e824877191dd416be77ab12403d35979d6e1b362245780",
"sha256:28bd9770e3782153590c075705fc2d3a6802e2cf624f1deeb22d5d45e41a66ac",
"sha256:83353724c30d0a8fe294a68d5264683020658bc60df518afe1f1701a814c8c6e",
"sha256:b74ee38843561a6157f4d0987734e70812e5b189793bf82a868bc677dbea3304",
"sha256:c7aa52d2581781a6864f7f026729707dc1183af62d7ee7156eef7de3ef882c63",
"sha256:7d9c46e3a13827196810bf7039c9334ce0f857c706185f58b7f0528caee08f19",
"sha256:cded4ca5c962fefcab6d669b14db3b3beb9db2904c82f874c6bd1cd7470065e1",
"sha256:6f92aa1ebce00e666f65f4ab01e434524115f8e62d86b6e60b853ba0e3fc2d14",
"sha256:10cff458764d8b4e0bcaa9bf1f0acb8059540714201b48670beb458c9d19e411"
]
},
"Metadata": {
"LastTagTime": "2020-08-11T10:49:55.716974587Z"
}
}
]
docker name : 容器命名
docker run --name centos_container -i -t centos
docker ps : 显示正在运行的镜像
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
277830e2a2a5 centos "/bin/bash" 11 minutes ago Up 11 minutes nifty_mahavira
993d02fc5b05 centos "/bin/bash" 16 minutes ago Up 15 minutes centos_container
login
docker login --username kingshine
Password:
Login Succeeded
拉取镜像
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
在上述语法中,如果没有指定tag,那么默认会使用“:latest”作为标签
docker pull redis
列出本地镜像
要想列出本地已经下载的镜像,可以使用:
docker image ls [OPTIONS] [REPOSITORY[:TAG]]
docker image ls redis
docker image ls r*
docker image ls r:2
筛选
我们可以使用筛选参数来进行筛选,比如-f或--filter,格式为“key=value”,支持多个筛选器。目前支持的方式有:
- dangling,是否悬空镜像(布尔类型)。
- label,标签(label=<key>或label=<key>=<value>)。
- before(<image-name>[:<tag>],<image id>orimage@digest),过滤在给定id或引用之前创建的镜像。
- since(<image-name>[:<tag>],<image id>orimage@digest),过滤自给定id或引用以来创建的镜像。
- reference,过滤指定模式匹配的镜像。
筛选悬空镜像
docker images --filter "dangling=true"
Label筛选
docker images --filter label=MAINTAINER=xinlai@xin-lai.com
按指定镜像的前后时间来筛选。
在指定镜像之前
docker images -f "before=redis:2.6"
在指定镜像之后
docker image -f "since=redis:2.6"
reference筛选
docker images -f=reference='r:2.8*'
运行镜像
无论我们本地是否存在相关镜像,都可以使用docker run命令来运行。如果本地镜像不存在,Docker会自动拉取相关镜像并运行。语法如下:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS 特别多,请自行查看。
简单运行
Run命令的配置项很多,但是通常使用起来很简单,例如“docker run redis”
列出容器
刚才我们通过“docker run”将镜像运行起来了,也就是基于镜像新建一个容器并进行启动。那么如何查看容器列表呢?语法如下:
docker ps [OPTIONS]
查看正在运行的容器
查看刚刚运行的容器,仅需执行以下命令:
docker ps
显示正在运行和已停止的容器
docker ps命令默认只显示正在运行的容器。要查看所有容器,请使用-a(或--all)标志
查看镜像详情
语法:docker image inspect IMAGE [IMAGE...]
docker image inspect dingtalk.net
删除镜像
删除镜像可使用以下命令:
docker image rm [OPTIONS] IMAGE [IMAGE...]
docker image rm golang
批量删除
docker rmi可以删除一个或多个镜像。结合上面的筛选,我们也可以通过以下命令来清理悬空镜像:
docker rmi $(docker images -f "dangling=true" -q)
清理未使用的镜像
在很多情况下,使用Docker一段时间后,本地就会存在大量无用的镜像,占用大量的空间,比如悬空镜像。这时我们可以运行以下命令来执行批量清理:
docker system prune [OPTIONS]
配置比较简单,接下来我们可以直接运行以下命令:
docker system prune
运行后需要确认,如图4-31所示。执行上述命令会清理以下内容:
- 已停止的容器(container)。
- 未被任何容器所使用的卷(volume)。
- 未被任何容器所关联的网络(network)。
- 所有悬空镜像(image)。
磁盘占用分析
有时清理了无用镜像还是发现磁盘空间不够,那么如何查看相关磁盘空间的占用情况呢?可以通过以下命令完成:
docker system df [OPTIONS]
docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 215.1MB 0B (0%)
Containers 1 1 5B 0B (0%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
但是我们还需要知道具体是哪个镜像、哪个数据卷占用了空间,这时可以通过-v参数来实现:
docker system df -v
docker system df -v
Images space usage:
REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS
centos latest 0d120b6ccaa8 14 hours ago 215.1MB 0B 215.1MB 1
Containers space usage:
CONTAINER ID IMAGE COMMAND LOCAL VOLUMES SIZE CREATED STATUS NAMES
f1df9b984d76 centos "/bin/bash" 0 5B 48 minutes ago Up 48 minutes flamboyant_benz
Local Volumes space usage:
VOLUME NAME LINKS SIZE
Build cache usage: 0B
CACHE ID CACHE TYPE SIZE CREATED LAST USED USAGE SHARED
删除容器
我们可以使用以下语法删除一个或多个容器:
docker rm [OPTIONS] CONTAINER [CONTAINER...]
停止容器再删除
刚才我们启动了容器“aspnetcore_sample”,这里可以直接使用以下命令进行删除:
docker rm aspnetcore_sample
//执行时提示无法删除正在运行的容器。我们需要先停止容器再删除:
docker stop aspnetcore_sample
docker rm aspnetcore_sample
强制删除正在运行的容器
回到刚才的场景,除了停止容器再删除之外,我们也可以直接强制删除:
docker rm aspnetcore_sample --force
删除所有已停止的容器
有没有办法批量删除所有已停止的容器呢?自然是有的,具体如下:
docker rm (docker ps -a -q) --force
Docker持续开发工作流
基于Docker容器的内部循环开发工作流

(1)开发。根据需求开发应用程序,和传统开发没有什么变化,不限编程语言。
(2)编写Dockerfile。Dockerfile是由一系列命令和参数构成的脚本,用来构建镜像。
(3)创建自定义镜像。基于“docker build”命令构建自定义镜像,在第4章已经讲过,接下来应用于实践。
(4)定义docker-compose。Docker Compose是一个用于定义和运行多个Docker应用程序的工具,非常适合进行开发和测试,尤其适用于微服务架构。
(5)启动Docker应用。可以用第4章学过的“docker run”命令来启动Docker应用,也可以基于“docker-compose up”(下面会进行介绍)。
(6)测试。测试人员基于容器环境进行测试,无须开发人员介入,随时部署或摧毁。
(7)部署或继续开发。基于容器实现持续交付和部署。
开发
一般情况下,我们搭建好框架代码之后就需要针对需求进行开发,以满足业务为目的,也就是这个开发过程并没有什么改变,也没什么变化。比如开发一个CRM(客户关系管理系统),之前是什么样的开发方式、开发工具、技术体系、软件架构,那么现在也一样。二者的主要区别在于,开发Docker应用程序时,是在本地环境中的Docker容器(可以是Linux容器或Windows容器)中部署和测试。
编写Dockerfile
过去,如果要开始编写.NET Core、Java、Python、NodeJs、Go等应用程序,那么首要任务就是在计算机上安装相关语言运行时。但是,这需要我们的计算机环境和应用程序兼容,并且还需要和生产环境相匹配。使用Docker,我们可以将可移植的.NET Core、Java、Python、NodeJs、Go运行时作为镜像获取,无须安装。然后,我们可以基于运行时的基础镜像来构建应用程序镜像,确保应用程序和其依赖项、运行时一起运行。
镜像对应的文件存储路径
/Users/kingshine/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
docker java 如何退出
jshell> /exit
| Goodbye
网友评论