1. Docker概述

环境配置十分麻烦,每一个机器都要部署环境(集群Redis、ES、Hadoop….)!容易出错又很麻烦。

Docker的思想类似于集装箱

隔离:Docker的核心思想!打包装箱,每个箱子都是互相隔离的,也就是说不会有端口冲突。

在容器技术出现之前,我们都是使用虚拟机技术。

  • 虚拟机:在windows安装一个Vmware,通过这个软件我们可以虚拟出一台或多台电脑。但过于笨重。
  • 虚拟机也是属于虚拟化技术,Docker容器技术也是一种虚拟化技术。

vm: Linux原生镜像(一个电脑) 隔离:需要开启多个虚拟机。 一般好几G,启动很慢

docker:隔离,镜像十分小巧,运行镜像就可以。 一般就几M、KB,秒级运行。

浅聊Docker

Docker是基于Go语言开发的,是个开源项目。

1.1 Docker解决依赖兼容问题。

  1. 将应用的函数库(libs)、依赖(Deps)、配置与应用一起打包。
  2. 将每个应用放到一个隔离容器去运行,避免互相干扰。

​ 这样打包的应用中,既包含了应用本身,还包含了应用所需要用到的函数和依赖。你不需要单独去安装这些,自然也就不存在兼容问题。

​ 虽然解决了不同应用的兼容问题,但在开发和测试等环节会存在差异,操作系统版本也会不一样,这些问题又该如何解决。

1.2 Docker解决操作系统环境差异

  • 先了解操作系统结构,以Ubuntu操作系统为例。
    • 系统应用:操作系统本身提供的应用、函数库。这些含数据是对内核指令的封装,使用更加方便
    • 系统内核:所有Linux发行版的内核都是Linux,例如CentOS、Ubuntu、Fedora等。内核可以与计算机硬件交互,对外提供内核指令,用于操作计算机硬件。
    • 计算机硬件:例如CPU、内存、磁盘等
  • 应用与计算机交互的流程如下
    1. 应用调用操作系统应用(函数库),实现各种功能
    2. 系统函数库是对内核指令集的封装,会调用内核指令
    3. 内核指令操作计算机硬件
  • Ubuntu和CentOS都是基于Linux内核,无非是系统应用不同,提供的函数库有差异。
  • 如果一个Ubuntu版本的MySQL应用安装到CentOS系统,MySQL在调用Ubuntu函数库时,会发现找不到或不匹配,就报错。
  • Docker解决操作不同系统环境的问题:
    • Docker将用户程序所需要的系统函数库一起打包
    • Docker运行到不同操作系统时,直接基于打包的函数库,借助于操作系统的Linux内核来运行

1.3 小结

  • Docker将应用、依赖、函数库、配置一起打包,形成可移植镜像。
  • 使用沙盒机制,互相隔离。
  • Docker镜像包含完整的运行环境,包含系统函数库,依赖于Linux的内核,可以在任何Linux操作系统上运行。
  • Docker是一个快速交付应用、运行应用的技术,具有以下优势:
    • 程序、依赖、运行环境打包成一个镜像。
    • 隔离
    • 启动、移除可以通过一行命令完成,便捷。

2.Docker安装

环境配置

1、CentOS 7.9

2、FinalShell远程连接

环境查看

1
2
[root@iZf8z970qe30x0djyapgppZ ~]# uname -r
3.10.0-1160.81.1.el7.x86_64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@iZf8z970qe30x0djyapgppZ ~]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 1.卸载旧版本
yum -y remove docker docker-common docker-selinux docker-engine

# 2.需要的安装包
yum install -y yum-utils

# 3.设置镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 更新yum软件包索引
yum makecache fast

# 4.安装docker相关内容
yum install docker-ce docker-ce-cli containerd.io

# 5.启动docker
systemctl start docker

# 6.使用docker version 是否安装成功

# 7.安装镜像
docker run hello-world

# 8.查看镜像
docker images

#9.卸载docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
# /var/lib/docker docker的默认工作路径

阿里云镜像加速

image-20230203170620994

1
2
3
4
5
6
7
8
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://m8gp3q7l.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

底层原理

Docker是怎么工作的?

Docker是一个Client-Server结构的系统,Docker的守护进行运行在主机上。通过Socket从客户端访问!

DockerServer接收到Docker-Client的指令,就会执行这个命令!

Docker为什么比VM快?

1、Docker有着比虚拟机更少的抽象层。

2、Docker利用的是宿主机的内核,vm需要Guest OS.

所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载Guest OS,分钟级别的,而docker是利用宿主机的操作系统,省略了这个复杂的过程,秒级。

Docker的常用命令

帮助命令

1
2
3
docker version  #显示docker的版本信息
docker info #显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help # 万能命令

镜像命令

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

1
2
3
4
5
6
7
8
[root@Jiang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 16 months ago 13.3kB
镜像的仓库源 镜像的标签 镜像的id 镜像的创建时间 镜像的大小

# 可选项
-a, --all #列出所有镜像
-q, --quiet #只显示镜像的id

docker search 搜索镜像

1
2
3
4
5
6
7
[root@Jiang ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 13748 [OK]
mariadb MariaDB Server is a high performing open sou… 5245 [OK]

# 可选项,通过搜索来过滤
--filter=STARS=3000 #搜索出来的镜像就是START大于3000的

docker pull 下载镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 下载镜像 docker pull 镜像名[:tag]
#如果不写tag,默认就是 latest
[root@Jiang ~]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete #分层下载,docker image的核心 联合文件系统
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
688ba7d5c01a: Pull complete
00e060b6d11d: Pull complete
1c04857f594f: Pull complete
4d7cfa90e6ea: Pull complete
e0431212d27d: Pull complete
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709 #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址

#等价
docker pull mysql
docker pull docker.io/library/mysql:latest

# 指定版本下载
[root@Jiang ~]# 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 删除镜像

1
2
3
docker rmi -f 容器id #删除指定容器
docker rmi -f 容器id 容器id #删除多个容器
docker rmi -f $(docker images -aq) # 删除全部容器

容器命令

我们有了镜像才能创建容器,linux,下载一个centos镜像来测试学习

1
docker pull centos

新建容器并启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
docker run [可选参数] image

#参数说明
--name="Name" 容器名字 用来区分容器
-d 后台运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口
-p 容器端口
容器端口
-p 随机指定端口

# 启动并进入容器
[root@Jiang ~]# docker run -it centos /bin/bash
[root@1ab268ef85d9 /]#
[root@1ab268ef85d9 /]# exit #退出容器

列出所有运行中容器

1
2
3
4
# docker ps 命令
-a #当前正在运行+历史运行的容器
-n=? #显示最近创建的容器
-q

退出容器

1
2
exit 	#直接停止容器并退出
CTRL + P + Q #容器不停止退出

删除容器

1
2
3
docker rm 容器id
docker rm -f $(docker ps -aq) #删除所有容器
docker ps -a -q|xargs docker rm #删除所有容器

启动和停止容器

1
2
3
4
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id

常用其它命令

后台启动容器

1
2
docker run -d 镜像名
docker容器使用后台运行,就必须有一个前台进程,docker发现没有应用,就会自动停止。

查看日志

1
2
3
4
docker logs -f -t --tail 
-tf #显示日志
--tail number #显示日志条数
[root@Jiang /]# docker logs -f -t --tail 89d72e29fe43

查看容器中的进程信息

1
2
3
[root@Jiang /]# docker top 89d72e29fe43
UID PID PPID C STIME TTY TIME CMD
root 24370 24349 0 19:06 pts/0 00:00:00 /bin/bash

查看镜像元数据

1
docker inspect 容器id

进入当前正在运行的容器

1
2
3
4
5
6
7
8
9
10
#方式一
docker exec -it 容器id bashShell
[root@Jiang /]# docker exec -it 89d72e29fe43 /bin/bash
[root@89d72e29fe43 /]#
#方式二
docker attach 容器id

区别:
#docker exec 进入容器后开启新的一个终端,可以在里面操作。
#docker attach 进入容器正在执行的终端,不会启动新的进程。

从容器内拷贝文件到主机上

1
docker cp 容器id:容器内路径 目的主机路径

练习

docker安装Nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1.搜索镜像
# 2.下载镜像
# 3.运行测试
[root@Jiang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 13 months ago 141MB
centos latest 5d0da3dc9764 16 months ago 231MB

# -d 后台运行
# --name

[root@Jiang ~]# docker run -d --name nginx01 -p:3344:80 nginx
7d5dbff79a9f660a925c4953346958da268cff77836435483ed63787e1d97d72
[root@Jiang ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d5dbff79a9f nginx "/docker-entrypoint.…" 4 seconds ago Up 4 seconds 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01

# 进入容器
[root@Jiang ~]# docker exec -it nginx01 /bin/bash

每次改动nginx配置文件,都需要进入容器内部,十分麻烦。

可以通过数据卷方式在外部提供一个映射路径,达到在容器修改文件名,容器内部自动修改。

docker装一个tomcat

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@Jiang ~]# docker run -it --rm tomcat:9.0
# 我们之前启动都是后台,停止容器后,容器还可以查到 docker run -it --rm 一般用来测试,用完就删
# 下载再启动。
[root@Jiang ~]# docker pull tomacat
# 启动运行
[root@Jiang ~]# docker run -d -p 80:8080 --name tomcat01 tomcat

# 进入容器
[root@Jiang ~]# docker exec -it tomcat01 /bin/bash

# linux命令少了,没有webapp。
#阿里云镜像原因,默认是最小的镜像,所以不必要的都剔除。
#保证最小可运行的环境。

可视化

  • portainer
1
2
docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • Rancher(CI/CD再用)

什么是portainer?

Docker图形化界面管理工具。提供一个后台面板供我们操作。

Docker镜像讲解

镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包含代码、运行时、库、环境变量和配置文件。