简体   繁体   English

如何更改容器的源代码并从中生成新图像?

[英]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

  1. From the shell, edited what I wanted to edit in the source code.来自shell,在源码里编辑了我想编辑的。
  2. Copied the content of the app folder IN THE CONTAINER to my local subfolder(called 'dados'):将容器中应用程序文件夹的内容复制到我的本地子文件夹(称为“dados”):
cp -R /app /dados/
  1. Created a Dockerfile in the folder that's based on the image I want to edit, then run a command to remove the /app folder, and finally, a command to copy the contents of my local folder to the new image I was going to build.在基于我要编辑的图像的文件夹中创建一个 Dockerfile,然后运行一个命令来删除 /app 文件夹,最后,一个命令将我的本地文件夹的内容复制到我要构建的新图像。
FROM kodekloud/examplevotingapp_vote:v1
RUN rm -rf /app/*.*
COPY ./dados/app /app
  1. Created a new repository on DockerHub called 'myusername/my-voting-app' to receive my new image.在 DockerHub 上创建了一个名为“myusername/my-voting-app”的新存储库来接收我的新图像。
  2. Built the new image:构建新图像:
docker build -t myusername/my-voting-app .
  1. Tagged the image with my repo's name:用我的回购名称标记图像:
docker tag kaiohenricunha/my-voting-app kaiohenricunha/my-voting-app
  1. Sent to dockerhub:发送到 dockerhub:
docker push kaiohenricunha/my-voting-app
  1. Now on Kube.netes, changed my pod's container image to the new image I had built and deployed them.现在在 Kube.netes 上,将我的 pod 的容器镜像更改为我构建并部署它们的新镜像。

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.

相关问题 如何在不重新启动的情况下更改docker容器的源代码? - How to change docker container's source code without restarting it? 在开发中的 docker 容器的卷中创建新映像或共享源代码? - Create a new image or share source code in a volume in a docker container in development? 根据Google Cloud Container中容器的更改创建新图像 - Create a new image from a container’s changes in Google Cloud Container 如何从没有镜像的容器创建新的 Docker 镜像 - How to create a new Docker image from a container without an image 新到docker,想知道如何阅读docker的源代码? - new to docker,wonder how to read docker's source code? 如何在不重建Docker镜像的情况下更改源代码? - How to change source code without rebuilding image in Docker? 如何将容器与新图像链接? - How to link container with a new image? 如何从 Amazon 上正在运行的容器创建新的 docker 镜像? - How to create a new docker image from a running container on Amazon? 如何为同步的源代码构建Docker容器? - How to build a docker container for a synchronized source code? 如何从 K8s 集群中检索容器镜像(不仅仅是列出容器镜像名称)? - How can I retrieve the container images from a K8s cluster (not just list the container image names)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM