Docker容器技术-在开发中引用Docker
明确一点:
容器不适合构建那种发布周期以周或月为单位的大型单一架构企业软件,容器适合采用微服务的方式,以及探索诸如持续部署这样的技术,使得我们能安全地在一天内多次更新生产环境。
一、在开发中引用Docker
1.Hello World
[root@bogon ~]# tree identidock/
identidock/
└── app
└── identidock.py
1 directory, 1 file
[root@bogon ~]# cat identidock/app/identidock.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!\n'
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0')
[root@bogon identidock]# cat Dockerfile
FROM python:3.4
RUN pip install Flask==0.10.1
WORKDIR /app
COPY app /app
CMD ["python","identidock.py"]
[root@bogon identidock]# docker build -t identidock .
Sending build context to Docker daemon 3.584kB
Step 1/5 : FROM python:3.4
3.4: Pulling from library/python
85b1f47fba49: Already exists
5409e9a7fa9e: Pull complete
661393707836: Pull complete
1bb98c08d57e: Pull complete
c842a08369e2: Pull complete
e639d6c3a797: Pull complete
2e0d93ba8849: Pull complete
9e4c4ef684d8: Pull complete
Digest: sha256:602a002f554d617e33f7d9cfe9cf3add9b067ae9a52b346d9c2739e2b04f1911
Status: Downloaded newer image for python:3.4
---> 9ff45ddb54e9
Step 2/5 : RUN pip install Flask==0.10.1
---> Running in c82b2bbcbd6d
Collecting Flask==0.10.1
Downloading Flask-0.10.1.tar.gz (544kB)
Collecting Werkzeug>=0.7 (from Flask==0.10.1)
Downloading Werkzeug-0.12.2-py2.py3-none-any.whl (312kB)
Collecting Jinja2>=2.4 (from Flask==0.10.1)
Downloading Jinja2-2.9.6-py2.py3-none-any.whl (340kB)
Collecting itsdangerous>=0.21 (from Flask==0.10.1)
Downloading itsdangerous-0.24.tar.gz (46kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->Flask==0.10.1)
Downloading MarkupSafe-1.0.tar.gz
Building wheels for collected packages: Flask, itsdangerous, MarkupSafe
Running setup.py bdist_wheel for Flask: started
Running setup.py bdist_wheel for Flask: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/b6/09/65/5fcf16f74f334a215447c26769e291c41883862fe0dc7c1430
Running setup.py bdist_wheel for itsdangerous: started
Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a
Running setup.py bdist_wheel for MarkupSafe: started
Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57
Successfully built Flask itsdangerous MarkupSafe
Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, Flask
Successfully installed Flask-0.10.1 Jinja2-2.9.6 MarkupSafe-1.0 Werkzeug-0.12.2 itsdangerous-0.24
---> 56884eab20ce
Removing intermediate container c82b2bbcbd6d
Step 3/5 : WORKDIR /app
---> c8264e007723
Removing intermediate container 6434d0fa05bb
Step 4/5 : COPY app /app
---> af7180d3035a
Step 5/5 : CMD python identidock.py
---> Running in 8d7abf6ad746
---> bb30628df539
Removing intermediate container 8d7abf6ad746
Successfully built bb30628df539
Successfully tagged identidock:latest
[root@bogon identidock]# docker run -d -p 6000:6000 identidock
c37f908198b5c5fc1f587c5f0a5eb0a9bf86addab3ed995ae2a8afd9c1b05a11
[root@bogon identidock]# curl localhost:6000
Hello World!
2.Docker Machine的IP地址
如果你是通过Docker Machine来运行Docker的,你将无法使用localhost作为URL,而是必须使用Docker虚拟机的IP地址。
通过Docker Machine的ip命令可以帮助我们把这个步骤自动化。
[root@bogon identidock]# curl $(docker-machine ip default):6000
3.问题所在
即使代码需要少许改变,我们也需要重新创建镜像,并且重启容器。
解决方法:
把主机上的源码目录绑定挂载到容器内的源码目录上
[root@bogon identidock]# docker stop $(docker ps -lq)
c37f908198b5
[root@bogon identidock]# docker rm $(docker ps -lq)
c37f908198b5
[root@bogon identidock]# docker run -d -p 6000:6000 -v "$PWD"/app:/app identidock
4506f26b14ebdb01d982e1dd6b850b53309349bd453b3a848bbfde9b76266f6e
-v "$PWD"/app:/app参数把位于/app的app目录挂载到容器内,将覆盖容器中的/app目录的内容,在容器内也可以进行读写。(必须是绝对路径)
4.生产环境
以上的操作无法在生产环境中使用,因为它运行的是默认Flask Web服务器,仅适合开发环境。
uWSGI是一个可立即用于生产环境的应用服务器,它可以部署在Web服务器(nginx)的后面。
[root@bogon identidock]# cat Dockerfile
FROM python:3.4
RUN pip install Flask==0.10.1 uWSGI==2.0.8
WORKDIR /app
COPY app /app
CMD ["uwsgi","--http","0.0.0.0:9090","--wsgi-file","/app/identidock.py",\
"--callable","app","--stats","0.0.0.0:9191"]
[root@bogon identidock]# docker build -t identidock .
Sending build context to Docker daemon 3.584kB
Step 1/5 : FROM python:3.4
---> 9ff45ddb54e9
Step 2/5 : RUN pip install Flask==0.10.1 uWSGI==2.0.8
---> Running in 841c626396cf
Collecting Flask==0.10.1
Downloading Flask-0.10.1.tar.gz (544kB)
Collecting uWSGI==2.0.8
Downloading uwsgi-2.0.8.tar.gz (775kB)
Collecting Werkzeug>=0.7 (from Flask==0.10.1)
Downloading Werkzeug-0.12.2-py2.py3-none-any.whl (312kB)
Collecting Jinja2>=2.4 (from Flask==0.10.1)
Downloading Jinja2-2.9.6-py2.py3-none-any.whl (340kB)
Collecting itsdangerous>=0.21 (from Flask==0.10.1)
Downloading itsdangerous-0.24.tar.gz (46kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->Flask==0.10.1)
Downloading MarkupSafe-1.0.tar.gz
Building wheels for collected packages: Flask, uWSGI, itsdangerous, MarkupSafe
Running setup.py bdist_wheel for Flask: started
Running setup.py bdist_wheel for Flask: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/b6/09/65/5fcf16f74f334a215447c26769e291c41883862fe0dc7c1430
Running setup.py bdist_wheel for uWSGI: started
Running setup.py bdist_wheel for uWSGI: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/04/43/f1/b6308e3b9ea71a31b9e5b69b6fe50bea89e852688bf46e8b92
Running setup.py bdist_wheel for itsdangerous: started
Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a
Running setup.py bdist_wheel for MarkupSafe: started
Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57
Successfully built Flask uWSGI itsdangerous MarkupSafe
Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, Flask, uWSGI
Successfully installed Flask-0.10.1 Jinja2-2.9.6 MarkupSafe-1.0 Werkzeug-0.12.2 itsdangerous-0.24 uWSGI-2.0.8
---> bb39db2742b4
Removing intermediate container 841c626396cf
Step 3/5 : WORKDIR /app
---> 7159f825056f
Removing intermediate container adebe6c2be8c
Step 4/5 : COPY app /app
---> 10d16296b152
Step 5/5 : CMD uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py --callable app --stats 0.0.0.0:9191
---> Running in 9aa13fad3828
---> 74c2ce58923a
Removing intermediate container 9aa13fad3828
Successfully built 74c2ce58923a
Successfully tagged identidock:latest
[root@bogon identidock]# docker run -d -p 9090:9090 -p 9191:9191 identidock
5cf9310a588595fa5cf0ee9783db9ef8fe1e061489c419863cae2b46821e732d
[root@bogon identidock]# curl localhost:9090
Hello World!
[root@bogon identidock]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5cf9310a5885 identidock "uwsgi --http 0.0...." 2 minutes ago Up 2 minutes 0.0.0.0:9090->9090/tcp, 0.0.0.0:9191->9191/tcp gracious_boyd
[root@bogon identidock]# docker logs 5cf9310a5885
*** Starting uWSGI 2.0.8 (64bit) on [Mon Oct 23 23:08:32 2017] ***
compiled with version: 4.9.2 on 23 October 2017 23:06:45
os: Linux-3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017
nodename: 5cf9310a5885
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 2
current working directory: /app
detected binary path: /usr/local/bin/uwsgi
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
your memory page size is 4096 bytes
detected max file descriptor number: 65536
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on 0.0.0.0:9090 fd 4
uwsgi socket 0 bound to TCP address 127.0.0.1:42416 (port auto-assigned) fd 3
Python version: 3.4.7 (default, Oct 10 2017, 02:41:01) [GCC 4.9.2]
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x129f5f0
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 145536 bytes (142 KB) for 1 cores
*** Operational MODE: single process ***
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x129f5f0 pid: 1 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 1)
spawned uWSGI worker 1 (pid: 6, cores: 1)
*** Stats server enabled on 0.0.0.0:9191 fd: 13 ***
spawned uWSGI http 1 (pid: 7)
[pid: 6|app: 0|req: 1/1] 172.17.0.1 () {28 vars in 295 bytes} [Mon Oct 23 23:08:40 2017] GET / => generated 13 bytes in 2 msecs (HTTP/1.1 200) 2 headers in 79 bytes (1 switches on core 0)
[root@bogon identidock]# docker run identidock whoami
root
后续处理:
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
安全漏洞—以root身份运行。
在Dockerfile中加入以下行:
RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi(创建用户及组)
EXPOSE 9090 9191(暴露端口)
USER uwsgi(这一行以后的指令由uwsgi执行)
环境变量设置
[root@bogon identidock]# cat cmd.sh
#!/bin/bash
set -e
if [ "$ENV" = "DEV" ];then
echo "Running Development Server"
exec python "identidock.py"
else
echo "Running Production Server"
exec uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py \
--callable app --stats 0.0.0.0:9191
fi
5.容器内的用户和用户组
Linux内核使用UID和GID来识别用户,并决定访问权限。将UID和GID映射到标识符是由操作系统的用户空间处理的。因此在容器中的UID和主机上的UID是相同的,但在容器内创建的用户和用户组并不会传播到主机。这使得访问权限变得混乱,相同的文件,在容器和主机上的拥有者可能不一样。
把USER设置妥当是非常重要的。
6.配置文件和辅助脚本
随着应用的增长,应尽量把Dockerfile的内容移动到辅助文件和脚本中,例如pip的依赖关系应移到requirements.txt文件,uWSGI配置移动到ini文件中。
[root@bogon identidock]# cat Dockerfile.1031
FROM python:3.4
RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
RUN pip install Flask==0.10.1 uWSGI==2.0.8
WORKDIR /app
COPY app /app
EXPOSE 9090 9191
USER uwsgi
CMD ["/cmd.sh"]
[root@bogon identidock]# docker stop $(docker ps -q)
5cf9310a5885
4506f26b14eb
9543c03c9b29
a6fa275bf25e
315436a94296
273d88e3c232
521006b3e1d0
c4cf3b0bafe3
dd923378c826
[root@bogon identidock]# docker rm $(docker ps -aq)
e3d53f53f4cc
5cf9310a5885
4506f26b14eb
dab33ca46986
bc8a45b6bb49
9543c03c9b29
a6fa275bf25e
[root@bogon identidock]# chmod +x cmd.sh
[root@bogon identidock]# docker build -t identidock .
Sending build context to Docker daemon 5.632kB
Step 1/5 : FROM python:3.4
---> 9ff45ddb54e9
Step 2/5 : RUN pip install Flask==0.10.1 uWSGI==2.0.8
---> Using cache
---> bb39db2742b4
Step 3/5 : WORKDIR /app
---> Using cache
---> 7159f825056f
Step 4/5 : COPY app /app
---> Using cache
---> 10d16296b152
Step 5/5 : CMD uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py --callable app --stats 0.0.0.0:9191
---> Using cache
---> 74c2ce58923a
Successfully built 74c2ce58923a
Successfully tagged identidock:latest
[root@bogon identidock]# docker run -e "ENV=DEV" -p 6000:6000 identidock
*** Starting uWSGI 2.0.8 (64bit) on [Tue Oct 24 00:44:34 2017] ***
compiled with version: 4.9.2 on 23 October 2017 23:06:45
os: Linux-3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017
nodename: 2a4f1706fb55
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 2
二、通过Compose实现自动化
1.如何构建Compose
使用YAML文件存储不同容器配置,节省开发者重复且容易出错的输入,以避免自行开发解决方案的负担。
Compose将使我们免于自己维护用于服务编排的脚本,包括启动、连接、更新和停止容器。
在identidock目录下创建docker-compose.yml文件
[root@bogon identidock]# cat docker-compose.yml
identidock:
build: .
ports:
* "6000:6000"
environment:
ENV: DEV
volumes:
~ ./app:/app
解释:
- 第一行声明构建的容器名称;可定义多个容器;
- 容器的镜像通过当前目录(.)下的Dockerfile构建;每个容器的定义必须包含一个build或image关键字,image的值是用于启动容器的镜像的标签或ID;
- 声明对外开放的端口
- 设置容器的环境变量
- 配置数据卷
2.安装docker-compose
sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
docker-compose up
3.使用Compose的工作流程
up:启动所有在Compose文件中定义的容器,并且把她们的日志信息汇总一起。
build:重新建造有Dockerfile构建的镜像。需要更新镜像时使用。
ps:获取由Compose管理的容器的状态信息。
run:启动一个容器,并运行一个一次性的命令。被连接的容器会同时启动,除非使用--no-deps参数。
logs:汇总由Compose管理的容器的日志,并以彩色输出。
stop:停止容器,但不会删除。
rm:删除已停止的容器。使用-v来删除任何有Docker管理的数据卷。
工作流程:
(1)docker-compose up -d后台启动应用
(2)docker-compose logs和ps验证应用程序状态
(3)修改代码后,执行docker-compose build构建新景象
(4)docker-compose up -d取代运行中的镜像(Compose会保留原容器中所有旧的数据卷)
(5)强制停止Compose并重新创建所有容器,--force-recreate
(6)docker-compose stop停止应用程序
(7)docker-compose start或up重启相同的容器
(8)docker-compose rm彻底删除容器
Docker容器技术-在开发中引用Docker的更多相关文章
- 【转帖】一文看懂docker容器技术架构及其中的各个模块
一文看懂docker容器技术架构及其中的各个模块 原创 波波说运维 2019-09-29 00:01:00 https://www.toutiao.com/a6740234030798602763/ ...
- 开发自己的 chart - 每天5分钟玩转 Docker 容器技术(167)
Kubernetes 给我们提供了大量官方 chart,不过要部署微服务应用,还是需要开发自己的 chart,下面就来实践这个主题. 创建 chart 执行 helm create mychart 的 ...
- Docker Swarm 中最重要的概念- 每天5分钟玩转 Docker 容器技术(94)
从主机的层面来看,Docker Swarm 管理的是 Docker Host 集群.所以先来讨论一个重要的概念 - 集群化(Clustering). 服务器集群由一组网络上相互连接的服务器组成,它们一 ...
- 在 Scale Up 中使用 Health Check - 每天5分钟玩转 Docker 容器技术(145)
对于多副本应用,当执行 Scale Up 操作时,新副本会作为 backend 被添加到 Service 的负责均衡中,与已有副本一起处理客户的请求.考虑到应用启动通常都需要一个准备阶段,比如加载缓存 ...
- 在 Rolling Update 中使用 Health Check - 每天5分钟玩转 Docker 容器技术(146)
上一节讨论了 Health Check 在 Scale Up 中的应用,Health Check 另一个重要的应用场景是 Rolling Update.试想一下下面的情况: 现有一个正常运行的多副本应 ...
- Linux 运维工作中的经典应用ansible(批量管理)Docker容器技术(环境的快速搭建)
一 Ansible自动化运维工具 Python 在运维工作中的经典应用 ansible(批量管理操作) .安装ansible(需要bese epel 2种源) wget -O /etc/yum.rep ...
- 三文搞懂学会Docker容器技术(中)
接着上面一篇:三文搞懂学会Docker容器技术(上) 6,Docker容器 6.1 创建并启动容器 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] --na ...
- 微服务架构:基于微服务和Docker容器技术的PaaS云平台架构设计(微服务架构实施原理)
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 基于微服务架构和Docker容器技术的PaaS云平台建设目标是给我们的开发人员提供一套服务快速开发.部署.运维管理.持续开发持续集成的流程 ...
- 数据收集利器 cAdvisor - 每天5分钟玩转 Docker 容器技术(82)
cAdvisor 是 google 开发的容器监控工具,我们来看看 cAdvisor 有什么能耐. 在 host 中运行 cAdvisor 容器. docker run \ --volume=/:/r ...
随机推荐
- php 循环简写
<?php class a{ public function news($news){ $articles = array(); foreach ($news as $key => $va ...
- [已解决]window下Can't connect to MySQL server on 'localhost' (10061)与无法启动MYSQL服务”1067 进程意外终止”
查了一圈,发现都解决不了我的问题,查了 window 系统日志,提示缺少了某些文件,文件怎么丢的我也不知道,以下是解决办法. -- 我的 mysql 版本为 5.6.x 压缩包版本,我的 mysql ...
- Shader 优化笔记
如果shader中采了深度图,但是实际上相机没开深度图的话,会严重降帧. 做uv动画时应该 o.uv1.xy = v.uv * _Layer1_ST.xy + frac(_Layer1_ST.zw * ...
- Unity3D学习笔记——IDE工作视图
Unity3D中五个界面的使用: Project视图:存放游戏资源,比如贴图,音频,JS脚本等 Project中可创建的文件如下: Hierarchy视图:主要存放游戏场景中的对象,如摄像机,精灵,箱 ...
- linux 复制粘贴
如果想把文件内的第三行内容黏贴到第十五行: 1.进入你的文件,(处于命令模式,而不是编辑模式) 2.将你的光标移到你的第三行的开头(用方向键) 3,按下v,(你发现切换到可视模式了),按方向键,知道选 ...
- iOS Document Interaction 编程指南
本文转载至 http://www.2cto.com/kf/201306/219382.html iOS支持在你的app中用其他app预览和显示文档.iOS还支持文件关联,允许其他app通过你的程序打开 ...
- Xamarin.Forms学习之位图(二)
上篇文章分享了如何加载网络图片和PCL中的图片,所以今天继续分享关于如何加载平台的内嵌图片,在这之前说一下上篇文章开头的一个问题:为什么不能加载UWP项目,这是因为我升级了UWP的SDK,而Xamar ...
- 在使用NavigationController情况下的布局的Y轴的起始位置
在有的时候,当一个ViewController被push进一个NavigationController的时候,view上会有一个高度为64的NavigationBar(除非主动隐藏了Navigatio ...
- Ubuntu 16.04特性及使用基本方法
十招让Ubuntu 16.04用起来更得心应手 Ubuntu 16.04 LTS的这十项新功能,每个Ubuntu用户必须要知道! Ubuntu 16.04 LTS安装好需要设置的15件事
- 我的Android进阶之旅------>Android横竖屏切换总结
在默认情况下当屏幕从竖评变到横屏时会触发 onConfigurationChanged 事件 在默认情况下会重新加载画面并显示和横屏一样的画面,这样会有2个问题, * 布局问题,在竖屏 显示的布局 ...