docker的使用
一、简介
有时我们使用docker并不是为了纯净的环境,只是为了快速使用一个配置好的环境。这样,官方的最小环境反而不适合我们使用,所以我们需要一个基本能用的镜像,下面推荐:
本教程的目的,搭建一个适合的python环境,并使用vscode远程调试。
二、docker pull 拉取官方镜像
# 例子
#nginx
docker pull nginx
# Ubuntu18.04+ros-melodic
docker pull osrf/ros:melodic-desktop-full
# Ubuntu20.04+ros-noetic
docker pull osrf/ros:noetic-desktop-full
四、创建容器
简单的例子
docker run -itd -p 2200:22 --name chenjian nginx /bin/bash
#-itd参数解析
1、如果一个都不加,运行后容器直接结束
2、如果只有-it
表明开一个伪终端,并支持和容器交互。如果只加-t,终端内不能交互,只能观看,连ls都运行不了。
如果想退出后容器继续在后台运行,请加-d。
注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec
#总结
运行交互式容器
docker run -i -t nginx /bin/bash
启动容器(后台模式)
docker run -d nginx /bin/bash -c "while true; do echo hello world; sleep 1; done"
#上面的-c是bash里面的指令,-c 的意思是command,所以bash -c 后面应该跟一个command。
#用法:bash -c <cmd string>
docker run 命令常用参数
-d, --detach=false # 后台运行容器,并返回容器ID;
-i, --interactive=false # 以交互模式运行容器,通常与 -t 同时使用;
-t, --tty=false # 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-u, --user="" # 指定容器的用户
-a, --attach=[] # 登录容器(必须是以docker run -d启动的容器)
-w, --workdir="" # 指定容器的工作目录
-c, --cpu-shares=0 # 设置容器CPU权重,在CPU共享场景使用
-e, --env=[] # 指定环境变量,容器中可以使用该环境变量
-m, --memory="" # 指定容器的内存上限
-P, --publish-all=false # 指定容器暴露的端口
-p, --publish=[] # 指定容器暴露的端口
-h, --hostname="" # 指定容器的主机名
-v, --volume=[] # 给容器挂载存储卷,挂载到容器的某个目录
--volumes-from=[] # 给容器挂载其他容器上的卷,挂载到容器的某个目录
--cap-add=[] # 添加权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cap-drop=[] # 删除权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cidfile="" # 运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法
--cpuset="" # 设置容器可以使用哪些CPU,此参数可以用来容器独占CPU
--device=[] # 添加主机设备给容器,相当于设备直通
--dns=[] # 指定容器的dns服务器
--dns-search=[] # 指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件
--entrypoint="" # 覆盖image的入口点
--env-file=[] # 指定环境变量文件,文件格式为每行一个环境变量
--expose=[] # 指定容器暴露的端口,即修改镜像的暴露端口
--link=[] # 指定容器间的关联,使用其他容器的IP、env等信息
--lxc-conf=[] # 指定容器的配置文件,只有在指定--exec-driver=lxc时使用
--name="" # 指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字
--net="bridge" # 容器网络设置:
bridge # 使用docker daemon指定的网桥
host # 容器使用主机的网络
container:NAME_or_ID > # 使用其他容器的网路,共享IP和PORT等网络资源
none # 容器使用自己的网络(类似--net=bridge),但是不进行配置
--privileged=false # 指定容器是否为特权容器,特权容器拥有所有的capabilities
--restart="no" # 指定容器停止后的重启策略:
no # 容器退出时不重启
on-failure # 容器故障退出(返回值非零)时重启
always # 容器退出时总是重启
--rm=false # 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)
--sig-proxy=true # 设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理
五、ssh远程服务配置
#进入容器
docker exec -it chenjian1 /bin/bash
#更新包缓存。第一次进入容器,需要更新apt缓存,不然连基础软件包都查不到
apt update
#1.安装vim、net-tools
apt install vim
apt install net-tools
#2.安装ssh
sudo apt install ssh
#3.修改容器/etc/ssh/sshd_config
vim /etc/ssh/sshd_config
PermitRootLogin yes #允许root用户ssh登录
UsePAM no ##禁用PAM
#4.最后保存,重启
sudo /etc/init.d/ssh restart
(或sudo /etc/init.d/ssh start)
六、利用pycharm创建包含虚拟环境的工程,然后将工程通过scp拷贝到docker环境中即可运行
七、让容器启动时运行一些程序
三、Docker构建本地镜像(docker build)
有时,我们想自己定制一个镜像,而不是使用官方库中的镜像。此时就可以利用Dockerfile来创建镜像。
注意:Dockerfile放在单独一个空文件夹中,如果同级目录存在很多文件,构建会加载当前目录下所有文件,导致磁盘爆满。
docker build
docker build命令用于从Dockerfile构建镜像
典型用法
docker build -t ImageName:TagName dir
参数解释
-t 给镜像加一个Tag
ImageName 给镜像起的名称
TagName 给镜像的Tag名
Dir Dockerfile所在目录
例子
docker build -t hdk_location:v1.0 .
hdk_location 镜像名
v1.0 是tag标签
. 表示当前目录,即Dockerfile所在目录
查看构建的镜像
docker images
指令详解
Dockerfile 指令 | 说明 |
---|---|
FROM | 指定基础镜像,用于后续的指令构建。 |
MAINTAINER | 指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令) |
LABEL | 添加镜像的元数据,使用键值对的形式。 |
RUN | 在构建过程中在镜像中执行命令。 |
CMD | 指定容器创建时的默认命令。(可以被覆盖) |
ENTRYPOINT | 设置容器创建时的主要命令。(不可被覆盖) |
EXPOSE | 声明容器运行时监听的特定网络端口。 |
ENV | 在容器内部设置环境变量。 |
ADD | 将文件、目录或远程URL复制到镜像中。 |
COPY | 将文件或目录复制到镜像中。 |
VOLUME | 为容器创建挂载点或声明卷。 |
WORKDIR | 设置后续指令的工作目录。 |
USER | 指定后续指令的用户上下文。 |
ARG | 定义在构建过程中传递给构建器的变量,可使用 "docker build" 命令设置。 |
ONBUILD | 当该镜像被用作另一个构建过程的基础时,添加触发器。 |
STOPSIGNAL | 设置发送给容器以退出的系统调用信号。 |
HEALTHCHECK | 定义周期性检查容器健康状态的命令。 |
SHELL | 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。 |
CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
- CMD 在docker run 时运行。
- RUN 是在 docker build。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式:
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。
ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。
总结
Dockerfile中run、cmd和entrypoint都能够用于执行命令,下面是三者的主要用途:
run命令执行命令并创建新的镜像层,通常用于安装软件包
cmd命令设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换
entrypoint配置容器启动时的执行命令,不会被忽略,一定会被执行,即使运行 docker run时指定了其他命令。
四、docker清理
当使用一段时间后,docker占用的空间会很大
查看docker占用
docker system df
一般来说是一些无用的本地卷占用
docker volume prune
进行数据卷的清理【那些没有被任何容器使用的本地volume】
五、设置代理
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=127.0.0.1:7890"
Environment="HTTPS_PROXY=127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1"
报错管理
1、当有一天docker pull 突然出现以下错误,不管换源还是加代理都不行的时候,考虑时候是DNS出错了
Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshaketimeout
vim /etc/resolv.conf
改DNS服务器
nameserver 119.29.29.29 # 腾讯