Docker原理与应用

Docker

@ Author 雨

@ Date 2024年 4月17日

〇、Docker

1.什么是Docker?

Docker是一个开放源代码开放平台,用于开发应用、交付(shipping)应用和运行应用。Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。

Docker容器与虚拟机类似,但二者在原理上不同。容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、更能高效地利用服务器。 容器更多的用于表示软件的一个标准化单元。由于容器的标准化,因此它可以无视基础设施(Infrastructure)的差异,部署到任何一个地方。另外,Docker也为容器提供更强的业界的隔离兼容。

Docker 利用Linux核心中的资源分离机制,例如cgroups,以及Linux核心命名空间(namespaces),来建立独立的容器(containers)。这可以在单一Linux实体下运作,避免启动一个虚拟机造成的额外负担[4]。Linux核心对命名空间的支持完全隔离了工作环境中应用程序的视野,包括行程树、网络、用户ID与挂载文件系统,而核心的cgroup提供资源隔离,包括CPU存储器、block I/O与网络。从0.9版本起,Dockers在使用抽象虚拟是经由libvirtLXC与systemd - nspawn提供界面的基础上,开始包括libcontainer函式库做为以自己的方式开始直接使用由Linux核心提供的虚拟化的设施。

Docker引擎

Docker引擎(Docker Engine)是一个服务端-客户端结构的应用,主要有这些部分:Docker守护进程、Docker Engine API页面存档备份,存于互联网档案馆)、Docker客户端。

  • Docker守护进程(Docker daemons),也叫 dockerd ,是一个持久化的进程,用户管理容器。守护进程会监听Docker Engine API页面存档备份,存于互联网档案馆) 的请求。

  • Docker Engine API页面存档备份,存于互联网档案馆)是用于与Docker守护进程交互用的的API。它是一个RESTful API,因此它不仅可以被Docker客户端调用,也可以被wgetcurl等命令调用。

  • Docker客户端,也叫docker,是大部分用户与Docker交互的主要方式。用户通过客户端将命令发送给守护进程。

Docker注册中心

Docker注册中心(Docker registry)是用于存储Docker的镜像。Docker Hub 是一个公共的注册中心,任何人都可以使用,默认配置下,Docker将会在这里寻找镜像。

另外,用户可以自行构建私有注册中心。Docker Datacenter (DDC)的用户,可以直接使用 Docker Trusted Registry (DTR)。

2023年5月,在中国大陆地区被防火墙阻断屏蔽。

2. Docker写时更新机制:

"Docker写时更新"(Copy-on-Write, CoW)是指在Docker容器中对文件系统进行写操作时的一种优化技术。当容器启动时,会使用底层的镜像文件系统创建一个只读的文件系统层,然后在其上面添加一个可写的层。当容器内的进程对文件系统进行写操作时,Docker会将写操作复制到可写层,而不是直接修改底层镜像,以确保原始镜像的完整性不受影响。

这种写时复制的机制可以带来以下几个优点:

  1. 节省存储空间:多个容器可以共享相同的只读镜像层,而每个容器都有自己的可写层。因此,如果多个容器都使用相同的镜像,它们只需存储一份只读的镜像层,节省了存储空间。

  2. 快速创建容器:由于写操作只会影响容器自己的可写层,因此创建容器时不需要复制整个镜像,而只需要添加一个可写层,使得容器的启动速度更快。

  3. 快速删除容器:当容器被删除时,只需删除其可写层即可,而不会影响底层镜像,因此删除容器的速度也很快。

  4. 容器隔离性:每个容器都有自己的可写层,使得容器之间的文件系统操作互相隔离,不会相互影响。

写时更新是Docker容器技术中一个重要的优化手段,它提高了容器的效率和可用性,同时也提升了容器的隔离性和安全性。

3. Docker文件格式

Docker有两种文件格式,Dockerfile和Compose file。Dockerfile定义了单个容器的内容和启动时候的行为。Compose file定义了一个多容器应用。

Dockerfile

Docker 可以依照 Dockerfile 的内容,自动化地构建镜像。 Dockerfile 是包含着用户想要如何构建镜像的所有命令的文本。

 COPY . /app
 RUN make /app
 CMD python /app/app.py

Compose文件

Compose文件 是一个YAML文件,定义了服务(service)、网络、(volume)。

  • 服务(service)定义 各容器的配置,定义内容将以命令行参数的方式 传给 docker run 命令。

  • 网络(network),类似地,将定义内容传给 docker network create 命令 。

  • 卷(volume),类似地,将定义内容传给 docker volume create 命令。

docker run 命令中有一些选项,和 Dockerfile文件中的指令效果一样(如:CMD, EXPOSE, VOLUME, ENV),如果Dockerfile文件中使用这些指令,那么这些指令就会被视为默认参数,所以开发者无需特意在 Compose文件中再指定一次。

一、Docker常用命令

Docker常用组合命令:docker run -d --name mysql -p 3306:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123 mysql

run 运行容器,首先会查找镜像,有则直接创建容器,没有就会从仓库中下载到本地服务器上,再创建并打开

-d 后台运行

--name 为容器起名字,方便区分不同容器,便于管理

-p 端口映射

-e 环境变量

mysql 运行镜像的名字 mysql:5.7(默认最新版本)

docker exec -it 容器名/id bash 进入正在执行的容器内部

ctrl + D 退出容器

1. 帮助命令

 docker --version 查看docker版本信息
 docker 命令 --help 查看docker命令信息

2. 镜像命令

docker images:查看本机镜像

 [root@node1 ~]# docker images 列出镜像的详细信息
 REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
 hello-world   latest    d2c94e258dcb   11 months ago   13.3kB
 #可选项
 -a 显示所有镜像
 -q 只显示镜像的id
 -aq 

docker search: 从docker hub中查找镜像

 [root@node1 ~]# docker search mysql 
 NAME                            DESCRIPTION                                      STARS     OFFICIAL
 mariadb                         MariaDB Server is a high performing open sou…   5722      [OK]
 mysql                           MySQL is a widely used, open-source relation…   15008     [OK]
 phpmyadmin                      phpMyAdmin - A web interface for MySQL and M…   966       [OK]
 percona                         Percona Server is a fork of the MySQL relati…   627       [OK]
 #可选项
 -f starts数量  筛选大于指定数量的选项

docker pull:下载镜像

 [root@node1 ~]# docker pull mysql  #默认下载最新版本
 Using default tag: latest
 [root@node1 ~]#  docker pull mysql:5.7 #指定下载版本 镜像名后跟冒号+版本号  镜像名:[tags]
 #分层下载 docker images核心,联合文件系统
 bd37f6d99203: Pull complete 
 e733cb057651: Pull complete 
 af2fd35011dc: Pull complete 
 e5233d0f6ee3: Pull complete 
 cf11fd8658d3: Pull complete 
 85344d57c3cb: Pull complete 
 0eebca71f40d: Pull complete 
 18e468a1ddac: Pull complete 
 d9b2b8d35c75: Pull complete 
 57ba1b7684b4: Pull complete 
 Digest: sha256:203a051f50657d045108fa38a438a109101500d42b7ac4c03d399fcce43c4f2f
 Status: Downloaded newer image for mysql:latest
 docker.io/library/mysql:latest
 ​

docker rmi:删除镜像

 [root@node1 ~]# docker rmi 6f343283ab56  删除指定id镜像
 Untagged: mysql:latest
 Untagged: mysql@sha256:203a051f50657d045108fa38a438a109101500d42b7ac4c03d399fcce43c4f2f
 Deleted: sha256:6f343283ab56d883ec8ea17641b5d61d0252cc6c97dad3849cf3681dd1e2f37d
 Deleted: sha256:2b4c0a809c1e3fd353fdd6868d2335988bef66dc4891677042c0f503b203d414
 Deleted: sha256:5113dce4ac66d694008d06ea61512ac58573fe995efd77e8d285b7ba79dff6ac
 Deleted: sha256:fc037c17567de912528326b53c7296230319e5f20ff6639b8dfc6cd9bfda3724
 [root@node1 ~]# docker images
 REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
 mysql         5.7       5107333e08a8   4 months ago    501MB
 hello-world   latest    d2c94e258dcb   11 months ago   13.3kB
 #可选项
 -f 删除所有镜像
 [root@node1 ~]# docker rmi -f $(docker images -aq)

3.容器命令

容器必须要有镜像才能创建,向创建一个centos镜像

 [root@node1 ~]# docker pull centos

新建容器并启动

docker run [可选参数] iamge 运行容器(-d 后台方式运行 -it进入容器运行 exit停止执行并退出当前容器)

 docker run [可选参数] iamge
 #参数说明
 --name="Name"   容器名字
 -d 后台方式运行
 -it             使用交互方式运行,进入容器查看内容
 -p              指定容器端口 -p 8080:8080   
                 格式       -p 主机端口:容器端口
 —P              随机指定端口
 ​
 #测试
 [root@node1 ~]# docker run -it centos /bin/bash
 [root@fc2384391f7c /]# 启动并进入容器
 [root@fc2384391f7c /]# ls  #查看容器内
 bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
 [root@fc2384391f7c /]# exit #从容器中退出到主机

列出所有运行的容器

 [root@node1 ~]# docker ps 查看正在运行的容器
 CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
 [root@node1 ~]# docker ps -a  查看正在运行的容器 + 历史运行的容器
 CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                      PORTS     NAMES
 fc2384391f7c   centos    "/bin/bash"   2 minutes ago   Exited (0) 13 seconds ago             sharp_hamilton

退出容器

 exit 停止并退出容器
 ctrl + p + q 容器不停止退出

删除容器

 docker rm 容器id      删除指定容器,不能删除运行状态中的容器     
 docker rm -f $(docker ps -aq) 强制删除所有容器
 docker ps -aq|xargs docker rm  逐个删除容器

启动和停止容器

 docker start 容器id   启动停止的容器
 docker restart 容器id 重启容器
 docker stop 容器id  停止当前正在运行的容器
 docker kill 容器id  强制停止正在运行的容器

4. 其他常用命令

后台启动容器

 #命令docker run -d 镜像名 后台启动镜像
 [root@node1 ~]# docker run -d centos
 b48a037c1ed75b30b8cc2e21c76427a59f0a9d70f0be78f268843b8b47489774
 #问题docker ps 发现centos停止了
 #原因:容器启动后,发现没有被前台应用使用,即容器启动了但没有提供任何服务,自然回自动关闭

查看日志命令

 docker logs -f -t --tail

进入当前正在运行的容器

 docker exec -it 容器id/容器名 bash   #-it添加可输入终端     使用的交互模式(bash)
 [root@node1 ~]# docker exec -it 6ebaabe3fb18 /bin/bash  进入正在运行的容器,开启一个新终端
 docker attach 容器id
 [root@node1 ~]# docker exec -it 6ebaabe3fb18 /bin/bash  进入正在运行的容器,不会开启新终端

从容器内拷贝到主机上

 docker cp 容器id:容器内路径  目的主机路径
 [root@node1 yu]# docker attach 6ebaabe3fb18  //进入正在运行的容器
 [root@6ebaabe3fb18 /]# cd /home
 [root@6ebaabe3fb18 home]# ls                
 [root@6ebaabe3fb18 home]# touch text.java   //在容器内创建text.java文件
 [root@6ebaabe3fb18 home]# exit              //退出容器
 exit
 [root@node1 yu]# docker cp 6ebaabe3fb18:/home/text.java /root/yu //将容器内的文件拷贝到主机上
                                                Successfully copied 1.54kB to /root/yu
 [root@node1 yu]# ll
 总用量 0
 -rw-r--r-- 1 root root 0 4月  17 15:18 text.java
 -rw-r--r-- 1 root root 0 4月  17 15:16 yu.java
 #拷贝是一个收动过程,未来可以使用卷的技术将容与主机连通

常用命令汇总:

 attach    Attach to a running container  #当前shell下attach连接指定运行镜像
 build     Build an image from a Dockerfile  #通过Dockerfile定制镜像
 commit    Create a new image from a container's changes  #提交当前容器为新的镜像
 cp    Copy files/folders from a container to a HOSTDIR or to STDOUT  #从容器中拷贝指定文件或者目录到宿主机中
 create    Create a new container  #创建一个新的容器,同run 但不启动容器
 diff    Inspect changes on a container's filesystem  #查看docker容器变化
 events    Get real time events from the server#从docker服务获取容器实时事件
 exec    Run a command in a running container#在已存在的容器上运行命令
 export    Export a container's filesystem as a tar archive  #导出容器的内容流作为一个tar归档文件(对应import)
 history    Show the history of an image  #展示一个镜像形成历史
 images    List images  #列出系统当前镜像
 import    Import the contents from a tarball to create a filesystem image  #从tar包中的内容创建一个新的文件系统映像(对应export)
 info    Display system-wide information  #显示系统相关信息
 inspect    Return low-level information on a container or image  #查看容器详细信息
 kill    Kill a running container  #kill指定docker容器
 load    Load an image from a tar archive or STDIN  #从一个tar包中加载一个镜像(对应save)
 login    Register or log in to a Docker registry#注册或者登陆一个docker源服务器
 logout    Log out from a Docker registry  #从当前Docker registry退出
 logs    Fetch the logs of a container  #输出当前容器日志信息
 pause    Pause all processes within a container#暂停容器
 port    List port mappings or a specific mapping for the CONTAINER  #查看映射端口对应的容器内部源端口
 ps    List containers  #列出容器列表
 pull    Pull an image or a repository from a registry  #从docker镜像源服务器拉取指定镜像或者库镜像
 push    Push an image or a repository to a registry  #
 rename    Rename a container  #重命名容器
 restart    Restart a running container  #重启运行的容器
 rm    Remove one or more containers  #移除一个或者多个容器
 rmi    Remove one or more images  #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
 run    Run a command in a new container  #创建一个新的容器并运行一个命令
 save    Save an image(s) to a tar archive   #保存一个镜像为一个tar包(对应load)
 search    Search the Docker Hub for images  #在dockerhub中搜索镜像
 start    Start one or more stopped containers#启动容器
 stats    Display a live stream of container(s) resource usage statistics  #统计容器使用资源
 stop    Stop a running container            #停止容器
 tag         Tag an image into a repository  #给源中镜像打标签
 top       Display the running processes of a container #查看容器中运行的进程信息
 unpause    Unpause all processes within a container  #取消暂停容器
 version    Show the Docker version information       #查看容器版本号
 wait       Block until a container stops, then print its exit code  #截取容器停止时的退出状态值

查看容器运行日志

 docker logs 容器名称
 #可选项
 -f  持续查看日志

保存镜像到本地

 [root@node1 ~]# docker save -o yu.tar nginx      #保存镜像到本地  
 #可选项: -o 要将镜像保存到的文件地址和打包文件名称
 #nginx: 要保存的镜像名

导入(加载)本地镜像

 [root@node1 ~]# docker load -i ./yu.tar   # 加载本地打包镜像

二、Docker基础练习

1.Docker安装Nginx

 [root@node1 ~]# docker pull nginx        
 Using default tag: latest
 latest: Pulling from library/nginx
 a2abf6c4d29d: Pull complete 
 a9edb18cadd1: Pull complete 
 589b7251471a: Pull complete 
 186b1aaa4aa6: Pull complete 
 b4df32aa5a72: Pull complete 
 a0bcbecc962e: Pull complete 
 Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
 Status: Downloaded newer image for nginx:latest
 docker.io/library/nginx:latest
 [root@node1 ~]# 
 [root@node1 ~]# docker save -o yu.tar nginx
 [root@node1 ~]# ll
 总用量 142488
 drwxr-xr-x 2 root root      4096 4月  21 09:17 yu
 -rw------- 1 root root 145902080 4月  21 15:43 yu.tar
 [root@node1 ~]# docker rmi nainx
 Error response from daemon: No such image: nainx:latest
 [root@node1 ~]# docker rmi nginx
 Untagged: nginx:latest
 Untagged: nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
 Deleted: sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85
 Deleted: sha256:b625d8e29573fa369e799ca7c5df8b7a902126d2b7cbeb390af59e4b9e1210c5
 Deleted: sha256:7850d382fb05e393e211067c5ca0aada2111fcbe550a90fed04d1c634bd31a14
 Deleted: sha256:02b80ac2055edd757a996c3d554e6a8906fd3521e14d1227440afd5163a5f1c4
 Deleted: sha256:b92aa5824592ecb46e6d169f8e694a99150ccef01a2aabea7b9c02356cdabe7c
 Deleted: sha256:780238f18c540007376dd5e904f583896a69fe620876cabc06977a3af4ba4fb5
 Deleted: sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f
 [root@node1 ~]# docker images
 REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
 [root@node1 ~]# docker load -i ./yu.tar 
 2edcec3590a4: Loading layer [==================================================>]  83.86MB/83.86MB
 e379e8aedd4d: Loading layer [==================================================>]     62MB/62MB
 b8d6e692a25e: Loading layer [==================================================>]  3.072kB/3.072kB
 f1db227348d0: Loading layer [==================================================>]  4.096kB/4.096kB
 32ce5f6a5106: Loading layer [==================================================>]  3.584kB/3.584kB
 d874fd2bc83b: Loading layer [==================================================>]  7.168kB/7.168kB
 Loaded image: nginx:latest
 [root@node1 ~]# docker images
 REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
 nginx        latest    605c77e624dd   2 years ago   141MB

三、 数据卷挂载

1. 什么是数据卷

数据卷(volume)是一个虚拟目录,是容器内目录宿主机器目录之间映射的桥梁,通过数据卷技术实现了宿主机和容器的双向数据绑定

2. 数据卷如何使用

步骤:

  • 创建数据卷

  • 挂载数据卷:将数据卷与容器内目录绑定 docker run -v 数据卷:容器内目录。只能在最初创建容器时指定!也就是说,只能和run关联使用。如果挂载的数据卷不存在,则会自动创建。

 # 创建nginx容器,后台运行,运行名称 nginx_81 绑定数据卷 staticFile:容器内路径/usr/share/nginx/html 端口映射 81:80
 [root@node1 ~]# docker run -d --name nginx_81 -v staticFile:/usr/share/nginx/html -p 81:80 nginx
 6fd4f4c1eff4602d41ed4dbb88b43981c73e8a06cfffb8eb6e048a57ce81732e
 [root@node1 ~]# cd /var/lib/docker/volumes/staticFile/_data/  
 50x.html    index.html  
 ​
 [root@node1 ~]# docker exec -it 容器id/容器名 bash   #进入当前正在运行的镜像
 # ctrl + d 退出镜像

注意:/var/lib/docker/volumes/ 宿主机默认挂载地

3. 数据卷常用命令:

 #查看数据卷
 docker volume inspect 数据卷名称

4. 查看容器是够挂载数据卷

 #查看容器是否挂载数据卷
 docker inspect 容器名/id
 ​
 [root@node1 ~]# docker inspect nainx_81| grep volume
                 "Type": "volume",
                 "Source": "/var/lib/docker/volumes/html/_data",

四、 本地目录挂载

宿主机目录与容器目录挂载

创建Mysql容器时,为了确保容器卸载后,数据不会丢失,实现解耦,Docker会自动创建数据卷(匿名数据卷),且挂载在本机的/var/lib/mysql目录(数据存储地址)下。由于匿名数据卷的名字由Docker指定,名字太长了,所以一般使用自定义本地目录挂载。

本地目录挂载和数据卷挂载语法几乎一致,都是在创建容器时添加-v参数。不同的是本地目录-v 本地目录:容器内目录。要求本地目录必须以/或./开头,以表示与数据卷挂载不同,是本地目录挂载。

五、 DockerFile

1. 镜像结构

2.Dockerfile

Dockerfile就是一个文本文件,其中包含一个个指令,用指令说明执行什么操作来构建镜像,将来的Docker可以根据Dockerfile帮我们构建镜像。

两个标准的java项目的Dockerfile文件

  1. 基于ubuntu的基础镜像

 # 指定基础镜像
 From ubuntu:16.04
 # 配置环境变量,JDK安装目录
 ENV JAVA_DIR=/usr/local
 # 拷贝jdk和java项目包
 COPY ./jdk8.tar.gz $JAVA_DIR/
 COPY ./docker-demo.jar /tmp/app.jar
 # 安装JDK
 RUN cd $JAVA_DIR && tar -zxvf ./jdk8.tar.gz && mv ./jdk1.8.0_144 ./java8
 # 配置环境变量
 ENV JAVA_HOME=$JAVA_DIR/java8
 ENV PATH=$PATH:$JAVA_HOME/bin
 # 入口,java项目的启动命令
 ENTRYPOINT["java","-jar","/app.jar"]
 ​

      2. 基于jdk11的基础镜像

 # 基础镜像
 FROM openjdk:11.0-jre-buster
 # 拷贝jar包
 COPY docker-demo.jar /app.jar
 # 入口
 ENTRYPOINT["java","-jar","/app.jar"]

 未完待续。。。

相关推荐

  1. 《数据库原理应用

    2024-04-22 21:40:01       30 阅读
  2. Docker in Docker原理实战

    2024-04-22 21:40:01       43 阅读
  3. Docker in Docker原理实战

    2024-04-22 21:40:01       41 阅读
  4. Docker in Docker原理实战

    2024-04-22 21:40:01       39 阅读
  5. Docker in Docker原理实战

    2024-04-22 21:40:01       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-22 21:40:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-22 21:40:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-22 21:40:01       87 阅读
  4. Python语言-面向对象

    2024-04-22 21:40:01       96 阅读

热门阅读

  1. XiaodiSec day014 Learn Note 小迪渗透学习笔记

    2024-04-22 21:40:01       36 阅读
  2. 微信小程序

    2024-04-22 21:40:01       37 阅读
  3. notepad++快捷键和宏录制

    2024-04-22 21:40:01       40 阅读
  4. stm32开发三、单片机关键字extern

    2024-04-22 21:40:01       34 阅读
  5. 云原生周刊:CNCF 2023 年度调查报告 | 2024.4.15

    2024-04-22 21:40:01       40 阅读
  6. OpenCV2之简单处理视频

    2024-04-22 21:40:01       37 阅读
  7. Uipath用计划任务启动 bat脚本语句

    2024-04-22 21:40:01       31 阅读
  8. 【C语言】归并排序算法实现

    2024-04-22 21:40:01       36 阅读
  9. Element-UI el-autocomplete带输入建议的输入框组件

    2024-04-22 21:40:01       42 阅读
  10. 正则表达式?: ?= ?! 的用法详解

    2024-04-22 21:40:01       68 阅读