Docker学习笔记
- 安装docker
安装
帮助文档
官方文档地址:https://docs.docker.com/engine/install/centos/
更新软件包索引:yum makecache fast
# 1、卸载旧版本
sudo 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、设置镜像的仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/dockerce.repo
#默认是国外的,比较慢
##国内阿里云镜像
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#4、安装docker相关的引擎 docker-ce社区版 ee企业版
yum install -y docker-ce docker-ce-cli containerd.io
#5、启动docker
systemctl start docker ##标准的linux命令
#6、使用docker version判断是否安装成功
docker run hello-world
卸载
#1、卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#2、删除资源
sudo rm -rf /var/lib/docker ##docker的默认工作路径
sudo rm -rf /var/lib/containerd
2.阿里云镜像加速
阿里云帮助文档:https://help.aliyun.com/document_detail/60750.html
1.CentOS 7配置
–《旧版docker》–1.10.0以上版本看下方
CentOS的配置方式略微复杂,需要先将默认的配置文件(/lib/systemd/system/docker.service)复制到/etc/systemd/system/docker.service。然后再将加速器地址添加到配置文件的启动命令中,之后重启Docker即可。
sudo cp -n /lib/systemd/system/docker.service /etc/systemd/system/docker.service
sudo sed -i "s|ExecStart=/usr/bin/docker daemon|ExecStart=/usr/bin/docker daemon --registry-mirror=<your accelerate address>|g" /etc/systemd/system/docker.service
sudo sed -i "s|ExecStart=/usr/bin/dockerd|ExecStart=/usr/bin/dockerd --registry-mirror=<your accelerate address>|g" /etc/systemd/system/docker.service
sudo systemctl daemon-reload
sudo service docker restart
2.配置镜像加速器
(推荐安装1.10.0以上版本的Docker客户端,参考文档docker-ce)
Docker客户端版本大于 1.10.0 的用户
可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker ##创建目录
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://86nmhzp3.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
}
}
EOF
sudo systemctl daemon-reload ##重启服务
sudo systemctl restart docker ##启动
3.底层原理
docker是怎么工作的
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问。
DockerServer接收到Docker-Client的指令,就会执行这个命令。
docker为什么比VM快
1.docker有着比虚拟机更少的抽象层
2.docker利用的是宿主机的内核,vm需要Guest OS
(所以说新建容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载Guest OS,是分钟级别的,docker是利用宿主机的操作系统,省略的复杂过程,启动是秒级的。)、
4.Docker的常用命令
1.帮助命令
docker version #显示docker版本信息
docker info #显示docker的系统信息,包括镜像和容器的数量
docker --help #帮助命令
- 镜像命令
docker images 查看所有本地主机上的镜像
[root@zark ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/sonarqube latest d3899771462f 2 weeks ago 514 MB
docker.io/sonarqube 8.9.6-community 3f623568fa64 2 weeks ago 497 MB
docker.io/postgres latest e94a3bb61224 5 weeks ago 374 MB
docker.io/postgres 11.9 e07f0c129d9a 15 months ago 282 MB
#解释
REPOSITORY #镜像的仓库员
TAG #镜像的标签
IMAGE ID #镜像的ID
CREATED #镜像的创建时间
SIZE #镜像的大小
#可选项
-a ,--all #列出所有镜像
-q,--quiet #只显示镜像的id
docker search命令搜索镜像
[root@zark ~]# docker search mysql
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/mysql MySQL is a widely used, open-source relati... 11937 [OK]
docker.io docker.io/mariadb MariaDB Server is a high performing open s... 4562 [OK]
docker pull 下载镜像
docker rmi 删除镜像
rm -Linux的删除, i指image(镜像)
docker rmi -f +id #删除指定的容器
docker rmi -f $(docker images -aq) #删除全部的容器
3.容器命令
说明:有了镜像才能创建容器,linux,下载一个centos镜像来测试学习
docker pull centos #拉取centos镜像
新建容器并启动
docker run [可选参数] image
#参数说明
--name="Name" #容器名字 eg:Tomcat1,Tomcat2 ,用来区分容器
-d #后台方式运行
-it #使用交互方式运行,进入容器查看内容
-p #指定容器端口 -p 8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(映射)[常用
-p 容器端口
-P #随机指定端口
#测试,启动centos
docker run -it centos /bin/bash #打开centos的命令行
退出
#从容器中退回主机
exit #容器停止,退出
Ctrl+P+Q #容器不停止,退出
列出所有运行的容器
# docker ps 命令
#列出当前正在运行的容器
-a #列出当前正在运行的容器+历史运行过的容器 (a=>all)
-n=? #显示最近创建的容器
-q #只显示容器的编号
删除容器
docker rm 容器id #删除指定容器,不能删除正在运行的,强制删除使用 rm-f
docker rm -f $(docker ps -aq) #删除所有容器
docker ps -a -q|xargs docker rm #删除所有容器
启动和停止容器的操作
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器
4.常用其他命令
后台启动容器
#命令 docker run -d 镜像名
docker run -d centos
#问题docker ps发现centos停止了
#常见的坑:docker容器使用后台进行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# Nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
####查看日志
docker logs --help #帮助
docker logs -f -t --tail 条数(int)+容器id
#如果没有日志,可以进行以下操作:
#自己编写一段shell脚本
"while true;do echo zark;sleep 1;done"
docker run -d centos /bin/sh -c "while true;do echo zark;sleep 1;done"
#显示日志
-tf #全部显示
--tail number #输出的日志条数
#eg:
docker logs -tf --tail 10 dce7b8617bf(容器id)
#风险:while循环没停下来,之后要想办法改进
####查看容器中的进程信息
#命令 docker top 容器id
####查看镜像的元数据
#命令
docker inspect 容器id
#测试
####进入当前正在运行的容器
#我们通常容器都是使用后台方式运行的,需要进入容器,进行一些配置的修改
#命令
docker exec -it 容器id /bin/bash
#方式二
docker attach 容器id
docker exec #进入容器后开启一个新的终端,可以在里面操作(常用)
docker attach #进入容器正在执行的终端,不会启动新的进程
从容器内拷贝文件到主机上
#拷贝容器的文件到主机中
docker cp 容器id:容器内路径 目的主机路径
#拷贝宿主机的文件到容器中
docker cp 目的主机路径 容器id:容器内路径
[root@zark ~]# docker exec -it c703b5b1911f /bin/bash
[root@c703b5b1911f /]# cd home
[root@c703b5b1911f home]# ls
#touch 新建文件
[root@c703b5b1911f home]# touch test.java
[root@c703b5b1911f home]# ls
test.java
[root@c703b5b1911f home]# exit
exit
[root@zark ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c703b5b1911f centos "/bin/sh -c 'while t…" 35 minutes ago Up 35 minutes pedantic_banach
[root@zark ~]# docker cp c703b5b1911f:/home/test.java /home
[root@zark ~]# ls /home
hai pan test.java
参考:
https://blog.csdn.net/huangjhai/article/details/118854733
实战练习
1.docker安装Nginx
docker安装Nginx
#1.搜索镜像 search 建议去docker上搜索,可以看到帮助文档
#2.下载镜像 pull
#3.运行测试
[root@zark_01 ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
186b1aaa4aa6: Pull complete
b4df32aa5a72: Pull complete
a0bcbecc962e: Pull complete
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@zark_01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 12 days ago 141MB
centos latest 5d0da3dc9764 3 months ago 231MB
# -d 后台运行
# --name 给容器命名
# -p 宿主机端口,容器内部端口
[root@zark_01 ~]# docker run -d --name nginx01 -p 3344:80 nginx
9d768d415ca9887a30db045fdabf06ea37e477d0b61011c2f9bbcc5cf88e54e3
[root@zark_01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d768d415ca9 nginx "/docker-entrypoint.…" 15 seconds ago Up 15 seconds 0.0.0.0:3344->80/tcp nginx01
[root@zark_01 ~]# curl localhost:3344
#进入容器
[root@zark_01 ~]# docker exec -it nginx01 /bin/bash
root@9d768d415ca9:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@9d768d415ca9:/# cd /etc/nginx
root@9d768d415ca9:/etc/nginx# ls
conf.d mime.types nginx.conf uwsgi_params
fastcgi_params modules scgi_params
root@9d768d415ca9:/etc/nginx#
端口暴露的概念
思考:每次改动Nginx配置文件,都需要进入容器内部,十分麻烦,如何在容器外部提供一个映射路径,就能在容器外修改文件名,容器内部就自动修改的目的
-v,数据卷的应用
2.docker安装Tomcat
#官方的使用
docker run -it --rm tomcat:9.0
#之前的启动都是后台,停止容器之后,还是可以查到。
#docker run -it --rm 一般用来测试,用完之后自动删除images(多用于测试)
直接下载是
docker pull
配置:
#centos的3355端口映射容器的8080端口。容器命名为tomcat01
docker run -d -p 3355:8080 --name tomcat01 tomcat
测试访问:
能够成功访问到Tomcat,但是没有资源
问题:
[root@zark_01 ~]# docker exec -it tomcat01 /bin/bash
root@31e9be706d70:/usr/local/tomcat#
1.linux命令少了(ll不存在指令)
2.没有webapps。
镜像的原因,默认是最小的镜像,所有不必要的剔除了。保证最小可运行环境。
发现有webapps.dist文件夹,root那些在里边,复制过去
root@31e9be706d70:/usr/local/tomcat# ls
BUILDING.txt NOTICE RUNNING.txt lib temp work
CONTRIBUTING.md README.md bin logs webapps
LICENSE RELEASE-NOTES conf native-jni-lib webapps.dist
root@31e9be706d70:/usr/local/tomcat# cd /webapps
bash: cd: /webapps: No such file or directory
root@31e9be706d70:/usr/local/tomcat# cd webapps
root@31e9be706d70:/usr/local/tomcat/webapps# cd
root@31e9be706d70:~# cd /usr/local/tomcat/
root@31e9be706d70:/usr/local/tomcat# cd webapps.dist/
root@31e9be706d70:/usr/local/tomcat/webapps.dist# ls
ROOT docs examples host-manager manager
root@31e9be706d70:/usr/local/tomcat/webapps.dist# cd ..
root@31e9be706d70:/usr/local/tomcat# cp -r webapps.dist/* webapps
再次访问
内容出来了。
3.部署es+kibana
1.es部署
#es暴露的端口很多!
#es非常消耗内存
#es的数据一般需要放置到安全目录挂载
#--netsomenetwork?网络配置
#启动elsaticsearch
docker run -d --name elsaticsearch -p 9200:9200 -e "discovery.type=single-node" elsaticsearch:7.6.2
#启动了linux就卡住了,
#(es耗内存,1.x个g)
#停止整个docker
查看cpu状态
docker stats
耗内存大怎么办?
–增加内存限制
#修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
看看成果
内存占用确实变小了。
[root@zark_01 ~]# curl localhost:9200
{
"name" : "dc067d227625",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "r2gEgkjkSV-t6OFDpTvuZg",
"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"
}
#测试成功
2.kibana连接配置es
概念图
4.可视化
-
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/
访问成功。
可视化面板平时不使用,测试玩玩就好
Docker镜像
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
所有的应用,直接打包成docker镜像,就可以直接跑起来
如何得到镜像
- 从远程仓库下载
- 朋友拷贝给你
- 自己制作一个镜像DockerFile
Docker镜像加载原理
UnionFS(联合文件系统)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层叠加,同时可以将不同目录挂在到通一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件系统是docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看见一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
docker镜像加载原理
分层理解
commit镜像
docker commit #提交容器成为一个新的副本
#命令和git类似
docker commit -m "描述" -a "作者" 容器id 目标镜像名:[tag]
操作:
以Tomcat为例(原Tomcat的webapps包中无内容)
用命令将内容复制进webapps中后,打包
[root@zark_01 ~]# docker commit -a="zark" -m"comple" 31e9be706d70 tomcat02:1.0
sha256:4c04ebbe7d0866cdb296e566a4c4a91ecbeb07ad1f7779f25057ea871a5a0452
运行结果
用docker images查看镜像,发现有Tomcat02的镜像名称
容器数据卷
什么是容器数据卷
docker理念回顾
将应用和环境打包成一个镜像。数据如果都在容器中,将容器删除,数据就会丢失。
需求:数据可以持久化
Mysql,容器删了=删库跑路…
需求:Mysql数据可以存储在本地
容器之间可以有一个数据共享的技术!docker容器中产生的数据,同步到本地。
解决问题的办法:
卷技术,目录的挂载,将容器内的目录,挂载到linux上
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的。
使用数据卷
方式一:直接使用命令挂载 -v
docker run -it -v 主机目录:容器内目录
实战:安装MySQL
1.获取mysql镜像
docker pull mysql:5.7
2.运行容器
#官方文档
# "!安装启动mysql是需要配置密码的!"
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
实操
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=QWE123.. --name mysql01 mysql:5.7
b1ea402ad33e02c409f54c74920ad6758ccee3727d649581a557688f4964f1c7
在mysql workbench中成功访问并添加test数据库后:
在本地把mysql容器删掉之后:
在data里面的数据依然存在。
如此就实现了容器数据持久化功能
具名和匿名挂在
#匿名挂载
-v 容器内路径
docker run -d -p --name nginx01 -v /etc/nginx nginx
#查看所有的volume情况
docker volume ls
#这里能够发现,这种挂载是匿名挂载,在-V只写了容器内的路径,没有写容器外的路径
- 所有docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxx下的
通过具名挂在可以方便的找到我们的一个卷,大多数情况使用的都是具名挂载
#如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
拓展:
#通过-v 容器内路径:ro rw 改变读写权限
ro: readonly #只读
rw:readwrite #可读可写
#一旦设置了容器权限,容器对挂载出来的内容就有限定了
docker run -d -P -name 容器名 -v 挂名:/容器内地址:ro 镜像名
docker run -d -P -name 容器名 -v 挂名:/容器内地址:rw 镜像名
#eg:
docker run -d -P -name nginx01 -v juming-nginx:/etc/nginx:rw nginx
#ro:只要看到ro就说明这个路径只能通过宿主机操作,容器内部是无法操作的
初识DockerFile
dockerfile就是用来构建docker镜像的构建文件(命令脚本)
通过脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层
新建一个命令文本
[root@zark_01 docker-test-volume]# vim dockerfile
[root@zark_01 docker-test-volume]# cat dockerfile
FORM centos
VOLUME ["volume01","volume02"]
CMD echo "---end---"
CMD /bin/bash
#上面的每一个命令,就是镜像的一层
文本创建后vim 写下shell命令行,然后保存退出准备生成
#docker bulid 生成镜像指令
-f +路径
-t +镜像名和版本号
#不要忘记最后的一个"."#
eg:
docker build -f dockerfile -t zark/centos:2.0 .
运行结果:
查看本地镜像
docker images
启动一下自己写的镜像
docker run -it +镜像名
#eg:
docker run -it 941e86a065d2 /bin/bash
可以看到是成功跑起来的。
(在shell命令行中的)
退出来查看一下信息:
docker inspect +容器名
#eg:
docker inspect zark01
Source:显示了容器挂载的外目录
在volume01目录下新建txt文件进行测试
touch container.txt
进入volume01挂载的本地目录下
[root@zark_01 ~]# cd /var/lib/docker/volumes/3837ea078474266ead66417b7bf0ee4bf0ff8f36b86044963870537cdec4217b/_data/
[root@zark_01 _data]# ls
container.txt
# ↑发现在宿主机里能够找到对应的txt文件
假设构建镜像时没有挂载卷,要手动挂载镜像-v 卷名:容器内路径
数据卷容器
多个容器同步数据
--volumes-from +容器id 同步挂载
#eg:
docker run -it --name zark02 --volumes-from zark01 zark/centos:2.0
同步zark01容器数据共享。
结论:
容器之间的配置信息的传递,数据卷的生命周期一直持续到没有容器使用为止。
但是一旦持久化到了本地(-v),这个时候,本地的数据是不会删除的。
DockerFile
dockerfile介绍
dockerfile是用来构建docker镜像的文件,命令参数脚本
构建步骤:
-
编写一个 dockerfile文件
-
docker bulid 构建成为一个镜像
-
docker run 运行镜像
-
docker pull 发布镜像(DockerHub、阿里云镜像仓库)
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /LABEL
org.label-schema.schema-version=“1.0”
org.label-schema.name=“CentOS Base Image”
org.label-schema.vendor=“CentOS”
org.label-schema.license=“GPLv2”
org.label-schema.build-date=“20201113”
org.opencontainers.image.title=“CentOS Base Image”
org.opencontainers.image.vendor=“CentOS”
org.opencontainers.image.licenses=“GPL-2.0-only”
org.opencontainers.image.created=“2020-11-13 00:00:00+00:00”CMD [“/bin/bash”]
(官方的镜像脚本)
–很多官方镜像都是基础包,很多功能没有,可以自己搭建自己的镜像
dockerfile构建过程
dockerfile是面向开发的,以后发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单
docker镜像逐渐成为企业交付的标准,必须掌握
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过dockerfile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务的
dockerfile的指令
FROM # 基础镜像,一切从这里开始构建
MIANTAINER # 镜像作者,姓名+邮箱
RUN # 镜像构建时需要运行的命令
ADD # 步骤,Tomcat镜像,这个Tomcat压缩吧,添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 指定暴露端口 (与-p相同)
CMD # 指定这个容器启动的时候运行的命令,只有最后一条生效,可被替代
ENTERPOINT # 指定这个容器启动的时候运行的命令,可以追加命令
ONBUILD # 当构建一个被继承dockerfile这个时候就会运行ONBUILD的指令,触发命令
ENV # 构建的时候设置环境变量(eg:mysql用户密码,es限制内存)
实战测试
从dockerHub中的dockerfile可以发现,其中99%的镜像都是基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行构建。
然后ADD了一个centos的压缩包。
创建一个自己的centos
# 1.编写dockerfile的文件
FROM centos
MAINTAINER Zark<534662506@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 bulid -f +文件路径 -t 镜像名:版本 +.
#eg:
docker build -f mydockerfile -t mycentos .
#结果:
Successfully built 899a286246ac
Successfully tagged mycentos:latest
(工作目录默认是根目录)
比对:基于原来的centos上增加了pwd和ipconfig,vim的指令功能
列出本地镜像的变更历史
docker history +镜像名
Docker网路
理解docker0
清空所有环境
测试
ip addr
网卡有3个,->3个不同的环境
#问题:docker是如何处理容器网路访问的
测试Tomcat容器ping通
#运行一个Tomcat容器
docker run -d -p 3355:8080 --name tomcat01 tomcat
#查看容器内的网络地址 ip addr
docker exec -it tomcat01 ip addr
如果镜像中没有ip addr的指令的话,可以使用如下方法查看容器的ip
1.用docker的inspect命令
docker inspect --format='{{.NetworkSettings.IPAddress}}' tomcat01
172.18.0.2
2.进入容器查看hosts文件
#进入容器
docker exec -it tomcat01 /bin/bash
#查看hosts文件
cat /etc/hosts
3.进入容器,安装iproute2,或者安装net-tools
yum -y install net-tools
但是如果yum都没有的话会比较麻烦,建议还是用上面的方法
测试ping:
说明linux机是可以ping通docker容器内部的
原理
1.每启动一个docker容器,docker就会给docker容器分配一个Ip,只要安装了docker,就会有一个docker0的网卡(桥接模式,使用的是veth-pair技术)
在启动了Tomcat之后,再次ip addr,相比之前多了一个网络信息:
2.再启动一个Tomcat测试
docker run -d -P --name tomcat02 tomcat #-P 随机端口
# 不难发现这个容器带来的网卡都是一对对的
# veth-pair 就是一对的虚拟设备接口,都是成对出现的,一端连着协议,一端彼此相连
#正因为有这个特性,因此通常用veth-pair充当一个桥梁,连接各种虚拟网络设备
#OpenStac,Docker容器之间的链接,OVS的链接,都是使用的veth-pair技术
3.测试下Tomcat01和Tomcat02(容器之间)能否ping通
结论:Tomcat01和Tomcat02是公用的一个“路由器”–docker0
所有容器不指定网络的情况下,都是由docker0路由的,docker会给容器分配一个默认的可用ip
小结
docker 使用的是linux的桥接,宿主机中是一个docker容器的网桥,docker0
docker中的所有网络接口都是虚拟的。虚拟的转发效率高!(内网传递文件)
只要容器删除,对应网桥就没了
–link
思考一个场景,编写了一个微服务,database url=ip,项目 不重启,数据库IP换了,处理这个问题能否通过名字来进行访问容器?
[root@zark_01 ~]# docker exec -it centos01 ping centos02
ping: centos02: Name or service not known
#可以看出,直接ping容器名是行不通的
跑一个新的容器centos3
docker run -it -P --name centos03 --link centos02 centos /bin/bash
#新建一个centos03容器,用link和centos02容器相连
此时再来ping两个容器:
[root@zark_01 ~]# docker exec -it centos03 ping centos02
PING centos02 (172.18.0.3) 56(84) bytes of data.
64 bytes from centos02 (172.18.0.3): icmp_seq=1 ttl=64 time=0.134 ms
64 bytes from centos02 (172.18.0.3): icmp_seq=2 ttl=64 time=0.081 ms
64 bytes from centos02 (172.18.0.3): icmp_seq=3 ttl=64 time=0.074 ms
64 bytes from centos02 (172.18.0.3): icmp_seq=4 ttl=64 time=0.072 ms
64 bytes from centos02 (172.18.0.3): icmp_seq=5 ttl=64 time=0.088 ms
64 bytes from centos02 (172.18.0.3): icmp_seq=6 ttl=64 time=0.089 ms
64 bytes from centos02 (172.18.0.3): icmp_seq=7 ttl=64 time=0.072 ms
64 bytes from centos02 (172.18.0.3): icmp_seq=8 ttl=64 time=0.074 ms
64 bytes from centos02 (172.18.0.3): icmp_seq=9 ttl=64 time=0.072 ms
#可以看到成功ping通
#试试反向Ping一下
[root@zark_01 ~]# docker exec -it centos02 ping centos03
ping: centos03: Name or service not known
#@@并不行!
–link就是在hosts的配置中增加了一个172.18.0.3 centos02 写死
这种方式并不方便,只是单向的,因此不建议使用
(被坑了感觉我擦)
自定义网络
查看所有docker网络
[root@zark_01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
2491f5a846c2 bridge bridge local
1ca322335795 host host local
fb2386916b10 none null local
网络模式
bridge:桥接 docker(默认,自己创建也用桥接)
none :不配置网络
host :和宿主机共享网络
container:容器网络连通(用得少。局限大)
#创建自定义网络
[root@zark_01 ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynetwork
81a38122f83c8c199fb5fc9dc38ce1
# --driver bridge
# --subnet 192.168.0.0/16 192.168.0
# --gateway 192.168.0.1
#查看docker网络
[root@zark_01 ~]# docker network ls
用自定义网络去创建容器
docker run -d -P --name tomcat01 --network mynetwork tomcat
docker run -d -P --name tomcat02 --network mynetwork tomcat
再次测试ping
网络连通
连通自定义网络和docker0
docker network connect mynetwork tomcat-net01
# mynetwork 自定义网络名称
# Tomcat-net01 非自定义网络中的容器
查看自定义网络配置状态
docker network inspect mynetwork
# 连通之后就是将Tomcat-net01加到了mynetwork网络下
#但是只有连接进来的是打通的,同一网络下其他未connect的容器,还是无法ping通的
实战:部署Redis集群
创建redis集群网络
docker network create redis --subnet 172.38.0.0/16
通过shell脚本创建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 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 --network redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
通过脚本创建
#for循环脚本生成6个redis容器
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 --network redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done
创建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.16:6379 --cluster-replicas 1
Docker Swarm
CI/CD