一篇文章带你入门Docker!

434 阅读13分钟

一、为什么选择 Docker

传统虚拟机的缺点:资源占用十分多、冗余步骤多、启动很慢。

Docker 的优势:使用容器化技术,项目代码带上环境配置打包成镜像,上传到镜像仓库,别人下载镜像即可运行,不再需要复杂的环境配置。

「注意:容器化技术不是模拟一个完整的操作系统」。所以 Docker 之所以能火,是因为它比普通虚拟机轻巧!

Docker 和虚拟机技术的不同:

  • 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件;

  • Docker 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了;

  • 每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响。

二、Docker 中的几个术语

Docker的相关术语:

  • 镜像 (image)

  • 容器 (container)

  • 仓库 (repository)

镜像可以认为是一些软件和配置环境的整体打包。

容器可以认为是一个精简的 Linux 系统,它是通过镜像运行起来的实例,镜像运行起来就是容器。从这个角度来讲,镜像就类似于 Java 中的 Class 类型,由它可以创建多个实例。

镜像是存在硬盘上的东西,镜像运行起来,就形成一个容器,容器才是真正跑起来的程序。只不过在 Docker 中,我们可以进入容器,做一些操作,然后再把容器中的改动提交形成一个新的镜像。

仓库类似于 Github,我们写好的代码会提交到 Github 上面进行保存和管理,方便在其他地方也能下载代码。镜像仓库也是类似的,制作好的镜像,就把它放到镜像仓库,方便其他人直接用镜像部署。

三、Docker 安装与卸载

环境准备,Linux 要求内核 3.0 以上,我这里使用的阿里云服务器(CentOS 8),查看相关信息的命令如下:

➜  ~ uname -r    
4.18.0-193.14.2.el8_2.x86_64   # 要求 3.0 以上
➜  ~ cat /etc/os-release 
NAME="CentOS Linux"
VERSION="8 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="8"

Docker 的安装参照其官方文档按照步骤来就完全可以(Docker 的官方文档相当的详细),网址:docs.docker.com/engine/inst…

这里为了方便为大家把安装步骤以及相应的注释写出来:

1、卸载旧版本,如果服务器上没安装过 docker 就不用进行此步骤。

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

2、需要的安装包:

yum install -y yum-utils

3、设置镜像的仓库,官方文档中默认是国外的仓库,不推荐使用,这里推荐使用国内的,如下:

yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新 yum 软件包索引:

yum makecache fast # 注意:如果是 centos 8 版本则直接使用 yum makecache 即可

4、安装 docker ,docker-ce 代表为社区版,而 ee 代表是企业版,此处安装社区版。

yum install docker-ce docker-ce-cli containerd.io

注意:版本为 centos 8 时执行上述命令时会报错,说的是 containerd.io >= 1.2.2-3,解决方法:

(1)降低 docker 的版本;(2)如果不想降低 docker 版本,那么就更新 containerd.io 的版本:

wget https://download.docker.com/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm
yum install -y  containerd.io-1.2.6-3.3.el7.x86_64.rpm

然后重新执行:

yum install docker-ce docker-ce-cli containerd.io

5、启动 docker。

systemctl start docker

6、查看是否安装成功。

[root@eric ~]# docker version
Client: Docker Engine - Community
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 17:03:45 2020
 OS/Arch:           linux/amd64
 Experimental:      false
 ...

显示 docker 的版本信息则说明 docker 安装成功。

7、配置阿里云。

把上述的代码直接一步一步执行即可。

8、测试运行 hello-world。

第一次运行会自动从镜像仓库中拉取最新镜像,然后再运行镜像。

docker run hello-world 

等待出现以下内容,说明 hello-world 镜像拉取并运行成功。

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

Docker 中 run 命令运行的原理:

run命令运行原理

9、查看当前 Docker 中下载的镜像信息。

➜  ~ docker images         
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
hello-world           latest              bf756fb1ae65        4 months ago        13.3kB

卸载 Docker(除非不用,否则干嘛要卸载呢):

#1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#2. 删除资源
rm -rf /var/lib/docker # /var/lib/docker 是 docker 的默认工作路径!

Docker 常用命令

Docker 中的命令有很多,也不可能全部记完,还是像学习 Linux 命令一样,只要多练习实践,就能够快速掌握。另外,只要 Linux 玩得好,那么 Docker 这一块怎么玩都不会错。

Docker 命令官方文档:docs.docker.com/reference/,…

帮助命令

docker version   # 显示docker的版本信息

docker info      # 显示docker的系统信息,包括镜像和容器的数量

docker --help    # 帮助命令

镜像命令

docker images   #查看所有本地主机上的镜像 可以使用docker image ls代替

docker search   #搜索镜像

docker pull     #下载镜像

docker rmi      #删除镜像 

下面对这几个命令详细说明一下。

docker images 查看所有本地的主机上的镜像」

➜  ~ docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
mysql                 5.7                 e73346bdf465        24 hours ago        448MB

解释:

REPOSITORY  # 镜像的仓库源
TAG         # 镜像的标签
IMAGE ID    # 镜像的id
CREATED     # 镜像的创建时间
SIZE        # 镜像的大小

docker images 命令的可选项:

Options:
  -a, --all             Show all images (default hides intermediate images)  #列出所有镜像
  -q, --quiet           Only show numeric IDs  # 只显示镜像的id

例如:

➜  ~ docker images -aq  # 显示所有镜像的id
e73346bdf465

docker search 搜索镜像」

通常我们会在 DockerHub 官网中进行搜索相应的镜像,如下:

官网搜索镜像

但是我们也可以在 Docker 命令行中进行镜像搜索,例如:

[root@eric ~]# docker search mysql
NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql                             MySQL is a widely used, open-source relation??  10202               [OK]                
mariadb                           MariaDB is a community-developed fork of MyS??  3753                [OK]                
mysql/mysql-server                Optimized MySQL Server Docker images. Create??  746                                     [OK]
percona                           Percona Server is a fork of the MySQL relati??  511                 [OK]                  

docker search 命令后也可以加可选项:

Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output

例如我们对搜索的结果进行一定的过滤:

# --filter=STARS=5000 表示搜索出来的镜像就是 STARS 大于 5000 的      
➜  ~ docker search mysql --filter=STARS=5000
NAME                DESCRIPTION                                     STARS               OFFICIAL  
mysql               MySQL is a widely used, open-source relation…   9500                [OK]   

docker pull 下载镜像」

下载镜像:docker pull 镜像名[:tag],例如我们下载 tomcat 8,命令如下:

  ~ docker pull tomcat:8     # 如果不写tag,默认就是latest
8: Pulling from library/tomcat
90fe46dd8199: Already exists   #分层下载:docker image 的核心 联合文件系统
35a4f1977689: Already exists 
bbc37f14aded: Already exists 
74e27dc593d4: Already exists 
93a01fbfad7f: Already exists 
1478df405869: Pull complete 
64f0dd11682b: Pull complete 
68ff4e050d11: Pull complete 
f576086003cf: Pull complete 
3b72593ce10e: Pull complete 
Digest: sha256:0c6234e7ec9d10ab32c06423ab829b32e3183ba5bf2620ee66de866df640a027  # 签名 防伪
Status: Downloaded newer image for tomcat:8
docker.io/library/tomcat:8 #真实地址

#指定版本下载 MySQL,如
  ~ docker pull mysql:5.7

docker rmi 删除镜像」

➜  ~ docker rmi -f 镜像id                      # 删除指定的镜像
➜  ~ docker rmi -f 镜像id 镜像id 镜像id 镜像id  # 删除指定的多个镜像
➜  ~ docker rmi -f $(docker images -aq)        # 删除全部的镜像 $()为传入参数

容器命令

容器就是运行起来的镜像。

docker pull 名称[:tag] # 拉取镜像,有了镜像才可以创建出容器

docker run 镜像        # 新建容器并启动,此时会新键容器

docker ps              # 列出所有运行的容器
docker ps -a           # 列出所有的容器(包含历史)

docker rm 容器id        # 删除指定id的容器,注意和 rmi 的区别

docker start 容器id     # 启动容器,根据容器 id 来运行,此时不会新键容器
docker restart 容器id   # 重启容器
docker stop 容器id      # 停止当前正在运行的容器
docker kill 容器id      # 强制停止当前容器

「运行容器」

使用命令 docker run 镜像 命令来运行容器,此命令的可选项有:

--name="Name" # 容器名字 tomcat01 tomcat02 用来区分容器
-d    # 后台方式运行
-it    # 使用交互方式运行,进入容器查看内容
-p            # 指定容器的端口 -p 8080(宿主机):8080(容器)
-P(大写)      #随机指定端口

例如这里写个测试,启动 msyql 镜像并进入容器,使用 bash:

[root@eric ~]# docker run -it mysql /bin/bash
# 注意此时已经进入容器内部,观察主机名称的改变
root@6849133331da:/# ls
bin  boot  dev docker-entrypoint-initdb.d  entrypoint.sh  etc home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
# 进入 MySQL 数据库中
root@6849133331da:/# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.32 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
# 此时进入我们 Docker 中的数据库,和本地操作是一模一样的
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)
# 退出数据库
mysql> exit
Bye
# 退出 mysql 容器
root@6849133331da:/# exit
exit
# 查看运行的容器
[root@eric ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
6849133331da        mysql:5.7           "docker-entrypoint.s??   11 days ago         Up About a minute   0.0.0.0:3306->3306/tcp, 33060/tcp   mysql01
# 停止运行容器
[root@eric ~]# docker stop 6849133331da
docker6849133331da
[root@eric ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@eric ~]# 

有的容器退出后就会自动停止运行,如 centos,如果想容器不停止退出,则可以使用按键:ctrl + P + Q

对于上述在容器中运行的数据库,如果我们想要在外部连接使用,那该怎么办呢?很简单,只要我们把其端口映射出来就可以了,在我们运行数据库时,可以这样使用命令:docker run -d -p 3306:3306 mysql,它就表示后台运行 MySQL 数据库,并把其端口映射到服务器中,然后我们开启服务器防火墙相对应的 3306 端口以及阿里云安全组 3306 端口后,就可以使用公网地址和端口号连接我们 Docker 容器中的数据库了。例如我的:

连接Docker数据库

「列举容器」

docker ps    # 列举当前正在运行的容器

docker ps -a # 列举所有运行过的容器

「退出容器」

exit          # 容器停止并退出
ctrl + P + Q  # 容器不停止退出

「删除容器」

docker rm 容器id    # 删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -rf
docker rm -f 容器id 或 $(docker ps -aq)  # 删除指定的容器或全部删除(包括历史信息)
docker ps -a -q|xargs docker rm         # 删除所有的容器

「启动和停止容器的操作」

docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器

其他命令

「后台启动命令」

有时候我们想要容器在后台启动,例如我们想要在后台运行一个 centos 容器,那这个时候就用到了如下命令:

# 命令 docker run -d 镜像名
➜  ~ docker run -d centos
a8f922c255859622ac45ce3a535b7a0e8253329be4756ed6e32265d2dd2fac6c

此时我们来查看正在运行的容器:

➜  ~ docker ps           
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

发现并没有容器正在运行,centos 停止了。这是一个常见的坑,docker 容器使用后台运行,就必须要有一个前台进程,docker 发现没有应用,就会自动停止。比如 docker 中安装了 nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了。

「查看日志」

使用 docker logs 命令,可选项有:

docker logs --help
Options:
      --details        Show extra details provided to logs 
*  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
*      --tail string    Number of lines to show from the end of the logs (default "all")
*  -t, --timestamps     Show timestamps
      --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)   

显示日志:

docker logs -t --tail n 容器id  # 查看 n 行日志
docker logs -ft 容器id          # 跟着日志

「查看容器中进程信息」

docker top 容器id

「查看镜像的元数据」

比较重要的命令,可以查看容器的详细信息。

docker inspect 容器id

「进入当前正在运行的容器」

我们通常都是使用后台方式运行容器的,但是有些时候需要进入容器,修改一些配置,进入容器的方式有两种:

# 方式1:
docker exec -it 容器id bashshell

# 方式2:
docker attach 容器id

两种方式的区别:

docker exec   # 进入当前容器后开启一个新的终端,可以在里面操作。(常用)
docker attach # 进入容器正在执行的终端

测试:

➜  ~ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS      
55321bcae33d        centos              "/bin/sh -c 'while t…"   10 minutes ago      Up 10 minutes

# 测试 exec 方式进入在后台运行的容器,使用 bash 进行交互
➜  ~ docker exec -it 55321bcae33d /bin/bash
[root@55321bcae33d /]# 

# 测试 attach 方式
➜  ~ docker attach 55321bcae33d 
当前正在的代码...

「拷贝容器内文件到宿主机」

拷贝命令:

docker cp 容器id:容器内路径  宿主机目的路径

测试:

#进入docker容器内部
➜  ~ docker exec -it  55321bcae33d /bin/bash 
[root@55321bcae33d /]# ls
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
#新建一个文件
[root@55321bcae33d /]# echo "hello" > test.java
[root@55321bcae33d /]# cat test.java 
hello
[root@55321bcae33d /]# exit
exit
➜  ~ docker cp 55321bcae33d:/test.java /    #拷贝到宿主机 / 目录下
➜  ~ cd /              
➜  / ls   # 可以看见 test.java 确实存在
bin   home         lib     mnt   run      sys  
...
etc   test.java    media   root  swapfile  var  

总结

本文为 Docker 的入门文章,从为什么选择 Docker 也即 Docker 的优势说起,然后描述了 Docker 中的几个相关术语——镜像、容器、镜像仓库。紧接着就向大家介绍了 Docker 的安装与卸载,最后比较重要的是掌握 Docker 中常用的一些命令。