Docker命令

帮助命令

docker version 显示版本信息

docker info 显示系统信息,包括镜像和容器的数量

docker 命令 --help

systemctl restart docker.service 重启docker

镜像命令

docker images 查看所有本地的主机上的镜像

docker search 搜索镜像

容器命令

新建容器并启动:docker run [可选参数] images

调试,启动并进入容器:docker run -it centos /bin/bash

docker其他命令

docker ps 命令

-a #列出正在运行的容器+带出历史运行过的容器

-n=? #显示最近创建过的容器

-q #只显示容器的编号

退出容器

exit #直接容器停止并退出

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

删除容器

docker rm 容器id #删除指定容器,不能删除正在运行的容器

docker rm -f $(docker ps -aq) #删除所有容器

docker ps -a -q|xargs docker rm #删除所有容器

查看日志

docker logs -f -t --tail 容器

自己编写一段shell脚本

[root@linuxprobe ~]# docker run -d centos /bin/sh -c 'while true;do echo wsnd;sleep 1;done'

[root@linuxprobe ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
834f5c4d5db7 centos "/bin/sh -c 'while t…" 2 seconds ago Up 2 seconds angry_austin

显示日志

-tf #显示日志

--tail number #要显示日志条数

[root@linuxprobe ~]# docker logs -f -t --tail 10 834f5c4d5db7

查看容器中进程信息

命令 docker top 容器id

[root@linuxprobe ~]# docker top 834f5c4d5db7
UID PID PPID C STIME TTY TIME CMD
root 22144 22125 0 15:30 ? 00:00:00 /bin/sh -c while true;do echo wsnd;sleep 1;done
root 22763 22144 0 15:40 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1

查看镜像的元数据

命令

docker inspect 容器id

进入当前正在运行的容器

通常容器使用后台方式运行,需要进入容器,修改一些配置

命令

docker exec -it 容器id /bin/bash

测试

[root@linuxprobe ~]# docker exec -it 834f5c4d5db7 /bin/bash
[root@834f5c4d5db7 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@834f5c4d5db7 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:30 ? 00:00:00 /bin/sh -c while true;do echo wsnd;sleep 1;done
root 1058 0 0 07:48 pts/0 00:00:00 /bin/bash
root 1088 1 0 07:48 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root 1089 1058 0 07:48 pts/0 00:00:00 ps -ef

方法二

docker attach 容器id

测试

[root@834f5c4d5db7 /]# docker attach 834f5c4d5db7

正在执行当前的代码...

docker exec 进入容器后开启一个新的终端,可以在里面操作(常用)

docker attach 进入容器正在执行的终端,不会启动新的连接

从容器拷贝文件到主机上

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

查看当前主机目录下

[root@linuxprobe home]# ls
linux linuxprobe workdir
[root@linuxprobe home]# touch wsnd.java
[root@linuxprobe home]# ls
linux linuxprobe workdir wsnd.java
[root@linuxprobe home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
484ac31e25ea centos "/bin/bash" 2 minutes ago Up 2 minutes friendly_engelbart

进入docker容器内部

[root@linuxprobe home]# docker attach 484ac31e25ea
[root@484ac31e25ea /]# cd /home/
[root@484ac31e25ea home]# ls

在容器内新建一个文件

[root@484ac31e25ea home]# touch test.java
[root@484ac31e25ea home]# exit
exit
[root@linuxprobe home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@linuxprobe home]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
484ac31e25ea centos "/bin/bash" 3 minutes ago Exited (0) 13 seconds ago friendly_engelbart

将该文件拷贝出来到主机上

[root@linuxprobe home]# docker cp 484ac31e25ea:/home/test.java /home
[root@linuxprobe home]# ls
linux linuxprobe test.java workdir wsnd.java

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

作业练习

Docker安装Nginx

1、搜索镜像 search 建议去docker hub上搜索,可以看到帮助文档信息

2、下载镜像 pull

3、运行测试

[root@linuxprobe ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 7 weeks ago 141MB
mysql 5.7 c20987f18b13 2 months ago 448MB
mysql latest 3218b38490ce 2 months ago 516MB
hello-world latest feb5d9fea6a5 5 months ago 13.3kB
centos latest 5d0da3dc9764 5 months ago 231MB

-d 后台运行

--name 给容器命名

-p 宿主机端口,容器内部端口

[root@linuxprobe ~]# docker run -d --name nginx01 -p 3344:80 nginx
ec6edcb08308222e76b67558602e9d77c5b36e46c11addaf75d8d459a971468e
[root@linuxprobe ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec6edcb08308 nginx "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[root@linuxprobe ~]# curl localhost:3344

端口暴露的概念

思考:每次改动 nginx配置文件都需要进入容器内部?十分麻烦,要是可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改? -v 数据卷!

作业:docker来装一个Tomcat

官方的使用

docker run -it --rm tomcat:9.0

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

docker run -it --rm ,一般用完即删

下载在启动

docker pull tomcat

启动运行

docker run -d -p 3355:8080 --name tomcat01 tomcat

测试访问没有问题

[root@linuxprobe ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat
a5f6c59194b6de8f14a25f2e18779a3218eb0c1f1da2eeddf40b538dbeea2424

进入容器

[root@linuxprobe ~]# docker exec -it tomcat01 /bin/bash

发现问题:1、linux命令少了。 2、没有webapps,阿里云镜像的原因,默认是最小的镜像,所有不必要的都剔除掉。

保证最小可运行的环境

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

部署es+kibana

es 暴露的端口很多

es 十分耗内存

es 的数据一般需要放置到安全目录!挂载

--net somenetwork ? 网络配置

启动elasticsearch

$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2

启动了linux就小卡 docker stats 查看cpu的状态

es是十分耗内存的,1.xG 1核2G!

查看 docker stats

测试一下es是否成功

[root@linuxprobe ~]# curl localhost:9200
{
"name" : "4fa5278395e5",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "zVNHDHddSWWEB7kavXWMng",
"version" : {
"number" : "7.6.2",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
"build_date" : "2020-03-26T06:34:37.794943Z",
"build_snapshot" : false,
"lucene_version" : "8.4.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}

赶紧关闭,增加内存的限制,修改配置文件 -e 环境配置修改

docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms512m" elasticsearch:7.6.2

查看 docker stats

使用kibana连接es ? 思考网络如何才能连接过去?

可视化

portainer(先用这个)

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

Rancher(CI/CD再用)

什么是portainer ?

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

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

访问测试:http://ip:8088/

通过它来访问了:

选择本地的local选项

进入之后的面板:

平时不用,测试玩玩

commit镜像

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

# 命令和git原理类似

docker tomcat -m="提交的描述信息" -a=“作者” 容器id 目标镜像名,[TAG]

实战测试

# 1、启动一个默认的tomcat

# 2、发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的镜像默认webapps下面是没有文件的!

# 3、我自己拷贝进去了基本的文件

# 4、将我们操作过的容器通过commit提交为一个镜像!前面以后就用我们修改过的镜像即可。这就是我们自己的一个修改的镜像

如果想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,好比VM快照!

到了这里才算是入门Docker

容器数据卷

什么是容器数据卷

docker理念:将应用和环境打包成一个镜像

数据?如果数据都在容器中,那么容器删除,数据就会丢失!需求:数据可以持久化!

MySQL,容器删了,删库跑路!需求:MySQL数据可以存储在本地!

容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!

这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!

总结:容器的持久化和同步操作!容器间也是可以数据共享的!

使用数据卷

方式一:直接使用命令来挂载 -v

docker run -it -v -p 主机端口,容器内目录

# 测试

[root@linuxprobe home]# docker run -it -v /home/ceshi:/home centos /bin/bash

# 启动起来之后可以通过 docker inspect 容器id

测试文件的同步

再来测试!

  1. 停止容器
  2. 宿主机上修改文件
  3. 启动容器
  4. 容器内的数据依旧是同步的

好处:以后修改只需要在本地修改即可,容器内会自动同步!

实战:安装MySQL

思考:MySQL的数据持久化问题

# 获取镜像
[root@linuxprobe home]# docker pull mysql:5.7

# 运行容器,需要做数据挂载!
# 安装启动mysql,需要配置密码!
# 官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动我们的
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器
[root@linuxprobe home]# 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

# 启动成功之后,我们在本地使用sqlyog来连接测试一下
# sqlyog 连接到服务器的3310 ----  3310 和容器内的3306映射,这个时候就可以连接上了!

# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok!

假设我们将容器删除,发现我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能!

具名和匿名挂载
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /ect/nginx nginx

# 查看所有的 volume 的情况
[root@linuxprobe home]# docker volume ls
local     72a2ba8626cb0705e6c800598953d43461ed67388168c56b6653841815d10b61

# 这里发现,这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径!

#具名挂载
[root@linuxprobe home]# docker run -d -P --name nginx002 -v juming-nginx:/etc/nginx nginx
ad7f44d82a1247a67ade0bcffa4e01683610e7a25b3e06eca15521bf9ec3cf4c
[root@linuxprobe home]# docker volume ls
DRIVER    VOLUME NAME
local     72a2ba8626cb0705e6c800598953d43461ed67388168c56b6653841815d10b61
local     a2d6dececd85969a5affc6d53632dd660bc771c7ebef4c46c6a9141094c83b54
local     juming-nginx

# 通过 -v 卷名:容器内路径
# 查看一下这个卷

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

通过具名挂载可以方便找到我们的每一个卷,大多数情况使用具名挂载!

# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径    # 匿名挂载
-v 卷名:容器内路径  #具名挂载
-v /宿主机路径::容器内路径   #指定路径挂载

拓展:

# 通过 -v 容器内路径:ro  rw   改变读写权限
ro   readonly  # 只读
rw   readwrite # 可读可写

# 一旦设置了容器权限,容器对我们挂载啊出来的内容就有限定了!
[root@linuxprobe _data]# docker run -d -P --name nginx002 -v juming-nginx:/etc/nginx:ro nginx
[root@linuxprobe _data]# docker run -d -P --name nginx002 -v juming-nginx:/etc/nginx:rw nginx

# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的!
初识DockerFile

Dockerfile就是用来构建docker镜像的构建文件!命令脚本!先体验一下!

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

# 创建一个dockerfile文件,名字可以随随机 建议dockerfile
# 文件中的内容 指令(大写) 参数

FROM centos

VOLUME ["volume01","volume02"]

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

# 这里的每个命令,就是镜像的一层

# 启动自己写的容器 

这个卷和外部一定有一个同步的目录!

查看一下卷挂载的路径

测试一下刚才的文件是否同步出去了!

这种方式使用的十分多,因为我们通常会构建自己的镜像!

假设构建镜像的时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!

数据卷容器

多个mysql同步数据!

# 启动2个容器,通过我们刚才自己写的镜像启动
[root@linuxprobe ~]# docker run -it --name docker001 linuxprobe/centos:1.0

[root@linuxprobe ~]# docker run -it --name docker002 --volumes-from docker001 linuxprobe/centos:1.0

# 测试:可以删除docker001,查看一下docker002是否可以访问这个文件
# 测试依旧可以访问

多个mysql可以实现数据共享

[root@linuxprobe home]# 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

[root@linuxprobe home]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

# 这个时候可以实现两个容器数据同步!

结论:

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

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

DockerFile

DockerFile介绍

dockerfile 是用来构建docker镜像的文件!命令参数脚本!

构建步骤:

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

查看一下官方是怎么做的

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

DockerFile构建过程

基础知识:

  1. 每个保留关键字(指令)都必须是大写字母
  2. 执行从上到下顺序执行
  3. 表示注释

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

dockerfile是面向开发的,以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!

Docker镜像逐渐成为了企业交付的标准,必须要掌握!

步骤:开发,部署,运维。。。缺一不可!

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

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

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

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

实战测试

Docker Hub 中99%的镜像都是从这个基础镜像过来的 FROM scratch ,然后配置需要的软件和配置来进行的构建

创建一个自己的centos

# 1、编写Dockerfile的文件
[root@linuxprobe dockerfile]# cat mydockerfile-centos 
FROM centos
MAINTAINER yuanbao<1186286729@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

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

EXPOSE 80

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

# 2、通过这个文件构建镜像
# 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag]

Successfully built 3c6466fa24cc
Successfully tagged mydentos:0.1

# 3、测试运行

对比:之前原生的centos

我们可以列出本地镜像的变更历史

平时拿到一个镜像就可以研究它是怎么做的了?

CMD 和 ENTRYPOINT 区别

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

测试cmd

[root@linuxprobe dockerfile]# vim dockerfile-cmd-test
FROM centos:7
CMD ["ls","-a"]

# 构建镜像
[root@linuxprobe dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .

# run运行,发现我们的 ls -a 命令生效
[root@linuxprobe dockerfile]# docker run d4036e105735
.
..
.dockerenv
anaconda-post.log
bin
dev
etc
home
lib

# 想追加一个命令 -l    ls -al
[root@linuxprobe dockerfile]# docker run d4036e105735 -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.

# cmd 的情况下 -l 替换了 CMD ["ls","-a"] 命令,-l 不是命令所以报错!

测试 ENTRYPOINT

[root@linuxprobe dockerfile]# vim dockerfile-cmd-entrypoint
FROM centos:7
ENTRYPOINT ["ls","-a"]

[root@linuxprobe dockerfile]# docker build  -f dockerfile-cmd-entrypoint -t entrypointtest .
Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/2 : ENTRYPOINT ["ls","-a"]
 ---> Running in bb95719e841e
Removing intermediate container bb95719e841e
 ---> 7e3585974736
Successfully built 7e3585974736
Successfully tagged entrypointtest:latest
[root@linuxprobe dockerfile]# docker run 7e3585974736
.
..
.dockerenv
anaconda-post.log
bin
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

# 我们的追加命令,是直接拼接在 ENTRYPOINT 命令后面
[root@linuxprobe dockerfile]# docker run 7e3585974736 -l
total 12
drwxr-xr-x   1 root root     6 Mar  1 07:13 .
drwxr-xr-x   1 root root     6 Mar  1 07:13 ..
-rwxr-xr-x   1 root root     0 Mar  1 07:13 .dockerenv
-rw-r--r--   1 root root 12114 Nov 13  2020 anaconda-post.log
lrwxrwxrwx   1 root root     7 Nov 13  2020 bin -> usr/bin
drwxr-xr-x   5 root root   340 Mar  1 07:13 dev
drwxr-xr-x   1 root root    66 Mar  1 07:13 etc
drwxr-xr-x   2 root root     6 Apr 11  2018 home
lrwxrwxrwx   1 root root     7 Nov 13  2020 lib -> usr/lib
lrwxrwxrwx   1 root root     9 Nov 13  2020 lib64 -> usr/lib64
drwxr-xr-x   2 root root     6 Apr 11  2018 media
drwxr-xr-x   2 root root     6 Apr 11  2018 mnt
drwxr-xr-x   2 root root     6 Apr 11  2018 opt
dr-xr-xr-x 128 root root     0 Mar  1 07:13 proc
dr-xr-x---   2 root root   114 Nov 13  2020 root
drwxr-xr-x  11 root root   148 Nov 13  2020 run
lrwxrwxrwx   1 root root     8 Nov 13  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root     6 Apr 11  2018 srv
dr-xr-xr-x  13 root root     0 Mar  1 07:13 sys
drwxrwxrwt   7 root root   132 Nov 13  2020 tmp
drwxr-xr-x  13 root root   155 Nov 13  2020 usr
drwxr-xr-x  18 root root   238 Nov 13  2020 var

Dockerfile中很多命令都十分相似,需要了解区别,最好的学习就是对比它们然后测试效果!

实战:Tomcat镜像

1、准备镜像文件 tomcat 压缩包,jdk的压缩包!

2、编写dockerfile文件,官方命名 Dockerfile ,build 会自动寻找这个文件,就不需要 -f 指定了!

[root@linuxprobe yuanbao]# vim Dockerfile

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u321-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.59.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_321
ENV CLASSPATH $JAVA_HOME/lib.dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.59
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.59
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.59/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.59/bin/logs/catalina.out

3、构建镜像

# docker build -t diytomcat .

4、启动镜像

5、访问测试

6、发布项目(由于做了卷挂载,我们直接)

  <?xml version="1.0" encoding="UTF-8"?>
  <web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                               http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">

      
      
  </web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello,yuanbao</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("----my test web logs----");
%>
</body>
</html>
docker run -d -p 9090:8080 --name yuanbaotomcat6 -v /home/yuanbao/test/WEB-INF:/usr/local/apache-tomcat-9.0.59/webapps/test -v /home/yuanbao/tomcatlogs/:/usr/local/apache-tomcat-9.0.59/logs diytomcat

发现:项目部署成功,可以直接访问ok!

我们以后开发的步骤:需要掌握Dockerfile的编写!之后的一切都是用docker镜像来发布运行!

发布自己的镜像

DockerHub

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

2、确定这个账号可以登陆

3、在我们的服务器上提交自己的镜像

[root@linuxprobe home]# docker login --help

Usage:  docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username

[root@linuxprobe home]# docker login -u kodakku
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

4、登陆完毕后就可以提交镜像了,就是一步 docker push

# push自己的镜像到服务器上面!
[root@linuxprobe home]# docker push diytomcat
Using default tag: latest
The push refers to repository [docker.io/library/diytomcat]
8e10b60e4630: Preparing 
bac617ae4a9b: Preparing 
349908d5cce0: Preparing 
94b615fb0a9e: Preparing 
174f56854903: Preparing  
denied: requested access to the resource is denied # 拒绝

# push镜像的问题
[root@linuxprobe home]# docker push yuanbao/diytomcat:1.0
The push refers to repository [docker.io/yuanbao/diytomcat]
An image does not exist locally with the tag: yuanbao/diytomcat

# 解决:增加一个 tag (kodakku 为 DockerHub 账号)
[root@linuxprobe home]# docker tag a22e626ad7dc kodakku/tomcat:1.0

# docker push上去即可!自己发布的镜像尽量带版本号
[root@linuxprobe home]# docker push kodakku/tomcat:1.0
The push refers to repository [docker.io/kodakku/tomcat]
8e10b60e4630: Pushed 
bac617ae4a9b: Pushed 
349908d5cce0: Pushed 
94b615fb0a9e: Pushed 
174f56854903: Pushed 

提交的时候也是按照镜像的层级来进行提交的!

阿里云镜像服务器上

1、登陆阿里云

2、找到镜像服务

3、创建命名空间

4、创建容器镜像

5、浏览阿里云

阿里云容器镜像的就参考官方地址!

小结

Docker 网络

理解Docker0

清空所有环境

测试

三个网络

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

[root@linuxprobe ~]# docker run -d -P --name tomcat01 tomcat

# 进入容器并安装网络工具,因为tomcat里没有网络工具和yum
root@4865e9059fec:/usr/local/tomcat# docker exec -it 4865e9059fec /bin/bash
root@4865e9059fec:/usr/local/tomcat# apt update
root@4865e9059fec:/usr/local/tomcat# apt install -y iproute2
root@4865e9059fec:/usr/local/tomcat# apt install -y net-tools
root@4865e9059fec:/usr/local/tomcat# apt install -y iputils-ping

# 查看容器的内部网络地址 ip addr , 发现容器启动的时候回等到一个 eth0@if143 ip地址,docker分配的!
[root@linuxprobe ~]# docker exec -it 4865e9059fec ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
142: eth0@if143: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

# 思考:linux能不能 ping 通容器内部!
[root@linuxprobe ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.201 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.060 ms

# linux 可以 ping 通 docker 容器内部

原理

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

再次测试ip addr

2、再启动一个容器测试,发现又多了一对网卡!

# 我们发现这个容器带来网卡,是一对对的
# evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
# 正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术

3、我们来测试下 tomcat01 和 tomcat02 是否可以ping通?

[root@linuxprobe ~]# docker exec -it tomcat02 ping 172.17.0.3

# 结论:容器和容器之间是可以互相 ping 通的!

绘制一个网络模型图

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

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

小结

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

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

只要容器删除,对应的网桥一对就没了!

思考一个场景,我们编写了一个微服务,datebase url=ip: , 项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以通过名字来进行访问容器 ?

[root@linuxprobe ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known

# 如何可以解决呢?
# 通过 --link 就可以解决了网络连通问题
[root@linuxprobe ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
d3ccad14168dbf51daea2dfebfbeebe69d48d887b9545403d3983fe84df60109
[root@linuxprobe ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.107 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.262 ms

# 反向可以ping通吗?
[root@linuxprobe ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known

探究:inspect

其实这个tomcat03 就是在本地配置了tomcat02的配置?

# 查看 hosts 配置,在这里原理发现!
[root@linuxprobe ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.3	tomcat02 f3a6ad2c5c3a
172.17.0.4	d3ccad14168d

本质探究:--link 就是我们在 hosts 配置中增加了一个 172.17.0.3 tomcat02 f3a6ad2c5c3a

我们现在玩 Docker 已经不建议使用 --link 了!

现在都用自定义网络!不用 docker0 !

docker0问题:不支持容器名连接访问!

自定义网络

查看所有的docker网络

网络模式

bridge:桥接 docker 搭桥 (默认,自己创建也使用 bridge 模式)

none:不配置网络

host:和宿主机共享网络

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

测试

# 我们直接启动的命令 --net bridge ,而这个就是 docker0
docekr run -d -P --name tomcat01 tomcat
docekr run -d -P --name tomcat01 --net bridge tomcat	

# docker0 特点:默认的,域名不能访问,--link可以打通连接!

# 我们可以自定义一个网络!
# --driver bridge
# --subnet 192.168.0.0/16     
# --gateway 192.168.0.1
[root@linuxprobe ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
b3852400da33e1dcfba29c812407396f5d93846dd36f30d50a13fbd9057c3057
[root@linuxprobe ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
271065b7977c   bridge    bridge    local
a7a10db9a740   host      host      local
b3852400da33   mynet     bridge    local
23802e091565   none      null      local

我们自己的网络就创建好了!

[root@linuxprobe ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
2a02dd496415ec157a35562926e18a0aaad02397cbe2a47e9056cdd26d92e02a
[root@linuxprobe ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
2f2e43d7a4b934dd612051866d3d71f603d7108f8005e27d89f2b458517053fc
[root@linuxprobe ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "b3852400da33e1dcfba29c812407396f5d93846dd36f30d50a13fbd9057c3057",
        "Created": "2022-03-08T16:50:05.555707312+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": {
            "2a02dd496415ec157a35562926e18a0aaad02397cbe2a47e9056cdd26d92e02a": {
                "Name": "tomcat-net-01",
                "EndpointID": "7606f8770dbbf67f57b285da4f38c9de7b182f320447a375838db1daf9a7b31f",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "2f2e43d7a4b934dd612051866d3d71f603d7108f8005e27d89f2b458517053fc": {
                "Name": "tomcat-net-02",
                "EndpointID": "96f6604daa08936ae35fc0acf6a60e503bed73e1f61f360037c07b72c3672bcf",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

# 再次测试ping连接
[root@linuxprobe ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.044 ms
^C
--- 192.168.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.044/0.051/0.058/0.007 ms

# 现在不使用--link 也可以ping名字了!
[root@linuxprobe ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.159 ms
^C
--- tomcat-net-02 ping statistics ---

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

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

网络连通

# 测试打通 tomca01 - mynet

# 连通之后就是将 tomcat01 放到了 mynet 网络下

# 一个容器两个ip地址!  
# 阿里云服务器:公网ip 私网ip

[root@linuxprobe ~]# docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.071 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.094 ms

# tomcat02 是依旧打不通的
[root@linuxprobe ~]# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known

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

实战:部署Redis集群

shell脚本!

# 创建网卡
docker network create redis --subnet 172.38.0.0/16

# redis-cli 访问
docker run -it --link myredis:redis --rm redis redis-cli -h redis -p 6379

# 通过脚本创建6个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

# 单一启动容器
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

# 用for循环启动√
== 启动容器===
for port in $(seq 1 6); \
do \
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done
==进入其中一个容器===
docker exec -it redis-1 /bin/sh
==创建集群===
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

# 集群配置完毕
/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 --cl
uster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 05b721d8be4fe69d3b9bfcea4487d2d060d337da 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: f5421c0ae2d971c6d0c8405d4656c9ad9dcfbf7f 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 5f7f5f9599b1a9306eefc8cdb663971f3ffd2a40 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 7893dac761be51128741ad02d4ca81ab27cf84d4 172.38.0.14:6379
   replicates 5f7f5f9599b1a9306eefc8cdb663971f3ffd2a40
S: ae7fcd1edd25cc0bddb8bba472ff1a823c323326 172.38.0.15:6379
   replicates 05b721d8be4fe69d3b9bfcea4487d2d060d337da
S: 893b4619d5c813d0d99585052314546634ce69f7 172.38.0.16:6379
   replicates f5421c0ae2d971c6d0c8405d4656c9ad9dcfbf7f
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
....
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: 05b721d8be4fe69d3b9bfcea4487d2d060d337da 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 5f7f5f9599b1a9306eefc8cdb663971f3ffd2a40 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: f5421c0ae2d971c6d0c8405d4656c9ad9dcfbf7f 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 893b4619d5c813d0d99585052314546634ce69f7 172.38.0.16:6379
   slots: (0 slots) slave
   replicates f5421c0ae2d971c6d0c8405d4656c9ad9dcfbf7f
S: ae7fcd1edd25cc0bddb8bba472ff1a823c323326 172.38.0.15:6379
   slots: (0 slots) slave
   replicates 05b721d8be4fe69d3b9bfcea4487d2d060d337da
S: 7893dac761be51128741ad02d4ca81ab27cf84d4 172.38.0.14:6379
   slots: (0 slots) slave
   replicates 5f7f5f9599b1a9306eefc8cdb663971f3ffd2a40
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

docker 搭建 redis 集群完成!

我们使用了docker之后,所有的技术都会慢慢的变的简单起来!

SpringBoot 微服务打包 Docker 镜像

1、构建springboot微服务项目

2、打包应用

3、编写dockerfile

4、构建镜像

5、发布运行

Docker Compose

Docker Swarm

CI/CD Jenkins

posted on 2023-03-30 11:36  暗狱碳水  阅读(253)  评论(0编辑  收藏  举报