docker

Docker是一种开源应用容器引擎,提供一致性的开发和部署环境,强调快速、隔离性。镜像采用分层构建,利用写时复制技术,实现轻量级的虚拟化。容器是镜像的实例,具有独立运行的进程。Docker提供桥接网络、主机网络等多种网络模式,便于服务的暴露和通信。此外,通过数据卷功能,确保容器数据的持久化和共享。
摘要由CSDN通过智能技术生成

什么是docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

容器其实就是我们生活特别常见的物体,比如,盛水的杯子,装笔的笔筒,吃饭的碗。都是容器。那么docker容器存放的不过就是程序以及程序所依赖的环境

docker特性

一致性

一般情况下,开发人员的代码是在本地上开发测试的,它可能对于线上多多少少有一点不同。 可能在本地测试的时候没问题,推到线上就有问题。docker解决了这个问题,docker把程序和程序所依赖的环境打包成一个容器,在本地测试的时候没问题,推到线上也就不会有问题。这就是一致性

快速

没有虚拟化技术之前,电商站点在重大促销的时候,访问量比平常大几十倍,甚至几百倍的可能。 这时候我们需要提前把多余的服务器进行调试,配置,上线。来应对即将到来的活动。 这期间可能是痛苦的。 docker就免去了这一环节。 docker可以 将当前使用的服务可以直接打包推送对应的服务器上。启动和暂停更是一个docker命令即可。

隔离性

docker一个容器只运行一个进程以及其子进程,每个容器之间具有隔离性。互不干扰。

和传统vm技术不一样

在这里插入图片描述

docker相关名词

镜像

Docker镜像含有启动容器所需要的文件系统及其内容,因此,其用于创建并启动docker容器。

镜像分层构建

镜像采用分层构建机制,最底层是bootfs,上一层为rootfs

在这里插入图片描述
bootfs里面包含了kernel和BootLoader,在容器启动完成之后,会将其umount掉,以节省资源。 rootfs则是那些/etc,/proc等等根文件系统。 这两层在容器中都是只读的,不是可写的。

传统模式中,bootfs在启动之后,会将rootfs先设定为只读模式,等自身完全通过检查之后,在将其转为可写模式,等启动完毕之后,我们就可以在系统上写入数据。
但是docker中,并不是这样,它们都是只读的,而且是叠加到一起的。 这里采用了一种联合挂载的技术。

镜像在创建的时候,它可以有很多层,每一层都是只读的,只有在它被实例化成为容器的时候,容器位于它的最上层,实现了可写层。 例如下图:
在这里插入图片描述

联合挂载技术

传统的挂载方式,如果挂载的目录有数据的话,那么原目录的数据会隐藏起来。docker使用的是aufs,将分层镜像的文件同时都显示出来。docker的分层镜像,除了aufs,docker还支持btrfs, devicemapper和vfs等

写时复制

当 Docker 第一次启动一个容器时,初始的读写层是空的,当文件系统发生变化时,这些变化都会应用到这一层之上。比如,如果想修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层。由此,该文件的只读版本依然存在于只读层,只是被读写层的该文件副本所隐藏。该机制则被称之为写时复制(Copy on write)。

容器

容器就是基于镜像生成的一个可写层。 是依赖于镜像的。

仓库

存放镜像的地方,有docker官方维护的docker hub。 有本地的镜像仓库。还有国内的阿里云等第三方仓库。 稍后安装的时候会再次介绍

使用docker

安装docker

以centos7为例,安装的时候,首先关掉firewalld,并且建议安装最新版。此处使用仓库安装。

官方安装步骤
(1)安装docker仓库

[root@localhost ~] yum install -y yum-utils

[root@localhost ~] yum-config-manager \
>     --add-repo \
>     https://download.docker.com/linux/centos/docker-ce.repo

(2)安装docker

[root@localhost ~] yum install docker-ce

(3)启动docker

[root@localhost ~] systemctl start docker

准备仓库

如果使用docker官方的仓库,速度相对来说比较慢,阿里云等提供来网络加速功能。
此处以阿里云为例、

[root@localhost ~]# cat /etc/docker/daemon.json 
{
  "registry-mirrors": ["https://YOURID.mirror.aliyuncs.com"]
}

[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker

安装镜像

镜像可以直接使用pull命令拉取。 不添加版本号时,默认拉取latest,最新版
在这里插入图片描述

[root@localhost ~]# docker pull busybox
Using default tag: latest   #默认下载最新版
latest: Pulling from library/busybox
Digest: sha256:95cf004f559831017cdf4628aaf1bb30133677be8702a8c5f2994629f637a209
Status: Image is up to date for busybox:latest
docker.io/library/busybox:latest

#查看现在存在的镜像
[root@localhost ~]# docker images   
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              1c35c4412082        11 days ago         1.22MB

容器命令

docker run

有了镜像就可以启动容器。 使用docker run命令

参数解释
-t运行的时候去启动一个伪终端
–name STRING容器名字
-i交互式
–rm在停止的时候将容器删除,数据也随之消失
–network容器加入的网络
-d运行在后台
[root@localhost ~]# docker container run --name myimg --rm -it busybox 
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 sh
    8 root      0:00 ps

使用docker container ps可以查看容器运行状态

[root@localhost ~]# docker container ps 
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
72e02b8c1648        busybox             "sh"                About a minute ago   Up About a minute                       myimg

一个容器运行一个进程。使用了--rm选项,在容器退出的时候,容器也会消失

/ # exit
[root@localhost ~]# docker container ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

容器的进程可以被命令行中的进程覆盖掉。例如httpd容器默认运行的是"httpd -D FOREGROUND"

[root@localhost ~]# docker container run --name web --rm -it httpd
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Sun Jun 14 18:12:55.632316 2020] [mpm_event:notice] [pid 1:tid 139766166733952] AH00489: Apache/2.4.43 (Unix) configured -- resuming normal operations
[Sun Jun 14 18:12:55.632794 2020] [core:notice] [pid 1:tid 139766166733952] AH00094: Command line: 'httpd -D FOREGROUND'

我们可以使用/bin/bash来覆盖掉它原本的进程,但是具有服务的容器都要运行在前台

[root@localhost ~]# docker container run --name web --rm -it httpd /bin/bash
root@2558c47151f0:/usr/local/apache2# ls
bin  build  cgi-bin  conf  error  htdocs  icons  include  logs	modules

docker container exec

在容器中执行命令

[root@localhost ~]# docker container exec myimg ps
PID   USER     TIME  COMMAND
    1 root      0:00 sh
    6 root      0:00 ps

docker container stats

查看容器内的进程对资源占用的情况

docker container attach

将剥离终端的容器再次回到前端

[root@localhost ~]# docker container run -d --name web  -it busybox 

# 使用-d明令将进程放到后端运行。不能和--rm同时使用

使用attach重新回到前端

[root@localhost ~]# docker attach web
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var

docker container commit

我们在原有的镜像上做了修改之后,希望以后用自己做的版本,那么我们就可以将镜像推送上去

参数解释
-a指明作者信息
-p暂停容器在提交
[root@localhost ~]# docker container commit -a "ydong@local.com" -p web ydong/mytest 
sha256:a16eba970aa0976a0d48bfcf1a8caa58e1115f2eb4d3429f1a3f3ffb0744e1d6

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
ydong/mytest        latest              a16eba970aa0        About a minute ago   1.22MB

docker container push

将容器推送到网络上,默认推到docker官网。

首先需要 docker login 登录一下

[root@localhost ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: ydong07
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

如果想要传上官网,需要将镜像的标签改成和docker官网一样的名字

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ydong07/mytest      latest              a16eba970aa0        33 minutes ago      1.22MB

[root@localhost ~]# docker push ydong07/mytest
The push refers to repository [docker.io/ydong07/mytest]
2d12cbc270a9: Pushed 
1be74353c3d0: Pushed 
latest: digest: sha256:f717af0e25021b50ba5ec2d7cdcb70653089711298232c9d9ad1b0af38f25b78 size: 734

在这里插入图片描述

docker image tag

给镜像重新打标签

[root@localhost ~]# docker image tag ydong/mytest mytest/ydong

docker四种网络

docker提供了四种可用网络

桥网络

docker在启动的时候,会默认生成一个名叫docker0的桥,默认情况下,容器的ip地址都由docker0桥来分配,这就导致来只有宿主机可以访问到容器内的服务。

以httpd为例
1)启动一个容器提供httpd服务

[root@localhost ~]# docker run --name web -it --rm httpd
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Sun Jun 14 19:59:09.744044 2020] [mpm_event:notice] [pid 1:tid 140096873837696] AH00489: Apache/2.4.43 (Unix) configured -- resuming normal operations
[Sun Jun 14 19:59:09.744448 2020] [core:notice] [pid 1:tid 140096873837696] AH00094: Command line: 'httpd -D FOREGROUND'

2)宿主机访问
在这里插入图片描述

3)外网访问,是本机的80端口

在这里插入图片描述

docker在启动之后会生成一个虚拟的docker0桥网卡。 当容器运行起来之后,它负责分配地址。还有一个vethb69aca8的网卡名称,它相当于一根线,将容器的内的网线直接插到了docker0上

[root@ydong ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02428d0f865b	no		vethb69aca8

host网络

共享主机网络,主机的网络是什么样,容器的网络就是什么样。 和宿主机共享一个网络

示例:

[root@ydong ~]# docker run --name mytest -it --network host --rm busybox
/ # ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:8D:0F:86:5B  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:8dff:fe0f:865b/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:12 errors:0 dropped:0 overruns:0 frame:0
          TX packets:26 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1392 (1.3 KiB)  TX bytes:3259 (3.1 KiB)

ens33     Link encap:Ethernet  HWaddr 00:0C:29:05:AA:AF  
          inet addr:192.168.199.157  Bcast:192.168.199.255  Mask:255.255.255.0
          inet6 addr: fe80::89eb:3179:7d38:d8e8/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:175060 errors:0 dropped:0 overruns:0 frame:0
          TX packets:283769 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:18035448 (17.1 MiB)  TX bytes:687690836 (655.8 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:64790 errors:0 dropped:0 overruns:0 frame:0
          TX packets:64790 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:351471668 (335.1 MiB)  TX bytes:351471668 (335.1 MiB)

共享桥

内核中有6种名称空间,分别是:NET,UTS,IPC,MOUNT,USER,PID。NET,UTS和IPC是可以共享出去的。 MOUNT,USER,PID是不能共享的。

  • NET:提供网络隔离能力
  • UTS:提供主机名隔离能力
  • IPC:提供进程间通信隔离能力
  • MOUNT:提供磁盘挂载点和文件系统的隔离能力
  • USER:提供用户隔离能力
  • PID:提供进程隔离能力

空网络

无需用到网络时,不分配给它网络

expose port

假如容器中有httpd服务需要外界来访问它,但是bridge网络只能宿主机访问,外界如果想访问的话,需要使用-p选项,意思是将容器内的端口映射到宿主机上的某个端口,并暴露出去。相当于创建了DNAT规则

1)容器中的端口映射到宿主机上的随机端口。

[root@ydong ~]# docker run --name web -it --rm -p 80 httpd:2.4.43-alpine

[root@ydong ~]# docker port web
80/tcp -> 0.0.0.0:32771
#容器中的80端口映射到宿主机的32771

2)容器中的端口映射到宿主机上的制定端口

[root@ydong ~]# docker run --name web -it --rm --network bridge -p 80:80 httpd:2.4.43-alpine

[root@ydong ~]# docker port web
80/tcp -> 0.0.0.0:80
# 将容器中的端口80映射到宿主机上的80端口

3)宿主机绑定固定地址和固定端口

[root@ydong ~]# docker run --name web -it --rm --network bridge -p 192.168.199.157:80:80 httpd:2.4.43-alpine 

[root@ydong ~]# docker port web
80/tcp -> 192.168.199.157:80
#容器中的80端口映射到157宿主机上的80端口

4)宿主机绑定固定地址和随机端口

[root@ydong ~]# docker run --name web -it --rm --network bridge -p 192.168.199.157::80 httpd:2.4.43-alpine

[root@ydong ~]# docker port web
80/tcp -> 192.168.199.157:32768

docker volume

docker的数据都是放在容器内部的, 容器消失,数据也一起消失。 为了方便数据迁移,容器和容器之间共享数据。docker有一个功能叫存储卷。它可以将容器内的数据目录映射到宿主机上的某一处位置。这样容器消失,数据也不会消失

[root@ydong ~]# docker run --name web -it --rm -v /ydong/www/html:/usr/local/apache2/htdocs httpd:2.4.43-alpine

[root@ydong ~]# curl http://172.17.0.2
<h1>/ydong/www/html</h1>

容器之间还可以使用同一个存储卷

[root@ydong ~]# docker run --name web2 -it --rm --volumes-from web php:7.4.6-apache-buster /bin/bash
root@f59b59cb74cc:/var/www/html# cat /usr/local/apache2/htdocs/index.html 
<h1>/ydong/www/html</h1>
#这是两个不同的容器,挂载点都是一样的。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值