讲解
DockerFile的指令
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的:姓名+邮箱 maintainer
RUN # 镜像构建的时候需要运行的命令
ADD # copy内容到容器(压缩包,自动解压)
WORKDIR # 镜像的工作目录 workdir
VOLUME # 挂载的目录 volume
EXPOSE # 暴露端口配置 expose
CMD # 指定容器启动的时候需要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定容器启动的时候需要运行的命令,可以追加指令
ONBUILD # 当构建一个被继承 DckerFile 这个时候就会运行 ONBUILD 的指令 触发指令
COPY # 类似ADD 将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量
USER # 设置启动容器的用户
ARG # 设置变量命令 定义创建镜像过程中使用的环境变量
基本语法:ARG <name> [=<default value>]
#在执行docker build命令时, 可以通过 --build-arg <参数名>=<值>来覆盖Dockerfile中定义的变量值,Dockerfile 文件中 ${变量名}来取值。
ONBUILD # 对当前镜像的子镜像生效 # ONBUILD RUN ls -al
STOPSIGNAL # 当容器停止时给系统发送什么样的指令
HEALTHCHECK # 容器健康状况检查命令
LABEL # 添加元数据标签信息到为生成的镜像
基本语法:LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL是键值对。如果LABEL值中包含空格,请使用引号或反斜杠包裹。
一个镜像可以有多个标签。可以指定多行标签,也可以在一行上指定多个标签。
CMD 和 ENTRYPOINT 的区别
CMD # 指定容器启动的时候需要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定容器启动的时候需要运行的命令,可以追加指令 entrypoint
相同点:
只能写一条,如果写了多条,那么只有最后一条生效
容器启动时才运行,运行时机相同
不同点:
ENTRYPOINT不会被运行的command覆盖,而CMD则会被覆盖
#如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会作为ENTRYPOINT的参数
#如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD是一个完整的指令,那么它们两个会互相覆盖,谁在最后谁生效
COPY和ADD的区别
COPY - - - 把宿主机的文件复制到镜像中
COPY src desc
其中src表示宿主机上的路径(支持通配符,如*和?;通常使用相对路径);
desc表示目标镜像中的路径(通常使用绝对路径,如果不存在会被自动创建,包括父目录)。
Note:如果src是目录,则其内部文件或子目录会被递归复制,但src目录自身不会被复制。
ADD - - - 与COPY命令类似
ADD src desc
与COPY不同的是,ADD可以访问url路径,会访问网络进行下载,档到本地后打包到镜像。
此外,如果src是压缩包的话,会自动进行解压;但通过url获取的tar文件不会被展开。
RUN&&CMD
不要把RUN和CMD搞混了。
#RUN是构件容器时就运行的命令以及提交运行结果
#CMD是容器启动时执行的命令,在构件时并不运行,构件时紧紧指定了这个命令到底是个什么样子
Python 环境中的实验
实验 在 python 环境中 build 一个 web app
- Dockerfile (有 python 3.6.6 版本的 image/ 无需单独下载安装 python 环境)
vim Dockerfile
FROM python:3.6.6
LABEL maintainer="xu1102<[email protected]>"
RUN pip install flask
创建一个 python 的简单的源代码文件 app.py
vim app.py
om flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "hello docker"
if __name__ == '__main__':
app.run()
再将 app.py 添加到 image 里面
FROM python:3.6.6
LABEL "maintainer=xu1102<[email protected]>"
RUN pip install flask
COPY app.py /app/
WORKDIR /app
EXPOSE 5000
CMD ["python", "app.py"]
使用–no-index --find-links选项进行离线安装
将pip_packages文件夹,和requirements_offline.txt 放到需要部署的环境当中。执行关键一步:
pip install --no-index --find-links=. -r …/project/requirements_offline.txt
其中 --no-index 代表忽视pip 忽视默认的依赖包索引。–find-links= 代表从你指定的目录寻下找离线包
本列中:指定从当前目录下(也就是pip_packages下)寻找离线包,安装…/project/中requirements_offline.txt所需依赖。
pip使用指南——r参数
有的时候,你想用pip安一个库,可是结果它一下子给你安了很多库,你也不知道它们都是用来干啥的,但是它们都是你本来想要的那个库的关联库。
这里利用pip的r参数,配合自定义的requirements file文件,可以更好地管理第三方库,随时安装与卸载。
只要把所涉及到的所有库的名称都列出来
使用时,只需要在命令中追加参数r以及文件所在的目录就好了,一般格式为:
python -m pip install -r <file>
基于Docker-compose编排部署sentiment-analyzer情感分析系统
基础准备
1.Kubernetes集群部署完成
2.将压缩包Sentiment-Analyzer.tar.gz上传到master节点/root目录下并解压
案例实施
1.1构建sa-logic镜像
1)编写Dockerfile
编写yum文件
[root@master ~]# cd sentiment-analyzer/
[root@master sentiment-analyzer]# vi local.repo
[sa]
name=sa
baseurl=file:///opt/sa-repo
gpgcheck=0
enabled=1
编写Dockerfile
[root@master sentiment-analyzer]# vi Dockerfile-logic
FROM centos:centos7.5.1804 # 基础镜像,一切从这里开始构建
MAINTAINER Guo # 镜像是谁写的:姓名+邮箱
WORKDIR /root # 镜像的工作目录
RUN rm -rf /etc/yum.repos.d/*
COPY local.repo /etc/yum.repos.d/local.repo
COPY sa-repo /opt/sa-repo
COPY sa-logic/requirements.txt /root/requirements.txt
COPY sa-logic/app.py /root/app.py
ADD sa-logic/python-packages.tar.gz /root #添加内容
RUN yum -y install python3
RUN pip3 install --find-links=/root/python-packages -r /root/requirements.txt
#离线安装软件包 指定这个目录中安装软件包,而不从 pypi 上安装
#-r 把所涉及到的所有库的名称都列出来 不然它一下子给你安了很多依赖库
EXPOSE 5000 # 暴露端口配置
CMD ["python3", "app.py"] # 指定容器启动的时候需要运行的命令,只有最后一个会生效,可被替代
(2)构建镜像
[root@master sentiment-analyzer]# docker build -t sa-logic:v1.0 -f Dockerfile-logic .
Sending build context to Docker daemon 348.2MB
Step 1/13 : FROM centos:centos7.5.1804
---> cf49811e3cdb
Step 2/13 : MAINTAINER Guo
---> Using cache
---> 02855371e6e9
Step 3/13 : WORKDIR /root
---> Using cache
---> 452ef41a356d
Step 4/13 : RUN rm -rf /etc/yum.repos.d/*
---> Using cache
---> 39c82cf6edf1
Step 5/13 : COPY local.repo /etc/yum.repos.d/local.repo
---> Using cache
---> 10c3cd5c066c
Step 6/13 : COPY sa-repo /opt/sa-repo
---> Using cache
---> b6b326099da7
Step 7/13 : COPY sa-logic/requirements.txt /root/requirements.txt
---> Using cache
---> 75e961748d66
Step 8/13 : COPY sa-logic/app.py /root/app.py
---> Using cache
---> ac5de077a8d0
Step 9/13 : ADD sa-logic/python-packages.tar.gz /root
---> Using cache
---> c9c1f014253d
Step 10/13 : RUN yum -y install python3
---> Using cache
---> 5bb21dca931b
Step 11/13 : RUN pip3 install --find-links=/root/python-packages -r /root/requirements.txt
---> Using cache
---> 396b732716bb
Step 12/13 : EXPOSE 5000
---> Using cache
---> 8c08e0279108
Step 13/13 : CMD ["python3", "app.py"]
---> Using cache
---> 4af11144b511
Successfully built 4af11144b511
Successfully tagged sa-logic:v1.0
查看镜像列表:
[root@master sentiment-analyzer]# docker images | grep sa-logic
REPOSITORY TAG IMAGE ID CREATED SIZE
sa-logic v1.0 4af11144b511 About a minute ago 629MB
1.2构建sa-webapp镜像
编写Dockerfile
[root@master sentiment-analyzer]# vi Dockerfile-webapp
FROM centos:centos7.5.1804
MAINTAINER Guo
WORKDIR /root
RUN rm -rf /etc/yum.repos.d/*
COPY local.repo /etc/yum.repos.d/local.repo
COPY sa-repo /opt/sa-repo
ADD sa-webapp/go-packages.tar.gz /root
RUN yum -y install golang
RUN go build -o webapp .
EXPOSE 8080
CMD ["/root/webapp"]
(2)构建镜像
[root@master sentiment-analyzer]# docker build -t sa-webapp:v1.0 -f Dockerfile-webapp .
Sending build context to Docker daemon 348.2MB
Step 1/11 : FROM centos:centos7.5.1804
---> cf49811e3cdb
Step 2/11 : MAINTAINER Guo
---> Using cache
---> 02855371e6e9
Step 3/11 : WORKDIR /root
---> Using cache
---> 452ef41a356d
Step 4/11 : RUN rm -rf /etc/yum.repos.d/*
---> Using cache
---> 39c82cf6edf1
Step 5/11 : COPY local.repo /etc/yum.repos.d/local.repo
---> Using cache
---> 10c3cd5c066c
Step 6/11 : COPY sa-repo /opt/sa-repo
---> Using cache
---> b6b326099da7
Step 7/11 : ADD sa-webapp/go-packages.tar.gz /root
---> Using cache
---> 5a8c4ad14414
Step 8/11 : RUN yum -y install golang
---> Using cache
---> 1fe36d2e2728
Step 9/11 : RUN go build -o webapp .
---> Using cache
---> 3fb843836547
Step 10/11 : EXPOSE 8080
---> Using cache
---> 97dda96366e0
Step 11/11 : CMD ["/root/webapp"]
---> Using cache
---> f9d451bf0cfb
Successfully built f9d451bf0cfb
Successfully tagged sa-webapp:v1.0
查看镜像列表:
[root@master sentiment-analyzer]# docker images | grep sa-webapp
REPOSITORY TAG IMAGE ID CREATED SIZE
sa-webapp v1.0 f9d451bf0cfb About a minute ago 1.12GB
1.3构建sa-frontend镜像
(1)编写Dockerfile
[root@master sentiment-analyzer]# vi Dockerfile-frontend
FROM centos:centos7.5.1804
MAINTAINER Guo
WORKDIR /root
RUN rm -rf /etc/yum.repos.d/*
COPY local.repo /etc/yum.repos.d/local.repo
COPY sa-repo /opt/sa-repo
ADD sa-frontend/sa-frontend.tar.gz /root
## 填写主机IP地址,用于后续web访问后端
ENV VUE_APP_API_HOST=http://192.168.0.45:9002
RUN yum -y install nodejs nginx
RUN npm run build && rm -rf /usr/share/nginx/html/* && \
cp -rvf dist/* /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"] #
#最后加;是固定的,nginx官方特意在docker里设置的这个属性,格式也是他们来定的
#docker 容器默认会把容器内部第一个进程,也就是pid=1的程序作为docker容器是否正在运行的依据,如果docker 容器pid挂了,那么docker容器便会直接退出。
#nginx默认是以后台模式启动的,Docker未执行自定义的CMD之前,nginx的pid是1,执行到CMD之后,nginx就在后台运行,bash或sh脚本的pid变成了1。所以一旦执行完自定义CMD,nginx容器也就退出了。为了保持nginx的容器不退出,应该关闭nginx后台运行
#nginx -g directives : 设置 全局配置指令
CMD service nginx start
该命令会被包装为:
CMD [ "sh", "-c", "service nginx start"]
#启动nginx时,主进程其实是sh,而容器是因为sh这个主进程产生的,当该条命令执行完毕之后,sh作为主进程会退出,容器自然也会退出,因此导致nginx启动不了。所以需要使用
CMD ["nginx", "-g", "daemon off;"] 启动
(2)构建镜像
[root@master sentiment-analyzer]# docker build -t sa-frontend:v1.0 -f Dockerfile-frontend .
Sending build context to Docker daemon 348.2MB
Step 1/12 : FROM centos:centos7.5.1804
---> cf49811e3cdb
Step 2/12 : MAINTAINER Guo
---> Using cache
---> 02855371e6e9
Step 3/12 : WORKDIR /root
---> Using cache
---> 452ef41a356d
Step 4/12 : RUN rm -rf /etc/yum.repos.d/*
---> Using cache
---> 39c82cf6edf1
Step 5/12 : COPY local.repo /etc/yum.repos.d/local.repo
---> Using cache
---> 10c3cd5c066c
Step 6/12 : COPY sa-repo /opt/sa-repo
---> Using cache
---> b6b326099da7
Step 7/12 : ADD sa-frontend/sa-frontend.tar.gz /root
---> Using cache
---> 0856dadfabbf
Step 8/12 : ENV VUE_APP_API_HOST=http://192.168.0.45:9002
---> Using cache
---> d6f60d456724
Step 9/12 : RUN yum -y install nodejs nginx
---> Using cache
---> 63101aac3320
Step 10/12 : RUN npm run build && rm -rf /usr/share/nginx/html/* && cp -rvf dist/* /usr/share/nginx/html
---> Using cache
---> 9ffcbc426e87
Step 11/12 : EXPOSE 80
---> Using cache
---> 26b819ea11d0
Step 12/12 : CMD ["nginx", "-g", "daemon off;"]
---> Using cache
---> 447e3d98b3ab
Successfully built 447e3d98b3ab
Successfully tagged sa-frontend:v1.0
查看镜像列表:
[root@master sentiment-analyzer]#docker images | grep sa-frontend
REPOSITORY TAG IMAGE ID CREATED SIZE
sa-frontend v1.0 447e3d98b3ab 2 minutes ago 740MB
1.4编排部署sentiment-analyzer
(1)编写YAML文件
编写docker-compose.yaml文件:
[root@master sentiment-analyzer]# vi docker-compose.yaml
version: "3"
services:
sa-logic: # 第二级标签是 web ,服务名称
container_name: sa-logic #容器的命名
image: sa-logic:v1.0 # 如果镜像在本地不存在,Compose 将会尝试拉取这个镜像
ports:
- 9001:5000
sa-webapp:
container_name: sa-webapp
image: sa-webapp:v1.0
depends_on: #解决了容器的依赖
- sa-logic
ports:
- 9002:8080
environment:
- API_HOST=http://sa-logic:5000 #对接登录接口的 应学习接口编程
sa-frontend:
container_name: sa-frontend
image: sa-frontend:v1.0
depends_on:
- sa-webapp
ports:
- 9003:80
## build
服务除了可以基于指定的镜像,还可以基于一份 Dockerfile,在使用 up 启动之时执行构建任务,这个构建标签就是 build,它可以指定 Dockerfile 所在文件夹的路径。Compose 将会利用它自动构建这个镜像,然后使用这个镜像启动服务容器。
build: /path/to/build/dir
也可以是相对路径,只要上下文确定就可以读取到 Dockerfile
build: ./dir
设定上下文根目录,然后以该目录为准指定 Dockerfile
build:
context: ../
dockerfile: path/of/Dockerfile
如果你同时指定了 image 和 build 两个标签,那么 Compose 会构建镜像并且把镜像命名为 image 后面的那个名字
build: ./dir
image: webapp:tag
#depends_on
在使用 Compose 时,最大的好处就是少打启动命令,但是一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。
例如在没启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况我们需要加入一个标签,就是 depends_on,这个标签解决了容器的依赖、启动先后的问题。
例如下面容器会先启动 redis 和 db 两个服务,最后才启动 web 服务
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
注意的是,默认情况下使用 docker-compose up web 这样的方式启动 web 服务时,也会启动 redis 和 db 两个服务,因为在配置文件中定义了依赖关系
#env_file 与 environment
#env_file
在 docker-compose.yml 中可以定义一个专门存放变量的文件
如果有变量名称与 environment 指令冲突,则以后者为准
#environment
与上面的 env_file 标签完全不同,反而和 arg 有几分类似,这个标签的作用是设置镜像变量,它可以保存变量到镜像里面,也就是说启动的容器也会包含这些变量设置,这是与 arg 最大的不同。
一般 arg 标签的变量仅用在构建过程中。而 environment 和 Dockerfile 中的 ENV 指令一样会把变量一直保存在镜像、容器中,类似 docker run -e 的效果。
#expose 与 ports
#expose
与Dockerfile中的EXPOSE指令一样,指定暴露的端口,但只是作为一种参考,实际上docker-compose.yml的端口映射还是要用ports这样的标签
#ports
映射端口
使用HOST:CONTAINER格式或者只是指定容器的端口,宿主机会随机映射端口
docker-compose.yml 与 k8s
#docker-compose.yml
是单机管理,编排容器,可以同时管理多个 container ,将多个相关的容器一次性启动,比如运行一个jar需要依赖jdk、mysql、mq、redis等,这些容器只需要 docker-composer up 就可以全部启动,不需要一个个单独启动。
#k8s
多节点管理Docker,集群部署高可用应用
启动服务:
[root@master sentiment-analyzer]# docker-compose up -d
Creating network "sentiment-analyzer_default" with the default driver
Creating sa-logic ... done
Creating sa-webapp ... done
Creating sa-frontend ... done
[root@master sentiment-analyzer]# docker-compose ps
Name Command State Ports
-------------------------------------------------------------------
sa-frontend nginx -g daemon off; Up 0.0.0.0:9003->80/tcp
sa-logic python3 app.py Up 0.0.0.0:9001->5000/tcp
sa-webapp /root/webapp Up 0.0.0.0:9002->8080/tcp
(2)访问服务
在浏览器访问服务:http://192.168.0.45:9003/
随意输入一句话进行情感分析: