Docker技术入门与实战笔记

梦想与她 提交于 2020-03-02 21:57:08

Docker

一.底层技术支持cgroups/LXC/AUFS

1.cgroups

cgroups 进程分组化管理,Linux内核提供原生支持。通过分组实现对系统资源的限制与分配。

cgroups中的重要概念是“子系统”,也就是资源控制器,每种子系统就是一个资源的分配器.比如cpu子系统是控制cpu时间分配的。首先挂载子系统,然后才有control group的。比如先挂载memory子系统,然后在memory子系统中创建一个cgroup节点,在这个节点中,将需要控制的进程id写入,并且将控制的属性写入,这就完成了内存的资源限制。

2.LXC

LXC是Linux containers的简称,是一种基于容器的操作系统层级的虚拟化技术。

借助于namespace的隔离机制和cgroup限额功能,LXC提供了一套统一的API和工具来建立和管理container。

LXC旨在提供一个共享kernel的OS级虚拟化方法,在执行时不用重复加载Kernel,且container的kernel与host共享.

3.联合文件系统(UnionFS)

联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统。

联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像可以制作各种具体的应用镜像。

AuFS是ubantu上最常用的联合文件系统。

Docker镜像实际上是由具有依赖关系的多个Layer组成的。

Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过42层,现在是不得超过127层。

二.基本概念

1.Docker Image

1)操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:14.04 就包含了完整的一套Ubuntu 14.04 最小系统的 root 文件系统。

2)Docker Image内不建议有运行期需要修改的配置文件

2.Docker Container

1)Docker Container是Image的实例,共享内核
2)Docker Container里可以运行不同Os的Image,比如Ubuntu的或者Centos
3)Docker Container不建议内部开启一个SSHD服务,1.3版本后新增了docker exec命令进入容器排查问题。
4)Docker Container没有IP地址,通常不会有服务端口暴露,是一个封闭的“盒子/沙箱”

3.Docker Daemon

1)Docker Daemon是创建和运行Container的Linux守护进程,也是Docker最主要的核心组件.
2)Docker Daemon 可以理解为Docker Container的Container

4.数据卷

数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器可以随意删除、重新 run ,数据却不会丢失。

数据卷是一个的特殊目录,可以在容器之间共享和重用,数据卷默认会一直存在,即使容器被删除.Docker挂载数据卷的默认权限是读写,用户也可以通过:ro指定为只读。

数据卷容器 如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。

5. Docker Registry

1)一个Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

2)通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

eg:registry.cn-qingdao.aliyuncs.com/dockerres/dockerres:webv1s1

3)虚悬镜像 由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 <none> 的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image)。要注意区分虚悬镜像与中间层镜像。

三.Dockerfile

1.创建docker镜像

1)docker commit

docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]

eg:docker commit \
                  --author "Tao Wang <twang2218@gmail.com>" \
                  --message "修改了默认网页" \
                  webserver \
                  nginx:v2

2)Dockerfile

docker build [选项] <上下文路径/URL/->

eg:docker build -t nginx:v3 .  <.>表示上下文路径为当前目录

2.docker build的用法

a.直接用Git进行构建

docker build https://github.com/twang2218/gitlab-ce-zh.git

b.用给定的 tar 压缩包构建

docker build http://server/context.tar.gz

c.从标准输入中读取 Dockerfile 进行构建

docker build - < Dockerfile

d.从标准输入中读取上下文压缩包进行构建

docker build - < context.tar.gz

3.dockerfile命令

dockerfile内容:
    FROM debian:jessie
    RUN buildDeps='gcc libc6-dev make' \
        && apt-get update \
        && apt-get install -y $buildDeps \
        && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
        && mkdir -p /usr/src/redis \
        && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
        && make -C /usr/src/redis \
        && make -C /usr/src/redis install \
        && rm -rf /var/lib/apt/lists/* \
        && rm redis.tar.gz \
        && rm -r /usr/src/redis \
        && apt-get purge -y --auto-remove $buildDeps

1)FROM 指定基础镜像。

如果不以任何镜像为基础,则以FROM scratch代替。

2)RUN

shell 格式: RUN <命令>

exec 格式: RUN ["可执行文件", "参数1", "参数2"]

每一条RUN语句都会生成一个镜像,可以用&&将多条命令合成一条RUN语句。

3)COPY

COPY <源路径>... <目标路径>

COPY ["<源路径1>",... "<目标路径>"]

使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等.

eg:
COPY hom* /mydir/
COPY hom?.txt /mydir/

4)ADD

ADD格式与COPY一样 在COPY和ADD指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用COPY指令,仅在需要自动解压缩的场合使用ADD。

5)CMD 启动参数

CMD 指令用于指定容器默认的启动程序及参数。

shell 格式: CMD <命令>

exec 格式: CMD ["可执行文件", "参数1", "参数2"...]

指令格式上,一般推荐使用exec格式。

对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主 进程退出,容器就失去了存在的意义,从而退出。正确的做法是 直接执行可执行文件,并且要求以前台形式运行,不要以服务后台的形式启动。

6)ENTRYPOINT 启动参数

ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。

ENTRYPOINT的主要应用场景:

a.让镜像变成像命令一样使用

b.应用运行前的准备工作

7)ENV 设置环境变量

ENV <key> <value>

ENV <key1>=<value1> <key2>=<value2>

eg:ENV VERSION=1.0 DEBUG=on \
              NAME="Happy Feet"

8)ARG 构建参数

ARG <参数名>[=<默认值>]

构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是, ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。

9)VOLUME 定义匿名卷

VOLUME ["<路径1>", "<路径2>"...] VOLUME <路径>

容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。为了防止运行时用户忘记挂载卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷.

10)EXPOSE 声明端口

EXPOSE <端口1> [<端口2>...]

EXPOSE指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。

11)WORKDIR 指定工作目录

WORKDIR <工作目录路径>

12)USER 指定当前用户

USER <用户名>

13)HEALTHCHECK 健康检查

HEALTHCHECK [选项] CMD <命令> :设置检查容器健康状况的命令

HEALTHCHECK NONE :如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

eg:HEALTHCHECK --interval=5s --timeout=3s \
                                CMD curl -fs http://localhost/ || exit 1

14)ONBUILD 为他人做嫁衣裳

ONBUILD <其它指令>

eg:ONBUILD COPY ./package.json /app
     ONBUILD RUN [ "npm", "install" ]
     ONBUILD COPY . /app/

Dockerfile 中的其它指令都是为了定制当前镜像而准备的,唯有 ONBUILD 是为了帮助别人定制自己而准备的。

ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN , COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。

四、Docker网络服务

1.外部访问容器

可以通过 -P 或-p 参数来指定端口映射。

a.使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。
b.-p hostPort:containerPort 指定端口
eg:$ sudo docker run -d -p 5000:5000 training/webapp python app.py
c.-p ip:hostPort:containerPort
eg:sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
d.ip::containerPort 映射到指定地址的任意端口
eg:sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
e.使用 udp 标记来指定 udp 端口
eg:sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
f.docker port 来查看当前映射的端口配置
eg:docker port nostalgic_morse 5000

2.容器互联

--link 参数的格式为 --link name:alias ,其中 name 是要链接的容器的名称, alias 是这个连接的别名。

eg:sudo docker run -d -P --name web --link db:db training/webapp python app.py

3.网桥

Docker启动时,会自动在主机上创建一个docker0虚拟网桥。当创建一个Docker容器的时候,同时会创建了一对虚拟网卡(veth pair)接口,这对接口一端在容器内,即eth0;另一端在本地并被挂载到docker0网桥。这样所有容器在一个局域网内,通过docker0与主机通信。

4.网络配置

--net=bridge 这个是默认值,连接到默认的网桥。

--net=host 告诉 Docker 不要将容器网络放到隔离的命名空间中,即不要容器化容器内的网络。此时容器使用本地主机的网络,它拥有完全的本地主机接口访问权限。

--net=container:NAME_or_ID 让 Docker 将新建容器的进程放到一个已存在容器的网络栈中,新容器进程有自己的文件系统、进程列表和资源限制,但会和已存在的容器共享 IP 地址和端口等网络资源,两者进程可以直接通过lo 环回接口通信。

--net=none 让 Docker 将新容器放到隔离的网络栈中,但是不进行网络配置。之后,用户可以自己进行配置。

五.其他

tomcat Dockerfile
FROM tomcat:8.5.37-jre8
  MAINTAINER "wdw"
  ADD web1.war /usr/local/tomcat/webapps/
  CMD ["catalina.sh", "run"]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!