Ubuntu上docker安装
UBUNTU 20.04 LTS 安装 DOCKER看高博主的博文,一键复制命令安装即可。
docker命令
docker version
查看你docker版本信息
docker info
显示docker系统级别的信息
docker --help
docker命令查询
docker docs的referrence介绍了docker的详细命令
镜像操作
docker images
镜像命令
docker search
搜索镜像
docker pull
下载镜像
docker pull [镜像名或Id][:tag]
下载指定镜像
镜像是一种分层结构,逐层构建。镜像之间存在明显的层次结构。不同的镜像累积起来完成共同的任务。镜子的叠加是连续的。
例如使用docker引擎构建一个tomcat环境,需要先构建ubuntu或者centos镜像,在再该镜像上构建jdk环境,再构建tomcat环境。构建mysql也是如此,实际上docker镜像的层次分化的更细,从下载的过程也能看出来,是层次下载的。
先下载了mysql最新版,然后再下载mysql5.7版,之前的镜像下载好了无需再下载,只需要下载mysql5.7的部分即可。
docker rmi
删除镜像
容器命令
下载完镜像后需要根据镜像配置自定义的容器,用于运行定制化的服务,基于镜像构建容器的命令是docker run
。
该命令参数较多,比较复杂。请前往官方网站查看。
docker log
查看容器内部日志
docker top
查看容器内部镜像进程
docker exec
在正在运行的容器操作命令
docker attach
连接后台运行的docker容器并进入。
docker cp
克隆容器数据到主机
镜子阉割
有时候在构建mysql镜像的时候,深入Linux底层,发现很多命令都被阉割了,只支持运行服务的最小内核。该镜像仅用于部署。
数据同步
Docker是一个相对封闭的空间,需要通过端口映射来访问。通过docker部署引用,必然需要上传文件到docker内部。然而,docker只是主机上的一个服务。显然,容器内部不存在上传文件的情况。
docker中有数据卷的概念,是docker服务的专属文件夹。 docker服务的数据使用该文件夹的内容,该文件夹和docker内部的数据同步修改。简单来说,就是为docker服务配置一个专门的目录,docker服务使用和产生的数据都会保存在这里。
docker run -v [主机目录:容器目录]
命令实现。
需要注意的是,只能挂载到文件夹上,不能挂载到文件上。因此,如果需要挂载某个文件夹中的多个文件之一,则需要提前在主机上创建一个新文件。
-v [主机文件夹]:[容器文件或文件夹]
主机只能是文件夹,容器是文件时就会同步到主机文件夹下,是文件夹是会同步两个文件夹。
# 不然会报错如下
docker: Error response from daemon: failed to create task for container: failed to create
shim task: OCI runtime create failed: runc create failed: unable to start container
process: error during container init: error mounting "/home/docker-volumes/nginx/conf" to
rootfs at "/etc/nginx/nginx.conf": mount /home/docker-
volumes/nginx/conf:/etc/nginx/nginx.conf (via /proc/self/fd/6), flags: 0x5000: not a
directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check
if the specified host path exists and is the expected type.
也有路径错误和主机路径错误的情况,如下:
映射路径为/home/docker-volumes
但是实际却是/home/xwh
。
由于nginx.conf是文件,其他两个都是目录,所以需要现在目录下新建文件
docker run -id --name nginx-proxy -p 80:80
-v /home/xwh/docker-volumes/nginx/html:/usr/share/nginx/html
-v /home/xwh/docker-volumes/nginx/nginx.conf:/etc/nginx/nginx.conf
-v /home/xwh/docker-volumes/nginx/conf.d:/etc/nginx/conf.d
nginx
这个命令本身没有问题,但是如果没有新建文件就会报错,conf.d和html都是文件夹,nginx.conf是文件。
虽然号出来了,但还是没有开始。原因是niginx.conf有问题,如下。
要将卷挂载到 nginx,首先必须有一个配置文件才能挂载。具体方法是正常启动一个nginx容器,不挂载卷,然后从cp复制一个配置文件,删除容器,然后重新挂载。启动一个新容器作为加载卷。
解决方案:
- 不要挂在数据卷上生成容器,目的是生成配置文件
成功运行,如下
2. 将容器生成的配置文件copy到主机
先停掉容器将容器的nginx.conf克隆到主机到主机中,查看nginx.conf有正常配置文件即可。
- 重新hook一次,如下
docker run -id --name nginx-proxy -p 80:80 -v /home/xwh/docker-volumes/nginx/html:/usr/share/nginx/html -v /home/xwh/docker-volumes/nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/xwh/docker-volumes/nginx/conf.d:/etc/nginx/conf.d nginx
如上图所示,容器成功运行,nginx服务也启动了。
dockerfile
使用docker拉取镜像后,您可以根据需要自定义镜像,打包镜像,或者上传到docker hub供任何人使用。不过每次输入图片都要自定义图片的DIV,确实很麻烦。
Dockerfile 提供了语法。您可以通过按照一定的语法编写docker镜像来定制它。官方提供了运行dockerfile构建镜像的相关命令。
Dockerfile 由一行命令语句组成,并支持以 # 开头的注释行。 Dockerfile分为四个部分:镜像基本信息、维护者信息、镜像操作指令、容器启动时的执行指令。
操作说明 | 描述 |
---|---|
从 | 指定基本图像信息(镜像是逐层叠加的,但都是在基本图像之上) |
维护者 | 指定维护者信息 |
跑步 | RUN 指令将对镜像执行跟随的命令。每运行一条 RUN 指令,镜像添加新的一层,并提交。格式为:RUN<command> 或 RUN ["executable", "param1", "param2"] 。前者将在 shell 终端中运行命令,即 /bin/sh -c;后者则使用 exec 执行。 |
指令管理系统 | CMD指令指定运行容器时的操作命令。 |
暴露 | 指定Docker服务器容器暴露的端口号 |
工作目录 | 格式为 WORKDIR /path/to/workdir。配置后续 RUN、CMD 和 ENTRYPOINT 指令的工作目录。 |
环境电压 | 格式为:ENV <key> <value> 。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。 |
添加 | 格式为:ADD <src> <dest> ,该命令将复制指定的 <src> 到容器中的 <dest> ,若是压缩包会自动解压 |
复制 | 格式为COPY <src> <dest> 。复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径)到容器中的 <dest> 。 |
入口点 | 配置容器启动后执行的命令,且不能被docker run提供的参数覆盖。 |
体积 | 创建一个可以从本地主机或其他容器挂载的挂载点。一般用于存储数据库和需要维护的数据。 |
用户 | 运行容器时指定用户名或UID,后续的RUN也将使用指定的用户。 |
建设 | 格式为 ONBUILD [指令]。配置将创建的镜像作为其他新建镜像的基础镜像时执行的操作指令。 |
CMD命令与ENTRYPOINT的区别在于前者只对最后一条命令生效,而后者可以执行多条命令。
编写完dockerfile后通过docker build
命令来创建镜像。也可以通过.dockerignore
文件(每一行添加一条匹配模式)来让 Docker 忽略路径下的目录和文件。要指定镜像的标签信息,可以通过-t
选项。
dockerfile构建镜像后就可以发布到docker hub中央仓库了。您需要先注册一个帐户。步骤如下:
docker login -u [username]
docker push [镜像名称]:[tag]
docker tag 命令为镜像设置标签。需要设置标签才能正常提交,否则不会有版本信息。
Dockerfile中EXPOSE
表示将容器的服务运行时监听的端口暴露给外部,此时服务只有docker实例的基础镜像ubuntu或centos上可以访问,docekr服务的宿主机器也访问不了。
docker run -it --name=gowebtest -p 8000:8000 go-web:1.0 bash
通过-p
将服务与主机端口映射才可以。
主机能够访问
镜像服务器
在开发过程中例如java最终会生成一个jar包,那么其他开发者拿到jar包后直接java -jar
就可以运行jar包。但是有前提条件的:
- jdk环境
- 数据库环境
- 中间件环境
如果Java使用jdk11,开发者需要在机器上安装jdk11版本。如果使用mysql8,则需要安装相应版本的mysql。这同样适用于各种中间件。这些都需要严格按照开发环境的配置。不过docker的存在让这些都可以一键配置,而且不会出现版本问题。
比如通过dockerfile编写jdk环境、mysql环境、redis环境生成dockerfile,然后将代码的jar文件和dockerfile打包成镜像。那么任何人拿到镜像后就可以直接构建容器并运行,无需配置任何环境。
docker网络
在主机未安装docker是只有两个网卡,如下,一个是本机地址另一个是内网地址。
本机地址是用来访问本机的网络服务的,例如在本机运行一个tpc服务,或者http的web服务都需要使用本机地址127.0.0.1
,每个机器的主机都是127.0.0.1。内网地址是在同一局域网下区分不同不同主机的,在网络原理是学习了每个电脑都是一个固定的ip实现计算机的通讯,但实际每个电脑有一个固定ip是不现实的,其实只有一个网络有一个固定的ip,也就是一个网线对应一个ip。
连接到同一网线的计算机之间的通信是通过内联网实现的。在统一网络下实现局域网,即以192.168开头的专用网络。由于内网IP由于路由器的作用,是由DHCP服务器自动分配的,所以不再赘述。 ,所以每台电脑都在同一个网络下但是有不同的内网IP,是唯一可以实现通信的。
但主机上启动的dcoker服务只是主机上的一个进程,显然有公网内网IP。不同的服务通过端口来区分。 docker服务通过端口映射实现外部访问。 Docker也可以构建独立的服务。如果docker想要访问网络服务,它需要有自己的IP。没有IP就无法实现网络服务。
docker有自己的网络服务docker0
,实现docekr内部的网络服务,如下
docker内部实现了新的路由机制,是基于B类地址也就是172开头的,该类地址可容纳65535太计算机因此也就意味这台硬件支持的能力下,一台主机可以启动最大这莫多的docker服务。局域网使用C类地址也就是192只能容纳小部分计算机,是计算机默认局域网使用的ip地址。
启动容器时docker网络会自动生成一个B类地址,作为docker服务的专属ip地址,ip之间通过桥接连接。
下载nginx镜像
在docker中提供了--link
来绑定网络实现网络的联通。