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 pidValgrind

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
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐