Docker
安装
# 安装yum工具包
yum install -y yum-utils
# 移除旧的docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 配置Docker安装的国内镜像源, 需要先安装yum工具包才能使用该命令
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装Docker
yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 启动Docker
systemctl start docker
# 查看Docker版本信息
docker version
# 配置Docker仓库的镜像源
# 创建配置文件目录
mkdir -p /etc/docker
# 创建配置文件
vim /etc/docker/daemon.json
# json文件中填入以下内容, 内容来自https://cr.console.aliyun.com/cn-beijing/instances/mirrors
{
"registry-mirrors": ["https://lsy3fajk.mirror.aliyuncs.com"]
}
# 重启守护进程
systemctl daemon-reload
# 重启docker
systemctl restart docker
# 测试镜像拉取
docker run hello-world
# 卸载docker
yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
# 删除残留文件
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
基本原理
容器
容器相当于一个轻量化的虚拟机,共享操作系统。
容器是半持久的,容器不删除则数据保留,容器一旦删除或被覆盖则数据会丢失。
镜像
每个镜像都是由多个镜像层组成的。
容器是镜像的实例,会在原镜像上新增一个镜像层,容器运行时产生的一切操作都写在这个新的镜像层。这意味着将操作后的容器也可重新打包为镜像。
官方镜像通常都是基础包,里面仅包含运行所需的最小依赖,通常需要自行进行二次构建。
数据卷
数据卷是持久化的核心,也是容器内的文件系统和容器外的文件系统沟通的桥梁,同时也可以实现容器间的数据同步。
命令
介绍
IMAGE 通常既可以是镜像标识也可以是镜像仓库:镜像标签
CONTAINER 同上
基础命令
版本信息
# 版本信息
docker version
命令帮助
# 命令帮助
docker command --help
查看Docker信息
# 查看Docker信息
docker info, docker system info
从镜像仓库查找镜像
# 从镜像仓库查找镜像
docker search
TERM
-f, --filter filter
查看Docker对象的元数据
# 查看Docker对象的元数据
docker inspect
NAME|ID [NAME|ID...]
查看容器的统计信息
# 查看容器的统计信息(CPU 内存等)
docker stats
[CONTAINER...]
-a, --all # 列出所有(默认只展示运行中的容器)
登录账户
docker login
[SERVER]
-p, --password string # 密码或token
-u, --username string # 用户名
登出账户
docker logout
[SERVER]
镜像命令
列出镜像
# 列出镜像,默认只列出
docker image ls, docker image list, docker images
-a, --all # 列出所有
-q, --quiet # 列出镜像标识,常用于复合命令的批量删除
-f, --filter filter
拉取镜像
# 拉取镜像
docker image pull, docker pull
NAME[:TAG|@DIGEST]
-a, --all-tags # 拉取所有
删除镜像
# 删除镜像
docker image rm, docker image remove, docker rmi
IMAGE [IMAGE...]
-f, --force # 强制删除
查看镜像的元数据
# 查看镜像的元数据
docker image inspect
IMAGE [IMAGE...]
-f, --format string
-s, --size # 显示容器大小
构建镜像
docker build, docker builder build, docker image build, docker buildx b
PATH | URL | -
-f, --file string # 构建文件的名称 默认为DockerFile
-t, --tag stringArray # 指定镜像标签
查看镜像构建历史
docker image history, docker history
IMAGE
-H, --human
-q, --quiet
推送镜像
# 通常推送前都需要创建新的镜像名称,因为docker仓库要求个人镜像必须携带账户名,即ssydx/imagename:tag形式
docker image push, docker push
NAME[:TAG]
-a, --all-tags # 推送某镜像的所有标签
创建新镜像名称
# 不会删除旧镜像
docker image tag, docker tag
SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
保存镜像
docker image save, docker save
IMAGE [IMAGE...]
-o, --output string
--platform string
载入镜像
# 由load保存的tar文件
docker image load, docker load
-i, --input string
--platform string
-q, --quiet
移除未使用的镜像
docker image prune
-a, --all # 移除所有未使用镜像(不仅是悬虚镜像)
--filter filter #
-f, --force
导入镜像(没搞懂)
docker image import, docker import
file|URL|- [REPOSITORY[:TAG]]
-c, --change list
-m, --message string
--platform string
容器命令
列出容器
# 列出容器
docker container ls, docker container list, docker container ps, docker ps
-a, --all # 列出所有
-q, --quiet # 仅列出容器标识
-f, --filter filter
-n, --last int # 列出最新的 n 个容器
-l, --latest # 列出最新的一个容器
-s, --size # 列出容器大小
创建并启动容器
# 创建并启动容器,如果启动的容器内没有前台进程,会自动停止
docker container run, docker run
IMAGE [COMMAND] [ARG...]
--name string # 容器名称
-d, --detach # 后台运行
-i, --interactive # 交互式运行
-t, --tty # 指派伪终端
-p, --publish list # 端口映射
-e, --env list # 环境参数
-v, --volume list # 挂载数据卷
退出容器
# 退出容器
exit # 退出容器
CTRL+P+Q # 不关闭进程退出容器
创建容器
# 创建容器
docker container create, docker create
IMAGE [COMMAND] [ARG...]
--name string # 容器名称
-i, --interactive # 交互式运行
-t, --tty # 指派伪终端
-p, --publish list # 端口映射
-e, --env list # 环境参数
删除容器
# 删除容器
docker container rm, docker container remove, docker rm
CONTAINER [CONTAINER...]
-f, --force # 强制删除
启动容器
# 启动容器
docker container start, docker start
CONTAINER [CONTAINER...]
-i, --interactive # 交互模式运行
停止容器
# 停止容器
docker container stop, docker stop
CONTAINER [CONTAINER...]
-t, --timeout int # 延时停止
重启容器
# 重启容器
docker container restart, docker restart
CONTAINER [CONTAINER...]
-t, --timeout int # 延时停止
在运行的容器中执行命令
# 在运行的容器中执行命令
docker container exec, docker exec
CONTAINER COMMAND [ARG...]
-d, --detach # 后台运行
-i, --interactive # 交互式运行
-t, --tty # 指派伪终端
-e, --env list # 环境参数
进入容器中的主进程
# 进入容器中的主进程
docker container attach, docker attach
CONTAINER
查看容器日志
# 查看容器日志,只有前台程序的输出会被记录
docker container logs, docker logs
CONTAINER
-f, --follow # 持续追踪日志
-n, --tail string # 输出最新的 n 条日志
-t, --timestamps # 显示时间戳
查看容器中的进程信息
# 查看容器中的进程信息
docker container top, docker top
CONTAINER [ps OPTIONS]
查看容器元数据
# 查看容器元数据
docker container inspect
CONTAINER [CONTAINER...]
-f, --format string
-s, --size # 显示容器大小
提交容器
# 提交容器,即把容器打包为镜像,相当于虚拟机的快照
docker commit
CONTAINER [REPOSITORY[:TAG]]
-a, --author string # 作者名字
-m, --message string # 附加信息
拷贝文件
# 拷贝文件
docker container cp, docker cp
CONTAINER:SRC_PATH DEST_PATH
SRC_PATH CONTAINER:DEST_PATH
数据卷命令
数据卷在其他命令中的使用
# 挂载
docker run -it -v //c/Users/ssydx/ceshi:/mnt/data centos:7 /bin/bash
# 挂载
docker run -d -p 3310:3306 -v //c/Users/ssydx/mysql/conf:/etc/mysql/conf.d -v //c/Users/ssydx/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# 以上为具名挂载
# 匿名挂载
docker run -d -p 8099:80 --name nginx01 -v /etc/nginx nginx
# 只读或读写
# ro readonly 只读,容器内只能读不能写
docker run -it -v //c/Users/ssydx/ceshi:/mnt/data:ro centos:7 /bin/bash
# ro readwrite 读写
docker run -it -v //c/Users/ssydx/ceshi:/mnt/data:rw centos:7 /bin/bash
# dockfile挂载,会自动挂载(能且仅能匿名挂载)
FROM centos:7
VOLUME ["volume01","volume02"]
CMD ["/bin/bash"]
# 容器关联挂载,两者的文件会同步
# 前提是初始容器(其他所有容器都直接或间接--volumes-from)定义了数据卷,通过dockerfile或-v定义
# 只要多个容器之前存在挂载关系(无所谓挂载与被挂载),就可以实现文件同步,即使停止或删除其中任意个容器,其他容器仍然可以正常访问和同步
docker run -it --name docker01 ssydx/centos
docker run -it --name docker02 --volumes-from docker01 ssydx/centos
# 以下两者在数据同步的效果是相同的
# 分别挂载
docker run -it --name docker01 -v //c/Users/ssydx/ceshi:/mnt/data centos:7 /bin/bash
docker run -it --name docker02 -v //c/Users/ssydx/ceshi:/mnt/data centos:7 /bin/bash
# 共享挂载
docker run -it --name docker01 -v //c/Users/ssydx/ceshi:/mnt/data centos:7 /bin/bash
docker run -it --name docker02 --volumes-from docker01 centos:7 /bin/bash
列出卷
docker volume ls, docker volume list
-f, --filter filter
-q, --quiet # 仅列出卷名
网络命令
docker network
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 ls, docker network list
-f, --filter filter Provide filter values (e.g. "driver=bridge")
-q, --quiet Only display network IDs
# 示例
[root@cloudhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
f8d7afac0feb bridge bridge local
8dffdbbb4754 host host local
7c62537c2879 none null local
查看网络元数据
docker network inspect
NETWORK [NETWORK...]
-f, --format string
-v, --verbose
# 示例
[root@cloudhost ~]# docker network inspect f8d7afac0feb
[
{
"Name": "bridge",
"Id": "f8d7afac0feb290ca06e6375b85d8b70da8ffb5d28875cd6a0403fc7417e86f4",
"Created": "2025-05-13T22:17:23.208499059+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"25a28b42a3546d013cfbfadb5dc0a620a7f27e305ebf952cb40de891066968fa": {
"Name": "tomcat01",
"EndpointID": "a00841e3077e4b77875df5a4fba2d113588a4a418bedd626f807dd8bd3c2ad0d",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"e4f3d4bba32db5d9511983e4af29c42788a378bbe3d7d2c43324976e51366b3e": {
"Name": "tomcat02",
"EndpointID": "c640cdc1aed4d8c7de8edfbe6de8d6de6640bda1bc49baed48f5349fe801668b",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"ee4b60276067148940b2ec0db88b14433a351ab4927773dffd48fa5b603dcfb0": {
"Name": "tomcat03",
"EndpointID": "0c4b7eb206e0afe5245a078ff79310e416d5e56235a34a29c7d8a4518c418376",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
移除网络
docker network rm, docker network remove
-f, --force # 网络不存在时不报错
创建网络
# 为什么要创建自定义桥接网络?因为它默认即可以通过容器名称互联
docker network create
NETWORK
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver
(default map[])
--config-from string The network from which to copy the configuration
--config-only Create a configuration only network
-d, --driver string Driver to manage the Network (default "bridge")
--gateway strings IPv4 or IPv6 Gateway for the master subnet
--ingress Create swarm routing-mesh network
--internal Restrict external access to the network
--ip-range strings Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
--scope string Control the network's scope
--subnet strings Subnet in CIDR format that represents a network segment
# 示例
[root@cloudhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mybridge
连接网络
docker network connect
NETWORK CONTAINER
断联网络
docker network disconnect
NETWORK CONTAINER
-f, --force # 强制断联
安装测试
安装Nginx
# 搜索 nginx 是否存在
# https://hub.docker.com/ 也可以搜索,并且有详细的镜像帮助信息
docker search nginx
# 拉取最新的 nginx 镜像
docker pull nginx
# 创建并启动 nginx 容器
# 从 nginx 镜像(即nginx:latest)创建容器,容器名为 nginx01,后台启动,将本机8099端口映射到nginx服务器监听的80端口
docker run -d --name nginx01 -p 8099:80 nginx
# 检查容器是否启动
docker ps
# 访问端口,测试服务是否正常运行
curl.exe localhost:8099
# 返回值为
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
安装Tomcat
# 拉取
docker pull tomcat
# 创建并运行
docker run -d -p 8099:8080 --name tomcat01 tomcat
# 访问
curl.exe localhost:8099
# 返回
<!doctype html>
<html lang="en">
<head>
<title>HTTP Status 404 – Not Found</title>
<style type="text/css">
body {font-family:Tahoma,Arial,sans-serif;}
h1, h2, h3, b {color:white;background-color:#525D76;}
h1 {font-size:22px;}
h2 {font-size:16px;}
h3 {font-size:14px;}
p {font-size:12px;}
a {color:black;}
.line {height:1px;background-color:#525D76;border:none;}
</style>
</head>
<body>
<h1>HTTP Status 404 – Not Found</h1>
<hr class="line" />
<p><b>Type</b> Status Report</p>
<p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p>
<hr class="line" />
<h3>Apache Tomcat/11.0.6</h3>
</body>
</html>
# 注意:默认webapps下没有文件,这会导致404错误,可以进行如下操作
# 进入容器并启动bash终端
docker exec -it tomcat01 /bin/bash
# 查看webapps目录下的文件,为空,这也是404的原因
ls webapps
# 查看webapps.dist目录下的文件,不为空
ls webapps.dist
# 将webapps.dist目录下的所有文件复制到webapps
cp -r webapps.dist/* webapps
# 再次检查webapps目录
ls webapps
# 这时再访问就正常了
安装Elasticsearch
# 暂不下载新版ES,新版需要进行安全配置,比较麻烦
docker run -d --name elasticsearch7 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
# 访问
curl.exe localhost:9200
# 返回
{
"name" : "1d49e247104f",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "WE0jlsH8Rt-XoHEX0Q3kOw",
"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"
}
# ES默认的资源占用相当高,进行以下设置降低占用
# 限制初始堆内存为64M,最大堆内存为512M
docker run -d --name elasticsearch701 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS='-Xms64m -Xmx512m' elasticsearch:7.6.2
安装Portainer
# 下载镜像,创建容器,运行容器
docker run -d -p 8099:9000 --restart always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer-ce
# 访问端口
# 设置密码
# 查看仪表盘
Dockerfile
基础
关键字大写
顺序执行
#表示注释
每个指令都创建一个镜像层
指令
FROM # 基础镜像
MAINTAINER # 镜像维护者信息,已废弃
LABEL # 镜像维护者信息
RUN # 镜像构建时运行的命令
ADD # 类似COPY,并且支持远程文件和自动解压
WORKDIR # 镜像的工作目录
VOLUME # 挂载数据卷
COPY # 将文件拷贝到镜像中
ENV # 设置环境变量,使用变量时$VAR
EXPOSE # 暴露端口配置
CMD # 单独存在时可以指定命令,和 ENTRYPOINT 同时使用则只能传递参数给 ENTRYPOINT。如果启动时自行指定则会覆盖CMD
ENTRYPOINT # 容器启动时运行的命令,无论是自行指定的命令或参数还是CMD指定的命令或参数,都会作为 ENTRYPOINT 的命令的参数
ONBUILD # 触发指令,当前构建不会触发,构建基于该镜像的构建文件时会运行该指令
USER # 设置容器运行时的用户名
ARG # 定义构建参数
# 如果见到一些镜像继承自scratch镜像,要知道该镜像是最基础的官方镜像,本质是一个空镜像
构建测试
构建CentOS
FROM centos:7
LABEL maintainer="**********" \
description="Customized CentOS 7 with Vim and Net-tools"
ENV MYPATH=/usr/local
WORKDIR $MYPATH
# 替换为阿里云的 CentOS 7 镜像源
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
yum makecache && \
yum -y update && \
yum -y install vim net-tools && \
yum clean all && \
rm -rf /var/cache/yum/*
EXPOSE 8080
CMD ["/bin/bash"]
构建Tomcat
Dockerfile
# 提前编写readme.txt文件并放到当前目录
# 提前下载jdk和tomcat的压缩包并放到当前目录
# Dockfile文件
# 基础镜像
FROM centos:7
# 构建文件的附加信息
LABEL maintainer="**********"
LABEL description="Customized Tomcat"
# 复制文件到容器内的指定目录
COPY readme.txt /usr/local/readme.txt
# 添加两个压缩包,自动解压
ADD jdk-8u202-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.105.tar.gz /usr/local/
# 基于其他镜像源安装vim
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
yum -y install vim
# 设置基本环境变量
ENV MYPATH=/usr/local
# 设置工作目录
WORKDIR $MYPATH
# 设置jdk和tomcat的环境变量
ENV JAVA_HOME=$MYPATH/jdk1.8.0_202
ENV CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME=$MYPATH/apache-tomcat-9.0.105
ENV CATALINA_BASE=$CATALINA_HOME
ENV PATH=$PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 暴露端口
EXPOSE 8080
# 执行命令
CMD ["/bin/sh", "-c", "$CATALINA_HOME/bin/startup.sh && tail -F $CATALINA_HOME/logs/catalina.out"]
# 构建
docker build -t diytomcat .
# 启动
docker run -d --name mytomcat -p 8099:8080 -v //c/Users/ssydx/docker/build/tomcat/test:/usr/local/apache-tomcat-9.0.105/webapps/test -v //c/Users/ssydx/docker/build/tomcat/logs:/usr/local/apache-tomcat-9.0.105/logs diytomcat
# 访问
curl.exe localhost:8099
web.xml
<!-- 在本地test目录下新建WEB-INF目录,并添加该xml文件 -->
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
</web-app>
index.jsp
<!-- 在本地test目录下添加该文件 -->
<html>
<head><title>Hello World</title></head>
<body>
Hello World!<br/>
<%
out.println("Your IP address is " + request.getRemoteAddr());
%>
</body>
</html>
<!-- 访问 -->
curl.exe localhost:8099/test
Docker网络
查看本机网络
[root@cloudhost ~]# 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
# 阿里云内网地址
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:46:7b:9d brd ff:ff:ff:ff:ff:ff
inet 172.31.90.3/20 brd 172.31.95.255 scope global dynamic eth0
valid_lft 1892155449sec preferred_lft 1892155449sec
inet6 fe80::216:3eff:fe46:7b9d/64 scope link
valid_lft forever preferred_lft forever
# docker网络地址,类似路由器,默认请求都会发送到该地址,由其进行转发到对应的容器中
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:54:73:3b:3e brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:54ff:fe73:3b3e/64 scope link
valid_lft forever preferred_lft forever
# 与容器通信的地址,与容器中的成对出现,这就是evth-pair技术
7: vethb1ea393@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 72:fe:61:82:a3:eb brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::70fe:61ff:fe82:a3eb/64 scope link
valid_lft forever preferred_lft forever
查看容器网络
[root@cloudhost ~]# PID=$(docker inspect --format '{{ .State.Pid }}' tomcat01 )
[root@cloudhost ~]# nsenter --net=/proc/$PID/ns/net 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
# 与docker通信的地址
6: eth0@if7: <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
容器交流
# docker和容器交流
[root@cloudhost ~]# 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.055 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.057 ms
^C
# 实际上容器和容器之间也可以通过这种方式交流,在一个容器内ping另一个容器的网址
# tomcat02 ping tomcat01
docker exec -it tomcat02 ping 172.17.0.2
# 删除容器后网关对自动被删除
延申知识1
172.17.0.2/16
172.17.0.2: 这是容器或主机的 IPv4 地址。你可以把它理解为这台“设备”在这个网络中的唯一标识。
/16: 这是 子网掩码的简写形式,表示前 16 位是网络地址,其余 16 位是主机地址。
换句话说:
网络地址范围:172.17.0.0
子网掩码:255.255.0.0
这个子网中可用的 IP 地址数量:2^(32 - 16) = 65,536 个地址
可用主机地址范围:172.17.0.1 ~ 172.17.255.254
别名连接
# 将03链接02
docker run -d -p 8101:8080 --name tomcat03 --link tomcat02 tomcat:10.0.0-jdk8
# 直接通过容器名称进行ping
docker exec -it tomcat03 ping tomcat02
# 反向不行
# 链接原理,也就是说在容器的hosts文件中给172.17.0.3起了别名tomcat02
[root@cloudhost etc]# 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 e4f3d4bba32d
172.17.0.4 ee4b60276067
# 不推荐使用,有更好的方法:自定义桥接网络
[root@cloudhost ~]# docker run -d -P --name tomcat01 --network mybridge tomcat:10.0.0-jdk8
[root@cloudhost ~]# docker run -d -P --name tomcat02 --network mybridge tomcat:10.0.0-jdk8
# 两者可以通过容器名称进行互相ping
[root@cloudhost ~]# docker exec -it tomcat01 ping tomcat02
[root@cloudhost ~]# docker exec -it tomcat02 ping tomcat01
延申知识2
网络连接的模式:
1. bridge 桥接(docker默认)
2. none 无连接
3. host 和宿主机共享
4. container 容器网络连接
网络测试
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
# 创建redis容器
for port in $(seq 1 6)
do
docker run -d \
--name redis-${port} \
-p 637${port}:6379 \
-p 1637${port}:16379 \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
--network redis \
--ip 172.38.0.1${port} \
redis redis-server /etc/redis/redis.conf
done
# 进入容器redis-1
# 配置集群
root@b008d39986ed:/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 --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: de85a670a8cca6e50d560087aa2c8cf5629f6a07 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: c6d13c03c519ed6675ff747b12501ca01e124513 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: 127975058b71871fb0f46ff5e98fdcb2bb5570c0 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: f105d1800ea0c295e76b95c160f27eedee8744c1 172.38.0.14:6379
replicates 127975058b71871fb0f46ff5e98fdcb2bb5570c0
S: 7fe3d48906a629018e69af8ba22d7da7a241eac6 172.38.0.15:6379
replicates de85a670a8cca6e50d560087aa2c8cf5629f6a07
S: a5302db2a398563f324a2fc1fdcd384e0c232947 172.38.0.16:6379
replicates c6d13c03c519ed6675ff747b12501ca01e124513
# 采用默认推荐
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: de85a670a8cca6e50d560087aa2c8cf5629f6a07 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: f105d1800ea0c295e76b95c160f27eedee8744c1 172.38.0.14:6379
slots: (0 slots) slave
replicates 127975058b71871fb0f46ff5e98fdcb2bb5570c0
M: c6d13c03c519ed6675ff747b12501ca01e124513 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 7fe3d48906a629018e69af8ba22d7da7a241eac6 172.38.0.15:6379
slots: (0 slots) slave
replicates de85a670a8cca6e50d560087aa2c8cf5629f6a07
M: 127975058b71871fb0f46ff5e98fdcb2bb5570c0 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: a5302db2a398563f324a2fc1fdcd384e0c232947 172.38.0.16:6379
slots: (0 slots) slave
replicates c6d13c03c519ed6675ff747b12501ca01e124513
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
# 集群模式连接服务器
root@b008d39986ed:/data# redis-cli -c
# 查看集群信息
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:249
cluster_stats_messages_pong_sent:258
cluster_stats_messages_sent:507
cluster_stats_messages_ping_received:253
cluster_stats_messages_pong_received:249
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:507
# 查看节点,三主三从
127.0.0.1:6379> cluster nodes
f105d1800ea0c295e76b95c160f27eedee8744c1 172.38.0.14:6379@16379 slave 127975058b71871fb0f46ff5e98fdcb2bb5570c0 0 1747235548536 3 connected
de85a670a8cca6e50d560087aa2c8cf5629f6a07 172.38.0.11:6379@16379 myself,master - 0 1747235547000 1 connected 0-5460
c6d13c03c519ed6675ff747b12501ca01e124513 172.38.0.12:6379@16379 master - 0 1747235547032 2 connected 5461-10922
7fe3d48906a629018e69af8ba22d7da7a241eac6 172.38.0.15:6379@16379 slave de85a670a8cca6e50d560087aa2c8cf5629f6a07 0 1747235548000 1 connected
127975058b71871fb0f46ff5e98fdcb2bb5570c0 172.38.0.13:6379@16379 master - 0 1747235548000 3 connected 10923-16383
a5302db2a398563f324a2fc1fdcd384e0c232947 172.38.0.16:6379@16379 slave c6d13c03c519ed6675ff747b12501ca01e124513 0 1747235548636 2 connected
# 已知 redis-3为主节点,redis-4为对应的从节点
# 以下操作可以不在同一主机进行
# 集群模式连接服务
# 设置键值对,自动设置到其中一对主从节点内
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
# 集群模式连接服务
# 访问键值对,似乎不能借助keys * 访问
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.13:6379
"b"
# 停止一个容器(上面的172.38.0.13:6379对应的主机,即redis-3)
[root@cloudhost data]# 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#计算机编程合集 文章被收录于专栏
本专栏包含Java、Linux、MySQL、Redis、RabbitMQ、Docker、HTML、CSS、JS等等,作为个人学习记录及知识总结,将长期进行更新!