Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器完全使用沙箱机制,相互之间不会有任何接口。
- 快速,一致地交付你的应用:Docker容器可以确保从开发环境到生产环境的一致性,简化软件交付过程。
- 响应式部署和扩展:Docker的轻量级和快速启动特性使得基于容器的应用可以在短时间内被自动扩展或缩减。
- 在同一硬件上运行更多的工作负载:Docker是资源友好的,可以让你在同一套硬件上运行更多的应用。
目录:
[TOC]
Docker安装
Docker支持多种平台,包括Ubuntu、Debian、CentOS等Linux发行版,以及Windows和macOS。
Linux上安装Docker
以Ubuntu为例,首先更新应用包索引:
sudo apt-get update
然后安装Docker:
sudo apt-get install docker-ce docker-ce-cli containerd.io
Windows上安装Docker
在Windows上,可以通过安装Docker Desktop来使用Docker。访问Docker官网下载Docker Desktop安装程序,然后按照向导完成安装。
https://www.docker.com/products/docker-desktop/
macOS上安装Docker
在macOS上,同样可以通过安装Docker Desktop来使用Docker。访问Docker官网下载Docker Desktop安装程序,然后按照向导完成安装。
验证安装
安装完成后,可以通过运行hello-world镜像来验证Docker是否正确安装:
docker run hello-world
如果安装正确,你将看到一条消息,说明你的Docker正在运行,并且能够从Docker Hub拉取镜像。
或者使用docker version
命令看下docker版本,能看到版本说明也是安装成功:
Docker镜像管理
Docker镜像是一个轻量级、可执行的独立软件包,包含运行应用所需的所有内容:代码、运行时、库、环境变量和配置文件。
查找镜像
在Docker Hub上查找镜像:
docker search ubuntu
这个命令会列出Docker Hub中与ubuntu
相关的镜像。
拉取镜像
从Docker Hub拉取一个镜像到本地:
docker pull ubuntu:18.04
这个命令会从Docker Hub拉取Ubuntu 18.04的官方镜像。
查看本地镜像
查看当前系统上的Docker镜像列表:
docker images
截图中是我之前拉的SRS镜像。
删除镜像
删除一个本地镜像:
docker rmi ubuntu:18.04
这个命令会删除本地的Ubuntu 18.04镜像。
构建镜像
使用Dockerfile构建新的镜像:
docker build -t my-ubuntu .
这个命令会根据当前目录下的Dockerfile来构建一个名为my-ubuntu
的镜像。
Docker容器管理
容器是独立运行的一个或一组应用,以及它们的运行环境。通过Docker容器,开发者可以打包应用与环境,并在任何支持Docker的平台上无缝部署。
运行容器
从镜像启动一个新容器:
docker run -it --name my-container ubuntu:18.04 /bin/bash
这个命令会从ubuntu:18.04
镜像启动一个名为my-container
的容器,并启动一个交互式的bash会话。
查看运行中的容器
查看当前正在运行的容器:
docker ps
停止容器
停止一个运行中的容器:
docker stop my-container
启动已停止的容器
启动一个已停止的容器:
docker start my-container
删除容器
删除一个容器:
docker rm my-container
注意:只有停止状态的容器才能被删除。
容器日志
查看容器的输出日志:
docker logs my-container
这个命令会显示容器的标准输出。
Docker网络管理
Docker网络允许容器间通信,以及容器与外部世界通信。Docker提供了多种网络模式,包括bridge、host、none和overlay等。
查看网络
列出所有Docker网络:
docker network ls
创建网络
创建一个新的网络:
docker network create --driver bridge my-bridge-network
这个命令创建了一个名为my-bridge-network
的bridge网络。
运行容器时指定网络
在特定网络中运行容器:
docker run -d --name my-container --network my-bridge-network nginx
这个命令在my-bridge-network
网络中启动了一个名为my-container
的容器,并运行nginx服务。
连接容器到网络
将已存在的容器连接到网络:
docker network connect my-bridge-network my-container
断开容器与网络的连接
从网络中断开容器:
docker network disconnect my-bridge-network my-container
删除网络
删除一个网络:
docker network rm my-bridge-network
Docker卷和数据管理
Docker卷用于持久化和共享容器的数据。通过使用卷,可以将数据生命周期从容器生命周期中解耦出来。
创建卷
创建一个新的卷:
docker volume create my-volume
运行容器时挂载卷
在容器中使用卷:
docker run -d --name my-container -v my-volume:/data nginx
这个命令启动了一个nginx容器,将my-volume
卷挂载到容器的/data
目录。
查看卷
列出所有卷:
docker volume ls
删除卷
删除一个卷:
docker volume rm my-volume
Docker Compose使用
Docker Compose是一个用于定义和运行多容器Docker应用的工具。通过Compose,你可以使用YAML文件来配置应用的服务。
安装Docker Compose
请根据官方文档指引安装Docker Compose。
使用Compose文件定义服务
创建一个docker-compose.yml
文件,定义服务:
version: '3'
services:
web:
image: nginx
ports:
- "80:80"
db:
image: postgres
environment:
POSTGRES_PASSWORD: example
启动服务
通过Docker Compose启动服务:
docker-compose up
停止服务
停止由Docker Compose启动的服务:
docker-compose down
制作Dockerfile
制作一个Dockerfile
通常涉及定义从哪个基础镜像开始、如何构建你的应用、以及当容器启动时需要执行什么命令等步骤。下面是一个简单的示例,展示了如何为一个Python Flask应用创建一个Dockerfile
。
示例:Python Flask 应用
假设你有一个简单的Flask应用,结构如下:
/your-app
- app.py
- requirements.txt
其中,app.py
是Flask应用的主文件,requirements.txt
列出了所有的Python依赖。
app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, Docker!'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
requirements.txt
flask
Dockerfile
接下来,创建一个Dockerfile
来容器化这个Flask应用。
# 使用官方Python运行时作为父镜像
FROM python:3.8-slim
# 设置工作目录
WORKDIR /app
# 将当前目录内容复制到位于/app中的容器中
COPY . /app
# 安装requirements.txt中指定的任何所需包
RUN pip install --no-cache-dir -r requirements.txt
# 使端口80可用于该容器外的环境
EXPOSE 80
# 定义环境变量
ENV NAME World
# 在容器启动时运行app.py
CMD ["python", "app.py"]
这个Dockerfile
执行了以下步骤:
- 从官方Python 3.8 slim镜像开始构建。
- 将工作目录设置为容器内的
/app
。 - 复制当前目录下的所有文件到容器内的
/app
目录。 - 使用
pip
安装requirements.txt
文件中列出的所有依赖。 - 将容器的端口80设置为对外开放。
- 设置一个环境变量
NAME
,值为World
。 - 定义容器启动时执行的默认命令为
python app.py
。
构建和运行Docker镜像
在包含Dockerfile
的目录中运行以下命令来构建镜像:
docker build -t my-flask-app .
构建完成后,运行你的容器:
docker run -p 4000:80 my-flask-app
这会将容器的80端口映射到宿主机的4000端口。现在,你可以通过访问http://localhost:4000
来访问你的Flask应用。
这只是一个基本的Dockerfile
示例。根据你的应用需求,你可能需要调整和优化你的Dockerfile
,例如使用多阶段构建来减小镜像大小,或者添加更多的配置和优化步骤。
制作java jar文件Dockerfile
制作一个用于Java应用(打包成jar文件)的Dockerfile
通常需要考虑基础镜像、构建环境、运行环境和启动命令等因素。以下是一个示例,展示如何为一个简单的Spring Boot应用创建一个Dockerfile
。
假设
- 你的Spring Boot应用已经被打包成一个名为
app.jar
的jar文件。 - 你想要在容器内运行这个jar文件。
Dockerfile
# 使用官方OpenJDK运行时作为父镜像
FROM openjdk:11-jre-slim
# 设置工作目录为/app
WORKDIR /app
# 将jar文件复制到容器的/app目录下
COPY target/app.jar /app/app.jar
# 暴露应用运行的端口
EXPOSE 8080
# 定义容器启动时执行的命令
CMD ["java", "-jar", "/app/app.jar"]
这个Dockerfile
执行了以下步骤:
- 基础镜像:从官方OpenJDK 11 slim版本的镜像开始构建。这个镜像包含了运行Java应用所需的JRE环境。
- 工作目录:将容器内的工作目录设置为
/app
。 - 复制jar文件:将构建好的jar文件(假设位于你的项目的
target
目录下)复制到容器的/app
目录下。请根据你的实际构建路径修改COPY
命令中的源路径。 - 暴露端口:将容器的端口8080设置为对外开放,这假设你的Spring Boot应用默认监听在8080端口上。如果你的应用监听的是其他端口,请相应地修改此处。
- 启动命令:定义了容器启动时执行的命令,使用
java -jar
来运行jar文件。
构建和运行Docker镜像
在包含Dockerfile
的目录中运行以下命令来构建镜像:
docker build -t my-spring-boot-app .
构建完成后,运行你的容器:
docker run -p 8080:8080 my-spring-boot-app
这会将容器的8080端口映射到宿主机的8080端口。现在,你可以通过访问http://localhost:8080
来访问你的Spring Boot应用。
请注意,这个示例假设你的Spring Boot应用已经被构建并打包成jar文件。在实际的项目中,你可能会使用Maven或Gradle作为构建工具,并且可能会在Dockerfile中包含构建步骤,或者使用多阶段构建来优化最终镜像的大小。
Docker Swarm集群管理
Docker Swarm是Docker的原生集群管理工具,它允许你将多个Docker主机组成一个集群,在集群中部署和管理容器。
Swarm集群
在主节点上初始化Swarm集群:
docker swarm init --advertise-addr <MANAGER-IP>
这个命令会初始化一个Swarm集群,并将当前节点设置为管理节点。
Swarm集群
在工作节点上加入Swarm集群:
docker swarm join --token <SWARM-JOIN-TOKEN> <MANAGER-IP>:2377
使用管理节点提供的加入令牌来加入集群。
Swarm节点
在管理节点上查看集群的节点信息:
docker node ls
部署服务到Swarm
在Swarm集群中部署服务:
docker service create --replicas 3 --name my-web nginx
这个命令会在Swarm集群中创建一个名为my-web
的服务,并部署3个nginx容器实例。
Swarm服务
列出所有Swarm服务:
docker service ls
查看特定服务的详细信息:
docker service ps my-web
缩放服务的副本数量:
docker service scale my-web=5
更新服务:
docker service update --image nginx:latest my-web
安全管理
Docker安全包括镜像安全、容器运行时安全、网络安全等方面。
官方镜像
尽可能使用官方镜像,减少安全风险。
扫描镜像中的漏洞
使用Docker Hub或其他第三方工具扫描镜像中的安全漏洞。
最小化容器权限
使用最小权限原则运行容器,例如,避免使用--privileged
标志。
管理容器的网络访问
根据需要配置容器的网络访问策略,避免不必要的外部访问。
安全存储敏感数据
使用Docker secrets或其他加密工具安全地存储和管理敏感数据。
Docker性能优化
优化Docker的性能,包括容器性能优化、资源分配、日志管理等。
优化容器启动时间
尽量减少容器镜像的大小,使用Alpine Linux等轻量级基础镜像。
资源限制
合理分配容器的CPU和内存资源,避免资源争抢导致的性能下降。
docker run -d --name my-container --memory=512m --cpus=1 nginx
日志管理
合理配置容器日志的大小和滚动策略,避免日志文件过大影响性能。
Docker文件系统和存储优化
Overlay2 文件系统
Overlay2是Docker推荐的存储驱动,因为它提供了良好的性能和兼容性。Overlay2通过创建一个层叠的文件系统,将容器和镜像的变更层放在顶层,而共享的只读层保持不变。
多阶段构建
利用Dockerfile的多阶段构建可以减小最终镜像的大小,提高构建效率。例如,您可以在一个阶段中编译您的应用,然后在另一个阶段中仅复制编译后的二进制文件到一个新的轻量级基础镜像中。
# 第一阶段:编译
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .
# 第二阶段:运行
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]
Docker安全加固
使用非root用户运行容器
默认情况下,容器以root用户运行,这可能带来潜在的安全风险。通过在Dockerfile中指定非root用户,可以增加容器的安全性。
FROM nginx
RUN adduser -D myuser
USER myuser
利用Docker秘密管理敏感信息
对于需要在容器中使用的敏感信息(如数据库密码),应避免直接在Dockerfile或环境变量中硬编码,而是使用Docker秘密(Docker Secrets)来安全地管理这些数据。
Docker监控和日志管理
使用Prometheus和Grafana进行监控
Prometheus是一个开源监控解决方案,可以与Docker容器化环境很好地集成。通过导出容器和Docker守护进程的度量标准,Prometheus可以收集并存储这些数据,而Grafana可以用来可视化这些数据。
配置日志驱动
Docker支持多种日志驱动程序,可以将容器的日志发送到不同的目的地,如本地文件、json-file或远程日志服务器。通过合理配置日志驱动,可以有效管理容器日志。
docker run -d --name my-container --log-driver=syslog --log-opt syslog-address=udp://192.168.0.42:514 nginx
Docker CI/CD集成
Docker可以与Jenkins、GitLab CI/CD等持续集成和持续部署工具无缝集成。通过在CI/CD管道中使用Docker,可以自动化构建、测试和部署容器化应用。
示例:使用Docker在GitLab CI/CD中构建和推送镜像
build_image:
stage: build
script:
- docker build -t myapp:$CI_COMMIT_SHA .
- docker push myapp:$CI_COMMIT_SHA
Docker常见问题解答
Q: 如何删除所有停止的容器?
A: 使用docker container prune
命令。
Q: 如何删除悬空(dangling)镜像?
A: 使用docker image prune
命令。
Q: Docker容器与虚拟机有何不同?
A: Docker容器是轻量级的,共享宿主机的内核,而虚拟机包括完整的操作系统和虚拟硬件,因此更重。
Q: 如何备份Docker容器中的数据?
A: 可以通过创建数据卷的快照来备份数据,或者使用docker cp
命令将数据从容器复制到宿主机。