为何K8S Pod中配置不同暴露端口仍出现容器启动失败?
解决同一Pod中httpd因端口占用无法启动的问题
问题根源
你配置的containerPort只是Kubernetes用来标识容器暴露端口的声明性字段——它不会修改容器内部服务实际监听的端口。nginx默认监听80端口,启动后会占用Pod网络命名空间内的80端口;而httpd默认也监听80,自然会因端口被占用启动失败。
解决方案
要解决这个问题,必须让两个服务在Pod内监听不同的端口,以下是具体实现方式:
1. 修改两个服务的监听端口,与声明的containerPort匹配
因为nginx默认也监听80,所以需要同时修改nginx和httpd的监听端口,分别对应81和82:
针对nginx:
创建自定义nginx.conf,将监听端口从80改为81:
events { worker_connections 1024; } http { server { listen 81; # 修改为81 server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } } }
针对httpd:
创建自定义httpd.conf,修改监听端口为82,并添加ServerName消除域名提示:
ServerName localhost Listen 82 # 保留其他默认配置内容(比如DocumentRoot、模块加载等) DocumentRoot "/usr/local/apache2/htdocs" <Directory "/usr/local/apache2/htdocs"> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory> LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so
通过ConfigMap挂载配置到Pod
将上面的配置文件创建为ConfigMap,然后在Pod中挂载:
apiVersion: v1 kind: ConfigMap metadata: name: web-configs data: nginx.conf: | events { worker_connections 1024; } http { server { listen 81; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } } } httpd.conf: | ServerName localhost Listen 82 DocumentRoot "/usr/local/apache2/htdocs" <Directory "/usr/local/apache2/htdocs"> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory> LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so --- apiVersion: v1 kind: Pod metadata: name: dual-web-pod spec: containers: - name: nginx image: nginx ports: - containerPort: 81 volumeMounts: - name: web-configs mountPath: /etc/nginx/nginx.conf subPath: nginx.conf - name: httpd image: httpd ports: - containerPort: 82 volumeMounts: - name: web-configs mountPath: /usr/local/apache2/conf/httpd.conf subPath: httpd.conf volumes: - name: web-configs configMap: name: web-configs
2. 利用镜像启动参数/环境变量快速修改(部分镜像支持)
部分定制化的httpd/nginx镜像支持通过环境变量指定监听端口,比如:
- 对于httpd,若镜像支持
HTTPD_PORT变量,可直接在Pod配置中添加:- name: httpd image: httpd:custom env: - name: HTTPD_PORT value: "82" ports: - containerPort: 82 - 对于nginx,部分镜像支持
NGINX_LISTEN_PORT变量,或者通过启动命令指定:- name: nginx image: nginx command: ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
3. 排查验证
可以进入nginx容器查看端口占用情况,确认问题:
kubectl exec dual-web-pod -c nginx -- netstat -tulpn
修改后应该能看到nginx监听81端口,httpd启动后监听82端口,二者不再冲突。
内容的提问来源于stack exchange,提问作者macosmi
相关产品推荐
相关产品推荐

