脚本宝典收集整理的这篇文章主要介绍了Docker学习笔记——Docker基础,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
官方介绍:
docker 是一个开源的应用容器引擎,基于Go 语言并遵从 apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker的构想是要实现“Build, Ship and Run Any App, Anywhere”,即通过对应用的封装(Packaging)、分发(Distribution)、部署(deployment)、运行生命周期(Runtime)进行管理,达到应用组件级别的“一次封装,到处运行”。
本人理解:
我们在开发到上线一个程序的时候需要接触很多环境,比如:开发环境(一般是在自己电脑)、测试环境、生产环境,在不同的环境中我们开发出的程序可能出现一些问题。可能在自己电脑上可以跑的程序,到了其它机器上就会因为环境不同而出现一些问题。而且换到不同的机器上我们就需要重新配置环境。例如下图所示。所以我们就想,如果能把环境一起打包运行,那样不就可以解决不同运行环境的问题了。使用Docker就可以解决这样的问题,我们可以使用Docker将程序以及环境打包为一个镜像,并上传到远程仓库,当需要在其它机器上运行时,只需要将镜像从远程仓库拉取下来直接运行即可。
Docker是一个C/S架构的软件,Docker会启动一个守护进程用来接收客户端的命令并执行相应的命令。比如:docker run 镜像名,可以根据一个镜像运行一个容器。
镜像(Image):
Docker中的镜像就像是一个只读的模板,比如操作系统镜像,我们可以使用操作系统镜像来安装一个操作系统;又像是面向对象中的类,通过类我们可以创建一个对象。镜像是可以复用的,我们可以通过Docker运行一个镜像实例,运行起来的镜像就是一个容器。
容器(Container):
Docker容器类似一个轻量级的沙箱,Docker利用容器技术来运行和隔离应用。容器是从镜像创建的应用运行实例。它可以启动、开始、停止、删除,而这些容器都是彼此相互隔离、互不可见的。
可以把容器看作一个简易版的linux系统环境(包括root用户权限、进程空间、用户空间和网络等)以及运行在其中的应用程序打包而成的盒子。
仓库(ReposITory)
Docker仓库类似代码仓库,是Docker集中存放镜像文件的仓库,仓库分为私有仓库和公有仓库。可以通过Docker从仓库中拉取一个镜像,也可以上传自己的镜像。目前最大的公开仓库是官方提供的Docker Hub,就像Github一样,Docker Hub存放了很多官方的或者非官方的镜像,例如:nginx镜像、redis镜像等。官网:https://hub.docker.COM/
如下图,下图中包含了三部分,分别时Docker客户端、Docker守护进程以及远程仓库。Docker客户端可以接收命令并通知Docker守护进程来进行一系列的操作,比如拉取镜像、运行容器等。Docker守护进程将会管理镜像以及容器。远程仓库存放了很多种不同的镜像。
Docker的安装:ubuntu20.04安装Docker_PEerless__的博客-CSDN博客
在使用下面的命令时,可以加参数 --help 来查看帮助文档。例如dokcer run --help:
下面显示了docker run命令的使用方式以及其它的可选参数和其解释。
docker images
使用docker images命令可以查看本机已经存在的镜像。分别显示了镜像名、标签(版本信息)、镜像ID、创建时间以及镜像的大小。
除此之外,还有一些可选参数,可以通过docker images --help 命令来查看,下面两个是比较常用的参数:
# -a参数,显示所有的镜像 docker images -a -a, --all Show all images (default hides intermediate images) # -q参数,只显示镜像ID -q, --quiet Only show image IDs
docker tag sourname:tag desname:tag #例如: docker tag ubuntu:18.04 myubuntu:lastest
docker seArch 镜像名 #参数: # 过滤输出内容 -f, --filter filter Filter output based on conditions PRovided # 限制输出个数 --limit int Max number of search results (default 25) # 例如 docker search --filter=is-official=true MySQL # 搜索mySQL官方镜像 docker search --filter=stars=200 mysql # 搜索star大于200的mysql镜像 docker search --limit 5 mysql # 只显示5个输出
使用docker search可以从远程仓库搜索镜像,上面显示了镜像名、描述、stars、是否是官方镜像等信息。
docker pull 镜像名 docker pull 镜像名:tag #例如 docker pull mysql # 不加tag,将会拉取最新版本 docker pull mysql:5.7 # 拉取5.7版本的mysql
在镜像名后可以指定拉取的版本,如果不指定就会拉取最新版本,关于镜像的版本可以到docker hup来搜索。网址:https://hub.docker.com/
使用下面命令可以删除本机仓库中的一个镜像,rmi ==> remove image
docker rmi 镜像名 或 镜像ID #例如 docker rmi centos 或 docker rmi 9f266d35e02c , 命令Docker images可以查看镜像ID 参数: # 强制删除,类似linux命令 rm -f -f, --force Force removal of the image # 如果要删除所有的镜像可以使用以下命令, docker images -aq 会显示所有镜像的ID docker rmi `docker images -aq` 或 docker rmi $(docker images -aq)
Docker镜像的save和load命令可以将镜像导出到本地以及加载本地镜像到镜像库。使用save命令可以将镜像导出到本地,这样就可以跟别人分享自己的镜像,当然也可以提交到远程仓库,将在后面介绍。通过load命令则可以加载别人分享的镜像。
docker save -o 生成的镜像名 镜像 # 例如 docker save -o mysql5_7.tar mysql:5.7
docker load -i 本地镜像名 或者 docker load < 本地镜像名
docker run 镜像名 参数: -d, --detach Run container in background and print container ID 后台运行容器 -e, --env list Set environment VARiables 设置环境变量 --expose list Expose a port or a range of ports 暴露端口 -i, --interactive Keep STDIN open even if not attached 交互模式 --name string Assign a name to the container 给当前运行的容器指定名字 -p, --publish list Publish a container's port(s) to the host 指定端口映射 -P, --publish-all Publish all exposed ports to random ports 随机指定暴露的端口映射 -t, --tty Allocate a pseudo-TTY 分配一个终端 -v, --volume list Bind mount a volume 挂载数据卷 --volumes-From list Mount volumes from the specified container(s) 从一个数据卷容器挂载目录 -w, --workdir string Working directory inside the container 指定容器中的工作目录
我们可以使用交互模式来运行一个容器,例如下面命令:
docker run -it --name c1 centos /bin/bash
-t选项让Docker分配一个伪终端并绑定到容器的标准输入上,-i则让容器的标准输入保持打开,–name给容器指定名字,centos为创建容器使用的镜像,/bin/bash为容器中运行的终端。如果镜像不存在,Docker会从远程仓库拉取,然后再运行。如下图,运行容器后发现终端发生了变化,说明我们已经进入了容器,用户为root用户,@后的一串字符为当前容器的ID。可以使用ls命令来查看当前目录下的文件。
输入exit命令可以退出当前容器。
使用docker ps -a来查看所有容器,发现刚刚运行的容器在退出后就停止运行了。对于所创建的bash容器,当用户使用exit命令退出bash进程后,容器也会自动退出。这是因为对于容器来说,当其中的应用退出后,容器的使命完成,也就没有运行的必要了。
使用 Ctrl + p + q来退出容器可以让容器在后台继续运行。
我们可以在启动时让容器在后台运行,这样在退出容器后,容器会继续运行。
docker run -id --name c2 centos
运行后,输出了运行的容器的ID。使用docker ps -a命令来查看所有容器,发现刚刚启动的容器还在运行
可以使用下面的命令进入容器:
docker exec -it c2 /bin/bash 或 docker exec -it 29f35e8928c5 /bin/bash
在进入容器并退出后发现,c2容器依然在运行。
当利用docker run来创建并启动容器时,docker在后台运行的标准操作包括:
检查本地是否存在指定的镜像,不存在就从远程仓库下载;利用镜像创建一个容器,并启动该容器;分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层;从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去;从网桥的地址池配置一个IP地址给容器;执行用户指定的应用程序;执行完毕后容器被自动终止。
docker ps 参数: # 查看所有容器 -a, --all Show all containers (default shows just running) # 只显示容器ID -q, --quiet Only display container IDs
使用docker ps可以查看容器,类似linux的ps命令查看进程。不加参数只会显示当前正在运行的容器,-a参数可以显示所有容器,-q只显示容器ID,如果要删除所有容器就可以使用该参数了,类似删除全部镜像。
1)暂停容器
# 暂停容器 docker pause 容器名 或 ID # 继续运行暂停的容器 docker unpause 容器名 或 ID
2)终止容器
docker stop 容器名 或 ID
该命令会首先向容器发送SIGTERM信号,等待一段超时时间后(默认为10s),再发送SIGKILL信号来终止容器。
docker start 容器名 或 ID
# 重启容器,先终止再启动 docker restart 容器名 或 ID
docker rm 容器名 或 ID 参数: #强制删除容器 -f, --force Force the removal of a running container (uses SIGKILL)
容器在运行时使用docker rm无法删除,需要加-f参数才可。
如果要删除所有容器,也可以使用类似删除所有镜像的命令:
docker rm `docker ps -aq` 或 docker rm $(docker ps -aq)
某些时候,需要将容器从一个系统迁移到另外一个系统,此时可以使用Docker的导入和导出功能。
1)导出容器
导出容器是指,导出一个已经创建的容器到另一个文件,不管这个容器是否处于运行状态。
docker export -o exportname 容器名 或 docker export 容器名 > exportname # 例如 docker export -o test_for_run.tar ce1 docker export ce1 > test_for_run
之后,可将导出的tar文件传输到其它机器上,然后通过导入命令导入到系统中,实现容器的迁移。
2)导入容器
docker import filename
使用docker inspect可以查看容器的具体信息,会以json格式返回容器ID、创建时间、路径、状态、镜像、配置在内的各项信息。
docker inspect 容器名 或 ID # 同样使用docker inspect 镜像名 或 镜像ID 也可以查看镜像的相关信息
里面有很多参数,在这里只展示了一部分。
使用下面的命令可以查看docker容器中的进程信息。
docker top 容器名 或 ID
-e, --env list Set environment variables 设置环境变量
使用-e命令可以给运行的容器设置环境变量
--expose list Expose a port or a range of ports 暴露端口
例如,运行nginx时可以将容器的80端口进行暴露。
我们在外部机器是无法直接通过网络与容器进行通信的,但是宿主机是可以和容器直接通信的,因此我们可以借助宿主机来和容器进行通信。
例如下图,在容器中运行了一个端口为3306的mysql数据库,在外部机器中是无法直接访问容器中的mysql的。因此可以配置一个端口映射,容器中的3306端口映射到宿主机的3307端口(也可以是其它端口),这样我们可以直接通过宿主机的IP以及端口来访问容器中的数据库。
-p, --publish list Publish a container's port(s) to the host 指定端口映射 -P, --publish-all Publish all exposed ports to random ports 随机指定暴露的端口映射
例如在运行nginx时,可以将容器内的80端口映射为宿主机的8080端口,我们就可以在浏览器中通过8080端口来访问容器中的nginx。-p自己指定映射的端口。
-P让docker来随机指定映射的端口。
可以使用docker inspect来查看映射的端口:
-w, --workdir string Working directory inside the container 指定容器中的工作目录
可以通过-w命令来指定容器中的工作目录,运行容器后,容器就在指定的工作目录。
在生产环境中使用Docker,往往需要对数据进行持久化,或者需要在多个容器直接进行数据共享,这必然涉及容器的数据管理操作,容器中的管理数据主要有两种方式:
数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似Linux中的mount行为。 数据卷可以提供很多有用的特性: 数据卷可以在容器间共享和重用,容器间传递数据将变得高效与方便;对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作;对数据卷的更新不会影响镜像,解耦开应用和数据;卷会一直存在,直到没有容器使用,可以安全地卸载它(即使容器被删除了,本地数据卷也不会被删除)。
数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似Linux中的mount行为。
数据卷可以提供很多有用的特性:
-v, --volume list Bind mount a volume 挂载数据卷 # 使用: -v 宿主机目录:容器目录
当容器在删除后,容器中的数据也就随之被删除了。如果我们运行了一个mysql的容器,当容器被删除后,我们不希望mysql中的数据也被删除。因此我们可以将容器中的数据与宿主机的一个目录建立一个映射,这两个目录中的数据会被同步。
如上图所示,运行了一个名字为c6的centos的容器,并指定了宿主机的/home/mgh/data与容器/usr/local/data的映射(如果路径中的文件夹不存在,则会创建),在容器的/usr/local/data目录中创建了hello.txt并写入内容。然后退出容器,在宿主机的/home/mgh/data目录中发现也有这样一个文件。同时在宿主机中创建了world.txt文件,进入容器后也可以看到该文件。
我们也可以将多个容器中的一个目录挂载在宿主机的同一个目录下,这样就可以在容器间共享数据了。
多个容器共享数据,我们可以将它们挂载在同一个目录,如果创建比较多的容器的话,这种方式操作还是比较麻烦的。另一种方法就是创建一个数据卷容器,在运行这个容器时将目录挂载在宿主机上,在启动其它容器时我们可以使用–volumes-from并指定数据卷容器来共享数据。
--volumes-from list Mount volumes from the specified container(s) 从一个特殊的容器中挂载数据卷 # 例如 也可以指定多个目录 docker run -id --name volume-container -v /home/data:/usr/local/data centos docker run -id --name volume-des1 --volumes-from volume-container centos
如上图所示,先使用命令创建了一个数据卷容器,将容器中/usr/local/data挂载到宿主机的/home/data中,然后创建了三个容器并指定了数据卷容器。可以看到在数据卷容器的/usr/local/data目录下创建文件,其它几个容器都是可以共享数据的。
如果删除了挂载地容器,数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载它的容器时显式使用docker rm -v命令来指定同时删除关联地容器。
步骤如下:
搜索mysql镜像
docker search mysql
拉取mysql镜像
docker pull mysql:5.7
运行容器设置端口映射
# 创建mysql目录用于存储mysql数据 mkdir ~/mysql cd ~/mysql
docker run -id -p 3307:3306 --name c_mysql -v ~/mysql/conf:/etc/mysql/conf.d -v ~/mysql/LOGs:/logs -v ~/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
参数说明:
-p 3307:3306 将容器的3306端口映射到宿主机的3307端口。
-v 挂载目录
-e MYSQL_ROOT_PASSWORD=123456 初始化root密码
运行容器后,可以进入容器使用Mysql客户端连接mysql查看。
docker exec -it 容器ID /bin/bash mysql -uroot -p
也可以使用navicat等工具来连接mysql:
搜索tomcat镜像
docker search tomcat
docker pull tomcat # 直接拉取最新版
# 创建tomcat目录用于存储tomcat数据信息 mkdir ~/tomcat cd ~/tomcat
docker run -id --name c_tomcat -p 8080:8080 -v ~/tomcat:/usr/local/tomcat/webapps tomcat
docker pull nginx # 直接拉取最新版
mkdir -p ~/nginx/conf cd ~/nginx/conf vim nginx.conf # 在~/nginx/conf下创建nginx.conf配置文件,将下面的内容黏贴到nginx.conf中 ---------------------------------------------------------------- user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; }
docker run -id --name=c_nginx -p 80:80 -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v ~/nginx/conf/logs:/var/log/nginx -v ~/nginx/conf/htML:/usr/share/nginx/html nginx
拉取redis镜像
docker pull redis # 直接拉取最新版
docker run -id --name c_redis -p 6379:6379 redis
使用外部机器连接redis
redis-cli -h 宿主机ip -p 6379
常用地创建镜像的方式有两种,分别是:将容器提交为一个镜像、使用Dockerfile创建镜像。
首先先思考几个问题: Docker 镜像本质是什么?Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB
首先先思考几个问题:
操作系统的组成部分:
Linux文件系统由bootfs和rootfs两部分组成
不同的linux发行版,bootfs基本一样,而rootfs不同,如ubuntu,centos等。
Docker镜像是由特殊的文件系统叠加而成,最底端是 bootfs,并使用宿主机的bootfs ,第二层是 root文件系统rootfs,称为base image,然后再往上可以叠加其他的镜像文件。
联合文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器
因此上面思考的答案是:
Docker 镜像本质是什么? :是一个分层的文件系统 Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G? : Centos的ISO镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层 Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB : 由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的tomcat镜像大小500多MB
Docker 镜像本质是什么?
:是一个分层的文件系统
Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?
: Centos的ISO镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层
Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB
: 由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的tomcat镜像大小500多MB
我们可以将一个容器转为一个镜像。也可以将一个镜像生成一个本地的压缩文件,在1.6节已经介绍。
我们从远程仓库拉取的官方的ubuntu系统是很纯净的,里面去除了很多不必要的软件,甚至连sudo命令的没有。我们可以运行一个从官网拉取的镜像,并在容器中安装vim、GCC、make等工具,然后将该容器提交为一个镜像。那么之后根据这个镜像运行新的容器时,容器中就会有这些工具了。
docker commit 容器名 或 ID 生成的镜像标签 # 例如 docker commit ubuntu1 myubuntu:lastest
Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义的镜像。Dockerfile一般由一行行指令组成,并且支持以#开头的注释行;每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像;对于开发人员:可以为开发团队提供一个完全一致的开发环境;对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作了;对于运维人员:在部署时,可以实现应用的无缝移植;
一般而言,Dockerfile主体内容分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
Dockerfile相关命令:
Dockerfile构建命令:
docker build -f ./Dockerfile -t myimage . # -f 参数用于指定dockerfile的位置,如果在当前目录下切名字为Dockerfile,也可以不指定 # -t target 用于指定生成的镜像名 # .为构建的目录
写了一个简单的springboot程序:
可以在浏览器中访问的到:
构建步骤:
1.将项目打包为jar文件,并上传到linux的一个目录下,例如/home/mgh/docker_springboot文件下:
mkdir ~/docker_springboot
2.创建Dokcerfile文件:
vim Dockerfile
3.写Dockerfile:
dockerfile 内容如下
# 由于springboot项目依赖java jdk,因此需要有jdk的环境。也可以是ubuntu或centos,但是其中没有java环境,还需要安装 FROM java:8 # 作者信息,也可以不要 MAINTAINER author<author@hdu.edu.cn> # 将当前目录下的jar包添加到镜像中,并命名为app.jar ADD springboot_test-0.0.1-SNAPSHOT.jar app.jar # 运行springboot项目 也可以是CMD ["java", "-jar", "app.jar"] CMD java -jar app.jar
4.构建镜像:
docker build -t springboot_test .
5.构建成功
6.运行容器
docker run -id -p 8080:8080 springboot_test
7.在浏览器中访问
1.创建目录、写一个helloworld程序
mkdir ~/cpp_docker vim hello.cpp
程序如下,每隔一秒打印一次hello,world
#include <iostream> #include <unistd.h> using namespace std; int main() { while(1) { cout << "hello,world!" << endl; sleep(1); } return 0; }
2.创建Dockerfile文件并写入
vim Dockerfile # 内容如下: # 基础镜像 FROM ubuntu:18.04 MAINTAINER author<author@hdu.edu.cn> # 设置环境变量 ENV MYPATH /usr/local/test # 设置工作目录,设置工作目录后,启动容器,容器所在目录就是工作目录 WORKDIR $MYPATH # 将当前文件夹下的cpp文件拷贝到工作目录 COPY hello.cpp $MYPATH # 安装g++ 以及 编译cpp文件。也可以将这三个命令分开写成三条,但是会生成三层,所以不建议 # 在安装软件的时候,系统可能会让你输入y或n来同意或拒绝安装,使用-y参数就是同意安装。不然可能会失败。 RUN apt-get update && apt-get -y install g++ && g++ hello.cpp -o hello # 容器启动时执行的命令 CMD ["./hello"]
3.构建镜像
docker build -t cpp_test .
4.运行容器
docker run -it cpp_test
可以看到容器中在打印hello,world。但是退出不了了,可以使用docker stop将这个容停止。
将使用gin框架的一个web程序构建为docker镜像:
1.golang代码:
package main import ( "github.com/gin-gonic/gin" "net/http" ) func main() { engine := gin.Default() engine.GET("/jige", func(context *gin.Context) { data := map[string]interface{}{ "name" : "kunkun", "age" : 23, "hobby" : "sing jump rap", } context.JSON(http.StatusOK, data) }) engine.Run("0.0.0.0:8080") }
go.mod
go mod init go mod tidy
2.将程序打包上传到linux的一个文件中
mkdir ~/docker_golang #程序文件名 gin_json
3.创建Dockerfile
vim Dockerfile # dockerfile内容如下 # 基础镜像 FROM golang MAINTAINER author <author@hdu.edu.cn> # 设置环境变量 ENV GO111MODULE on # 设置golang代理否则下载gin框架很可能会失败 ENV GOProxy https://goproxy.cn # 设置工作目录 WORKDIR /go/src/gin_json/ # 把当前目录下所以文件拷贝到容器的工作目录 COPY . . # 安装gin框架依赖 RUN go mod tidy # 容器启动运行程序 CMD go run main.go
4.构建镜像
docker build -t gotest .
5.运行容器
docker run -id -p 9090:8080 gotest
6.浏览器访问页面
以上是脚本宝典为你收集整理的Docker学习笔记——Docker基础全部内容,希望文章能够帮你解决Docker学习笔记——Docker基础所遇到的问题。
如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。