Skip to content

Docker

Moby-logo

概述

什么是虚拟化

在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。

在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件   对资源充分利用

虚拟化技术种类很多,例如:软件虚拟化、硬件虚拟化、内存虚拟化、网络虚拟化(vip)、桌面虚拟化、服务虚拟化、虚拟机等等。

什么是Docker

Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production.

容器与虚拟机比较

  • 容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统

  • 传统方式则是在硬件层面实现

  • 与传统的虚拟机相比,Docker 优势体现为启动速度快、占用体积小

docker-containerized-and-vm-transparent-bg

https://www.docker.com/resources/what-container

Docker组件

engine-components-flow

入门

安装

Linux版本安装

bash
sudo dnf install langpacks-en glibc-all-langpacks -y
sudo yum -y erase podman buildah
sudo yum update -y
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum install -y docker-ce  --allowerasing
docker -v

Desktop版本安装

开启Hyper-V

以管理员身份运行 PowerShell

bash
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
系统配置
  • step 1

Desktop-Install-SysConfig-1

  • step 2

Desktop-Install-SysConfig-2

  • step 3

Desktop-Install-SysConfig-3

  • step 4

Desktop-Install-SysConfig-4

  • step 5

Desktop-Install-SysConfig-5

WSL安装

参考微软官方文档安装

https://docs.microsoft.com/zh-cn/windows/wsl/install-win10

Docker Desktop安装
  • step 1

Desktop-Install-Process-1

  • step 2

Desktop-Install-Process-2

  • step 3

Desktop-Install-Process-3

  • step 4

Desktop-Install-Process-4

  • step 5

Desktop-Install-Process-5

配置仓库

  1. 编辑配置文件
  • Linux

    bash
    vim /etc/docker/daemon.json
  • Docker Desktop

    Desktop-Deamon-Config

  1. 修改为如下配置
json
{
  "debug": true,
  "experimental": true,
  "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://cr.console.aliyun.com/",
    "https://registry.docker-cn.com",
    "https://docker.mirrors.ustc.edu.cn"
  ],
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  }
}

配置代理

启动

bash
## 启动docker服务
systemctl start docker

## 重新加载配置文件
systemctl daemon-reload

## 停止docker服务
systemctl stop docker

## 重启docker服务
systemctl restart docker

## 查看docker服务状态
systemctl status docker

## 设置docker服务开机自启动
systemctl enable docker

## 查看docker状态
docker info

## 查看docker帮助
docker --help

快速入门

拉取tomcat镜像

可通过https://hub.docker.com/检索镜像

bash
docker pull tomcat:8.5.68-jdk8

查看镜像是否已经拉取

bash
docker images

通过镜像运行容器

bash
docker run -id --name tomcat -p 8080:8080 tomcat:8.5.68-jdk8

打开浏览器,测试

bash
http://宿主机ip:8080

常用命令

敲docker的任意一个命令,最后--help,就能够查看此命令的详细解释

镜像操作【重点】

  • pull

    docker pull [OPTIONS] NAME[:TAG|@DIGEST]

    从远程仓库中,拉取一个镜像

  • search【不常用】

    docker search [OPTIONS] TERM

    通过命令行方式,检索镜像

  • images

    docker images [OPTIONS] [REPOSITORY[:TAG]]

    列出在本地仓库中的所有镜像

  • rmi

    docker rmi [OPTIONS] IMAGE [IMAGE...]

    删除一个镜像 Options:

    • -f

    强制删除

  • save【了解】

    docker save [OPTIONS] IMAGE [IMAGE...]

    Save one or more images to a tar archive (streamed to STDOUT by default)

  • load【了解】

    docker load [OPTIONS]

    Load an image from a tar archive or STDIN

  • tag【了解】

    docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

    Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

  • commit【了解】

    docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

    Create a new image from a container's changes

容器操作【重点】

  • run

    docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

    基于一个镜像启动一个容器 Options:

    • -d

    在后台运行容器(不占用用户进程)

    • -e

    设置容器内部的环境变量

    • -i

    使用标准输入

    • -p

    端口映射,将容器中的某一个端口,映射到宿主机的一个端口

    • -v

    绑定数据卷

    • --name string

    指定容器的名称

    • --rm

    当容器关闭时,自动删除

    • --network string

    运行一个容器并连接到指定网络

    • 练习

    启动mysql容器

    docker run -id

    --name mysql

    -p 3307:3306

    -e MYSQL_ROOT_PASSWORD=root

    -v /Users/LEAF/mysql_data:/var/lib/mysql

    mysql:5.7.34

  • ps

    docker ps [OPTIONS]

    列出容器 参数:

    • -a

    列出所有容器,包括停止的

    • -q

    只查看容器ID

  • logs

    docker logs [OPTIONS] CONTAINER

    查看容器的日志 选项:

    • -f

    实时监听日志,直到用户输入Ctrl - C

  • exec

    docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

    进入容器 Options:

    • -it

    使用用户控制台

  • cp

    docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

    将宿主机中的目录或文件,复制到容器中;或将容器中的目录或文件,复制到宿主机中

  • restart

    docker restart [OPTIONS] CONTAINER [CONTAINER...]

    重启

  • stop

    docker stop [OPTIONS] CONTAINER [CONTAINER...]

    停止

  • start

    docker start [OPTIONS] CONTAINER [CONTAINER...]

    启动

  • rm

    docker rm [OPTIONS] CONTAINER [CONTAINER...]

    删除 Options:

    • -f

    强制删除,可以删正在运行中的容器

  • inspect

    docker inspect [OPTIONS] NAME|ID [NAME|ID...]

    查看容器的详情

  • container prune

    docker container prune [OPTIONS]

    删除所有没有正在使用的容器

  • 练习

    1. 运行mysql容器

    docker run -id

    -e MYSQL_ROOT_PASSWORD=root

    -p 3307:3306

    -v "E:/Program Files/mysql_data":/var/lib/mysql

    --name mysql

    mysql:5.7.34

    1. 停止mysql容器

    docker stop mysql

    1. 启动mysql容器

    docker start mysql

    1. 重启mysql容器

    docker restart mysql

    1. 停止mysql容器,查看正在运行中的容器

    docker stop mysql

    docker ps

    1. 查看所有容器

    docker ps -a

    1. 运行mysql容器,查看mysql容器的日志

    docker start mysql

    docker logs mysql

    1. 实时查看mysql容器的日志

    docker logs -f mysql

    1. 进入mysql容器,查看容器中的/home目录的内容

    docker exec -it mysql bash

    1. 将宿主机中的一个空目录复制到容器中

    docker cp "C:/Program Files/newfolder" mysql:/home

    1. 将容器中的一个空文件复制到宿主机中

    docker cp mysql:/home/newfile "C:/Program Files/"

数据卷操作

数据卷的核心,在于映射时,指定别名,而不是绝对路径

  • volume create

    docker volume create [OPTIONS] [VOLUME]

    创建数据卷

  • volume inspect

    docker volume inspect [OPTIONS] VOLUME [VOLUME...]

    查看数据卷详情

  • volume ls

    docker volume ls [OPTIONS]

    列出所有的数据卷

    Options:

    • -q

    只查看数据卷的名字

  • volume rm

    docker volume rm [OPTIONS] VOLUME [VOLUME...]

    删除数据卷,如果一个数据卷正在被容器使用,那么无法删除

    Options:

    • -f

    强制删除

  • volume prune

    docker volume prune [OPTIONS]

    删除所有没有正在使用的数据卷

  • 练习

    1. 创建mysql_data数据卷

    docker volume create mysql_data

    1. 将mysql容器删除,重新生成一个mysql容器,用mysql_data数据卷别名启动

    docker rm -f mysql

    bash
    docker run -id \
    -e MYSQL_ROOT_PASSWORD=root \
    -p 3307:3306 \
    -v mysql_data:/var/lib/mysql \
    --name mysql \
    mysql:5.7.34
    1. 查看mysql_data数据卷详情

    docker volume inspect mysql_data

    1. 删除mysql_data数据卷,会提示无法删除,因为正在使用当中

    docker volume rm mysql_data

    1. 删除mysql容器,删除mysql_data数据卷

    docker rm -f mysql

    docker volume rm mysql_data

网络操作【重点】

Container-Network

  • network create

    docker network create [OPTIONS] NETWORK

    创建网络

    Options:

    • -d string

    网络类型(默认为bridge类型)

  • network rm

    docker network rm NETWORK [NETWORK...]

    删除网络

  • network inspect

    docker network inspect [OPTIONS] NETWORK [NETWORK...]

    查看网络信息

    Options:

    • -v

    详情模式

  • network ls

    docker network ls [OPTIONS]

    列出网络

    Options:

    • -q

    只显示网络ID

  • network prune

    docker network prune [OPTIONS]

    删除所有没有正在使用的网络

  • 练习

    1. 建立global网络,默认是bridge类型网络

    docker network create global

    1. 查看所有网络,确认global已经被创建

    docker network ls

    1. 运行tomcat1和tomcat2容器,全部使用global网络

      bash
      docker run -id \
      -p 8081:8080 \
      --name tomcat1 \
      --network global \
      tomcat:8.5.68-jdk8
      
      docker run -id \
      -p 8082:8080 \
      --name tomcat2 \
      --network global \
      tomcat:8.5.68-jdk8
    2. 进入tomcat1容器,curl测试tomcat2是否能够连接

      bash
      docker exec -it tomcat1 bash
      curl http://tomcat2:8080

Dockerfile

什么是Dockerfile

Dockerfile 是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。

1、对于开发人员:可以为开发团队提供一个完全一致的开发环境; 2、对于测试人员:可以直接拿开发时所构建的镜像或者通过 Dockerfile 文件构建一个新的镜像开始工作了; 3、对于运维人员:在部署时,可以实现应用的无缝移植。

指令

  • FROM image_name:tag

    使用哪个基础镜像启动构建流程

  • MAINTAINER username

    声明镜像的创建者

  • ENV key value

    设置环境变量 (可以写多条)

  • ADD

    将宿主机的文件复制到容器内,如果是一个压缩文件,将会在复制后自动解压

  • COPY

    和ADD相似,但是如果有压缩文件并不能解压

  • WORKDIR

    设置工作目录

  • RUN

    是Dockerfile的核心部分(可以写多条)

  • EXPOSE

    根据镜像启动容器后,将要占用哪些端口

  • CMD

    根据镜像启动容器后,将要运行哪些命令

命令

  • build

docker build [OPTIONS] PATH | URL | -

根据dockerfile构建镜像

Options:

  • -t list

指定镜像名称与版本号

快速入门

编写Dockerfile文件

dockerfile
## 依赖镜像名称和ID
FROM centos:7.9.2009

## 指定镜像创建者信息
MAINTAINER future-weaver

## 切换工作目录
WORKDIR /usr
RUN mkdir  /usr/local/java

## ADD 是相对路径jar,把java添加到容器中
ADD jdk-8u321-linux-x64.tar.gz /usr/local/java/

## 配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_321
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

根据Dockerfile构建镜像

bash
docker build -t jdk:8 .

服务编排三剑客

Compose、Machine和Swarm是Docker原生提供的三大编排工具

Docker Compose【重点】

之前运行一个镜像,需要添加大量的参数,可以通过Docker-Compose编写这些参数。而且Docker-Compose可以帮助我们批量的管理容器。这些信息只需要通过一个docker-compose.yml文件去维护即可。

安装

  1. Linux 版本安装
bash
wget https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-Linux-x86_64

mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose

chmod 777 /usr/local/bin/docker-compose

docker-compose -v
  1. Docker Desktop 版本安装

Docker Desktop 自带 docker-compose 二进制文件,安装 Docker 之后可以直接使用。

快速入门

  1. 创建 docker 网络
bash
docker network create global
  1. 新建目录,创建 docker-compose.yml 文件
yml
version: '3.9'
services:
  mysql:
    restart: always
    image: mysql:5.7.34
    container_name: mysql
    ports:
      - 3307:3306
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
     - ./mysql_data:/var/lib/mysql
  tomcat:
    restart: always
    image: tomcat:8.5.75-jdk8
    container_name: tomcat
    ports:
      - 8080:8080
    volumes:
     - ./webapps:/usr/local/tomcat/webapps

networks:
  default:
    external: true
    name: global
  1. 启动容器
bash
docker-compose up -d
  1. 停止并删除容器

    bash
    docker-compose down

docker-compose.yml配置文件

https://docs.docker.com/compose/compose-file/

命令

  • docker-compose up

    docker-compose up [SERVICE...]

    Create and start containers

  • docker-compose down

    docker-compose down

    Stop and remove containers, networks

  • docker-compose start

    docker-compose start [SERVICE...]

    Start services

  • docker-compose stop

    docker-compose stop [SERVICE...]

    Stop services

  • docker-compose restart

    docker-compose restart

    Restart containers

  • docker-compose rm

    docker-compose rm [SERVICE...]

    Removes stopped service containers

  • docker-compose ps

    docker-compose ps

    List containers

  • docker-compose logs

    docker-compose logs [service...]

    View output from containers

Nexus部署

常见的Maven仓库管理软件
Nexus安装
yml
version: '3.9'
services:
 nexus:
   image: sonatype/nexus3:3.31.1
   container_name: nexus
   ports:
     - 8081:8081

networks:
 default:
   external: true
   name: global
Nexus登录

访问私服:http://宿主机ip:8081/

用户名: admin

进入容器查看admin密码:

bash
docker exec -it nexus3 bash
cat /nexus-data/admin.password
仓库类型【了解】
  • group

    包含多个仓库,通过group库的地址可以从包含的多个仓库中查找构件

  • hosted

    私服 服务器本地的仓库,其中存储诸多构件

  • proxy

    代理仓库,其会关联一个远程仓库, 比如中央仓库,aliyun仓库,向该仓库查找构件时,如果没有会从其关联的仓库中下载

仓库名称【了解】
  • maven-public

    包含了central、releases、snapshots仓库

  • maven-central

    代理仓库

  • maven-releases

    存放项目的稳定发布版本,一个模块做完后如果需要共享给他人,可以上传到私服的该库

  • maven-snapshots

    对应不稳定的发布版本

Maven配置私服【重点】
  1. Maven 关联私服

配置settings.xml,设置私服地址、认证等信息

xml
<servers>
    <server> 
        <id>nexus-public</id> <!-- nexus的认证id -->
        <username>admin</username> <!--nexus中的用户名密码-->
        <password>admin123</password> 
    </server>
</servers>

<profiles>
    <profile> 
        <id>nexus</id> 
        <repositories> 
            <repository> 
                <id>nexus-public</id> <!--nexus认证id 【此处的repository的id要和 <server>的id保持一致】-->
                <!--name随便-->
                <name>Nexus Release Snapshot Repository</name> 
                <!--地址是nexus中仓库组对应的地址-->
                <url>http://localhost:8081/nexus/content/groups/public/</url>
                <releases><enabled>true</enabled></releases> 
                <snapshots><enabled>true</enabled></snapshots> 
            </repository>
        </repositories> 
        <pluginRepositories> <!--插件仓库地址,各节点的含义和上面是一样的-->
            <pluginRepository> 
                <id>nexus-public</id> <!--nexus认证id 【此处的repository的id要和 <server>的id保持一致】-->
                <!--地址是nexus中仓库组对应的地址-->
                <url>http://localhost:8081/nexus/content/groups/public/</url>
                <releases><enabled>true</enabled></releases> 
                <snapshots><enabled>true</enabled></snapshots> 
            </pluginRepository> 
        </pluginRepositories> 
    </profile>
</profiles>

<activeProfiles>
    <activeProfile>yourjdk</activeProfile>
    <!-- 使私服配置生效 -->
    <activeProfile>nexus</activeProfile>
</activeProfiles>

至此,Maven项目中需要依赖时,Maven会从私服中下载

  1. Maven 项目部署到私服
  • 执行 :mvn deploy 即可将项目部署到私服对应的仓库中,此时项目中的打包方式多为jar

  • 但需要提前在项目的pom.xml中配置部署私服仓库位置,如下:

xml
    <!-- ... -->
    <dependencies>
        <!-- .... -->
    </dependencies>
    
    <!-- 在项目的pom.xml中 配置私服的仓库地址,可以将项目打jar包部署到私服 -->
    <distributionManagement>
        <repository>
            <id>nexus-public</id> <!-- nexus认证id -->
            <url>http://localhost:8081/nexus/content/repositories/releases</url>
        </repository>
        <snapshotRepository>
            <id>nexus-public</id> <!-- nexus认证id -->
            <url>http://localhost:8081/nexus/content/repositories/snapshots</url>
        </snapshotRepository>
    </distributionManagement>
</project>

注意:如上的 repository的 id 依然是要和settings.xml中配置的server中的id 一致,才能通过私服的认证

Docker私有仓库部署

仓库搭建
  1. docker-compose.yml
yml
version: '3.9'
services:
  registry:
    restart: always
    image: registry:2.7.1
    container_name: registry
    ports:
      - 5000:5000

networks:
  default:
    external: true
    name: global
  1. 测试

    tex
    http://docker宿主机ip:5000/v2/_catalog
仓库配置

参考《2.2 仓库配置》,添加如下选项,并重启docker

json
"insecure-registries": [
  "localhost:5000"
]
上传镜像至仓库
  1. 标记此镜像为私有仓库的镜像
docker tag jdk1.8 docker宿主机ip:5000/jdk1.8
  1. 再次启动私服容器
docker start registry
  1. 上传标记的镜像
docker push docker宿主机ip:5000/jdk1.8

Docker Machine【了解】

Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境。

安装

  1. Linux 版本安装

    bash
    wget https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-Linux-x86_64
    
    mv docker-machine-Linux-x86_64 /usr/local/bin/docker-machine
    
    chmod 777 /usr/local/bin/docker-machine
    
    docker-machine -v
  2. Docker Desktop 版本安装

    Docker Desktop 自带 docker-machine 二进制包,安装之后即可使用。

命令

  • docker-machine create

    docker-machine create [OPTIONS] [arg...]

    创建一个 Docker 主机

  • docker-machine ssh

    docker-machine ssh [arg...]

    SSH 到主机上执行命令

  • docker-machine ls

    docker-machine ls [OPTIONS] [arg...]

    列出所有管理的主机

  • docker-machine start

    docker-machine start [arg...]

    启动一个主机

  • docker-machine stop

    docker-machine stop [arg...]

    停止一个主机

  • docker-machine restart

    docker-machine restart [arg...]

    重启主机

  • docker-machine rm

    docker-machine rm [OPTIONS] [arg...]

    删除某台主机

Docker Swarm【了解】

Docker Swarm 是 Docker 官方编排(Orchestration)项目之一,提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行支持的核心方案。使用它,用户可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台。竞品为 K8S。

6 CI/CD

CI/CD

Engine API

Engine API 是由 Docker 守护进程提供的。在默认情况下,Docker 守护进程会绑定到一个所在宿主机的套接字。Docker 守护进程需要以 root 权限来运行,以便它有足够的权限去管理所需要的资源。如果系统中存在一个名为 docker 用户组,Docker 会将上面所说的套接字的所有者设为该用户组。因此任何属于 docker 用户组的用户都可以运行 Dockerd 而无须 root 权限。

如果想远程访问 Engine API,就需要将 Docker 守护进程绑定到一个网络接口上。只需要给 Docker 守护进程传递一个-H标志即可。

注意

Docker Remote API无法在Docker Desktop下使用

配置守护进程

编辑启动项配置文件

  • /usr/lib/systemd/system/docker.service
# 默认的Systemd守护进程启动选项
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

# 绑定到网络接口的Systemd守护进程启动选项
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock

编辑daemon.json配置文件

  • fd: file descriptor,文件描述符
json
"debug": true,
"hosts": [
  "fd://",
  "unix:///var/run/docker.sock",
  "tcp://0.0.0.0:2375"
]

重新加载和启动Docker守护进程

bash
systemctl daemon-reload
systemctl restart docker

开启防火墙

bash
/sbin/iptables -I INPUT -p tcp --dport 2375 -j ACCEPT
firewall-cmd --zone=public --add-port=2375/tcp --permanent
systemctl restart firewalld

RESTful Engine API

https://docs.docker.com/engine/api/v1.41

  • Create an exec instance
bash
curl -X POST -H "Content-Type: application/json" \
-k \
--cert /root/openssl/cert.pem \
--key /root/openssl/key.pem \
-d '{
  "Cmd":["touch", "/hello.log"]
}' \
https://DOCKER_REMOTE_SITE:2376/containers/{id}/exec

# id: ID or name of container
  • Start an exec instance
bash
curl -X POST -H "Content-Type: application/json" \
-k \
--cert /root/openssl/cert.pem \
--key /root/openssl/key.pem \
-d '{
  "Detach": false,
  "Tty": false
 }' \
https://DOCKER_REMOTE_SITE:2376/exec/{id}/start

# id: Exec instance ID

Docker Engine API认证

我们已经看到了如何连接到Docker Remote API,不过这也意味着其他人都能连接到同样的 API。Docker Remote API的认证机制采用了TLS/SSL证书来确保用户与 API 之间连接的案例性。

我们可以创建自己的证书授权中心(Certificate Authority, CA),或者使用已有的 CA。在这里,我们将建立自己的证书授权中心。

TLS/SSL概述

HTTP交互

http

https解决方案

http-secure-solution

https

CA

Certificate Authority,证书授权中心,负责管理和签发证书

数字证书

也叫CA证书。是由CA所签发的证书,其中包括:

  1. 拥有者身份信息,用于确认身份
  2. CA机构的签名,用于保证身份真实
  3. 公钥,用于通信过程中的加解密

docker-engine-tls

制作根证书

生成RSA密钥
bash
mkdir /etc/docker/cert
cd /etc/docker/cert
openssl genrsa -out ca-key.pem 4096
签发根证书
bash
openssl req -new -x509 -days 3650 -key ca-key.pem -sha256 -out ca.pem

此时会提示输入:

  • Country Name (2 letter code) [XX]

国家编码,可使用默认值,或输入.留空

  • State or Province Name (full name)

州或省,可使用默认值,或输入.留空

  • Locality Name (eg, city) [Default City]

城市名称,可使用默认值,或输入.留空

  • Organization Name (eg, company) [Default Company Ltd]

企业名称,可使用默认值,或输入.留空

  • Organizational Unit Name (eg, section) []

部门名称,可使用默认值,或输入.留空

  • Common Name (eg, your name or your server's hostname) []

表示允许在哪些服务器上使用证书,最重要的选项,没有之一!

要么为FQDN(fully qualified domain name,完全限定的域名)形式(即从 DNS 中解析后得到的结果,比如 docker.example.com)

要么为 *,这将允许在任何服务器上使用该服务器证书。

本例中,输入*

  • Email Address []:

邮箱,可使用默认值,或输入.留空

以下为控制台输出,供对比参考

tex
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:*
Email Address []:

签发服务器证书

生成RSA密钥
bash
openssl genrsa -out server-key.pem 4096
生成证书请求
bash
openssl req -new -key server-key.pem -out server.csr

注意

Common Name指定为*

以下为控制台输出,供对比参考

tex
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:*
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
签发证书
bash
openssl x509 -req -days 3650 -sha256 -CA ca.pem -CAkey ca-key.pem -CAcreateserial -in server.csr -out server.pem

签发客户端证书

生成RSA密钥
bash
openssl genrsa -out client-key.pem 4096
生成证书请求
bash
openssl req -new -key client-key.pem -out client.csr

注意

Common Name指定为*

以下为控制台输出,供对比参考

tex
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:*
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
签发证书
bash
openssl x509 -req -days 3650 -sha256 -CA ca.pem -CAkey ca-key.pem -CAcreateserial -in client.csr -out client.pem

服务端配置

编辑配置文件
bash
vim /etc/docker/daemon.json
json
"tls": true,
"tlscacert": "/etc/docker/cert/ca.pem",
"tlscert": "/etc/docker/cert/server.pem",
"tlskey": "/etc/docker/cert/server-key.pem",
"hosts": [
  "fd://",
  "unix:///var/run/docker.sock",
  "tcp://0.0.0.0:2376"
]

2376端口号,是Docker中TLS/SSL的默认端口号。对于非认证的连接,只能使用2375这个端口。

重新加载配置文件
bash
systemctl daemon-reload
systemctl restart docker

客户端连接

检查签发证书

client.pem,client-key.pem复制到客户端

测试连接
bash
curl -k https://DOCKER_REMOTE_SITE:2376/info --cert /etc/docker/cert/cert.pem --key /etc/docker/cert/key.pem

IDEA集成Docker的快捷部署

xml
<properties>
  <docker.image.prefix>前缀</docker.image.prefix>
</properties>

<build>
  <plugins>
    <plugin>
      <groupId>com.spotify</groupId>
      <artifactId>docker-maven-plugin</artifactId>
      <version>1.0.0</version>

      <configuration>
        <!--远程Docker的地址-->
        <dockerHost>https://DOCKER_REMOTE_SITE:2376</dockerHost>
        <dockerCertPath>${project.basedir}/path/to/cert</dockerCertPath>
        <!--镜像名称,前缀/项目名-->
        <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
        <dockerDirectory>src/main/docker</dockerDirectory>
        <resources>
          <resource>
            <targetPath>/</targetPath>
            <directory>${project.build.directory}</directory>
            <include>${project.build.finalName}.jar</include>
          </resource>
        </resources>
      </configuration>
    </plugin>
  </plugins>
</build>

参考资料

https://docs.docker.com/docker-for-windows/install/

https://docs.docker.com/docker-for-mac/install/

https://docs.docker.com/compose/compose-file/

https://docs.docker.com/compose/compose-file/deploy/

https://docs.docker.com/config/daemon/

https://docs.docker.com/engine/api/v1.41

https://docs.docker.com/engine/install/

https://docs.docker.com/engine/reference/builder/

https://docs.docker.com/engine/reference/commandline/dockerd/

https://docs.docker.com/get-started/overview

https://mp.weixin.qq.com/s/4QayQY7tXnkmtdQBXHz7vg

https://www.bilibili.com/video/BV1i741137kk?from=search&seid=17833650203758282461

https://www.cnblogs.com/liyuchuan/p/13198960.html

https://www.docker.com/company/newsroom/media-resources

https://www.docker.com/resources/what-container

https://yeasy.gitbook.io/docker_practice/network/port_mapping

https://blog.csdn.net/yangkuo024/article/details/119738080

学习目标总结

  • 掌握 Docker 的镜像操作
  • 掌握 Docker 的容器操作
  • 了解 Docker 的数据卷操作
  • 掌握 Docker 的网络操作
  • 了解镜像的制作与上传
  • 掌握 Docker Compose
  • 了解 Docker Machine
  • 了解 Docker Swarm