[英]How to change a container's source code and generate a new image from it?
I have deployed this using Kube.netes:我已经使用 Kube.netes 部署了它:
apiVersion: apps/v1
kind: Deployment
metadata:
name: voting-app-deploy
labels:
name: voting-app-deploy
app: demo-voting-app
spec:
replicas: 1
selector:
matchLabels:
name: voting-app-pod
app: demo-voting-app
template:
metadata:
name: voting-app-pod
labels:
name: voting-app-pod
app: demo-voting-app
spec:
containers:
- name: voting-app
image: kodekloud/examplevotingapp_vote:v1
ports:
- containerPort: 80
With this Service:使用此服务:
apiVersion: v1
kind: Service
metadata:
name: voting-service
labels:
name: voting-service
app: demo-voting-app
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30004
selector:
name: voting-app-pod
app: demo-voting-app
After checking if the Pods are running, I get a shell to the running container where I can see the source code and make changes using vi:检查 Pod 是否正在运行后,我将 shell 发送到正在运行的容器,我可以在其中查看源代码并使用 vi 进行更改:
kubectl exec -it podsname -- sh
The problem is whenever I destroy the deployment and bring it back I lose all my changes in the source code.问题是每当我销毁部署并将其恢复时,我都会丢失源代码中的所有更改。
This is the application's Dockerfile, which I got from within the running container:这是应用程序的 Dockerfile,我从正在运行的容器中获得:
# Using official python runtime base image
FROM python:2.7-alpine
# Set the application directory
WORKDIR /app
# Install our requirements.txt
ADD requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
# Copy our code from the current folder to /app inside the container
ADD . /app
# Make port 80 available for links and/or publish
EXPOSE 80
# Define our command to be run when launching the container
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:80", "--log-file", "-", "--access-logfile", "-", "--workers", "4", "--keep-alive", "0"]
So, how can I get this source code and generate a new image?那么,我怎样才能得到这个源代码并生成一个新的图像呢?
Quick and dirty又快又脏
If you change your code often and this isn't a production environment you can use the --reload
that's according to this thread is available since gunicorn 19.0.如果您经常更改代码并且这不是生产环境,您可以使用根据此线程的--reload
自 gunicorn 19.0 以来可用。 this option makes the server reload your code changes into new workers.此选项使服务器将您的代码更改重新加载到新的工作人员中。
Then when you want to save your new image you can use docker commit
to "commit" or save your changes to a new image like so:然后当你想保存你的新图像时,你可以使用docker commit
来“提交”或保存你对新图像的更改,如下所示:
docker commit running_container_name_or_id imagerepo/image-name:tag
Though this isn't that recommended in the long run just for small fixes and checks.尽管从长远来看,这并不是仅针对小的修复和检查而推荐的做法。
Long term preferred usage If you want a long term method method either develop locally with a mounted bind-mount (map a folder from the host machine to the docker container) and build a final image for kube.netes, or you could mount your source code using a config map like in this example:长期首选用法如果你想要一个长期的方法方法,要么在本地开发一个挂载的绑定挂载(将一个文件夹从主机映射到 docker 容器)并为 kube.netes 构建一个最终图像,或者你可以挂载你的源代码使用配置 map 的代码,如本例所示:
apiVersion: v1
kind: ConfigMap
metadata:
name: file-configmap
namespace: default
data:
config.conf: |
[mysqld]
binlog-format=mixed
Pod (usage in deployment is the same): Pod(部署中的用法相同):
apiVersion: v1
kind: Pod
metadata:
name:
spec:
containers:
- name: container-name
image: image-name
volumeMounts:
- name: my-file-volume
mountPath: /path/in/container/config.conf
subPath: config.conf
volumes:
- name: my-file-volume
configMap:
name: file-configmap
I've found a solution to my problem that's not common, I guess.我猜,我已经找到了解决我的问题的不常见方法。 I have to clarify that i'm not working on production environment.我必须澄清我不是在生产环境中工作。 I just want to "steal" the source code from an image, since I don't have access to the repository.我只想从图像中“窃取”源代码,因为我无权访问存储库。
Here is what I did:这是我所做的:
1. Created a folder and subfolder to organize the code. 1.创建一个文件夹和子文件夹来组织代码。 2. Got a shell inside the pod's container: 2. 在 pod 的容器中得到一个 shell:
docker exec -it containername sh
or或者
kubectl exec -it podsname -- sh
cp -R /app /dados/
FROM kodekloud/examplevotingapp_vote:v1
RUN rm -rf /app/*.*
COPY ./dados/app /app
docker build -t myusername/my-voting-app .
docker tag kaiohenricunha/my-voting-app kaiohenricunha/my-voting-app
docker push kaiohenricunha/my-voting-app
You should use volumes.你应该使用卷。
Volumes will allow you to map the src
code folder in the container to a path outside of your container and it will not be destroyed during restart since it will be store outside of your container.卷将允许您将容器中的src
代码文件夹 map 到容器外部的路径,并且它不会在重新启动期间被销毁,因为它将存储在容器外部。
You can see a working sample with explanation here: https://github.com/nirgeier/Kube.netesLabs/tree/master/Labs/09-StatefulSet您可以在此处查看带有解释的工作示例: https://github.com/nirgeier/Kube.netesLabs/tree/master/Labs/09-StatefulSet
emptyDir
emptyDir
is the default volume and it's being deleted when the pod is deleted, but I'm using it here to show you a sample on how to use volumes. emptyDir
是默认卷,它会在删除 pod 时被删除,但我在这里使用它来向您展示如何使用卷的示例。
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
In you container(kubectl exec), use ps | grep gunicorn
在你的容器(kubectl exec)中,使用ps | grep gunicorn
ps | grep gunicorn
find the process of your application. ps | grep gunicorn
找到你申请的进程。 Killed it then start it again.杀死它然后重新启动它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.