CentOS 7(使用 yum 进行安装)

# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
# Step 4: 更新并安装Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 5: 设置docker开机自启
sudo systemctl enable docker
# Step 6: 开启Docker服务
sudo service docker start
# 注意:
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。
# vim /etc/yum.repos.d/docker-ce.repo
#   将[docker-ce-test]下方的enabled=0修改为enabled=1
#
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# yum list docker-ce.x86_64 --showduplicates | sort -r
#   Loading mirror speeds from cached hostfile
#   Loaded plugins: branch, fastestmirror, langpacks
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
#   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
#   Available Packages
# Step2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)
# sudo yum -y install docker-ce-[VERSION]

Docker 进程相关命令

  • 启动docker服务:
systemctl start docker 
  • 停止docker服务:
systemctl stop docker 
  • 重启docker服务:
systemctl restart docker 
  • 查看docker服务状态:
systemctl status docker 
  • 设置开机启动docker服务:
systemctl enable docker

Docker 镜像相关命令

  • 查看镜像: 查看本地所有的镜像
docker images 
# 查看所用镜像的id 
docker images –q 
  • 搜索镜像:从网络中查找需要的镜像
docker search 镜像名称 
  • 拉取镜像:从Docker仓库下载镜像到本地,镜像名称格式为 名称:版本号,如果版本号不指定则是最新的版本。 如果不知道镜像版本,可以去docker hub 搜索对应镜像查看。
docker pull 镜像名称 
  • 删除镜像: 删除本地镜像
# 删除指定本地镜像 
docker rmi 镜像id 
# 删除所有本地镜像
docker rmi `docker images -q`

Docker 容器相关命令

  • 查看容器
# 查看正在运行的容器 
docker ps
# 查看所有容器
docker ps –a
  • 创建并启动容器
docker run 参数 
  • 参数说明:
  -i:保持容器运行。通常与 -t 同时使用。加入it这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭。 
  -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用。 
  -d:以守护(后台)模式运行容器。创建一个容器在后台运行,需要使用docker exec 进入容器。退出后,容器不会关闭。 
  -it: 创建的容器一般称为交互式容器,-id 创建的容器一般称为守护式容器 
  --name:为创建的容器命名。
  -p: 端口主机端口与容器端口的映射关系,如配置-p 8888:80代表开放容器端口80并将主机端口8888映射到容器的80端口
  -P:表示开放容器全部端口,并将主机的端口随机与容器端口做映射
  --rm: 表示容器停止后自动删除容器
  –restart:重启策略,always意外关闭之后就会自动重启(开机启动),on-failure可以设置重启次数(on-failure:3表示重启3次),默认no即不会重启
  --net:配置网卡
  • 进入容器
# 退出容器,容器不会关闭 
docker exec 参数
# 进入nginx并打开终端
docker exec -it nginx /bin/bash 
  • 停止容器
docker stop 容器名称 
  • 启动容器
docker start 容器名称 
  • 删除容器:如果容器是运行状态则删除失败,需要停止容器才能删除
docker rm 容器名称 
  • 查看容器信息
docker inspect 容器名称

Docker 容器的数据卷

什么是数据卷

  • 数据卷是宿主机中的一个目录或文件
  • 当容器目录和数据卷目录绑定后,对方的修改会立即同步
  • 一个数据卷可以被多个容器同时挂载
  • 一个容器也可以被挂载多个数据卷

有什么用

  • 容器数据持久化
  • 外部机器和容器间接通信
  • 容器之间数据交换

配置数据卷

  • 创建启动容器时,使用 –v 参数 设置数据卷
docker run ... –v 宿主机目录(文件):容器内目录(文件) ...
  • 注意事项:
  1. 目录必须是绝对路径
  2. 如果目录不存在,会自动创建
  3. 可以挂载多个数据卷

以nginx为例

docker run \
-p 8888:80 \
--name nginx \
-v /Users/wandaren/develop/docker-nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /Users/wandaren/develop/docker-nginx/conf/conf.d:/etc/nginx/conf.d \
-v /Users/wandaren/develop/docker-nginx/log:/var/log/nginx \
-v /Users/wandaren/develop/docker-nginx/html:/usr/share/nginx/html \
-d nginx
# 挂载nginx.conf配置文件
-v /Users/wandaren/develop/docker-nginx/conf/nginx.conf:/etc/nginx/nginx.conf
# 挂载nginx配置文件
-v /Users/wandaren/develop/docker-nginx/conf/conf.d:/etc/nginx/conf.d
#	挂载nginx日志文件
-v /Users/wandaren/develop/docker-nginx/log:/var/log/nginx
# 挂载nginx内容
-v /Users/wandaren/develop/docker-nginx/html:/usr/share/nginx/html
\	shell 命令换行

网络Network

是什么

  • 是Docker对容器网络隔高的一项技术,提供了多种不同的模式供用户使用,选择不同的网络模式来实现容器网络的互通以及彻底的隔离。

为什么需要

  • 容器间的风络隔离
  • 实现部分容器之间的网络共享
  • 管理多个子网下容的ip

能干什么

  • 提供了多种模式,可以定制化的为每个容器指定不同的网络
  • 自定义网络模式,划分不同的子网以及网关、dns等配置
  • 网络互通
    • 实现不同子网之间的网络互通
    • 基于容器名(主机名)的方式在网络内访问

image.png

Dockerfile

Docker 镜像原理


- 进程调度子系统
- 进程通信子系统
- 内存管理子系统
- 设备管理子系统
- 文件管理子系统
- 网络通信子系统
- 作业控制子系统

操作系统组成部分:
Linux文件系统由bootfs和rootfs两部分组成

- bootfs:包含bootloader(引导加载程序)和 kernel(内核)
- rootfs: root文件系统,包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件
- 不同的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 commit 容器id 镜像名称:版本号 
docker save -o 压缩文件名称 镜像名称:版本号 
docker load –i 压缩文件名称

dockerfile

  • Dockerfile 是一个文本文件
  • 包含了一条条的指令
  • 每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像
  • 对于开发人员:可以为开发团队提供一个完全一致的开发环境
  • 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作了
  • 对于运维人员:在部署时,可以实现应用的无缝移植

案例

使用commit构建镜像,修改nginx默认首页内容

# 启动一个临时容器
docker run --rm -d -p 80:80 --name n1 nginx
# 进入临时容器
docker exec -it n1 /bin/bash
# 进入nginx挂载目录
cd /usr/share/nginx/html/
# 修改index.html内容
echo '<h1>hello docker</h1>' > index.html 

image.png

# 使用commit构建镜像
docker commit -a "作者" -m "描述" n1 mynginx:1
# 查看镜像
docker images
# 运行新镜像
docker run -d --rm -p 80:80 --name n2 mynginx:1

image.png

bulid常用命令

#1,先指定当前镜像的基础镜像是什么
FROM openjdk:8

# 2,描述这个镜像的作者,以及联系方式 (可选)
MAINTAINER test<xxx@qq.com>

# 3,镜像的标签信息 (可选 )
LABEL version="1."LABEL description="这是我的第一个 Dockerfile"

# 4,环境变量配置
ENV JAVA ENV dev
ENV APP NAME test-dockerfile

# ENV JAVA ENVdev APP NAME=test-dockerfile


#5,在构建镜像时,需要执行的 shell 命令
RUN Is -al
RUN mkdir /www/dockerfile/test

# 6,将主机中的指定文件复制到容器的目标位置,可以简单理解为 cp 命令
# ADD /www/test/index.html /www/server
ADD ["/www/test","/www/server"]

#7,设置容器中的工作目录,如果该目录不存在,那么会自己创建
WORKDIR /app
# 在设置完工作目录后,执行 pwd 命令,打印的目录就是 /app
RUN pwd

# 8,镜像数据卷绑定,将主机中的指定目录挂载到容器中
VOLUME ["/www/test"]

# 9,设置容器启动后要暴露的端口
EXPOSE 8080/tcp

# CMD 和 ENTRYPOINT 选择其一即可,作用是描述镜像构建完成后,启动容器时默认执行的脚本
# CMD ping 127.0.0.1
# CMD ["sh",'-c","ping 127.0.0.1"]

# ENTRYPONINT ping 127.9.0.1
ENTRYPOINT "sh","-c","ping 127.0.0.1"

拓展命令

  • ARG设置变量命令,ARG命令定义了一个变量,在docker build创建镜像的时候,使用 --build-arg =来指定参数

  • HEALTHCHECK 容器健康状况检查命令

    CMD与ENTRYPOINT的区别
    相同点:
    
    
  • 在整个 Dockerfile 中只能设置一次,如果写了多次则只有量后一次生效

不同点:

  • ENTRYPOINT 不会被运行容器时指定的命令所覆盖,而CMD 会被覆盖
  • 如果同时设置了这两个指令,且 CMD 仅仅是选项而不是参数,CMD 中的内容会作为 ETRYPQINI 的参数(一股不这么)
  • 如果两个都是完整命令,那么只会执行最后一条

#### bulid构建springboot容器并运行

##### 以jar的形式

一个简单的springboot项目,端口默认8080,提供了一个对外访问接口/hello
![image.png](https://cdn.nlark.com/yuque/0/2023/png/8364180/1691635749768-fcca8620-f2c1-4634-afd1-258fec3cf7da.png#averageHue=%231e1f22&clientId=u1e83b879-5788-4&from=paste&height=455&id=u52aa12dc&originHeight=910&originWidth=1774&originalType=binary&ratio=2&rotation=0&showTitle=false&size=176730&status=done&style=none&taskId=uaa3cee78-ae0f-41df-b397-34fb20dd4da&title=&width=887)

```java
package com.example.demo.contorller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description TODO
 * @Version 1.0.0
 * @Date 2023/8/10
 * @Author wandaren
 */
@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(){
        return "hello docker springboot!";
    }
}

# 创建目录
mkdir springboot-docker
cd springboot-docker
# 创建Dockerfile
touch Dockerfile
# 将springboot启动jar拷贝到springboot-docker目录下,jar包与Dockerfile放在同级目录

编写Dockerfile文件内容如下

# 关联基础依赖
FROM openjdk:17

# 将项目jar包拷贝到容器中
ADD *.jar /app.jar

# 配置项目环境变量
ENV APP_OPTS=""
# JVM环境变量
ENV JVM_OPTS="-Duser.tomezone=Asia/Shanghai -Xms128m -Xmx128m"

# 暴露端口,与项目端口对应
EXPOSE 8080

# 设置启动时的命令
ENTRYPOINT ["sh","-c","java $JVM_OPTS -jar /app.jar $APP_OPTS"]

构建与测试

# 最后一个参数为Dockerfile文件路径目录(springboot-docker),.表示同级目录下的Dockerfile
docker build -t springboot-docker:1.0.0 .
# 运行
docker run --rm -d -p 8888:8080 springboot-docker:1.0.0
# 访问http://localhost:8888/hello即可
以war的形式部署到tomcat
  • 使用的是springboot3.1.2,tomcat10.1.11
改造springboot项目
  • 修改打包方式为war,排除springboot自带的tomcat
<!--  修改打包方式为war  -->
<packaging>war</packaging>
<!-- 排除springboot自带的tomcat -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
  </exclusions>
</dependency>

  • 添加servle-api或者tomcat依赖,二选一即可
<!-- servlet依赖 -->
<dependency>
  <groupId>jakarta.servlet</groupId>
  <artifactId>jakarta.servlet-api</artifactId>
  <version>6.0.0</version>
  <scope>provided</scope>
</dependency>

<!-- 这个依赖让你能够在程序入口类:xxxAppAplication中直接执行main方法启动tomcat -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <!-- 但是这里一定要设置为provided -->
    <scope>provided</scope>
</dependency>
  • 修改启动类,继承SpringBootServletInitializer重写configure方法
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
		// 注意这里要指向原先用main方法执行的Application启动类
		return builder.sources(DemoApplication.class);
	}

}
编写Dockerfile,将war拷贝到Dockerfile同级目录下
FROM tomcat:10.1.11

WORKDIR /usr/local/tomcat/webapps

# 拷贝到tomcat并改为ROOT解压之后更方便使用(访问可以不带路径)
ADD *.war ROOT.war

ENTRYPOINT ["sh","-c","../bin/catalina.sh run"]
  • 构建与运行
# 最后一个参数为Dockerfile文件路径目录(/Users/wandaren/tomcat-docker),会自动查找Dockerfile文件
docker build -t javaweb /Users/wandaren/tomcat-docker
docker run -d --rm -P javaweb