Docker总结

🐳一、Docker概述

在这里插入图片描述
  我们可以看到Docker的图标是一只小鲸鱼,上面背着各种的集装箱。其实我们可以这样理解,小鲸鱼就像是我们的一台虚拟机,虚拟机中的各个容器就像是各个集装箱。有的集装箱当中装的是水果,有的集装箱装的是衣服,但是他们各自是不会影响对方的,因为他们通过集装箱的保护下好好地把对方隔离了。

1、Docker为什么会出现?

  在实际开发的过程中我们经常会碰到这种情况,当我们作为后端与前端以及运维对接的时候,往往会遇到一些情况就是在我本机的环境可以正常运行,但是在对方的环境就不可以正常运行,或者在测试环境、生产环境就不可以正常运行。👿啊啊啊啊啊啊啊啊👿,这样就会比较浪费时间了。
  docke就是专门为了解决这种水土不服的问题而出现的,docker可以将软件带环境安装,来解决这种问题。
在这里插入图片描述
  传统上认为,软甲编码开发/测试结束后,所产生的成果即是程序或是能够编译执行的二进制字节码等(java为例)。而为了让这些程序可以顺利执行,开发团队也得准备完整的部署文件,让运维团队得以部署应用程式。开发需要清楚的告诉运维部署团队,用的全部配置文件+所有软件环境。不过,即便如此,仍然常常发生部署失败的状况。Docker的出现使得Docker得以打破过去[程序及应用]的观念。通过镜像(images)将作业系统核心除外,运作应用程式所需要的系统环境,由上而下打包,达到应用程式跨平台的无缝运作。🈴

2、Docker的历史

  2010年, 几个年轻的美国人成立了一家公司叫做dotCloud,这家公司主要做pass云计算服务,其底层技术上,dotCloud 平台利用了 Linux 容器技术,他们将自己的的技术命名为docker。
  docker刚诞生的时候, 并没有引起行业的注意, dotCloud公司越来越难, 经济效益也不景气, 后来就要活不下去了, 他们有强烈的愿望, 希望能活下去.。于是, 想了一个办法, 将docker开源。
  2013年, docker开源了. 并且他们也将公司正式改名为Docker. docker受到越来越多的人关注. 渐渐的docker就火了. 活了以后, docker每个月就会更新一个版本. 2014年.4.9 docker1.0发布。
  一款开源软件能否在商业上成功,很大程度上依赖三件事 - 成功的 user case(用例), 活跃的社区和一个好故事。 dotCloud 之家的 PaaS 产品建立在docker之上,长期维护且有大量的用户,社区也十分活跃。👨🏽‍🌾

3、Docker的官方地址

每学一门新的技术的时候,我们需要知道这门技术的一些官方文档,以及学习路径
Docker官网
DockerHub官网

4、Docker能做什么

传统虚拟机

在这里插入图片描述
虚拟机技术缺点:
1、资源占用十分多
2、冗余步骤多(配置各种环境)
3、启动慢

容器化技术

容器化技术不是一个完整的系统
在这里插入图片描述
比较Docker和虚拟机技术的不同:
● 传统虚拟机,虚拟出一套硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件。
● 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了。
● 每个容器间是互相隔离的,每个容器内部都有一个属于自己的文件系统,互不影响。

5、Docker的基本组成

在这里插入图片描述
镜像(image):
  docker镜像就好比是一个模板,可以通过这个模板来创建容器服务。
容器(container):
  Docker利用容器技术,独立运行一个或者一个组的应用,通过镜像来创建。
仓库(repository):
  仓库就是存放镜像的地方。

🐶二、安装Docker

1、查看环境

[root@VM-12-17-centos ~]# uname -r
3.10.0-1160.71.1.el7.x86_64

系统的内核版本是在3.10以上的

[root@VM-12-17-centos ~]# cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

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

使用的系统版本是CentOS7

2、安装

在这里插入图片描述
我们直接打开docker的官网,找到安装教程,然后我们就可以跟着教程来做啦🏃🏿‍♀️ 🏃🏿 🏃🏿‍♂️

卸载旧的版本

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

需要的安装包

sudo yum install -y yum-utils

设置镜像的仓库

sudo 
yum-config-manager \ 
--add-repo \
 https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
 ##默认是国外的,我这里设置成了国内阿里云的镜像加速

更新yum软件包的索引

yum makecache fast
# 如出现错误:yum makecache: error: argument timer: invalid choice: 'fast' (choose from 'timer')
# 是centos 7 以上的无需fast,将最后的fast去掉,即 yum makecache

#如出现如下报错
# https://mirrors.aliyun.com/docker-ce/linux/centos/2.1903/x86_64/stable/repodata/repomd.xml: [Errno 14] HTTPS Error 404 - Not Found
# Trying other mirror.
# 经过排查发现是仓库配置中的 $releasever 找不到导致
# 解决方案
# 1. 打开仓库配置文件  vim /etc/yum.repos.d/docker-ce.repo 
# 2. 编辑 docker-ce-stable 的baseurl值
# [docker-ce-stable]
# name=Docker CE Stable - $basearch
# #baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable
# baseurl=https://download.docker.com/linux/centos/7/$basearch/stable

安装docker相关的依赖 docker-ce社区 如果是ee为企业版,我们通常下载ce的

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

启动docker

sudo systemctl start docker

检查docker是否安装成功

[root@VM-12-17-centos ~]# docker version
Client: Docker Engine - Community
 Version:           23.0.3
 API version:       1.42
 Go version:        go1.19.7
 Git commit:        3e7cbfd
 Built:             Tue Apr  4 22:04:18 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community 社区版
 Engine:
  Version:          23.0.3
  API version:      1.42 (minimum version 1.12)
  Go version:       go1.19.7
  Git commit:       59118bf
  Built:            Tue Apr  4 22:02:01 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.20
  GitCommit:        2806fc1057397dbaeefbea0e4e17bddfbd388f38
 runc:
  Version:          1.1.5
  GitCommit:        v1.1.5-0-gf19387a
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

测试hello world程序

[root@VM-12-17-centos ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally  #从本地中没有找到hello-world镜像
latest: Pulling from library/hello-world  #从远程仓库拉取hello-world镜像
2db29710123e: Pull complete 
Digest: sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9
Status: Downloaded newer image for hello-world:latest

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

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

查看一下刚下载的docker镜像

[root@VM-12-17-centos ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    feb5d9fea6a5   18 months ago   13.3kB

卸载docker

卸载依赖

 sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras

删除资源

sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

🐱三、Docker run的流程以及Docker的底层运行原理

1、Docker run的流程图

在这里插入图片描述

2、Docker是怎么工作的?

Docker是一个Cilent-Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问。
在这里插入图片描述

3、Docker为什么比VM快?

在这里插入图片描述
1、Docker拥有着比虚拟机更少的抽象层。
2、Docker利用的是宿主机的内核,vm需要是Guest OS。
3、所以,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统的内核。避免引导,虚拟机是加载Guest OS,分钟级别的。而docker是利用宿主机的操作系统的,省略了这个复杂的过程,秒级别的。🏄🏾‍♂️
在这里插入图片描述

🐭四、Docker的常用命令

命令文档的地址

1、帮助命令

命令作用
docker version显示docker的版本信息
docker info显示docker的系统信息,包括镜像喝容器的数量
docker --help帮助命令(可以查看到各个命令的解释)

2、镜像命令

(1)显示docker的镜像

[root@VM-12-17-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 18 months ago 13.3kB

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

(2)显示docker的镜像只显示容器的id

[root@VM-12-17-centos ~]# docker images -q
3f3447deacaa
55ee3f86a3bb
afef20758bd3
feb5d9fea6a5

(3)列出所有的镜像

[root@VM-12-17-centos ~]# docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 3f3447deacaa 10 days ago 455MB
redis 6.2 55ee3f86a3bb 2 weeks ago 113MB
mongo 4.4 afef20758bd3 3 weeks ago 431MB
hello-world latest feb5d9fea6a5 18 months ago 13.3kB

3、搜索镜像命令

相当于去docker hub搜索镜像

[root@VM-12-17-centos ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 14027 [OK]

4、下载镜像命令

下载镜像

docker pull 镜像名称

下载指定版本的镜像

docker pull 镜像名称 版本号

5、删除镜像命令

删除单个镜像

docker rmi 镜像id或者名称

删除所有的镜像

docker rmi -f $(docker images -aq)        
#其中 $ 意思是把后面的这段查询结果传进去,进行操作,docker images -aq意味着查询出#所有的镜像

6、容器命令

(1)新建容器并启动

docker run [可选参数] image


#参数说明
--name [容器名字]    #帮容器起名字用去区分容器
-d             #后台方式进行
-it      		# 使用交互方式运行,进入容器查看内容
-p           	#指定容器的端口    通常使用这种  -p 主机端口:容器端口

(2)运行的容器

docker ps 	#列出当前正在运行的容器
 -a  		#列出当前正在运行的容器+带出历史运行过的容器
 -n=?  		#显示最近创建的容器
 -q 		#只显示容器的编号

(3)退出容器

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

(4)删除容器

docker rm 容器id  					#删除指定容器,不能删除正在运行的容器,如果要删除那只能够rm -f强制删除
docker rm -f $(docker ps -aq)		#删除所有的容器

(5)启动和停止容器的操作

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

(6)查看日志

docker logs -tf 容器id					#指定容器要显示的日志
docker logs -tf --tail 指定行数 容器id	#指定容器要显示指定最后的条数的日志

(7)查看容器中进程信息

docker top 容器id

(8)查看镜像的元数据

docker inspect 容器id

(9)进入当前正在运行的容器

docker exec -it 容器id /bin/bash

(10)进入容器正在执行的终端,不会启动新的进程

docker attach 容器id

(11)从容器内拷贝文件到主机上

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

🐹五、Docker镜像

1、镜像是什么

  Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 不包含 任何动态数据,其内容在构建之后也不会被改变。
通常如何获得镜像呢?🍉
●从远程仓库下载
●朋友拷贝给你
●自己制作一个镜像DockerFile

2、Docker镜像加载原理

(1)UnionFS(联合文件系统)
  联合文件系统(Union File System):2004年由纽约州立大学石溪分校开发,它可以把多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。UnionFS允许只读和可读写目录并存,就是说可同时删除和增加内容。UnionFS应用的地方很多,比如在多个磁盘分区上合并不同文件系统的主目录。另外UnionFS具有写时复制(copy-on-write)功能UnionFS可以把只读和可读写文件系统合并在一起,虚拟上允许只读文件系统的修改可以保存到可写文件系统当中。
(2)Docker是如何使用UnionFS?
  如果我们浏览Docker hub,能发现大多数镜像都不是从头开始制作,而是从一些base镜像基础上创建,比如debian基础镜像。
  而新镜像就是从基础镜像上一层层叠加新的逻辑构成的。这种分层设计,一个优点就是资源共享。
  想象这样一个场景,一台宿主机上运行了100个基于debian base镜像的容器,难道每个容器里都有一份重复的debian拷贝呢?这显然不合理;借助Linux的unionFS,宿主机只需要在磁盘上保存一份base镜像,内存中也只需要加载一份,就能被所有基于这个镜像的容器共享。
  当某个容器修改了基础镜像的内容,比如 /bin文件夹下的文件,这时其他容器的/bin文件夹是否会发生变化呢?
  根据容器镜像的写时拷贝(Copy-on-Write)技术,某个容器对基础镜像的修改会被限制在单个容器内。
  容器镜像由多个镜像层组成,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /text,上层的 /text 会覆盖下层的 /text,也就是说用户只能访问到上层中的文件 /text。
  将中间只读的 rootfs 的集合称为 Docker 镜像,Docker 镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。UnionFS 使得镜像的复用、定制变得更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
在这里插入图片描述
  当用docker run启动这个容器时,实际上在镜像的顶部添加了一个新的可写层。这个可写层也叫容器层。
在这里插入图片描述
  容器启动后,其内的应用所有对容器的改动,文件的增删改操作都只会发生在容器层中,对容器层下面的所有只读镜像层没有影响。
  Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!这一层就是我们通常说的容器层,容器之下的都叫镜像层!老千层饼了🥑🥑🥑

3、Commit镜像

在达到这个Commit操作之前,我们先部署一下我们所需要的环境,跟着我来就好了啦啦啦啦🏊‍♀️ 🏊 🏊‍♂️

部署环境

拉取镜像

docker pull tomcat:9.0

启动容器

docker run --name tomcat01 -p 虚拟机端口:8080 -d tomcat:9.0 

这个时候我们访问暴露出去的端口可以看到
在这里插入图片描述
别慌小伙子🤹 🤹‍♂️ 🤹‍♀️,这个时候我们进入容器内部一探究竟

docker exec -it tomcat01 /bin/bash

在这里插入图片描述
我们可以看到这里的webapp没有东西,那当然是没有界面的啦(因为docker去拉取镜像的时候,拿到的是精简版的tomcat,所以这里是没有数据的)
这些数据都在webapp.dist这个文件下面
在这里插入图片描述
然后我们就把文件拷贝过去吧

tomcat# cp -r webapps.dist/* webapps

在这里插入图片描述
芜湖大师兄回来喽🎸🎸🎸

提交镜像

然后我们就来提交一下镜像啦

[root@VM-12-17-centos ~]# docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED        STATUS        PORTS                                                    NAMES
6835231f577f   tomcat:9.0   "catalina.sh run"        16 hours ago   Up 16 hours   0.0.0.0:外部虚拟机端口->8080/tcp, :::外部虚拟机端口->8080/tcp                tomcat01
docker commit -a="imperfect" -m="add webapps app" 6835231f577f tomcat02:1.0

-a表示作者
-m表示提交的信息
最后tomcat02:1.0代表镜像的名字和版本

然后我们来check一下🥰

[root@VM-12-17-centos ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
tomcat02      1.0       5a529b8cceff   4 seconds ago   482MB
tomcat        9.0       061a3c8c49ee   2 weeks ago     477MB

这样子我们的镜像就提交到本地啦开心🤩🤩🤩

🐰六、容器数据卷使用

1、什么是容器数据卷?

  Docker将运用与运行的环境打包形成容器运行, Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来, 那么当容器删除后,数据自然也就没有了。 为了能保存数据在Docker中我们使用卷。|

  卷就是目录或文件,存在于一个或多个容器中,由Docker挂载到容器,但卷不属于联合文件系统(Union FileSystem),因此能够绕过联合文件系统提供一些用于持续存储或共享数据的特性:。

有以下这样子的一个场景:
如果我们把mysql的数据放在容器里面,没有挂载到外部虚拟机的目录的话,我们容器删了,那么里面的数据就没有了,删了容器就相当于删库跑路了!🌩
需求:我们mysql的数据可以存储在本地,docker容器之间可以有一个数据共享的技术。我们容器内的目录,需要挂载到linux上面。
在这里插入图片描述

2、使用数据卷

这里我就浅浅以mysql举一下例子啦🚙

docker run -p 外部虚拟机端口:3306 --name mysql \
-v /var/lib/docker/mysql/conf.d/:/etc/mysql/conf.d \  ##/var/lib/docker/mysql/conf.d/表示虚拟机的目录,/etc/mysql/conf.d表示容器内的目录
-v /var/lib/docker/mysql/mysql/:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=数据库认证密码 \
-d mysql:5.7

可以看到上面我们引入了两个新的东西一个是-v一个是-e,这两个我是这样子理解的-v表示volume,-e表示environment

docker inspect 容器id

同样的我们可以使用docker inspect来查看到具体的挂载目录的信息
在这里插入图片描述

3、匿名挂载和具名挂载

这里拓展一下在启动容器的时候

-v 容器内路径      		#匿名挂在
-v 卷名:容器内路径 		#具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载!

所有的docker容器内的卷,没有指定具体的目录的情况下都是在/var/lib/docker/volumes

4、卷的读写权限

docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

其中最后这里的ro(read only)表示这个路径的文件操作只能通过宿主机来进行写操作,容器内部是只有读操作的。
其中rw表示宿主机和容器内部都可以进行读写操作。

🦊七、数据卷容器(volumes-from容器间传递共享)

1、构建镜像

首先我们先构建一个自己的镜像,先浅浅体验一下

[root@VM-12-17-centos docker-test-volume]# pwd
/home/docker-test-volume
[root@VM-12-17-centos docker-test-volume]# vim dockerfile1

里面dockerfile1的脚本是长这个样子的哦

FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash

接下来我们来执行一下构建镜像的命令,别忘记最后一个 .

docker build -f /home/docker-test-volume/dockerfile1 -t imperfect/centos:1.0 .

这样子我们就构建镜像完成啦
在这里插入图片描述

接下来我们可以启动一下自己创建的镜像,这里可以看到我们刚才在dockerfile1里面写的两个卷
在这里插入图片描述
我们也可以看到这两个文件在宿主机挂载的位置
在这里插入图片描述

2、使用–volumes-from

在这里插入图片描述
我们先启动docker01

docker run -it --name docker01 imperfect/centos:1.0

启动docker02

docker run -it --name docker02 --volumes-from docker01 imperfect/centos:1.0

其中–volumes-from 继承docker01
我们可以看到这个里面同样也有volume1和volume2
在这里插入图片描述
接下来我们测试一下
在docker01的volume01新增两个文件
在这里插入图片描述
然后我们在docker02的volume01看下是否有这两个文件
在这里插入图片描述
宿主机上的文件
在这里插入图片描述
原理:docker01将数据卷挂载到宿主机上,docker02将数据挂载到和docker01相同的数据卷上,其实都指向了宿主机的同一个文件上

🐻八、DockerFile

  Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

DockerFile的构建步骤
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像(DockerHub、阿里云镜像仓库)

1、DockerFile指令

DockerFile指令的基本规则:
1、每个关键字(指令)都必须是大写字母
2、执行从上到下顺序执行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交

DockerFile指令:

指令解释
FROM基础镜像,一切从这里构建
MAINTAINER镜像是谁写的,姓名+邮箱
RUN镜像构建的时候需要运行的命令
ADD添加镜像,添加内容
WORKDIR镜像的工作目录
VOLUME挂载的目录
EXPOSE暴露端口配置
CMD指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD当构建一个被继承DockerFile 这个时候就会运行ONBUILD的指令,触发指令。
COPY类似ADD,将我们的文件拷贝到镜像中
ENV构建的时候设置环境变量

2、通过dockerfile构建镜像

首先我们先创建一个dockerfile文件

vim mydockerfile-centos

dockerfile里面长这个样子🍔

FROM centos:7
MAINTAINER imperfect
ENV MYPATH usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

CMD echo %MYPATH
CMD echo "---end---"
CMD /bin/bash

通过文件构建镜像

docker build -f mydockerfile-centos -t mycentos:0.1 .

我们可以看到这样子我们就生成了一个镜像了
在这里插入图片描述
启动容器

docker run -it mycentos:0.1

可以看到直接进到工作目录了
在这里插入图片描述
这就是我们在dockerfile中配置的工作目录

ENV MYPATH usr/local

我们加载了yum插件以后,ifconfig可以用了
在这里插入图片描述
我们也可以通过docker images来看一下镜像构建的历史

docker history 镜像id

例如我这里看到mysql镜像的构建历史
在这里插入图片描述
暴露在3306端口
默认挂载的目录

3、CMD和ENTRYPOINT区别

(1)我们先构建一个CMD测试的dockerfile

vim dockerfile-cmd-test

长这样子的🍗

FROM centos:7
CMD ["ls","-a"]

构建镜像

docker build -f dockerfile-cmd-test -t cmdtest .

我们正常运行容器可以看到正常执行了
在这里插入图片描述
我们给他追加一个命令-l
在这里插入图片描述
会发现这里报错了
在cmd的情况下 -l替换了CMD中的命令,而-l不是命令,所以报错了

(2)我们先构建一个ENTRYPOINT测试的dockerfile

vim dockerfile-entrypoint-test 

dockerfile中长这个样子的

FROM centos:7
ENTRYPOINT ["ls","-a"]

构建镜像

docker build -f dockerfile-entrypoint-test -t entrypointtest .

正常执行
在这里插入图片描述
那现在我们来追加-l 呢
在这里插入图片描述
追加成功了🌰 🥜 🍯

🐨九、发布镜像到DockerHub

1、Dockerfile制作tomcat镜像

准备tomcat压缩包和jdk压缩包
编写dockerfile文件

tomcat安装包
jdk安装包
在这里插入图片描述
那我们就可以开始编写dockerfile文件啦

vim Dockerfile

注意这里我们Dockerfile大写字母开头,build会自动寻找这个文件,这是官方命名。
这是我们的Dockerfile文件

FROM centos:7						#在centos的基础上进行搭建
MAINTAINER imperfect				#作者名称

ADD jdk-8u361-linux-x64.tar.gz /usr/local/	#这里的ADD命令直接把压缩包解压到指定目录
ADD apache-tomcat-9.0.73.tar.gz /usr/local/

RUN yum -y install vim			#安装命令插件
ENV MYPATH /usr/local
WORKDIR $MYPATH					#工作目录

ENV JAVA_HOME /usr/local/jdk1.8.0_361			#配置环境
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.73
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.73
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080			#向外部暴露的端口
CMD usr/local/apache-tomcat-9.0.73/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.73/bin/logs/catalina.out	#启动容器执行脚本	

然后我们就可以构建镜像啦

docker build -t diytomcat . 

芜湖,我们又多了自己的镜像啦🥰
在这里插入图片描述
然后我们就可以来启动容器了!

docker run -d -p 9205:8080 --name imperfectdiytomcat -v /home/imperfect/build/tomcat/test:/usr/local/apache-tomcat-9.0.73/webapps/test -v /home/imperfect/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.73/logs diytomcat

启动成功!
在这里插入图片描述
然后我们来写一个页面吧

[root@VM-12-17-centos test]# pwd
/home/imperfect/build/tomcat/test
vim index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<h1>hello imperfect</h1>

<p>我的第一个段落。</p>

</body>
</html>

在这里插入图片描述
啦啦啦,这样我们就制作好属于我们自己diy的tomcat镜像啦🧑‍💻 👨‍💻

2、发布镜像到dockerHub

DockerHub
在这里插入图片描述
登陆一下账号
在这里插入图片描述
然后给我diy的镜像打一个tag版本

[root@VM-12-17-centos test]# docker images
REPOSITORY         TAG       IMAGE ID       CREATED         SIZE
diytomcat          latest    47471720f233   3 hours ago     821MB
[root@VM-12-17-centos test]# docker tag 47471720f233 imperfect/tomcat:1.0
[root@VM-12-17-centos test]# docker images
REPOSITORY         TAG       IMAGE ID       CREATED         SIZE
imperfect/tomcat   1.0       47471720f233   3 hours ago     821MB
diytomcat          latest    47471720f233   3 hours ago     821MB

然后我们来push一下

docker push imperfect/tomcat:1.0

🐯十、Docker全流程总结

在这里插入图片描述

🦁十一、Docker网络

1、Docker网络实现

  首先,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)来收发数据包;此外,如果不同子网之间要进行通信,需要路由机制。

  Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优势之一是转发效率较高。 Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发,发送接口的发送缓存中的数据包被直接复制到接收接口的接收缓存中。对于本地系统和容器内系统看来就像是一个正常的以太网卡,只是它不需要真正同外部网络设备通信,速度要快很多。

  Docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做 veth pair)。

创建网络参数
Docker 创建一个容器的时候,会执行如下操作:

创建一对虚拟接口,分别放到本地主机和新容器中;
1、本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 veth65f9;
2、容器一端放到新容器中,并修改名字作为 eth0,这个接口只在容器的名称空间可见;
从网桥可用地址段中获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 veth65f9。
-完成这些之后,容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。

2、Docker的四种网络模式

Docker网络模式配置说明
host模式–net=host容器和宿主机共享Network namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
container模式–net=container:NAME_or_ID容器和另外一个容器共享Network namespace。创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围
bridge模式–net=bridge(默认为该模式)此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。
none模式–net=none该模式关闭了容器的网络功能。

3、bridge模式

  当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

接下来我们来实战看一下这种模式

docker run -d -P --name tomcat01 tomcat:7.0
docker run -d -P --name tomcat02 tomcat:7.0

直接通过linux来pingtomcat01
在这里插入图片描述
成功ping通

tomcat02 ping tomcat01
在这里插入图片描述
成功ping通

然后我们分别来看一下宿主机上的网络设置
在这里插入图片描述
再看一下tomcat01的
在这里插入图片描述
再看一下tomcat02的
在这里插入图片描述
结构图:
在这里插入图片描述
结论:tomcat01和tomcat02是公用一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的。

4、自定义网络

通过–help我们可以看到,如果我们需要创建一个网络,可以使用create来创建在这里插入图片描述
通过create里面的–help我们可以再深入看具体创建网络的命令
在这里插入图片描述
自定义网络

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

–subnet创建一个子网,在192.168.0.0/16(192.168.0.2至192.168.255.255)网段下,默认网关是192.168.0.1,名字为mynet。
在这里插入图片描述
在这里插入图片描述

创建成功!!!🚴‍♀️ 🚴 🚴‍♂️

然后我们把tomcat部署到自己自定义的网络当中

[root@VM-12-17-centos ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat:7.0
8870470f62fbee558b5dfce24c3060e4c59de72c636e2f0a6be52d0dba0476f6
[root@VM-12-17-centos ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat:7.0
42ccd75d40d443988f3b01e2948428e3dcdd8df2abda191750145efc14dad564

然后我们再看一下自定义网络的信息

[root@VM-12-17-centos ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "b0b2781225d6d9ec6347a8da1b9b324328b17e35c7f757fda5caeee8f24fc5eb",
        "Created": "2023-04-17T15:19:21.441110265+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "42ccd75d40d443988f3b01e2948428e3dcdd8df2abda191750145efc14dad564": {
                "Name": "tomcat-net-02",
                "EndpointID": "ec3e082b471d5235fbe0fcf8e2105e89397d4d21751dd9a5aa0d143fe0fe9b67",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "8870470f62fbee558b5dfce24c3060e4c59de72c636e2f0a6be52d0dba0476f6": {
                "Name": "tomcat-net-01",
                "EndpointID": "5150400ddf045ad348329ca301dcce16832858e3d9189281e9b6d5b664b855e5",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

我们就可以看到成功了!!!🧸

docker exec -it tomcat-net-01 ping tomcat-net-02

在这里插入图片描述
这里我们可以看到通过服务名称也可以ping到!
我们自定义网络docker都已经帮我们维护好了对应的关系,而利用我们的默认的docker0是做不到这一点的。

5、网络连通

目前docker网络架构图
在这里插入图片描述
目前的架构上如果tomcat-01是无法跟tomcat-net-01连通的,因为都不属于同一个网段下!
在这里插入图片描述
我们现在需要把tomcat-01跟mynet自定义网卡进行连通。
这里看了一下命令,有这样子的一个命令
在这里插入图片描述
把tomcat01容器跟mynet网卡进行打通

docker network connect mynet tomcat01

然后我们再看一下mynet的详细信息

[root@VM-12-17-centos ~]# docker network inspect mynet 
[
    {
        "Name": "mynet",
        "Id": "b0b2781225d6d9ec6347a8da1b9b324328b17e35c7f757fda5caeee8f24fc5eb",
        "Created": "2023-04-17T15:19:21.441110265+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "42ccd75d40d443988f3b01e2948428e3dcdd8df2abda191750145efc14dad564": {
                "Name": "tomcat-net-02",
                "EndpointID": "ec3e082b471d5235fbe0fcf8e2105e89397d4d21751dd9a5aa0d143fe0fe9b67",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "8870470f62fbee558b5dfce24c3060e4c59de72c636e2f0a6be52d0dba0476f6": {
                "Name": "tomcat-net-01",
                "EndpointID": "5150400ddf045ad348329ca301dcce16832858e3d9189281e9b6d5b664b855e5",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "e644c46cf336b9a75353762f8eda9e525e4e0fd29e24e8d6dca957cad218e030": {
                "Name": "tomcat01",
                "EndpointID": "9050aa240b39e25711751e230ce6a33d98c76467ea7c966b95d01792f097e56f",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

连通之后我们发现tomcat01加到了mynet的网段中当中来了,这样就变成了一个容器拥有两个ip地址。
在这里插入图片描述
芜湖,我们现在就可以ping通了🉐🉐🉐

🐮十二、Redis集群部署实战

部署redis网卡

docker network create redis --subnet 172.38.0.0/16

通过脚本创建六个redis配置

for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

启动redis

# 第一个redis
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
Unable to find image 'redis:5.0.9-alpine3.11' locally
5.0.9-alpine3.11: Pulling from library/redis
cbdbe7a5bc2a: Pull complete 
dc0373118a0d: Pull complete 
cfd369fe6256: Pull complete 
3e45770272d9: Pull complete 
558de8ea3153: Pull complete 
a2c652551612: Pull complete 
Digest: sha256:83a3af36d5e57f2901b4783c313720e5fa3ecf0424ba86ad9775e06a9a5e35d0
Status: Downloaded newer image for redis:5.0.9-alpine3.11
fb849a84983b2d8fbd55ea5276fbab26d47495b1ed3128b12644a72e65a3d353

# 第二个redis
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 第三个redis
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 第四个redis
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 第五个redis
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 第六个redis
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

查看启动情况

[root@VM-12-17-centos /]# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED              STATUS              PORTS                                                                                      NAMES
449967ac9b3b   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp   redis-6
c669b7e54378   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp   redis-5
7bf3b13d1556   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp   redis-4
4af23659f094   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp   redis-3
aca3f884c626   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   2 minutes ago        Up 2 minutes        0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp   redis-2
ca2a6800bc41   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   2 minutes ago        Up 2 minutes        0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp   redis-1

配置Redis集群信息

redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

执行结果
在这里插入图片描述
然后咱们来测试一下🥣

/data # redis-cli -c
127.0.0.1:6379> cluster nodes
f07821adc39c52439d0fd89007ac05e2ed72d3e0 172.38.0.14:6379@16379 slave 87a6a79283f737b01c40a275947c88f60502a291 0 1681720219369 4 connected
3b3177eee822c4ecbef5cb904c19a69648e95f71 172.38.0.12:6379@16379 master - 0 1681720219569 2 connected 5461-10922
6a2497337603e45dba37385bc222992c7f548c0f 172.38.0.16:6379@16379 slave 3b3177eee822c4ecbef5cb904c19a69648e95f71 0 1681720218000 7 connected
89d7a9381e350c087e8543126c03d91d59904737 172.38.0.13:6379@16379 master - 0 1681720217565 3 connected 10923-16383
87a6a79283f737b01c40a275947c88f60502a291 172.38.0.11:6379@16379 myself,master - 0 1681720216000 1 connected 0-5460
6355492c2d963d87cacf8694336205af6bcbd62d 172.38.0.15:6379@16379 slave 89d7a9381e350c087e8543126c03d91d59904737 0 1681720218367 5 connected
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379  #这里我们可以看到是redis-3在处理
OK
172.38.0.13:6379> 

然后我们新建一个会话停掉redis-3

[root@VM-12-17-centos ~]# docker stop redis-3
redis-3
[root@VM-12-17-centos ~]# 

重新get a
在这里插入图片描述
这里我们就发现redis-3挂掉后redis-5顶上来了

🐷十三、构建Jar包docker镜像

首先我们编写一下Dockerfile文件

FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=9090"]

EXPOSE 9090

ENTRYPOINT ["java", "-jar", "/app.jar"]

然后把dockerfile与jar包放到同级目录下
在这里插入图片描述
构建镜像

docker build -t ruoyi-gateway .
docker run -d -p 9090:9090 --name ruoyi-gateway ruoyi-gateway

啦啦啦,成功部署啦🌝🌝🌝
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值