写点什么

资深专家都知道的 Docker 常用命令

  • 2019-01-07
  • 本文字数:9198 字

    阅读完需:约 30 分钟

资深专家都知道的Docker常用命令

开发人员一直在努力提高 Docker 的使用率和性能,命令也在不停变化。Docker 命令经常被弃用,或被替换为更新且更有效的命令,本文总结了近年来资深专家最常用的命令列表并给出部分使用方法。


目前,Docker 共有 13 个管理命令和 41 个通用命令,以下是常用 Docker 命令列表:


  • docker help—检查最新 Docker 可用命令;

  • docker attach—将本地输入、输出、错误流附加到正在运行的容器;

  • docker commit—从当前更改的容器状态创建新镜像;

  • docker exec—在活动或正在运行的容器中运行命令;

  • docker history—显示镜像历史记录;

  • docker info—显示系统范围信息;

  • docker inspect—查找有关 docker 容器和镜像的系统级信息;

  • docker login—登录到本地注册表或 Docker Hub;

  • docker pull—从本地注册表或 Docker Hub 中提取镜像或存储库;

  • docker ps—列出容器的各种属性;

  • docker restart—停止并启动容器;

  • docker rm—移除容器;

  • docker rmi—删除镜像;

  • docker run—在隔离容器中运行命令;

  • docker search—在 Docker Hub 中搜索镜像;

  • docker start—启动已停止的容器;

  • docker stop—停止运行容器;

  • docker version—提供 docker 版本信息。

查找 Docker 版本和系统信息

无论是在本地还是云端,我们都需要检查 Docker 版本和系统信息,可以使用以下命令找到 Docker 版本:


$ docker versionClient:Version: 18.03.0-ceAPI version: 1.37Go version: go1.9.4Git commit: 0520e24Built: Wed Mar 21 23:06:22 2018OS/Arch: darwin/amd64Experimental: falseOrchestrator: swarmServer:Engine:Version: 18.03.0-ceAPI version: 1.37 (minimum version 1.12)Go version: go1.9.4Git commit: 0520e24Built: Wed Mar 21 23:14:32 2018OS/Arch: linux/amd64Experimental: true
复制代码


另一个重要命令是 docker info:


$ docker infoContainers: 0Running: 0Paused: 0Stopped: 0Images: 0Server Version: 18.03.0-ceStorage Driver: overlay2Backing Filesystem: extfsSupports d_type: trueNative Overlay Diff: trueLogging Driver: json-fileCgroup Driver: cgroupfsPlugins:Volume: localNetwork: bridge host ipvlan macvlan null overlayLog: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
复制代码


该命令将显示部分设备信息,比如服务器版本、存储驱动程序、内核版本、操作系统、总内存等。当尝试为当前 Docker 安装启动新资源或尝试找出系统级资源分配问题时,这些信息非常有用,这也是检查运行、停止容器数量及下载镜像数量的快速方法。

搜索下载 Docker 镜像

可以使用 docker search 命令在 Docker Hub 搜索已有镜像:


$ docker search ubuntuNAME DESCRIPTION STARS OFFICIAL AUTOMATEDubuntu Ubuntu is a Debian-based Linux operating sys… 7861 [OK]dorowu/ubuntu-desktop-lxde-vnc Ubuntu with openssh-server and NoVNC 190 [OK]rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… 156 [OK]ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with ansible 93 [OK]ubuntu-upstart Upstart is an event-based replacement for th… 87 [OK]neurodebian NeuroDebian provides neuroscience research s… 50 [OK]
复制代码


以上对 ubuntu 的搜索显示可用镜像、描述和官方状态等信息。如果要下载 ubuntu 镜像,可以使用 docker pull 命令:


$ docker pull ubuntuUsing default tag: latestlatest: Pulling from library/ubuntu6b98dfc16071: Pull complete4001a1209541: Pull complete6319fc68c576: Pull completeb24603670dc3: Pull complete97f170c87c6f: Pull completeDigest: sha256:5f4bdc3467537cbbe563e80db2c3ec95d548a9145d64453b06939c4592d67b6dStatus: Downloaded newer image for ubuntu:latest$
复制代码

Docker 镜像

使用 docker info 命令查找拥有镜像数量:


$ docker infoContainers: 0Running: 0Paused: 0Stopped: 0Images: 1
复制代码


docker images 命令可详细列出拥有镜像:


$ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED             SIZEubuntu              latest              113a43faa138        2 weeks ago         81.2MB
复制代码


假设下载 NGINX 镜像,可以运行 docker pull 命令:


$ docker pull nginx
复制代码


如果检查 Docker 镜像,会看到如下内容:


$ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED             SIZEubuntu              latest              113a43faa138        2 weeks ago         81.2MBnginx               latest              cd5239a0906a        2 weeks ago         109MB
复制代码


如果寻找 Ubuntu 16.04 版本,可使用 16.04 标签下载特定版本:


$ docker pull ubuntu:16.04
复制代码


随后,将出现两个 Ubuntu 映像版本:


$ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED             SIZEubuntu              16.04               5e8b97a2a082        2 weeks ago         114MBubuntu              latest              113a43faa138        2 weeks ago         81.2MBnginx               latest              cd5239a0906a        2 weeks ago         109MB
复制代码


注意:无需注册 Docker Hub 即可提取镜像。如果想将镜像推送到 Docker Hub,需要注册然后使用 docker login 命令登录:


$ docker login --username=yourhubusername --email=youremail@company.com
复制代码

运行镜像的 Docker 容器

假设想在 docker 上运行 NGINX 服务器,可运行以下命令:


$ docker run -p 8080:80 nginx
复制代码


如果已用 run 命令从 Docker Hub 提取 nginx 映像创建 NGINX 容器。 -p 8080:80 会告诉 Docker 将 localhost 端口 8080 映射到 Docker 容器端口 80,应该能够从 http:// localhost:8080 访问 NGINX 服务器。


NGINX 容器已附加到命令行。如果退出命令行,容器将会停止,可使用 detach(’-  d)启动 NGINX 容器,这样即使退出命令行也可继续运行。


$ docker run -p 8080:80 -d nginx
复制代码


以上命令将以分离模式启动容器并返回命令行。

使用 docker ps 命令列出 Docker 容器

docker ps 命令允许查找正在运行的所有容器:


$ docker psCONTAINER ID         IMAGE         COMMAND         CREATED           STATUS          PORTS             NAMES6162daed25da         nginx  "nginx -g 'daemon of…" 7 minutes ago   Up 7 minutes  0.0.0.0:8080->80/tcp  hardcore_torvalds
复制代码


如上显示容器的各种属性,可以看到是从 nginx 镜像创建并显示端口转发信息。CONTAINER ID 和 NAMES 属性需要特别提及,可以使用上述两大属性唯一标识容器。二者都可自动生成,但也可在容器创建过程中为容器命名。


创建一个名为 my_nginx 的 NGINX 容器:


$ docker run --name my_nginx -p 8888:80 -d nginx
复制代码


再次列出所有 Docker 容器:


$ docker psCONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                  NAMESe7b19b6ad778        nginx               "nginx -g 'daemon of…"   About a minute ago   Up About a minute   0.0.0.0:8888->80/tcp   my_nginx6162daed25da        nginx               "nginx -g 'daemon of…"   15 minutes ago       Up 16 minutes       0.0.0.0:8080->80/tcp   hardcore_torvalds
复制代码


请注意,新容器的名称为“my_nginx”。 处理大量容器时,可以使用命名约定,这可以更好得组织容器。


docker ps 命令仅显示正在运行的容器。如果对上述情况使用 docker info 命令:


$ docker infoContainers: 2Running: 2Paused: 0Stopped: 0Images: 3
复制代码


可以看到有两个容器正在运行,如果一个暂停或已停止,则不会仅使用 docker ps 命令查看这些容器,必须使用 all( -  a)选项:


$ docker ps -a
复制代码

启动,停止,重启和杀死容器

假设要停止’my_nginx’容器,可使用 CONTAINER ID 或 NAME。


$ docker stop my_nginxmy_nginx
复制代码


列出 Docker 容器:


$ docker psCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES6162daed25da        nginx               "nginx -g 'daemon of…"   27 minutes ago      Up 27 minutes       0.0.0.0:8080->80/tcp   hardcore_torvalds$ docker ps -aCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                          PORTS                  NAMESe7b19b6ad778        nginx               "nginx -g 'daemon of…"   12 minutes ago      Exited (0) About a minute ago                          my_nginx6162daed25da        nginx               "nginx -g 'daemon of…"   27 minutes ago      Up 27 minutes                   0.0.0.0:8080->80/tcp   hardcore_torvalds
复制代码


如果在没有-a 选项的情况下运行 docker ps,只显示正在运行的容器。在第二种情况下,可以看到’my_nginx’容器处于退出状态。


让我们 docker start  容器:


$ docker start my_nginxmy_nginx
复制代码


检查 Docker 容器列表:


$ docker psCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMESe7b19b6ad778        nginx               "nginx -g 'daemon of…"   16 minutes ago      Up 29 seconds       0.0.0.0:8888->80/tcp   my_nginx6162daed25da        nginx               "nginx -g 'daemon of…"   30 minutes ago      Up 30 minutes       0.0.0.0:8080->80/tcp   hardcore_torvalds
复制代码


可以看到 STATUS 显示容器’my_nginx’再次被启动。


如果由于某些问题而需重启容器,则可使用 restart 命令,这比单独停止和启动容器速度更快:


$ docker restart my_nginx
复制代码


可以像进程一样终止 docker 容器,比如终止 my_nginx 容器:


$ docker kill my_nginx
复制代码


再次列出 Docker 容器:


$ docker ps -aCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS                  NAMESe7b19b6ad778        nginx               "nginx -g 'daemon of…"   22 minutes ago      Exited (137) 7 seconds ago                          my_nginx6162daed25da        nginx               "nginx -g 'daemon of…"   36 minutes ago      Up 36 minutes                0.0.0.0:8080->80/tcp   hardcore_torvalds
复制代码


容器 my_nginx 未运行。此外,可在信息中看到一个正在运行的容器和一个已停止容器:


$ docker infoContainers: 2Running: 1Paused: 0Stopped: 1Images: 3
复制代码

Docker Exec Bash 和 Docker SSH

如果需要与 shell 进行交互以创建服务或解决问题,可以使用 docker exec 命令创建交互式 shell。比如,用 bash shell 从 ubuntu 映像启动一个容器:


$ docker run --name my_ubuntu -it ubuntu:latest bashroot@a19c770b8621:/#
复制代码


root @haracle#表示位于 Docker 容器的 bash shell 中,可以运行 shell 命令:


root@a19c770b8621:/# lsbin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr varroot@a19c770b8621:/# pwd/
复制代码


列出 Docker 容器:


$ docker psCONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                  NAMESa19c770b8621        ubuntu:latest       "bash"                   About a minute ago   Up About a minute                          my_ubuntu6162daed25da        nginx               "nginx -g 'daemon of…"   About an hour ago    Up About an hour    0.0.0.0:8080->80/tcp   hardcore_torvalds
复制代码


如上,my_ubuntu 正在运行。假设想将 Docker ssh 放入’my_ubuntu’容器中,可以使用 docker exec bash:


$ docker exec -it my_ubuntu bashroot@a19c770b8621:/#
复制代码


使用 docker exec 向容器发出命令。例如,可以直接用命令提示符在 my_ubuntu 容器上运行 ls 命令:


$ docker exec -it my_ubuntu lsbin dev home lib64 mnt proc run srv tmp varboot etc lib media opt root sbin sys usr
复制代码

以分离模式启动容器并使用 docker attach

以上示例用附加模式启动 ubuntu 容器,我们也可在分离模式下启动:


$ docker run -it -d --name my_ubuntu_2 ubuntu:latest bash75b28b7208359137b3e1dc2843387918e28b4c6c4860ef0cdeac79c205f5cbc4
复制代码


验证容器是否正在运行:


$ docker psCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES75b28b720835        ubuntu:latest       "bash"                   3 minutes ago       Up 3 minutes                               my_ubuntu_2a19c770b8621        ubuntu:latest       "bash"                   15 minutes ago      Up 15 minutes                              my_ubuntu6162daed25da        nginx               "nginx -g 'daemon of…"   2 hours ago         Up 2 hours          0.0.0.0:8080->80/tcp   hardcore_torvalds
复制代码


使用 docker attach 命令获取 docker exec bash-like 效果:


$ docker attach my_ubuntu_2root@75b28b720835:/#
复制代码

检查 Docker 镜像历史

Docker 社区镜像是分层创建的,可使用 Docker history 命令查看镜像创建方式。先看看有哪些镜像:


$ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED             SIZEubuntu              16.04               5e8b97a2a082        2 weeks ago         114MBubuntu              latest              113a43faa138        2 weeks ago         81.2MBnginx               latest              cd5239a0906a        2 weeks ago         109MB
复制代码


查看 nginx 镜像历史:


$ docker history nginxIMAGE               CREATED             CREATED BY                                      SIZE                COMMENTcd5239a0906a        2 weeks ago         /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B                  <missing>           2 weeks ago         /bin/sh -c #(nop)  STOPSIGNAL [SIGTERM]         0B                  <missing>           2 weeks ago         /bin/sh -c #(nop)  EXPOSE 80/tcp                0B                  <missing>           2 weeks ago         /bin/sh -c ln -sf /dev/stdout /var/log/nginx…   22B                 <missing>           2 weeks ago         /bin/sh -c set -x  && apt-get update  && apt…   53.7MB              <missing>           2 weeks ago         /bin/sh -c #(nop)  ENV NJS_VERSION=1.15.0.0.…   0B                  <missing>           2 weeks ago         /bin/sh -c #(nop)  ENV NGINX_VERSION=1.15.0-…   0B                  <missing>           7 weeks ago         /bin/sh -c #(nop)  LABEL maintainer=NGINX Do…   0B                  <missing>           8 weeks ago         /bin/sh -c #(nop)  CMD ["bash"]                 0B                  <missing>           8 weeks ago         /bin/sh -c #(nop) ADD file:ec5be7eec56a74975…   55.3MB
复制代码


使用镜像历史命令查找最近更改,如果在新版本镜像中发现问题,则此命令可帮助找到原因,也可用以下命令:


$ docker image history nginx
复制代码

Docker 检查容器

可以使用 docker inspect 命令查找有关系统的信息,运行 docker ps 命令列出 Docker 容器:


$ docker psCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES6162daed25da        nginx               "nginx -g 'daemon of…"   2 hours ago         Up 2 hours          0.0.0.0:8080->80/tcp   hardcore_torvalds
复制代码


使用 CONTAINER ID 检查容器(也可使用容器名称):


$ docker inspect 6162daed25da[{"Id": "6162daed25da50b98afca5f7ed8caca2289bf309b2547d87ae8674b899d604a4","Created": "2018-06-25T05:46:37.902211302Z","Path": "nginx","Args": ["DriverOpts": null}}}}]
复制代码


该命令将以 JSON 格式提供大量信息,以下是查找容器 IP 地址的技巧:


$ docker inspect 6162daed25da | grep "IPAddress"            "SecondaryIPAddresses": null,            "IPAddress": "172.17.0.2",                    "IPAddress": "172.17.0.2",
复制代码

使用 docker cp 将文件从本地复制到容器

再次列出 Docker 容器:


$ docker psCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES6162daed25da        nginx               "nginx -g 'daemon of…"   3 hours ago         Up 3 hours          0.0.0.0:8080->80/tcp   hardcore_torvalds
复制代码


NGINX 容器在端口 8080 上运行。因此,如果转到 http:// localhost:8080,将看到以下内容:


"Welcome to nginx!"
复制代码


如果看到此页面,则 nginx Web 服务器已成功安装并正常运行,需要进一步配置。


首先,在本地目录中创建 index.html:


<html><Header><title>My Website</title></header><body>Hello world</body></html>
复制代码


使用带有 ls 的 docker exec 命令检查 NGINX 容器中具有 index.html 的文件夹:


$ docker exec -it hardcore_torvalds ls /usr/share/nginx/html50x.html index.html
复制代码


使用创建的本地文件覆盖容器 index.html 文件:


$ docker cp index.html hardcore_torvalds:usr/share/nginx/html/
复制代码


如果再次检查http://localhost:8080,应该可以看到问候语“Hello world”。


可使用 docker cp 命令在本地计算机和创建容器间移动文件,此方法可用于覆盖配置文件。

创建 Docker 镜像

如果想复制更多“Hello World”容器,必须将当前容器保存为镜像。


首先,停止容器:


$ docker stop hardcore_torvalds
复制代码


列出所有 Docker 容器:


$ docker ps -aCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS               NAMES75b28b720835        ubuntu:latest       "bash"                   About an hour ago   Exited (0) About an hour ago                       my_ubuntu_2a19c770b8621        ubuntu:latest       "bash"                   2 hours ago         Exited (0) About an hour ago                       my_ubuntu6162daed25da        nginx               "nginx -g 'daemon of…"   3 hours ago         Exited (0) 27 seconds ago                          hardcore_torvalds
复制代码


从 STATUS 中,可以看到 NGINX’corecore_torvalds’容器已停止。使用 docker commit 命令创建新镜像:


$ docker commit 6162daed25da nginx_hello_world_templatesha256:117d060587a316035ed5a776e613d9cfbeee9fbfe202c6edc9203820c7da987b
复制代码


如果现在检查,将看到新镜像:


$ docker imagesREPOSITORY                   TAG                 IMAGE ID            CREATED             SIZEnginx_hello_world_template   latest              117d060587a3        40 seconds ago      109MBubuntu                       16.04               5e8b97a2a082        2 weeks ago         114MBubuntu                       latest              113a43faa138        2 weeks ago         81.2MBnginx                        latest              cd5239a0906a        2 weeks ago         109MB
复制代码


可以使用此镜像并启动新 Docker 容器,新创建容器将具有“Hello world”页面,而不是“Welcome NGINX”页面。示例如下:


$ docker run -it -d -p 8886:80 nginx_hello_world_template4e042d76c39125471951626ba42cd609a65c73f041943298f74f4fc43dc5596a$
复制代码

删除 Docker 容器和镜像

Docker 容器和镜像会占用硬盘空间,因此最好定期清理。首先停止所有容器,然后列出所有容器,使用以下 Docker 命令执行操作:


$ docker ps -aCONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS                         PORTS               NAMES4e042d76c391        nginx_hello_world_template   "nginx -g 'daemon of…"   2 minutes ago       Exited (0) 8 seconds ago                           boring_keldysh75b28b720835        ubuntu:latest                "bash"                   2 hours ago         Exited (0) About an hour ago                       my_ubuntu_2a19c770b8621        ubuntu:latest                "bash"                   2 hours ago         Exited (0) About an hour ago                       my_ubuntu6162daed25da        nginx                        "nginx -g 'daemon of…"   3 hours ago         Exited (0) 11 minutes ago                          hardcore_torvalds
复制代码


如上,有 4 个处于停止状态的容器,可使用 docker rm 命令删除容器:


$ docker rm 4e042d76c391 75b28b720835 a19c770b8621 6162daed25da4e042d76c39175b28b720835a19c770b86216162daed25da
复制代码


可使用 NAMES 代替 CONTAINER ID,容器列表现在应该是干净的:


$ docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
复制代码


列出 Docker 镜像:


$ docker imagesREPOSITORY                   TAG                 IMAGE ID            CREATED             SIZEnginx_hello_world_template   latest              117d060587a3        11 minutes ago      109MBubuntu                       16.04               5e8b97a2a082        2 weeks ago         114MBubuntu                       latest              113a43faa138        2 weeks ago         81.2MBnginx                        latest              cd5239a0906a        2 weeks ago         109MB
复制代码


可使用 docker rmi 命令和 IMAGE ID 删除 docker 镜像:


$ docker rmi 117d060587a3 5e8b97a2a082 113a43faa138 cd5239a0906a
复制代码


最后,Docker 镜像列表应该是干净的:


$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE
复制代码


原文链接:https://dzone.com/articles/top-docker-commands-itsyndicate


2019-01-07 08:2018387
用户头像
赵钰莹 极客邦科技 总编辑

发布了 884 篇内容, 共 653.7 次阅读, 收获喜欢 2681 次。

关注

评论 1 条评论

发布
用户头像
真是吹牛逼不打草稿标题党,什么叫顶级 docker命令?
看这些还不如去看文档呢
2019-01-07 12:03
回复
没有更多了
发现更多内容

架构师训练营第 1 期 -- 第六周作业

发酵的死神

极客大学架构师训练营

Java9新特性-上篇

hepingfly

Java Java新特性

TarsCpp 组件之 MySQL 操作

TARS基金会

c++ MySQL 数据库 微服务 TARS

甲方日常42

句子

工作 随笔杂谈 日常

Scrapy 源码剖析(二)Scrapy是如何运行起来的?

Kaito

Python 爬虫 Scrapy 源码剖析

科大讯飞翻译系统变身“随身翻译官” 助力粤港澳大湾区一体化建设

Talk A.I.

央行数字货币亮相 吹皱一池春水

CECBC

数字货币 银行

架构师训练营第二周总结

lakers

极客大学架构师训练营

架构师训练营第二周作业

lakers

极客大学架构师训练营

架构师训练营第六周总结

邓昀垚

极客大学架构师训练营

如何搭建一个爬虫代理服务?

Kaito

爬虫 代理

如何构建一个通用的垂直爬虫平台?

Kaito

Python 爬虫 代理

Scrapy 源码剖析(三)Scrapy有哪些核心组件?

Kaito

Python 爬虫 Scrapy 源码剖析

目标检测学习-比赛路线

Dreamer

2020年9月公有云性能评测:UCloud、腾讯云屈居二三名,冠军竟然是它?

博睿数据

云计算 公有云 评测 排行榜

TarsCpp 组件 之 智能指针详解

TARS基金会

c++ 微服务 智能指针 TARS

元模型驱动(三):构建我们自己的元模型-KAYA

KaYa

DDD Kaya MDA MDD 元建模

嵌入式面试之《Linux系统编程100问》

哒宰的自我修养

Linux 线程 网络编程 进程

「架构师训练营第 1 期」第六周作业

张国荣

积极参与数字货币等国际规则制定,塑造新的竞争优势

CECBC

疫情 经济

架构师训练营第二周

M.

【面经】面试官:讲讲类的加载、链接和初始化?

冰河

架构 JVM 类加载 优化 性能调试

架构师训练营第 1 期 第 6 周作业

李循律

极客大学架构师训练营

有状态软件如何在k8s上快速扩容甚至自动扩容

东风微鸣

Kubernetes DevOps openshift

架构师训练营第 1 期 -- 第六周学习总结

发酵的死神

极客大学架构师训练营

SpringCloud 和 SpringBoot 版本选型

hepingfly

微服务 springboot SpringCloud 选型

当AI入职FBI,克格勃直呼内行

脑极体

美国半导体十年计划中的NO.1,模拟硬件究竟有什么价值?

脑极体

CICD实战——服务自动测试

TARS基金会

微服务 单元测试 CI/CD

Scrapy源码剖析(一)架构概览

Kaito

Python 爬虫 Scrapy 源码剖析

2020年区块链行业十大趋势

CECBC

区块链 技术人才

资深专家都知道的Docker常用命令_服务革新_赵钰莹_InfoQ精选文章