关闭nginx容器之后,再次启动,原来宿主机映射的端口失效的问题解决
最近用containerd在部署nginx的时候,发生了一个比较诡异的问题,当笔者通过nerdctl stop把原来的nginx容器关闭,然后再通过nerdctl run启动一个新的nginx容器的时候,把原来的宿主机端口映射到这个新容器上,但新启动的容器却无法通过映射的端口收到任何请求,而且新容器启动顺利,没有任何报错。这个问题的原因十分隐蔽,而且一开始让人无从下手。本文介绍了这个问题的解决办法,为被该问题困扰的同学提供一个脱困的思路。
1. 环境
出现问题的服务器环境长这样:
$ sudo uname -a
Linux ubuntu-1 5.4.0-121-generic #137-Ubuntu SMP Wed Jun 15 13:33:07 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
$ sudo nerdctl version
Client:Version: v0.20.0OS/Arch: linux/amd64Git commit: e77e05b5fd252274e3727e0439e9a2d45622ccb9Server:containerd:Version: 1.6.6GitCommit: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
同时还更新了cni网络插件到v1.1.1版本。
使用最新的nginx镜像:
$ sudo nerdctl exec nginx-4087e nginx -v
nginx version: nginx/1.25.0
2. 问题重现
首先启动一个nginx容器:
$ sudo nerdctl run -d -v /home/linmao/nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/linmao/nginx/cert:/cert/ -p 8000:8000 -p 4443:4443 nginx
15b4bc769d04e6c28ac895c0403085656e866a35f72157edd6b81aec5464cbe6
其中映射了2个端口,8000端口用来提供http端点,4443端口用来提供https端点。
nginx.conf长这样:
events {worker_connections 64;
}http {resolver 8.8.8.8;server {listen 8000;# 这是部署在nginx服务器上层的网络入口防火墙的ip地址,4443端口映射到本机的4443端口。rewrite ^(.*) https://xxx.xxx.xxx.xxx:4443$1 permanent;}server {listen 4443 ssl;# 这是笔者自签的证书ssl_certificate /cert/self_cert.pem;ssl_certificate_key /cert/self_key.pem;location ~ /(.*)$ {# 这是代理的后端服务的域名proxy_pass https://www.xxxx.com/$1;proxy_redirect off;proxy_set_header Host $proxy_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}
}
此时8000端口和4443端口是正常的。
$ curl localhost:8000
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.25.0</center>
</body>
</html>$ curl localhost:4443
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx/1.25.0</center>
</body>
</html>
关闭这个容器之后再用同样的命令run一个新的nginx,新的nginx启动日志是正常的,但是该新nginx无法收到任何网络流量。映射出来的端口并没有被监听。
$ sudo nerdctl stop 15b4bc769d04
15b4bc769d04$ sudo nerdctl run -d -v /home/linmao/nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/linmao/nginx/cert:/cert/ -p 8000:8000 -p 4443:4443 nginx
b8bf8e71ce1578d2b1f79c5d66cb75d2287a0f0d942d978761124f2dc003b3b8$ sudo nerdctl logs -f b8bf8e71ce1578d2b1f79c5d66cb75d2287a0f0d942d978761124f2dc003b3b8
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up$ curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: No route to host
$ curl localhost:4443
curl: (7) Failed to connect to localhost port 4443: No route to host$ netstat -ano|grep :8000
$
$ netstat -ano|grep :4443
$
3. 问题的原因
遇到这样的问题笔者是一点不慌(才怪),马上打开iptables看一下nat表,一下发现了一些不正常的地方(列表较长,不相关的规则被笔者去掉了,留下的都是相关的规则)。nat表的POSTROUTING链多了2个名为CNI-xxxxxx的规则,并且增加了2个名称对应为CNI-xxxxx的链。另外CNI-HOSTPORT-DNAT的链增加了2个名为CNI-DN-xxx的规则,同时增加了2个对应名称为CNI-DN-xxxxx的规则链。
$ sudo iptables -nL -t nat --line-numbers
...
Chain POSTROUTING (policy ACCEPT)
num target prot opt source destination
...
9 CNI-d7ad1e347f6ac6bffdae5988 all -- 10.4.0.54 0.0.0.0/0 /* name: "bridge" id: "default-15b4bc769d04e6c28ac895c0403085656e866a35f72157edd6b81aec5464cbe6" */
10 CNI-a294464dbb367262e6fa35c6 all -- 10.4.0.55 0.0.0.0/0 /* name: "bridge" id: "default-b8bf8e71ce1578d2b1f79c5d66cb75d2287a0f0d942d978761124f2dc003b3b8" */
...
Chain CNI-HOSTPORT-DNAT (2 references)
num target prot opt source destination
1 CNI-DN-d7ad1e347f6ac6bffdae5 tcp -- 0.0.0.0/0 0.0.0.0/0 /* dnat name: "bridge" id: "default-15b4bc769d04e6c28ac895c0403085656e866a35f72157edd6b81aec5464cbe6" */ multiport dports 8000,4443
2 CNI-DN-a294464dbb367262e6fa3 tcp -- 0.0.0.0/0 0.0.0.0/0 /* dnat name: "bridge" id: "default-b8bf8e71ce1578d2b1f79c5d66cb75d2287a0f0d942d978761124f2dc003b3b8" */ multiport dports 8000,4443
...
Chain CNI-DN-a294464dbb367262e6fa3 (1 references)
num target prot opt source destination
1 CNI-HOSTPORT-SETMARK tcp -- 10.4.0.0/24 0.0.0.0/0 tcp dpt:8000
2 CNI-HOSTPORT-SETMARK tcp -- 127.0.0.1 0.0.0.0/0 tcp dpt:8000
3 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000 to:10.4.0.55:8000
4 CNI-HOSTPORT-SETMARK tcp -- 10.4.0.0/24 0.0.0.0/0 tcp dpt:4443
5 CNI-HOSTPORT-SETMARK tcp -- 127.0.0.1 0.0.0.0/0 tcp dpt:4443
6 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:4443 to:10.4.0.55:4443
...
Chain CNI-DN-d7ad1e347f6ac6bffdae5 (1 references)
num target prot opt source destination
1 CNI-HOSTPORT-SETMARK tcp -- 10.4.0.0/24 0.0.0.0/0 tcp dpt:8000
2 CNI-HOSTPORT-SETMARK tcp -- 127.0.0.1 0.0.0.0/0 tcp dpt:8000
3 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000 to:10.4.0.54:8000
4 CNI-HOSTPORT-SETMARK tcp -- 10.4.0.0/24 0.0.0.0/0 tcp dpt:4443
5 CNI-HOSTPORT-SETMARK tcp -- 127.0.0.1 0.0.0.0/0 tcp dpt:4443
6 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:4443 to:10.4.0.54:4443
...
Chain CNI-d7ad1e347f6ac6bffdae5988 (1 references)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 10.4.0.0/24 /* name: "bridge" id: "default-15b4bc769d04e6c28ac895c0403085656e866a35f72157edd6b81aec5464cbe6" */
2 MASQUERADE all -- 0.0.0.0/0 !224.0.0.0/4 /* name: "bridge" id: "default-15b4bc769d04e6c28ac895c0403085656e866a35f72157edd6b81aec5464cbe6" */
...
Chain CNI-a294464dbb367262e6fa35c6 (1 references)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 10.4.0.0/24 /* name: "bridge" id: "default-b8bf8e71ce1578d2b1f79c5d66cb75d2287a0f0d942d978761124f2dc003b3b8" */
2 MASQUERADE all -- 0.0.0.0/0 !224.0.0.0/4 /* name: "bridge" id: "default-b8bf8e71ce1578d2b1f79c5d66cb75d2287a0f0d942d978761124f2dc003b3b8" */
...
再看一下mangle表,mangle表正常(空的):
$ sudo iptables -nL -t mangle --line-numbers
Chain PREROUTING (policy ACCEPT)
num target prot opt source destinationChain INPUT (policy ACCEPT)
num target prot opt source destinationChain FORWARD (policy ACCEPT)
num target prot opt source destinationChain OUTPUT (policy ACCEPT)
num target prot opt source destinationChain POSTROUTING (policy ACCEPT)
num target prot opt source destinationChain KUBE-IPTABLES-HINT (0 references)
num target prot opt source destinationChain KUBE-KUBELET-CANARY (0 references)
num target prot opt source destination
再看一下filter表也正常,不过在笔者的另一台机器里发现了fliter表也被增加了几个规则。不过在笔者尝试重现问题的时候并未发现filter表有异常。建议同学们也查一下这个表。
$ sudo iptables -nL -t filter --line-numbers
这些新增的规则和规则链不会因为容器的停止而删除。后来笔者发现,这些规则的新增,是因为nginx.conf配置文件中,server块的rewrite命令后边写了ip地址。
server {listen 8000;# 就是这一句写了ip地址,导致出现了上边那些规则,如果把ip地址改成localhost就不会出现上边的问题。rewrite ^(.*) https://xxx.xxx.xxx.xxx:4443$1 permanent;}
4. 问题的解决
知道了原因就很好办了,直接使用iptables -F 或者 iptables -D删掉多出来的规则就行了。有同学知道为什么nginx.conf把rewrite写成一个ip地址,就会在iptables增加一些不会自动删除的规则和规则链的原因的吗?快来评论区告诉笔者吧。
相关文章:
关闭nginx容器之后,再次启动,原来宿主机映射的端口失效的问题解决
最近用containerd在部署nginx的时候,发生了一个比较诡异的问题,当笔者通过nerdctl stop把原来的nginx容器关闭,然后再通过nerdctl run启动一个新的nginx容器的时候,把原来的宿主机端口映射到这个新容器上,但新启动的容…...
【小沐学Python】Python实现在线电子书(MkDocs + readthedocs + github + Markdown)
文章目录 1、简介2、安装3、创建新项目4、添加页面5、编辑导航页6、设置主题7、更改图标图标8、构建网站9、部署9.1 准备github项目9.2 注册登录Read the Docs9.3 导入github项目到 Read the Docs 10、Markdown语法10.1 横线10.2 标题10.3 段落10.4 文字高亮10.5 换行10.6 斜体…...
Python 中的短路评估
文章目录 Python 中的逻辑运算符or (或)运算符AND 运算符 什么是短路在 Python 中使用 AND 运算符进行短路在 Python 中使用 OR 运算符进行短路 本文是关于使用逻辑运算符在 Python 中显示短路行为。 Python 中的逻辑运算符 or (或)运算符 OR:两个操作数均使用 Py…...
LVGL源码分析(1):lv_ll链表的实现
在LVGL中难免需要用到链表:group中的对象需要用链表来存储,这样可以切换对象的焦点;再比如LVGL内部的定时器,多个定时器也是用链表进行存储的。这篇文章就来分析一下LVGL中链表的源码。 文章目录 1 链表结构体2 插入元素源码分析…...
js判断数据类型的几种方法及其局限性(typeof, instanceof, Object.prototype.toString.call())
js中判断了类型的方法有很多, 这篇文章主要来说一下常用的几种判断类型的方法,以及使用: 每个方法都各有优缺点,在日常使用的时候请结合这些优缺点进行斟酌: 1. 使用typeof判断数据类型 javaScript中typeof可以判断以下类型: undefined: 未定义的变量或者值 boolean: 布…...
【MySQL】一文带你掌握聚合查询和联合查询
文章目录 1. 聚合函数1.1 COUNT1.2 SUM1.3 AVG1.4 MAX,MIN 2. GROUP BY3. HAVING4. 联合查询4.1 内连接4.2 外连接4.3 自连接4.4 子连接 5.合并查询5.1 UNION5.2 UNION ALL 1. 聚合函数 概念: 聚合函数是一种用于处理数据集合的函数,它将多个…...
初步了解JVM
JVM 整体组成部分 类加载器 类加载过程 加载:使用IO读取字节码文件,转换并存储,为每个类创建一个Class对象,存储在方法区中 链接(验证,准备,解析) 验证:对字节码文件格式进…...
嘀嗒陪诊小程序v1.0.8+小程序前端
嘀嗒陪诊小程序功能相对简单,后台也简捷,如果只是做个陪诊服务的小程序也基本能满足了,整体测试了下海参崴发现BUG,小程序端也能正常为使用,唯一用户授权接口是老的。 应用背景:人口老龄化少子化ÿ…...
Java中线程的生命周期
Java中线程的生命周期 Java中线程的声明周期与os中线程的生命周期不太一样,java中线程有6个状态,见下: NEW: 初始状态,线程被创建出来但没有被调用 start() 。RUNNABLE: 运行状态,线程被调用了 start()等待运行的状态…...
光线追踪RayTracing,基本原理,判断物体与光线相交
光线的三点假设: 光线按直线传播光线之间不会发生碰撞光线会经过一系列折射反射进入摄像机 可以从摄像机发出光线,推出可逆的光路 上图中,透明球在与相机直连的线条处,需要将折射和反射的着色点结果相加,如果有光源直…...
三十六、数学知识——组合数(递推法 + 预处理法 + 卢卡斯定理 + 分解质因数求解组合数 + 卡特兰数)
组合数算法主要内容 一、基本思路1、组合数基本概念2、递推法——询问次数多 a b 值较小 模处理(%mod)3、预处理阶乘方法——询问次数较多 a b 值很大 模处理(%mod)4、卢卡斯定理——询问次数较少 (a b 值很大&am…...
LinuxC编程——高级文件操作
目录 一、查询文件信息1、stat2、stat fstat lstat区别 二、目录操作2.1 opendir2.2 readdir2.3 closedir例练习:实现ls操作 三、库3.1 库的定义3.2 库的分类3.2.1 静态库3.2.2 动态库 3.3 创建库3.3.1 静态库制作3.3.2 动态库制作 一、查询文件信息 1、stat int …...
【基础知识整理】图的基本概念 邻接矩阵 邻接表
一、图概述 定义: 图(graph)是由一些点(vertex)和这些点之间的连线(edge)所组成的; 其中,点通常被成为"顶点(vertex)“,而点与点之间的连线则被成为"边或弧”(edege)。 通常记为,G(V,E)。 图是一种重要的…...
5.程序控制结构|Java学习笔记
文章目录 程序流程控制介绍顺序控制分支控制分支控制if elseswitch分支结构 循环控制for循环控制while循环控制do...while循环控制跳转控制语句breakcontinuereturn 程序流程控制介绍 顺序控制分支控制循环控制 顺序控制 程序从上到下逐行地执行,中间没有任何判断…...
【最优PID 整定】PID性能指标(ISE,IAE,ITSE和ITAE)优化、稳定性裕量(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Linux内核中断和Linux内核定时器
目录 Linux内核中断 Linux内核定时器 Linux内核中断 int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev) 功能:注册中断 参数: irq : 软中断号 gpio的软中断号 软中断号 gpio_to_i…...
OMG--IDL(Interface Definition Language)
OMG--IDL(Interface Definition Language) 1 概述2 内容缩写IDL 语法和语义概述词法约定ISO Latin-1的字母字符如下表十进制数字字符图形字符格式化字符Tokens注释标识符冲突规则转义标识符关键字IDL识别的其他字符字面量 预处理IDL 语法构建块核心数据类…...
英语学习:M开头
machine 机器 mad 发疯的,生气的 madam 女士,夫人 madame 夫人 magazine 杂志 magic 有魔力的 maid 女仆,侍女 mail 邮递 mailbox 邮箱 mainland 大陆 major 较大的,主要的 majority 大多数 male 雄的 man 人类 man…...
【计算机组成原理与体系结构】控制器
目录 一、CPU的功能与基本结构 二、指令周期的数据流 三、数据通路 四、硬布线控制器 五、微程序控制器 六、微指令 一、CPU的功能与基本结构 运算器基本结构 控制器基本结构 CPU的基本结构 二、指令周期的数据流 取址周期 间址周期 中断周期 指令周期流程 三、数据通路 …...
结构化命令
章节目录: 一、使用 if-then 语句二、if-then-else 语句三、嵌套 if 语句四、test 命令4.1 数值比较4.2 字符串比较4.3 文件比较 五、复合条件测试六、if-then 的高级特性6.1 使用单括号6.2 使用双括号6.3 使用双方括号 七、case 命令八、结束语 本章内容࿱…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...
数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...
【版本控制】GitHub Desktop 入门教程与开源协作全流程解析
目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork(创建个人副本)步骤 2: Clone(克隆…...
