Docker

Docker

docker中文网:https://vuepress.mirror.docker-practice.com/

1、 什么是Docker

什么是Docker

官方介绍:

We have a complete container solution for you no matter who you are and where you are on your containerization journey

我们为你提供了一个完整的容器解决方案,不管你是谁,不管你在哪,你都可以开启你的容器旅程。

Docker就是容器技术

docker的作用
  1. 在开发的时候,在本地测试环境可以跑,生产环境跑不起来。

    我们在一个Java web应用程序涉及很多东西,比如jdk,tomcat,mysql等软件环境。当这些软件的某一项版本不一致时候,可能就会导致应用程序跑不起来。Docker则将程序以及使用软件环境直接打包在一起,无论在哪个机器上保证了环境的一致。

    一致的运行环境,更轻松的迁移

  2. 服务器自己的程序挂了,结果发现是别人的程序出了问题把内存吃完了,自己程序因为内存不够挂了。

    这种也是一种常见的情况,你的服务器会跟公司其他人的程序共享一台服务器。所以不可避免受到其他程序的干扰。docker很好的解决了环境隔离的问题。

    对进程进行封装隔离,容器与容器之间互不影响,更高效的利用系统资源。

  3. 大量的流量,需要在多部署几十台服务器

    部署几十台服务器,可能服务器的环境还不是一致的。就会出现各种问题。如果用docker,我们只需要将程序打包到镜像,你要多少台服务器,极大提高了部署效率。

    通过镜像复制多个环境一致容器

docker与虚拟机的区别

docker和虚拟机区别

虚拟机的缺点:

  1. 虚拟机运行软件环境之前必须自身携带操作系统,本身很小的应用程序却因为携带了操作系统而变得非常大。很笨重。
  2. 通过虚拟机在资源调度上经过很多步骤。

docker的优势:

  1. docker是不携带操作系统的,所以docker的应用非常轻巧。
传统虚拟机 Docker容器
磁盘占用 几个GB到几十个GB 几十MB到几百MB
CPU内存占用 虚拟操作系统非常占用CPU和内存 Docker引擎占用极低
启动速度 几分钟 几秒
安装管理 需要专门的运维技术 安装、管理方便
应用部署 每次部署都耗时费力 第二次部署轻松便捷
耦合性 多个应用服务器安装到一起,容易互相影响 每个应用服务器一个容器,达到隔离
系统依赖 需要相同或相似的内核,Linux

2、 docker安装

通用所有的平台

在测试或开发环境中,Docker官方为了简化安装流程,提供了一套便捷的安装脚本,Centos系统上可以使用这套脚本,另外可以通过--mirror选项来使用国内镜像源进行安装。

执行这个命令后,脚本就会自动的将一切准备工作做好,并且把Docker的稳定版本安装在系统中。

脚本:

1
2
3
curl -fsSL get.docker.com -o get-docker.sh

sudo sh get-docker.sh --mirror Aliyun

3、docker的基本使用

查看docker版本
1
docker version
查看docker状态:
1
systemctl status docker
启动docker服务:
1
systemctl start docker
停止docker服务:
1
systemctl stop docker
重启docker服务:
1
systemctl restart docker
查看docker信息:
1
docker info
docker开机自启动
1
systemctl enable docker
建立docker组,并使用root用户
1
2
3
4
5
6
# 创建docker组
sudo groupadd docker
# 将当前用户加入docker组
sudo usermod -aG docker $USER
# 重启docker服务
systemctl restart docker

4、docker核心概念和核心架构图

1. 镜像 image

定义:一个镜像代表着一个软件。比如说mysql镜像、redis镜像、nginx镜像……

2.容器 container

定义:基于某个镜像运行一次就会生成一个实例,这个实例称为一个容器。

3. 仓库 repository

定义:用于存储docker中所有镜像的具体位置

远程仓库:docker在世界范围维护一个唯一的远程仓库

本地仓库:当前自己机器中下载镜像存储位置

Docker使用

例子:启动一个安装mysql 5.7 版本的容器

  1. 打开docker hub https://registry.hub.docker.com/

  2. 选择mysql官方镜像,并选择版本5.7

Docker Hub使用

  1. 启动docker

    1
    systemctl start docker
  2. 拉取docker

    1
    docker pull mysql:5.7

    拉取镜像 - 1

拉取镜像 - 2

5、docker镜像相关操作

查看本地仓库中存在的镜像
1
docker images

镜像字段

显示镜像ID
1
docker images -q
拉取镜像
1
docker pull 镜像:版本号
通过命令行搜索镜像
1
docker search mysql
删除镜像

镜像没有被使用

1
2
3
docker image rm 镜像名:tag

docker image rm 镜像id

镜像被使用过

1
2
docker image rm -f 镜像名:tag
docker image rm -f 镜像id

简化写法:

1
2
3
4
5
docker rmi -f 镜像ID
docker rmi -f 镜像名:5.7

# 删除所有
docker rm -f $(docker images -q)

6、容器相关命令

通过镜像运行一个容器
1
2
3
4
5
6
7
8
9
10
docker run 镜像名:tag | 镜像ID

# 后台执行
docker run -d 镜像名:tag | 镜像ID

# 映射宿主机
docker run -p 宿主机端口号:容器内端口号 镜像名:tag

比如:
docker run tomcat:8.0-jre8

我们启动的一个容器,具有隔离性,是没有办法与外界交互的。

启动tomcat:8080后,输入Linux系统IP地址和tomcat端口号

访问失败

我们需要在启动容器时添加参数。

1
docker run -p 8080(系统上外部端口) : 8080(容器内服务监听的端口)  tomcat:8.0-jre8

成功访问

注意:容器和容器之间是隔离的,因此我们启动多个容器,对于容器内可以都是用8080端口,但是容器映射的操作系统不能出现相同的端口号。

1
2
# 我们在启动一个tomcat
docker run -p 8081:8080 tomcat:8.0-jre8

我们查看此时的容器:

1
docker ps

查看容器

查看容器
1
2
3
4
5
6
# 查看正在运行程序
docker ps
# 查看所有程序
docker ps -a
# 返回正在运行的容器ID
docker ps -q

查看容器命令

1
2
3
4
5
6
7
CONTAINER ID   容器ID
IMAGE 镜像
COMMAND 容器内执行命令
CREATED 创建时间
STATUS 当前状态
PORTS 容器服务监听的端口
NAMES 容器名称
重启、停止容器
1
2
3
4
5
6
7
8
# 启动容器
docker start 容器ID|容器名称
# 重启容器
docker restart 容器ID|容器名称
# 正常停止容器
docker stop 容器ID|容器名称
# 立即停止容器
docker kill 容器ID|容器名称
删除容器
1
2
3
4
5
6
# 删除停止的容器
docker rm 容器ID|容器名称
# 删除正在运行的容器
docker rm -f 容器ID|容器名称
# 删除所有容器
docker rm -f $(docker ps -aq)
查看容器内服务运行日志
1
2
3
4
5
6
7
docker logs 容器ID|容器名称

# 实时监听日志信息
docker logs -f 容器ID|容器名称

# 加上日志的时间戳
docker logs -t 容器ID|容器名称
查看容器内进程
1
docker top 容器ID|容器名称
宿主机和容器内部进行交互
1
2
# 进入容器,并于容器内命令终端进行交互
docker exec -it 容器ID|容器名称 bash

bash就是容器内的终端。

容器内部

1
2
# 退出容器
exit

退出容器

宿主机和容器的传输文件

从容器复制文件到宿主机

1
2
3
4
docker cp 容器ID|容器名称:容器内资源路径 宿主机路径

如:
docker cp 86fe26389d83:/usr/local/tomcat/RUNNING.txt ./RUNNING.txt

image-20210527161639012

从宿主机复制文件到容器

1
2
3
4
docker cp 文件|路径  容器ID|容器名称 : /容器内资源路径

如:
docker cp aa.txt 86fe26389d83:/usr/local/tomcat

image-20210527162033156

查看容器内细节
1
docker inspect 容器ID|容器名称
数据卷Volume

实现宿主机系统与容器之间的文件共享

类似于挂载:

宿主机系统目录改变,直接影响docker目录

image-20210527204555352

如何使用:

启动一个容器时 比如启动一个tomcat

  1. 自定义数据卷目录

    docker run-d -p 8080:8080 -v 宿主机目录(绝对路径):容器内路径 tomcat:8.0-jre8

    例:
    docker run -d -p 8080:8080 -v /root/apps/:/usr/local/tomcat/webapps tomcat:8.0-jre8

  2. 自动数据卷目录

    docker run -d -p 8080:8080 -v aa:/usr/local/tomcat/webapps tomcat:8.0-jre8

    注意:

    1. aa代表一个数据卷名字,可以随便写。docker在不存在时自动创建这个数据卷同时自动映射宿主机中某个目录
    2. 同时在启动容器时,会将aa对应容器目录中全部内容复制到aa映射目录中
将容器打包成新镜像
1
docker commit -m ""  -a""  容器ID|容器名称   打包的镜像名称:标签
将镜像备份出来
1
docker save 容器名称 -o 文件名

7、 docker镜像原理

镜像是一种轻量级的,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含某个软件所需的所有内容,包括代码、运行时所需的库、环境变量和配置文件。

一个软件镜像不仅仅是原来的软件包,包含软件包所需的操作系统依赖,软件自身的依赖,以及自身的软件包组成。不同的镜像之间可能会存在公共的镜像,因此,docker镜像采用分层镜像原理

image-20210528125326506

docker在设计镜像时,每一个镜像都是由多个镜像共同组成。

镜像原理 —- UnionFS(联合文件系统)

UnionFS文件系统是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加。同时可以将不同目录挂载到同一虚拟文件系统下。

UnionFS文件系统是docker镜像的基础。

这种文件系统特性:就是一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

docker的镜像实际上是由一层一层的文件系统组成。

为什么要采用这种分层结构

资源共享

有多个镜像都是从相同的base镜像构建而来,那么宿主机只需在磁盘中保存一份base镜像。同时内存也只需要要加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都是可以被共享的。

当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称为容器层,容器层之下都叫镜像层。

8、docker安装mysql服务

1、dockerhub中搜索mysq服务
1
docker pull mysql:5.7
2、基本使用

dockerhub中详细的解释的如何使用这个镜像。

image-20210528132841767

1
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

-e MYSQL_ROOT_PASSWORD=my-secret-pw 代表给root用户指定密码

比如:启动一个mysql服务,操作系统端口号为3307,密码为root,并且在后台执行

1
docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root mysql:5.7

此时,就已经启动了mysql服务

image-20210528133928618

我们可以通过SQLyog来查看:

image-20210528134123883

image-20210528134204014

3、持久化

容器与容器之间是隔离的。如果我们删除某个容器,那么容器中的数据就会被删除。因此我们要做数据持久化。

image-20210528135042157

通过数据卷的方式持久化。

启动一个容器,后台运行,操作系统的端口号为3307,用户密码为root,名称为mysql1

mysqldata数据卷没有会重新创建。

1
docker run -d -p  3307:3306 -e MYSQL_ROOT_PASSWORD=root --name mysql1 -v mysqldata:/var/lib/mysql  mysql:5.7

执行之后,启动mysql服务

image-20210528140034121

我们查看是否有mysqldata数据卷

1
docker volume ls

image-20210528140149727

我们查看mysqldata数据卷中的信息

1
docker volume inspect mysqldata

image-20210528140405571

此时,数据卷创建好了,并且挂载到宿主机的某个位置。

我们在客户端创建表,添加数据。

image-20210528140654325

此时,我们停掉mysql服务,并且删除这个容器。

1
docker rm -f $(docker ps -aq)

然后重新启动容器,并且指定数据卷为mysqldata。

1
docker run -d -p  3307:3306 -e MYSQL_ROOT_PASSWORD=root --name mysql1 -v mysqldata:/var/lib/mysql  mysql:5.7

重新打开客户端。数据依然还在。

image-20210528141026518

4、 修改配置文件

默认的配置文件是在/etc/mysql/my.cnf

启动一个mysql服务,后台运行,指定root用户密码,指定容器名,使用数据卷进行数据持久化,以修改之后的配置文件启动。

1
docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=root --name mysql3308 -v mysqldata:/var/lib/mysql -v mysqlconfig:/etc/mysql mysql:5.7

我们通过数据卷的方式将MySQL的配置文件挂载到操作系统的某个目录文件中。

查看配置文件的位置:

image-20210528142409329

我们在宿主机中找到这个目录文件。

image-20210528142452935

所以我们在启动MySQL时,指定数据卷。就可以达到通过配置文件来启动的目的。

9、docker中容器之间的网络配置

1、 为什么要提供网络功能

docker允许通过外部访问容器或容器互联的方式来提供网络服务。

2、网络配置原理

当docker启动时,会自动在主机上创建一个docker0虚拟网桥。实际上是Linux的一个bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。

同时,docker随机分配一个本地未占用的私有网段中的一个地址给docker0接口。

当创建一个 Docker 容器的时候,同时会创建了一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。

通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。

image-20210528193306826

image-20210528194234276

3、网络使用

查看docker中的网络配置

1
docker network ls

bridge是默认的网桥

image-20210528194820229

我们可以进入一个容器来查看网络配置信息。

1
2
3
4
# 启动容器
docker run -d -p 8080:8080 --name mytomcat tomcat:8.0-jre8

docker inspect 容器ID|容器名

image-20210528195619131

容器与容器之间的交互

我们创建两个tomcat,mytomcat和tomcat2。我们进入mytomcat的容器内,在这个容器内去访问tomcat2的8080端口。

image-20210528200352177

我们还需要知道tomcat2的ip地址。

1
docker inspect 55fd2f590189

image-20210528200907644

进入mytomcat容器内

1
docker exec -it 66fd52d82688 bash
1
2
访问tomcat2的8080端口
curl http://172.17.0.3:8080

image-20210528201243617

自定义网桥

如果我们每一个容器都是用默认的网桥。就会造成带宽的降低。因此我们自定义网桥。

1
2
# 创建自定义网桥
docker network create -d bridge 网桥名称
1
docker network create -d bridge net

image-20210528202247215

我们查看net网桥中的信息。

image-20210528202552064

我们在启动一个tomcat,这是的tomcat IP地址就会是172.18.0.xxx这个网段了。

使用自定义网桥
1
docker run -d -p 8080:8080 --name tomcat --network net tomcat:8.0-jre8

image-20210528203139533


Docker
https://johnjoyjzw.github.io/2021/05/01/Docker/
Author
John Joy
Posted on
May 1, 2021
Licensed under