一、Docker入门
镜像与容器概念?
用重装系统来解释的话,镜像(images)就是我们要装的系统(win7、win10、manjaro 等 iso 文件),容器好比是 U 盘。我们可以把系统放进各种容量足够的 U 盘里,那么这个 U 盘就是一个容器,当我们需要重装系统的时候,就使用(启动)这个 U 盘(容器)。
因此,一个镜像可以去创建多个容器,各个容器之间互不干扰。
Q:docker 拉取的镜像为什么比我们直接下载的文件体积大?
A:一个镜像不仅仅是原来的软件包,它还包含了软件包运行所需的操作系统依赖、软件自身依赖等。所以随着我们的使用,使用的镜像越多,新的镜像下载会越来越快,因为有些依赖已经存在,后续的镜像如果对存在的依赖有使用的话,它会复用已经存在的依赖,而不会去再次下载。
二、准备
为了避免使用普通用户运行 docker 的相关命令时出现报错,我们可以在docker命令前加上sudo去运行,但是每次都加显然很麻烦。那么在安装完docker后,可以使用以下命令:
1 | # 创建 docker 用户组 |
镜像源配置
有两种方法修改镜像源,一种是命令行命令,另一种是修改相关文件。
1. 命令行设置国内镜像源
1 | dockerd --registry-mirror=https://hub-mirror.c.163.com |
2. 编辑配置文件设置镜像加速
1 | { |
设置完毕重启 docker 服务。
1 | systemctl restart docker |
加速源 | url | 说明 |
---|---|---|
Docker 官方提供 | https://registry.docker-cn.com | 无需注册,已关闭,无法使用 |
中科大 | https://docker.mirrors.ustc.edu.cn/ | 无需注册(推荐)暂时无法使用,留意官网通告 |
阿里云 | 登录阿里云的容器hub服务,镜像加速器那一栏里会为你独立分配一个加速器地址 | 需要注册 |
网易云 | https://hub-mirror.c.163.com | 无需注册 |
三、常用命令
1 | # 镜像操作 |
以上的 name/id 均指容器创建时指定的名称或者容器的标识id(docker ps可以查看).
接下来以 MySQL 为例来体会一下docker,使用之前确定网络连接良好。
1 | # 查找docker hub中是否有MySQL镜像,可以去 [docker hub](https://hub.docker.com/) 的官网搜索版本 |
选项 | 说明 |
---|---|
run | 运行一个docker容器 |
–name | 指定容器的名字 mysql8 |
-p 9999:3306 | 设置端口映射:宿主机映射端口:容器运行端口;客户端工具(例如navicat)连接时可以通过 9999 端口进行连接 |
-e MYSQL_ROOT_PASSWORD=123456 | 添加环境变量:初始化root用户的密码为 123456 |
-d | 表示使用守护进程运行,即服务挂在后台运行 |
-v | 数据卷映射,本地目录在前,容器内目录在后。删除容器后,映射的本地目录内容仍然存在 |
–restart=always | 在 docker 服务启动后,自动运行该容器 |
如果已经运行的容器想要设置跟随 docker 服务启动,使用下面的命令
docker update --restart=always name/id
四、Docker进阶
1. Docker为什么提供网络功能?
Docker 允许通过外部访问容器或容器互联的方式来提供网络服务,方便了不同容器间进行通信。一般在使用 docker 网桥(bridge)实现容器与容器通信时,都是站在一个应用角度进行容器通信。
1 | # 查看网桥配置 |
网桥不会自动创建,如果要使用网桥,必须 先创建,再使用; 运行容器时若指定的网桥不存在,那么会导致这个容器运行失败。在容器启动时指定了网桥后,在这个网桥中的所有容器,可以直接使用容器名称与其它容器通信。类似于同一局域网进行联机对战。
1 | docker run -d --name tomcat01 -p 8081:8080 --network ems tomcat:8.0-jre8 |
网络的好处:
- 容器间通信: 容器可以相互通信,无需暴露端口到宿主机。
- 服务发现: 容器可以通过服务名(如 mysql 或 redis)相互发现,而不需要知道对方的 IP 地址或端口号。
- 网络隔离: 不同的服务可以属于不同的网络,从而实现网络隔离和安全性。
2. docker数据卷(volume)
- 数据卷的修改会立即影响到容器;
- 对数据的更新修改,不会影响镜像;
- 数据卷默认一直存在,即使容器被删除
实现容器与宿主机之间数据共享。数据卷就是上面创建mysql时的 -v
指定的映射目录,可以把容器内的数据持久化,这样删除容器时我们不必担心数据丢失。但是注意,这样做外部的改变和容器内部的改变会互相影响。
如果我们希望外部影响内部,但是内部操作不影响外部的话,在创建容器时我们可以这样指定: -v /usr/mysql/data:/var/lib/mysql:ro
,其中 ro
代表只读(read only)。前面的映射目录我们也可以使用数据卷简称,这个简称可以随便起名,例如:-v aa:/var/lib/mysql
,这样docker会自动帮我们创建 aa 存储目录,可以使用 docker volume inspect aa
查看它的路径。
1 | # 查看数据卷 |
五、Dockerfile
如果不清楚 Dockerfile 的相关指令含义,可以查阅官方文档,有清晰的介绍。Dockerfile 文件中的命令必须使用大写,通常以 FROM 指令开始。
下面使用 Dockerfile 创建 Java 镜像在容器运行作为一个简单的 Demo,其实,它也是很简单的。首先创建一个空的文件夹,在空文件夹中创建 DockerFile 文件,编辑:
1 | # 以 openjdk:8-jre 为基础 |
构建自定义镜像:docker build -t demo:1.0 .
,注意最后的 .
不要漏掉。
用自定义镜像启动容器:docker run -d -p 8081:8081 --name demo demo:1.0
六、docker-compose
docker-compose 和 Dockerfile 很相似,都是需要我们写一个文件,文件中按照特定的格式去写一些内容和指令,再使用命令去运行这个文件。一个 docker-compose 对应一个 stack。
和 docker 的不同:docker是面向容器的,而 docker-compose 是面向服务的,这也是两者本质区别。
另外,如果是 Window 系统,安装 Docker for Window 后就包括了 dcoker-compose 工具;如果是 Linux 系统,那么额外需要安装 docker-compose 插件。没错,docker-compose 是 docker 的一个插件。
1. 常用命令
1 | # 查看帮助 |
2. docker-compose.yml示例
1 | version: "3.8" # 4.0以下 |
同一网络中的服务可以使用服务名称进行通信
3. 使用portainer可视化工具
- 下载可视化工具:
docker pull portainer/portainer
- 启动 portanier,需要开放两个端口,8000 为监听服务的端口,9000 为向外部提供服务的端口。
docker -d -p 8000:8000 -p 9000:9000 --name portanier --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
- 浏览器访问 http://localhost:9000
4. 卸载 Docker
1 | sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras |