Docker基础学习笔记

Docker基础学习笔记

Docker常用基本命令

镜像常用命令

images 命令

用于查看本地的docker镜像

# 用法
docker images

在这里插入图片描述

search 命令

用于搜索Docker Hub上的镜像

# 用法
docker search + 镜像名:[tag]
# 例:
docker search centos:8

在这里插入图片描述

tag 命令

标记本地镜像,将其归入某一仓库

也可以用来改镜像名

# 用法
docker tag + 容器ID + 新的容器名:[tag]
# 例:
docker tag d23bdf5b1b1b java01:8

在这里插入图片描述

pull 命令

从镜像仓库中拉取或者更新指定镜像

# 用法
docker pull + 镜像名:[tag]
# 例:
docker pull java:8

在这里插入图片描述

rmi 命令

删除本地一个或多个镜像。

==docker rmi > docker image rm

# 用法
docker rmi + 镜像名:[tag]/镜像id
# 常用参数
-f : 强制删除
# 例:
docker rmi java:8  # docker image rm java:8

在这里插入图片描述

inspect 命令

获取容器/镜像的元数据

# 用法
docker inspect + 镜像id

# 例:查看debian镜像
docker inspect 

在这里插入图片描述

login 命令

登录到镜像仓库

# 用法
docker login

在这里插入图片描述

push 命令

将本地的镜像上传到镜像仓库,要先登陆到镜像仓库

这里的镜像名要是存储库名/镜像名:tag

# 用法
docker push + 存储库名/镜像名:[tag]

# 例: 把debian上传
docker push debian:latest

在这里插入图片描述

build 命令

用于使用 Dockerfile 创建镜像

# 用法
docker build + 参数 + Dockerfile地址 .

# 常用参数:
-f : 指定要使用的Dockerfile路径
-m : 设置内存最大值
-q : --quiet安静模式,成功后只输出镜像id
--rm : 设置镜像成功后删除中间容器
-t : --tag镜像的名字及标签,通常 name:tag

# 例:dockerfile创建一个how:0.1镜像
docker build -f dockerfile -t how:0.1 .

在这里插入图片描述

history 命令

查看指定镜像的创建历史

用法:
docker history + 镜像名/镜像id

# 例:查看debian镜像历史
docker history debian

在这里插入图片描述

容器常用命令

run 命令

创建一个新的容器并运行一个命令

# 用法
docker run + 参数 + 镜像名:[tag]/镜像id 
# 常用参数:
-d : 后台运行容器
-t : 为容器重新分配一个伪输入终端,通常与 -i 同时使用
-p : 随机分配端口映射
-P : 指定端口映射, 格式: 主机端口:容器端口
-i : 以交互模式运行容器,通常与 -t 同时使用
--name= : 为容器指定一个名字(否则随机命名)
-e username= : 设置环境变量
--net= : 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型(不设定默认桥接模式)
--link= : 链接到另一个容器
--expose= : 开放一个端口或一组端口
-v : 相当于 -volume 绑定一个卷/路径
--rm : 当容器停止后自动删除容器
# 例:以交互模式启动debian容器命名为debian01执行/bin/bash命令
docker run -it --name debian01 debian /bin/bash

在这里插入图片描述

# 例:后台启动bwapp容器命名为bwapp01指定容器的80端口与主机的8080端口映射
docker run -d -p 8080:80 --name bwapp01 35d0ed4da0ae
# 访问主机的8080端口:127.0.0.1:8080

在这里插入图片描述

在这里插入图片描述

# 例:以交互模式启动debian容器命名为debian02 链接到debian01容器执行bin/bash命令,安装iputils-ping,ping debain01
docker run -it --name debian02 --link debian01 debian /bin/bash

在这里插入图片描述
在这里插入图片描述

create 命令

创建一个新的容器但不启动它

类似于run命令

# 用法
docker create + 参数 + 镜像名:[tag]/id

# 例:创建一个命名为debian的容器
docker create --name debian debian

在这里插入图片描述

exit 命令

退出容器

快捷键Ctrl + P + Q 也可以退出容器

# 用法
exit

例:从debian02容器中退出来

在这里插入图片描述

stop 命令

停止一个运行中的容器

# 用法
docker stop + 容器名/容器id

# 例:停止debian02容器运行
docker stop debian02

在这里插入图片描述

start 命令

启动一个或多个已经被停止的容器

# 用法
docker start + 容器名/容器id

# 例:启动debian02容器
docker start debian02

在这里插入图片描述

restart 命令

重启容器

# 用法
docker restart + 容器名/容器id

# 例:重启debian02容器
docker restart debian02

在这里插入图片描述

kill 命令

杀掉一个运行中的容器

# 用法
docker kill + 容器名/容器id
# 例:杀掉当前在运行的debian02容器
docker kill debian02

在这里插入图片描述

pause 命令

暂停容器中所有的进程

# 用法
docker pause + 容器名/容器id

# 例:暂停debian02容器中所有的进程
docker pause debian02

在这里插入图片描述

unpause 命令

恢复容器中所有的进程

# 用法
docker unpause + 容器名/容器id

# 例:恢复debian02容器中所有的进程
docker unpause debian02

在这里插入图片描述

exec 命令

进入在运行的容器中执行命令

# 用法
docker exec + 参数 + 容器名/容器id

# 常用参数:
-d : 在后台运行
-i : 交互模式(常于 -t 连用)
-t : 分配一个伪终端(常于 -i 连用)

# 例:交互模式进入debian02执行/bin/bash
docker exec -it debian02 /bin/bash

在这里插入图片描述

attach 命令

连接到正在运行中的容器

exit退出后容器自动关闭

# 用法
docker attach + 容器名/容器id

# 例:连接到debian02容器中
docker attach debian02

在这里插入图片描述

ps 命令

列出容器

# 用法
docker ps + 参数

# 常用参数
-a : 所有容器(正在运行的容器和已经停止的容器)
-q : 显示容器id
# 例:列出正在运行的容器
docker ps

在这里插入图片描述

# 例:列出所有容器
docker ps -a

在这里插入图片描述

# 例:列出正在运行的容器id
docker -q

在这里插入图片描述

# 例:显示所有容器的id
docker ps -aq

在这里插入图片描述

rm 命令

删除一个或多个容器

==docker rm > docker container rm

# 用法
docker rm + 参数 + 容器名/容器id

# 常用参数
-f : 强制删除
-l : 移除容器的网络,不移除容器
-v : 删除与容器关联的卷
# 例:强制删除debian容器
docker rm -f debian

在这里插入图片描述

# 例:删除所有容器
docker rm $(docker ps -a -q)

inspect 命令

获取容器/镜像的元数据

# 用法
docker inspect + 容器id

# 例:查看debian02容器
docker inspect 4a58f3042379

在这里插入图片描述

cp 命令

用于容器与主机之间的数据拷贝

# 用法
docker cp 容器id:容器内数据路径 + 主机路径      # 容器文件拷贝到主机
docker cp 主机路径数据路径 + 容器id:容器内路径   # 主机文件拷贝到容器

# 例:从主机E:\Docker_Projects\拷贝一份readme.md进debian02的/home里
cd /d E:\Docker_Projects\              # cd到E:\Docker_Projects\下
docker cp readme.md 4a58f3042379:/home # 把文件拷贝到容器的/home下
docker exec -it debian02 /bin/bash     # 进入容器
cd /home/                              # cd到/home下
ls                                     # 查看/home下文件

在这里插入图片描述

# 例:把容器里/home/1.txt拷贝到主机的E:\Docker_Projects\下
docker cp 4a58f3042379:/home/1.txt /Docker_Projects\ # 把容器/home/1.txt拷贝到E:\Docker_Projects\下
cd Docker_Projects\                                  # cd到E:\Docker_Projects\下
ls                                                   # 查看文件

在这里插入图片描述

commit 命令

从容器创建一个新的镜像

# 用法
docker commit + 参数 + 容器id + 镜像名:[tag]

# 常用参数:
-a : 提交的镜像作者
-c : 使用Dockerfile指令来创建镜像
-m : 提交时的说明文字
-p : 在commit时,将容器暂停

# 例:用正在运行的debian02容器创建一个debian02:0.1的镜像
docker commit -a "how" -m "just for fun" 4a58f3042379 debian02:0.1

在这里插入图片描述

容器数据卷

使用方式:

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

docker run -it -v 主机目录:容器内目录

匿名挂载: 在-v 命令后只写容器内的路径,不写容器外的路径

具名挂载:在-v命令后主机路径和容器路径都有(方便找到)

区分指定路径挂载 , 具名挂载还是匿名挂载
-v 容器内路径                 #匿名挂载
-v 卷名:容器内路径             #具名挂载
-v 主机路径:容器内路径          #指定路径挂载
# 通过 -v 容器内路径: ro/rw 来改变读写权限
ro:readonly    #只读
rw:readwrite   #可读可写

一旦设了容器权限,只能通过宿主机来操作,容器内无法操作
# 查看同步目录
docker inspect + 容器id

方式二:dockerfile来实现

数据卷容器

多个容器数据同步

--volumes-from + 父容器id

Dockerfile

  • 写一个dockerfile
  • docker build 构建一个镜像文件
  • docker run 运行镜像
  • docker push 发布镜像(dockerhub , 阿里云)

基础知识:

  1. 每个保留关键字(指令)都必须是大写字母
  2. 执行顺序:从上到下的顺序
  3. #表示注释
  4. 每个指定都会创建一个新的镜像层并提交

Dockerfile常用命令

FROM           # 基础镜像
MAINTAINER     # 镜像谁写的,姓名+邮箱
RUN            # 镜像构建的时候需要执行的命令
ADD            # 添加内容
WORKDIR        # 镜像的工作目录
VOLUME         # 挂载的目录
EXPOSE         # 暴露端口
CMD            # 指定这个容器启动的时候运行的命令(只有最后一个会生效,可以被替代)
ENTRYPOINT     # 指定这个容器启动的时候运行的命令(可以追加命令)
ONBULID        # 当构建一个被继承Dockerfile这个时候就会运行 ONBULID 的指令(触发指令)
COPY           # 类似ADD命令将文件拷贝到镜像中
ENV            #构建的时候设置环境变量

创建一个自己的CentOS

1.编写dockerfile文件
# 编写dockerfile文件
FROM centos
MAINTAINER how<penghao223366@gmail.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH

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

CMD echo SMYPATH
CMD echo "-----end-----"
CMD /bin/bash
2.通过dockerfile文件创建centos镜像
# 通过dockerfile文件创建centos镜像
docker build -f + dockerfile文件路径 -t + 镜像名:[tag] .
3.测试运行

通过history命令来列出本地镜像的变更历史

docker history + 镜像id

CMD和ENTRYPOINT的区别

# CMD
FROM centos
CMD ["ls", "-a"]

# ENTRYPOINT
FROM centos
ENTRYPOINT ["ls", "-a"]

实战:部署Tomcat

1.写Dockerfile

# 写Dockerfile
FROM centos
MAINTAINER how<penghao223366@gmail.com>

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

ADD jdk-8u301-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.52.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYTPATH

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

EXPOSE 8080

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

2.制作镜像

# 制作镜像
docker build -t diytomcat .

3.启动容器

# 启动容器
docker run -d -p 9090:8080 --name mytomcat -v /e/Docker_Projects/testfile/Tomcat/test:/usr/local/apache-tomcat-9.0.52/webapps/test -v /e/Docker_Projects/testfile/Tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.52/logs 21138e46bc7f

4.启动访问测试

# 启动访问测试
127.0.0.1:9090

5.发布项目(在本地编写发布)

# 发布项目(在本地编写发布)
# (1)
touch web.xml

<?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">

<display-name></display-name>

<!-- 欢迎页面 -->
<welcome-file-list>
 <welcome-file>index.jsp</welcome-file>
 <welcome-file>index1.jsp</welcome-file>
</welcome-file-list
<!-- 欢迎页面 -->


<!-- url-pattern的意思是所有的.do文件都会经过TestServlet处理。 --> 
<servlet>
 <servlet-name>servlet1</servlet-name>
 <servlet-class>net.test.TestServlet</servlet-class>
</servlet>

<servlet-mapping>
 <servlet-name>servlet1</servlet-name>
 <url-pattern>*.do</url-pattern>
</servlet-mapping>

# (2)
touch index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
 <form action="beandemo.jsp" method="post">
     用户名:<input type="text" name="username">
     密码:<input type="password" name="password">
     <input type="submit" value="Submit">
 </form>
</body>
</html>

6.部署成功可以访问

发布镜像

DockerHub

  1. 地址:https://hub.docker.com/ ,注册自己的账号
  2. 确定账号可以登录
  3. 在服务器提交自己的镜像
docker login # 登录
	-u:username
	-p:password


docker push # 发布镜像
# [注]改名
docker tag + [镜像id] + [镜像的新名字:版本号]

阿里云镜像仓库

  1. 登录阿里云
  2. 找到容器镜像服务
  3. 创建命名空间
  4. 创建容器镜像
# 登录阿里云Docker Registry
docker login --username=[用户名] registry.cn-shanghai.aliyuncs.com
# 从Registry中拉取镜像
docker pull registry.cn-shanghai.aliyuncs.com/howhacker/howhacker:[镜像版本号]
# 将镜像推送到Registry
docker login --username=howha**** registry.cn-shanghai.aliyuncs.com

docker tag [ImageId] registry.cn-shanghai.aliyuncs.com/howhacker/howhacker:[镜像版本号]

docker push registry.cn-shanghai.aliyuncs.com/howhacker/howhacker:[镜像版本号]

Docker网络

理解Docker0

–link命令

# 创建tomcat01容器
docker run -d -P --name tomcat01 tomcat
# 创建tomcat02容器连接tomcat01
docker run -d -P --link tomcat01 --name tomcat02 tomcat
# 这是tomcat02可以ping tomcat01
docker exec -it tomcat02 ping tomcat01  # 可以ping通
# 但是tomcat01不可以ping通tomcat02
docker exec -it tomcat01 ping tomcat02  # 不可以ping通

–link通过host映射实现连接

但是不建议这么使用

自定义网络!不适用docker0

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

自定义网络

网络模式:

  • bridge : 桥接(默认,自己创建也是用桥接模式)
  • none : 不配置网络
  • host : 和宿主机共享网络
  • container : 容器网络连通(用的少,局限大)
# 之前直接启动的命令默认有哟个 --net bridge,这个就是docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

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

创建一个自定义网络

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

# --driver bridge :桥接
# --subnet 192.168.0.0/16 : 子网地址(-192.168.255.255)
# --gateway 192.168.0.1 : 网关地址
[root@how ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "9eb5921910ce0d4fa4d1ee8d5f55b07203cc62a67e71154596e9d39f8d557323",
        "Created": "2021-09-04T16:31:49.676301454+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": {},
        "Options": {},
        "Labels": {}
    }
]
# 启动两个容器
[root@how ~]# docker run -d -P --net mynet --name tomcat01 tomcat
276c60ea13a5c3bb9ca7a2d4762576e62ffc7d4083449c70595f0433e0c2c26d
[root@how ~]# docker run -d -P --net mynet --name tomcat02 tomcat
0a0e314d0197992ae4e21cc539e87ffb6ade91cbf2ab0229422759b9f1b60c01
#查看
[root@how ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "9eb5921910ce0d4fa4d1ee8d5f55b07203cc62a67e71154596e9d39f8d557323",
        "Created": "2021-09-04T16:31:49.676301454+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": {
            "0a0e314d0197992ae4e21cc539e87ffb6ade91cbf2ab0229422759b9f1b60c01": {
                "Name": "tomcat02",
                "EndpointID": "7ba95ab2b03a6bf2719c78bb46092e1184bef280e632978312d379400d022e60",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "276c60ea13a5c3bb9ca7a2d4762576e62ffc7d4083449c70595f0433e0c2c26d": {
                "Name": "tomcat01",
                "EndpointID": "b20754389dcdd0498171401452d86df6b9cf6e8435076793121dd24c6058de69",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
# 测试(可以ping容器名也可以ping容器ip)
root@276c60ea13a5:/usr/local/tomcat# ping tomcat02
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.071 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.064 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.070 ms
^C
--- tomcat02 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3109ms
rtt min/avg/max/mdev = 0.064/0.073/0.088/0.008 ms

root@276c60ea13a5:/usr/local/tomcat# 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.064 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.062 ms
64 bytes from 192.168.0.3: icmp_seq=4 ttl=64 time=0.059 ms
^C
--- 192.168.0.3 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3081ms
rtt min/avg/max/mdev = 0.046/0.057/0.064/0.007 ms

不同的集群使用不同的网络,保证集群健康

网络连通

#新建一个网络mynet2
docker network create --driver bridge --subnet 192.167.0.0/16 --gateway 192.167.0.1 mynet2

# 新建两个mynet2网络下的容器tomcat03,tomcat04
docker run -d -P --net mynet2 --name tomcat03 tomcat
docker run -d -P --net mynet2 --name tomcat04 tomcat
# 将tomcat03连接到mynet网络下
docker network connect mynet tomcat03

# 查看mynet网络
[root@how ~]# docker network inspect mynet
[
 {
     "Name": "mynet",
        "Id": "9eb5921910ce0d4fa4d1ee8d5f55b07203cc62a67e71154596e9d39f8d557323",
        "Created": "2021-09-04T16:31:49.676301454+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": {
            "0a0e314d0197992ae4e21cc539e87ffb6ade91cbf2ab0229422759b9f1b60c01": {
                "Name": "tomcat02",
                "EndpointID": "7ba95ab2b03a6bf2719c78bb46092e1184bef280e632978312d379400d022e60",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "276c60ea13a5c3bb9ca7a2d4762576e62ffc7d4083449c70595f0433e0c2c26d": {
                "Name": "tomcat01",
                "EndpointID": "b20754389dcdd0498171401452d86df6b9cf6e8435076793121dd24c6058de69",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "318bd30ff5030f6e4f824f682d37368258f140b52c685c04a1b6507049ad318b": {
                "Name": "tomcat03",
                "EndpointID": "164ad155cd13719571c940f0360eb9d33cbdbe5f5837e180258d312ae1b0fcb6",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
   ]
   
# 联通后直接将tomcat03加入到mynet中
# 一个容器2个ip
# 测试
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.085 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.061 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.059 ms
^C
--- tomcat02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2026ms
rtt min/avg/max/mdev = 0.059/0.068/0.085/0.011 ms
root@318bd30ff503:/usr/local/tomcat# ping tomcat01
PING tomcat01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.087 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.057 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.056 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.059 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=5 ttl=64 time=0.057 ms
^C
--- tomcat01 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4094ms
rtt min/avg/max/mdev = 0.056/0.063/0.087/0.011 ms
# tomcat03可以ping通tomcat02, tomcat01
# 此时tomcat04依旧无法ping通tomcat02, tomcat01

实战部署Redis集群:

分片 + 高可用 + 负载均衡

六台redis

三主三从

1.创建Redis网络

# 创建Redis网络
docker network create --driver bridge --subnet 192.168.0.1/16 --gateway 192.168.0.1 Redis

2.启动6个Redis容器

(1).创建脚本启动
# 创建脚本启动
for port in $(seq 1 6); \
do \
mkdir -p /home/admin/Docker-file/mydata/redis/node-${port}/conf
touch /home/admin/Docker-file/mydata/redis/node-${port}/conf/redis.conf
cat <<EOF>/home/admin/Docker-file/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 192.168.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
docker run -p 637${port}:6379 -p1637${port}:16379 --name redis-${port} -v /home/admin/Docker-file/mydata/redis/node-${port}/data:/data -v /home/admin/Docker-file/mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf -d --net Redis --ip 192.168.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf;
done
(2).命令启动
# 启动redis-1
docker run -p 6371:6379 -p 16371:16379 --name redis-1 -v /home/admin/Docker-file/mydata/redis/node-1/data:/data -v /home/admin/Docker-file/mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf -d --net Redis --ip 192.168.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 启动redis-2
docker run -p 6372:6379 -p 16372:16379 --name redis-2 -v /home/admin/Docker-file/mydata/redis/node-2/data:/data -v /home/admin/Docker-file/mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf -d --net Redis --ip 192.168.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 启动redis-3
docker run -p 6373:6379 -p 16373:16379 --name redis-3 -v /home/admin/Docker-file/mydata/redis/node-3/data:/data -v /home/admin/Docker-file/mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf -d --net Redis --ip 192.168.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 启动redis-4
docker run -p 6374:6379 -p 16374:16379 --name redis-4 -v /home/admin/Docker-file/mydata/redis/node-4/data:/data -v /home/admin/Docker-file/mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf -d --net Redis --ip 192.168.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 启动redis-5
docker run -p 6375:6379 -p 16375:16379 --name redis-5 -v /home/admin/Docker-file/mydata/redis/node-5/data:/data -v /home/admin/Docker-file/mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf -d --net Redis --ip 192.168.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 启动redis-6
docker run -p 6376:6379 -p 16376:16379 --name redis-6 -v /home/admin/Docker-file/mydata/redis/node-6/data:/data -v /home/admin/Docker-file/mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf -d --net Redis --ip 192.168.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

3.创建集群

# 进入容器redis-1
docker exec -it redis-1 /bin/sh
# 创建集群
redis-cli --cluster create 192.168.0.11:6379 192.168.0.12:6379 192.168.0.13:6379 192.168.0.14:6379 192.168.0.15:6379 192.168.0.16:6379 --cluster-replicas 1
# 返回
/data # redis-cli --cluster create 192.168.0.11:6379 192.168.0.12:6379 192.168.0.13:6379 192.168.0.14:6379 192.168.0.15:6379 192.168.0.16:6379 --cluster-re
plicas 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 192.168.0.15:6379 to 192.168.0.11:6379
Adding replica 192.168.0.16:6379 to 192.168.0.12:6379
Adding replica 192.168.0.14:6379 to 192.168.0.13:6379
M: 2fc2a259cc36419457e1576aa8e5f92b8c966b30 192.168.0.11:6379
   slots:[0-5460] (5461 slots) master
M: cca30ab3faf91376ba7a7e6dffefd325dd0e3887 192.168.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: acc7304f9f218970a9fef330accba86486329837 192.168.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 44d1fc8286dc8d0f95514c9e9f1dec715c25fab7 192.168.0.14:6379
   replicates acc7304f9f218970a9fef330accba86486329837
S: 315f0d008576280a3f37c1e22552ad017bff46aa 192.168.0.15:6379
   replicates 2fc2a259cc36419457e1576aa8e5f92b8c966b30
S: d838c16b2cb75415e466c0e236a3eaf15c2bddfb 192.168.0.16:6379
   replicates cca30ab3faf91376ba7a7e6dffefd325dd0e3887
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 192.168.0.11:6379)
M: 2fc2a259cc36419457e1576aa8e5f92b8c966b30 192.168.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: acc7304f9f218970a9fef330accba86486329837 192.168.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 44d1fc8286dc8d0f95514c9e9f1dec715c25fab7 192.168.0.14:6379
   slots: (0 slots) slave
   replicates acc7304f9f218970a9fef330accba86486329837
S: 315f0d008576280a3f37c1e22552ad017bff46aa 192.168.0.15:6379
   slots: (0 slots) slave
   replicates 2fc2a259cc36419457e1576aa8e5f92b8c966b30
S: d838c16b2cb75415e466c0e236a3eaf15c2bddfb 192.168.0.16:6379
   slots: (0 slots) slave
   replicates cca30ab3faf91376ba7a7e6dffefd325dd0e3887
M: cca30ab3faf91376ba7a7e6dffefd325dd0e3887 192.168.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.

4.测试

# 进入集群
redis-cli -c  # redis-cli : 单机   redis-cli -c : 集群

# 查看信息
cluster info

# 返回
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:426
cluster_stats_messages_pong_sent:427
cluster_stats_messages_sent:853
cluster_stats_messages_ping_received:422
cluster_stats_messages_pong_received:426
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:853

# 查看nodes
cluster nodes

# 返回
127.0.0.1:6379> cluster nodes
acc7304f9f218970a9fef330accba86486329837 192.168.0.13:6379@16379 master - 0 1630764542020 3 connected 10923-16383
44d1fc8286dc8d0f95514c9e9f1dec715c25fab7 192.168.0.14:6379@16379 slave acc7304f9f218970a9fef330accba86486329837 0 1630764541519 4 connected
2fc2a259cc36419457e1576aa8e5f92b8c966b30 192.168.0.11:6379@16379 myself,master - 0 1630764540000 1 connected 0-5460
315f0d008576280a3f37c1e22552ad017bff46aa 192.168.0.15:6379@16379 slave 2fc2a259cc36419457e1576aa8e5f92b8c966b30 0 1630764541018 5 connected
d838c16b2cb75415e466c0e236a3eaf15c2bddfb 192.168.0.16:6379@16379 slave cca30ab3faf91376ba7a7e6dffefd325dd0e3887 0 1630764541018 6 connected
cca30ab3faf91376ba7a7e6dffefd325dd0e3887 192.168.0.12:6379@16379 master - 0 1630764543021 2 connected 5461-10922

# 存值
set a b

# 返回
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 192.168.0.13:6379
OK
# 存放在192.168.0.13里

# 把192.168.0.13这个容器给停了
docker stop redis-3
redis-3

# get a的值
get a

# 返回
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 192.168.0.14:6379
"b"

# 查看nodes
cluster nodes

# 返回
192.168.0.14:6379> cluster nodes
315f0d008576280a3f37c1e22552ad017bff46aa 192.168.0.15:6379@16379 slave 2fc2a259cc36419457e1576aa8e5f92b8c966b30 0 1630764997099 5 connected
d838c16b2cb75415e466c0e236a3eaf15c2bddfb 192.168.0.16:6379@16379 slave cca30ab3faf91376ba7a7e6dffefd325dd0e3887 0 1630764996097 6 connected
acc7304f9f218970a9fef330accba86486329837 192.168.0.13:6379@16379 master,fail - 1630764788489 1630764787687 3 connected
cca30ab3faf91376ba7a7e6dffefd325dd0e3887 192.168.0.12:6379@16379 master - 0 1630764995096 2 connected 5461-10922
44d1fc8286dc8d0f95514c9e9f1dec715c25fab7 192.168.0.14:6379@16379 myself,master - 0 1630764996000 7 connected 10923-16383
2fc2a259cc36419457e1576aa8e5f92b8c966b30 192.168.0.11:6379@16379 master - 0 1630764996000 1 connected 0-5460

5.docker搭建Redis完成!

SpringBoot微服务打包Docker镜像

  1. 构建spring boot项目
  2. 打包项目
  3. 编写dockerfile
  4. 构建镜像
  5. 发布运行

1.创建一个Spring Boot项目

# 创建一个Spring Boot项目
# 新建一个软件包controller,建立一个HelloController类
package com.example.hello.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloControler {

    @RequestMapping("/hello")
    public String hello(){
        return "hello,howhacker";
    }
}

本地自测:127.0.0.1:8080

然后打包

2.新建一个Dockerfile文件

# 新建一个Dockerfile文件
# 编辑Dockerfile
FROM java:8

COPY hello-0.0.1-SNAPSHOT.jar /app.jar

CMD ["---server.port=8080---"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]

3.创建镜像容器

docker build -t how .
docker -d -P --name how how

cca30ab3faf91376ba7a7e6dffefd325dd0e3887 192.168.0.12:6379@16379 master - 0 1630764995096 2 connected 5461-10922
44d1fc8286dc8d0f95514c9e9f1dec715c25fab7 192.168.0.14:6379@16379 myself,master - 0 1630764996000 7 connected 10923-16383
2fc2a259cc36419457e1576aa8e5f92b8c966b30 192.168.0.11:6379@16379 master - 0 1630764996000 1 connected 0-5460

5.docker搭建Redis完成!

SpringBoot微服务打包Docker镜像

  1. 构建spring boot项目
  2. 打包项目
  3. 编写dockerfile
  4. 构建镜像
  5. 发布运行

1.创建一个Spring Boot项目

# 创建一个Spring Boot项目
# 新建一个软件包controller,建立一个HelloController类
package com.example.hello.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloControler {

    @RequestMapping("/hello")
    public String hello(){
        return "hello,howhacker";
    }
}

本地自测:127.0.0.1:8080

然后打包

2.新建一个Dockerfile文件

# 新建一个Dockerfile文件
# 编辑Dockerfile
FROM java:8

COPY hello-0.0.1-SNAPSHOT.jar /app.jar

CMD ["---server.port=8080---"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]

3.创建镜像容器

docker build -t how .
docker -d -P --name how how

热门文章

暂无图片
编程学习 ·

Java输出数组的内容

Java输出数组的内容_一万个小时-CSDN博客_java打印数组内容1. 输出内容最常见的方式// List<String>类型的列表List<String> list new ArrayList<String>();list.add("First");list.add("Second");list.add("Third");list.ad…
暂无图片
编程学习 ·

母螳螂的“魅惑之术”

在它们对大蝗虫发起进攻的时候&#xff0c;我认认真真地观察了一次&#xff0c;因为它们突然像触电一样浑身痉挛起来&#xff0c;警觉地面对限前这个大家伙&#xff0c;然后放下自己优雅的身段和祈祷的双手&#xff0c;摆出了一个可怕的姿势。我被眼前的一幕吓到了&#xff0c;…
暂无图片
编程学习 ·

疯狂填词 mad_libs 第9章9.9.2

#win7 python3.7.0 import os,reos.chdir(d:\documents\program_language) file1open(.\疯狂填词_d9z9d2_r.txt) file2open(.\疯狂填词_d9z9d2_w.txt,w) words[ADJECTIVE,NOUN,VERB,NOUN] str1file1.read()#方法1 for word in words :word_replaceinput(fEnter a {word} :)str1…
暂无图片
编程学习 ·

HBASE 高可用

为了保证HBASE是高可用的,所依赖的HDFS和zookeeper也要是高可用的. 通过参数hbase.rootdir指定了连接到Hadoop的地址,mycluster表示为Hadoop的集群. HBASE本身的高可用很简单,只要在一个健康的集群其他节点通过命令 hbase-daemon.sh start master启动一个Hmaster进程,这个Hmast…
暂无图片
编程学习 ·

js事件操作语法

一、事件的绑定语法 语法形式1 事件监听 标签对象.addEventListener(click,function(){}); 语法形式2 on语法绑定 标签对象.onclick function(){} on语法是通过 等于赋值绑定的事件处理函数 , 等于赋值本质上执行的是覆盖赋值,后赋值的数据会覆盖之前存储的数据,也就是on…
暂无图片
编程学习 ·

Photoshop插件--晕影动态--选区--脚本开发--PS插件

文章目录1.插件界面2.关键代码2.1 选区2.2 动态晕影3.作者寄语PS是一款栅格图像编辑软件&#xff0c;具有许多强大的功能&#xff0c;本文演示如何通过脚本实现晕影动态和选区相关功能&#xff0c;展示从互联网收集而来的一个小插件&#xff0c;供大家学习交流&#xff0c;请勿…
暂无图片
编程学习 ·

vs LNK1104 无法打开文件“xxx.obj”

写在前面&#xff1a; 向大家推荐两本新书&#xff0c;《深度学习计算机视觉实战》和《学习OpenCV4&#xff1a;基于Python的算法实战》。 《深度学习计算机视觉实战》讲了计算机视觉理论基础&#xff0c;讲了案例项目&#xff0c;讲了模型部署&#xff0c;这些项目学会之后可以…
暂无图片
编程学习 ·

工业元宇宙的定义与实施路线图

工业元宇宙的定义与实施路线图 李正海 1 工业元宇宙 给大家做一个关于工业元宇宙的定义。对于工业&#xff0c;从设计的角度来讲&#xff0c;现在的设计人员已经做到了普遍的三维设计&#xff0c;但是进入元宇宙时代&#xff0c;就不仅仅只是三维设计了&#xff0c;我们的目…
暂无图片
编程学习 ·

【leectode 2022.1.15】完成一半题目

有 N 位扣友参加了微软与力扣举办了「以扣会友」线下活动。主办方提供了 2*N 道题目&#xff0c;整型数组 questions 中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题&#xff0c;请返回被选的 N 道题目至少包含多少种知识点类型。 示例 1&#xff1a…
暂无图片
编程学习 ·

js 面试题总结

一、js原型与原型链 1. prototype 每个函数都有一个prototype属性&#xff0c;被称为显示原型 2._ _proto_ _ 每个实例对象都会有_ _proto_ _属性,其被称为隐式原型 每一个实例对象的隐式原型_ _proto_ _属性指向自身构造函数的显式原型prototype 3. constructor 每个prot…
暂无图片
编程学习 ·

java练习代码

打印自定义行数的空心菱形练习代码如下 import java.util.Scanner; public class daYinLengXing{public static void main(String[] args) {System.out.println("请输入行数");Scanner myScanner new Scanner(System.in);int g myScanner.nextInt();int num g%2;//…
暂无图片
编程学习 ·

RocketMQ-什么是死信队列?怎么解决

目录 什么是死信队列 死信队列的特征 死信消息的处理 什么是死信队列 当一条消息初次消费失败&#xff0c;消息队列会自动进行消费重试&#xff1b;达到最大重试次数后&#xff0c;若消费依然失败&#xff0c;则表明消费者在正常情况下无法正确地消费该消息&#xff0c;此时…
暂无图片
编程学习 ·

项目 cg day04

第4章 lua、Canal实现广告缓存 学习目标 Lua介绍 Lua语法 输出、变量定义、数据类型、流程控制(if..)、循环操作、函数、表(数组)、模块OpenResty介绍(理解配置) 封装了Nginx&#xff0c;并且提供了Lua扩展&#xff0c;大大提升了Nginx对并发处理的能&#xff0c;10K-1000K Lu…
暂无图片
编程学习 ·

输出三角形

#include <stdio.h> int main() { int i,j; for(i0;i<5;i) { for(j0;j<i;j) { printf("*"); } printf("\n"); } }
暂无图片
编程学习 ·

stm32的BOOTLOADER学习1

序言 最近计划学习stm32的BOOTLOADER学习,把学习过程记录下来 因为现在网上STM32C8T6还是比较贵的,根据我的需求flash空间小一些也可以,所以我决定使用stm32c6t6.这个芯片的空间是32kb的。 #熟悉芯片内部的空间地址 1、flash ROM&#xff1a; 大小32KB&#xff0c;范围&#xf…
暂无图片
编程学习 ·

通过awk和shell来限制IP多次访问之学不会你打死我

学不会你打死我 今天我们用shell脚本&#xff0c;awk工具来分析日志来判断是否存在扫描器来进行破解网站密码——限制访问次数过多的IP地址&#xff0c;通过Iptables来进行限制。代码在末尾 首先我们要先查看日志的格式&#xff0c;分析出我们需要筛选的内容&#xff0c;日志…
暂无图片
编程学习 ·

Python - 如何像程序员一样思考

在为计算机编写程序之前&#xff0c;您必须学会如何像程序员一样思考。学习像程序员一样思考对任何学生都很有价值。以下步骤可帮助任何人学习编码并了解计算机科学的价值——即使他们不打算成为计算机科学家。 顾名思义&#xff0c;Python经常被想要学习编程的人用作第一语言…
暂无图片
编程学习 ·

蓝桥杯python-数字三角形

问题描述 虽然我前后用了三种做法&#xff0c;但是我发现只有“优化思路_1”可以通过蓝桥杯官网中的测评&#xff0c;但是如果用c/c的话&#xff0c;每个都通得过&#xff0c;足以可见python的效率之低&#xff08;但耐不住人家好用啊&#xff08;哭笑&#xff09;&#xff09…