• pod中将代码与运行环境分离


    0. 前言

    我们在创建一个 python 的 web 服务的镜像时,一般的做法是,将 python 环境与代码打包成一个镜像,然后将这个镜像进行发布。

    现在有个需求就是将 python 环境和代码分别构造成两个镜像,让他们进行解耦,并且将他们编排在一个 pod 中。

    本文介绍如何将 pod 中的代码与运行的环境进行拆分。

    1. 思路

    首先我们将代码打包成镜像 A,再将 python 运行环境打包成镜像 B,通过编排在 Pod 中的 InitContainer 设置为镜像 A,并将其内的代码拷贝到挂载的 emptyDir 存储卷中,然后在镜像 B 中挂载相同的存储卷,在使用运行环境中的 python 去执行存储卷中拷贝过来的代码即可。

    2. 案例

    2.1 创建代码镜像

    先创建一个简单的 python web 程序 main.py

    from flask import Flask
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def hello_world():
        return "Hello, World!"
    
    app.run(host="0.0.0.0")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    我们再创建包含代码镜像的 Dockerfile,做的事情是将 main.py 文件拷贝到镜像的根目录下,文件命名为Dockerfile_code

    FROM busybox:latest
    COPY main.py /
    
    • 1
    • 2

    我们通过 docker build 开始创建镜像,镜像名称为 demo_code,默认 tag为 latest

    docker build . -t "demo_code" -f Dockerfile_code
    
    • 1

    这个时候我们的代码镜像创建好了。

    2.2 创建 python 运行环境

    我们开始创建 python 运行环境镜像的 Dockerfile,以 python3 的镜像为基础,并安装 flask 库,文件名为 Dockerfile_runtime

    FROM python:3
    RUN pip install flask
    
    • 1
    • 2

    再构建一下这个镜像,镜像名为 demo_runtime,默认 tag 是 latest

    docker build . -t "demo_runtime" -f Dockerfile_runtime
    
    • 1

    这个时候,两个镜像都已准备好

    2.3 容器编排

    创建 deployments.yaml 文件,在 Pod 中的 initContainers 中配置代码镜像, 然后挂载临时存储卷,将代码复制到存储卷中。

    然后再配置应用容器 python 运行环境,挂载上面相同的临时存储卷,然后再使用 python 将代码运行。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: demo
      labels:
        app: demo
    spec:
      selector:
        matchLabels:
          app: demo
      template:
        metadata:
          labels:
            app: demo
        spec:
          initContainers:
            - image: demo_code:latest
              name: code
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - mountPath: /opt/demo
                name: app-volume
              command: ["cp", "/main.py", "/opt/demo/"]
          containers:
            - name: runtime
              image: demo_runtime:latest
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 5000
                  hostPort: 5000
                  protocol: TCP
                  name: http
              volumeMounts:
                - mountPath: /opt/demo
                  name: app-volume
              command: ["python", "/opt/demo/main.py"]
          volumes:
          - name: app-volume
            emptyDir: { }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    我们通过 kubectl apply 创建 deployments

    kubectl apply -f deployments.yaml
    
    • 1

    我们通过 kubectl get pods 可以看到 pod 已经创建成功,然后找到 pod 所在的节点。通过节点 ip+端口即可访问到容器的中接口。

    [root@k8s-master-07rf9 test]# kubectl get pods -o wide
    NAME                    READY   STATUS    RESTARTS   AGE     IP               NODE               NOMINATED NODE   READINESS GATES
    demo-6f49db5d6c-25vss   1/1     Running   0          4m58s   10.244.132.130   k8s-master-07rf9   <none>           <none>
    
    
    [root@k8s-master-07rf9 test]# curl 10.65.132.187:5000
    Hello, World!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3. 总结

    本文的编排方式只是 pod 的设计模式的一种。有兴趣的可以了解更多。

    通过这种方式可以让代码与运行环境解耦,当我们更新代码时,并不会影响到运行环境。

    相关推荐

    k8s之docker容器

    k8s之Pod

    欢迎关注,互相学习,共同进步~

    个人博客

    微信公众号:编程黑洞

  • 相关阅读:
    torch.cumprod实现累乘计算
    dpdk 网卡初始化 —— 收包
    光点高校数据中台,助力高校信息化迎来发展新格局_光点科技
    AS86汇编语法
    智工教育:公务员网上报名确认事项与流程的状态标识
    2023内蒙古科技大学计算机考研信息汇总
    【中秋快乐】如何用three.js实现我的太空遐想3D网页
    25 Python的collections模块
    如何在视频上添加水印?建议收藏这些方法
    Python条件语句+字典
  • 原文地址:https://blog.csdn.net/qq_22918243/article/details/127843141