docker

docker的简介

docker是什么?

Docker 是一个开源的应用容器引擎, 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上。通俗点说就是把应用打包放到一个盒子(容器)里,然后运行这些盒子,这些盒子就是一个一个进程。
在这里插入图片描述

docker容器技术如何实现?

前面说了docker就是把应用放到一个盒子里,应用还是我们的应用不用关心,我们最关心的就是这个盒子怎么实现的。其实也很简单就是加一些挡板把这些线程都隔离起来类似我们一个个隔离起来的工位。

docker容器的本质就是宿主机上的一个进程,只不过是利用了 Linux 内核的cgroup,namespace,chroot等技术对进程进行封装隔离。实现了类似虚拟化的功能。(这些技术我们之后再讲)

docker与虚拟化的区别是什么?

在这里插入图片描述

HostOS:宿主机操作系统
Hypervisor:虚拟层,虚拟出硬件

Guest OS:虚拟机操作系统

VM在虚拟层上安装完全独立的Guest OS,在里面运行各种个样的程序。每个虚拟化应用程序不仅包括应用程序(可能只有50 MB)、必要的二进制文件和库,还包括整个客户操作系统(可能有10 GB),你可以在windows上运行linux操作系统。

Docker在Docker Engine层上面运行各种程序,利用的Host OS,Docker Engine容器仅包含应用程序及其依赖项。它在主机操作系统的用户空间中作为独立进程运行。

docker有哪些优势?

提高系统资源的利用率
快速的启动时间
开发,测试,生产环境一致
快速部署,迁移

docker基本概念和使用

镜像(image)

Docker镜像是由文件系统叠加而成,最底端是一个文件引导系统,第一层即bootfs。第二层是root文件系统rootfs(列如我们要构建一个mysql的镜像,那个这个镜像就包含了mysql的所有文件),这些文件就是一个只读的模板。利用这个模版可以用来创建 Docker 容器。

容器(Container)

Docker 利用容器来运行应用。 容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是 相互隔离的、保证安全的平台。 可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。 *注:镜像是只读的,容器在启动的时候创建一层可写层作为最上层。

docker仓库

仓库是集中存放镜像文件的场所。 仓库分为公开仓库(Public)和私有仓库(Private)两种形式。 最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。 国内的公开仓库包括 Docker Pool 等,可以提供大陆用户更稳定快速的访问。 当然,用户也可以在本地网络内创建一个私有仓库。 当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓 库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来 就可以了。

理解了这三个概念,就理解了 Docker 的整个生命周期。

镜像

镜像拉取

docker pull [options] name [:tag] 表示从仓库拉取镜像 options是参数 name要拉取的镜像名tag是版本

我们这里拉取一下mysql的镜像

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker pull mysql:5.7.25
5.7.25: Pulling from library/mysql
27833a3ba0a5: Pull complete 
864c283b3c4b: Pull complete 
cea281b2278b: Pull complete 
8f856c14f5af: Pull complete 
9c4f38c23b6f: Pull complete 
1b810e1751b3: Pull complete 
5479aaef3d30: Pull complete 
1d924ec3d520: Pull complete 
1ab7ae63ac60: Pull complete 
08aa5f3680e9: Pull complete 
a832d0a0972a: Pull complete 
Digest: sha256:dba5fed182e64064b688ccd22b2f9cad4ee88608c82f8cff21e17bab8da72b81
Status: Downloaded newer image for mysql:5.7.25
docker.io/library/mysql:5.7.25

需要特别说明的是,docker的镜像是分层的,这里每一行代表镜像的一层最后堆积成mysql的镜像。这种分层镜像的思想可以让底层的镜像得到复用。如果官网下载镜像特别慢可以使用阿里云进行加速具体可以参考https://blog.csdn.net/weixin_43569697/article/details/89279225

查看所有镜像

docker images会展示本地有的所有的镜像

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
redis               latest              62f1d3402b78        2 weeks ago         104MB
ubuntu              latest              d70eaf7277ea        3 weeks ago         72.9MB
mysql               5.7.25              98455b9624a9        20 months ago       372MB
ubuntu              12.10               3e314f95dcac        6 years ago         172MB
删除镜像

docker rmi 删除镜像

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker rmi 62f1d3402b78
Untagged: redis:latest
Untagged: redis@sha256:a0494b60a0bc6de161d26dc2d2f9d2f1c5435e86a9e5d48862a161131affa6bd
Deleted: sha256:62f1d3402b787aebcd74aaca5df9d5fe5e8fe4c0706d148a963c70d74a497e51
Deleted: sha256:a00918a3a63fe7820ab3b038f0c157d579e37cb53cb6627ff399a59b6b993d5b
Deleted: sha256:8b8d9955ce888edc9bb9fcbeac7e5bc02db761ee9cbf35e2d6d6c5e13d6efb91
Deleted: sha256:4767a65a353899f079e51c19590715802ab8fca0951166ec4966ed6bac48464e
Deleted: sha256:a8f09c4919857128b1466cc26381de0f9d39a94171534f63859a662d50c396ca
Deleted: sha256:2ae5fa95c0fce5ef33fbb87a7e2f49f2a56064566a37a83b97d3f668c10b43d6
Deleted: sha256:d0fe97fa8b8cefdffcef1d62b65aba51a6c87b6679628a2b50fc6a7a579f764c
创建镜像

创建镜像有两种方式一种是使用dockerfile编写,一种是使用docker commit让运行的容器变成镜像

DockerFile

我们用Dockerfile创建一个镜像,在mysql5.7.25的文件的基础上新建一个文件并且输入一句话

#mydocker file
#FROM表示以mysql:5.7.21镜像为基础镜像
FROM mysql:5.7.25
#执行命令在mysql根目录下创建一个文件dockerFirst.txt并写入内容dockerfile创建的镜像
RUN echo 'dockerfile创建的镜像' > /dockerFileFirst.txt

这个是我们写好的dockerfile运行一下试试注意最后的 . 一定不要省略表示在当前位置读取dockerfile也可以自己指定dockerfile的位置

[root@iZ2zehx0enix3hhxj0tiloZ mydockerfile]# docker build -t mysqldockerfile:v2.0 .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM mysql:5.7.25
 ---> 98455b9624a9
Step 2/2 : RUN echo 'dockerfile创建的镜像' > /dockerFileFirst.txt
 ---> Running in 8b17d4cbd312
Removing intermediate container 8b17d4cbd312
 ---> 0e4ef1f45616
Successfully built 0e4ef1f45616
#查看本地的镜像
[root@iZ2zehx0enix3hhxj0tiloZ mydockerfile]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysqldockerfile     v2.0                0e4ef1f45616        34 seconds ago      372MB
mysqlfile           v1.0                068db9de31ad        34 minutes ago      372MB
ubuntu              latest              d70eaf7277ea        3 weeks ago         72.9MB
mysql               latest              db2b37ec6181        3 weeks ago         545MB
mysql               5.7.25              98455b9624a9        20 months ago       372MB
ubuntu              12.10               3e314f95dcac        6 years ago         172MB

发现打的镜像已经存在了

关于dockerfile命令介绍
在这里插入图片描述

Docker commit
#启动刚才下载的mysql
[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker run -p 3306:3306 --name mysql01 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.25
644ebae23f8f2a9c44b523b68fbb8c5fbb4adceb2152bb4cbd2bdd58ba29837a
#进入容器
[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker exec -it  mysql01  /bin/bash
root@644ebae23f8f:/# ls
bin  boot  dev  docker-entrypoint-initdb.d  entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
#创建一个文件并输入内容
root@644ebae23f8f:/# echo 'mysql test' > mysqlTest01.txt
#查看已经创建了该文件
root@644ebae23f8f:/# ls                                
bin  boot  dev  docker-entrypoint-initdb.d  entrypoint.sh  etc  home  lib  lib64  media  mnt  mysqlTest01.txt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

commit命令说明


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

OPTIONS说明:

-a :提交的镜像作者;

-c :使用Dockerfile指令来创建镜像;

-m :提交时的说明文字;

-p :在commit时,将容器暂停。

查看启动的容器

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
644ebae23f8f        mysql:5.7.25        "docker-entrypoint.s…"   11 minutes ago      Up 11 minutes       0.0.0.0:3306->3306/tcp, 33060/tcp   mysql01

构建镜像

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker commit -a fangfangbixia -m 'my first mysql' 644ebae23f8f mysqlfile:v1.0
sha256:068db9de31ad21099f86ecc446029ca17ef141df93014dc2bcde2ef663dce4ea

看到本地已有镜像,发现已经有了之前创建的镜像

#可以看到本地已经有fang
[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysqlfile           v1.0                068db9de31ad        2 minutes ago       372MB
ubuntu              latest              d70eaf7277ea        3 weeks ago         72.9MB
mysql               5.7.25              98455b9624a9        20 months ago       372MB
ubuntu              12.10               3e314f95dcac        6 years ago         172MB
上传镜像

用户可以通过 docker push 命令,把自己创建的镜像上传到仓库中来共享。例如,用户在 Docker Hub上完成注册后,可以推送自己的镜像到仓库中。如果不加地址和端口,那就是上传到Docker Hub。要传到自己的镜像仓库,必须包含地址,没有的话先tag。

docker tag [username]/xxx:tag来打tag

#先打个tag
[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker tag  mysql:5.7.25 fangfangbixia/mysql02
#上传镜像
[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker push fangfangbixia/mysql02
The push refers to repository [docker.io/fangfangbixia/mysql02]
82582edf9553: Layer already exists 
9209148debed: Mounted from library/mysql 
364557e875f1: Layer already exists 
5075b9328698: Pushed 
97874ea0e7f9: Layer already exists 
458d25c646d8: Layer already exists 
ec41e34b35a0: Layer already exists 
3437f67a712b: Layer already exists 
0aa7d65147ef: Layer already exists 
f411d8bde01c: Layer already exists 
5dacd731af1b: Mounted from library/mysql 
latest: digest: sha256:e889999df625a5a358a03cc433057cb5a8d3de17fbe11a70964da0eb9c7677b1 size: 2621

Docker 会上传镜像的每一层。因为fangfangbixia/mysql02 这个镜像实际上跟官方的 mysql 镜像一模一样,Docker Hub 上已经有了全部的镜像层,所以真正上传的数据很少,可以看到很多层都显示 Layer already exists

登录 https://hub.docker.com可以看到我们自己上传的镜像
在这里插入图片描述

删除所有镜像
docker rmi $(docker ps -a | awk '{print $1}')

容器

容器就是宿主机上的一个进程,这个进程独立运行着一个或一组应用

启动容器

docker run 创建一个新的容器

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS说明:

-a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;

-d: 后台运行容器,并返回容器ID;

-i: 以交互模式运行容器,通常与 -t 同时使用;

-P: 随机端口映射,容器内部端口随机映射到主机的端口

-p: 指定端口映射,格式为:主机(宿主)端口:容器端口

-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;

--name="nginx-lb": 为容器指定一个名称;

--dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;

--dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;

-h "mars": 指定容器的hostname;

-e username="ritchie": 设置环境变量;

--env-file=[]: 从指定文件读入环境变量;

--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;

-m :设置容器使用内存最大值;

--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;

--link=[]: 添加链接到另一个容器;

--expose=[]: 开放一个端口或一组端口;

--volume , -v: 绑定一个卷

需要注意的是我们可以使用 -it 以交互的模式启动容器,也可以使用-d 后台运行的模式启动容器启用一个mysql,设置名字为fangfangmysql01密码123456

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker run --name fangfangmysql01 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.25
展示所有容器

docker ps 展示所有运行中的容器

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
85bc5e4d591f        mysql:5.7.25        "docker-entrypoint.s…"   2 days ago          Up 2 days           0.0.0.0:3306->3306/tcp, 33060/tcp   fangfangmysql01
 

docker ps 会展示所有正在运行的容器,docker ps -a 展示所有的容器包括已经停止的容器

进入容器

docker exec 在运行的容器中执行命令,可以在运行的容器中直接指定bash目录进入终端,进入到之前运行的终端中

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker exec -it fangfangmysql01 /bin/bash
root@1e2e25e1aebb:/# 
退出容器

通过bash命令进入容器后,可以通过exit命令直接退出容器

root@1e2e25e1aebb:/# exit
exit
停止容器

docker stop 来停止一个运行中的容器。

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker stop fangfangmysql01
fangfangmysql01

当Docker容器中指定的应用终结时,容器也自动停止。 例如对于上一章节中只启动了一个终端

的容器,用户通过 exit 命令或 Ctrl+d 来退出终端时, 所创建的容器立刻停止。

启动停止容器

docker start 启动一个或者是多个处于停止中的容器

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker start fangfangmysql01 
fangfangmysql01
[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
1e2e25e1aebb        mysql:5.7.25        "docker-entrypoint.s…"   18 minutes ago      Up 4 seconds        0.0.0.0:3306->3306/tcp, 33060/tcp   fangfangmysql01
[root@iZ2zehx0enix3hhxj0tiloZ ~]# 

可以看到启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。

删除容器

docker rm 删除容器

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker rm fangfangmysql01
fangfangmysql01

需要注意的是docker rm是删除容器,docker rmi是删除镜像

查看容器/镜像的详细信息

docker inspect < id> 或者是< name:tags>,docker中可以通过name+tags来确定唯一的镜像,查看镜像或者是容器的详细信息

[root@iZ2zehx0enix3hhxj0tiloZ ~]# docker inspect 98455b9624a9
[
    {
        "Id": "sha256:98455b9624a96e32b353297bb312913b6bbd62ac195cea2c7dd477209ba572d6",
        "RepoTags": [
            "mysql:5.7.25"
        ],
        "RepoDigests": [
            "mysql@sha256:dba5fed182e64064b688ccd22b2f9cad4ee88608c82f8cff21e17bab8da72b81"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2019-03-26T23:42:41.544289046Z",
        "Container": "7df6fb5998bd5716ae9608678f1b80b96f4de5cd427cf5ceed4993650ed447c6",
        "ContainerConfig": {
            "Hostname": "7df6fb5998bd",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "3306/tcp": {},
                "33060/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.7",
                "MYSQL_MAJOR=5.7",
                "MYSQL_VERSION=5.7.25-1debian9"
            ]
            。。。

到这里我们关于docker的镜像和容器已经学完了那么我们来思考一个问题,docker的多个容器是可以共享同一个镜像docker是怎么做到的?当某个容器修改了基础镜像的内容,这时其他容器 是否也会被修改?
在这里插入图片描述

嘿嘿还记得前面提到的镜像的分层吗?在docker中镜像是一层一层的,低层文件如果相同就共用。这种分层最大的一个好处就是 - 共享资源,相同的镜像只需要一份就可以了,所以我们在写dockerfile的时候尽量把共用的镜像写在下面,但是修改怎么办呢?会不会互相影响,答案是不会的。

当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中,只有容器层是可写的,容器层下面的所有镜像层都是只读的。这就是容器的 Copy-on-Write 特性。

在这里插入图片描述
Docker 支持不同的存储驱动,包括 aufs、devicemapper、overlay2、zfs 和 vfs 等等,在最新的 Docker 中,overlay2 取代了 aufs 成为了推荐的存储驱动。我们可以通过docker inspec查看容器的基本信息。
在这里插入图片描述

可以看到我这个容器用的是overlay2存储驱动,对overlay2来说UpperDir下的文件是可以写的。LowerDir文件夹下都是只读的。

容器网络

默认Docker的网络就是使用的bridge,一般内部地址都是172.x.x.x。假设我们启动一个mysql容器,在

主机上,我们可以通过内部地址访问,我们用docker inspect能看到它的ip地址
在这里插入图片描述

ping一下是可以ping通的。
在这里插入图片描述

但是172.x这个地址,对于其他机器来说是不可访问的。需要怎么办呢?要做端口映射。我们可以在容器启动的时候-p指定端口映射,用-P可以随机映射端口。然后直接访问宿主机的这个端口就可以了。

用navicat连接一下发现是可以连接通的。
在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XwOAuF3k-1606141325513)(/Users/mac/Desktop/截屏2020-11-22 下午1.20.18.png)]

Docker数据卷

数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

数据卷可以在容器之间共享和重用

对数据卷的修改会立马生效

对数据卷的更新,不会影响镜像

数据卷默认会一直存在,即使容器被删除

注意:数据卷的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的数据卷。

一般像日志,数据库的数据我们都希望长期保存不会随着容器的删除而删除就需要把容器的目录挂载到宿主机上

在磁盘上创建一个文件夹,用来存放mysql的文件。比如 /data/mysql/data

docker run --name fangfangmysql02 -p 3306:3306 -v /data/mysql/data:/var/lib/mysql  -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.25
9ab284b19d8aee1c04551ec077659ad59342ee359174c54c80552b6bc9160c59

安装ps:

apt-get update && apt-get install procps

安装ip:

apt-get update & apt-get install -y iproute2

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值