docker指令存档

目录

Docker

1、概念

2、架构图

3、安装

4、Docker怎么工作的?

5、Docker常用命令

帮助命令

镜像命令

1、查看镜像

2、帮助命令

3、搜索镜像

4、拉取镜像

5、删除镜像

容器命令

1、启动

2、查看运行的容器

3、删除容器

4、启动&停止

其他命令

1、后台启动容器

2、查看日志

3、查看容器内的进程信息

4、查看镜像的元数据

5、进入当前正在运行的容器

方式一

方式二

6、从容器内拷贝文件到主机上

6、小结

7、Docker安装Nginx

1、搜索镜像

2、下载镜像

3、运行镜像

4、测试

停止

流程

思考

8、Docker安装Tomcat

1、下载并启动

2、测试&问题

3、解决问题

4、再测试

思考

9、部署es&kibana

1、启动

2、查看内存状态

3、停掉

4、增加内存限制

5、测试

思考

10、可视化

1、什么是portainer?

2、测试

11、镜像

1、是什么?

2、怎么获得?

2.镜像加载原理

3、镜像层&容器层

4、提交自己的镜像

1、启动

2、进入并拷贝

3、提交镜像

12、Docker理念

持久化

同步操作

13、容器数据卷(Volume)

同步文件

1、挂载 -v

2、测试

3、反向测试

安装MySQL

1、下载

2、测试连接

具名&匿名挂载

1、匿名挂载

2、具名挂载

3、卷路径

4、判断是哪种挂载?

初识DockerFile

1、构建自己的镜像

2、匿名挂载同步查看

数据卷容器

1、容器挂载

2、删除测试

多个MySQL实现数据共享

结论

再见DockerFile

构建步骤

构建过程

DockerFile指令

实战测试

1、编写DockerFile

2、测试

查看构建历史

CMD&ENTRYPOINT

1、测试CMD

2、测试ENTRYPOINT

Tomcat镜像

Dockerfile

运行&挂载

测试

主机修改tomcat

外网访问

catalina.out

发布自己的镜像

DockerHub

阿里云

Docker流程

14、Docker网络

1、清空环境

2、查看地址

3、问题

1、启动容器并查ip

2、ping测试

启动容器后我们再次测试 ip a

再启动一个tomcat测试

绘制网络模型图

4、自定义网络

网络模式

1、清理环境

2、创建我们自己的网络

3、启动测试我们自己的网络

4、网络连通

15、Redis集群部署实战

1、redis集群的搭建

2、停掉主机&获取值

3、查看集群节点信息

16、打包镜像

1、打包项目

2、编写Dockerfile

3、构建镜像

4、测试访问

本地测试

外网访问


Docker

1、概念

docker指令存档_第1张图片

Docker核心思想:隔离,每个箱子是隔离的,打包装箱。

虚拟机技术缺点

docker指令存档_第2张图片

1、资源占用多

2、冗余步骤多

3、启动慢

容器技术

容器化技术不是模拟的一个完整的操作系统。

docker指令存档_第3张图片

比较Docker和虚拟机技术的不同:

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

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

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

优点:

image-20211025223000164

2、架构图

docker指令存档_第4张图片

镜像(image):【类】

docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,Tomcat镜像-->run-->tomcat1容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。

容器(container):【对象】

Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建。目前可以把这个容器理解为就是一个简易的Linux系统。

仓库(repository):存放镜像的地方。分为共有仓库和私有仓库。

3、安装

环境准备:

1、保证系统内核在3.10以上

uname -r

我的版本:3.10.0-1160.el7.x86_64

2、查看镜像是否是centos7

cat /etc/os-release

3、进入帮助文档

Get Docker | Docker Docs

开始

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、\textcolor{red}{设置镜像仓库} ,解决下载慢

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

4、更新软件包索引

yum makecache fast

5、安装docker引擎(ce 社区版)

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

6、启动docker

systemctl start docker

7、通过版本号查看是否启动成功

docker version

8、测试运行

docker run hello-world

docker指令存档_第5张图片

9、查看拉取的镜像

docker images

image-20211026210629821

附:怎么卸载引擎?

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

4、Docker怎么工作的?

docker指令存档_第6张图片

Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问!

DockerServer接收到Docker-Client的指令,就会执行这个命令!

docker指令存档_第7张图片

Docker为什么比VM快?

1、Docker有着比虚拟机更少的抽象层。

docker指令存档_第8张图片

2、Docker利用的是宿主机的内核,vm 需要 guest os

新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载 guest os ,分钟级别的,而docker是利用宿主机的操作系统,省略了这个复杂的过程,秒级。

5、Docker常用命令

docker | Docker Docs

镜像就像手机中APP安装包,容器就像已安装的APP应用

帮助命令

1、查看版本
docker version
​
2、查看信息(镜像和容器的数量等)
docker info
​
3、查看命令
docker 命令 --help

镜像命令

1、查看镜像
1、查看本地主机上所有的镜像
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
hello-world   latest    feb5d9fea6a5   4 weeks ago   13.3kB
​
REPOSITORY      镜像的仓库源
TAG             镜像的标签
IMAGE ID        镜像的id
CREATED         镜像的创建时间
SIZE            镜像的大小
​
Options(选项):
  -a, --all             # 列出所有的镜像
​
  -q, --quiet           # 只显示镜像的id

2、帮助命令
docker images --help

docker指令存档_第9张图片

3、搜索镜像
搜索镜像
[root@localhost ~]# docker search mysql
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   11593         
mariadb                           MariaDB Server is a high performing open sou…   4409     
​
mysql/mysql-server                Optimized MySQL Server Docker images. Create…   857       
​
​
STARS:收藏量
--filter=STARS=3000     搜索出来的镜像就是收藏量大于3000的。

过滤搜索镜像:

docker指令存档_第10张图片

4、拉取镜像
下载镜像
docker pull 镜像名[:tag]    # 如果不写tag,默认就是最新版本

docker指令存档_第11张图片

解决下载镜像慢!

##使用阿里云镜像加速器
[root@localhost ~]# mkdir -p /etc/docker
[root@localhost ~]# tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://9cpn8tt6.mirror.aliyuncs.com"]
}
EOF
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker

指定版本下载:

docker pull mysql:5.7

docker指令存档_第12张图片

查看下载的镜像:

docker指令存档_第13张图片

5、删除镜像

删除镜像:

rm:删除 i:images -f:强制删除 后面可以指定id来删除

docker rmi -f 容器id  #删除指定的容器
docker rmi -f 容器id 容器id 容器id  #删除多个容器
docker rmi -f $(docker images -aq)  #删除全部的容器

docker指令存档_第14张图片

容器命令

前提:必须有镜像才能创建容器,我们来下载一个centos镜像来测试学习。

docker pull centos

docker指令存档_第15张图片

1、启动
docker run [可选参数] image /bin/bash
​
#  参数说明
--name="Name"       容器名称  Tomcat01  Tomcat02  用来区分容器
-d                  后台方式运行
-it                 使用交互方式(需要给定控制台)运行,进入容器查看内容
​
-p                  指定容器的端口(四种方式)
    -p  ip:主机端口:容器端口
    -p  主机端口:容器端口(常用)
    -p  容器端口
    -p  随机指定端口
​

通过启动镜像进入容器:

/bin/bash:这个是指定的控制台

docker run -it  centos /bin/bash

docker指令存档_第16张图片

查看容器内的centos并退出:

exit            #   从容器中退回主机
Ctrl + P + Q    #   容器不停止退回主机

docker指令存档_第17张图片

docker指令存档_第18张图片

2、查看运行的容器
1、查看运行中的容器
docker ps
2、查看运行过的容器
docker ps -a
3、查看最近运行的容器
docker ps -a -n=1
4、查看当前所有容器的编号
docker ps -aq

docker指令存档_第19张图片

3、删除容器
docker rm 容器id                  #  删除指定的容器  ,不能删除正在运行的容器,如果要强制删除,rm -f  
​
docker rm -f $(docker ps -aq)    #  删除所有的容器
​
docker ps -a -q|xargs docker rm  #删除所有的容器

xargs 作用:将上个命令的输出作为参数传给 docker rm 这个命令

docker指令存档_第20张图片

4、启动&停止

注意:这里跟之前的 docker run [可选参数] image /bin/bash 不同,之前是第一次,没有容器id。

\textcolor{red}{启动容器后,还是在主机,并没有进入容器} !

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

docker指令存档_第21张图片

其他命令

1、后台启动容器
#  命令docker run -d 镜像名
docker run -d centos

docker指令存档_第22张图片

出现问题:

我们使用命令 docker ps 后,发现 centos 停止了。

\textcolor{blue}{常见的坑} :docker 容器使用后台运行,就必须要有一个前台进程,因为docker发现没有应用,就会自动停止。

例如安装Nginx:容器启动后,docker发现自己没有提供服务,就会立刻停止,就是没有程序了。

2、查看日志
# 自己编写一段shell脚本
docker run -d centos /bin/sh -c "while true;do echo giegie;sleep 1;done"
​
#  显示日志
--tf                #  显示日志  f:跟踪日志(实时显示)  t:时间戳(timestamps)
--tail number       #  要显示的尾部日志条数
​
[root@localhost ~]# docker logs -tf --tail 10 4b121dd5bc49

docker指令存档_第23张图片

3、查看容器内的进程信息
[root@localhost ~]# docker top 4b121dd5bc49
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                70910               70890               0                   20:52               ?                   00:00:00            /bin/sh -c while true;do echo giegie;sleep 1;done
root                73560               70910               0                   21:14               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
​

UID:用户id

PID:当前进程id

PPID:父进程id

4、查看镜像的元数据
docker inspect 容器id

docker指令存档_第24张图片

5、进入当前正在运行的容器

我们通常使用的容器是由后台方式运行的,所以需要进入容器内来修改一些配置。

方式一

docker exec:\textcolor{red}{进入容器后开启一个新的终端,可以在里面操作(常用)} 。

#  exec -it  前后台交互执行
docker exec -it 容器id /bin/bash

docker指令存档_第25张图片

方式二

docker attach:\textcolor{red}{进入容器正在执行的终端,不会启动新的进程} 。

docker attach 容器id

docker指令存档_第26张图片

6、从容器内拷贝文件到主机上

拷贝是一个手动过程,未来我们使用 -v 卷 的技术,可以实现。

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

docker指令存档_第27张图片

6、小结

docker指令存档_第28张图片

7、Docker安装Nginx

1、搜索镜像
docker search nginx
2、下载镜像
docker pull nginx
3、运行镜像
#  先查看镜像
docker images
​
#  取别名后运行
docker run -d --name nginx01 -p 3344:80 nginx

docker指令存档_第29张图片

4、测试

1、本地测试

curl localhost:3344

docker指令存档_第30张图片

2、外网测试(通过互联网)

docker指令存档_第31张图片

停止

docker指令存档_第32张图片

流程

docker指令存档_第33张图片

思考

我们每次改动Nginx配置文件,都需要进入容器内部?这就十分的麻烦,我们通过在容器外部提供一个映射路径,达到在容器外部修改文件,容器内部就可以自动修改。 -v 数据卷!

8、Docker安装Tomcat

我们之前的启动都是后台,停止容器之后,容器还是可以查到的

#  官方的使用,下载下来,运行后,就删除容器了(镜像还在)
docker run -it --rm tomcat:9.0

docker指令存档_第34张图片

docker指令存档_第35张图片

1、下载并启动
#  下载最新的Tomcat
docker pull tomcat
​
#  通过虚拟机端口3355映射内部tomcat端口8080,启动tomcat镜像来启动tomcat容器,取名为tomcat01
docker run -d -p 3355:8080 --name tomcat01 tomcat

docker指令存档_第36张图片

2、测试&问题

首先进入网站测试,404。之后我们进入容器:

docker exec -it tomcat01 /bin/sh

进入容器内发现问题:

1、Linux命令少了。

2、没有webapps。

docker指令存档_第37张图片

原因:阿里云镜像的原因,默认是最小的镜像,所有不必要的都剔除出去了。它是保证最小的可运行环境。

3、解决问题

将webapps.dist的内容全部拷贝到webapps里面。

cp -r webapps.dist/* webapps

docker指令存档_第38张图片

4、再测试

docker指令存档_第39张图片

思考

我们以后部署项目,每次都要进入容器,十分麻烦。我们要是可以在容器外提供一个映射路径,webapps,我们在外部放置项目,就自动同步到内部就好了。

9、部署es&kibana

es:暴露的端口多,而且十分耗内存,它的数据一般需要放置到安全目录,挂载。

官网启动弹性搜索(elasticsearch)

#  --net somenetwork:网络配置,暂时不需要
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag
1、启动
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2

docker指令存档_第40张图片

CPU资源有限,所以可能会卡。

docker指令存档_第41张图片

2、查看内存状态
docker stats

docker指令存档_第42张图片

3、停掉

docker指令存档_第43张图片

4、增加内存限制
#  修改配置文件  -e  环境配置修改
docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

docker指令存档_第44张图片

5、测试

docker指令存档_第45张图片

思考

使用kibana怎么用网络连接到es?

docker指令存档_第46张图片

10、可视化

portainer和Rancher(CI/CD)

1、什么是portainer?

Docker图形化界面管理工具!提供一个后台面板供我们操作。

docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

2、测试

外网测试:

http://192.168.85.129:8088/

docker指令存档_第47张图片

docker指令存档_第48张图片

内网测试:

curl localhost:8088

11、镜像

1、是什么?

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

所有的应用,直接打包docker镜像,就可以直接跑起来!

2、怎么获得?

1、从远程仓库下载

2、从朋友拷贝过来

3、自己制作DockerFile

#####

1、UnionFS

docker指令存档_第49张图片

2.镜像加载原理

docker指令存档_第50张图片

bootfs(文件加载系统):就像我们启动电脑->加载->界面,界面加载完成后,不需要加载了。

docker指令存档_第51张图片

阉割版

docker指令存档_第52张图片

资源复用

image-20211030000132710

3、镜像层&容器层

docker指令存档_第53张图片

image-20211030000807312

4、提交自己的镜像

docker commit 提交容器成为一个新的副本

#  命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]

1、启动
#  启动一个默认的tomcat
docker run -it -p 8080:8080 tomcat

docker指令存档_第54张图片

2、进入并拷贝
#  发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的镜像默认webapps下面是没有文件的!我们自行拷贝文件。
注意:这里新开了一个shell,之前的tomcat不要关闭了。

docker指令存档_第55张图片

3、提交镜像
#  将我们操作过的容器通过commit提交为一个镜像,我们以后就使用这个我们修改过的镜像即可。
docker commit -a="gay" -m="add webapps app" 709df7e3e649 tomcat02:1.0

docker指令存档_第56张图片

提交容器id后,在镜像中能看到新的镜像。也就是当前容器的状态!

类似于虚拟机里面的快照,可以回滚。

docker指令存档_第57张图片

12、Docker理念

将应用和环境打包成一个镜像。

持久化

如果数据都在容器中,那么我们容器删除,数据就会丢失。

\textcolor{red}{需求:数据可以持久化} 。

MySQL的容器删了,删库跑路?

\textcolor{red}{需求:MySQL的数据可以存储在本地} 。

容器之间可以有一个数据共享的技术,Docker容器中产生的数据,同步到本地!这就是卷技术,\textcolor{red}{目录的挂载} ,将我们容器内的目录挂载到Linux虚拟机上面。

同步操作

docker指令存档_第58张图片

13、容器数据卷(Volume)

容器的\textcolor{red}{持久化} 和\textcolor{red}{同步操作} ,容器间也是可以数据共享的。

方式一

同步文件

1、挂载 -v
#  直接使用命令来挂载  -v    通过主机目录映射容器内目录
docker run -it -v 主机目录:容器内目录 镜像 /bin/bash
​
#  测试:挂载到主机后进入容器
[root@localhost home]# docker run -it -v /home/ceshi:/home centos /bin/bash

docker指令存档_第59张图片

查看

#  在主机上查看上面的那个容器详情
docker inspect 容器id

image-20211030135721244

理解成在主机上创建了一个快捷方式,那么容器没了,主机上的那个也就没啥用了,跟着没了。有点不同的是,它文件内容是双向绑定的!

2、测试

在容器内建一个文件,测试主机上是否也生成一个对应的文件

docker指令存档_第60张图片

3、反向测试

在主机内修改文件,已经退出的容器依旧可以获取到文件内容!

#  exit 退出并停止容器   
#  ctrl + p + q 退出不会停止容器

docker指令存档_第61张图片

好处:\textcolor{red}{我们以后修改只需要在本地修改即可,容器内会自动同步} !

安装MySQL

1、下载
#  获取镜像
[root@localhost home]# docker pull mysql:5.7
​
#  运行容器,需要做数据挂载
#  -d:后台运行  -p:端口映射  -v:卷挂载  -e:环境配置  --name:容器别名
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

docker指令存档_第62张图片

2、测试连接

本地使用Navicat连接

docker指令存档_第63张图片

本地新建一个数据库,去Linux上面查看

docker指令存档_第64张图片

假设我们将主机上的容器删除,我们挂载到本地的数据卷依旧存在,这就实现了容器的持久化功能。

相当于只删除了一个快捷方式而已。

docker指令存档_第65张图片

具名&匿名挂载

1、匿名挂载
#  匿名挂载
-v 容器内路径! -P 随机映射端口(注:p是大写的)
docker run -d -P --name nginx01 -v /etc/nginx nginx
​
#  查看所有的volume的情况
docker volume ls

docker指令存档_第66张图片

2、具名挂载
#  具名挂载  -v  卷名:容器内路径  区别之前我们是:  -v /xx/xx:/xx/xx
docker run -d -P --name nginxginx02 -v juming-nginx:/etc/nginx nginx
​
#  查看一下这个卷
docker volume inspect juming-nginx

docker指令存档_第67张图片

3、卷路径

所有的docker容器内的卷,没有指定目录的情况下都是在

/var/lib/docker/volumes/xxxx/_data

docker指令存档_第68张图片

4、判断是哪种挂载?
#  如何确定是具名挂载还是匿名挂载,还是指定路径挂载?
#   1、匿名挂载
-v  容器内路径
#   2、具名挂载
-v  卷名:容器内路径
#   3、指定路径挂载
-v  /宿主机路径:容器内路径
​
拓展:
#   通过 -v 容器内路径:ro rw 改变读写权限
只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的。
ro:     readonly        #只读
rw:     readwrite       #可读可写,默认是这个
​
#   一旦设置了容器权限,那么容器对我们挂载出来的内容就有限定了。
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

初识DockerFile

方式二

DockerFile就是用来构建docker镜像的构建文件!命令脚本!

通过这个脚本可以生成镜像,镜像是一层一层的,所以脚本是一个一个的命令,每个命令都是一层。

1、构建自己的镜像
#  创建一个dockerfile文件,名字可以随机,建议DockerFile
​
[root@localhost docker-test-volume]# cat dockerfile1 
FROM centos
​
#  -f:文件的地址  -t:生成的镜像名               构建,在哪里呢?名字呢?
[root@localhost docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t chenjun/centos:1.0 .
​
#  文件中内容,注意VOLUME之后要有个空格。指令(大写)参数,这里的每个命令,就是镜像的一层,这种是匿名挂载
FROM centos
​
VOLUME ["volume01","volume02"]
​
CMD echo "----end----"
​
CMD /bin/bash

将chenjun/contos:1.0挂载到cenos(即FROM centos)

docker指令存档_第69张图片

2、匿名挂载同步查看

docker指令存档_第70张图片

数据卷容器

docker指令存档_第71张图片

1、容器挂载
通过我们刚才写的自己的镜像来启动三个容器
docker run -it --name docker01 容器id或者自己取的容器名
#  --volumes-fom:将docker02挂载到docker01上面
docker run -it --name docker02 --volumes-fom docker01 容器id或者自己取的容器名

docker指令存档_第72张图片

docker03挂载到docker01上面

docker指令存档_第73张图片

2、删除测试

哪怕你删除了docker01,其他两个不会收到影响, --volumes-fom 类似于备份一样。他们都是挂载到宿主机上面了!

区别于之前的挂载,那是一种类似创建快捷方式(双向、共享),!

注意:容器需要先启动,你才能通过 exec -it 或者 attach 进入。

docker指令存档_第74张图片

多个MySQL实现数据共享
docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
​
docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 mysql:5.7

结论

容器之间配置信息的传递,数据卷容器的声明周期一直持续到没有容器使用为止。

但是一旦你持久化到了本地(-v),这个时候,本地的数据是不会删除的。

再见DockerFile

DockerFile就是用来构建docker镜像的构建文件!命令脚本!

构建步骤
  • 1、编写一个DockerFile文件

  • 2、docker build 构建成为一个镜像

  • 3、docker run 运行镜像

  • 4、docker pull 发布镜像(DockerHub、阿里云镜像仓库!)

很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像。

构建过程
  • 1、每个保留关键字(指令)都必须是大写字母

  • 2、从上到下的顺序执行

  • 3、# 表示注释

  • 4、每一个指令都会创建提交一个新的镜像层,并提交!

docker指令存档_第75张图片

DockerFile是面向开发的,我们以后需要发布项目,做镜像,就需要编写DockerFile文件。Docker镜像逐渐成为企业交付的标准。

DockerFile:构建文件,定义了一切的步骤,源代码。

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品。

Docker容器:容器就是镜像运行起来提供服务器。

DockerFile指令

通过DockerFile指令,我们可以自己写镜像!

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

docker指令存档_第76张图片

实战测试
1、编写DockerFile
#  编写一个自己的DockerFile文件  echo:输出  在原有的centos上写自己的镜像。
​
FROM centos
MAINTAINER chenjun<[email protected]>
​
ENV MYPATH /usr/local
WORKDIR $MYPATH
​
RUN yum install -y vim
RUN yum install -y net-tools
​
EXPOSE 80
​
CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash
​
​
#  构建  -f:DockerFile文件路径  -t:镜像名:[tag]
docker build -f mydockerfile-centos -t mycentos:0.1 .

原本是没有vim命令的,现在我们给他装上。

docker指令存档_第77张图片

2、测试

docker指令存档_第78张图片

查看构建历史

这个查看历史可以方便我们查看别的镜像是怎么构建的!!!

[root@localhost docker-file]# docker history 镜像id

docker指令存档_第79张图片

CMD&ENTRYPOINT
CMD         # 指定这个容器启动时需要运行的命令,只有最后一个会生效,可被替代。
ENTERYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令

1、测试CMD
vim dockerfile-cmd-test  #  建文件
​
FROM centos
CMD ["ls","-a"]
​
#  构建DockerFile,即自己的镜像
docker build -f dockerfile-cmd-test -t cmdtest .
​
#  运行,这里的镜像没有版本号,所以不用加
docker run -it cmdtest

docker指令存档_第80张图片

替换,不可追加!

[root@localhost docker-file]# docker run -it cmdtest -l
​
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled
​
#  cmd的情况下,-l 替换了CMD["ls","-a"]命令,-l不是命令,所以报错了。

docker指令存档_第81张图片

2、测试ENTRYPOINT

可追加!

vim dockerfile-cmd-entrypoint  #  建文件
​
FROM centos
ENTRYPOINT ["ls","-a"]
​
#  构建DockerFile,即自己的镜像
docker build -f dockerfile-cmd-entrypoint -t entrypoint-test .

docker指令存档_第82张图片

Tomcat镜像
  • 1、准备镜像文件 tomcat 压缩包,jdk 的压缩包。

docker指令存档_第83张图片

  • 2、编写DockerFile文件,官方命名\textcolor{red}{Dockerfile} ,build会自动寻找这个文件,就不用 -f 去指定了。

  • 3、构建生成的目标镜像 docker build -t diytomcat . 这个 diytomcat 就是我们的镜像!

docker指令存档_第84张图片

Dockerfile
FROM centos
MAINTAINER chenjun<[email protected]>
​
COPY readme.txt /usr/local/readme.txt
​
ADD jdk-8u11-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.22.tar.gz /usr/local/
​
RUN yum install -y vim
​
ENV MYPATH /usr/local
WORKDIR $MYPATH
​
​
ENV MYPATH /usr/local
WORKDIR $MYPATH
​
ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
​
EXPOSE 8080
​
​
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out

运行&挂载
[root@localhost tomcat]# docker run -d -p 9090:8080 --name chenjuntomcat -v /home/chenjun/build/tomcat/test://usr/local/apache-tomcat-9.0.22/webapps/test -v /home/chenjun/build/tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.22/logs diytomcat

docker指令存档_第85张图片

测试

docker指令存档_第86张图片

主机修改tomcat

docker指令存档_第87张图片

web.xml


     

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




hello. xiaofan


Hello World!
<% System.out.println("-----my test web logs------"); %>

外网访问

docker指令存档_第88张图片

catalina.out
[root@localhost tomcatlogs]# pwd
/home/chenjun/build/tomcat/tomcatlogs

#  查看多少人访问了我们的这个服务器
[root@localhost tomcatlogs]# cat catalina.out 

发布自己的镜像

DockerHub

  • 1、地址:https://hub.docker.com/ 注册自己的账号

  • 2、登录:docker login -u jc110

  • 3、标签:docker tag 镜像id jc110/tomcat:1.0

  • 4、推送:docker push jc110/tomcat:1.0

DockerHub

docker指令存档_第89张图片

docker指令存档_第90张图片

阿里云

阿里云镜像服务

  • 1、登录阿里云

  • 2、找到容器镜像服务

  • 3、创建命名空间

  • 4、创建容器镜像

  • 5、docker登录后推送

$ docker login --username=jc_s**** registry.cn-hangzhou.aliyuncs.com
$ docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/gay/gaytest:[镜像版本号]
$ docker push registry.cn-hangzhou.aliyuncs.com/gay/gaytest:[镜像版本号]

docker指令存档_第91张图片

docker指令存档_第92张图片

报错:

Error response from daemon: Get "https://registry.cn-hangzhou.aliyuncs.com/v2/": unauthorized: authentication required

解决:

docker指令存档_第93张图片

登录

docker login --username=jc_study registry.cn-hangzhou.aliyuncs.com

docker指令存档_第94张图片

docker指令存档_第95张图片

查看

docker指令存档_第96张图片

Docker流程

docker save保存的是镜像(image),docker export保存的是容器(container)。

docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像。

docker指令存档_第97张图片

docker指令存档_第98张图片

docker指令存档_第99张图片

14、Docker网络

1、清空环境
#   我们先删除所有的容器和镜像
#   强制删除所有的容器
[root@localhost ~]# docker rm -f $(docker ps -aq)
#   强制删除所有的镜像
[root@localhost ~]# docker rmi -f $(docker images -aq)

docker指令存档_第100张图片

docker指令存档_第101张图片

2、查看地址
#   查看地址 ip a  或者  ip addr  或者  ifconfig
[root@localhost ~]# ip a

docker指令存档_第102张图片

3、问题

docker是如何处理容器网络访问的?

image-20211031133128494

1、启动容器并查ip
#   拉取并通过后台运行tomcat镜像来启动容器
[root@localhost ~]# docker run -d -P --name tomcat01 tomcat

#   查看容器的内部网络地址  ip addr
[root@localhost ~]# docker exec -it tomcat01 ip addr

遇到问题:

#   docker exec -it tomcat01 ip addr错误docker没有ip指令
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip": executable file not found in $PATH: unknown

解决问题:

#   进入容器执行    apt-get update & apt-get install -y iproute2
root@93989b839391:/usr/local/tomcat# apt-get update & apt-get install -y iproute2

docker指令存档_第103张图片

#   发现容器启动的时候会得到一个docker分配的  eth0@if97 的ip地址

docker指令存档_第104张图片

2、ping测试
#   Linux虚拟机ping通docker容器内部
[root@localhost ~]# ping 容器ip

docker指令存档_第105张图片

原理

172.17.0.1 这个是docker给我们的主机的ip

172.17.0.2 这个是docker给我们的容器(tomcat01)的ip

我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的技术是 veth-pair 技术!

启动容器后我们再次测试 ip a

docker指令存档_第106张图片

97: eth0@if96

容器内 ip addr

image-20211031155513211

96: eth0@if97

再启动一个tomcat测试

image-20211031151226644

99: vethd82c62d@if98

进入容器后 ip a

172.17.0.2 这个是docker给我们的容器(tomcat02)的ip

docker指令存档_第107张图片

98: eth0@if99

我们发现这个容器带来网卡,都是一对一对的

veth-pair就是一对的虚拟机接口,他们都是成对出现的,一端连着协议,一端彼此相连。(veth意思是virtual ethernet,虚拟以太网连接)

正因为这个特性,veth-pair 充当一个桥梁,连接各种 虚拟网络设备的

OpenStac,Docker容器之间的连接,OVS的连接,都是使用veth-pair

tomcat01和tomcat02 都在同一个网段,所以它两都是可以相互ping通的,即:容器和容器之间是可以相互ping通的!

docker exec -it tomcat02 ping 172.17.0.2

绘制网络模型图

docker指令存档_第108张图片

结论:tomcat01和tomcat02 是共用的一个路由器,docker0。

所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。

小结

Docker使用的是Linux的桥接,宿主机中是一个Docker容器的网桥 docker0 。

docker指令存档_第109张图片

Docker中所有的网络接口都是虚拟的,虚拟的转发效率高!(内网传递文件,很快。)

只要容器停止/删除,对应的网桥一对就没有了。

255.255.0.1/16

可用主机数:2 的16次方 -2 (减去网关和广播)= 65 534

255.255.255.255

11111111.11111111.11111111.11111111

前16个叫网络位,后16个是主机位。与或算法

思考

我们编写微服务的时候需要绑定数据库,database url=ip:,项目不重启,数据库ip换掉了,我们怎么处理这个问题?可以用名字来进行容器的访问。

这里启动不同的容器ip都不同,这怎搞?

解决:类似springcloud的feign去Nacos找服务名即可。

#   以交互方式进入正在运行的容器  tomcat02
[root@localhost ~]# docker exec -it tomcat02 /bin/bash
#   发现  tomcat02的 ping 命令无法使用
root@db1ab920ec45:/usr/local/tomcat# ping tomcat01

#   解决   apt install iputils-ping
#   如果执行错误,先执行这个: apt-get update
root@db1ab920ec45:/usr/local/tomcat# apt install iputils-ping

tomcat02去ping通tomcat01测试

docker指令存档_第110张图片

#   出现问题
root@db1ab920ec45:/usr/local/tomcat# ping tomcat01
ping: tomcat01: Name or service not known
#   怎么解决?
[root@localhost ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat


#   出现问题
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ping": executable file not found in $PATH: unknown
#   怎么解决?
root@dfdd58783733:/usr/local/tomcat# apt-get update & apt-get install -y iproute2


#   出现问题
bash: ping: command not found
#   怎么解决?
root@dfdd58783733:/usr/local/tomcat# apt install iputils-ping
#   如果执行错误,先执行这个: apt-get update

docker指令存档_第111张图片

docker指令存档_第112张图片

之前我们是通过ip去ping通的,现在我们link过后直接通过服务名去ping通!

#   列举网络
[root@localhost ~]# docker network ls

#   查看网络详情
[root@localhost ~]# docker network inspect 2704ec4445bc

docker指令存档_第113张图片

docker指令存档_第114张图片

之前我们用tomcat03去连接tomcat02

docker run -d -P --name tomcat03 --link tomcat02 tomcat

#   查看host配置,在这里原理发现!
[root@localhost ~]# docker exec -it tomcat03 cat /etc/hosts

docker指令存档_第115张图片

--link 就是我们在 hosts 配置中增加了一个 172.17.0.3 tomcat02 db1ab920ec45,但是tomcat02却没有绑定tomcat01。

我们现在已经不建议使用--link了。自定义网络,不使用docker0.

docker0的问题:他不支持容器名连接访问。

4、自定义网络
#   查看所有的docker网络
[root@localhost ~]# docker network ls

docker指令存档_第116张图片

网络模式

bridge:桥接 docker 搭桥(默认,自己架构也使用这个)

host:和宿主机共享网络

none: 不配置网络

container:容器内网络连通(用的少,局限很大)

测试

1、清理环境

docker指令存档_第117张图片

2、创建我们自己的网络
#   我们直接启动命令  --net bridge ,而这个是我们的docker0
#   平常写法
[root@localhost ~]# docker run -d -P --name tomcat01
#   相当于下面这种默认的
[root@localhost ~]# docker run -d -P --name tomcat01 --net bridge tomcat


#   docker0特点:默认的,域名不能访问,--link可以打通连接。
#   我们可以自定义一个网络

#   --driver bridge
#   --subnet 192.168.0.0/16 可以支持255*255个网络 192.168.0.2 ~ 192.168.255.254
# 	--gateway 192.168.0.1

[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

docker指令存档_第118张图片

查看我们自己配置的网络的详情

[root@localhost ~]# docker network inspect mynet

docker指令存档_第119张图片

3、启动测试我们自己的网络
[root@localhost ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
​
[root@localhost ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
​
[root@localhost ~]# docker network inspect mynet

docker指令存档_第120张图片

docker指令存档_第121张图片

#   再次测试两个容器的ping连接,可以成功
docker exec -it tomcat-net-01 ping 192.168.0.3

我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐平时这样使用网络!

好处:不同的集群使用不同的网络,保证集群是安全和健康的。

4、网络连通

docker指令存档_第122张图片

docker指令存档_第123张图片

docker指令存档_第124张图片

#   将tomcat01和mynet连通
docker network connect  mynet tomcat01
 
#   连通之后就是将tomcat01 放到了mynet网路下
#   一个容器两个ip地址:
#   例如:阿里云服务器,公网ip,私网ip

#   tomcat01容器去ping我们自己的网络
docker exec -it tomcat01 ping tomcat-net-01

结论:假设我们需要跨网络操作别人,就需要使用 docker network connect 连通!

15、Redis集群部署实战

docker指令存档_第125张图片

# 创建网卡
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

# 创建结点1
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
 
#创建结点2
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

#创建结点3
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

#创建结点4
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

#创建结点5
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

#创建结点6
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@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof  nodes.conf

/data # 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.16:6379 --cluster-replicas 1

1、redis集群的搭建

docker指令存档_第126张图片

docker指令存档_第127张图片

2、停掉主机&获取值

docker指令存档_第128张图片

3、查看集群节点信息

docker指令存档_第129张图片

16、打包镜像

Springboot微服务打包Docker镜像

  • 1、架构springboot项目

  • 2、打包应用

  • 3、编写DockerFile

  • 4、构建镜像

  • 5、发布运行

1、打包项目

docker指令存档_第130张图片

打开 demo-0.0.1-SNAPSHOT.jar 的文件位置,然后cmd

java -jar demo-0.0.1-SNAPSHOT.jar

下载docker插件

docker指令存档_第131张图片

2、编写Dockerfile

docker指令存档_第132张图片

FROM java:8
​
COPY *.jar /app.jar
​
CMD ["--server.port=8080"]
​
EXPOSE 8080
​
ENTRYPOINT ["java", "-jar", "/app.jar"]

3、构建镜像

docker指令存档_第133张图片

4、测试访问

本地测试

docker指令存档_第134张图片

使用了Docker之后,给别人交付的就是一个镜像就可以了!!!

外网访问

docker指令存档_第135张图片

关闭防火墙

systemctl stop firewalld

开机自动关闭防火墙

systemctl disable firewalld

你可能感兴趣的:(docker,容器,运维)