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 ...
随机推荐
- 微信小程序安装vant
1.初始化npm并安装 npm init -y npm install 2.修改project.config.json { "setting": { "packNpmMa ...
- manjaro安装后配置与美化
时间同步 sudo timedatectl set-ntp true 换源 sudo pacman-mirrors -i -c China -m rank 更新 更新系统 sudo pacman -S ...
- Delphi集合增删的另一种操作
D7 1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, ...
- 10.10 2020 实验 6:OpenDaylight 实验——OpenDaylight 及 Postman 实现流表下发
一.实验目的 熟悉 Postman 的使用:熟悉如何使用 OpenDaylight 通过 Postman 下发流表. 二.实验任务 推荐阅读:SDNLAB 文章:OpenFlow 协议超时机制简介 ...
- Leecode 141.环形链表(Java 快慢指针)
想法: 1:遍历链表,每次判断节点是否被访问过.(哈希表) 2:快慢指针(看题解之后) 两个指针pq都在head头指针开始(初始化): 快指针每次走两步,慢指针每次走一步,如果 ...
- 去除Bigdecimal末尾的.00
String total = new BigDecimal("100.00").stripTrailingZeros().toPlainString();
- Winform 应用DotnetBar
Winform 使用NotNetBar namespace WindowsFormExample { public partial class FrmMain : Office2007Form { p ...
- Repeater 绑定数据是根据数据修改行的颜色值信息
<ItemTemplate> <tr <%# Eval("dayu20").ToString()=="0"? "style=' ...
- 👋 和我一起学【Three.js】「初级篇」:0. 总论
「和我一起学 XXX」是我 2023 年的一个新企划,目的是向读者(也包括未来的自己)介绍我正在学习的某项新技术.文章会通过长期反复迭代的方式保持其内容的新鲜度.文章有较大内容更新时,会在文章开头进行 ...
- Javaweb问题解决--在.java文件里面写sql语句模糊查询不成功的原因
问题描述 在上学期,我就遇到了这个问题(别骂别骂),然后当时卡住之后,Mybatis闯入了我的视线,然后直接换用了较为方便的Mybatis框架结构,这个问题也就被搁置了,今天重新提起,优势慢慢地查阅了 ...