赞
踩
Docker 是一个开源的应用容器引擎。Docker 可以让开发者打包他们创建的应用以及相应的依赖包到一个可移植、轻量级的容器中。Docker 可大大简化在容器中管理应用程序的过程。容器使用沙盒机制,运行在其中的应用与主系统相互分离,类似与虚拟机。但容器比虚拟机有更棒的可移植性、占用计算机资源更小。
有关 Docker 容器的不同组件的详细介绍,请看这篇《 Docker 生态系统:通用组件》(正在撰写中,稍后上线)。
这篇教程里,我们在 Ubuntu 20.04 上安装并运行 Docker Community Edition(CE)。
我会带领大家从零开始,一起在一台全新的 Ubuntu 上安装 Docker、讲解 Docker 容器和镜像的使用方式。最后将我们配置好的镜像推送到 Docker hub 上保存并可以与他人共享。
这些都是 Docker 最基础的技能,是 Docker 入门必备知识。让我们开始吧。
要学习本教程,你需要先准备一下环境:
设置一台 Ubuntu 20.04 服务器。
(你可以按照我们的《Ubuntu 20.04 初始服务器设置指南》来配置。正在撰写中,稍后上线)
如果你希望把自己创建和配置好的镜像保存在 Docker Hub,和他人共享你配置好的镜像的话,可以去 Docker Hub 注册一个自己的账号。我们在本教程中第 7 步与第 8 步会教大家如何使用 Docker Hub。
docker run
运行起来的镜像( images )叫容器( containers )官方 Ubuntu 存储库中提供的 Docker 安装软件包可能不是最新版本。
Ubuntu 官方的版本库中并不一定是 Docker 最新的安装包,为了保证是最新版,我们从 Docker 官方库来安装。
首先,更新现有的软件包列表:
$ sudo apt update
注意:如果无法更新,可能是你的软件源指向是国外的服务器,很可能已经被墙。所有首次更新请打开 VPN。
接下来,安装一些必备软件包,让 apt 通过 HTTPS 使用软件包。
sudo apt install apt-transport-https ca-certificates curl software-properties-common
然后将官方 Docker 版本库的 GPG 密钥添加到系统中:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
执行后显示
OK
将 Docker 版本库添加到APT源:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
执行后显示:
- Get:1 https://download.docker.com/linux/ubuntu focal InRelease [36.2 kB]
- Hit:2 http://cn.archive.ubuntu.com/ubuntu focal InRelease
- Get:3 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages [3056 B]
- Hit:4 http://cn.archive.ubuntu.com/ubuntu focal-updates InRelease
- Hit:5 http://cn.archive.ubuntu.com/ubuntu focal-backports InRelease
- Hit:6 http://cn.archive.ubuntu.com/ubuntu focal-security InRelease
- Fetched 39.2 kB in 2s (16.1 kB/s)
- Reading package lists... Done
接下来,我们用新添加的 Docker 软件包来进行升级更新。
sudo apt update
确保要从 Docker 版本库,而不是默认的 Ubuntu 版本库进行安装:
apt-cache policy docker-ce
执行后会看到这样的结果( Docker 的版本号可能略有不同)
- docker-ce:
- Installed: (none)
- Candidate: 5:19.03.12~3-0~ubuntu-focal
- Version table:
- 5:19.03.12~3-0~ubuntu-focal 500
- 500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
- 5:19.03.11~3-0~ubuntu-focal 500
- 500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
- 5:19.03.10~3-0~ubuntu-focal 500
- 500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
- 5:19.03.9~3-0~ubuntu-focal 500
- 500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
请注意,到目前这一步docker-ce
还未安装,但根据上一步中的列表,可以看到 docker-ce 来自 Docker 官方版本库。
最后,安装 Docker :
sudo apt install docker-ce
现在 Docker 已经安装完毕。我们启动守护程序。检查 Docker 是否正在运行:
sudo systemctl status docker
执行结果类似以下内容,说明该服务处于活动状态并且正在运行:
- ● docker.service - Docker Application Container Engine
- Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
- Active: active (running) since Sat 2020-07-08 02:55:20 UTC; 5min ago
- TriggeredBy: ● docker.socket
- Docs: https://docs.docker.com
- Main PID: 4287 (dockerd)
- Tasks: 8
- Memory: 36.4M
- CGroup: /system.slice/docker.service
- └─4287 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
现在,安装 Docker 不仅可以为您提供 Docker 服务(守护程序),还可以为您提供docker
命令行实用程序或 Docker 客户端。docker
命令行的使用会在本教程后边讨论。
(此步不影响 Docker 使用,可选择跳过)
默认情况下,docker
命令只能由 root 用户或由 docker 组中的用户运行,docker 组用户是在Docker安装过程中自动创建的。
如果你在执行docker
命令时,没有用 sudo ,并且使用的用户也不是 docker 组成员,那么结果会显示:
- Output
- docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
- See 'docker run --help'.
如果要避免sudo
在运行docker
命令时键入任何内容,请将用户名添加到docker
组中:
如果不想用 sudo 来执行 docker 命令,那么我们只需要把对应的用户添加到 docker 组中即可。
sudo usermod -aG docker ${USER}
使用新组成员身份执行命令,需要注销后重新登录,或使用su来切换身份。
su - ${USER}
系统将提示你输入此用户密码以继续。
我们可以通过id
这个命令来确认刚刚添加的用户是否已经在 docker 组中:
id -nG
- Output
- kalasearch sudo docker
如果你需要添加一个用户到docker
组,而你又不是以该用户的身份登录的,可使用此命令来添加:
sudo usermod -aG docker ${USER}
本教程接下来会假定大家使用的用户已经在 docker 组中,并使用此用户执行docker
命令。如果你没有添加正在使用的用户到 docker 组中,那么请在执行命令前加上sudo
好了,到这里我们已经万事俱备。让我们开始探索docker
的使用方法吧
我们可以向docker
命令传送一系列选项、参数等。
语法格式如下:
docker [option] [command] [arguments]
要查看所有可用的子命令,请键入:
docker
从 docker 19 开始,完整的命令列表:
- $ docker
-
- Usage: docker [OPTIONS] COMMAND
-
- A self-sufficient runtime for containers
-
- Options:
- --config string Location of client config files (default
- "/home/kalasearch/.docker")
- -c, --context string Name of the context to use to connect to the daemon
- (overrides DOCKER_HOST env var and default context set
- with "docker context use")
- -D, --debug Enable debug mode
- -H, --host list Daemon socket(s) to connect to
- -l, --log-level string Set the logging level
- ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
- --tls Use TLS; implied by --tlsverify
- --tlscacert string Trust certs signed only by this CA (default
- "/home/kalasearch/.docker/ca.pem")
- --tlscert string Path to TLS certificate file (default
- "/home/kalasearch/.docker/cert.pem")
- --tlskey string Path to TLS key file (default
- "/home/kalasearch/.docker/key.pem")
- --tlsverify Use TLS and verify the remote
- -v, --version Print version information and quit
-
- Management Commands:
- builder Manage builds
- config Manage Docker configs
- container Manage containers
- context Manage contexts
- engine Manage the docker engine
- image Manage images
- network Manage networks
- node Manage Swarm nodes
- plugin Manage plugins
- secret Manage Docker secrets
- service Manage services
- stack Manage Docker stacks
- swarm Manage Swarm
- system Manage Docker
- trust Manage trust on Docker images
- volume Manage volumes
-
- Commands:
- attach Attach local standard input, output, and error streams to a running container
- build Build an image from a Dockerfile
- commit Create a new image from a container's changes
- cp Copy files/folders between a container and the local filesystem
- create Create a new container
- diff Inspect changes to files or directories on a container's filesystem
- events Get real time events from the server
- exec Run a command in a running container
- export Export a container's filesystem as a tar archive
- history Show the history of an image
- images List images
- import Import the contents from a tarball to create a filesystem image
- info Display system-wide information
- inspect Return low-level information on Docker objects
- kill Kill one or more running containers
- load Load an image from a tar archive or STDIN
- login Log in to a Docker registry
- logout Log out from a Docker registry
- logs Fetch the logs of a container
- pause Pause all processes within one or more containers
- port List port mappings or a specific mapping for the container
- ps List containers
- pull Pull an image or a repository from a registry
- push Push an image or a repository to a registry
- rename Rename a container
- restart Restart one or more containers
- rm Remove one or more containers
- rmi Remove one or more images
- run Run a command in a new container
- save Save one or more images to a tar archive (streamed to STDOUT by default)
- search Search the Docker Hub for images
- start Start one or more stopped containers
- stats Display a live stream of container(s) resource usage statistics
- stop Stop one or more running containers
- tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
- top Display the running processes of a container
- unpause Unpause all processes within one or more containers
- update Update configuration of one or more containers
- version Show the Docker version information
- wait Block until one or more containers stop, then print their exit codes
- Run 'docker COMMAND --help' for more information on a command.
要查看特定命令可用的选项,请键入:
docker ${docker-subcommand} --help
要查看有关 Docker 的系统信息,请使用:
docker info
棒,到这里你已经学会了 docker 的基本运行命令,接下来,让我们来看看 docker 最重要的功能,如何使用镜像。
如何在Docker中使用镜像
Docker 容器(containers)是从 Docker 镜像生成出来的。默认情况下,Docker 从Docker Hub下载这些镜像,Docker 公司在运营这个Docker Hub。
任何人都可以在 Docker Hub 上托管自己的 Docker 镜像。因此,我们大多数需要的应用程序和 Linux 发行版都能在这里找到。
要检查是否可以访问 Docker Hub 和从这个网站下载镜像,请输入:
docker run hello-world
如果你得到以下结果,说明你的机器访问 Docker hub 一切顺畅:
- $ docker run hello-world
- Unable to find image 'hello-world:latest' locally
- latest: Pulling from library/hello-world
- 0e03bdcc26d7: Pull complete
- Digest: sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9
- Status: Downloaded newer image for hello-world:latest
-
- Hello from Docker!
- This message shows that your installation appears to be working correctly.
-
- To generate this message, Docker took the following steps:
- 1. The Docker client contacted the Docker daemon.
- 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
执行此命令时,Docker 首先在本地查找hello-world
,如没有,它会从 Docker Hub(默认版本库)下载了该镜像。下载镜像后,Docker 会根据镜像创建一个容器,并执行该容器中的应用程序。
您可以通过将docker
命令与search
子命令配合使用来搜索 Docker Hub 上可用的镜像。
例如,要搜索 Ubuntu 的镜像,请输入:
docker search ubuntu
此命令会在 Docker Hub 上搜索并返回名称与搜索字符串匹配的所有镜像列表。
执行后显示的结果如下:
- NAME DESCRIPTION STARS OFFICIAL AUTOMATED
- ubuntu Ubuntu is a Debian-based Linux operating sys… 11102 [OK]
- dorowu/ubuntu-desktop-lxde-vnc Docker image to provide HTML5 VNC interface … 443 [OK]
- rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… 245 [OK]
- consol/ubuntu-xfce-vnc Ubuntu container with "headless" VNC session… 220 [OK]
- ubuntu-upstart Upstart is an event-based replacement for th… 110 [OK]
- neurodebian NeuroDebian provides neuroscience research s… 68 [OK]
- 1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5 ubuntu-16-nginx-php-phpmyadmin-mysql-5 50 [OK]
- ubuntu-debootstrap debootstrap --variant=minbase --components=m… 44 [OK]
- nuagebec/ubuntu Simple always updated Ubuntu docker images w… 24 [OK]
- i386/ubuntu Ubuntu is a Debian-based Linux operating sys… 21
- 1and1internet/ubuntu-16-apache-php-5.6 ubuntu-16-apache-php-5.6 14 [OK]
- 1and1internet/ubuntu-16-apache-php-7.0 ubuntu-16-apache-php-7.0 13 [OK]
- 1and1internet/ubuntu-16-nginx-php-phpmyadmin-mariadb-10 ubuntu-16-nginx-php-phpmyadmin-mariadb-10 11 [OK]
- 1and1internet/ubuntu-16-nginx-php-5.6 ubuntu-16-nginx-php-5.6 8 [OK]
- 1and1internet/ubuntu-16-nginx-php-5.6-wordpress-4 ubuntu-16-nginx-php-5.6-wordpress-4 7 [OK]
- 1and1internet/ubuntu-16-apache-php-7.1 ubuntu-16-apache-php-7.1 6 [OK]
- darksheer/ubuntu Base Ubuntu Image -- Updated hourly 5 [OK]
- 1and1internet/ubuntu-16-nginx-php-7.0 ubuntu-16-nginx-php-7.0 4 [OK]
- pivotaldata/ubuntu A quick freshening-up of the base Ubuntu doc… 4
- pivotaldata/ubuntu16.04-build Ubuntu 16.04 image for GPDB compilation 2
- 1and1internet/ubuntu-16-sshd ubuntu-16-sshd 1 [OK]
- smartentry/ubuntu ubuntu with smartentry 1 [OK]
- 1and1internet/ubuntu-16-php-7.1 ubuntu-16-php-7.1 1 [OK]
- pivotaldata/ubuntu-gpdb-dev Ubuntu images for GPDB development 1
- pivotaldata/ubuntu16.04-test Ubuntu 16.04 image for GPDB testing 0
“ OFFICIAL” 列(即官方)对应的镜像,就是出自官方的镜像了,大家可放心使用。
接下来,我们可以用pull
子命令,将你需要的镜像下载到计算机。
本教程我们使用ubuntu
的官方镜像。
docker pull ubuntu
你将看到以下执行结果:
- Using default tag: latest
- latest: Pulling from library/ubuntu
- 692c352adcf2: Pull complete
- 97058a342707: Pull complete
- 2821b8e766f4: Pull complete
- 4e643cc37772: Pull complete
- Digest: sha256:55cd38b70425947db71112eb5dddfa3aa3e3ce307754a3df2269069d2278ce47
- Status: Downloaded newer image for ubuntu:latest
- docker.io/library/ubuntu:latest
下载镜像后,可以用run
来运行镜像。
从上面这个案例我们可以发现,使用run
来执行本地不存在的hello-world
镜像时, docker 发现本地没有这个镜像,会直接在 Docker hub 上查找并下载对应的镜像。
要查看已下载到计算机的镜像:
docker images
输出结果如下:
- REPOSITORY TAG IMAGE ID CREATED SIZE
- ubuntu latest adafef2e596e 4 days ago 73.9MB
- hello-world latest bf756fb1ae65 6 months ago 13.3kB
当镜像执行时,它会生成一个容器,我们在容器中添加所需的软件后,可以把这个容器再次打包成新镜像。并可以把这个镜像上传到 Docker hub 上,方便自己在其他机器上使用。或是分享给合作开发者一起使用。这一点我们会在本教程后面的步骤中进行实践。
下一步,让我们来看看容器是如何运行的吧。
在上一步的例子中,我们执行了hello-world
并学习了如何查看镜像和容器。但其实容器并不仅仅是这样,它可比这有用的多。接下来我们来看看容器能做些什么。
作为示例,让我们用 Ubuntu 最新镜像来运行。使用-i -t 这两个参数,可以让你通过 shell 来方面他们。
docker run -it ubuntu
执行命令后,提示符会变为你正在使用镜像的容器id:
root@7896ef8f403f:/#
注意:这个容器ID,在此例中,为7896ef8f403f
。我们可以使用这个ID来识别和删除这个容器。
现在,我们可以在容器内执行任何命令了。例如,让我们更新容器内的软件源。
我们在容器内是以 root 用户身份进行操作的,所有不需要使用sudo
root@7896ef8f403f:/# apt update
然后在这个容器中可安装任何应用程序。我们来安装Node.js:
apt install nodejs
执行这个命令,系统会把Node.js安装在刚刚我们从官方下载的 Ubuntu 镜像的容器里。安装完成后,请验证是否已安装 Node.js:
node -v
我们会在终端中看到版本号:
v10.19.0
我们安装的这个node.js只会在这个容器里被修改,不会修改镜像。
要退出容器,可输入exit
。
下一步,让我们来学习如何在系统上管理容器。
在使用 Docker 一段时间后,我们的计算机上会有许多活动(运行)和非活动容器。
要查看这些活动中的容器对象,请使用:
docker ps
输出内容如下:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
在本教程中,我们启动了两个容器。一个是hello-world
镜像,另一个是ubuntu
镜像。这两个容器目前都没有在运行,但是它们仍然保存在计算机里。
要查看所有容器(活动和非活动),请docker ps -a
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 7896ef8f403f ubuntu "/bin/bash" 19 minutes ago Exited (127) About a minute ago keen_curie
- b012485e74b4 hello-world "/hello" 27 minutes ago Exited (0) 27 minutes ago admiring_ishizaka
要查看最后创建的容器,可使用:
docker ps -l
输出结果如下:
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 7896ef8f403f ubuntu "/bin/bash" 20 minutes ago Exited (127) About a minute ago keen_curie
要启动已停止的容器,请使用docker start
命令+容器ID或容器名。
我们来启动刚刚关掉的容器7896ef8f403f
docker start 7896ef8f403f
容器启动,我们可以docker ps用来查看其状态:
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 7896ef8f403f ubuntu "/bin/bash" 23 minutes ago Up About a minute keen_curie
要停止正在运行的容器,请使用docker stop
命令+容器 ID 或容器名。这次,我们将使用 Docker 分配的容器名称,即keen_curie
:
docker stop keen_curie
当某些容器我们不会再使用,我们可以通过容器 ID 或名称来轻松删除它们。我们可以通过docker rm
命令来删除不用的容器。
docker rm keen_curie
使用docker ps -a
命令查找与hello-world
镜像关联的容器的容器ID或名称,然后将其删除。
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 7896ef8f403f ubuntu "/bin/bash" 25 minutes ago Exited (0) About a minute ago keen_curie
- b012485e74b4 hello-world "/hello" 32 minutes ago Exited (0) 32 minutes ago admiring_ishizaka
根据这个列表,可以看到我们这台机器上hello-world
容器名称为admiring_ishizaka
docker rm admiring_ishizaka
我们可以启动一个新容器,并使用--name
为其命名。还可以使用--rm
创建一个容器并让这个容器在结束时自动删除。
等多命令和参数可用docker run help
来查看。
我们添加了各种软件的容器,还可以转换为镜像,我们可以用它们创建建新的容器。让我们看看它是如何工作的。
将镜像上传至Docker Hub
启动 Docker 镜像时,可以像使用虚拟机一样创建,修改和删除文件。我们所做的更改将仅应用于在这个容器里。我们可以启动和关闭这个容器,用docker rm
命令来删除不用的容器。
接下来,我们来谈谈当我们在容器中安装好各种软件,我们想把它保存成一个新镜像时,我们应该怎么做。
刚刚我们在 Ubuntu 的容器中安装 Node.js,此时,这个容器里的内容已经不同于生成它的镜像。如果以后我们想直接打开镜像就预装 Node.js 的话,我们可以把这个容器生成为新的镜像。
然后用以下命令将更改提交到 Docker hub。
docker commit -m "What you did to the image" -a "Author Name" container_id repository/new_image_name
参数 -m 是提交镜像的备注,让我们知道此镜像有哪些不同之处。参数 -a 用于指定作者名。
这除非你在 Docker Hub 上创建了其他repository
,一般来说container_id
是 Docker Hub 上你的用户名,
例如:
我们在 Docker 上的用户名是 kalasearch ,我们将刚刚创建的容器7896ef8f403f
上传至Docker Hub。
docker commit -m "added node.js" -a "kalasearch" 7896ef8f403f kalasearch/ubuntu-nodejs
当我们提交新镜像时,新生成的镜像也会在我们的计算机上本地保存。在本教程的后面,我们可以学到如何将镜像推送到 Docker Hub,以便其他人可以访问它。
我们用 docker images
命令查看本地镜像:
docker images
输出如下,可以发现刚刚的新镜像已经在其中了:
- REPOSITORY TAG IMAGE ID CREATED SIZE
- kalasearch/ubuntu-nodejs latest 07bb1f0fbf36 44 seconds ago 163MB
- ubuntu latest adafef2e596e 4 days ago 73.9MB
- hello-world latest bf756fb1ae65 6 months ago 13.3kB
在此例中,ubuntu-nodejs
是新镜像,它是我们从 Docker hub 下载的官方ubuntu
镜像派生的。它们的镜像大小差异,反映了所做的更改。
在此例中,我们安装了 NodeJS。因此,下次我们需要使用已预安装 NodeJS 的 Ubuntu 运行容器时,就可以直接使用新镜像。
现在,现在我们可以把我们创建的新镜像共享给需要的人啦,下面我们谈谈如何共享创建的镜像。
从现有镜像里创建新镜像后,下一步是与我们的朋友共享。我们可以在 Docker Hub 上来共享我们的镜像。要将我们的镜像推送到 Docker Hub,我们必须要有docker帐户。
本节介绍如何将 Docker 镜像推送到 Docker Hub。要了解如何创建自己的私有 Docker,请查看《如何在 Ubuntu 14.04 上设置私有 Docker》(正在撰写中,稍后上线)
要推送镜像,请首先登录 Docker Hub。
docker login -u docker-registry-username
输入账号对应的密码后,即可登录成功。
Login Succeeded
注意:如果你在 Docker 注册用户名与用于创建镜像的本地用户名不同,要在备注中记录 Docker 用户名:
docker tag kalasearch/ubuntu-nodejs kalasearch/ubuntu-nodejs
然后,我们就可以推送镜像到 Docker hub 上了,命令如下:
docker push docker-registry-username/docker-image-name
如果我们要把ubuntu-nodejs
镜像推送到kalasearch
的版本库,命令如下:
docker push kalasearch/ubuntu-nodejs
上传镜像需要一些时间,过程如下:
- The push refers to repository [docker.io/kalasearch/ubuntu-nodejs]
- 039d7bd0cf7b: Pushed
- 544a70a875fc: Mounted from library/ubuntu
- cf0f3facc4a3: Mounted from library/ubuntu
- 132bcd1e0eb5: Mounted from library/ubuntu
- d22cfd6a8b16: Mounted from library/ubuntu
- .......
DockerDashboard
如果推送尝试导致此类错误,则你可能未登录:
- The push refers to repository [docker.io/kalasearch/ubuntu-nodejs]
- 039d7bd0cf7b: Preparing
- 544a70a875fc: Preparing
- cf0f3facc4a3: Preparing
- 132bcd1e0eb5: Preparing
- d22cfd6a8b16: Preparing
- .....
登录docker login
并重新提交。然后就能在 DockerHub 上看到你到镜像啦。
现在,我们可以docker pull kalasearch/ubuntu-nodejs
命令在任意一台机器上使用我们自己创建的镜像啦。
本教程中,我们学会了如何安装 Docker,在 Docker 中使用镜像和容器,并将修改后的镜像推送到 Docker Hub。
我们已经掌握了 Docker 的入门基础知识,如果想深入学习 Docker 可在 kalasearch 程序员社区中找到更多 Docker 教程。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。