我试图在GKE上启动我的js.js应用程序,但是无论我指定哪个端口,我总是得到这样的错误:
Error: listen EACCES: permission denied tcp://10.3.253.94:3000
at Server.setupListenHandle [as _listen2] (net.js:1296:21)
at listenInCluster (net.js:1361:12)
at Server.listen (net.js:1458:5)
at Function.listen (/srv/node_modules/express/lib/application.js:618:24)
at Object.<anonymous> (/srv/src/index.js:42:5)
at Module._compile (internal/modules/cjs/loader.js:1137:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
at Module.load (internal/modules/cjs/loader.js:985:32)
at Function.Module._load (internal/modules/cjs/loader.js:878:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
我尝试了多个端口(8080,8000,3000)。我在Docker镜像中将用户设置为root
。
下面是我的设置:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: api
name: api
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
dnsPolicy: ClusterFirst
restartPolicy: Always
containers:
- image: gcr.io/ellioseven-kbp/journal-api:1.0.14
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
name: api
apiVersion: v1
kind: Service
metadata:
labels:
app: api
name: api
namespace: default
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 3000
selector:
app: api
type: NodePort
FROM node:12-alpine
ENV PATH /srv/node_modules/.bin:$PATH
ENV API_PORT 3000
ENV REDIS_HOST redis
COPY . /srv
WORKDIR /srv
ENV PATH /srv/node_modules/.bin:$PATH
RUN yarn install
CMD yarn start
EXPOSE 3000
USER root
const port = process.env.API_PORT || 3000
app.listen(port, () => console.log("Listening on " + port))
我在试图解决这个问题时完全不知所措,任何帮助都将不胜感激。
3条答案
按热度按时间zdwk9cvp1#
问题在environment variable conflicting with the service name上。
根据Kubernetes文档
对于Map到名为
bar
的容器的名为foo
的服务,定义了以下变量:更改服务名称或环境变量
例如,使用
API_PORT_NUMBER
而不是API_PORT
ecfdbz9o2#
看起来它不能只绑定到
3000
端口。它可以是以下任何一种:0.0.0.0
。您可以尝试:然后,您可以连接到Pod并尝试启动应用程序
✌️
3duebb1j3#
我在EKS上也遇到了同样的问题。与您的情况相同,问题是由于服务名称中的自动环境变量注入。
回到您的问题上下文,服务名是
api
,选择器指向podapi
。K8将使用以下服务环境变量注入服务主机和端口(请参阅群集信息)
但是等等,这还不是全部!**. K8还创建与Docker Engine的“遗留容器链接”功能兼容的变量。
来自k8s服务网络-环境变量来源:
当Pod在Node上运行时,kubelet会为每个active Service添加一组环境变量。它添加了{SVCNAME}_SERVICE_HOST和{SVCNAME}_SERVICE_PORT变量,其中服务名称为大写,破折号转换为下划线。它还支持与Docker Engine的"legacy container links"功能兼容的变量(请参阅makeLinkVariables)。
因此,这里是
api
服务的环境变量的完整列表,它将被自动创建并注入到api
pod中(您也可以在上面的原始K8s文档中看到redis-primary服务的示例)。正如您所看到的,自动生成的env包含
API_PORT
变量,它与您的env name变量名冲突ENV API_PORT 3000
这种env命名冲突导致pod解析错误的
API_PORT
值并抛出pod启动异常。为了解决这个问题,(正如上面@Anonymous回答所指出的那样),您必须:
api
服务重命名为另一个名称,以避免env变量模式冲突API_PORT_NUMBER