DockerFile
DockerFile介绍
DockerFile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
- 编写一个dockerfile文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub、阿里云镜像仓库!)
查看一下官方是怎么做的?
发现官方的镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!
官方既然可以制作镜像,那么我们也可以!
DockerFile构建过程
基础知识:
- 每个保留关键字(指令)都是必须是大写字母
- 执行从上到下顺序执行
#
表示注释
- 每一个指令都会创建提交一个新的镜像层,并提交!
DockerFile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为企业交付的标准,必须要掌握!
步骤:开发,部署,运维。。。缺一不可!
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品!
Docker容器:容器就是镜像运行起来提供服务的
DockerFile的指令
以前的话我们就是使用别人的,现在我们知道了这些指令后,我们来练习自己写一个镜像!
FROM # 基础镜像,一切从这里开始构建 MAINTAINER # 镜像是谁写的,姓名+邮箱 RUN # 镜像构建的时候需要运行的命令 ADD # 步骤,tomcat镜像,这个tomcat压缩包!添加内容 WORKDIR # 镜像的工作目录 VOLUME # 挂载的目录 EXPOSE # 暴露端口配置 CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令 ONBUILD # 当构建一个被继承的 DockerFile 这个时候就会运行 ONBUILD 的指令,触发指令 COPY # 类似ADD,将我们的文件拷贝到镜像中 ENV # 构建的时候设置环境变量!
实战测试
Docker Hub中99%镜像都是从这个基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行构建
创建一个自己的centos
创建出错可以查看我的博客中遇到的错误
一栏中的相关内容进行解决!
# 1 编写Dockerfile的文件 [root@ls-Cwj2oH9C dockerfile]# cat mydockerfile-centos FROM centos:7.9.2009 MAINTAINER wydilearn<406623380@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum install vim RUN yum install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "----end----" CMD /bin/bash # 2 通过这个文件构建镜像 # 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag] Successfully built 4ca77dadd64f Successfully tagged mycentos:7.9.2009 # 3 测试运行
对比:之前的原生centos
工作目录默认是根目录,没有vim、ifconfig等命令
我们增加之后的镜像:
我们可以列出本地镜像的变更历史
我们平时拿到一个镜像,可以研究一下它是怎么做的了!
CMD 和 ENTRYPOINT 区别
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
测试cmd
# 编写 dockerfile 文件 [root@ls-Cwj2oH9C dockerfile]# vim dockerfile-cmd-test FROM centos CMD ["ls","-a"] # 构建镜像 [root@ls-Cwj2oH9C dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest . # run运行,发现我们的ls -a 命令生效 [root@ls-Cwj2oH9C dockerfile]# docker run 08f5a6379ff7 . .. .dockerenv anaconda-post.log bin dev etc home lib lib64 # 想追加一个命令 -l ls -al [root@ls-Cwj2oH9C dockerfile]# docker run 08f5a6379ff7 -l docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown. ERRO[0000] error waiting for container: context canceled # CMD的情况下 -l 替换了CMD ["ls","-a"]命令,-l 不是命令所以报错!
测试 ENTRYPOINT
[root@ls-Cwj2oH9C dockerfile]# vim dockerfile-cmd-entrypoint FROM centos:7.9.2009 ENTRYPOINT ["ls","-a"] [root@ls-Cwj2oH9C dockerfile]# docker build -f dockerfile-cmd-entrypoint -t entrypoint-test . Sending build context to Docker daemon 4.096kB Step 1/2 : FROM centos:7.9.2009 ---> eeb6ee3f44bd Step 2/2 : ENTRYPOINT ["ls","-a"] ---> Running in a11a899f08f4 Removing intermediate container a11a899f08f4 ---> db46b6b11456 Successfully built db46b6b11456 Successfully tagged entrypoint-test:latest [root@ls-Cwj2oH9C dockerfile]# docker run d74cdaf8abb6 . .. .dockerenv anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var # 我们的追加命令,是直接拼接在我们的 ENTRYPOINT 命令的后面! [root@ls-Cwj2oH9C dockerfile]# docker run d74cdaf8abb6 -l total 64 drwxr-xr-x 1 root root 4096 Jul 12 08:56 . drwxr-xr-x 1 root root 4096 Jul 12 08:56 .. -rwxr-xr-x 1 root root 0 Jul 12 08:56 .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 Jul 12 08:56 dev drwxr-xr-x 1 root root 4096 Jul 12 08:56 etc drwxr-xr-x 2 root root 4096 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 4096 Apr 11 2018 media drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt drwxr-xr-x 2 root root 4096 Apr 11 2018 opt dr-xr-xr-x 173 root root 0 Jul 12 08:56 proc dr-xr-x--- 2 root root 4096 Nov 13 2020 root drwxr-xr-x 11 root root 4096 Nov 13 2020 run lrwxrwxrwx 1 root root 8 Nov 13 2020 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Apr 11 2018 srv dr-xr-xr-x 13 root root 0 Jul 9 02:03 sys drwxrwxrwt 7 root root 4096 Nov 13 2020 tmp drwxr-xr-x 13 root root 4096 Nov 13 2020 usr drwxr-xr-x 18 root root 4096 Nov 13 2020 var
Dockerfile中很多命令都十分的相似,我们需要了解它们的区别,我们最好的学习就是对比他们然后测试效果!
实战:Tomcat镜像
- 准备镜像文件 tomcat 压缩包,jdk的压缩包!
- 编写dockerfile文件,官方命名
Dockerfile
,build 会自动寻找这个文件,就不需要 -f 指定了!
FROM centos:7.9.2009 MAINTAINER wydilearn<406623380@qq.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8u333-linux-x64.tar /usr/local/ ADD apache-tomcat-10.0.22.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_333 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-10.0.22 ENV CATALINA_BASE /usr/local/apache-tomcat-10.0.22 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-10.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-10.0.22/bin /logs/catalina.out
- 构建镜像
# docker build -t diytomcat .
- 启动镜像
- 访问测试
- 发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了!)
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" 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,kuangshen</title> </head> <body> Hello World!<br/> <% System.out.println("----my test web logs----"); %> </body> </html>
发现:项目部署成功,可以直接访问ok!
我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!
发布自己的镜像
DockerHub
- 地址 https://hub.docker.com/ 注册自己的账号!
- 确定这个账号可以登录
- 在我们的服务器上提交自己的镜像
[root@ls-Cwj2oH9C tomcatlogs]# 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
- 登录完毕后就可以提交镜像了,就是一步 docker push
# 给自己要发布的镜像增加一个 tag [root@ls-Cwj2oH9C tomcat]# docker tag 52f83276fc08 wydilearn/diytomcat:1.0 # docker push上去即可!自己发布的镜像尽量带上版本号 [root@ls-Cwj2oH9C tomcat]# docker push wydilearn/diytomcat:1.0 The push refers to repository [docker.io/wydilearn/diytomcat] 3c40fff9f2ee: Pushed fc3bd8b32ed0: Pushed f8c82bfdcfb9: Pushed a5760cf5dc3b: Pushed 174f56854903: Mounted from library/centos 1.0: digest: sha256:e0fae8f6383fdbf05a1fc89676fd7696949fc16d378f698a60918cb16a0fabb9 size: 1373
提交的时候也是按照镜像的层级来进行提交的。
发布到阿里云镜像服务上
- 登录阿里云
- 找到容器镜像服务
- 创建命名空间
- 创建容器镜像
- 浏览阿里云
阿里云容器镜像就参考官方地址!
小结
Docker 网络
理解Docker0
清空所有环境
测试
三个网络
# 问题:docker 是如何处理容器网络访问的?
[root@ls-Cwj2oH9C /]# docker run -d -P --name tomcat01 tomcat # 查看容器的内部网络地址 ip addr,发现容器启动的时候会得到一个 eth0@if2763 IP地址,docker分配的! [root@ls-Cwj2oH9C /]# docker exec -it 232419b4b0ff /bin/bash # 进入容器安装两个命令 root@232419b4b0ff:/usr/local/tomcat# apt update && apt install -y iproute2 root@232419b4b0ff:/usr/local/tomcat# apt install iputils-ping root@232419b4b0ff:/usr/local/tomcat# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 2762: eth0@if2763: <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@ls-Cwj2oH9C /]# 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.047 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.044 ms # linux可以ping通容器内部
原理
- 我们每启动一个docker容器,docker就会给docker容器分配一个IP,我们只要安装了docker,就会有一个网卡 docker0
桥接模式,使用的技术是 evth-pair 技术!
再次测试ip addr
- 再启动一个容器测试,发现又多了一对网卡!
# 我们发现这个容器带来网卡,都是一对一对的 # evth-pair 就是一堆的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连 # 正因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备 # OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
- 我们来测试下tomcat01和tomcat02是否可以ping通!
# 进入tomcat02 [root@ls-Cwj2oH9C /]# docker exec -it tomcat02 /bin/bash root@fde1226260aa:/usr/local/tomcat# apt update && apt install -y iproute2 root@fde1226260aa:/usr/local/tomcat# apt install iputils-ping root@fde1226260aa:/usr/local/tomcat# 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.087 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.071 ms
结论:容器和容器之间是可以互相ping通的!
绘制一个网络模型图:
结论:tomcat01 和 tomcat02 是共用的一个路由器,docker0。
所有的容器不指定网络的情况下,都是 docker0 路由的,docker会给我们的容器分配一个默认的可用IP
小结
Docker中的所有网络接口都是虚拟的。虚拟的转发效率高!
只要容器删除,对应的一对网桥就没了!
--link
思考一个场景,我们编写了一个微服务,database url=ip:,项目不重启数据库ip换掉了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
[root@ls-Cwj2oH9C ~]# docker exec -it tomcat02 ping tomcat01 ping: tomcat01: Name or service not known # 如何可以解决呢? # 通过--link 就可以解决网络连通问题 [root@ls-Cwj2oH9C ~]# docker run -it -d -P --name tomcat03 --link tomcat02 tomcat 371f584079471c6b8934c5ee961d741dba06884e0e85135bd0d224f685f0d6ca [root@ls-Cwj2oH9C ~]# docker exec -it tomcat03 /bin/bash root@371f58407947:/usr/local/tomcat# apt update && apt install -y iproute2 root@371f58407947:/usr/local/tomcat# apt install iputils-ping root@371f58407947:/usr/local/tomcat# 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.111 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.062 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.061 ms
探究:inspect!
其实这个tomcat03就是在本地配置了tomcat02配置
# 查看 hosts 配置,在这里原理发现! [root@ls-Cwj2oH9C ~]# docker exec -it tomcat03 /bin/bash root@371f58407947:/usr/local/tomcat# 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 fde1226260aa 172.17.0.4 371f58407947
本质探究:--link 就是在hosts配置中增加了一个 172.17.0.3 tomcat02 fde1226260aa
我们现在用Docker,已经不建议使用 --link 了!
自定义网络!不使用docker0!
docker0的问题:它不支持容器名连接访问!
自定义网络
查看所有的docker网络
网络模式
bridge:桥接模式 docker(默认,自己创建也使用 bridge 桥接模式)
none:不配置网络
host:和宿主机共享网络
container:容器内网络连通!(用的较少!局限很大)
三种常见网络模式(补充)
bridged(桥接模式)
虚拟机和宿主计算机处于同等地位,虚拟机就像是一台真实主机一样存在于局域网中
NAT(网络地址转换模式)
宿主计算机相当于一台开启了DHCP功能的路由器,而虚拟机则是内网中的一台真实主机
host-only(仅主机模式)
相当于虚拟机通过双绞线和宿主计算机直连,而宿主计算机不提供任何路由服务。因此在Host-only模式下,虚拟机可以和宿主计算机互相访问,但是虚拟机无法访问外部网络。
测试
# 我们直接启动的命令 --net bridge,而这个就是我们的docker0 [root@ls-Cwj2oH9C /]# docker run -d -P --name tomcat01 tomcat [root@ls-Cwj2oH9C /]# docker run -d -P --name tomcat01 --net bridge tomcat # docker0特点,默认,域名不能访问,--link可以打通连接! # 我们可以自定义一个网络! # --driver bridge # --subnet 192.168.0.0/16 192.168.0.2 192.168.255.255 # --gateway 192.168.0.1 [root@ls-Cwj2oH9C /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet c82c2708387b95f0d932ae395fe0dc1d3182d38a47b820584c66e39219541eb4 [root@ls-Cwj2oH9C /]# docker network ls NETWORK ID NAME DRIVER SCOPE 1340a553ba22 bridge bridge local 6f12b7793243 host host local c82c2708387b mynet bridge local 2581ba94b5d9 none null local
我们自己的网络就创建好了!
[root@ls-Cwj2oH9C /]# docker run -d -P --name tomcat-net-01 --net mynet tomcat e1d698bdf7bd90daf158e00e7f3c69785590198b477e1b45ef0fb2f6d2dd8ed6 [root@ls-Cwj2oH9C /]# docker run -d -P --name tomcat-net-02 --net mynet tomcat 685b7164f606200c809c81858a291374171ed2ddf77e30e24f94fbbbbcdbe2e1 [root@ls-Cwj2oH9C /]# docker network inspect mynet [ { "Name": "mynet", "Id": "c82c2708387b95f0d932ae395fe0dc1d3182d38a47b820584c66e39219541eb4", "Created": "2022-07-16T17:38:25.818266785+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": { "685b7164f606200c809c81858a291374171ed2ddf77e30e24f94fbbbbcdbe2e1": { "Name": "tomcat-net-02", "EndpointID": "7a3ac62a87388c10907bee1b83800d28968caf47160bec9999c3921a3e5183ff", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" }, "e1d698bdf7bd90daf158e00e7f3c69785590198b477e1b45ef0fb2f6d2dd8ed6": { "Name": "tomcat-net-01", "EndpointID": "ea12cb9879b8d6801eabd3510e67e3a546888723ea743eedaec5274cca080ff0", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] # 再次测试ping连接 [root@ls-Cwj2oH9C ~]# 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.085 ms 64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.070 ms # 现在不使用--link也可以ping名字了! [root@ls-Cwj2oH9C ~]# 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.055 ms 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.063 ms
我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis - 不同的集群使用不同的网络,保证集群是安全和健康的
mysql - 不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
# 测试打通 tomcat01 - mynet # 连通之后就是将 tomcat01 放到了 mynet 网络下 # 一个容器两个ip地址! # 阿里云服务:公网ip 私网ip
# 01 连通ok [root@ls-Cwj2oH9C ~]# 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.072 ms 64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.070 ms # 02 是依旧打不通的 [root@ls-Cwj2oH9C ~]# docker exec -it tomcat02 ping tomcat-net-01 ping: tomcat-net-01: Name or service not known
结论:假设要跨网络操作别人,就需要使用 docker network connect 连通!
实战:部署Redis集群
shell脚本
# 创建网卡 [root@ls-Cwj2oH9C /]# docker network create redis --subnet 172.38.0.0/16 # 通过脚本创建六个redis配置 [root@ls-Cwj2oH9C /]# 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 [root@ls-Cwj2oH9C conf]# 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 [root@ls-Cwj2oH9C conf]# 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 [root@ls-Cwj2oH9C conf]# 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 [root@ls-Cwj2oH9C conf]# 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 [root@ls-Cwj2oH9C conf]# 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 [root@ls-Cwj2oH9C conf]# 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 # 任意进入一个reids容器,注意使用 /bin/sh 而不是 /bin/bash [root@ls-Cwj2oH9C conf]# docker exec -it redis-1 /bin/sh # 创建集群 /data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6 379 172.38.0.15:6379 172.38.0.16:6379 --cluster-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: f142bdcc5c5d7ac81eb70d91da9987b71a79d2e2 172.38.0.11:6379 slots:[0-5460] (5461 slots) master M: 3ab93307a4de5df775702779665ca4583abe5210 172.38.0.12:6379 slots:[5461-10922] (5462 slots) master M: abe4ba6a98b5fe967d952ffc06060d7c07474821 172.38.0.13:6379 slots:[10923-16383] (5461 slots) master S: ca57da80daea08a065f5add0a607edde9d11e7eb 172.38.0.14:6379 replicates abe4ba6a98b5fe967d952ffc06060d7c07474821 S: e9664d81440a18689a1d8cd00f7a191f78f0979c 172.38.0.15:6379 replicates f142bdcc5c5d7ac81eb70d91da9987b71a79d2e2 S: f972b8b774941d383a26ab31cc337c5017657ba0 172.38.0.16:6379 replicates 3ab93307a4de5df775702779665ca4583abe5210 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: f142bdcc5c5d7ac81eb70d91da9987b71a79d2e2 172.38.0.11:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: abe4ba6a98b5fe967d952ffc06060d7c07474821 172.38.0.13:6379 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: ca57da80daea08a065f5add0a607edde9d11e7eb 172.38.0.14:6379 slots: (0 slots) slave replicates abe4ba6a98b5fe967d952ffc06060d7c07474821 S: f972b8b774941d383a26ab31cc337c5017657ba0 172.38.0.16:6379 slots: (0 slots) slave replicates 3ab93307a4de5df775702779665ca4583abe5210 S: e9664d81440a18689a1d8cd00f7a191f78f0979c 172.38.0.15:6379 slots: (0 slots) slave replicates f142bdcc5c5d7ac81eb70d91da9987b71a79d2e2 M: 3ab93307a4de5df775702779665ca4583abe5210 172.38.0.12:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. /data # redis-cli -c 127.0.0.1:6379> cluster info 127.0.0.1:6379> cluster nodes 127.0.0.1:6379> set a b [root@ls-Cwj2oH9C ~]# docker stop redis-3 redis-3 127.0.0.1:6379> get a -> Redirected to slot [15495] located at 172.38.0.14:6379 "b"
docker搭建redis集群完成!
我们使用了docker之后,所有的技术都会慢慢的变得简单起来!
SpringBoot微服务打包Docker镜像
- 构建springboot项目
@RestController public class HelloController { @RequestMapping("/hello") public String hello(){ return "hello,wydilearn"; } }
- 打包应用
- 编写dockerfile
FROM java:8 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"]
- 构建镜像
[root@ls-Cwj2oH9C home]# mkdir idea [root@ls-Cwj2oH9C home]# cd idea [root@ls-Cwj2oH9C idea]# ls demo1-0.0.1-SNAPSHOT.jar Dockerfile [root@ls-Cwj2oH9C idea]# docker build -t wydilearn .
- 发布运行!
[root@ls-Cwj2oH9C idea]# docker run -d -P --name wydilearn-springboot-web wydilearn cd4d8f37d9e980af091eceac6ef30f51b9291fc415c53457285353881e19f84b [root@ls-Cwj2oH9C idea]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cd4d8f37d9e9 wydilearn "java -jar /app.jar …" 37 seconds ago Up 36 seconds 0.0.0.0:49163->8080/tcp, :::49163->8080/tcp wydilearn-springboot-web [root@ls-Cwj2oH9C idea]# curl localhost:49163 {"timestamp":"2022-07-17T04:04:03.880+00:00","status":404,"error":"Not Found","path":"/"} [root@ls-Cwj2oH9C idea]# curl localhost:49163/hello
以后我们使用了Docker之后,给别人交付的就是一个镜像即可!
到了这里我们已经完全够用了Docker!