1、DockerFile(重点)
什么是DockerFile
Dockerfile 是一个用来构建镜像的脚本文件,文本内容包含一条条构建镜像所需的指令和说明。
第一步,你写了个java项目,打包成jar包
第二步,jar包+java环境通过dockerfile文件的指令构建,tag就是版本的区别,
一条条构建镜像所需的指令?有哪些指令
mysql的dockerfile
在dockerhub随便点进一个镜像的tag,就可以看到它的dockerfile(在github上),比如mysql
可以发现mysql的基础镜像是debian:buster-silm
centos的dockerfile
dockerhub上搜索centos的镜像,点其中一个tag,查看它的dockerfile
可以发现centos的基础镜像是scratch
scratch是所有镜像的根镜像,所有的docker镜像应该都是从dockerfile构建的!
DockerFile指令
完整命令如下: 在dockerfile指令中,会存在很多相似的指令,之后可以多注意一下! 参数追加规则!
workdir 设置工作目录,如tomcat镜像的默认工作目录是/usr/local/tomcat
官方文档学习:https://docs.docker.com/engine/reference/builder/
Dockerfile构建
1、每个关键字,必须是大写字母
2、指令是从上到下依次执行
3、# 代表注释
4、每个指令本质就是构建了一个新的镜像层!将它提交!
应用来说:
代码 =>.apk => 客户端下载运行
DockerFile、Docker镜像、Docker 容器 ( 理解:相当于软件三个不同的阶段 )
DockerFile 软件的原材料(代码)=> Build => Docker镜像(交付的产品)=> Run => Docker 容器(最终软件的运行状态!)
实战:CentOS
官方镜像:
1、编写DockerFile
一定需要有一个 DockerFile 文件、可以随意命名(但是不建议) 默认的名称 Dockerfile
[root@alibaba coding]# vim mydockerfile-centos
FROM centos:7.8.2003
MAINTAINER jude<747463168@qq.com>
ENV MYPATH /usr/local # 配置环境变量
WORKDIR $MYPATH
RUN yum -y install vim # 编译镜像时运行的脚本
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH # 容器的启动命令,就是docker run的时候要启动哪些命令
CMD ech "------end------"
CMD /bin/bash
[root@alibaba coding]# ls
mydockerfile-centos
2、构建镜像
通过Dockerfile进行构建镜像! docker build
别忘记后面的 . ,-f , 如果不要的情况下,文件名必须为 Dockerfile,-t 指定生成镜像的名称
[root@alibaba coding]# docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--cgroup-parent string Optional parent cgroup for the container
--compress Compress the build context using gzip
--cpu-period int Limit the CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight)
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--force-rm Always remove intermediate containers
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
-m, --memory bytes Memory limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--network string Set the networking mode for the RUN instructions during build (default "default")
--no-cache Do not use cache when building the image
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
--security-opt strings Security options
--shm-size bytes Size of /dev/shm
-t, --tag list Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
--ulimit ulimit Ulimit options (default [])
# docker build 一个镜像
[root@alibaba coding]# docker build -f mydockerfile-centos -t mycentos:1.0 .
构建完成,通过docker images 命令查看自己构建的镜像mycentos:1.0
3、运行镜像
docker run 运行自己构建的镜像,默认进入工作目录是 /usr/local,且支持vim、ifconfig命令
发现docker run 只执行最后一个CMD命令 /bin/bash
4、docker history命令查看任何一个镜像的创建过程
发现最底下的那一层是镜像centos:7.8.2003,每一条命令执行完毕,提交一个新的镜像层!,前面我们说过镜像是分层的。
CMD 和 ENTRYPOINT 区别
启动容器的时候,我们都可以使用这两个命令来执行一个启动时的运行命令!
-
CMD : 设置容器的启动命令 ,Dockerfile 中有多个CMD 指令,但是只有最后一个会生效,CMD 默认的参数会被 docker run 参数替代!
-
ENTRYPOINT : 设置容器的入口 ENTRYPOINT 的参数 和 docker run 进行拼接!
CMD 指令:
[root@alibaba coding]# vim dockerfile-cmd-test
FROM centos:7.8.2003
CMD ["ls","-a"]
# 构建镜像
[root@alibaba coding]# docker build -f dockerfile-cmd-test -t cmdtest:1.0 .
# run,参数替代,
[root@alibaba coding]# docker run cmdtest:1.0 -l # 会报错CMD不会拼接命令-l
[root@alibaba coding]# docker run cmdtest:1.0 ls -al
ENTRYPOINT:
[root@alibaba coding]# vim dockerfile-entrypoint-test
FROM centos:7.8.2003
ENTRYPOINT ["ls","-a"]
# 构建镜像
[root@alibaba coding]# docker build -f dockerfile-entrypoint-test -t entrypoint .
# run
[root@alibaba coding]# docker run entrypoint:latest
[root@alibaba coding]# docker run entrypoint:latest -l # 会拼接命令为 ls -al
容器一启动,自动执行 jar包!执行项目,如下:
FROM java:8
# 拷贝当前目录下的jar包到容器内的/app.jar
COPY *.jar /app.jar
# 配置应用tomcat的端口
CMD ["--server.port=8080"]
# 暴露容器的端口
EXPOSE 8080
# 设置容器的入口程序,启动容器后就执行java命令启动程序
ENTRYPOINT ["java","-jar","/app.jar"]
小结:编写dockerfile=> 构建=> 运行!
实战:Tomcat
新电脑,装我们的tomcat的步骤:
1、下载 jdk 的包
2、安装jdk
3、配置环境变量
# 环境变量在末尾添加JAVA_Home
[root@alibaba jdk1.8.0_201]# vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_201
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
# 使环境变量生效
[root@alibaba jdk1.8.0_201]# source /etc/profile
[root@alibaba jdk1.8.0_201]# java -version
4、下载tomcat的包
5、解压tomcat
使用dockerfile构建自己的tomcat镜像
1、需要有原材料,jdk-8u251-linux-x64.tar.gz 和apache-tomcat-9.0.36.tar.gz 上传到服务器,
# 建一个readme.md文件
[root@alibaba tomcat]# vim readme.md
hello,welcome,这是一个使用dockerfile构建的tomcat镜像@jude<747463168.com>
2、编写Dockerfile
[root@alibaba tomcat]# vim Dockerfile # 官方名称
FROM centos
MAINTAINER coding<24736743@qq.com>
# 复制一个文件到容器/usr/local目录内
COPY readme.md /usr/local/readme.md
# 自动解压到容器/usr/local目录下
ADD jdk-8u251-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.36.tar.gz /usr/local/
# 安装vim命令支持
RUN yum -y install vim
# 配置环境变量
ENV MYPATH /usr/local
# 工作目录
WORKDIR $MYPATH
# 配置JDK环境
ENV JAVA_HOME /usr/local/jdk1.8.0_251
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# 配置tomcat
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.36
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.36
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin:$CATALINA_HOME/lib
# 暴露容器内部端口8080
EXPOSE 8080
# 启动容器后执行命令:启动tomcat和打印日志
CMD /usr/local/apache-tomcat-9.0.36/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.36/bin/logs/catalina.out
3、构建镜像
[root@alibaba tomcat]# docker build -t coding/tomcat .
docker image命令查看镜像
启动运行tomcat
[root@alibaba tomcat]# docker run -d -p 9090:8080 --name codingtomcat -v /home/coding/tomcat/webapps:/usr/local/apache-tomcat-9.0.36/webapps/test -v /home/coding/tomcat/logs:/usr/local/apache-tomcat-9.0.36/logs coding/tomcat
5ddf6c85a6aac4ccb6abe03caab5cdfe6f5e78c079ef396c1c4ed546be5b92d4
# 运行后挂载的webapps与logs目录
[root@alibaba tomcat]# ls
apache-tomcat-9.0.36.tar.gz Dockerfile jdk1.8.0_201 jdk-8u201-linux-x64.tar.gz logs readme.md webapps
外网访问
小结:
制作镜像、运行挂载,东西都没有问题了!本地docker我们到此彻底玩转!
发布镜像到DockerHub
官方镜像仓库地址 DockerHub!
1、注册 DockerHub!
2、登录 DockerHub!
3、本地docker 登录仓库
# 看登录登出命令
[root@alibaba tomcat]# docker --help
...
login Log in to a Docker registry
logout Log out from a Docker registry
...
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
4、push测试
# 登录后,push测试
[root@alibaba tomcat]# docker push coding/tomcat:lastest
5、本地镜像有问题,没有账号名称! tag!
# 需要修改名字
[root@alibaba tomcat]# docker tag 14113680e4b6 kuangshen/tocmat:1.0
# 重新push
发布镜像到本地仓库
https://docs.docker.com/engine/reference/commandline/push/
使用本地服务器作为镜像仓库
# 拉取镜像
docker pull registry
# 创建容器
docker run -d -p 5000:5000 registry
# 配置私有仓库地址
[root@alibaba tomcat]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://dyv68vb0.mirror.aliyuncs.com"],
"insecure-registries": ["http://47.113.95.179:5000"]
}
# 重启daemon进程
systemctl daemon-reload
# 重启docker
systemctl restart docker
# 启动仓库
访问http://47.113.95.179:5000/v2/_catalog
[root@alibaba tomcat]# curl localhost:5000/v2/_catalog
{"repositories":[]}
push测试
# 标记
[root@alibaba tomcat]# docker tag 25821f0bd151 47.113.95.179:5000/codingtomcat
# 推送
[root@alibaba tomcat]# docker push 47.113.95.179:5000/codingtomcat
下载镜像
[root@helloworld ~]# docker pull 47.113.95.179:5000/codingtomcat
Using default tag: latest
Error response from daemon: Get https://47.113.95.179:5000/v2/: http: server gave HTTP response to HTTPS client
问题使用http不安全,无法拉取
如何删除本地仓库上的镜像
# 查看仓库容器的配置文件
[root@alibaba tomcat]# docker exec -it 00b75ac66ff7 cat /etc/docker/registry/config.yml
# 修改配置文件 增加delete 字段
[root@alibaba tomcat]# docker exec -it 00b75ac66ff7 vi /etc/docker/registry/config.yml
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
delete:
enabled: true
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
# 重启容器,生效配置
[root@alibaba tomcat]# docker restart 00b75ac66ff7
# 获取镜像摘要信息
curl --header "Accept:application/vnd.docker.distribution.manifest.v2+json" -I -XGET http://镜像地址/v2/镜像名称/manifests/镜像版本
[root@alibaba tomcat]# curl --header "Accept:application/vnd.docker.distribution.manifest.v2+json" -I -XGET http://localhost:5000/v2/codingtomcat/manifests/latest
HTTP/1.1 200 OK
Content-Length: 1373
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:d1f34ec22fe18c640a4e5af347f7b1e8e68914a6fd41a7fc7f56c80c154fe86b
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:d1f34ec22fe18c640a4e5af347f7b1e8e68914a6fd41a7fc7f56c80c154fe86b"
X-Content-Type-Options: nosniff
Date: Tue, 16 Jun 2020 15:01:30 GMT
# 删除私有仓库上的镜像
curl -I -XDELETE 私有仓库地址/v2/镜像名称/manifests/镜像对应sha256值
[root@alibaba tomcat]# curl -I -XDELETE http://localhost:5000/v2/codingtomcat/manifests/sha256:d1f34ec22fe18c640a4e5af347f7b1e8e68914a6fd41a7fc7f56c80c154fe86b
HTTP/1.1 202 Accepted
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Date: Tue, 16 Jun 2020 15:05:38 GMT
Content-Length: 0
发现其实还是删除不了的,自己的服务器做镜像仓库用起来有点费劲。
发布镜像到阿里云(建议)
1、登录阿里云,找到容器镜像服务
首先要自己开通容器镜像服务
2、创建命名空间,唯一确定你!
3、创建镜像仓库!选择私有或者公开,选择本地仓库
4、上传镜像
点进仓库,看操作指南写得很清楚,包括如何上传镜像和拉取镜像
-
登录 docker login 阿里云仓库
docker login --username=xxxx registry.cn-shenzhen.aliyuncs.com
-
镜像打标签
docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/icoding-jude/icoding-study:redis-1.0
- 推送镜像到阿里云仓库
docker push registry.cn-shenzhen.aliyuncs.com/icoding-jude/icoding-study:redis-1.0
5、推送完后就可以在我们的官方仓库查看了
仓库类型是私有的,需要登录docker才能pull,公有的直接pull。
在另外一台服务器上拉取刚上传的镜像
docker pull registry.cn-shenzhen.aliyuncs.com/icoding-jude/icoding-study:redis-1.0
把仓库类型改为私有,再尝试拉取失败,需要docker login登录
docker login登录仓库后,拉取成功
6、登出docker 阿里云仓库
[root@alibaba ~]# docker logout registry.cn-shenzhen.aliyuncs.com
总结
记住这幅图,到目前为止,Docker使用没有任何问题了!
2、IDEA整合Docker
自己写一个项目,使用docker来发布!交付,就是一个镜像而已!(应用 + 环境)
1、项目打包本地运行通过
web层接口定义HelloController
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello,coding";
}
}
package打jar包
2、编写Dockerfile,
先安装docker的插件(有提示功能),安装完后重启idea,让插件生效
3、构建镜像
把jar包和Dockerfile上传到服务器
[root@alibaba idea-app]# ls
Dockerfile hello-0.0.1-SNAPSHOT.jar
# .代表当前目录
[root@alibaba idea-app]# docker build -t helloapp .
4、运行镜像通过
# -d 后台运行 -P随机暴露端口
[root@alibaba idea-app]# docker run -d -P helloapp
6572d2298ca013d679d8cc3753af17e93dd88aa4c827fafb2d6f569350367c27
# 访问测试
[root@alibaba idea-app]# curl localhost:32772/hello
hello,coding
[root@alibaba idea-app]#
5、发布镜像!
可以把镜像上传到阿里云镜像仓库了
小结
在使用了docker之后,以后的一切交付产品都使用docker来完成即可!
3、Docker网络
理解docker0
# 查看本地ip
[root@alibaba www]# ip addr
# 分析3个网络
lo 127.0.0.1 # 本地回环地址
eth0 172.17.90.138 # 阿里云的私有ip
docker0 172.18.0.1 # docker的网卡
# docker怎么处理容器间的访问的?
实际场景:
开发了很多的微服务项目,都需要连接数据库, url 地址,容器重启==> 每次url都会发生变化!(使用容器名连接 !)
如果可以直接指定ip就好了!
容器之间是否可以ping通!不能直接ping通,需要把容器放到同一个网络
原理
发现启动一个容器,本地就会多一个网卡,418与419一对网卡(容器内与宿主机)对应
宿主机与容器是可以ping通的
# linux服务器是可以和容器内的应用ping通的!tomcat01的ip是172.18.0.2
[root@kuangshen idea-app]# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.069 ms
再启动一个tomcat容器
发现又多一对网卡420与421,420是容器内的网卡,421上宿主机上的网卡,它们是绑定的关系,从图中可以看出:420: eth0@if421,
421: veth139bf0a@if420。同时从图中发现491,421分别代表tomcat01和tomcat02,都连接到docker0 网卡上
得出结论:
# linux <=> 容器
419:@if418 418:eth0@if419
421:@if420 420:eth0@if421
# 每一次启动,容器都会产生一对网卡!
# 序号依次递增!
# linux 这样一对虚拟设备接口! 这叫 veth-pair 技术
顾名思义,veth-pair 就是一对的虚拟设备接口,和 tap/tun 设备不同的是,它都是成对出现的。一端连着协议栈,一端彼此相连着。如下图所示:
正因为有这个特性,它常常充当着一个桥梁,连接着各种虚拟网络设备,典型的例子像“两个 namespace 之间的连接”,“Bridge、OVS 之间的连接”,“Docker 容器之间的连接” 等等,以此构建出非常复杂的虚拟网络结构,比如 OpenStack Neutron。
发现,容器是可以互相ping通的,但是要通过ip地址!使用容器名就不行
# 默认docker0网卡,容器间使用容器名是无法ping通的,要使用ip地址
[root@kuangshen idea-app]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
结论:tomcat1 和 tomcat2 实际上,共用了一个路由! docker0,任何一个容器默认启动的时候都是docker0网络。docker0 就会给容器分配一个可用ip,自增!
16是后面两位可以改变的意思,8+8=16,范围是172.18.0.0 - 172.18.255.255,所以默认docker0 最多可以分配 65535
如果是8,范围是172.18.0.0 - 172.18.0.255
比如之后要自己创建一个网络,这些都是可以自己配置的!
–link容器互联
jdbc:mysql://172.18.0.2:3306 , 每次启动容器,ip都会变!
jdbc:mysql://容器名:3306 , 每次启动容器,容器名不变即可!
# 直接使用容器名是无法ping通过的,需要使用--link参数
[root@kuangshen idea-app]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
# 使用--link,tomcat03在启动的时候连接到 tomcat02
[root@kuangshen idea-app]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
714c8b810584248a595f9e7d033038fa7ddc05c77110d96ee88abe78019755b0
[root@kuangshen idea-app]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
714c8b810584 tomcat "catalina.sh run" 3 seconds ago Up 2 seconds 0.0.0.0:32773->8080/tcp tomcat03
10175c786309 tomcat "catalina.sh run" About a minute ago Up About a minute 0.0.0.0:32772->8080/tcp tomcat02
2f39a5a6588d tomcat "catalina.sh run" About a minute ago Up About a minute 0.0.0.0:32771->8080/tcp tomcat01
# tomcat03 --link 连接到了一个容器之后,这时候才可以ping通容器名!
[root@kuangshen idea-app]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.18.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.18.0.3): icmp_seq=1 ttl=64 time=0.092 ms
64 bytes from tomcat02 (172.18.0.3): icmp_seq=2 ttl=64 time=0.068 ms
# 但是反过来tomcat02是无法连接tomcat03的,说明 --link 连接是单向的
[root@kuangshen idea-app]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
如果在docker0情况下,我们可以使用–link 让容器之间可以使用容器名来ping通,连接成功!
–link 是一个单向连接!
原理:
进入容器tomcat03,查看配置文件/etc/hosts ,发现–link本质是在/etc/hosts配置文件上配置了映射。tomcat02上的/etc/hosts没有配置tomcat03的ip地址映射,所以tocmat02无法通过容器名直接连接到tocmat03。
# 强制删除全部的容器
docker rm -f $(docker ps -qa)
自定义一个网卡
我们可以把elasticsearch集群放在一个网络里,redis集群放在一个网络,mysql集群放在一个网络
# 创建一个容器,就自动多一对网卡
# 删除一个容器,自动减少,id还是自增!
# docker run 不指定 网络,默认就是docker0
docker0:
1、默认的
2、容器名访问,访问不了的!
3、--link访问域名!麻烦,简陋,每个都配置!
4、使用 docker network
查看所有网络
网络模式
Docker网络模式 | 配置 | 说明 |
---|---|---|
host模式 | –net=host | 容器和宿主机共享Network namespace。主机! |
container模式 | –net=container:NAME_or_ID | 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。 |
none模式 | –net=none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。自己设置 |
bridge模式 | –net=bridge | (默认为该模式)路由器,自动划分ip! |
1、自己创建网卡
[root@alibaba ~]# docker network --help
Usage: docker network COMMAND
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
# 查看帮助命令 docker network create --help
# --subnet 是子网范围,--gateway 是网关
[root@alibaba ~]# docker network create --drive bridge --subnet 192.167.0.0/16 --gateway 192.167.0.1 mynet2
2、使用自己的网络 –net,启动容器
# 创建启动一个容器,并指定网络mynet2
[root@alibaba ~]# docker run -d -P --name tomcat01 --net mynet tomcat:9.0
[root@alibaba ~]# docker run -d -P --name tomcat02 --net mynet tomcat:9.0
# 查看网络mynet2的详细信息
docker network inspect mynet
3、使用容器名相互ping通
[root@alibaba ~]# docker exec -it tomcat01 ping tomcat02
[root@alibaba ~]# docker exec -it tomcat02 ping tomcat01
自定义网络的一个好处!我们没有配置任何东西,他自己就可以相互ping通,比docker0强大!
使用自定义的网络,docker自身就帮我们维护了所有容器之间的连通,我们通常会这样来使用docker网络搭建项目环境!
网络连通
# 创建启动容器tomcat03,tomcat04, 不指定网络,默认是docker0,容器间只能通过ip地址相互ping通,无法通过容器名ping通
[root@alibaba ~]# docker run -d -P --name tomcat03 tomcat:9.0
5c0a620ca3d83cf542551299aad1bf295be5287a5b7cad658f9e7e9f88c91a80
[root@alibaba ~]# docker run -d -P --name tomcat04 tomcat:9.0
34668e99b2cf5bdf5992bc4a9ca074cdbcae501b398ee4e12c0f06aa10a75efa
# tomcat01,tomcat02在网络mynet,tomcat03,tomcat04在网络docker0
在不同网络中的tomcat可以通过ip地址相互ping通,但无法通过容器名相互ping通(自定义网络可以,docker0需要通过–link单向连接实现容器名ping通)
将容器tomcat03也加入网络mynet! 一个容器多个IP !
# 查看帮助命令
[root@alibaba ~]# docker network connect --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
# 通过 docker network connet 连通
[root@alibaba ~]# docker network connect mynet tomcat03
[root@alibaba ~]# docker network inspect mynet
这样就可以实现容器跨网络访问!
网络就是基础问题;计算机网络原理没有问题!
Redis集群部署
上图3主3从
下去测试即可!主要理解docker网络,可以配置集群隔离,保证我们集群的安全性,每个服务集群有自己的网络!
1、自定义一个网络redis-net
[root@alibaba ~]# docker network create --subnet 172.38.0.0/16 --gateway 172.38.0.1 redis-net
c549a717573c11e698a0303657dc5502c0ec8da7940ed3d9099d9e67c94e5d2c
2、使用脚本启动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
requirepass redisjude666 # master开启密码保护,默认是没有密码的
masterauth redisjude666 # replica同master交互密码
EOF
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-net --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done
6个redis的配置文件和数据目录
3、创建集群
# 进入一个redis,注意这里是 sh命令
[root@alibaba ~]# docker exec -it redis-1 /bin/sh
# 创建集群(创建成功!)
# -a 是redis的密码
redis-cli -a redisjude666 --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
4、连接集群
# 进入一个redis,连接集群 (-c 连接集群!)
redis-cli -c
# 查看集群信息
127.0.0.1:6379> cluster info
# 查看节点
127.0.0.1:6379> cluster nodes
5、高可用测试
# set a b (选择一个容器进行set)
# 停止到存值的容器 (删除容器)
# 然后再次get a,发现依旧可以获取值 (自动转移到从机,依旧可以获得值)
# 查看节点,发现高可用完全没问题
set 一个key ,该key存储到了172.38.0.13 (容器redis-3), slot 槽点分片
进入容器redis-2,get a 会自动跳到 172.38.0.13 获取值,现在尝试把redis-3容器停掉,
[root@alibaba /]# docker stop redis-3
redis-3
依旧可以获取值
redis-3已失去连接,从节点redis-4 成为了 master 节点,实现了高可用。
redis集群的关闭与重启
集群的关闭
我这里使用docker安装,直接docker stop 容器关闭
[root@alibaba ~]# docker stop redis-6 redis-5 redis-4 redis-2 redis-1
其他redis集群的搭建方式,可以kill id 关闭redis实例
# 查找redis实例进程号
ps -ef | grep redis
# 关闭redis进程,使用kill -9 ${进程号},如果需要关闭多个进程,进程号之间空格隔开即可
kill -9 10252 10257 10262 10267 10272 10294
# 也可以批量kill
pkill -9 redis
集群的重新启动
-
保留原来的数据
逐个关闭redis实例,再逐个的启动即可。
-
丢弃原来的数据
关闭实例,清空实例中数据存放目录的所有内容,然后逐个启动实例,在任意一个实例上执行集群的创建命令即可,本质上就是创建一个新的集群 清空数据存储目录内容:
rm -rf /opt/redis/cluster/7001/data/*
rm -rf /opt/redis/cluster/7002/data/*
rm -rf /opt/redis/cluster/7003/data/*
rm -rf /opt/redis/cluster/7004/data/*
rm -rf /opt/redis/cluster/7005/data/*
rm -rf /opt/redis/cluster/7006/data/*
启动实例
redis-server /opt/redis/cluster/7001/redis.conf
redis-server /opt/redis/cluster/7002/redis.conf
redis-server /opt/redis/cluster/7003/redis.conf
redis-server /opt/redis/cluster/7004/redis.conf
redis-server /opt/redis/cluster/7005/redis.conf
redis-server /opt/redis/cluster/7006/redis.conf
创建实例
# -a cyclone 是redis的密码
redis-cli -a redisjude666 --cluster create --cluster-replicas 1 192.168.220.11:7001 192.168.220.11:7002 192.168.220.11:7003 192.168.220.11:7004 192.168.220.11:7005 192.168.220.11:7006
参考文章:https://www.cnblogs.com/paul8339/p/11987345.html