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 # 腾讯

posted @ 2021-12-07 20:53  chenjian688  阅读(87)  评论(0编辑  收藏  举报