Docker Container操作案例
容器的基本操作
- 通过nginx镜像文件创建容器
docker run -d --name mynginx001 -p 8101:80 nginx:1.22.0
- 1
- 查看容器是否正常运行
- 查看容器详细信息
docker container inspect mynginx001
- 1
- 查看日志信息
docker logs -f mynginx001
- 1
- 删除容器
docker rm mynginx001
- 1
容器状态迁移
- 创建并运行容器
#更具镜像ID创建容器
docker create --name mynginx002 -p 8102:80 3a8963c304a2
#启动容器
docker start mynginx002
- 1
- 2
- 3
- 4
- docker kill 和 doker stop
docker kill mynginx002
docker stop mynginx002
- 1
- 2
- docker pause 剥夺容器CPU资源
docker pause mynginx002
docker unpause mynginx002
- 1
- 2
容器批量处理技巧
- -a:表示打印所有的容器信息, 包括正在运行和已经退出的
- -q: 表示只返回容器 ID
- -f: 表示基于给的条件过滤 等价于 --filter 选项
? 容器的批量搜索
通过名称、运行状态和祖先(镜像)进行过滤
#通过名字进行过滤
docker ps -f name=mywebsite4
#通过运行状态进行过滤
docker ps -f status=exited
- 1
- 2
- 3
- 4
docker ps -f ancestor=nginx:1.24.0
- 1
只返回ID信息
docker ps -q
- 1
? 容器的批量操作
停止掉正在运行的所有容器
docker stop `docker ps -q`
- 1
重启所有已经停止的容器
docker start `docker ps -a -q`
- 1
容器交互模式
attached模式
attached 模式创建的容器会在前台运行。
创建attached模式的容器
docker run --name mynginx006 -p 8106:80 nginx:1.24.0
- 1
如果杀死attached模式下的容器会发生什么
detached模式
detached模式是指将容器进行后台运行
创建detached模式的容器
docker run --name mynginx007 -p 8107:80 -d nginx:1.24.0
- 1
docker logs -f mynginx007
- 1
docker attach会将detached容器转换为attach容器
docker attach mynginx007
- 1
interactive模式
当我们创建好一个容器之后, 可能需要去容器内部获取一些信息或执行一些命令,就需要进入到交互式模式。例如创建一个 Ubuntu 容器之后,需要到系统里输入各种Shell 命令和系统进行交互就需要进入交互式模式才可以完成。interactive模式
就是交互式模式
- -i:保持容器运行。通常与 -t 同时使用,加入 it 这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭
- 为容器重新分配一个伪输入终端,通常与 -i 同时使用
创建一个交互式模式容器
docker run -it --name mynginx008 -p 8108:80 nginx:1.24.0 bash
- 1
在交互式模式容器中退出会发生什么
容器的interactive模式之和后台运行的容器交互
#创建一个后台运行的容器
docker run -d --name mynginx010 -p 8110:80 nginx:1.24.0
#容器的interactive模式之和后台运行的容器交互
docker exec -it mynginx010 bash
- 1
- 2
- 3
- 4
容器与宿主机内容复制
- 启动一个nginx服务并在宿主机上编辑一个index.html文件
docker cp mynginx011:/usr/share/nginx/html/index.html .
- 1
- 将编辑好的文件拷贝回容器中
docker cp ./index.html mynginx011:/usr/share/nginx/html/
- 1
这里我们需要注意的是,容器和容器之间不能通过docker cp
命令进行文件的拷贝。
容器自动删除
交互模式下启动一个nginx容器
docker run -it --rm --name mynginx012 -p 8112:80 nginx:1.24.0 bash
- 1
后台启动一个nginx服务
docker run -d --rm --name mynginx012 -p 8112:80 nginx:1.24.0
- 1
容器自动重启
容器重启选项如下:
#默认值不自动重启
docker run --restart=no [容器名]
#若容器的退出状态非 0,则自动重启容器,还可以指定重启次数,若超过指定次数未能启动容器则放弃
docker run --restart=on-failure:3 [容器名] : on-failure
#容器退出时总是重启
docker run --restart=always [容器名] :always
#容器退出时总是重启,但不考虑 Docker 守护进程启动时就已经停止的容器
docker run --restart=unless-stopped [容器名] unless-stopped
#如果容器启动时没有设置–restart 参数,则通过下面命令进行更新:
docker update --restart=always [容器名]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
容器异常停止,会自动重启吗
#创建一个容器,设置为总是重启
docker run -d --name mynginx025 -p 8125:80 --restart=always nginx:1.24.0
- 1
- 2
docker stop容器后还会重启吗
docker stop mynginx025
- 1
容器环境变量设置
为容器设置多个环境变量
- 通过多个-e配置多个环境变量
docker run -it --rm -e MYTEST=1 -e MYTEST2=2 -e MYTEST3=3 nginx:1.24.0 bash
- 1
- 通过配置文件设置多个环境变量
#创建容器时指定环境变量配置文件
docker run -it --rm --env-file=./myenv nginx:1.24.0 bash
- 1
- 2
容器详情查看
#指定一系列参数创建容器
docker run -d --name mynginx029 -p 8029:80 -e MYTEST=1 -h mynginx029.com nginx:1.24.0
#查看容器摘要信息
docker ps
#查看容器详情
docker container inspect mynginx029
- 1
- 2
- 3
- 4
- 5
- 6
容器执行单行命令
我们可以直接借助 docker 的容器环境执行一些命令,比如容器中有某个命令而宿主机上没有这个时候借助容器可以完成某些任务。
#假定宿主机上没有ping指令和ifconfig指令
docker run --rm busybox:1.36.0 ping www.baidu.com
docker run --rm busybox:1.36.0 ifconfig
- 1
- 2
- 3
容器镜像导入导出
- 启动一个nginx容器并修改其首页内容
cd /usr/share/nginx/html/
echo "I am from cjl docker" > index.html
- 1
- 2
- 将容器保存为tar包
docker export -o mynginx030.tar mynginx030
- 1
- 把tar包还原为一个镜像,并使用该镜像运行一个容器
#将该tar包还原为镜像
docker import mynginx030.tar mynginx:v0.30
#使用该镜像运行一个容器
docker run -d --name mynginx030 -p 8030:80 mynginx:v0.30
docker run -d --name mynginx030 -p 8030:80 mynginx:v0.30 nginx -g "daemon off;"
- 1
- 2
- 3
- 4
- 5
这里我们发现导出的镜像无法直接运行一个容器,这时因为docker export
命令将容器导出为镜像时丢失了部分镜像的数据,因此我们需要补齐这些信息才能运行容器
容器日志查看
启动nginx容器并查看日志
#查看容器所有日志
docker logs mynginx031
- 1
- 2
docker logs -f mynginx031
- 1
将日志信息重定向到文件中
#将标准输出日志重定向到info.log 标准错误日志重定向到err.log
docker logs mynginx031 > info.log 2 > err.log
- 1
- 2
#进入docker存储的根目录下
cd /data/var/lib/docker
#查看容器的container id
docker ps
#进入该容器id的目录下
cd 8f0f3b8ca830a004acf5f0ebefd3cbd83020077eee6d25e940cdcee337d51709/
#以.log结尾的就是日志文件
- 1
- 2
- 3
- 4
- 5
- 6
- 7
容器资源查看
查看容器的资源占用情况
docker stats mynginx031
- 1
docker top mynginx031 aux
- 1
Docker Container综合实战
综合实战一:Mysql容器化安装
- 进入 mysql 的镜像网站,查找 mysql 的镜像
- 用docker直接运行一个mysql服务
docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -p 8201:3306 -d mysql:5.7
- 1
- 进入mysql容器中检查mysql容器是否正常工作
docker exec -it mysql bash
- 1
查看基本操作是否正常
- 通过可视化工具远程连接mysql
综合实战二:Redis容器化安装
Redis简介
在 Web 应用发展的初期,那时关系型数据库受到了较为广泛的关注和应用,原因是因为那时候 Web 站点基本上访问和并发不高、交互也较少。而在后来,随着访问量的提升,使用关系型数据库的 Web 站点多多少少都开始在性能上出现了一些瓶颈,而瓶颈的源头一般是在磁盘的 I/O 上。而随着互联网技术的进一步发展,各种类型的应用层出不穷,这导致在当今云计算、大数据盛行的时代,对性能有了更多的需求,主要体现在以下几个方面:
- 低延迟的读写速度:应用快速地反应能极大地提升用户的满意度
- 支撑海量的数据和流量:对于搜索这样大型应用而言,需要利用 PB 级别的数据和能应对百万级的流量
为了克服这一问题, NoSQL 应运而生,它同时具备了高性能、可扩展性强、高可用等优点,受到广泛开发人员和仓库管理人员的青睐。
Redis 是什么
Redis
全称 Remote Dictionary Server,中文名为远程字典服务器。
Redis 是现在最受欢迎的 NoSQL 数据库之一, Redis 是一个使用 ANSI C 编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库,其具备如下特性:
- 基于内存运行,性能高效
- 支持分布式,理论上可以无限扩展
- key-value 存储系统
- 开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、 Key-Value 数据库,并提供多种语言的 API
Redis的应用场景
几乎所有的大厂都在使用 Redis。 Redis 提供了多种数据类型, String 类型、哈希类型、列表类型、集合类型和顺序集合类型,借助这些类型可以方便的实现多种应用,如缓存系统(“热点”数据:高频读、低频写)、计数器、消息队列系统、实时排行榜、社交网络。
Redis生活案例
Redis 就像一个新华字典,可以根据某个字符可以很快的找到字典对应的字。
Redis 容器创建
- 下载redis镜像并启动redis容器
docker run --name redis -d -p 8300:6379 redis:7
- 1
- 进入redis容器检查是否正常工作
docker exec -it redis bash
- 1
- 通过可视化工具远程连接redis服务
综合实战三:C++容器制作
镜像源
镜像源就是把官方的源做一个镜像,你可以在这下载软件。比如 ubuntu 官方源在国外,下载软件可能会很慢,这时候就需要换成国内的镜像源。我们基于 ubuntu 来制作 C++容器,运行输出HelloWorld可以把镜像源当做一个代理商,比如买车本来要去车厂,但是设置了一个个 4s 店以后,
我去 4s 店就好了,不用跑到车厂。
制作C++容器
- 下载Ubuntu镜像并启动容器
docker pull ubuntu:22.04
docker run -it --name mycpp ubuntu:22.04 bash
- 1
- 2
- 配置国内镜像源并安装gcc
sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list
apt-get update
apt install -y gcc
- 1
- 2
- 3
当然 ,由于Ubuntu系统上可能没有安装vim,所以这里我们需要手动安装一下:
apt install -y vim
- 1
- 编辑代码并运行
#include
int main()
{
printf("hello docker!\n");
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
综合实战四:SpringBoot容器制作
编写demo
-
创建maven项目
-
在下面pom.xml中修改配置如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.bitgroupId>
<artifactId>dockerdemoartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.7.7version>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<executions>
<execution>
<goals>
<goal>repackagegoal>
goals>
execution>
executions>
plugin>
plugins>
build>
project>
- 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
- 44
- 45
- 编写主函数构建 Spring 容器、编写控制器
// 主函数构建Spring容器--Main.java
package com.bit;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class,args);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
// 编写控制器
package com.bit;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/hello")
public class ExampleController {
@RequestMapping("")
public String index(){
return "Hello I am from docker!";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
下面进行代码测试:
- 使用maven打包生成jar包
- 测试jar包是否可用
制作容器
- 下载Ubuntu镜像并启动容器、配置国内镜像源加速
docker run -it --name myjava -p 8080:8080 ubuntu:22.04 bash
sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list
apt-get update
- 1
- 2
- 3
- 安装 jdk并检查是否正常运行
apt install -y openjdk-8-jdk
java -version
- 1
- 2
- 打开新的 shell 窗口,将 jar 拷贝到容器里面
docker cp ./dockerdemo-1.0-SNAPSHOT.jar myjava:/
- 1
- 在容器中启动Java服务,并使用浏览器进行访问
java -jar dockerdemo-1.0-SNAPSHOT.jar
- 1
综合实战五:容器资源更新
容器内存资源控制
- 在容器中启动Java服务,并使用docker stats进行监控。
docker run -it --name myjava2 adoptopenjdk/openjdk8
docker cp dockerdemo-1.0-SNAPSHOT.jar myjava2:/
- 1
- 2
- 通过docker update 更新容器占用的内存
docker update -m 10m --memory-swap 10m myjava2
- 1
- 停掉Java服务,并修改内存极小,看Java服务还能否启动
docker update -m 10m --memory-swap 10m myjava2
java -jar dockerdemo-1.0-SNAPSHOT.jar
- 1
- 2
容器CPU资源控制
- 在容器中启动Java服务,并执行一个命令,打满 cpu
docker run -it --name myjava3 adoptopenjdk/openjdk8
#Bash
for i in `seq 1 $(cat /proc/cpuinfo |grep "physical id" |wc -l)`
do
dd if=/dev/zero of=/dev/null &
done
#说明:
#cat /proc/cpuinfo |grep “physical id” | wc -l 可以获得 CPU 的个数,
我们将其表示为 N
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 对CPU资源占用率进行更改
docker update --cpu-period 100000 --cpu-quota 10000 myjava3
- 1
常见问题
docker create、 docker start 和 docker run 有什么区别?
docker create
命令从 Docker 映像创建一个全新的容器。但是,它不会立即运行它。
docker start
命令将启动任何已停止的容器。如果使用 docker create 命令创建容器,则可以使用此命令启动它。
docker run
命令是创建和启动的组合,因为它创建了一个新容器并立即启动它。实际上,如果 docker run 命令在您的系统上找不到上述映像,它可以从 Docker Hub 中提取映像。
docker import 和 docker load 有什么区别?
想要了解 docker load 与 docker import 命令的区别,还必须知道 docker save
与 docker export
命令:
- docker save images_name:将一个镜像导出为文件,再使用 docker load 命令将文件导入为一个镜像,会保存该镜像的的所有历史记录。比 docker export 命令导出的文件大,很好理解,因为会保存镜像的所有历史记录。
- docker export container_id:将一个容器导出为文件,再使用 dockerimport 命令将容器导入成为一个新的镜像,但是相比 docker save 命令,容器文件会丢失所有元数据和历史记录,仅保存容器当时的状态,相当于虚拟机快照。
既可以使用 docker load 命令来导入镜像库存储文件到本地镜像库,也可以使用docker import 命令来导入一个容器快照到本地镜像库。
两者的区别在于容器快照将会丢弃所有的历史记录和元数据信息,而镜像存储文件将保存完整记录,体积也会更大。
docker rm & docker rmi & docker prune 的差异?
docker rm
: 删除一个或多个容器docker rmi
: 删除一个或多个镜像docker prune
: 用来删除不再使用的 docker 对象
评论记录:
回复评论: