前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Django应用容器化

Django应用容器化

作者头像
cuijianzhe
发布于 2022-06-14 11:25:23
发布于 2022-06-14 11:25:23
83900
代码可运行
举报
文章被收录于专栏:cuijianzhecuijianzhe
运行总次数:0
代码可运行

Docker

三大核心要素:镜像(Image)、容器(Container)、仓库(Registry)

(先整体看下流程,再逐个演示)

镜像(Image)

打包了业务代码及运行环境的包,是静态的文件,不能直接对外提供服务。

容器(Container)

镜像的运行时,可以对外提供服务。本质上讲是利用 namespace 和 cgroup 等技术在宿主机中创建的独立的虚拟空间

仓库(Registry)
  • 公有仓库,Docker Hub,阿里,网易...
  • 私有仓库,企业内部搭建
    • Docker Registry,Docker 官方提供的镜像仓库存储服务
    • Harbor, 是 Docker Registry 的更高级封装,它除了提供友好的 Web UI 界面,角色和用户权限管理,用户操作审计等功能
  • 镜像访问地址形式 registry.devops.com/demo/hello:latest,若没有前面的 url 地址,则默认寻找 Docker Hub 中的镜像,若没有 tag 标签,则使用 latest 作为标签
  • 公有的仓库中,一般存在这么几类镜像
    • 操作系统基础镜像(centos,ubuntu,suse,alpine)
    • 中间件(nginx,redis,mysql,tomcat)
    • 语言编译环境(python,java,golang)
    • 业务镜像(django-demo...)
  • 启动容器
  • 后台启动 $ docker run --name nginx -d nginx:alpine
  • 查看 run 流程
  • 查看容器进程
  • 等同于在虚拟机中开辟了一块隔离的独立的虚拟空间
  • 启动容器的同时进入容器,-ti 与/bin/sh 或者/bin/bash 配套使用,意思未分配一个 tty 终端 $ docker run --name nginx -ti nginx:alpine /bin/sh (注意:退出容器后,该容器会变成退出状态,因为容器内部的 1 号进程退出)
  • 实际上,在运行容器的时候,镜像地址后面跟的命令等于是覆盖了原有的容器的 CMD 命令,因此,执行的这些命令在容器内部就是 1 号进程,若该进程不存在了,那么容器就会处于退出的状态,比如,宿主机中执行
  • echo 1,执行完后,该命令立马就结束了
  • ping www.baidu.com,执行完后,命令的进程会持续运行 docker run -d --name test_echo nginx:alpine echo 1,容器会立马退出 docker run -d --name test_ping nginx:alpine ping www.baidu.com,容器不会退出,但是因为没有加-d 参数,因此一直在前台运行,若 ctrl+C 终止,则容器退出,因为 1 号进程被终止了
  • 映射端口,把容器的端口映射到宿主机中,-p <host_port>:<container_port> $ docker run --name nginx -d -p 8080:80 nginx:alpine
  • 资源限制,-cpuset-cpus 用于设置容器可以使用的 vCPU 核。-c,--cpu-shares 用于设置多个容器竞争 CPU 时,各个容器相对能分配到的 CPU 时间比例。假设有三个正在运行的容器,这三个容器中的任务都是 CPU 密集型的。第一个容器的 cpu 共享权值是 1024,其它两个容器的 cpu 共享权值是 512。第一个容器将得到 50% 的 CPU 时间,而其它两个容器就只能各得到 25% 的 CPU 时间了。如果再添加第四个 cpu 共享值为 1024 的容器,每个容器得到的 CPU 时间将重新计算。第一个容器的 CPU 时间变为 33%,其它容器分得的 CPU 时间分别为 16.5%、16.5%、33%。必须注意的是,这个比例只有在 CPU 密集型的任务执行时才有用。在四核的系统上,假设有四个单进程的容器,它们都能各自使用一个核的 100% CPU 时间,不管它们的 cpu 共享权值是多少。 $ docker run --cpuset-cpus="0-3" --cpu-shares=512 --memory=500m nginx:alpine

容器数据持久化

  • 挂载主机目录
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker run --name nginx -d  -v /opt:/opt -v /var/log:/var/log nginx:alpine
$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d -v /opt/mysql/:/var/lib/mysql mysql:5.7
  • 使用 volumes 卷
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker volume ls
$ docker volume create my-vol
$ docker run --name nginx -d -v my-vol:/opt/my-vol nginx:alpine
$ docker exec -ti nginx touch /opt/my-vol/a.txt
  • 验证数据共享
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker run --name nginx2 -d -v my-vol:/opt/hh nginx:alpine
$ docker exec -ti nginx2 ls /opt/hh/
a.txt
  • 进入容器或者执行容器内的命令
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker exec -ti <container_id_or_name> /bin/sh
$ docker exec -ti <container_id_or_name> hostname
  • 主机与容器之间拷贝数据 主机拷贝到容器
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ echo '123'>/tmp/test.txt
$ docker cp /tmp/test.txt nginx:/tmp
$ docker exec -ti nginx cat /tmp/test.txt
123

容器拷贝到主机

$ docker cp nginx:/tmp/test.txt ./

  • 查看容器日志

查看全部日志

$ docker logs nginx

实时查看最新日志

$ docker logs -f nginx

从最新的 100 条开始查看

$ docker logs --tail=100 -f nginx

  • 停止或者删除容器

停止运行中的容器

$ docker stop nginx

启动退出容器

$ docker start nginx

删除退出容器

$ docker rm nginx

删除运行中的容器

$ docker rm -f nginx

  • 查看容器或者镜像的明细

查看容器详细信息,包括容器 IP 地址等

$ docker inspect nginx

查看镜像的明细信息

$ docker inspect nginx:alpine

Django 应用容器化实践

django 项目介绍

Dockerfile

Dockerfile 是一堆指令,在 docker build 的时候,按照该指令进行操作,最终生成我们期望的镜像

  • FROM 指定基础镜像,必须为第一个命令
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
格式:
	FROM <image>
	FROM <image>:<tag>
示例:
	FROM mysql:5.7
注意:
	tag是可选的,如果不使用tag时,会使用latest版本的基础镜像
  • MAINTAINER 镜像维护者的信息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
格式:
	MAINTAINER <name>
示例:
    MAINTAINER cuijianzhe
    MAINTAINER 598941324@qq.com
    MAINTAINER Jianzhe Cui <598941324@qq.com>
  • COPY|ADD 添加本地文件到镜像中
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
格式:
	COPY <src>... <dest>
示例:
    ADD hom* /mydir/          # 添加所有以"hom"开头的文件
    ADD test relativeDir/     # 添加 "test"`WORKDIR`/relativeDir/
    ADD test /absoluteDir/    # 添加 "test"/absoluteDir/
  • WORKDIR 工作目录
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
格式:
	WORKDIR /path/to/workdir
示例:
    WORKDIR /a  (这时工作目录为/a)
注意:
	通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUNCMDENTRYPOINTADDCOPY等命令都会在该目录下执行
  • RUN 构建镜像过程中执行命令
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
格式:
	RUN <command>
示例:
    RUN yum install nginx
    RUN pip install django
    RUN mkdir test && rm -rf /var/lib/unusedfiles
注意:
	RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
  • CMD 构建容器后调用,也就是在容器启动时才进行调用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
格式:
    CMD ["executable","param1","param2"] (执行可执行文件,优先)
    CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
    CMD command param1 param2 (执行shell内部命令)
示例:
    CMD ["/usr/bin/wc","--help"]
    CMD ping www.baidu.com
注意:
	CMD不同于RUNCMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
  • ENTRYPOINT 设置容器初始化命令,使其可执行化
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
格式:
    ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
    ENTRYPOINT command param1 param2 (shell内部命令)
示例:
    ENTRYPOINT ["/usr/bin/wc","--help"]
注意:
	ENTRYPOINTCMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令
  • ENV
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
格式:
    ENV <key> <value>
    ENV <key>=<value>
示例:
    ENV myName John
    ENV myCat=fluffy
  • EXPOSE
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
格式:
    EXPOSE <port> [<port>...]
示例:
    EXPOSE 80 443
    EXPOSE 8080
    EXPOSE 11211/tcp 11211/udp
注意:
    EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
  • Dockerfile git clone https://gitee.com/agagin/python-demo.git 当前工作路径:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@k8s-master python-demo]# cat Dockerfile 
# This my first django Dockerfile
# Version 1.0

# Base images 基础镜像
FROM centos:centos7.5.1804

#MAINTAINER 维护者信息
LABEL maintainer="598941324@qq.com"

#ENV 设置环境变量
    ENV LANG en_US.UTF-8
    ENV LC_ALL en_US.UTF-8

#RUN 执行以下命令
RUN curl -so /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum install -y  python36 python3-devel gcc pcre-devel zlib-devel make net-tools

#工作目录
WORKDIR /opt/myblog

#拷贝文件至工作目录
COPY . .

#安装nginx
RUN tar -zxf nginx-1.13.7.tar.gz -C /opt  && cd /opt/nginx-1.13.7 && ./configure --prefix=/usr/local/nginx \
&& make && make install && ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

RUN cp myblog.conf /usr/local/nginx/conf/myblog.conf

#安装依赖的插件
RUN pip3 install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com -r requirements.txt

RUN chmod +x run.sh && rm -rf ~/.cache/pip

#EXPOSE 映射端口
EXPOSE 8002

#容器启动时执行命令
CMD ["./run.sh"]
定制化基础镜像
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@k8s-master python-demo]# cat Dockerfile-base 
[root@k8s-master python-demo]# cat Dockerfile-base 
# Base images 基础镜像
FROM centos:centos7.5.1804

#MAINTAINER 维护者信息
LABEL maintainer="598941324@qq.com"

#ENV 设置环境变量
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8

#RUN 执行以下命令
RUN curl -so /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum install -y  python36 python3-devel gcc pcre-devel zlib-devel make net-tools

COPY nginx-1.13.7.tar.gz  /opt

#安装nginx
RUN tar -zxf /opt/nginx-1.13.7.tar.gz -C /opt  && cd /opt/nginx-1.13.7 && ./configure --prefix=/usr/local/nginx && make && make install && ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

构建基础镜像

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@k8s-master python-demo]# docker build . -t centos-python3-nginx:v1 -f Dockerfile-base
[root@k8s-master python-demo]# docker tag centos-python3-nginx:v1 10.200.51.36:5000/base/centos-python3-nginx:v1
[root@k8s-master python-demo]# docker push 10.200.51.36:5000/base/centos-python3-nginx:v1
简化 Dockerfile
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@k8s-master python-demo]# cat Dockerfile-optimized 
# This my first django Dockerfile
# Version 1.0

# Base images 基础镜像
FROM centos-python3-nginx:v1

#MAINTAINER 维护者信息
LABEL maintainer="598941324@qq.com"

#工作目录
WORKDIR /opt/myblog

#拷贝文件至工作目录
COPY . .

RUN cp myblog.conf /usr/local/nginx/conf/myblog.conf

#安装依赖的插件
RUN pip3 install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com -r requirements.txt

RUN chmod +x run.sh && rm -rf ~/.cache/pip

#EXPOSE 映射端口
EXPOSE 8002

#容器启动时执行命令
CMD ["./run.sh"]

构建镜像

docker build . -t myblog -f Dockerfile-optimized

运行 mysql

docker run -d -p 3306:3306 --name mysql -v /opt/mysql/mysql-data/:/var/lib/mysql -e MYSQL_DATABASE=myblog -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

查看数据库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker exec -ti mysql bash
#/ mysql -uroot -p123456
#/ show databases;

启动 Django 应用

启动容器

docker run -d -p 8002:8002 --name myblog -e MYSQL_HOST=10.200.51.36 -e MYSQL_USER=root -e MYSQL_PASSWD=123456 myblog

查看应用运行状态

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@k8s-master python-demo]# docker exec -it myblog bash
[root@3087587eb981 myblog]# ps -aux 
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.1  0.0  13284  1436 ?        Ss   10:49   0:00 /bin/bash ./run.sh
root         10  0.0  0.0  20544  1564 ?        S    10:50   0:00 nginx: master process nginx -c /usr/local/nginx/conf/myblog.conf -g daemon off;
root         11  0.6  0.0 145272 30004 ?        S    10:50   0:00 uwsgi --ini ./uwsgi.ini
nobody       12  0.0  0.0  20984  1068 ?        S    10:50   0:00 nginx: worker process
root         14  0.0  0.0 219004 25500 ?        Sl   10:50   0:00 uwsgi --ini ./uwsgi.ini
root         15  0.0  0.0 219004 25504 ?        Sl   10:50   0:00 uwsgi --ini ./uwsgi.ini
root         18  0.6  0.0  13404  2016 pts/0    Ss   10:50   0:00 bash
root         32  0.0  0.0  53312  1864 pts/0    R+   10:50   0:00 ps -aux
migrate 进行数据库同步
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker exec -ti myblog bash
#/ python3 manage.py makemigrations
#/ python3 manage.py migrate
#/ python3 manage.py createsuperuser

创建超级用户

docker exec -ti myblog python3 manage.py createsuperuser

收集静态文件

docker exec -ti myblog python3 manage.py collectstatic

访问 10.200.51.36:8002/admin

  • 构建镜像,替换默认编码:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@k8s-master ~]# mkdir mysql
[root@k8s-master ~]# cd mysql/
[root@k8s-master mysql]# vim Dockerfile
[root@k8s-master mysql]# vim my.cnf
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@k8s-master mysql]# cat my.cnf 
[mysqld]
user=root
character-set-server=utf8
lower_case_table_names=1

[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@k8s-master mysql]# cat Dockerfile 
FROM mysql:5.7
COPY my.cnf /etc/mysql/my.cnf

## CMD或者ENTRYPOINT默认继承
[root@k8s-master python-demo]# 
[root@k8s-master python-demo]# docker build . -t mysql:5.7-utf8
Sending build context to Docker daemon  2.104MB
Step 1/2 : FROM mysql:5.7
 ---> 413be204e9c3
Step 2/2 : COPY my.cnf /etc/mysql/my.cnf
 ---> 0e412c9aaf3c
Successfully built 0e412c9aaf3c
Successfully tagged mysql:5.7-utf8
[root@k8s-master python-demo]# docker tag mysql:5.7-utf8 10.200.51.36:5000/mysql:5.7-utf8
[root@k8s-master python-demo]# docker push 10.200.51.36:5000/mysql:5.7-utf8

删除旧的 mysql 容器,使用新镜像启动,不用再次初始化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@k8s-master python-demo]# docker rm -f mysql 
mysql   
[root@k8s-master python-demo]# rm -rf /opt/mysql/mysql-data/*
[root@k8s-master python-demo]# docker run -d -p 3306:3306 --name mysql -v /opt/mysql/mysql-data/:/var/lib/mysql -e MYSQL_DATABASE=myblog -e MYSQL_ROOT_PASSWORD=123456 10.200.51.36:5000/mysql:5.7-utf8
9b3af65a50c3a88858567bd190b6388c98016a79687ee92370a85b683b3c77ea

查看 MySQL 字符集

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@k8s-master mysql]# docker exec -it mysql bash
root@d7440060e2a6:/# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.29 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like '%charac%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)

重新 migrate

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker exec -ti myblog bash
#/ python3 manage.py makemigrations
#/ python3 manage.py migrate
#/ python3 manage.py createsuperuser

Docker 网络详见:https://www.cjzshilong.cn/articles/2019/03/27/1553657246955.html


标题:Django应用容器化

作者:cuijianzhe

地址:https://cloud.tencent.com/developer/article/2022863

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Docker
    • 容器数据持久化
    • 停止运行中的容器
  • Django 应用容器化实践
    • Dockerfile
    • 启动 Django 应用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档