Docker之——入门、数据卷、网络管理、自定义镜像、阿里镜像仓库服务

直击Docker的作用

1
技术存在的必然性,一个技术的存在都是为了解决指定的问题.

image-20210610090947848

image-20210628090441036

Docker介绍

概述

1
2
3
4
5
6
7
8
9
10
11
12
13
#什么是镜像?
将Linux程序基于运行环境打包,就是镜像,特征:
只读
分层,每一层都基于前一层,层称为Layer
#什么是容器?
容器是镜像运行的一个实例。
是将镜像做只读拷贝后创建一层可写的Layer层,然后创建独立内存、网络等空间并运行。
特征:
容器是宿主机的一个独立进程。
多个容器间相互独立
容器操作不影响镜像
#Docker作用?
软件或程序环境迁移

image-20210628101716586

Docker镜像服务

1
2
3
4
5
6
7
8
9
镜像服务: 
管理存放镜像的位置,用于共享镜像文件
官方: https://hub.docker.com/
阿里: https://www.aliyun.com/
仓库:
每一种软件对应一个仓库,在仓库中存放有当前软件不同版本的各个镜像
不同版本使用tag区分
eg:
mysql:5.6 mysql:5.7.25

image-20210610102444848

Docker架构

image-20210330102632713

Docker安装

1.卸载旧版docker

1
2
3
4
5
6
7
8
9
10
11
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce

2.安装docker依赖

1
2
3
4
# 安装基本依赖库
yum install -y yum-utils device-mapper-persistent-data lvm2 --skip-broken
# 更新XFS文件系统管理工具
yum update xfsprogs -y

3.安装docker

1
2
3
4
5
6
7
8
9
# 更新本地镜像源
yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
# 更新镜像源缓存
sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
# 更新镜像源缓存
yum makecache fast
# 安装Docker
yum install -y docker-ce

4.启动docker服务

1
2
3
4
5
6
7
8
9
10
# 查看防火墙状态
systemctl status firewalld
# 关闭本地防火墙
systemctl stop firewalld
# 禁止开机启动防火墙
systemctl disable firewalld
# 启动docker服务
systemctl start docker
# 设置开机自启动
systemctl enable docker

5.配置镜像加速

Docker官方镜像仓库网速较差,我们需要设置国内镜像:

​ 参考阿里云的镜像加速文档:阿里云镜像管理地址(https://www.aliyun.com/)

1
2
3
4
5
6
7
8
9
10
11
# 创建配置文件
mkdir -p /etc/docker
# 配置镜像加速地址 (填写自己阿里云下的镜像加速地址)
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://62gzcr8n.mirror.aliyuncs.com"]
}
EOF
# 重新加载配置并重启Docker
systemctl daemon-reload
systemctl restart docker

image-20210610112711816

image-20210610112740492

image-20210329193827827

Docker相关命令

镜像操作

相关命令

1
2
3
4
5
6
7
8
9
10
11
12
操作Docker镜像的常用命令有:
docker --help : 查询帮助
docker xxx --help : 查询xxx命令的作用和使用方式★★★★★
docker search 镜像名称 : 在镜像仓库搜索镜像
docker pull 镜像名称:tag : 从镜像仓库拉取镜像
docker push : 将本地镜像推送到远程镜像库
docker images : 查看本地镜像列表
docker rmi 镜像名称:tag : 删除本地镜像
docker save -o xxx.tar 镜像名1 镜像名2 : 保存镜像为一个tar文件
docker load -i xxx.tar : 加载本地tar文件中包含的镜像
docker build : 构建一个镜像(我们自己制作镜像)
docker tag 镜像名:tag 新镜像名:tag : 给镜像打新标签(重命名)

练习1:

需求:从镜像仓库中拉取一个nginx镜像

1
# 1.首先去镜像仓库搜索nginx镜像,比如DockerHub: https://hub.docker.com/

image-20210329195043716

1
2
3
4
# 2.根据镜像名称搜索,相关镜像对应的拉取命令
docker pull nginx
# 3.查看拉取到的镜像
docker images

练习2

需求:去DockerHub搜索并拉取一个Redis镜像

1
2
3
4
# 步骤一:去DockerHub搜索redis镜像
# 步骤二:查看Redis镜像的名称和版本
# 步骤三:利用docker pull命令拉取镜像
docker pull redis

练习3

需求:将Redis镜像打包为一个新镜像myredis:1.0,并导出到本地磁盘

1
2
3
4
5
6
# 1.查询docker tag命令的作用和语法
docker tag --help
# 2.使用docker tag打包镜像
docker tag redis:latest myredis:1.0
# 3.使用docker save将镜像打入到tar包中,便于传播
docker save -o myredis.tar myredis:1.0
1
docker load -i 文件名.tar

容器操作

1
将一个镜像运行起来,就可以得到镜像对应的容器.

相关命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
操作Docker容器的常用命令有:
docker run --name 容器名称 -p 80:80 -d 镜像名称 : 创建并运行容器
--name 容器名称
--restart=always 随容器启动而启动
-p 端口映射
-d 后台运行
docker stop 容器名称 :停止容器
docker start 容器名称:启动容器
docker ps :查看运行中的容器
docker ps -a : 查看所有容器
docker rm 容器名称:删除容器
docker rm -f 容器名称 : 强制删除容器(无论运行与否)
docker exec :执行容器内的指定指令
docker commit :提交一个容器为镜像

案例1

需求:创建并运行一个Nginx容器

1
2
3
4
5
6
7
8
9
10
# 1.创建并运行一个Nginx容器的命令为:
docker run --name mn -p 80:80 -d nginx
# 命令解读:
# docker run :创建并运行一个容器
# --name : 给容器起一个名字,比如叫做mn
# -p :端口映射,例如:-p 8080:80,把容器的80端口映射到宿主机的8080端口
# -d:后台运行容器
# nginx:镜像名称
# 2.访问虚拟机页面 http://[你的虚拟机IP]
192.168.190.149:80

案例2(了解)

需求:进入Nginx容器,修改HTML文件内容,添加“传智播客欢迎您”

1
2
3
4
5
6
# 创建并运行nginx容器
docker run \
--name mn \
-p 80:80 \
-d \
nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1.进入nginx容器的命令为
docker exec -it mn bash
#命令解读:
# docker exec :进入容器内部执行
# -it : 给当前进入的容器创建一个Linux命令行终端,允许我们通过命令行与容器交互
# mn :要进入的容器的名称
# bash:进入容器后执行的命令,bash是一个linux终端交互语言格式
# 2.进入nginx的HTML所在目录 /usr/share/nginx/html (此目录去官网查找)
cd /usr/share/nginx/html
# 3.修改index.html的内容
sed -i 's#Welcome to nginx#传智播客欢迎您#g' index.html
sed -i 's#<head>#<head><meta charset="utf-8">#g' index.html
# 4.退出,容器的客户端
exit

案例3

运行一个redis容器,并且支持数据持久化

1
2
3
4
#1.到DockerHub搜索Redis镜像
#2.查看Redis镜像文档中的帮助信息
#3.利用docker run 命令运行一个Redis容器
docker run --name redis -p 6379:6379 -d redis redis-server --appendonly yes
1
2
3
4
redis:
持久化机制:
RDB: 默认开启的(快照机制)
AOF: 手动配置

案例4

进入redis容器,并执行redis-cli客户端命令,存入num=666

1
2
3
4
5
6
#1.进入redis容器
docker exec -it 容器名称 bash
#2.执行redis-cli客户端命令
redis-cli
#3.设置数据num=666
set num 666

数据卷

概述

image-20210330002905638

image-20210330002928724

image-20210330003000678

操作数据卷命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
数据卷是一个虚拟的概念,一个数据卷指向宿主机上的一个文件夹:
每创建一个数据卷就会在/var/lib/docker/volumes目录下新建一个对应的文件夹
#创建数据卷
docker volume create 数据卷名称
#查询数据卷信息
docker volume inspect 数据卷名称
#查询所有数据卷基本信息
docker volume ls
#删除未使用的数据卷
docker volume prune
#删除数据卷
docker volume rm 数据卷名称
#挂载数据卷 (建立数据卷与容器目录的对应关系)
docker run \
--name mn \
-v html:/usr/share/nginx/html \
-p 8080:80 \
-d \
nginx
# 说明:
# docker run :就是创建并运行容器
# --name mn :给容器起个名字叫mn
# -v html:/root/htm :把html数据卷挂载到容器内的/root/html这个目录中
# -p 8080:80 :把宿主机的8080端口映射到容器内的80端口
# nginx :镜像名称

案例1

创建一个数据卷,并查看数据卷在宿主机的目录位置

1
2
3
4
5
6
#1.创建数据卷
docker volume create html
#2.查看所有数据卷
docker volume ls
#3.查看数据卷详细信息
docker volume inspect html

案例2

创建一个nginx容器,将容器内的HTML目录挂载到数据卷HTML上,并修改HTML卷中的index.html内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#1.去DockerHub的Nginx页面查看HTML目录在容器内的位置
#2.创建容器并挂载数据卷到容器内的HTML目录
docker run \
--name mn \
-v html:/usr/share/nginx/html \
-p 80:80 \
-d \
nginx
#3.进入HTML数据卷所在位置,并修改HTML内容
# 查看html数据卷的位置
docker volume inspect html
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件
vi index.html

案例3

挂载文件

挂载到宿主机文件覆盖nginx容器内配置文件,并修改内容。实现一个方向代理效果:
http://localhost:80/s 请求代理到 http://www.baidu.com/s

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#1.去DockerHub的Nginx页面查看配置文件在容器内的位置
容器中配置文件位置: /etc/nginx/nginx.conf
#2.在宿主机的/tmp目录新建一个nginx.conf文件,编写反向代理逻辑
cd /tmp
touch nginx.conf
参考下面配置
#3.创建nginx容器,挂载/tmp/nginx.conf到容器内的nginx配置文件
# 删除旧容器
docker rm -f mn
# 创建新容器,挂载nginx.conf文件
docker run \
--name mn \
-v html:/usr/share/nginx/html \
-v /tmp/nginx.conf:/etc/nginx/nginx.conf \
-p 80:80 \
-d \
nginx
#4.在浏览器查看访问:http://192.168.190.145s,这里的192.168.190.145替换为你的IP地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
worker_processes  1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /s {
proxy_pass https://www.baidu.com;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}

网络管理

当我们要部署基于docker的微服务群时,往往会需要容器之间互相连接。这时就需要用到Docker中的网络配置了

1
2
集群: 多台服务器做相同的事情
分布式: 多台服务器做不同的事情,在共同协作下完成一个具体的业务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#创建一个名为my-net的网络(名称可以自定义)
docker network create my-net
#将指定容器加入到my-net网络
docker network connet my-net 容器名称
#将一个容器退出指定的网络
docker network disconnect 网络名称 容器名称
#查看网络的详细信息,如IP网段等
docker network inspect 网络名称
#列出所有的网络
docker network ls
#删除所有未使用的网络
docker network prune
#删除所有指定的网络
docker network rm 网络名

案例1

创建一个网络my-net,并且将之前的nginx容器加入网络中

1
2
3
4
5
6
7
8
#1.创建一个名为my-net的网络
docker network create my-net
#2.查看创建的网络
docker network ls
#3.查看网络加入语法
docker network connect --help
#4.将nginx容器加入网络
docker network connect my-net mn

案例2

基于busyBox镜像创建并运行一个容器,加入my-net网络,测试与nginx容器的网络是否畅通

1
2
3
4
5
6
7
8
9
10
#1.基于BusyBox镜像创建容器,并使用--network参数加入my-net网络
docker run -it --rm --name busybox1 --network my-net busybox sh
# 命令说明:
# -it 运行容器并保持一个可交互的shell终端
# --rm 容器退出时,自动删除容器
# --network my-net 连接到my-net网络
# busybox 是一个测试用的简单容器
# sh 终端交互方式采用sh方式
#2.通过ping命令测试网络连接,同一个网络中的容器可以用容器名互联
ping mn
1
2
3
小结:
创建容器时的 --network 参数允许我们直接加入一个网络中
互联的容器可以利用 容器名互相访问

常用镜像

安装mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
==========================
# 关闭或禁用Linux上已经安装的mysql,因为端口被占用了
# 关闭
systemctl stop [mysql/mysqld]
# 禁用
systemctl disable [mysql/mysqld]
===========================
#1.拉取或从本地加载MySQL镜像。因为镜像文件较大,推荐从本地加载
docker pull mysql:5.6
#2.创建两个数据卷mysql-data、mysql-conf
docker volume create mysql-data
docker volume create mysql-conf
#3.进入mysql-conf数据卷所在目录,新建一个my.cnf文件
# 查看数据卷对应目录
docker volume inspect mysql-conf
# 进入
cd /var/lib/docker/volumes/mysql-conf/_data
# 创建核心配置文件 my.cnf(Linux环境下mysql的核心配置文件)
touch my.cnf
#4.编辑my.cnf文件,设置mysql编码等配置属性
--------------
# mysql配置文件内容:
[mysqld]
skip-name-resolve
character_set_server=utf8
datadir=/var/lib/mysql
server-id=1000
---------------
#5.创建并运行容器。【具体参数及挂载目录参考DockerHub网站的说明】
docker run \
--name mysql \
-p 3306:3306 \
-d \
-e MYSQL_ROOT_PASSWORD=root \
-v mysql-data:/var/lib/mysql \
-v mysql-conf:/etc/mysql/conf.d \
--privileged \
mysql:5.6

DockerFile自定义镜像

dockerFile概述

回顾之前镜像原理的章节,我们可以了解到,镜像的本质是一层层的Layer。基于一个rootfs这个基础的Layer定制每一层所添加的配置、文件,要执行的操作等。
如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么这个脚本就是 Dockerfile。
因此,Dockerfile就是一个描述镜像构建的文件。其中一定会有一个基础镜像(BaseImage),然后在基础镜像上每完成一次修改或安装命令,就形成一层新的Layer,直到镜像构建完成。

常用命令(参考)

命令作用
FROM image_name:tag定义了使用哪个基础镜像启动构建流程
MAINTAINER user_name声明镜像的创建者
ENV key value设置环境变量 (可以写多条)
RUN command是Dockerfile的核心部分(可以写多条)
ADD source_dir/file dest_dir/file将宿主机的文件复制到容器内,如果是一个压缩文件,将会在复制后自动解压
COPY source_dir/file dest_dir/file和ADD相似,但是如果有压缩文件并不能解压
WORKDIR path_dir设置工作目录
EXPOSE port1 prot2用来指定端口,使容器内的应用可以通过端口和外界交互
CMD argument在构建容器时使用,会被docker run 后的argument覆盖
ENTRYPOINT argument入口点,容器启动后会执行的命令,比如启动mysql。效果和CMD相似,但是并不会被docker run指定的参数覆盖
VOLUME将本地文件夹或者其他容器的文件挂载到容器中

案例1

基于Nginx镜像构建一个新镜像,修改其中的index.html文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#1.在一个空文件夹新建一个文件,命名为Dockerfile,内容如下
# 创建空文件夹
mkdir /tmp/nginxfile
# 进入空文件夹
cd /tmp/nginxfile
# 创建Dockerfile文件
touch Dockerfile
-----------------
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
-----------------
#2.执行命令,构建镜像
docker build -t mynginx:1.0 .
#3.删除已经存在的镜像
docker rm -f mn
#4.创建并运行容器
docker run --name mn -p 80:80 -d mynginx:1.0
1
2
3
4
这个Dockerfile非常简单,就两个命令:FROM和RUN
FROM:就是基础镜像,是Dockerfile中必备的,我们构建镜像没必要从rootfs开始,可以基于已有镜像基础上去构建自己的镜像,节省很多时间
RUN:像 Shell 脚本一样可以执行命令,这里是直线echo 命令将'<h1>Hello, Docker!</h1>'写入容器的index.html文件中,那么nginx的欢迎页面内容就被修改了。
这个Dockerfile描述的镜像就比nginx官方镜像多了一层Layer,定制了nginx欢迎页面。

案例2

从CentOS定制nginx镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 基于centos7安装
FROM centos:7

#拷贝nginx的安装包
COPY nginx-1.10.3.tar.gz /usr/local/src

# 环境变量
ENV NGX_DIR=/opt/nginx

#安装依赖、解压、编译、安装
RUN yum -y install pcre pcre-devel zlib zlib-devel openssl openssl-devel gcc tar \
&& cd /usr/local/src \
&& tar -xvf nginx-1.10.3.tar.gz \
&& rm -rf nginx-1.10.3.tar.gz \
&& cd nginx-1.10.3 \
&& ./configure --prefix=$NGX_DIR --sbin-path=/usr/bin/nginx \
&& make \
&& make install

#设置数据挂载目录以及工作目录 匿名卷:当前卷默认不存在,当容器创建时,再生成当前卷
VOLUME $NGX_DIR

#容器启动后执行该命令
ENTRYPOINT ["nginx", "-g", "daemon off;"]

案例3★

基于java:8-alpine镜像,将一个Java项目构建为镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1.新建一个空的目录,然后在目录中新建一个文件,命名为Dockerfile
# 2.拷贝课前资料提供的app.jar到这个目录中
# 3.编写Dockerfile文件:
touch Dockerfile
--------------------
# 基于java:8-alpine作为基础镜像
FROM java:8-alpine
# 将app.jar拷贝到镜像中作为新Layer层
COPY app.jar /tmp/app.jar
# 编写入口ENTRYPOINT
ENTRYPOINT ["java", "-jar", "/tmp/app.jar"]
----------------------
# 4.使用docker build命令构建镜像
docker build -t web:1.0 .
# 5.使用docker run创建容器并允许
docker run --name web -p 9090:9090 -d web:1.0

Docker镜像服务

1
2
3
4
之前当我们需要使用镜像时都是从阿里云上或DockerHub上下载.
也可以自己通过Dockerfile做镜像.
我们能不能将我们自己做的镜像上传到阿里云或DockerHub?

阿里云镜像服务

1
2
3
4
镜像服务地址: https://cr.console.aliyun.com/
1.找到个人实例
2.创建命名空间(阿里云域名/你的命名空间)
3.设置登录的密码

image-20210610174834160

私有镜像仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 安装镜像仓库镜像
docker run -d \
--restart=always \
--name registry \
-p 5000:5000 \
-v registry-data:/var/lib/registry \
registry
# 镜像仓库默认会自动启动,如何查看镜像仓库中有哪些镜像呢?
访问: http://你的宿主机地址:5000/v2/_catalog
# 配置允许指定ip向本地镜像仓库提交镜像
# 打开要修改的文件
vi /etc/docker/daemon.json
# 添加内容: json格式,需要加 逗号
"insecure-registries":["http://宿主机ip地址:5000"]
# 重加载
systemctl daemon-reload
# 重启docker
systemctl restart docker
# 推送
docker push 宿主机ip地址:5000/nginx:1.0
# 拉取
docker pull 宿主机ip地址:5000/nginx:1.0
# 镜像若想存放到本地镜像仓库,需满足本地仓库的格式
格式: docker tag nginx:latest 宿主机ip地址:5000/nginx:1.0

总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Docker(码头工人): 容器化管理技术
相关名词:
镜像: 对现有的环境和程序进行打包,打好的包叫做镜像.
在镜像中进行分层,现有层需要基于前一层,对前一层做了只读拷贝
底层: 文件系统 rootfs
中间层: 软件安装层
顶层: 软件入口
容器: 根据镜像创建对应的运行环境
将镜像做了只读拷贝后,提供了一个可写层,在可写层中可以操作这个软件
镜像服务:
本质上就是一个存放有镜像文件的远程仓库,在该仓库中提供了无数个可用的镜像文件
镜像仓库: 一款软件对应一个镜像仓库
镜像文件: xxx:tag
xxx: 软件的名称
tag: 软件的版本号
Docker工作原理:
Docker是使用go语言开发的一款C/S架构的软件.使用之前必须先启动docker服务.
通过在客户端发送docker命令给服务器,服务器解析后,完成对应的功能
systemctl start docker : 启动docker服务
systemctl stop/restart/status docker
命令常用方式: 命令提示
docker --help : 查询帮助
docker xxx --help : 查询xxx命令的作用和使用方式★★★★★
操作Docker镜像的常用命令有:
docker search 镜像名 : 在镜像仓库搜索镜像
docker pull 镜像名称 : 从镜像仓库拉取镜像
docker push 镜像名称 : 将本地镜像推送到远程镜像库
docker images : 查看本地镜像列表
docker rmi 镜像名称:tag : 删除本地镜像
docker save -o xxx.tar 镜像名1 镜像名2 : 保存一个或多个镜像到一个tar文件
docker load -i xxx.tar : 加载本地tar文件中包含的镜像
docker build : 构建一个镜像
docker tag : 给镜像打新标签(重命名)
docker tag nginx mynginx:1.0
操作Docker容器的常用命令有:
docker run --name mn -p 80:80 -d 镜像名称 : 创建并运行容器
--name 容器名称
-p 端口映射
-d 后台运行
--restart=always 随容器启动而启动
docker stop 容器名称:停止容器
docker start 容器名称:启动容器
docker ps :查看运行中的容器
docker ps -a : 查看所有容器
docker rm 容器名称:删除容器(删除未运行的容器)
docker rm -f 容器名称 : 强制删除容器(无论运行与否)
docker exec :执行容器内的指定指令
docker commit :提交一个容器为镜像