Docker-01-安装&基础命令
文章目录
- Docker-01-安装&基础命令
 - 一、Docker是什么?
 - 二、安装Docker
 - ①:卸载旧版
 - ②:配置Docker的yum库
 - ③:安装Docker
 - ④:启动和校验
 - ⑤:配置镜像加速
 - 01:注册阿里云账号
 - 02:开通镜像服务
 - 03:配置镜像加速
 
- 三、快速入门 - 部署MySQL
 - ①:快速安装
 - ②:小结
 - ③:命令解读
 
- 四、基础 - 命令
 - ①:常见命令
 - 01:命令介绍
 - 02:示例(安装Nginx)
 - 03:命令别名
 
- ②:数据卷
 - 01:什么是数据卷
 - 02:数据卷命令
 - 03:示例(创建nginx数据卷)
 - 04:示例(创建MySQL数据卷)
 - 05:挂载本地目录或文件
 
一、Docker是什么?
"Docker"一词指代了多个概念,包括开源社区项目、开源项目使用的工具、主导支持此类项目的公司 Docker Inc.,以及该公司官方支持的工具。这些技术和公司的同名可能会造成混淆。
以下简要说明 Docker 以便区分:
IT 软件"Docker"是支持创建和使用 Linux® 容器的容器化技术。
 开源 Docker 社区致力于改进这类技术,并免费提供给所有用户,使之获益。
 Docker Inc. 公司凭借 Docker 社区产品起家,主要负责提升社区版本的安全性,并将技术进步与广大技术社区分享。此外,它还专门对这些技术产品进行完善和安全固化,以服务于企业客户。
 借助 Docker,您可将容器当做轻巧、模块化的虚拟机来使用。同时,您还将获得高度灵活性,实现对容器的高效创建、部署及复制,并在环境之间迁移它们,从而有助于您针对云来优化应用
了解更多看这里:https://www.redhat.com/zh/topics/containers/what-is-docker
二、安装Docker
①:卸载旧版
首先如果系统中已经存在旧的Docker,则先卸载:
yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine
 

②:配置Docker的yum库
1.首先要安装一个yum工具
yum install -y yum-utils
 
2.安装成功后,执行命令,配置Docker的yum源:
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
 

③:安装Docker
1.执行命令,安装Docker
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
 
④:启动和校验
# 启动Docker
systemctl start docker
# 停止Docker
systemctl stop docker
# 重启
systemctl restart docker
# 设置开机自启
systemctl enable docker
# 执行docker ps命令,如果不报错,说明安装启动成功
docker ps
 

⑤:配置镜像加速
- 以阿里云镜像加速为例
 
01:注册阿里云账号
访问阿里云网站: https://www.aliyun.com/ 注册一个账号。
02:开通镜像服务
1.在首页的产品中,找到阿里云的容器镜像服务:

2.点击后进入控制台 (首次可能需要选择立刻开通,然后进入控制台。):

03:配置镜像加速
1.找到镜像工具下的镜像加速器:


2.具体命令如下:
# 创建目录
mkdir -p /etc/docker
# 复制内容,注意把其中的镜像加速地址改成你自己的
tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"]
}
EOF
# 重新加载配置
systemctl daemon-reload
# 重启Docker
systemctl restart docker
 

三、快速入门 - 部署MySQL
①:快速安装
1.使用Docker安装,仅仅需要一步即可,在命令行输入下面的命令(建议采用CV大法):
docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  mysql
 

MySQL安装完毕!通过任意客户端工具即可连接到MySQL
大家可以发现,当我们执行命令后,Docker做的第一件事情,是去自动搜索并下载了MySQL,然后会自动运行MySQL,我们完全不用插手,是不是非常方便。
而且,这种安装方式你完全不用考虑运行的操作系统环境,它不仅仅在CentOS系统是这样,在Ubuntu系统、macOS系统、甚至是装了WSL的Windows下,都可以使用这条命令来安装MySQL。
 要知道,不同操作系统下其安装包、运行环境是都不相同的!如果是手动安装,必须手动解决安装包不同、环境不同的、配置不同的问题!
而使用Docker,这些完全不用考虑。就是因为Docker会自动搜索并下载MySQL。注意:这里下载的不是安装包,而是镜像。镜像中不仅包含了MySQL本身,还包含了其运行所需要的环境、配置、系统级函数库。因此它在运行时就有自己独立的环境,就可以跨系统运行,也不需要手动再次配置环境了。这套独立运行的隔离环境我们称为容器。
 说明:
- 镜像:英文是image
 - 容器:英文是container
 
因此,Docker安装软件的过程,就是自动搜索下载镜像,然后创建并运行容器的过程。
Docker官方提供了一个专门管理、存储镜像的网站,并对外开放了镜像上传、下载的权利。Docker官方提供了一些基础镜像,然后各大软件公司又在基础镜像基础上,制作了自家软件的镜像,全部都存放在这个网站。这个网站就成了Docker镜像交流的社区:
https://hub.docker.com/

②:小结
Docker本身包含一个后台服务,我们可以利用Docker命令告诉Docker服务,帮助我们快速部署指定的应用。Docker服务部署应用时,首先要去搜索并下载应用对应的镜像,然后根据镜像创建并允许容器,应用就部署完成了。

③:命令解读
利用Docker快速的安装了MySQL,非常的方便,不过我们执行的命令到底是什么意思呢?
docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  mysql
 
解读:
docker run -d:创建并运行一个容器,-d则是让容器以后台进程运行--name mysql: 给容器起个名字叫mysql,你可以叫别的-p 3306:3306: 设置端口映射。
- 容器是隔离环境,外界不可访问。但是可以将宿主机端口映射容器内到端口,当访问宿主机指定端口时,就是在访问容器内的端口了。
 - 容器内端口往往是由容器内的进程决定,例如
 MySQL进程默认端口是3306,因此容器内端口一定是3306;而宿主机端口则可以任意指定,一般与容器内保持一致。- 格式:
 -p 宿主机端口:容器内端口,示例中就是将宿主机的3306映射到容器内的3306端口-e TZ=Asia/Shanghai: 配置容器内进程运行时的一些参数
- 格式:
 -e KEY=VALUE,KEY和VALUE都由容器内进程决定- 案例中,
 TZ=Asia/Shanghai是设置时区;MYSQL_ROOT_PASSWORD=123是设置MySQL默认密码mysql: 设置镜像名称,Docker会根据这个名字搜索并下载镜像
- 格式:
 REPOSITORY:TAG,例如mysql:8.0,其中REPOSITORY可以理解为镜像名,TAG是版本号- 在未指定
 TAG的情况下,默认是最新版本,也就是mysql:latest
镜像的名称不是随意的,而是要到DockerRegistry中寻找,镜像运行时的配置也不是随意的,要参考镜像的帮助文档,这些在DockerHub网站或者软件的官方网站中都能找到。
如果我们要安装其它软件,也可以到DockerRegistry中寻找对应的镜像名称和版本
四、基础 - 命令
①:常见命令
首先我们来学习Docker中的常见命令,可以参考官方文档:
https://b11et3un53m.feishu.cn/wiki/MWQIw4Zvhil0I5ktPHwcoqZdnec#V25KdqFzrobjOtx2Oxqct6uOn6g
01:命令介绍
其中,比较常见的命令有:
| 命令 | 说明 | 文档地址 | 
|---|---|---|
| docker pull | 拉取镜像 | docker pull | 
| docker push | 推送镜像到DockerRegistry | docker push | 
| docker images | 查看本地镜像 | docker images | 
| docker rmi | 删除本地镜像 | docker rmi | 
| docker run | 创建并运行容器(不能重复创建) | docker run | 
| docker stop | 停止指定容器 | docker stop | 
| docker start | 启动指定容器 | docker start | 
| docker restart | 重新启动容器 | docker restart | 
| docker rm | 删除指定容器 | docs.docker.com | 
| docker ps | 查看容器 | docker ps | 
| docker logs | 查看容器运行日志 | docker logs | 
| docker exec | 进入容器 | docker exec | 
| docker save | 保存镜像到本地压缩文件 | docker save | 
| docker load | 加载本地压缩文件到镜像 | docker load | 
| docker inspect | 查看容器详细信息 | docker inspect | 
用一副图来表示这些命令的关系:

补充:
 默认情况下,每次重启虚拟机我们都需要手动启动Docker和Docker中的容器。通过命令可以实现开机自启:
# Docker开机自启
systemctl enable docker
# Docker容器开机自启
docker update --restart=always [容器名/容器id]
 
02:示例(安装Nginx)
# 第1步,去DockerHub查看nginx镜像仓库及相关信息
# 第2步,拉取Nginx镜像
docker pull nginx
# 第3步,查看镜像
docker images
# 结果如下:
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx        latest    605c77e624dd   16 months ago   141MB
mysql        latest    3218b38490ce   17 months ago   516MB
# 第4步,创建并运行Nginx容器
docker run -d --name nginx -p 80:80 nginx
# 第5步,查看运行中容器
docker ps
# 也可以加格式化方式访问,格式会更加清爽
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 第6步,访问网页,地址:http://虚拟机地址
# 第7步,停止容器
docker stop nginx
# 第8步,查看所有容器
docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 第9步,再次启动nginx容器
docker start nginx
# 第10步,再次查看容器
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 第11步,查看容器详细信息
docker inspect nginx
# 第12步,进入容器,查看容器内目录
docker exec -it nginx bash
# 或者,可以进入MySQL
docker exec -it mysql mysql -uroot -p
# 第13步,删除容器
docker rm nginx
# 发现无法删除,因为容器运行中,强制删除容器
docker rm -f nginx
 
03:命令别名
给常用Docker命令起别名,方便我们访问:
# 修改/root/.bashrc文件
vi /root/.bashrc
内容如下:
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
alias dis='docker images'
# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
 
然后,执行命令使别名生效
source /root/.bashrc
 
②:数据卷
容器是隔离环境,容器内程序的文件、配置、运行时产生的容器都在容器内部,我们要读写容器内的文件非常不方便。大家思考几个问题:
- 如果要升级MySQL版本,需要销毁旧容器,那么数据岂不是跟着被销毁了?
 - MySQL、Nginx容器运行后,如果我要修改其中的某些配置该怎么办?
 - 我想要让Nginx代理我的静态资源怎么办?
 
因此,容器提供程序的运行环境,但是程序运行产生的数据、程序运行依赖的配置都应该与容器解耦。
01:什么是数据卷
数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。
 以Nginx为例,我们知道Nginx中有两个关键的目录:
- html:放置一些静态资源
 - conf:放置配置文件
 
如果我们要让Nginx代理我们的静态资源,最好是放到html目录;如果我们要修改Nginx的配置,最好是找到conf下的nginx.conf文件。
但遗憾的是,容器运行的Nginx所有的文件都在容器内部。所以我们必须利用数据卷将两个目录与宿主机目录关联,方便我们操作。如图:
 
在上图中:
- 我们创建了两个数据卷:
conf、html - Nginx容器内部的
conf目录和html目录分别与两个数据卷关联。 - 而数据卷conf和html分别指向了宿主机的
/var/lib/docker/volumes/conf/_data目录和/var/lib/docker/volumes/html/_data目录 
这样以来,容器内的conf和html目录就 与宿主机的conf和html目录关联起来,我们称为挂载。此时,我们操作宿主机的/var/lib/docker/volumes/html/_data就是在操作容器内的/usr/share/nginx/html/_data目录。只要我们将静态资源放入宿主机对应目录,就可以被Nginx代理了。
小提示:
/var/lib/docker/volumes这个目录就是默认的存放所有容器数据卷的目录,其下再根据数据卷名称创建新目录,格式为/数据卷名/_data。
为什么不让容器目录直接指向宿主机目录呢?
- 因为直接指向宿主机目录就与宿主机强耦合了,如果切换了环境,宿主机目录就可能发生改变了。由于容器一旦创建,目录挂载就无法修改,这样容器就无法正常工作了。
 - 但是容器指向数据卷,一个逻辑名称,而数据卷再指向宿主机目录,就不存在强耦合。如果宿主机目录发生改变,只要改变数据卷与宿主机目录之间的映射关系即可。
 
不过,我们通过由于数据卷目录比较深,不好寻找,通常我们也允许让容器直接与宿主机目录挂载而不使用数据卷。
02:数据卷命令
数据卷的相关命令有:
| 命令 | 说明 | 文档地址 | 
|---|---|---|
| docker volume create | 创建数据卷 | docker volume create | 
| docker volume ls | 查看所有数据卷 | docs.docker.com | 
| docker volume rm | 删除指定数据卷 | docs.docker.com | 
| docker volume inspect | 查看某个数据卷的详情 | docs.docker.com | 
| docker volume prune | 清除数据卷 | docker volume prune | 
注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建。
03:示例(创建nginx数据卷)
- 准备工作 因为运行中无法创建数据卷(所以先删除运行中的容器)
 
# 查看运行中的容器
docker ps
# 删除正则运行的nginx
docker rm -f nginx
 

2.开始创建数据卷
# 1.首先创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
 

3.查看数据卷及详情
# 2.然后查看数据卷
docker volume ls
# 结果
DRIVER    VOLUME NAME
local     29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f
local     html
# 3.查看数据卷详情
docker volume inspect html
# 结果
[
    {
        "CreatedAt": "2024-05-17T19:57:08+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/html/_data",
        "Name": "html",
        "Options": null,
        "Scope": "local"
    }
]
# 4.查看/var/lib/docker/volumes/html/_data目录
ll /var/lib/docker/volumes/html/_data
# 可以看到与nginx的html目录内容一样,结果如下:
总用量 8
-rw-r--r--. 1 root root 497 12月 28 2021 50x.html
-rw-r--r--. 1 root root 615 12月 28 2021 index.html
 

4.修改index.html内容 并查看效果
# 5.进入该目录,并随意修改index.html内容
cd /var/lib/docker/volumes/html/_data
vi index.html
# 6.打开页面,查看效果
# 7.进入容器内部,查看/usr/share/nginx/html目录内的文件是否变化
docker exec -it nginx bash
 


04:示例(创建MySQL数据卷)
# 如果没有创建 先创建 mysql容器(我们先不指定挂载目录)
docker run -d --name mysql -p 3306:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123456 mysql:tag
# 指定MySQL的挂载目录(今天我们先不用这个,我们先不指定挂载目录看看会不会有默认的挂载目录)
docker run -d --name mysql -v mysql:/var/lib/mysql -p 3306:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123456 mysql:tag
# 1.查看MySQL容器详细信息
docker inspect mysql
 
我们关注两部分内容,第一是.Config.Volumes部分:
# 关注其中.Config.Volumes部分和.Mounts部分
{
  "Config": {
    // ... 略
    "Volumes": {
      "/var/lib/mysql": {}
    }
    // ... 略
  }
}
 
可以发现这个容器声明了一个本地目录,需要挂载数据卷,但是数据卷未定义。这就是匿名卷。
 然后,我们再看结果中的.Mounts部分:
{
  "Mounts": [
    {
      "Type": "volume",
      "Name": "29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f",
      "Source": "/var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data",
      "Destination": "/var/lib/mysql",
      "Driver": "local",
    }
  ]
}
 
可以发现,其中有几个关键属性:
- Name:数据卷名称。由于定义容器未设置容器名,这里的就是匿名卷自动生成的名字,一串hash值。
 - Source:宿主机目录
 - Destination : 容器内的目录
上述配置是将容器内的/var/lib/mysql这个目录,与数据卷29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f挂载。于是在宿主机中就有了/var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data这个目录。这就是匿名数据卷对应的目录,其使用方式与普通数据卷没有差别。 
接下来,可以查看该目录下的MySQL的data文件:
ls -l /var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data
 
注意:每一个不同的镜像,将来创建容器后内部有哪些目录可以挂载,可以参考DockerHub对应的页面
05:挂载本地目录或文件
可以发现,数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:
# 挂载本地目录
-v 本地目录:容器内目录
# 挂载本地文件
-v 本地文件:容器内文件
 
注意:本地目录或文件必须以 / 或 ./开头,如果直接以名字开头,会被识别为数据卷名而非本地目录名。
例如:
-v mysql:/var/lib/mysql # 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
-v ./mysql:/var/lib/mysql # 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录
 
示例,删除并重新创建mysql容器,并完成本地目录挂载:
- 挂载
/root/mysql/data到容器内的/var/lib/mysql目录 - 挂载
/root/mysql/init到容器内的/docker-entrypoint-initdb.d目录(初始化的SQL脚本目录) - 挂载
/root/mysql/conf到容器内的/etc/mysql/conf.d目录(这个是MySQL配置文件目录)
在课前资料中已经准备好了mysql的init目录和conf目录: 

以及对应的初始化SQL脚本和配置文件:

 
其中,hm.cnf主要是配置了MySQL的默认编码,改为utf8mb4;
我们直接将整个mysql目录上传至虚拟机的/root目录下:

接下来,我们演示本地目录挂载:
# 1.删除原来的MySQL容器
docker rm -f mysql
# 2.进入root目录
cd ~
# 3.创建并运行新mysql容器,挂载本地目录
docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  -v ./mysql/data:/var/lib/mysql \
  -v ./mysql/conf:/etc/mysql/conf.d \
  -v ./mysql/init:/docker-entrypoint-initdb.d \
  mysql
# 4.查看root目录,可以发现~/mysql/data目录已经自动创建好了
ls -l mysql
# 结果:
总用量 4
drwxr-xr-x. 2 root    root   20 5月  19 15:11 conf
drwxr-xr-x. 7 polkitd root 4096 5月  19 15:11 data
drwxr-xr-x. 2 root    root   23 5月  19 15:11 init
# 查看data目录,会发现里面有大量数据库数据,说明数据库完成了初始化
ls -l data
# 5.查看MySQL容器内数据
# 5.1.进入MySQL
docker exec -it mysql mysql -uroot -p123
# 5.2.查看编码表
show variables like "%char%";
# 5.3.结果,发现编码是utf8mb4没有问题
+--------------------------+--------------------------------+
| Variable_name            | Value                          |
+--------------------------+--------------------------------+
| character_set_client     | utf8mb4                        |
| character_set_connection | utf8mb4                        |
| character_set_database   | utf8mb4                        |
| character_set_filesystem | binary                         |
| character_set_results    | utf8mb4                        |
| character_set_server     | utf8mb4                        |
| character_set_system     | utf8mb3                        |
| character_sets_dir       | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+
# 6.查看数据
# 6.1.查看数据库
show databases;
# 结果,hmall是黑马商城数据库
+--------------------+
| Database           |
+--------------------+
| hmall              |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
# 6.2.切换到hmall数据库
use hmall;
# 6.3.查看表
show tables;
# 结果:
+-----------------+
| Tables_in_hmall |
+-----------------+
| address         |
| cart            |
| item            |
| order           |
| order_detail    |
| order_logistics |
| pay_order       |
| user            |
+-----------------+
# 6.4.查看address表数据
+----+---------+----------+--------+----------+-------------+---------------+-----------+------------+-------+
| id | user_id | province | city   | town     | mobile      | street        | contact   | is_default | notes |
+----+---------+----------+--------+----------+-------------+---------------+-----------+------------+-------+
| 59 |       1 | 北京     | 北京   | 朝阳区    | 13900112222 | 金燕龙办公楼   | 李佳诚    | 0          | NULL  |
| 60 |       1 | 北京     | 北京   | 朝阳区    | 13700221122 | 修正大厦       | 李佳红    | 0          | NULL  |
| 61 |       1 | 上海     | 上海   | 浦东新区  | 13301212233 | 航头镇航头路   | 李佳星    | 1          | NULL  |
| 63 |       1 | 广东     | 佛山   | 永春      | 13301212233 | 永春武馆       | 李晓龙    | 0          | NULL  |
+----+---------+----------+--------+----------+-------------+---------------+-----------+------------+-------+
4 rows in set (0.00 sec)
                















![[Docker] Dockerfile](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Fpics%2Fdockerfile2.png&pos_id=img-ZmxxhkqE-1705327420998)


