Docker容器核心实践(操作容器)
镜像和容器是docker中最基础的概念,镜像可以理解为包含应用程序以及其相关依赖的一个基础文件系统,在其启动过程中,以只读的方式被用于创建容器的运行环境,本质上是基于UnionFS文件系统的一组镜像层依次挂载而得,每个镜像层包含的是对上一层镜像的修改
获取镜像
最常见的获取镜像的方式是从镜像仓库拉取,即使用docker pull
$ docker pull python
Using default tag: latest
latest: Pulling from library/python
699c8a97647f: Pull complete
86cd158b89fd: Pull complete
a226e961cfaa: Pull complete
4cec535da207: Pull complete
225fdd30e1a3: Pull complete
356a16c6c201: Pull complete
c1615dab98ef: Pull complete
8b4436f8e17c: Pull complete
c20627d9f29f: Pull complete
Digest: sha256:4d25a30d2943e5feb9c571b763936c843d7a6f45216f508bfe99741067f4ca06
Status: Downloaded newer image for python:latest
docker.io/library/python:latest
当没有使用镜像标签时,docker会默认使用latest
镜像被拉取后,就存放到本地,接受当前docker实例管理,通过docker images
即可看到
Docker Hub是docker官方建立的中央镜像仓库,除了普通镜像仓库的功能外,内部还有更加细致的权限管理,可以通过docker search
搜索其中镜像
$ docker search ubuntu
通过docker inspect
可以获取镜像更详细的信息
$ docker inspect ubuntu
[
{
"Id": "sha256:27941809078cc9b2802deb2b0bb6feed6c236cde01e487f200e24653533701ee",
"RepoTags": [
"ubuntu:jammy",
"ubuntu:latest"
......
docker inspect 的结果中可以看到关于镜像相当完备的信息
使用docker rmi
可以删除镜像,参数是镜像名称或ID
$ docker rmi golang:1.8.3
Untagged: golang:1.8.3
Untagged: golang@sha256:32c769bf92205580d6579d5b93c3c705f787f6c648105f00bb88a35024c7f8e4
运行管理
可以通过docker create
来创建容器
$ docker create --name nginx nginx:latest
fb0125e4f477c5fa9046db8a134eb9f0c8a7610508c690947c86f9c1149f2413
Docker会根据所给出的镜像创建容器,在控制台中会打印出Docker为容器所分配的容器ID,此时容器处于Created状态,之后对容器的操作可以通过容器ID或者其缩略形式进行
处于Created状态的容器,其内部的应用程序还未启动,通过docker start
启动
$ docker start nginx
nginx
由于为容器指定了名称,所以可以直接制定名称
当容器启动后,其中应用就会运行出来,容器的几个生命周期,也会绑定到这个应用
docker run
可将docker create
和docker start
合为一步
$ docker run --name centos centos:latest
加上-d可以让容器在后台运行:
$ docker run --name nginx -d nginx:latest
f4b404f3062aacb4640abcfcc1ff5816ed76b96cf64f88d541c93c602a082b7a
使用docker ps
可以列出处于运行中的容器,如果要列出所有状态的容器,要增加-a选项
$ docker ps
docker stop
可以停止正在运行的容器
$ docker stop nginx
使用docker rm
完全删除容器,正在运行的容器默认情况下不可删除
$ docker rm nginx
使用docker exec
让容器运行给出的命令:
docker exec nginx more /etc/hostname
::::::::::::::
/etc/hostname
::::::::::::::
f4b404f3062a
可以打开容器的bash,来实现对容器内虚拟环境的控制
$ docker exec -it nginx bash
root@f4b404f3062a:/#
上述命令要加上-it选项,-i表示保持输入流,只有使用它才能保证控制台程序能够识别命令,-t表示启用一个伪终端,形成与bash的交互
使用docker attach
用于将当前输入输出流连接到指定的容器上
$ docker attach nginx
可以理解为将容器中主程序转为了前台运行
容器网路
打通容器间的网络,使其能够互相通讯:
$ docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql
$ docker run -d --name webapp --link mysql webapp:latest
使用--link选项进行配置,即可实现容器间的网络通讯
网络打通不意味着可以任意访问被连接容器中的任何服务,Docker为容器访问增加了一套安全机制,只有容器自身允许的端口,才能被其他容器访问
使用--expose
可以在容器创建时进行定义暴露的端口
$ docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --expose 13306 --expose 23306 mysql:5.7
f9fd4c57b996247b62b2e20b0bccb3c0f0f255ad12535602ff31cfdad9458843
上述暴露了13306和23306两个端口,可以在docker ps中看到这两个端口已经打开
在docker inspect
中的Networks字段也可以看到网络的相关信息
$ docker inspect mysql
[
{
"Id": "f9fd4c57b996247b62b2e20b0bccb3c0f0f255ad12535602ff31cfdad9458843",
"Created": "2023-02-07T14:01:45.754100581Z",
"Path": "docker-entrypoint.sh",
. .........
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "b590cb0b2c9aee999cfe6ee55353da7771544a5f4db0b20f6f9dccf332ebe498",
"EndpointID": "cea559cd785577a87ec86fab0f0576c410383b0557db037f42553398a461a9c5",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
上述可以看到mysql容器在bridge网络中分配的IP地址,自身的端点和MAC地址,bridge网络的网关地址信息
在没有明确制定容器网络时,容器会连接到bridge网络中
在docker中可以创建网络,形成自己定义的虚拟子网
$ docker network create -d bridge individual
27e2b2b893b89f2b8a8474d925855e00edfb4ca27a3c9102392b921572f2216f
-d选项可以为新的网络指定驱动的类型,其值可以是bridge(默认),也可以是其他类型
使用docker network ls
可以查看docker已经存在的类型:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
b590cb0b2c9a bridge bridge local
95aa02052f1e host host local
27e2b2b893b8 individual bridge local
创建容器时,可以通过--network
来指定容器加入的网络,一旦被指定,容器便不会默认加入到bridge这个网络中了
$ docker run -d --name mysql57 -e MYSQL_RANDOM_ROOT_PASSWORD=yes --network individual mysql:5.7
634883bd92f2c57cb6e3190eb6fb2112af9ac7b8d5ede66233ac741b4fa62796
此时再查看其Network字段:
"Networks": {
"individual": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"634883bd92f2"
],
"NetworkID": "27e2b2b893b89f2b8a8474d925855e00edfb4ca27a3c9102392b921572f2216f",
"EndpointID": "e21cb42cbfb537b09e286fc659d2d3b4d2aaf6a55509380fb8efbd87afe296fa",
"Gateway": "172.19.0.1",
"IPAddress": "172.19.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:13:00:02",
"DriverOpts": null
}
}
...
可见容器所加入的网络已经变成了individual网络,如下可以将其他容器连接到这个网络
$ docker run -d --name webapp --link mysql --network individual webapp:latest
使用-p可以进行端口映射
$ docker run -d --name nginx -p 80:80 -p 443:443 nginx
213cb28960cdfee22d6907b9534b9bb99a2e767e770c98c5bbecf0c985c12188
存储数据
使用-v选项来指定内外挂载的对应目录或文件,挂载文件到容器
$ docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html nginx
d8653640c428f17214f88d50f2eec3e194d0ea8f357cd4bff4174e00706be124
形式是 -v <host-path>:<container-path>
或 --volume <host-path>:<container-path>
,其中 host-path 和 container-path 分别代表宿主操作系统中的目录和容器中的目录,为了避免混淆,Docker 这里强制定义目录时必须使用绝对路径,不能使用相对路径
之后就可以看到宿主操作系统中的文件出现在了容器中的目录
在挂载的宿主机目录下创建index.html,会发现容器挂载到目录下也出现了该文件
$ docker exec nginx ls /usr/share/nginx/html
index.html
通过docker inspect
可以看到挂载信息:
"Mounts": [
{
"Type": "bind",
"Source": "/webapp/html",
"Destination": "/usr/share/nginx/html",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
挂载信息中可以看到一个RW字段,这表示挂载目录或文件的读写性
Docker 还支持以只读的方式挂载,通过只读方式挂载的目录和文件,只能被容器中的程序读取,但不接受容器中程序修改它们的请求。在挂载选项 -v
后再接上 :ro
就可以只读挂载
-tmpfs可以挂载临时目录:
$ docker run -d --name webapp --tmpfs /webapp/cache webapp:latest
此处利用内存来存储数据,由于内存不是持久性存储设备,所以带给Tmpfs Mount的特征就是临时性挂载
-v还可以定义数据卷,其本质依然是宿主操作系统上的一个目录,不过放在容器内部,接收docker管理
$ docker run -d --name golang -v /storage golang:alpine
c15750feba4aec5040491f5530eb4eaef7bd92c38ae23f1b8e9172dc4a88cdde
查看其挂载信息:
"Mounts": [
{
"Type": "volume",
"Name": "73eb66e64795352afd6e81384147b7372450e234938fbb71a3c07f1499502950",
"Source": "/var/lib/docker/volumes/73eb66e64795352afd6e81384147b7372450e234938fbb71a3c07f1499502950/_data",
"Destination": "/storage",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
Type类型为volume,如果希望数据在多个容器间共享,利用数据卷可以在保证数据持久性和完整性的前提下完成自动化操作
使用docker volume create
独立创建数据卷:
$ docker volume create appdata
appdata
通过docker volume ls
可以列出当前已创建的数据卷:
$ docker volume ls
DRIVER VOLUME NAME
...
local appdata
...
同理,删除数据卷:
$ docker volume rm appdata
appdata
使用--mount可以更丰富地配置挂载,使用CSV格式来定义多个参数
sudo docker run -d --name webapp webapp:latest --mount 'type=volume,src=appdata,dst=/webapp/storage,volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>' webapp:latest
Docker容器核心实践(操作容器)的更多相关文章
- docker 实践三:操作容器
在学习了 docker 镜像的内容后,我们在来看 docker 的另一个核心点:容器. 注:环境为 CentOS7,docker 19.03 docker 的容器是镜像的一个运行实例.docker 镜 ...
- docker 基础之操作容器
Docker子命令分类 Docker 环境信息 info .version 容器生命周期管理 Create.exec.kill.pause.restart.rm.run.start.stop.unpa ...
- docker镜像、容器以及命令操作
docker image docker image是一个极度精简版的Linux程序运行环境,官网的java镜像包括的东西更少,除非是镜像叠加方式的如centos+java7 docker image是 ...
- Docker实战(二)之操作Docker容器
容器是Docker的另外一个核心概念.简单来说,容器是镜像的一个运行实例.所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层.如果认为虚拟机是模拟运行的一整套操作系统系统(包括内核,应 ...
- Kubernetes+Docker+Istio 容器云实践
随着社会的进步与技术的发展,人们对资源的高效利用有了更为迫切的需求.近年来,互联网.移动互联网的高速发展与成熟,大应用的微服务化也引起了企业的热情关注,而基于Kubernetes+Docker的容器云 ...
- 容器化之路Docker网络核心知识小结,理清楚了吗?
Docker网络是容器化中最难理解的一点也是整个容器化中最容易出问题又难以排查的地方,加上使用Kubernets后大部分人即使是专业运维如果没有扎实的网络知识也很难定位容器网络问题,因此这里就容器网络 ...
- Docker 与 K8S学习笔记(二)—— 容器核心知识梳理
本篇主要对容器相关核心知识进行梳理,通过本篇的学习,我们可以对容器相关的概念有一个全面的了解,这样有利于后面的学习. 一.什么是容器? 容器是一种轻量级.可移植.自包含的软件打包技术,使应用程序可以在 ...
- Docker容器入门实践
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目.它基于 Google 公司推出的 Go 语言实现. 项目后来加入了 Linux 基金会,遵从了 ...
- Docker操作容器2
Docker操作容器1:https://blog.csdn.net/Kevinnsm/article/details/ 1.如何更改docker容器中的配置文件(如nginx容器中的nginx.con ...
- docker学习笔记2:容器操作
一.列出主机上已经创建的容器 docker ps -a 二.创建交互式容器 命令: docker run -i -t ubuntu /bin/bash 其中-i -t 表示创建一个提供交互式shell ...
随机推荐
- JS变量之间赋值,修改变量值,原变量会随之改变的问题
现象: 开发vue项目的过程中,需要多次用到一份基础数据,为减少代码量,提高一下复用效果,便用变量A来定义,在项目中需要用到时就用变量A进行赋值. 在项目中调用时,我新定义一个变量B,再将变量A赋值给 ...
- echarts图表自适应屏幕/浏览器窗口大小
昨天完成echarts柱状图的生成,突然发现在项目中还有个小缺陷,当柱状图完成渲染之后,放大缩小浏览器窗口echarts柱状图宽度没有随之改变. 接昨天的代码做了小调整: setTimeout(fun ...
- pdb 和 gdb 联调 python + cpython源码
起因: 下面这段奇怪的 python 代码,一个奇怪的 bug,简单来说就是在一个模块内定义了一个 class Test, 然后创建了一个 Test 的对象 ,然后在一个函数内通过 from impo ...
- Assert的使用和简单解释
Assert 的简单使用 Document d = Jsoup.connect("http://www.baidu.com").get(); Assert.notNull(d, & ...
- 转:MyBatis 日志打印
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012666996/article/details/79106599Mybatis SQL语句控制台 ...
- filebeat+elasticsearch+kibana
一.到elasticsearch官网下载 filebeat+elasticsearch+kibana http://www.elasticsearch.cn/ 二.安装filebeat tar -xz ...
- 爬快手,graphql查询语言
graphql查询语言:https://blog.csdn.net/qq_41882147/article/details/82966783 即:前端调用同一个接口传入不同的操作,得到不同的返回值 一 ...
- vue路由守卫并向后台发送token
vue代码 //全局路由首位:当路由发生异常首先执行的方法 router.beforeEach((to, from, next) => { //是否被认证 var isAuthenticated ...
- c++实现类似python的map一样,批量操作一个vector的功能【python一样写c++、三】
python里有一个东西,叫map. 它可以实现像这样,对list每个元素进行操作,并返回新的list(python3是迭代器) 像这样 a=list(map(int,input().split()) ...
- Python Web开发初试,基于Flask
目录 关于web框架 Python flask使用 关于web框架 仅仅对于应用层的coder而言,web框架的使用其实就是写路由,分发路由,写输出.当然如果要安全,要测试,要写优秀的接口,那需要继续 ...