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在使用抽象虚拟是经由libvirt的LXC与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客户端调用,也可以被
wget
和curl
等命令调用。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会将写操作复制到可写层,而不是直接修改底层镜像,以确保原始镜像的完整性不受影响。
这种写时复制的机制可以带来以下几个优点:
节省存储空间:多个容器可以共享相同的只读镜像层,而每个容器都有自己的可写层。因此,如果多个容器都使用相同的镜像,它们只需存储一份只读的镜像层,节省了存储空间。
快速创建容器:由于写操作只会影响容器自己的可写层,因此创建容器时不需要复制整个镜像,而只需要添加一个可写层,使得容器的启动速度更快。
快速删除容器:当容器被删除时,只需删除其可写层即可,而不会影响底层镜像,因此删除容器的速度也很快。
容器隔离性:每个容器都有自己的可写层,使得容器之间的文件系统操作互相隔离,不会相互影响。
写时更新是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文件
基于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"]
未完待续。。。