[英]How to deploy a node.js with redis on kubernetes?
我有一个非常简单的node.js应用程序(HTTP服务),它与redis“对话”。 我想创建一个部署并使用minikube运行它。
根据我的理解,我需要一个kubernetes Pod为我的应用程序,基于docker镜像。 这是我的Dockerfile:
FROM node:8.9.1
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD ["npm", "start"]
我用docker build -t my-app .
构建了docker镜像docker build -t my-app .
接下来,我为我的应用程序Pod创建了一个Pod定义:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: my-app
image: my-app:latest
imagePullPolicy: Never
ports:
- containerPort: 8080
到现在为止还挺好。 但是从现在开始,我不清楚如何继续使用redis:
应该redis是另一个Pod,还是一个服务(就Kubernetes而言)?
如何从我的应用程序中引用redis? 根据是否将redis定义为Pod / Service,如何获取连接URL和端口? 我读到了Kubernetes创建的环境变量,但我不确定它们是否适用于Pods或Services。
如何在单一配置下聚合(我的app和redis)? 如何确保redis首先启动,然后启动我的应用程序(需要运行redis实例),以及如何将我的HTTP端点暴露给“外部世界”? 我读到了Deployments,但我不确定如何将这些部分连接在一起。
理想情况下,我希望在YAML文件中包含所有配置,以便在一天结束时可以使用单个命令启动整个基础结构。
我想我找到了一个解决方案(使用部署和服务)。
对于我的部署,我在一个Pod中使用了两个容器(webapp + redis),因为没有活动的redis实例运行webapp没有意义,另外它在应用程序启动时连接到redis。 我在这个推理中可能是错的,所以如果你不这么想的话,请随时纠正我。
这是我的部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
spec:
selector:
matchLabels:
app: my-app-deployment
template:
metadata:
labels:
app: my-app-deployment
spec:
containers:
- name: redis
image: redis:latest
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /srv/www
name: redis-storage
- name: my-app
image: my-app:latest
imagePullPolicy: Never
ports:
- containerPort: 8080
volumes:
- name: redis-storage
emptyDir: {}
这是服务定义:
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
ports:
- port: 8080
protocol: TCP
type: NodePort
selector:
app: my-app-deployment
我使用以下kubectl create -f deployment.yaml
部署: kubectl create -f deployment.yaml
然后,我使用kubectl create -f service.yaml
我使用minikube ip
读取IP并从kubectl describe service my-app-service
的输出中提取端口。
我同意以前的所有答案。 我只是通过执行一个命令来尝试更简单的事情。
首先,在文件中为redis创建必要的清单,例如redis.yaml
和service以将其暴露在外面。
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
app: node-redis
spec:
ports:
- name: redis
port: 6379
targetPort: 6379
type: NodePort
selector:
app: node-redis
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
selector:
matchLabels:
app: node-redis
replicas: 1
template:
metadata:
labels:
app: node-redis
spec:
containers:
- name: redis
image: redis:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
# data volume where redis writes data
volumeMounts:
- name: data
mountPath: /data
readOnly: false
volumes:
- name: data
persistentVolumeClaim:
claimName: redis-data
---
# data volume
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-data
labels:
app: node-redis
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
接下来将您的应用的清单放在另一个文件中,说my-app.yaml
。 这里我放置了volume字段,以便您可以使用redis存储的数据。
apiVersion: v1
kind: Pod
metadata:
name: my-app
labels:
app: node-redis
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 8080
# data volume from where my-app read data those are written by redis
volumeMounts:
- name: data
mountPath: /data
readOnly: false
volumes:
- name: data
persistentVolumeClaim:
claimName: redis-data
现在我们可以使用以下bash文件my-app.sh
。
#!/bin/bash
kubectl create -f redis.yaml
pod_name=$(kubectl get po -l app=node-redis | grep app-with-redis | awk '{print $1}')
# check whether redis server is ready or not
while true; do
pong=$(kubectl exec -it $pod_name -c redis redis-cli ping)
if [[ "$pong" == *"PONG"* ]]; then
echo ok;
break
fi
done
kubectl create -f my-app.yaml
只需运行chmod +x my-app.sh; ./my-app.sh
部署chmod +x my-app.sh; ./my-app.sh
。 要获取网址运行minikube service redis --url
。 您可以类似地获取应用的网址。 唯一需要的是,您的应用需要nodePort
类型的服务才能从群集外部访问它。
所以,现在一切都掌握在你手中。
是的,你需要一个separete deployement
和redis service
使用kubernetes服务发现,应该内置,KubeDNS,CoreDNS
使用readniness和liveness探针
是的,您可以编写一个大的yaml文件来描述所有部署和服务。 然后:
kubectl apply -f yourfile.yml
或者您可以将yaml放在单独的文件中,然后执行以下操作:
kubectl apply -f dir/
我建议你进一步阅读k8s文档,但总的来说,你提出的问题是:
我会在一个单独的pod中运行redis(即:因此,如果自身崩溃,您的Web应用程序不会删除redis服务器)。
这是您的redis部署和服务:
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
selector:
matchLabels:
app: redis
replicas: 1
template:
metadata:
labels:
app: redis
spec:
volumes:
- name: host-sys
hostPath:
path: /sys
initContainers:
- name: disable-thp
image: redis:4.0-alpine
volumeMounts:
- name: host-sys
mountPath: /host-sys
command: ["sh", "-c", "echo never > /host-sys/kernel/mm/transparent_hugepage/enabled"]
containers:
- name: redis
image: redis:4.0-alpine
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 350m
memory: 1024Mi
ports:
- containerPort: 6379
service.yaml:
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
app: redis
spec:
ports:
- port: 6379
name: redis
selector:
app: redis
由于我们已经公开了kubernetes Service
您可以通过主机名访问您的redis实例,或者它是“服务名称”,即redis
。
您可以访问https://github.com/mateothegreat/k8-byexamples-redis查看我的kubernetes redis存储库。 如果您想要更简单的路线,只需运行make install
即可。
祝你好运,如果你仍然卡住了,请伸出手!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.