参考
Docker 入门教程
Docker —— 从入门到实践
1.Docker是什么
1.1 环境配置
软件开发最大的麻烦事之一,就是环境配置。用户计算机的环境都不相同,你怎么知道自家的软件,能在那些机器跑起来?
用户必须保证两件事:操作系统的设置,各种库和组件的安装。只有它们都正确,软件才能运行。举例来说,安装一个 Python 应用,计算机必须有 Python 引擎,还必须有各种依赖,可能还要配置环境变量。
如果某些老旧的模块与当前环境不兼容,那就麻烦了。开发者常常会说:"它在我的机器可以跑了"(It works on my machine),言下之意就是,其他机器很可能跑不了。
环境配置如此麻烦,换一台机器,就要重来一次,旷日费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。
1.2 虚拟机
虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在 Windows 系统里面运行 Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。
但存在以下问题:
- 资源占用多;
- 冗余步骤多;
- 启动慢;
1.3 Linux 容器
由于虚拟机存在这些缺点,Linux 发展出了另一种虚拟化技术:Linux 容器(Linux Containers,缩写LXC)。
Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。
由于容器是进程级别的,相比虚拟机有很多优势。
- 启动快;
- 资源占用少;
- 体积小;
1.4 Docker主要用途
Docker 的主要用途,目前有三大类。
- 提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。
- 提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容。
- 组建微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。
2.Docker安装
Docker是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE);企业版(Enterprise Edition,缩写为 EE)。企业版包含了一些收费服务。下面列举是社区版安装教程
- Mac
- Windows
- Ubuntu
- Debian
- CentOS
- Fedora
- 其他 Linux 发行版
2.1 检测是否安装成功
$ docker version
# 或者
$ docker info
2.2 开启Docker服务
Docker 是服务器----客户端架构。命令行运行docker命令的时候,需要本机有 Docker 服务。如果这项服务没有启动,可以用下面的命令启动
# service 命令的用法
$ sudo service docker start
# systemctl 命令的用法
$ sudo systemctl start docker
3.Docker常用命令
3.1 镜像
获取镜像(docker image pull)
Docker Hub 上有大量的高质量的镜像可以用,我们可以直接获取已经做好的镜像文件。
下面代码中,docker image pull是抓取 image 文件的命令。library/hello-world是 image 文件在仓库里面的位置,其中library是 image 文件所在的组,hello-world是 image 文件的名字。
由于 Docker 官方提供的 image 文件,都放在library组里面,所以它的是默认组,可以省略。
$ docker pull --help
$ docker image pull --help
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Pull an image or a repository from a registry
Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
--platform string Set platform if server is multi-platform capable
-q, --quiet Suppress verbose output
$ docker image pull library/hello-world
$ docker image pull hello-world
列出镜像(docker image ls)
列表包含了 仓库名、标签、镜像 ID、创建时间 以及 所占用的空间。
(base) [12:48:37] root@VM-4-4-centos:~
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
rocker/rstudio latest 0f828055b20c 3 days ago 1.89GB
hello-world latest feb5d9fea6a5 2 weeks ago 13.3kB
codercom/code-server latest 08823d73807e 3 weeks ago 1.11GB
删除本地镜像(docker image rm)
可以通过image_ID 或 镜像名来删除
(base) [12:52:04] root@VM-4-4-centos:~
$ docker image rm hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:9ade9cc2e26189a19c2e8854b9c8f1e14829b51c55a630ee675a5a9540ef6ccf
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359
(base) [12:53:39] root@VM-4-4-centos:~
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
rocker/rstudio latest 0f828055b20c 3 days ago 1.89GB
codercom/code-server latest 08823d73807e 3 weeks ago 1.11GB
3.2 容器
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(exited)的容器重新启动。
新建并启动(docker run)
常用的参数:
-i:运行容器
-t:容器启动后会进入命令行,将入这两个参数后,容器创建壳登录进去,即分配一个伪终端
-d: 后台运行(创建容器后不会自动登录容器,只加-i-t两个参数,创建后会自动进入容器)
-v:表示目录映射关系,前者是宿主机目录,后者是容器映射目录。
-p : 标识端口映射,前者是宿主机端口,后者是容器映射端口。可使用多个-p做端口映射
如果容器不存在,会自动docker pull 一个最新的image;
(base) [12:56:46] root@VM-4-4-centos:~
$ docker run ubuntu:18.04 /bin/echo 'Hello world'
Unable to find image 'ubuntu:18.04' locally
18.04: Pulling from library/ubuntu
284055322776: Pull complete
Digest: sha256:bfb4cabd667790ead5c95d9fe341937f0c21118fa79bc768d51c5da9d1dbe917
Status: Downloaded newer image for ubuntu:18.04
Hello world
启动已终止容器(docker container start)
终止容器(docker container stop)
查看所有容器(docker ps -a)
进入容器(docker exec)
在使用 -d 参数时,容器启动后会进入后台。
某些时候需要进入容器进行操作,包括使用 docker attach
命令或 docker exec
命令,推荐大家使用 docker exec 命令
举例:
(base) [13:09:25] root@VM-4-4-centos:~
$ docker exec -it 4791c4f6cd63 bash
root@4791c4f6cd63:/# ls
bin dev home lib32 libx32 mnt proc run srv tmp var
boot etc lib lib64 media opt root sbin sys usr
root@4791c4f6cd63:/# pwd
/
删除容器(docker container rm)
比如:需要删除modest_feistel这个容器,需要先stop
->再rm
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4791c4f6cd63 ubuntu "bash" 3 minutes ago Up 3 minutes modest_feistel
4eafd6d919e3 ubuntu "bash" 3 minutes ago Up 3 minutes sharp_wilbur
4dd3572398e8 codercom/code-server:latest "/usr/bin/entrypoint…" 11 hours ago Up 11 hours 0.0.0.0:8080->8080/tcp code-server
2f6ca3b22896 rocker/rstudio "/init" 11 hours ago Up 11 hours 0.0.0.0:8787->8787/tcp rstuido
$ docker container stop modest_feistel
modest_feistel
$ docker container rm modest_feistel
modest_feistel
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4eafd6d919e3 ubuntu "bash" 4 minutes ago Up 4 minutes sharp_wilbur
4dd3572398e8 codercom/code-server:latest "/usr/bin/entrypoint…" 11 hours ago Up 11 hours 0.0.0.0:8080->8080/tcp code-server
2f6ca3b22896 rocker/rstudio "/init" 11 hours ago Up 11 hours 0.0.0.0:8787->8787/tcp rstuido
3.3 仓库
目前 Docker 官方维护了一个公共仓库 Docker Hub,其中已经包括了数量超过 2,650,000 的镜像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
注册
你可以在 https://hub.docker.com 免费注册一个 Docker
账号。
登录
可以通过执行 docker login
命令交互式的输入用户名及密码来完成在命令行界面登录 Docker Hub
。
你可以通过 docker logout
退出登录。
搜索镜像(docker search)
例如以 centos 为关键词进行搜索:
$ docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 6449 [OK]
ansible/centos7-ansible Ansible on Centos7 132 [OK]
consol/centos-xfce-vnc Centos container with "headless" VNC session… 126 [OK]
jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos - … 117 [OK]
centos/systemd systemd enabled base container.
4. 其他
4.1 外部访问容器
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P
或 -p
参数来指定端口映射。
- 当使用
-P
标记时,Docker 会随机
映射一个端口到内部容器开放的网络端口。
使用 docker container ls 可以看到,本地主机的 32768 被映射到了容器的 80 端口。此时访问本机的 32768 端口即可访问容器内 NGINX 默认页面。
$ docker run -d -P nginx:alpine
$ docker container ls -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fae320d08268 nginx:alpine "/docker-entrypoint.…" 24 seconds ago Up 20 seconds 0.0.0.0:32768->80/tcp bold_mcnulty
- 当使用
-p
则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有
ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
.
使用 hostPort:containerPort 格式本地的 80/443 端口映射到容器的 80/443 端口
$ docker run -d \
-p 80:80 \
-p 443:443 \
nginx:alpine
4.2 docker 目录挂载
比如你使用docker安装了rstudio,你想将某个宿主目录设定为docker-rstudio容器的home目录,就需要考虑这个问题,可以用-v参数指定;
譬如我要启动一个centos容器,宿主机的/test目录挂载到容器的/soft目录,可通过以下方式指定:
docker run -it -v /test:/soft centos /bin/bash
这样在容器启动后,容器内会自动创建/soft的目录。通过这种方式,我们可以明确一点,即-v参数中,冒号":"前面的目录是宿主机目录,后面的目录是容器内目录。
欢迎评论交流~