Ubuntu/linux c开发(9)docker部署+容器制作
c++ 执行文件 docker部署
1、docker部署
1.1 查询当前系统是否有docker
> whereis docker
docker: /etc/docker # 存在
1.2 卸载docker
dpkg -l | grep docker
sudo apt remove -y --purge xxx #上面的输出
1.3 安装docker
1.3.1 安装指令
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
1.3.2 错误及解决办法
错误:
E: 软件包 docker-ce 没有可安装候选
E: 无法定位软件包 docker-ce-cli
E: 无法定位软件包 containerd.io
E: 无法按照 glob ‘containerd.io’ 找到任何软件包
E: 无法按照正则表达式 containerd.io 找到任何软件包
解决办法
把仓库设置成阿里云仓库。
sudo add-apt-repository \
"deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu/ $(lsb_release -cs) \
stable"
如果报错:sudo: add-apt-repository:找不到命令 解决方式
执行:
sudo apt-get install python-software-properties
sudo apt install software-properties-common
2、容器制作
在/home目录下创建docker目录,docker目录下的列表:(windows下展示)
App1和App2是自己c++生成的执行文件;Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明;lib是需要的so库文件;pic是宿主机的存储图片的位置,之前docker容器内生成图片文件数据文章有说明,剩下的sh文件是docker镜像生成和销毁的执行文件。
2.1 Dockerfile
Dockerfile展开说要说很久,目前就展示一些常用的:
2.1 .1、FROM
定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
2.1 .2、RUN
用于执行后面跟着的命令行命令。有以下俩种格式:
shell 格式:
RUN <命令行命令>
<命令行命令> 等同于,在终端操作的 shell 命令。
exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
例如:
RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
2.1 .3、MAINTAINER
镜像维护者姓名或邮箱地址
2.1 .4、ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
2.1 .5、ADD
ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
2.1 .6、CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:CMD 在docker run 时运行;RUN 是在 docker build。
2.1 .7、WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
2.1.8 例子
FROM ubuntu
MAINTAINER xxx
# 设置变量
ENV WORKDIR /home/docker/apps
# 设置时区
#ENV TIME_ZONE=Asia/Shanghai
#RUN cp /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime && echo ${TIME_ZONE} > /etc/timezone
# 添加依赖
ADD lib/* /usr/lib/
#ADD lib/* /usr/lib64/
# 设置工作目录
RUN mkdir -p ${WORKDIR}
WORKDIR ${WORKDIR}
# 启动命令
CMD ${WORKDIR}/start.sh
2.2 sh文件
2.2.1 docker-run.sh
#!/bin/sh
HOME=/home/docker
restart=unless-stopped
network=host
# stop apps
# 根据通道增减
docker stop App1&& docker rm App1
docker stop App2 && docker rm App2
# build gatherapp image
docker rmi gatherapp:1.0
docker load < ubuntu.tar
docker build -t gatherapp:1.0 ${HOME} && \
# run apps
# 创建容器
docker run -d --name App1\
-v /etc/localtime:/etc/localtime:ro \
-p 5666:5666\
-v ${HOME}/pic:${HOME}/pic \
-v ${HOME}/App1:${HOME}/apps --restart=${restart} \
gatherapp:1.0 && \
docker run -d --name App2\
-v /etc/localtime:/etc/localtime:ro \
-p 8866:8866\
-v ${HOME}/App2:${HOME}/apps --restart=${restart} \
gatherapp:1.0 && \
在挂载目录为多级情况下需要注意:
可能会出现权限不足的提示。我们需要添加参数–privileged=true来解决挂载的目录没有权限的问题。
例:
docker run -d --name App2\
--privileged=true\
-v /etc/localtime:/etc/localtime:ro \
-p 8866:8866\
-v ${HOME}/App2:${HOME}/apps --restart=${restart} \
gatherapp:1.0 && \
2.2.2 docker-restart.sh
#! /bin/bash
docker restart App1
docker restart App2
2.2.3 docker-stop.sh
#! /bin/bash
docker stop App1
docker stop App2
2.3 App执行文件
app是c++编译生成的执行文件,start.sh内容如下:
#!/bin/sh
./app.
就是单纯的执行,目的是方便Dockerfile创建镜像时,不需要编写太多的执行命令。这样一个启动命令就OK。
#Dockerfile 启动命令
CMD ${WORKDIR}/start.sh
2.4 pic和lib
这两个文件夹没有太多需要注意的,lib文件夹下存你执行程序需要的so动态库(看你自己调用你调用静态库就保存.a文件)。它主要的目的就是提供依赖环境。在2.1.8 例子中ADD已经将内容拷贝到创建的镜像了。而pic的注意上面也提过了,在2.2.1 docker-run.sh 中,-v ${HOME}/App1:${HOME}/apps --restart=${restart}
已经将镜像和宿主机进行了绑定这样就可以在本地落图了。
2.5 启动docker
进入/home/docker目录,执行
./docker-run.sh
2.5 停止/重启docker
停止
./docker-stop.sh
重启
./docker-restart.sh
3、docker容器状态
命令:
docker stats
docker stats 命令用来显示容器使用的系统资源。
展示内容:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
802ce16fe53c xxxxServer 0.01% 6.203MiB / 31.3GiB 0.02% 19.4MB / 8.97MB 0B / 0B 23
默认情况下,stats 命令会每隔 1 秒钟刷新一次输出的内容直到你按下 ctrl + c。下面是输出的主要内容:
字段 | 说明 |
---|---|
[CONTAINER] | 以短格式显示容器的 ID |
[CPU %] | CPU 的使用情况。 |
[MEM USAGE / LIMIT] | 当前使用的内存和最大可以使用的内存。 |
[MEM %] | 以百分比的形式显示内存使用情况。 |
[NET I/O] | 网络 I/O 数据。 |
[BLOCK I/O] | 磁盘 I/O 数据。 |
[PIDS] | PID 号。 |
[MEM USAGE / LIMIT]
需要注意下,他展示的是容器使用的内存,包括你程序生成的文件大小都包含在内。如果你的程序没有生成文件,使用他来判断内存泄露也是可以的(正常日志输出也是有计算大小),所以,判断内存泄露正常还是使用top -p pid
和Valgrind
。
4、注意事项
在启动docker后,可以调用命令查看镜像状态:
//当前创建运行中的镜像
docker ps
//所有创建的镜像
docker ps -a
正常运行:
如果镜像运行失败
查看docker日志:
docker logs --tail=1000 容器名称 (查看容器前多少行的日志)
进入容器
docker exec -it 容器名 /bin/bash
退出当前容器:
exit
# -it 进入容器退出(前台容器自动结束【后台停止运行】)
1.在我们使用 -it 参数直接进入该容器的时候,使用exit退出的时候这个容器就会自动结束。
- 此时后台就没有该运行中的容器。
1、观察他的创建和状态时间,如果对应不上那么应该是被重新拉起过;
2、如果有监听端口端口是否一直占用。
如果运行失败,正常是两个原因:
1、执行程序(sh、.文件、.out文件)权限是否有执行权限 -> 赋执行权限
2、自己写的app是否依赖库齐全。 -> 直接运行执行文件,补充依赖
检查库版本:使用ldd命令检查你的程序依赖哪些库以及它们的版本。这可以帮助你确定是否安装了正确的库版本。
ldd your_program
更多推荐
所有评论(0)