Docker基础用法

Docker基础用法

1、Docker为什么会出现?

一款软件产品必须经过:开发 -> 上线

开发人员负责将应用程序开发制作出来。
运维人员负责上线,配置应用程序。

在这里存在一个问题:开发环境和上线环境不一致;可能会导致,开发人员在自己的电脑上可以正常运行代码,运维人员将服务程序上线到服务器后,由于环境不一致可能会导致运行失败,服务不可用。

如何解决上述问题?

  • 对上线的服务器系统进行环境配置,但环境配置十分麻烦特别是集群部署时,集群中的每一台机器都需要部署环境。
  • 将开发环境和程序代码一起打包到服务器中运行。

Docker就是将开发环境和程序代码一起打包到服务器中运行的技术。

java语言 --> apk程序 --> 发布到应用商店 --> 客户下载apk --> 安装使用(必须要有环境才能安装成功)

java语言 --> jar环境 --> 打包项目和环境(镜像) --> 上传到docker仓库(商店) --> 下载仓库中的镜像 --> 运行使用

2、Docker介绍

Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

docker_logo.jpg

Docker的核心思想就是来自集装箱;集装箱的概念是隔离货物,所以docker的核心就是隔离机制。同时docker使用可移植镜像所以部署以及运维极其方便快捷。

2.1 Docker发展史

2010年,几个热爱IT的年轻人,在美国成立了一家公司叫做dotCloud,主要做一些Paas的云计算服务和LXC有关的容器技术赚钱盈利,他们将自己的容器技术命名为Docker!

Docker刚刚诞生的时候,并没有引起行业的注意!这个时候 dotCloud公司难以在行业中存活,所以这几个年轻人选择开放Docker源代码来引起注意!

2013年,Docker开源!越来越多的人发现docker的优点,救火了,docker每个月都会更新一个版本!

2014年4月9日,Docker1.0发布!

Docker为什么这么火?十分的轻巧

在容器技术出来之前,我们都是使用虚拟机技术!
虚拟机:在window中装一个Vmware,通过这个软件我们可以虚拟出来一台或者多台电脑!(很笨重)
虚拟机也是属于虚拟化技术,Docker容器技术,也是一种虚拟化技术!

vm:隔离,需要开启多个虚拟机!linux centos原生镜像(一个电脑!)需要几个G内存空间,开启需要几分钟!
docker:隔离,镜像(最核心的环境4m内存)十分的小巧,运行镜像就可以了!小巧!几个M或KB的内存空间,秒级启动!

2.2 容器和虚拟机的区别

虚拟机:通过虚拟化技术模拟真实的硬件从而创建出来的一台拥有完整功能的逻辑计算机。

Docker容器:docker容器也是一种虚拟化技术,和传统虚拟化不一样的是docker只模拟一个程序最核心的运行环境,所以十分小巧,启动更快。

Docker虚拟化技术和传统虚拟化技术架构对比:
vm_vs_docker.png

对比 特点
虚拟机 完整的系统功能,隔离性更好,占用空间大(通常以G为单位),运行占用资源较多,启动慢(分钟级启动)
容器 只有程序运行的核心环境,不需要安装直接运行镜像即可,隔离性一般,十分小巧占用空间极小(一般以M为单位),启动快(秒级启动)

2.3 Docker引擎架构

Docker 引擎(Docker Engine)是目前主流的容器引擎;Docker 引擎是一个包含以下组件的客户/服务器 架构的应用程序,如图所示:

Docker引擎组成:
docker_engine.png

  • 服务器:即Docker守护进程(Daemon),这是 Docker 的后台应用程序,可使用 dockerd 命令 进行管理。Docker守护进程监听来自Docker API的请求,可用于创建和管理 Docker对象,如镜 像、容器、网络和卷。一台主机运行一个 Docker守护进程。
  • REST API:定义程序与 Docker守护进程交互的接口,便于编程操作 Docker 平台和容器。REST API是一套目前比较成熟的Internet 应用程序 API架构
  • 客户端:即命令行接口(Command-Line Interface,CLI),可使用 docker 命令进行操作。命令 行接口又称命令行界面,可以通过命令或脚本使用 Docker 的REST API 接口来控制Docker守护进 程,或者与Docker守护进程进行交互。当用户使用 docker run 这样的命令时,客户端将这些命令 发送到Docker守护进程来执行。Docker客户端可以与多个 Docker守护进程进行通信。许 多 D o c k e r 应 用程序都会使用底层的 API和命令行接口。

2.4 Docker 架构

Docker运行架构:
docker_framework.png

  • Docker客户端与 Docker守护进程通信,而Docker守护进程相当于Docker服务器,负责构建、运 行和分发容器的繁重任务。Docker客户端与守护进程可以在同一个系统上运行,也可以让 Docker 客户端连接到远程主机上的 Docker守护进程。Docker客户端和守护进程使用REST API通过UNIX 套接字(Socket)或网络接口进行通信。D o c k e r守护进程和 Docker客户端属于 Docker 引擎的 一部分。
  • Docker 注册中心用于存储和分发 Docker 镜像。Docker Hub和 Docker Cloud 是任何人都可以使 用的公开注册中心,默认情况下,Docker守护进程会到Docker Hub中查找镜像。除此之外,用户 还可以运行自己的私有注册中心。

2.5 Docker底层技术

  • 名称空间(Namespace):又 称命名空间,Linux 的名称空间机制提供了一种资源隔离的解决方 案。Docker 通过名称空间机制为容器提供隔离的工作空间,运行容器时,Docker会为该容器创建 一系列的名称空间
  • 控制组(Control Group):Linux 可以通过控制组设置进程使用 CPU、内存和I/O资源的限额, Linux 上的 Docker 引擎正是依赖这种底层技术来限制容器使用的资源
  • 联合文件系统(Union File System,UnionFS):这是为 Linux、FreeBSD 和NetBSD 操作系统设 计的一种文件系统,可以将其他文件系统合并到一个联合挂载点。作为轻量级的高性能分层文件系 统,联合文件系统支持将文件系统中的变更信息进行提交。联合文件系统是实现 Docker 镜像的 技术基础,Docker 镜像可以通过分层来实现继承
  • 容器格式(Container Format):Docker 引擎将名称空间、控制组和联合文件系统打包到一起所 使用的就是容器格式。默认的容器格式是 Libcontainer。Docker 将来还可能会通过集成FreeBSD Jails或Solaris Zones 来支持其他的容器格式

2.6 Docker优势

Docker优势:

  • 应用程序快速、一致地交付
    • 开发人员在本地编写应用程序代码,通过Docker与同事进行共享。
    • 通过Docker将应用程序推送到测试环境中,执行自动测试和手动测试。
    • 开发人员发现程序错误时,可以在开发环境中进行修复,然后重新部署到测试环境来进行测试和验证。
    • 完成应用程序测试之后,向客户提供补丁程序非常简单,只需将更新后的镜像推送到生产环境中。
  • 响应式部署和伸缩应用程序
  • 更简单的系统运维
    • 在容器化之后,我们的开发,测试环境都是高度一致的!
  • 更高效的计算资源利用
    • Docker是内核级别的虚拟化,可以再一个物理机上可以运行很多的容器实例!

2.7 Docker 名词解释

镜像(image):
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像=>run=>tomcat1容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。

容器(container):
Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的。
启动,停止,删除,基本命令!
目前就可以把这个容器理解为就是一个简易的linux系统

仓库(repository):
仓库就是存放镜像的地方!
仓库分为公有仓库和私有仓库!

2.8 Docker中的容器

  • lxc –> libcontainer –> runC

OCI&OCF

OCI

Open Container-initiative

  • 由Linux基金会主导于2015年6月创立
  • 旨在围绕容器格式和运行时制定一个开放的工业化标准
  • 包含两个规格
    • 运行规范(runtime-spec)
    • 镜像规格(image-spec)

OCF

Open Container Format

runC是一个命令行工具,用于根据OCI规范生成和运行容器

  • 容器作为runC的子进程启动,并且可以嵌入到各种其他系统中,而无需运行守护进程
  • runC是建立在libcontainer之上的,libcontainer是一种支持数百万Docker引擎安装的容器技术

docker提供了一个专门容纳容器镜像的站点://hub.docker.com

3、Docker环境部署

# 1.首先配置yum仓库
curl -o /etc/yum.repos.d/CentOS-Base.repo //mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo

# 2.卸载旧的版本
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
                  

# 3.设置镜像的仓库
yum-config-manager \
    --add-repo \
    //download.docker.com/linux/centos/docker-ce.repo # 默认是从国外的。
yum-config-manager \
    --add-repo \
    //mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 推荐使用阿里云的。
    
# 4.安装容器相关的。docker-ce(社区版)docker-ee(企业版)
yum install docker-ce 

# 5.启动docker服务并设置开机自启
systemctl start docker
systemctl enable docker
# 6.使用docker version查看是否安装成功
docker version

# 7.测试hello-world
docker run hello-world

# 8.查看一下,下载的这个hello-world镜像

docker加速

docker-ce的配置文件是/etc/docker/daemon.json,此文件默认不存在,需要我们手动创建并进行配置,而docker的加速就是通过配置此文件来实现的。

docker的加速有多种方式:

  • docker cn
  • 中国科技大学加速器
  • 阿里云加速器

阿里云加速器使用方法

打开浏览器,访问阿里云官网

登录之后点击右上角控制台,在点击左上角产品与服务

弹性计算里找到容器镜像服务

在/etc/docker目录下新建文件daemon.json将加速器地址写入

mkdir -p /etc/docker
vim /etc/docker/daemon.json
{
"registry-mirrors": ["//此处地址为自己阿里云镜像加速地址.mirror.aliyuncs.com"]
}

重启服务

systemctl daemon-reload
systemctl restart docker

了解:卸载docker

# 1.卸载依赖
yum remove docker-ce 

# 2.删除资源
rm -rf /var/lib/docker
rm -rf /var/lib/containerd

# /var/lib/docker  docker的默认工作路径

4、Docker的常用命令

4.1 帮助命令

docker version         # 显示docker的版本信息
docker info           # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help      # 帮助命令

4.2 镜像命令

docker images 查看所有本地的主机上的镜像

[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    feb5d9fea6a5   10 months ago   13.3kB
# 解释
REPOSITORY     //镜像的仓库源
TAG          //镜像的标签
IMAGE ID       //镜像的id
CREATED        //镜像的创建时间
SIZE          //镜像的大小
# 命令参数可选项
 -a, --all         # 显示所有镜像 (docker images -a)
 --digests 		      #显示镜像的摘要信息(docker images --digests)
 -q, --quiet        # 仅显示镜像id (docker images -q)

docker search 搜索镜像

[root@localhost ~]# docker search mysql
NAME      DESCRIPTION                            STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   12966     [OK]       
......
# 解释
NAME			   //镜像仓库源的名称
DESCRIPTION		//表示该镜像的功能
STARS			   //表示下载热度
OFFICIAL		  //是否docker官方发布
AUTOMATED		  //自动构建
# 命令参数可选项 (通过搜索来过滤)
--filter=STARS=3000     # 搜索出来的镜像就是stars大于3000的
[root@localhost ~]# docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…             12966      [OK]       
mariadb   MariaDB Server is a high performing open sou…              4966      [OK]       

docker pull 下载镜像

# 下载镜像:docker pull 镜像名[:tag]
[root@localhost ~]# docker pull mysql
Using default tag: latest						#如果不写tag,默认就是latest,最新的版本
latest: Pulling from library/mysql
32c1bf40aba1: Pull complete 				 # 分层下载,docker image的核心,联合文件下载
3ac22f3a638d: Pull complete 
b1e7273ed05e: Pull complete 
20be45a0c6ab: Pull complete 
410a229693ff: Pull complete 
1ce71e3a9b88: Pull complete 
c93c823af05b: Pull complete 
c6752c4d09c7: Pull complete 
d7f2cfe3efcb: Pull complete 
916f32cb0394: Pull complete 
0d62a5f9a14f: Pull complete 
Digest: sha256:ce2ae3bd3e9f001435c4671cf073d1d5ae55d138b16927268474fc54ba09ed79
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest			# 真实地址

# 指定版本下载
[root@localhost ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Already exists        # 联合文件下载,已经存在的资源可以共用
93619dbc5b36: Already exists
99da31dd6142: Already exists
626033c43d70: Already exists
37d5d7efb64e: Already exists
ac563158d721: Already exists
d2ba16033dad: Already exists
0ceb82207cd7: Pull complete
37f2405cae96: Pull complete
e2482e017e53: Pull complete
70deed891d42: Pull complete
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

docker rmi 删除镜像

[root@localhost ~]# docker rmi -f 镜像id              # 删除指定的镜像
[root@localhost ~]# docker rmi -f 镜像id 镜像id 镜像id    # 删除多个镜像(空格分隔)
[root@localhost ~]# docker rmi -f $(docker images -aq)    # 删除全部的镜像

docker inspect 获取镜像的详细信息

[root@localhost ~]# docker inspect 镜像名:标签

docker tag 添加镜像别名,类似于别名

[root@localhost ~]# docker tag 镜像名:标签 新镜像名:新标签

# 示例:
[root@localhost ~]# docker tag mysql:5.7 mysql:alone
[root@localhost ~]# docker images 
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
mysql        5.7      3147495b3a5c   8 days ago      431MB
mysql        alone     3147495b3a5c   8 days ago      431MB

4.3 容器命令

说明:我们有了镜像才可以创建容器,下载一个centos 镜像来测试学习。

docker pull centos

容器创建命令

docker create 创建新容器

[root@localhost ~]# docker create 镜像名

# 示例:
[root@localhost ~]# docker create centos
1f8c0d836c2751fd39b46922d256505626925a7519154e2d0b811ede561bb097
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS    PORTS     NAMES
1f8c0d836c27   centos    "/bin/bash"   10 seconds ago   Created             jovial_chaum

docker run 容器创建并运行

docker run [可选参数] image
# 参数说明
--name="name"        容器名字:用来区分容器
-d                    后台方式运行:相当于nohup
-it                    使用交互式运行:进入容器查看内容
-p                    指定容器的端口(四种方式)小写字母p
    -p ip:主机端口:容器端口
    -p 主机端口:容器端口
    -p 容器端口
    容器端口
-P                     随机指定端口(大写字母P)

#使用centos镜像启动一个名为centos0的容器
[root@localhost ~]# docker run --name centos0 centos

# 使用centos镜像启动容器并分配一个bash shell的终端进入容器
[root@localhost ~]# docker run -it centos /bin/bash
[root@6c39cc898c6c /]# ls		 # 查看容器内的centos(基础版本,很多命令都是不完善的)
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@6c39cc898c6c /]# exit
exit
# 注意:
1.指定-it选项为容器分配shell后,启动容器时运行的命令将会被shell替代
2.不加-d选项的容器一旦使用exit退出容器shell,容器就终止运行;ctrl+p+q可以退出shell,容器仍将继续运行

# 使用 mysql镜像启动一个名为 mysql1的容器并在后台运行
[root@localhost ~]# docker run --name mysql1 -d mysql
867c0734a5f21ae1fb607f5cdf2eb03bb4494eb5dc1056caa164689d0a2dc76f

#使用 mysql镜像启动一个名为 mysql2的容器,该容器在后台运行,访问宿主机的8080端口可以访问到容器的80端口
[root@localhost ~]# docker run --name mysql2 -d -p 8080:80 mysql
c07b515d0041fbb6905990c9377971fd0353cdb63e1adb80f5f05648d850baf8

容器查看命令

docker ps 查看容器运行状态

# 选项:
-a 			//显示所有的容器,包括未运行的
-q			//只显示容器id
-l			//显示最近创建的容器。
-f "筛选条件"		//根据条件过滤显示的内容

# 示例:
示例:
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE        COMMAND    CREATED          STATUS           PORTS     NAMES
c8af463c6e52   hello-world   "/hello"   14 seconds ago  Exited (0) 13 seconds ago     strange_cartwright

# 解释
CONTAINER ID		 //容器 ID
IMAGE			     //使用的镜像
COMMAND			   //启动容器时运行的命令
CREATED			   //容器的创建时间
STATUS			  //容器状态
# 容器状态有7种:
	created(已创建)
	restarting(重启中)
	running(运行中)
	removing(迁移中)
	paused(暂停)
	exited(停止)
	dead(死亡)
PORTS			//容器的端口信息和使用的连接类型(tcp\udp)。
NAMES			//容器名称

docker inspect 查看容器详细信息

# 示例:
[root@localhost ~]# docker inspect test
......略........

容器删除命令

docker rm 删除容器

docker rm 容器名			//删除容器,无法删除运行状态下的容器
选项:
-f				//强制,可以删除运行状态下的容器

# 示例:
//删除mysql1容器
[root@localhost ~]# docker rm nginx01
mysql1

//批量删除所有容器
[root@localhost ~]# docker rm $(docker ps -qa)
9b2fa686b4ae
a4f41fb35ac3

容器生命周期管理命令

docker start   容器名	//开启容器
docker stop    容器名	//停止容器
docker kill    容器名	//杀死容器
docker restart  容器名	 //重启容器
docker pause   容器名	//暂停容器中所有的进程
docker unpause  容器名	 //恢复容器中所有的进程

容器占用资源查看命令

docker stats  容器名	//查看容器使用资源信息
docker top    容器名	//查看容器中运行的进程信息,支持ps命令参数
docker port   容器名	//查看宿主机端口和容器端口之间的端口映射

容器日志查看命令

# 当容器创建失败时,因为容器没有启动成功则无法看到错误日志,无法判断问题所在,下面命令可以查看日志,不管容器时候启动成功

docker logs   容器名	//获取容器的日志信息
选项:
-f			//跟随打印最新的日志追加在最后面
-t			//显示日志打印的时间戳
--tail 数量		//只显示最新的指定数量的几条日志信息

容器内进程连接和命令执行

docker attach 连接到正在运行的容器进程中,默认连接到容器启动时启动的进程

# 连接到httpd03容器中的nginx进程,此时可以看到httpd03工作日志
[root@localhost ~]# docker attach httpd03
172.17.0.1 - - [04/Aug/2022:09:06:29 +0000] "GET / HTTP/1.1" 304 -
# 注意:使用attach连接到容器容器进程,一旦终止容器内的进程,容器就终止运行

# 如果容器启动时运行的命令是shell进程,则连接shell终端
[root@localhost ~]# docker attach httpd04
root@6b830320e24a:/usr/local/apache2# exit
exit

docker exec 不进入容器执行容器中的命令

# docker exec 容器名 执行命令	
选项:
-d				//后台执行,不显示结果
-it				//为容器分配一个始终运行的伪终端,需要指定shell;-i保持运行状态,-t是分配伪终端

# 示例:
#不进入容器执行容器中的ls命令
[root@localhost ~]# docker exec httpd04 ls			
bin
build
cgi-bin
......

# 使用docker exec命令打开一个shell进入到容器中,使用exit退出shell,容器也不会终止运行
[root@localhost ~]# docker run --name httpd05 -it -d httpd /bin/bash	
1b656ba8a5b5689c0b2e688537358779964a9e43f174ce3ab5ff7196dac4e402
[root@localhost ~]# docker exec -it httpd05 /bin/bash
root@1b656ba8a5b5:/usr/local/apache2# exit
exit

注意:

# docker exex # 进入容器后开启一个新的终端,可以再里面操作(常用)

# docker attach # 进入容器正在执行的终端,不会启动新的进程。

5、docker event state

Tags: