代码编织梦想

Docker简介

Docker 镜像(image)

镜像是一个可执行的包,它包含了所有用来执行某个软件所需要的内容,包括代码,运行时,库,环境变量,还有配置文件。

Docker容器(container)

容器是镜像运行时的实例–镜像执行时,在内存中变成的样子。容器可以原生地运行在Linux中,它和其余的容器共享本地Linux主机的内核。docker ps,查看正在运行的容器;docker stop,中断运行的容器。每个容器都分别独立在进程中运行,占用的内存不超过任何其他可执行文件。

虚拟机VS容器

在这里插入图片描述
传统的虚拟化技术,比如 VMWare, KVM, Xen,目标是创建完整的虚拟机。为了运行应用,除了部署应用本身及其依赖(通常几十 MB),还得安装整个操作系统(几十 GB)。而对于容器来说,所有的容器共享同一个 Host OS,这使得容器在体积上要比虚拟机小很多。另外,启动容器不需要启动整个操作系统,所以容器部署和启动速度更快,开销更小,也更容易迁移。

Docker仓库

Docker仓库用来保存镜像。Docker仓库分为公有仓库和私有仓库。
公有的仓库有Docker Hub等。Docker Hub(https://hub.docker.com/) 是 Docker 为公众提供的托管 Registry,上面有很多现成的 image,为 Docker 用户提供了极大的便利。http://Quay.io(https://quay.io/)是另一个公共托管 Registry,提供与 Docker Hub 类似的服务。
出于对速度或安全的考虑,用户也可以创建自己的私有 Registry。后面我们会学习如何搭建私有 Registry。

Docker安装

根据官网直接下载对应的Docker版本。https://docs.docker.com/install/

测试Docker

运行docker --version查看docker的版本

docker --version
Docker version 18.09.2, build 6247962

运行docker info可以查看更多关于docker安装的细节。

docker info

使用Dockerfile定义容器

准备Dockerfile文件

在新创建的目录下,创建Dockerfile文件。Dockerfile文件定义了在容器环境中进行什么操作,比如对网络接口资源的访问,比如对磁盘驱动的访问。后续,可以根据Dockerfile文件,创建新的镜像

# 表明将官方 Python 运行时用作父镜像。后续可以根据自己已有的镜像作为父镜像构建
FROM python:2.7-slim

# 表明将工作目录设置为 /app。为后续的RUN,CMD等操作指令配置工作目录,可以使用多个WORKDIR指令。
WORKDIR /app

# 将当前目录内容复制到位于 /app 中的容器中。容器的指定路径必须是绝对路径,如果不存在会自动创建对应目录。
ADD . /app

# 安装 requirements.txt 中指定的任何所需软件包
RUN pip install -r requirements.txt

# 表示本地端口 80 可供此容器外的环境使用。需要在docker run的时候使用-p或者-P选项生效
EXPOSE 80

# 定义环境变量
ENV NAME World  # 等同于NAME=“World”

# 在容器启动时运行 app.py
CMD ["python", "app.py"]

上述Dockerfile文件表示,会将当前目录内容,添加到/app中的容器。当前目录中存在requirements.txt文件和app.py文件同时需要根据自己的需求创建。下面表明同一目录下的文件情况

$ ls
Dockerfile		app.py			requirements.txt

构建

通过docker build 创建Docker镜像。-t表示镜像标签(tag)。注意后面有个.,表明1以当前文件夹下的Dockerfile文件进行构建

docker build -t friendlyhello .

除了上面介绍的通过Dockerfile构建镜像之外,还有一种构建办法。就是使用docker commit命令,通过容器构建镜像。docker commit创建镜像有三个过程,先运行容器,再对容器内容进行修改,最后commit将容器保存为新的镜像。

Usage:	docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Create a new image from a container's changes

Options:
  -a, --author string    Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
  -c, --change list      Apply Dockerfile instruction to the created image
  -m, --message string   Commit message
  -p, --pause            Pause container during commit (default true)

镜像的共享

登录镜像
docker login
pull镜像

docker pull默认从官方仓库获取,也可从似有仓库获取,需要指定位置。例如从myregistry.local仓库的5000端口获取test-image镜像。

docker pull myregistry.local:5000/testing/test-image

获取ubuntu官方镜像

docker pull ubuntu
标记镜像

将本地镜像(local image)与镜像仓库(registry)中关联起来的标记是:username/repository:tag
tag实际上是可选的,但是一般推荐写上。例如:

docker tag <image> username/repository:tag
docker tag friendlyhello gordon/get-started:part2

push(上传)镜像

上传已经标记好的镜像到仓库中。

docker push username/repository:tag

创建并运行容器

docker run运行容器,其中参数i表示交互模式。t表示分配一个伪tty。

docker run -it <image id或者image name>
docker run -i -t ubuntu:14.04

docker run运行容器的时候,最好指定一下–shm-size,单位是字节,因为默认是docker容器中默认是64M,很多软件无法正常工作,可以设置为–shm-size=59g。这个/dev/shm是linux下一个非常有用的目录,这个目录(共享内存目录)在内存里而不是硬盘上。

swap 和shm的区别

swap(交换内存)是一个文件,是使用硬盘空间的一部分作为物理内存来扩展RAM空间的,虽然是物理硬盘的一部分,但是仍然属于RAM,并且属于易失性存储,重启机器会使数据丢失;空间大小在一般情况下,swap的空间大小设置为物理内存的两倍大小;docker中的swap对应于物理机器linux系统中的swap

shm(共享内存)在机器上挂载名可以是dev/shm,也可以是tmpfs;是将虚拟内存的一部分挂载为临时文件系统,用于应用程序的加速,原理是允许其中的数据被不同的应用程序访问;在tmpfs中创建的文件很自然地也就创建在了虚拟内存中,因此其存储性质同swap,属于易失性存储;在docker中使用–shm-size命令挂载的分区是/dev/shm,可以在docker的命令行中使用df -h命令查看;同时也能看到本机的物理机器上的tmpfs分区;

区别总结

  • tmpfs使用内存空间而swap使用物理存储空间
  • swap有经验意义上推荐的大小,而tmpfs没有;tmpfs的大小与所运行系统的目的有关
  • tmpfs可以使当前运行系统中的应用程序运行的更快,而swap是缓解系统物理内存压力的
  • wap空间满了表明系统正在高负荷运转,会造成性能下降甚至死机;而tmpfs满了以后并不一定有上面的情况
  • tmpfs是作为“增强型”功能出现的,而swap是必须有的功能

为了避免踩坑,还需要看情况设置ulimit参数,更改docker容器资源限制。
详细参考官网docker run的参数:https://docs.docker.com/engine/reference/commandline/run/#set-ulimits-in-container—ulimit
以及ulimit的使用https://www.ibm.com/developerworks/cn/linux/l-cn-ulimit/index.html
一般加上 --name,指定容器的名称。
踩坑: 默认启动的容器磁盘大小只有10G,随着容器变大,就会出现no space left on device的错误。可以设置为:–storage-opt size=100G
还有个常用选项:–rm,如果只是在开发调试过程中短期运行,其用户数据并无保留的必要,因而可以在容器启动时设置–rm选项,这样在容器退出时就能够自动清理容器内部的文件系统。automatically remove the container when it exits. 不支持docker run -d 启动的容器。

最终我在服务器上运行命令如下:

docker run -it --shm-size=59g --ulimit memlock=-1 --ulimit stack=67108864 --storage-opt size=100G --name=‘xinming’ imageID

常用命令

docker images

列出当前系统镜像

docker rmi

删除一个或者多个镜像

Usage:	docker rmi [OPTIONS] IMAGE [IMAGE...]

Remove one or more images

Options:
  -f, --force      Force removal of the image
      --no-prune   Do not delete untagged parents
docker info
Server Version: 1.12.6         # 服务器版本:1.12.6
Storage Driver: devicemapper    # 存储驱动程序:devicemapper
Pool Name: docker-8:3-2097465-pool    # 池名称:docker-8:3-2097465-pool
Pool Blocksize: 65.54 kB      # Pool Blocksize:65.54 kB
Base Device Size: 107.4 GB    # 基本设备大小:107.4 GB
Backing Filesystem: ext4      # 支持文件系统:ext4
Data file: /dev/loop0      # 数据文件:/ dev / loop0
Metadata file: /dev/loop1    # 元数据文件:/ dev / loop1
Data Space Used: 5.352 GB    # 使用的数据空间:5.352 GB
Data Space Total: 107.4 GB    # 数据空间总计:107.4 GB
Data Space Available: 10.04 GB    # 可用数据空间:10.04 GB
Metadata Space Used: 7.229 MB    # 使用的元数据空间:7.229 MB
Metadata Space Total: 2.147 GB    # 元数据空间总计:2.147 GB
Metadata Space Available: 2.14 GB    # 可用元数据空间:2.14 GB
Thin Pool Minimum Free Space: 10.74 GB    # 精简池最小可用空间:10.74 GB
Udev Sync Supported: true      # Udev Sync支持:true
Deferred Removal Enabled: true      # 延迟删除已启用:true
Deferred Deletion Enabled: true      # 延迟删除已启用:true
Deferred Deleted Device Count: 0      # 延迟删除的设备数:0
Data loop file: /var/lib/docker/devicemapper/devicemapper/data    # 数据循环文件:/ var / lib / docker / devicemapper / devicemapper / data
WARNING: Usage of loopback devices is strongly discouraged for production use. Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.    # 警告:强烈建议不要使用环回设备进行生产。使用`--storage-opt dm.thinpooldev`指定自定义块存储设备。
Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata    # 元数据循环文件:/ var / lib / docker / devicemapper / devicemapper / metadata
Library Version: 1.02.107-RHEL7 (2015-10-14)    版本:1.02.107-RHEL7(2015-10-14)
Logging Driver: journald    # 日志驱动程序:journald
Cgroup Driver: systemd    # Cgroup驱动程序:systemd
Plugins:      # 插件:
Volume: local    # 存储卷:本地
Network: bridge host null overlay    # 网络:桥接主机空覆盖
Swarm: inactive    # Swarm:不活跃
Runtimes: docker-runc runc    # 运行时:docker-runc runc
Default Runtime: docker-runc    # 默认运行时:docker-runc
Security Options: seccomp    # 安全选项:seccomp
Kernel Version: 3.10.0-327.el7.x86_64    # 内核版本:3.10.0-327.el7.x86_64
Operating System: CentOS Linux 7 (Core)    # 操作系统:CentOS Linux 7(核心)
OSType: linux    # 系统类别:linux

docker容器

docker start

运行停止的容器。在容器内执行exit后,容器就会退出并停止!
docker stop 容器名/id
docker start 容器名/id(已经停止的容器)

docker start ContainerID

docker ps

列出正在运行的容器。加上参数-a后,就会列出所有的容器,还包括关闭的容器。-s会显示所有的文件大小

docker kill

退出容器

退出容器:

exit
注意:这个命令退出容器,会使容器就变成Exited的状态,这样容器就会关闭。

或者

Ctrl+P+Q
如果要正常退出不关闭容器,请按Ctrl+P+Q进行退出容器

docker rm

删除一个或者多个容器。必须停止容器,才能删掉。

进入容器

创建进入容器

创建一个守护态的Docker容器,根据docker镜像。

docker run -itd ubuntu:14.04 /bin/bash

容器开启之后,通过下面的命令进入该容器。

登陆正在运行的容器

attach方式

docker attach ContainerID

这个命令始终会进入原来创建的终端,因此,该命令有一个问题。当多个窗口同时使用该命令进入该容器时,所有的窗口都会同步显示。如果有一个窗口阻塞了,那么其他窗口也无法再进行操作。因为这个原因,所以docker attach命令不太适合于生产环境,平时自己开发应用时可以使用该命令。

ssh方式

相信大家第一个想到的就是ssh。在镜像(或容器)中安装SSH Server,这样就能保证多人进入
容器且相互之间不受干扰了。但是使用了Docker容器之后不建议使用ssh进入到Docker容器内。关于为什么不建议使用,请参考如下文章:
为什么不需要在 Docker 容器中运行 sshd

exec方式 (推荐)

docker exec -it Containerid command

例如下面的命令。

docker exec -it 775c7c9ee1e1 /bin/bash

使用docker exec -h查看手册后,能够看到相应的参数介绍
Options:
-d, --detach Detached mode: run command in the background
–detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
-i, --interactive Keep STDIN open even if not attached
–privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the container

exec 的方式优点:这样就会创建一个新的终端。不受原终端运行的影响。所以如果在此终端执行exit命令,也不会使该容器停止。
杀掉正在运行的一个或者多个容器

docker kill container

Usage:	docker rm [OPTIONS] CONTAINER [CONTAINER...]

Remove one or more containers

Options:
  -f, --force     Force the removal of a running container (uses SIGKILL)
  -l, --link      Remove the specified link
  -v, --volumes   Remove the volumes associated with the container

参考:
Docker官方_get-started
Docker中文官方_get-startde
非常详细的Docker学习笔记_CSDN
每天五分钟玩转Docker容器技术_阿里云云栖社区

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xinming_365/article/details/89641712

docker - 资源限制-爱代码爱编程

#参考资源限制方法两种 资源限制针对 docker daemon ( 不针对 contrainer ) 资源限制针对 docker contrainer (针对 contrainer 及 contrainer 下所有的

如何在docker内部使用ulimit——如何在docker内部生成core_weixin_33809981的博客-爱代码爱编程

Ulimit 在linux里ulimit命令可以对shell生成的进程的资源进行限制。 常用的ulimit限制 打开文件句柄数core文件大小设置进程能够消耗的虚拟内存设置用户能够打开的进程数目 不太常用的ulimit限制 设置数据段的最大值.单位:kbytes 设置创建文件的最大值.单位:blocks 设置在内存

postgresql on docker部署是的shm配置注意_weixin_34037173的博客-爱代码爱编程

标签 PostgreSQL , docker , shm , 动态共享内存 背景 如果你使用docker启动PG时,遇到类似这样的问题,可能你需要看看docker的/dev/shm是不是不够大。 "ERROR: could not resize shared memory segment "/PostgreSQL.3887824

理解Docker ulimit参数-爱代码爱编程

ulimit ulimit本是一个Linux内的命令。最初设计是用来限制进程对资源的使用情况的,因为早期的系统系统资源包括内存,CPU都是非常有限的,系统要保持公平,就要限制大家的使用,以达到一个相对公平的环境。 # 使用格式 >>> ulimit [options] [limit] >>> ulimit -n 102

Docker--开发中常用操作-爱代码爱编程

1.Ubuntu 安装 Docker $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun 2. Docker 镜像加速器 2.1 安装docker镜像加速器 在 /etc/docker/daemon.json 中写入如下内容(如果文

Docker容器CPU、memory资源限制-爱代码爱编程

背景 在使用 docker 运行容器时,默认的情况下,docker没有对容器进行硬件资源的限制,当一台主机上运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制,那么容器之间会互相影响,小的来说会导致容器资源使用不公平;大的来说,可能会导致主机和集群资源耗尽,服务完全不可用。 d

docker 内存 limit 与 swap 限制-爱代码爱编程

结论 主机层没有开启 swap ,容器运行时无论怎么设置 --memory-swap,都不会使用到 swap,容器最大能使用的内存等于设置的内存限制; 主机层开启了 swap 如下表: memorymemory-swap效果M正数 S容器最大可用内存为S,其中 ram 为 M,swap 为(S-M),若 S=M 则无可用 swap 资源M0相当于未设

启动NV-docker的几条命令-爱代码爱编程

docker run -it -d -v /mnt:/mnt --cap-add=All -v /lib/modules:/lib/modules:ro -v /usr/local/docker-inspur/nvidia-volumes/volume:/usr/local/nvidia:ro --volume-driver=nvidia-docker -

更改Docker的shm(共享内存)大小-爱代码爱编程

error内容:ERROR: Unexpected bus error encountered in worker. This might be caused by insufficient shared memory (shm). 进入容器后可以df查看shm大小 原因: 创建docker的时候默认shm大小为64M,不够用!! 首先要关闭do

设置运行内存_docker 内存 limit 与 swap 限制-爱代码爱编程

结论 主机层没有开启 swap ,容器运行时无论怎么设置 --memory-swap,都不会使用到 swap,容器最大能使用的内存等于设置的内存限制; 主机层开启了 swap 如下表: 主机开启 swap 不设置 --memory-swap 参数 容器最大可以使用 2 倍的 --memory 内存 (可使用的 sw

deepstream6.0 python环境安装-爱代码爱编程

1.下载docker镜像 在官方网址可以选择可以选择合适的版本:https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_docker_containers.html docker pull nvcr.io/nvidia/deepstream:6.0-triton 2.启动容器