前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >docker知识总结

docker知识总结

作者头像
twelvecoder
发布于 2021-12-24 01:48:37
发布于 2021-12-24 01:48:37
55400
代码可运行
举报
文章被收录于专栏:十二的树洞十二的树洞
运行总次数:0
代码可运行

容器简介

什么是 Linux 容器

Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。

​ 容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。

容器就是虚拟化吗

​ 是,但是也不完全是。虚拟化使得许多操作系统可同时在单个系统上运行。容器则可共享同一个操作系统内核,将应用进程与系统其他部分隔离开。

​ 让多个操作系统在单个虚拟机监控程序上运行以实现虚拟化,并不能达成和使用容器同等的轻量级效果。

​ Linux 容器可从单个操作系统运行,在所有容器中共享该操作系统,因此应用和服务能够保持轻量级,并行快速运行。

什么是docker

​ “docker” 一词指代多种事物,包括开源社区项目、开源项目使用的工具、主导支持此类项目的公司 Docker Inc. 以及该公司官方支持的工具。

​ 借助 docker ,可将容器当做重量轻、模块化的虚拟机使用。同时,还能获得高度的灵活性,从而实现对容器的高效创建、部署及复制,并能将其从一个环境顺利迁移至另一个环境。

docker如何工作

​ docker 技术使用 Linux 内核和内核功能(例如 Cgroups 和 namespaces)来分隔进程,以便各进程相互独立运行。

​ 容器工具(包括 docker)可提供基于镜像的部署模式。这使得它能够轻松跨多种环境,与其依赖程序共享应用或服务组。docker 还可在这一容器环境中自动部署应用程序(或者合并多种流程,以构建单个应用程序)。

docker技术是否和传统的Linux容器相同

​ 否。docker 技术最初是基于 LXC 技术构建(大多数人都会将这一技术与“传统的” Linux 容器联系在一起),但后来它逐渐摆脱了对这种技术的依赖。

就轻量级虚拟化这一功能来看,LXC 非常有用,但它无法提供出色的开发人员或用户体验。除了运行容器之外,docker 技术还具备其他多项功能,包括简化用于构建容器、传输镜像以及控制镜像版本的流程。

​ 传统的 Linux 容器使用 init 系统来管理多种进程。这意味着,所有应用程序都作为一个整体运行。与此相反,docker 技术鼓励应用程序各自独立运行其进程,并提供相应工具以实现这一功能。这种精细化运作模式自有其优势。

docker的目标

​ docker的主要目标是"Build,Ship and Run any App,Angwhere",构建,运输,处处运行。

  • **构建:**做一个docker镜像
  • **运输:**docker pull
  • **运行:**启动一个容器

​ 每一个容器,他都有自己的文件系统rootfs。

docker中的镜像分层

​ docker支持通过扩展现有镜像,创建新的镜像。实际上,Docker Hub 中 99% 的镜像都是通过在base镜像中安装和配置需要的软件构建出来的。

​ 从上图可以看到,新镜像是从base镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

docker镜像为什么分层

​ 镜像分层最大的一个好处就是共享资源。

​ 比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

​ 如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是不会被修改的,修改只会被限制在单个容器内。这就是容器 Copy-on-Write 特性。

可写的容器层

​ 当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

​ 所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。

容器层的细节说明

​ 镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /a,上层的 /a 会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a。在容器层中,用户看到的是一个叠加之后的文件系统。

文件操作

文件操作

说明

添加文件

在容器中创建文件时,新文件被添加到容器层中

读取文件

在容器中读取某个文件时,docker会从上往下依次往各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后打开并读入内存。

修改文件

在容器中修改已存在的文件时,docker会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改。

删除文件

在容器中修改已存在的文件时,docker也是从上往下依次在各镜像层中查找此文件。找到后,会在容器层记录下此删除操作。(只是记录删除操作)

​ 只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。

​ 这样就解释了前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

docker网络类型

​ 为了更加详细地了解docker的网络运行原理,下面挑选几种较为重要的网络模型进行研究。

类型

说明

None

不为容器配置任何网络功能,没有网络 --net=none

Container

与另一个运行中的容器共享Network Namespace,–net=container:containerID

Host

与主机共享Network Namespace,–net=host

Bridge

docker设计的NAT网络模型(默认类型)

​ Bridge默认docker网络隔离基于网络命名空间,在物理机上创建docker容器时会为每一个docker容器分配网络命名空间,并且把容器IP桥接到物理机的虚拟网桥上。

不为容器配置网络功能

此模式下创建容器是不会为容器配置任何网络参数的,如:容器网卡、IP、通信路由等,全部需要自己去配置。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run  -it --network none busybox:latest  /bin/sh 
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
与其他容器共享网络配置(Container)

​ 此模式和host模式很类似,只是此模式创建容器共享的是其他容器的IP和端口而不是物理机,此模式容器自身是不会配置网络和端口,创建此模式容器进去后,会发现里边的IP是你所指定的那个容器IP并且端口也是共享的,而且其它还是互相隔离的,如进程等。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run  -it --network container:mywordpress_db_1  busybox:latest  /bin/sh 
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
105: eth0@if106: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
使用宿主机网络

​ 此模式创建的容器没有自己独立的网络命名空间,是和物理机共享一个Network Namespace,并且共享物理机的所有端口与IP,并且这个模式认为是不安全的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run  -it --network host  busybox:latest  /bin/sh
docker设计的NAT网络模型(默认类型)

​ 如上图所示为docker中bridge驱动模式的示意图,其中最下面的模块表示主机上的网卡。当docker启动时会自动在主机上创建一个虚拟网桥docker0,使用默认网络模式创建docker容器时会自动创建一对veth pair接口,一端连接在docker容器中(如图容器中的eth0),一端连接在虚拟网桥docker0上(如图veth)。这种veth pair是一种虚拟网络设备,主要用于不同namespace中(意味着网络隔离)的网络通信,它总是成对存在的。在这里可以把它想象成一对靠虚拟网线连接起来的两个虚拟网卡,一端连接着docker容器,一端连接着虚拟网桥docker0

​ 通过这种方式,不同docker容器之间可以通过ip地址互相通信,也可以通过虚拟网桥访问主机上的网络eth0(添加iptables规则,将docker容器对目标地址发出的访问通过地址伪装的方式修改为主机对目标地址进行访问)。

​ 如果想要外界网络访问docker容器时,需要在docker容器启动时加上参数-p [主机端口]:[容器端口]进行端口映射,原理也是通过修改iptables规则将访问[主机端口]的数据转发到docker容器的[容器端口]中,但是这种做法也存在着占用主机有限的端口资源的缺点。

查看网络列表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker network list 
NETWORK ID          NAME                  DRIVER              SCOPE
b15e8a720d3b        bridge                bridge              local
345d65b4c2a0        host                  host                local
bc5e2a32bb55        mywordpress_default   bridge              local
ebf76eea91bb        none                  null                local

docker操作

基础命令操作

查看docker相关信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]#  docker version  
Client:
 Version:    17.12.0-ce
 API version:    1.35
 Go version:    go1.9.2
 Git commit:    c97c6d6
 Built:    Wed Dec 27 20:10:14 2017
 OS/Arch:    linux/amd64
Server:
 Engine:
  Version:    17.12.0-ce
  API version:    1.35 (minimum version 1.12)
  Go version:    go1.9.2
  Git commit:    c97c6d6
  Built:    Wed Dec 27 20:12:46 2017
  OS/Arch:    linux/amd64
  Experimental:    false

配置docker镜像加速

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vi /etc/docker/daemon.json
{
  "registry-mirrors": ["https://registry.docker-cn.com"]
} 

启动容器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run -d -p 80:80 nginx
Unable to find image 'nginx:latest' locally
Trying to pull repository docker.io/library/nginx ... 
latest: Pulling from docker.io/library/nginx
a2abf6c4d29d: Pull complete 
f3409a9a9e73: Pull complete 
9919a6cbae9c: Pull complete 
fc1ce43285d7: Pull complete 
1f01ab499216: Pull complete 
13cfaf79ff6d: Pull complete 
Digest: sha256:d13dca1855de09e2fe392c58a66dd73d4ff4b71da4d1720bcf3f47b48c53ca1d
Status: Downloaded newer image for docker.io/nginx:latest
137a747ae587441071913b20874c981203d86e758a8f5309b577d2b924ad5114
# 容器启动后,在浏览器进行访问测试 

参数说明

参数

说明

run

创建并运行一个容器

-d

放入后台

-p

端口映射

nginx

镜像名称

镜像相关操作

搜索官方仓库镜像

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker search centos
INDEX       NAME                                        DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
docker.io   docker.io/centos                            The official build of CentOS.                   6936      [OK]       
docker.io   docker.io/ansible/centos7-ansible           Ansible on Centos7                              135                  [OK]
......

参数说明

参数

说明

NAME

镜像名称

DESCRIPTION

镜像说明

STARS

点赞数量

OFFICIAL

是否是官方的

AUTOMATED

是否是自动构建的

获取镜像

根据镜像名称拉取镜像

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker pull centos
Using default tag: latest
Trying to pull repository docker.io/library/centos ... 
latest: Pulling from docker.io/library/centos
a1d0c7532777: Pull complete 
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for docker.io/centos:latest

查看当前主机镜像列表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker image list
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/nginx     latest              f6987c8d6ed5        About an hour ago   141 MB
docker.io/centos    latest              5d0da3dc9764        3 months ago        231 MB

拉第三方镜像方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
docker pull index.tenxcloud.com/tenxcloud/httpd

导出镜像

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 导出
[root@docker ~]# docker image save centos > docker-centos.tar.gz

删除镜像

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker image rm centos:latest
Untagged: centos:latest
Untagged: docker.io/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Deleted: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
Deleted: sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59
[root@docker ~]# docker image list
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/nginx     latest              f6987c8d6ed5        About an hour ago   141 MB
[root@VM-4-4-centos ~]# 

导入镜像

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker image load -i docker-centos.tar.gz  
74ddd0ec08fa: Loading layer 238.6 MB/238.6 MB
Loaded image: docker.io/centos:latest
[root@docker ~]# docker image list
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/nginx     latest              f6987c8d6ed5        About an hour ago   141 MB
docker.io/centos    latest              5d0da3dc9764        3 months ago        231 MB

查看镜像的详细信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker image inspect centos
[
    {
        "Id": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
        "RepoTags": [
            "docker.io/centos:latest"
        ],
......

容器日常管理

最简单的运行一个容器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run nginx

创建容器,两步走(不常用)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker create centos:latest  /bin/bash
bb7f32368ecf0492adb59e20032ab2e6cf6a563a0e6751e58930ee5f7aaef204
[root@docker ~]# docker start stupefied_nobel
stupefied_nobel

快速启动容器方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run  centos:latest  /usr/bin/sleep 20;

容器内的第一个进程必须一直处于运行的状态,否则这个容器,就会处于退出状态!

查看正在运行的容器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@VM-4-4-centos ~]# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
137a747ae587        nginx               "/docker-entrypoin..."   17 minutes ago      Up 17 minutes       0.0.0.0:80->80/tcp   vigilant_goldstine

查看你容器详细信息/ip

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker container  inspect  容器名称/id

查看你所有容器(包括未运行的)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@VM-4-4-centos ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
137a747ae587        nginx               "/docker-entrypoin..."   17 minutes ago      Up 17 minutes       0.0.0.0:80->80/tcp   vigilant_goldstine

停止容器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker stop 容器名称/id 
或
[root@docker ~]# docker container  kill  容器名称/id

启动时进入容器方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run -it #参数:-it 可交互终端
[root@docker ~]# docker run -it nginx:latest  /bin/bash
root@79241093859e:/#

退出/离开容器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ctrl+p & ctrl+q

启动后进入容器的方法

启动一个docker

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run -it centos:latest 
[root@1bf0f43c4d2f /]# ps -ef 
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 15:47 pts/0    00:00:00 /bin/bash
root         13      1  0 15:47 pts/0    00:00:00 ps -ef

attach进入容器,使用pts/0 ,会让所用通过此方法进如放入用户看到同样的操作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker attach 1bf0f43c4d2f
[root@1bf0f43c4d2f /]# ps -ef 
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 15:47 pts/0    00:00:00 /bin/bash
root         14      1  0 15:49 pts/0    00:00:00 ps -ef

自命名启动一个容器 --name

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker attach 1bf0f43c4d2f
[root@1bf0f43c4d2f /]# ps -ef 
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 15:47 pts/0    00:00:00 /bin/bash
root         14      1  0 15:49 pts/0    00:00:00 ps -ef

exec 进入容器方法**(推荐使用)**

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker exec -it clsn1  /bin/bash 
[root@b20fa75b4b40 /]# 重新分配一个终端
[root@b20fa75b4b40 /]# ps -ef 
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 16:11 pts/0    00:00:00 /bin/bash
root         13      0  0 16:14 pts/1    00:00:00 /bin/bash
root         26     13  0 16:14 pts/1    00:00:00 ps -ef

删除所有容器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker rm -f  `docker ps -a -q`
# -f 强制删除

启动时进行端口映射

-p参数端口映射

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run -d -p 8888:80  nginx:latest 
287bec5c60263166c03e1fc5b0b8262fe76507be3dfae4ce5cd2ee2d1e8a89a9

不同指定映射方法

参数

说明

-p hostPort:containerPort

端口映射 -p 8080:80

-p ip:hostPort:containerPort

配置监听地址 -p 10.0.0.100:80

-p ip::containerPort

随机分配端口 -p 10.0.0.100::80

-p hostPort:containerPort:udp

指定协议 -p 8080:80:tcp

-p 81:80 -p 443:443

指定多个

随机映射

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
docker run -P (大P)# 需要镜像支持

数据卷的管理

挂载时创建卷

挂载卷

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run -d -p 80:80 -v /data:/usr/share/nginx/html nginx:latest
079786c1e297b5c5031e7a841160c74e91d4ad06516505043c60dbb78a259d09

容器内站点目录: /usr/share/nginx/html

宿主机写入数据,查看

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# echo "http://www.baidu.com" >/data/index.html
[root@docker01 ~]# curl 10.0.0.100
http://www.baidu.com

设置共享卷,使用同一个卷启动一个新的容器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run -d -p 8080:80 -v /data:/usr/share/nginx/html nginx:latest 
351f0bd78d273604bd0971b186979aa0f3cbf45247274493d2490527babb4e42
[root@docker01 ~]# curl 10.0.0.100:8080
http://www.baidu.com

查看卷列表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker volume ls
DRIVER              VOLUME NAME

创建卷后挂载

创建一个卷

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker volume create 
f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
[root@docker ~]# docker volume ls 
DRIVER              VOLUME NAME
local               f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521

指定卷名

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker volume ls 
DRIVER              VOLUME NAME
local               clsn
local               f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521

查看卷路径

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker volume inspect clsn 
[
    {
        "CreatedAt": "2018-02-01T00:39:25+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/clsn/_data",
        "Name": "clsn",
        "Options": {},
        "Scope": "local"
    }
]

使用卷创建

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run -d -p 9000:80 -v clsn:/usr/share/nginx/html nginx:latest 
1434559cff996162da7ce71820ed8f5937fb7c02113bbc84e965845c219d3503
# 宿主机测试
[root@docker ~]# echo 'blog.baidu.com' >/var/lib/docker/volumes/clsn/_data/index.html 
[root@docker01 ~]# curl 10.0.0.100:9000
blog.baidu.com

设置卷

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# docker run -d -P --volumes-from 079786c1e297 nginx:latest 
b54b9c9930b417ab3257c6e4a8280b54fae57043c0b76b9dc60b4788e92369fb

查看使用的端口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker ~]# netstat -lntup 
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1400/sshd           
tcp        0      0 10.0.0.100:2375         0.0.0.0:*               LISTEN      26218/dockerd       
tcp6       0      0 :::9000                 :::*                    LISTEN      32015/docker-proxy  
tcp6       0      0 :::8080                 :::*                    LISTEN      31853/docker-proxy  
tcp6       0      0 :::80                   :::*                    LISTEN      31752/docker-proxy  
tcp6       0      0 :::22                   :::*                    LISTEN      1400/sshd           
tcp6       0      0 :::32769                :::*                    LISTEN      32300/docker-proxy  
[root@docker ~]# curl 10.0.0.100:32769
http://www.baidu.com

dockerfile

  • dockerfile 是专门用来进行自动化构建镜像的编排文件,我们可以通过 docker build 命令来自动化地从 dockerfile 所描述的步骤来构建自定义的 Docker镜像,这比去命令行一条条指令执行的方式构建高效得多。
  • 另一方面,由于 dockerfile 提供了统一的配置语法,因此通过这样一份配置文件,可以在各种不同的平台上进行分发,需要时通过 dockerfile 构建一下就能得到所需的镜像。
  • 最后一个必须提的优点便是:dockerfile 通过与镜像配合使用,使得 docker镜像构建之时可以充分利用 “镜像的缓存功能”,因此也提效不少。

dockerfile自动构建docker镜像

官方构建dockerffile文件参考

https://github.com/CentOS/CentOS-Dockerfiles

dockerfile指令集

dockerfile主要组成部分:

  • 基础镜像信息 FROM centos:6.8
  • 制作镜像操作指令RUN yum insatll openssh-server -y
  • 容器启动时执行指令 CMD ["/bin/bash"]

dockerfile常用指令:

  • FROM 基础镜像
  • MAINTAINER 指定维护者信息,可以没有
  • RUN 要执行什么
  • ADD COPY文件,会自动解压
  • WORKDIR 设置当前工作目录
  • VOLUME 设置卷,挂载主机目录
  • EXPOSE 指定对外的端口
  • CMD 指定容器启动后的要干的事情

dockerfile其他指令:

  • COPY 复制文件
  • ENV 环境变量
  • ENTRYPOINT 容器启动后执行的命令
创建一个dockerfile

创建第一个Dockerfile文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 创建目录
[root@docker base]# cd /opt/base
# 创建Dcokerfile文件,注意大小写
[root@docker01 base]# vim Dockerfile
FROM centos:6.8
RUN yum install openssh-server -y 
RUN echo "root:123456" |chpasswd
RUN /etc/init.d/sshd start 
CMD ["/usr/sbin/sshd","-D"]

构建docker镜像

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker base]# docker image build  -t centos6.8-ssh . 
-t 为镜像标签打标签  . 表示当前路径

使用自构建的镜像启动

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@docker base]# docker run  -d -p 2022:22 centos6.8-ssh-b 
dc3027d3c15dac881e8e2aeff80724216f3ac725f142daa66484f7cb5d074e7a

如何高效编写dockerfile

基础镜像的选择有讲究
  • 一是 应当尽量选择官方镜像库里的基础镜像;
  • 二是 应当选择轻量级的镜像做底包

就典型的Linux基础镜像来说,大小关系如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Ubuntu > CentOS > Debian
多使用标签tag有好处
  • 构建镜像时,给其打上一个易读的镜像标签有助于帮助了解镜像的功能,比如:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
docker build -t=“centos:wordpress" .

例如上面的这个centos镜像是用来做wordpress用的,所以已经集成了wordpress功能,这一看就很清晰明了

  • 应该在 Dockerfile 的 FROM 指令中明确指明标签 Tag,不要再让 Docker daemon去猜,如
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FROM debian:twelveguo
充分利用镜像缓存

什么是镜像缓存?

由 dockerfile 最终构建出来的镜像是在基础镜像之上一层层叠加而得,因此在过程中会产生一个个新的镜像层。docker daemon 在构建镜像的过程中会缓存一系列中间镜像。

​ docker build镜像时,会顺序执行dockerfile中的指令,并同时比较当前指令和其基础镜像的所有子镜像,若发现有一个子镜像也是由相同的指令生成,则命中缓存,同时可以直接使用该子镜像而避免再去重新生成了。

​ 为了有效地使用缓存,需要保证 Dockerfile 中指令的连续一致,尽量将相同指令的部分放在前面,而将有差异性的指令放在后面

​ **举例:**假如想用dockerfile方式 基于最基本的centOS 镜像来构建两个不同的镜像时,两个dockerfile的开头可以相同:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FROM centos:latest
# 下面安装两个常用的工具
RUN yum install -y net-tools.x86_64
RUN yum install lrzsz
######## 上面为两个Dockerfile文件中相同的部分########

###### 下面为两个Dockerfile文件中不同的部分######
......
ADD和COPY指令的正确使用

​ 虽然两者都可以添加文件到镜像中,但在一般用法中,还是推荐以COPY指令为首选,原因在于ADD指令并没有COPY指令来的纯粹,ADD会添加一些额外功能,典型的如下 ADD一个压缩包时,其不仅会复制,还会自动解压,而有时并不需要这种额外的功能。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ADD twelveguo.tar.gz /path

​ 除此之外,在需要添加多个文件到镜像中的时候,不要一次性集中添加,而是选择 按需 在必要时 逐个 添加即可,因为这样有利于利用镜像缓存。

尽量使用docker volume

​ 虽然上面说推荐通过 COPY 命令来向镜像中添加多个文件,然而实际情况中,若文件大而多的时候还是应该优先用 docker-v 命令来挂载文件,而不是依赖于 ADD 或者 COPY

CMD 和 ENTRYPOINT指令 的正确理解使用

​ dockerfile 制作镜像时,会组合 CMD 和 ENTRYPOINT 指令来作为容器运行时的默认命令:即 CMD + ENTRYPOINT。此时的默认命令组成中:

  • ENTRYPOINT 指令部分固定不变,容器运行时是无法修改的
  • 而 CMD 部分的指令也可以改变,表现在运行容器时, docker run 命令中提供的参数会覆盖CMD的指令内容。

举个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FROM centos:latest
MAINTAINER twelveguo@tencent.com
ENTRYPOINT [ "ls", "-l"]
CMD ["-a"]

若以默认命令运行容器,可以发现,执行的是 ls-a-l 命令:

docker run 中增加参数 -t

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
docker run -it --rm --name test centos:twelveguo -t

也可以发现执行的是 ls-l-t,即 Dockerfile 中的 CMD 原参数被覆盖了:

因此推荐的使用方式是:

  • 使用exec格式的 ENTRYPOINT指令设置固定的默认命令和参数
  • 使用 CMD指令设置可变的参数
不推荐在 Dockerfile中 做端口映射

​ dockerfile 可以通过EXPOSE指令将容器端口映射到主机端口上,但这样会导致镜像在一台主机上仅能启动一个容器!

​ 所以应该在 docker run 命令中来用 -p 参数来指定端口映射,而不要将该工作置于 dockerfile 之中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#尽量避免这种方式
EXPOSE 8080:8899
#选择仅仅暴露端口即可,端口映射的任务交给docker run去做
EXPOSE 8080
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/12/22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Docker 容器入门
1.1 容器简介 1.1.1 什么是 Linux 容器 Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,
惨绿少年
2018/03/30
2K0
​Docker 数据卷的管理及自动构建docker镜像
https://github.com/CentOS/CentOS-Dockerfiles
码农编程进阶笔记
2021/07/20
7030
​Docker 数据卷的管理及自动构建docker镜像
Docker容器技术
Docker介绍 什么是容器 Linux容器是与系统其他部分隔离开的一系列进程,从另一个系统镜像运行,并由该镜像提供支持进程所需的全部文件。 容器镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。 来源:https://www.redhat.com/zh/topics/containers/whats-a-linux-container 容器就是虚拟化吗? 虚拟化使得许多操作系统可同时在单个系统上运行。 容器只能共享操作系统内核,将应用进程与系统其他部分,隔离开。
863987322
2018/03/29
3.5K0
Docker容器技术
Docker 实用学习笔记(看这一篇就足够了)
开始 -> Docker 在本机寻找对象 -> 判断本机是否有这个镜像 -> 没有则去下载 Docker Hub 这个镜像 —> 找不到镜像就返回错误(否则就下载镜像到本地)
Gorit
2021/12/08
2.4K0
Docker 实用学习笔记(看这一篇就足够了)
这20个Docker Command,有几个是你会的?
安装完成docker容器服务之后,需要了解如何操作它?在shell命令行下直接输入docker就可以查看帮助信息,如下。
民工哥
2020/09/16
5060
Docker从入门到干活,看这一篇足矣 [建议收藏]
Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。
码农编程进阶笔记
2021/07/20
4290
Docker从入门到干活,看这一篇足矣 [建议收藏]
Docker容器学习梳理--基础知识(1)
Docker是PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。 Docker是通过内核虚拟化
洗尽了浮华
2018/01/22
1.5K0
Docker容器学习梳理--基础知识(1)
Docker教程(超全总结)[通俗易懂]
如果需要通俗地描述容器的话,我觉得容器就是一个存放东西的地方,就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比如网站、程序甚至是系统环境。
全栈程序员站长
2022/11/04
3.3K0
Docker教程(超全总结)[通俗易懂]
Docker容器学习梳理-Dockerfile构建镜像
在Docker的运用中,从下载镜像,启动容器,在容器中输入命令来运行程序,这些命令都是手工一条条往里输入的,无法重复利用,而且效率很低。所以就需要一 种文件或脚本,我们把想执行的操作以命令的方式写入其中,然后让docker读取并分析、执行,那么重复构建、更新将变得很方便,所以Dockerfile就此诞生了。Docker提供了Dockerfile作为构建Docker镜像脚本,避免人们一行一行的输入,真是善莫大焉。Dockerfile脚本可以做到随时维护修改,即可以分享,更有利于在模板化,更不用说传输了,好处那
洗尽了浮华
2018/01/23
1.6K0
Docker容器学习梳理-Dockerfile构建镜像
墙裂推荐!看完全面掌握,最详细的 Docker 学习笔记总结(2021最新版)
Docker 是一个开源的容器引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者和系统管理员在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括 VMs(虚拟机)、bare metal、OpenStack 集群、云端、数据中心和其他的基础应用平台。容器是完全使用沙箱机制,相互之间不会有任何接口。
民工哥
2021/04/18
3.5K0
Docker容器学习梳理--基础知识(2)
之前已经总结了Docker容器学习梳理--基础知识(1),但是不够详细,下面再完整补充下Docker学习的一些基础。 Docker是个什么东西 Docker是一个程序运行、测试、交付的开放平台,Docker被设计为能够使你快速地交付应用。 在Docker中,你可以将你的程序分为不同的基础部分,对于每一个基础部分都可以当做一个应用程序来管理。 Docker能够帮助你快速地测试、快速地编码、快速地交付,并且缩短你从编码到运行应用的周期。 Docker使用轻量级的容器虚拟化平台,并且结合工作流和工具,来帮助你管
洗尽了浮华
2018/01/23
2K0
Docker容器学习梳理--基础知识(2)
docker命令实战
docker分层:每一次对原始镜像的修改都会形成新的一层,一层层的叠加,多个不同的容器实例可以共享原始镜像,并在磁盘记录新的修改,即采用写时复制的技术,可以节省磁盘空间
素履coder
2022/08/30
7120
docker命令实战
Docker 上运行 SQL Server
SQL Server 真是越来越有看头。当我们还在为 Linux 上运行 SQL Server 而兴奋的时候,SQL Server 已经开启了 容器化之路,至此才能看清微软的胸怀,开始拥抱更大的世界。当我越来越深入去阅读有关 Docker 容器的文档,已然发现曾经部署上千台 Linux MySQL 的场景,如今在 Docker 的帮助下,SQL Server 也是手到擒来。如果 SQL Server 再匹配一个分布式计算引擎,那也是分分钟即可打造一个计算怪兽,和小象 Hadoop 分庭抗礼。届时玩 SQL 的朋友们不用分心去折腾 Hadoop/Spark, 仅用 T-SQL 依然可以笑傲江湖。因为人工智能,机器学习算法本就是数据集合操作,天生和 SQL 结合紧密。不信看我的这篇:
Lenis
2019/12/26
2K0
Docker 入门笔记
ContainerViewer does not support full SVG 1.1
Rikka
2022/01/20
1.2K0
Docker 入门笔记
这就是你日日夜夜想要的docker!!!---------Docker镜像制作与私有仓库建立
Docker 镜像是由文件系统叠加而成(是一种文件的存储形式)。最底端是一个文件引 导系统,即 bootfs,这很像典型的 Linux/Unix 的引导文件系统。Docker 用户几乎永远不会和 引导系统有什么交互。实际上,当一个容器启动后,它将会被移动到内存中,而引导文件系 统则会被卸载,以留出更多的内存供磁盘镜像使用。Docker 容器启动是需要一些文件的, 而这些文件就可以称为 Docker 镜像。
不吃小白菜
2020/09/22
6270
这就是你日日夜夜想要的docker!!!---------Docker镜像制作与私有仓库建立
Docker的镜像
根据用户输入的文章内容,撰写摘要总结。
coders
2018/01/04
1.7K0
Docker的镜像
Docker之旅
记得以前电脑很贵,微软系统很流行。为了解决兼容性测试问题,我们搭建了很多虚拟机。当时比较流行的是vitural box, vmware。比如当时最新系统是win7,但是市面上还有vista, xp。就可以安装这样的虚拟机,如果每个系统需要不同的浏览器和其它软件,那么还得在虚拟机中安装。整个过程耗时很长,而且比较耗费资源。
赵云龙龙
2019/09/09
1K0
Docker之旅
容器技术|Docker三剑客之Compose
docker技术是基于Linux内核的cgroup技术实现的,那么问题来了,在非Linux平台上是否就不能使用docker技术了呢?答案是可以的,不过显然需要借助虚拟机去模拟出Linux环境来。 docker-machine就是docker公司官方提出的,用于在各种平台上快速创建具有docker服务的虚拟机的技术,甚至可以通过指定driver来定制虚拟机的实现原理(一般是virtualbox)。
民工哥
2020/09/16
7870
容器技术|Docker三剑客之Compose
使用docker运行zabbix-server
3、启动zabbix-mysql容器使用link连接mysql与java-gateway。
码农编程进阶笔记
2021/07/20
1.9K0
使用docker运行zabbix-server
Docker基础修炼3--Docker容器及常用命令
前文讲解了Docker镜像的原理和常用命令,本文继续通过官方的Apache镜像演示Docker容器相关的常用操作及命令。
不会飞的小鸟
2020/05/14
5560
相关推荐
Docker 容器入门
更多 >
LV.0
腾讯运营开发
目录
  • 容器简介
    • 什么是 Linux 容器
    • 容器就是虚拟化吗
  • 什么是docker
    • docker如何工作
    • docker技术是否和传统的Linux容器相同
    • docker的目标
    • docker中的镜像分层
      • docker镜像为什么分层
      • 可写的容器层
      • 容器层的细节说明
    • docker网络类型
      • 不为容器配置网络功能
      • 与其他容器共享网络配置(Container)
      • 使用宿主机网络
      • docker设计的NAT网络模型(默认类型)
  • docker操作
    • 基础命令操作
    • 镜像相关操作
    • 容器日常管理
    • 数据卷的管理
  • dockerfile
    • dockerfile自动构建docker镜像
      • dockerfile指令集
      • 创建一个dockerfile
    • 如何高效编写dockerfile
      • 基础镜像的选择有讲究
      • 多使用标签tag有好处
      • 充分利用镜像缓存
      • ADD和COPY指令的正确使用
      • 尽量使用docker volume
      • CMD 和 ENTRYPOINT指令 的正确理解使用
      • 不推荐在 Dockerfile中 做端口映射
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档