docker容器的标准使用过程_Docker容器基础介绍-程序员宅基地

技术标签: docker容器的标准使用过程  

Docker是PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。Docker是通过内核虚拟化技术(namespace以及cgroups等)来提供容器的资源隔离与安全保障。由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机( VM)额外的操作系统开销,提高资源利用率。

Docker是使用Go语言编写的一个程序运行、测试、交付的开放平台,Docker被设计为能够使你快速地交付应用。在Docker中,你可以将你的程序分为不同的基础部分,对于每一个基础部分都可以当做一个应用程序来管理。Docker能够帮助你快速地测试、快速地编码、快速地交付,并且缩短你从编码到运行应用的周期。Docker使用轻量级的容器虚拟化平台,并且结合工作流和工具,来帮助你管理、部署你的应用程序。Docker在其核心,Docker实现了让几乎任何程序都可以在一个安全、隔离的容器中运行。安全和隔离可以使你可以同时在机器上运行多个容器。Docker容器轻量级的特性,意味着可以得到更多的硬件性能。

Docker原理:建立-->传送-->运行

通过Docker Hub或者自己的Docker仓库分享Docker镜像, 从Docker镜像创建Docker容器, 在容器里运行应用程序。

Docker镜像是如何工作的?

Docker镜像是Docker容器运行时的只读模板,每一个镜像由一系列的层(layers)组成;Docker使用UnionFS(联合文件系统)来将这些层联合到一二镜像中,UnionFS文件系统允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。

正因为有了这些层(layers)的存在,Docker才会如此的轻量。当你改变了一个Docker镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新的层被添加或升级了。所以你不用重新发布整个镜像,只需要升级。层使得分发Docker镜像变得简单和快速。

每个镜像都是从一个基础的镜像开始的,比如ubuntu,一个基础的Ubuntu镜像,或者是Centos,一个基础的Centos镜像。你可以使用你自己的镜像作为新镜像的基础,例如你有一个基础的安装了Nginx的镜像,你可以使用该镜像来建立你的Web应用程序镜像。(Docker通常从Docker Hub获取基础镜像)

Docker镜像从这些基础的镜像创建,通过一种简单、具有描述性的步骤,我们称之为 指令(instructions)。每一个指令会在镜像中创建一个新的层,指令可以包含这些动作:

->  运行一个命令。

->  增加文件或者文件夹。

->  创建一个环境变量。

->  当运行容器的时候哪些程序会运行。

这些指令存储在Dockerfile文件中。当你需要建立镜像的时候,Docker可以从Dockerfile中读取这些指令并且运行,然后返回一个最终的镜像。

Docker仓库的用处?

Docker仓库是Docker镜像的存储仓库。可以推送镜像到Docker仓库中,然后在Docker客户端,可以从Docker仓库中搜索和拉取镜像。

Docker容器是如何工作的?

一个Docker容器包含了一个操作系统、用户添加的文件和元数据(meta-data)。每个容器都是从镜像建立的,镜像告诉Docker容器内包含了什么,当容器启动时运行什么程序,还有许多配置数据。Docker镜像是只读的,当Docker运行一个从镜像建立的容器,它会在镜像顶部添加一个可读写的层,应用程序可以在这里运行。

Docker容器运行时会做哪些事情?

使用docker命令时,Docker客户端都告诉Docker守护进程运行一个容器。

# docker run -i -t ubuntu /bin/bash

可以来分析这个命令,Docker客户端使用docker命令来运行,run参数表明客户端要运行一个新的容器。

Docker客户端要运行一个容器需要告诉Docker守护进程的最小参数信息是:

->  这个容器从哪个镜像创建,这里是ubuntu,基础的Ubuntu镜像。

->  在容器中要运行的命令,这里是/bin/bash,在容器中运行Bash shell。

那么运行这个命令之后在底层发生了什么呢?按照顺序,Docker做了这些事情:

->  拉取ubuntu镜像:Docker检查ubuntu镜像是否存在,如果在本地没有该镜像,Docker会从Docker Hub下载。如果镜像已经存在,Docker会使用它来创建新的容器。

->  创建新的容器:当Docker有了这个镜像之后,Docker会用它来创建一个新的容器。

->  分配文件系统并且挂载一个可读写的层:容器会在这个文件系统中创建,并且一个可读写的层被添加到镜像中。

->  分配网络/桥接接口:创建一个允许容器与本地主机通信的网络接口。

->  设置一个IP地址:从池中寻找一个可用的IP地址并且服加到容器上。

->  运行你指定的程序:运行指定的程序。

-> 捕获并且提供应用输出:连接并且记录标准输出、输入和错误让你可以看到你的程序是如何运行的。

由此就可以拥有一个运行着的Docker容器了!从这里开始你可以管理你的容器,与应用交互,应用完成之后,可以停止或者删除你的容器。

Docker与VM的区别:

docker与Openstack的对比

Docker用途:简单配置、代码流水线管理、开发效率、应用隔离、服务器整合、调试能力、多租户、快速部署

Docker可以快速交付应用程序

Docker可以为你的开发过程提供完美的帮助。Docker允许开发者在本地包含了应用程序和服务的容器进行开发,之后可以集成到连续的一体化和部署工作流中。举个例子,开发者们在本地编写代码并且使用Docker和同事分享其开发栈。当开发者们准备好了之后,他们可以将代码和开发栈推送到测试环境中,在该环境进行一切所需要的测试。从测试环境中,你可以将Docker镜像推送到服务器上进行部署。

Docker可以让开发和拓展更加简单

Docker的以容器为基础的平台允许高度可移植的工作。Docker容器可以在开发者机器上运行,也可以在实体或者虚拟机上运行,也可以在云平台上运行。Docker的可移植、轻量特性同样让动态地管理负载更加简单。你可以用Docker快速地增加应用规模或者关闭应用程序和服务。Docker的快速意味着变动几乎是实时的。

Docker可以达到高密度和更多负载

Docker轻巧快速,它提供了一个可行的、符合成本效益的替代基于虚拟机管理程序的虚拟机。这在高密度的环境下尤其有用。例如,构建你自己的云平台或者PaaS,在中小的部署环境下同样可以获取到更多的资源性能。

Docker改变了什么?

-> 面向产品:产品交付

-> 面向开发:简化环境配置

-> 面向测试:多版本测试

-> 面向运维:环境一致性

-> 面向架构:自动化扩容

Docker组件:镜像(Image)、容器(Container)、仓库(Repository)

Docker 架构:C/S架构

-> Docker使用客户端-服务器(client-server)架构模式。

-> Docker 客户端会与Docker守护进程进行通信。Docker 守护进程会处理复杂繁重的任务,例如建立、运行、发布你的 Docker 容器。

-> Docker 客户端和守护进程可以运行在同一个系统上,当然也可以使用Docker客户端去连接一个远程的 Docker 守护进程。

-> Docker 客户端和守护进程之间通过socket或者RESTful API进行通信。

Docker守护进程

如上图所示,Docker守护进程运行在一台主机上。用户并不直接和守护进程进行交互,而是通过 Docker 客户端间接和其通信。

Docker 客户端

Docker 客户端,实际上是 docker 的二进制程序,是主要的用户与 Docker 交互方式。它接收用户指令并且与背后的 Docker 守护进程通信,如此来回往复。

Docker 内部

要理解Docker内部构建,需要理解以下三种部件:

Docker 镜像 - Docker Images

Docker 仓库 - Docker Registry

Docker 容器 - Docker Containers

Docker镜像是Docker容器运行时的只读模板,每一个镜像由一系列的层 (layers) 组成。Docker 使用 UnionFS 来将这些层联合到单独的镜像中。UnionFS 允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。正因为有了这些层的存在,Docker 是如此的轻量。当你改变了一个 Docker 镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新 的层被添加或升级了。现在你不用重新发布整个镜像,只需要升级,层使得分发 Docker 镜像变得简单和快速。

Docker仓库用来保存镜像,可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。公有的 Docker 仓库名字是 Docker Hub。Docker Hub 提供了庞大的镜像集合供使用。这些镜像可以是自己创建,或者在别人的镜像基础上创建。Docker 仓库是 Docker 的分发部分。

Docker容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台,Docker 容器是 Docker 的运行部分。

libcontainer

Docker 从 0.9 版本开始使用 libcontainer 替代 lxc,libcontainer 和 Linux 系统的交互图如下:

下面说下Docker容器的底层技术:Namesapce(资源隔离)和Cgroup(资源限制)

命名空间   [Namespaces]

=>   pid namespace:使用在进程隔离(Process ID)

不同用户的进程就是通过pid namespace隔离开的,且不同 namespace 中可以有相同 PID。

具有以下特征:

-> 每个namespace中的pid是有自己的pid=1的进程(类似 /sbin/init 进程)

-> 每个 namespace 中的进程只能影响自己的同一个 namespace 或子 namespace 中的进程

-> 因为 /proc 包含正在运行的进程,因此在 container 中的 pseudo-filesystem 的 /proc 目录只能看到自己namespace 中的进程

-> 因为 namespace 允许嵌套,父 namespace 可以影响子 namespace 的进程,所以子 namespace 的进程可以在父namespace中看到,但是具有不同的 pid

=>   mnt namespace:使用在管理挂载点(Mount)

类似 chroot,将一个进程放到一个特定的目录执行。mnt namespace 允许不同namespace的进程看到的文件结构不同,这样每个namespace 中的进程所看到的文件目录就被隔离开了。同 chroot 不同,每个 namespace 中的 container 在 /proc/mounts 的信息只包含所在namespace的mount point。

=>   net namespace:使用在进程网络接口(Networking)

网络隔离是通过 net namespace 实现的, 每个 net namespace 有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每个 container 的网络就能隔离开来。 docker 默认采用 veth 的方式将 container 中的虚拟网卡同 host 上的一个 docker bridge 连接在一起。

=>   uts namespace:使用在隔离内核和版本标识 (Unix Timesharing System)

UTS ("UNIX Time-sharing System") namespace 允许每个 container 拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 Host 上的一个进程。

=>   ipc namespace:使用在管理进程间通信资源 (InterProcess Communication)

container 中进程交互还是采用 Linux 常见的进程间交互方法 (interprocess communication - IPC), 包括常见的信号量、消息队列和共享内存。然而同 VM 不同,container 的进程间交互实际上还是 host 上具有相同 pid namespace 中的进程间交互,因此需要在IPC资源申请时加入 namespace 信息 - 每个 IPC 资源有一个唯一的 32bit ID。

=>  user namespace:使用在管理空户空间

每个 container 可以有不同的 user 和 group id, 也就是说可以以 container 内部的用户在 container 内部执行程序而非 Host 上的用户。

有了以上6种namespace从进程、网络、IPC、文件系统、UTS 和用户角度的隔离,一个 container 就可以对外展现出一个独立计算机的能力,并且不同container从OS层面实现了隔离。然而不同 namespace 之间资源还是相互竞争的,仍然需要类似ulimit 来管理每个container所能使用的资源。

资源配额 [cgroups]

Docker还使用到了cgroups技术来管理群组。使应用隔离运行的关键是让它们只使用你想要的资源。这样可以确保在机器上运行的容器都是良民(good multi-tenant citizens)。群组控制允许Docker分享或者限制容器使用硬件资源。例如,限制指定的容器的内容使用。

cgroups实现了对资源的配额和度量。 cgroups 的使用非常简单,提供类似文件的接口,在 /cgroup 目录下新建一个文件夹即可新建一个 group,在此文件夹中新建 task 文件,并将 pid 写入该文件,即可实现对该进程的资源控制。具体的资源配置选项可以在该文件夹中新建子 subsystem ,{子系统前缀}.{资源项} 是典型的配置方法, 如 memory.usageinbytes 就定义了该 group 在 subsystem memory 中的一个内存限制选项。另外,cgroups 中的 subsystem 可以随意组合,一个 subsystem 可以在不同的 group 中,也可以一个 group 包含多个 subsystem - 也就是说一个 subsystem。

=>  memory

内存相关的限制

=>  cpu

在 cgroup 中,并不能像硬件虚拟化方案一样能够定义 CPU 能力,但是能够定义 CPU 轮转的优先级,因此具有较高 CPU 优先级的进程会更可能得到 CPU 运算。 通过将参数写入 cpu.shares ,即可定义改 cgroup 的 CPU 优先级 - 这里是一个相对权重,而非绝对值

=>  blkio

block IO 相关的统计和限制,byte/operation 统计和限制 (IOPS 等),读写速度限制等,但是这里主要统计的都是同步 IO

=>  devices

设备权限限制

Docker 联合文件系统

联合文件系统(UnionFS)是用来操作创建层的,使它们轻巧快速。Docker使用UnionFS提供容器的构造块。Docker可以使用很多种类的UnionFS包括AUFS, btrfs, vfs, and DeviceMapper。

Docker 容器格式

Docker连接这些组建到一个包装中,称为一个 container format(容器格式)。默认的容器格式是libcontainer。Docker同样支持传统的Linux容器使用LXC。在未来,Docker也许会支持其它的容器格式,例如与BSD Jails 或 Solaris Zone集成。

======================== Docker环境的安装部署==========================

环境准备(centos7)

# yum install -y docker

# systemctl start docker

# systemctl enable docker

镜像的查看(docker images信息结果包括:镜像仓库、标签、镜像ID、创建时间、镜像大小   )

[root@linux-node2 ~]# docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

docker.io/centos latest 60e65a8e4030 36 hours ago 196.6 MB

docker.io/nginx latest 813e3731b203 9 days ago 133.8 MB

docker.io/registry latest a8706c2bfd21 2 weeks ago 422.8 MB

镜像的导出、导入和下载(可以将本机下载的镜像导出,然后将导出文件上传到别的机器上,在别的机器上进行镜像导入)

[root@linux-node2 ~]# docker pull centos

[root@linux-node2 ~]# docker save centos > /opt/centos.tar.gz

将linux-node2的镜像导出文件上传到linux-node1机器上,然后在linux-node1机器上导入

[root@linux-node1 ~]# docker load < /opt/centos.tar.gz

镜像的删除(rmi后面可以跟多个id,用空格隔开)

docker rmi container_id

[root@linux-node2 ~]# docker rmi 813e3731b203

Docker重命名镜像名称和TAG

# docker tag IMAGEID(镜像id) REPOSITORY:TAG(仓库:标签)

[root@docker-test2 ~]# docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

93ec41b5ed04 About an hour ago 435.9 MB

[root@docker-test2 ~]# docker tag 93ec41b5ed04 kevin/nginx:v1

[root@docker-test2 ~]# docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

kevin/nginx v1 93ec41b5ed04 About an hour ago 435.9 MB

首次创建一个简单的容器

[root@linux-node2 ~]# docker run centos /bin/echo "hehe"

hehe

查看容器状态

可以使用docker ps只能看见存活的容器,docker ps -a 查看全部的容器,结果信息表示:

容器ID、使用的镜像、执行的命令、创建的时间、状态、端口、名称(如果不指定,自动生成)

[root@linux-node2 ~]# docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

daeb4d7f7aab centos "/bin/echo hehe" About a minute ago Exited (0) About a minute ago insane_einstein

创建容器

--name:指定容器名称

-t :分配一个tty终端

-i :容器的标准输保持打开的状态

[root@linux-node2 ~]# docker run --name mydocker -t -i centos /bin/bash

[root@94ab7a046f7c /]# ps aux

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root 1 0.0 0.1 11772 1872 ? Ss 03:42 0:00 /bin/bash

root 14 0.0 0.0 35888 1472 ? R+ 03:43 0:00 ps aux

这种方式创建自动进入容器,开启的容器只执行/bin/bash;

在容器中查看主机名

[root@94ab7a046f7c /]# hostname

94ab7a046f7c

[root@94ab7a046f7c /]# exit

启动、停止容器

# docker stop ID

# docker start ID

进入容器

[root@linux-node2 ~]# docker attach 94ab7a046f7c

[root@94ab7a046f7c /]#

删除容器

[root@linux-node2 ~]# docker rm ID/名称

加-f 强制删除,包括正在运行中的容器

映射

随机映射 (端口的映射是系统自动分配的)

[root@linux-node2 ~]# docker run -d -P nginx

90316d97ee975b4e62e1927a9fb31f20703556b1a3ea07880d0c68dcb5bbd3bb

[root@linux-node2 ~]# docker ps -l

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

90316d97ee97 nginx "nginx -g 'daemon off" 25 seconds ago Up 23 seconds 0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp ecstatic_almeida

指定映射 (如下,指定容器的80端口映射到主机的81端口上)

[root@linux-node2 ~]# docker run -d -p 81:80 nginx

0294a8f5b4fc81ba31383a8eb98ec62b136826eba92360c84afd87bf1bf819fc

[root@linux-node2 ~]# docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

0294a8f5b4fc nginx "nginx -g 'daemon off" 11 seconds ago Up 10 seconds 443/tcp, 0.0.0.0:81->80/tcp admiring_ramanujan

查看日志

命令为"docker logs +ID"

数据管理

数据卷

默认挂载目录

创建一个数据卷,名称是volume-test1,挂载到data下默认挂载目录

[root@linux-node2 ~]# docker run -it --name volume-test1 -v /data centos

[root@1768d6414cfc /]# ls -l /data/

total 0

列出容器的所有信息,查看mounts模块

[root@linux-node2 ~]# docker inspect 1768d6414cfc

"Mounts": [

{

"Name": "55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167",

"Source": "/var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data",

"Destination": "/data",

"Driver": "local",

"Mode": "",

"RW": true

}

],

查找挂载点并进入

[root@linux-node2 ~]# ll /var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data

总用量 0

[root@linux-node2 ~]# cd /var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data

创建一个cgt测试,并重新回到容器中查看

[root@linux-node2 _data]# mkdir cgt

去容器中查看

[root@1768d6414cfc /]# ls -l /data/

total 4

drwxr-xr-x 2 root root 4096 Jan 4 14:04 cgt

指定挂载目录。将容器的/opt映射到主机的/opt目录下(下面命令中前一个是主机路径,后一个是容器路径)

[root@linux-node2 ~]# docker run -it --name volume-test1 -v /opt:/opt centos

指定权限

只需要在挂载后面加上权限即可。rw为读写,ro为只读

[root@linux-node2 ~]# docker run -it --name volume-test1 -v /opt:/opt:rw centos

挂载单个文件

记录历史记录

[root@linux-node2 ~]# docker run -it -v ~/.bash_history:/.bash_history centos

数据卷容器

让一个容器可以访问另一个容器的数据卷。启动两个容器

启动nfs容器,挂在一个卷,使用-d直接在后台执行

[root@linux-node2 ~]# docker run -d --name nfs -v /data centos

209bc89b365ad6bc1eeae693ada01c04c2d08e9ee2b8816e624882944c116126

启动test1容器,挂载到nfs的数据卷容器上,

[root@linux-node2 ~]# docker run -it --name test1 --volumes-from nfs centos

[root@5e399198d6a8 /]# ls /data/

查看没内容

找到nfs容器的挂载点(可以使用名称,不仅仅是ID)

找到nfs容器的ID

[root@linux-node2 opt]# docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

209bc89b365a centos "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago nfs

找到nfs容器的挂载点

[root@linux-node2 _data]# docker inspect nfs

[root@linux-node2 opt]# cd /var/lib/docker/volumes/3938c9b1143d41340e148a4c7bc12d13b53966b15380c5b958a9e035897450d5/_data

[root@linux-node2 _data]# touch cgt

在test1上查看

[root@5e399198d6a8 /]# ls /data/

cgt

注意:数据卷容器不论停止还是开启,不影响其他容器挂载使用

如何制作镜像

方式一:手动构建容器

1)创建一个容器mynginx,使用centos镜像

[root@linux-node2 ~]# docker run --name mynginx -it centos

[root@f9c7dfb6f552 /]# rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm

[root@f9c7dfb6f552 /]# yum -y install nginx

[root@f9c7dfb6f552 /]# exit

exit

2)基于mynginx容器做一个镜像mynginx:v1

[root@linux-node2 ~]# docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

f9c7dfb6f552 centos "/bin/bash" 3 minutes ago Exited (0) 15 seconds ago mynginx

基于mynginx这个容器做一个镜像

[root@linux-node2 ~]# docker commit -m "my nginx" f9c7dfb6f552 cgt/mynginx:v1

3f3adc859b77b2b47c3631229761bee6c7066f1c708bc01c5173c2ef5c0adce8

提交镜像,同时打一个标签叫mynginx:v1,cgt相当于你向github上提交的用户名

查看镜像

[root@linux-node2 ~]# docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

cgt/mynginx v1 3f3adc859b77 About a minute ago 326.4 MB

3)基于mynginx:v1创建一个容器mynginxv1,目的是修改nginx不让其在后台运行

[root@linux-node2 ~]# docker run -it --name nginxv1 cgt/mynginx:v1

[root@ea64c5855006 /]# vi /etc/nginx/nginx.conf

daemon off; # 不再后台运行

[root@ea64c5855006 /]# exit

exit

[root@linux-node2 ~]# docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

ea64c5855006 cgt/mynginx:v1 "/bin/bash" 2 minutes ago Exited (0) 42 seconds ago nginxv1

4)基于mynginxv1提交mynginxv2版本

重新提交V2版本

[root@linux-node2 ~]# docker commit -m "my nginx" ea64c5855006 cgt/mynginx:v2

a480cdf9055ec4e640c65df6404c6ba42903ea77198a26cec75eef0e4965fe67

查看V2镜像

[root@linux-node2 ~]# docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

cgt/mynginx v2 a480cdf9055e 25 seconds ago

5)基于mynginxv2镜像,创建mynginxv2容器

启动容器,-d后台运行,-p指定端口 在后面是镜像,最后是命令(因为是yum安装的,可以直接写nginx,如果不是yum,那要写绝对路径)

[root@linux-node2 ~]# docker run -d -p 82:80 cgt/mynginx:v2 nginx

4eaf8a19034a673100f9355504628fad45e6ecbab91615afd6cb4e7a18b82171

[root@linux-node2 ~]# docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

4eaf8a19034a cgt/mynginx:v2 "nginx" 15 seconds ago Up 14 seconds 0.0.0.0:82->80/tcp elegant_leakey

可以在浏览器访问82端口

方式二:Dockerfile

1)Dockerfile包含的信息

-  基础镜像信息

-  维护者信息

-  镜像操作指令

-  容器启动时执行指令

2)文件的编写

[root@linux-node2 ~]# mkdir /opt/dockerfile/nginx/ -p

[root@linux-node2 ~]# cd /opt/dockerfile/nginx/

将index.html上传到此处

[root@linux-node2 nginx]# vim Dockerfile

# This is docker file

# version v1

# Author wangshibo

# Base image(基础镜像)

FROM centos

# Maintainer(维护者信息)

MAINTAINER wangshibo [email protected]

# Commands(执行命令)

RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm

RUN yum -y install nginx

# Add(添加文件)

ADD index.html /usr/share/nginx/html/index.html # index.html是自己编写的文件,放在后面的目录中,因为yum安装后Documentroot是在这里

RUN echo "daemon off;" >>/etc/nginx/nginx.conf

EXPOSE 80 # 对外的端口

CMD ['nginx'] # 执行的命令

3)构建容器,并运行。 建立newnginx容器,-t:标签,执行/opt/dockerfile/nginx/下面的默认的Dockerfile文件

[root@linux-node2 nginx]# docker build -t cgt/mynginx:v3 /opt/dockerfile/nginx/

[root@linux-node2 nginx]# docker run -d -p 83:80 cgt/mynginx:v3

Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。当你真正投入容器Docker的怀抱,不但可以发现它能解决很多问题,而且还具有众多的优点:

->它是不可变的-操作系统,库版本,配置,文件夹和应用都是一样的。您可以使用通过相同QA测试的镜像,使产品具有相同的表现。

->它是轻量级的-容器的内存占用非常小。不需要几百几千MB,它只要对主进程分配内存再加上几十MB。

-> 它很快速-启动一个容器与启动一个单进程一样快。不需要几分钟,您可以在几秒钟内启动一个全新的容器。

许多用户依然像对待典型的虚拟机那样对待容器,似乎都忘记了除了与虚拟机相似的部分,容器还有一个很大的优点:它是一次性的。这个"特性"本身促使用户改变他们关于使用和管理容器的习惯;下面将会说明下在容器中不应该做这些事,以确保最大地发挥容器的作用。

->不要在容器中存储数据 – 容器可能被停止,销毁,或替换。一个运行在容器中的程序版本1.0,应该很容易被1.1的版本替换且不影响或损失数据。有鉴于此,如果你需要存储数据,请存在卷中,并且注意如果两个容器在同一个卷上写数据会导致崩溃。确保你的应用被设计成在共享数据存储上写入。

->不要将你的应用发布两份 – 一些人将容器视为虚拟机。他们中的大多数倾向于认为他们应该在现有的运行容器里发布自己的应用。在开发阶段这样是对的,此时你需要不断地部署与调试;但对于质量保证与生产中的一个连续部署的管道,你的应用本该成为镜像的一部分。记住:容器应该保持不变。

->不要创建超大镜像 – 一个超大镜像只会难以分发。确保你仅有运行你应用/进程的必需的文件和库。不要安装不必要的包或在创建中运行更新(yum更新)。

->不要使用单层镜像 – 要对分层文件系统有更合理的使用,始终为你的操作系统创建你自己的基础镜像层,另外一层为安全和用户定义,一层为库的安装,一层为配置,最后一层为应用。这将易于重建和管理一个镜像,也易于分发。

->不要为运行中的容器创建镜像 – 换言之,不要使用"docker commit"命令来创建镜像。这种创建镜像的方法是不可重现的也不能版本化,应该彻底避免。始终使用Dockerfile或任何其他的可完全重现的S2I(源至镜像)方法。

->不要只使用"最新"标签 – 最新标签就像Maven用户的"快照"。标签是被鼓励使用的,尤其是当你有一个分层的文件系统。你总不希望当你2个月之后创建镜像时,惊讶地发现你的应用无法运行,因为最顶的分层被非向后兼容的新版本替换,或者创建缓存中有一个错误的"最新"版本。在生产中部署容器时应避免使用最新。

->不要在单一容器中运行超过一个进程-容器能完美地运行单个进程(http守护进程,应用服务器,数据库),但如果运行多个进程,管理、获取日志、独立更新都会遇到麻烦。

->不要在镜像中存储凭据。使用环境变量 –不要将镜像中的任何用户名/密码写死。使用环境变量来从容器外部获取此信息。

->使用非root用户运行进程 – "docker容器默认以root运行。(…)随着docker的成熟,更多的安全默认选项变得可用。现如今,请求root对于其他人是危险的,可能无法在所有环境中可用。你的镜像应该使用USER指令来指令容器的一个非root用户来运行。"

->不要依赖IP地址 – 每个容器都有自己的内部IP地址,如果你启动并停止它地址可能会变化。如果你的应用或微服务需要与其他容器通讯,使用任何命名与(或者)环境变量来从一个容器传递合适信息到另一个。

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

智能推荐

稀疏编码的数学基础与理论分析-程序员宅基地

文章浏览阅读290次,点赞8次,收藏10次。1.背景介绍稀疏编码是一种用于处理稀疏数据的编码技术,其主要应用于信息传输、存储和处理等领域。稀疏数据是指数据中大部分元素为零或近似于零的数据,例如文本、图像、音频、视频等。稀疏编码的核心思想是将稀疏数据表示为非零元素和它们对应的位置信息,从而减少存储空间和计算复杂度。稀疏编码的研究起源于1990年代,随着大数据时代的到来,稀疏编码技术的应用范围和影响力不断扩大。目前,稀疏编码已经成为计算...

EasyGBS国标流媒体服务器GB28181国标方案安装使用文档-程序员宅基地

文章浏览阅读217次。EasyGBS - GB28181 国标方案安装使用文档下载安装包下载,正式使用需商业授权, 功能一致在线演示在线API架构图EasySIPCMSSIP 中心信令服务, 单节点, 自带一个 Redis Server, 随 EasySIPCMS 自启动, 不需要手动运行EasySIPSMSSIP 流媒体服务, 根..._easygbs-windows-2.6.0-23042316使用文档

【Web】记录巅峰极客2023 BabyURL题目复现——Jackson原生链_原生jackson 反序列化链子-程序员宅基地

文章浏览阅读1.2k次,点赞27次,收藏7次。2023巅峰极客 BabyURL之前AliyunCTF Bypassit I这题考查了这样一条链子:其实就是Jackson的原生反序列化利用今天复现的这题也是大同小异,一起来整一下。_原生jackson 反序列化链子

一文搞懂SpringCloud,详解干货,做好笔记_spring cloud-程序员宅基地

文章浏览阅读734次,点赞9次,收藏7次。微服务架构简单的说就是将单体应用进一步拆分,拆分成更小的服务,每个服务都是一个可以独立运行的项目。这么多小服务,如何管理他们?(服务治理 注册中心[服务注册 发现 剔除])这么多小服务,他们之间如何通讯?这么多小服务,客户端怎么访问他们?(网关)这么多小服务,一旦出现问题了,应该如何自处理?(容错)这么多小服务,一旦出现问题了,应该如何排错?(链路追踪)对于上面的问题,是任何一个微服务设计者都不能绕过去的,因此大部分的微服务产品都针对每一个问题提供了相应的组件来解决它们。_spring cloud

Js实现图片点击切换与轮播-程序员宅基地

文章浏览阅读5.9k次,点赞6次,收藏20次。Js实现图片点击切换与轮播图片点击切换<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> <script type="text/ja..._点击图片进行轮播图切换

tensorflow-gpu版本安装教程(过程详细)_tensorflow gpu版本安装-程序员宅基地

文章浏览阅读10w+次,点赞245次,收藏1.5k次。在开始安装前,如果你的电脑装过tensorflow,请先把他们卸载干净,包括依赖的包(tensorflow-estimator、tensorboard、tensorflow、keras-applications、keras-preprocessing),不然后续安装了tensorflow-gpu可能会出现找不到cuda的问题。cuda、cudnn。..._tensorflow gpu版本安装

随便推点

物联网时代 权限滥用漏洞的攻击及防御-程序员宅基地

文章浏览阅读243次。0x00 简介权限滥用漏洞一般归类于逻辑问题,是指服务端功能开放过多或权限限制不严格,导致攻击者可以通过直接或间接调用的方式达到攻击效果。随着物联网时代的到来,这种漏洞已经屡见不鲜,各种漏洞组合利用也是千奇百怪、五花八门,这里总结漏洞是为了更好地应对和预防,如有不妥之处还请业内人士多多指教。0x01 背景2014年4月,在比特币飞涨的时代某网站曾经..._使用物联网漏洞的使用者

Visual Odometry and Depth Calculation--Epipolar Geometry--Direct Method--PnP_normalized plane coordinates-程序员宅基地

文章浏览阅读786次。A. Epipolar geometry and triangulationThe epipolar geometry mainly adopts the feature point method, such as SIFT, SURF and ORB, etc. to obtain the feature points corresponding to two frames of images. As shown in Figure 1, let the first image be ​ and th_normalized plane coordinates

开放信息抽取(OIE)系统(三)-- 第二代开放信息抽取系统(人工规则, rule-based, 先抽取关系)_语义角色增强的关系抽取-程序员宅基地

文章浏览阅读708次,点赞2次,收藏3次。开放信息抽取(OIE)系统(三)-- 第二代开放信息抽取系统(人工规则, rule-based, 先关系再实体)一.第二代开放信息抽取系统背景​ 第一代开放信息抽取系统(Open Information Extraction, OIE, learning-based, 自学习, 先抽取实体)通常抽取大量冗余信息,为了消除这些冗余信息,诞生了第二代开放信息抽取系统。二.第二代开放信息抽取系统历史第二代开放信息抽取系统着眼于解决第一代系统的三大问题: 大量非信息性提取(即省略关键信息的提取)、_语义角色增强的关系抽取

10个顶尖响应式HTML5网页_html欢迎页面-程序员宅基地

文章浏览阅读1.1w次,点赞6次,收藏51次。快速完成网页设计,10个顶尖响应式HTML5网页模板助你一臂之力为了寻找一个优质的网页模板,网页设计师和开发者往往可能会花上大半天的时间。不过幸运的是,现在的网页设计师和开发人员已经开始共享HTML5,Bootstrap和CSS3中的免费网页模板资源。鉴于网站模板的灵活性和强大的功能,现在广大设计师和开发者对html5网站的实际需求日益增长。为了造福大众,Mockplus的小伙伴整理了2018年最..._html欢迎页面

计算机二级 考试科目,2018全国计算机等级考试调整,一、二级都增加了考试科目...-程序员宅基地

文章浏览阅读282次。原标题:2018全国计算机等级考试调整,一、二级都增加了考试科目全国计算机等级考试将于9月15-17日举行。在备考的最后冲刺阶段,小编为大家整理了今年新公布的全国计算机等级考试调整方案,希望对备考的小伙伴有所帮助,快随小编往下看吧!从2018年3月开始,全国计算机等级考试实施2018版考试大纲,并按新体系开考各个考试级别。具体调整内容如下:一、考试级别及科目1.一级新增“网络安全素质教育”科目(代..._计算机二级增报科目什么意思

conan简单使用_apt install conan-程序员宅基地

文章浏览阅读240次。conan简单使用。_apt install conan