本文以参与[新人创作礼]活动,一起开启掘金创作之路
镜像基础命1令
pull
下载镜像的命令。镜像从远程镜像仓库服务的仓库中下载。默认情况下,镜像会从 Docker Hub 的
仓库中拉取。
通过下载过程,可以看到,一个镜像一般是由多个层组成,类似 f7e2b70d04ae 这样的串表示层的
唯一 ID。
docker pull tomcat:9.0.20-jre8-alpine
image
通过使用如下两个命令,列出本机已有的镜像
docker images
docker image ls
save
保存一个镜像包
docker save tomcat:9.0.20-jre8-alpine -o tomcat9.tar
docker save tomcat:9.0.20-jre8-slim > tomcat9.slim.tar
load
加载一个镜像包
docker load -i linux.tar
docker load < tomcat9.0.20.tar
search
不推荐使用search命令查找镜像,不够直观。
docker search tomcat
inspect
通过 docker inspect 命令,我们可以获取镜像的详细信息,其中,包括创建者,各层的数字摘要
等。
docker inspect 返回的是 JSON格式的信息,如果您想获取其中指定的一项内容,可以通过 -f 来指
定,如获取镜像大小
docker inspect tomcat:9.0.20-jre8-alpine
docker inspect -f {{".Size"}} tomcat:9.0.20-jre8-alpine
history
一个镜像是由多个层组成的, 通过 docker history命令,可以列出各个层的创建信息,例如:查看 tomcat:9.0.20-jre8-alpine的各层 信息
docker history tomcat:9.0.20-jre8-alpine
tag
标记本地镜像,将其归入某一仓库
docker tag tomcat:9.0.20-jre8-alpine lagou/tomcat:9
rmi
通过如下两个都可以删除镜像
docker rmi tomcat:9.0.20-jre8-alpine
docker image rm tomcat:9.0.20-jre8-alp
容器基础命令
运行容器
docker run -it --rm -p 8080:8080 tomcat:9.0.20-jre8-alpine
容器日志
docker run -itd --name tomcat9 -p 8080:8080 tomcat:9.0.20-jre8-alpine
docker logs -f tomcat9
删除容器
docker rm [OPTIONS] CONTAINER [CONTAINER...]
查看容器列表
docker ps [OPTIONS]
创建容器
创建一个容器但是不启动
docker create -it --name tomcat9 -p 8080:8080 9.0.20-jre8-alpine
启动、重启、终止
docker start tomcat9
docker stop tomcat9
docker restart tomcat9
进入容器
docker exec -it tomcat9.1 /bin/bash docker exec -it tomcat9.1 /sh
查看容器
docker inspect tomcat9
杀掉容器
docker kill tomcat9
网络
自建网络
docker安装后会自动创建3种网络: bridge host none
docker network ls
docker网络理论部分
docker使用Linux桥接网卡,在宿主机虚拟一个docker容器网桥(docker0),docker启动一个容器时会根 据docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时docker网桥是每个容器的默认网 关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接 通信。 docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着 外部网络无法通过直接Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容 器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时 候就通过[宿主机IP]:[容器端口]访问容器。
docker info
网络模式
bridge模式
默认的网络模式。bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的,但容
器通过宿主机的NAT规则后可以访问外网。
Bridge 桥接模式的实现步骤主要如下:
-
Docker Daemon 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为veth0 和veth1。而veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方。
-
Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0网桥上。保证宿主机的网络报文可以发往 veth0;
-
Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为eth0。如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到DockerContainer网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。
Bridge桥接模式的缺陷:
- 最明显的是,该模式下 Docker Container 不具有一个公有 IP,即和宿主机的 eth0 不处于同一个网段。导致的结果是宿主机以外的世界不能直接和容器进行通信。
- 虽然 NAT 模式经过中间处理实现了这一点,但是 NAT 模式仍然存在问题与不便,如:容器均需要在宿主机上竞争端口,容器内部服务的访问者需要使用服务发现获知服务的外部端口等。
- 另外 NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率.
注意:
veth设备是成双成对出现的,一端是容器内部命名为eth0,一端是加入到网桥并命名的veth(通常命名 为veth),它们组成了一个数据传输通道,一端进一端出,veth设备连接了两个网络设备并实现了数据 通信
host模式
相当于Vmware中的NAT模式,与宿主机在同一个网络中,但没有独立IP地址。
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是 和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿 主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机 的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就 不能再用了,网络的隔离性不好。
host网络模式需要在容器创建时指定–network=host
host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用宿主机 的 IP地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有IP。同时容器内 服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。 host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离 性。
Host 网络模式的缺陷:
最明显的是 Docker Container 网络环境隔离性的弱化。即容器不再拥有隔离、独立的网络环境。
另外,使用 host 模式的 Docker Container 虽然可以让容器内部的服务和传统情况无差别、无改造的使 用,但是由于网络隔离性的弱化,该容器会与宿主机共享竞争网络栈的使用;
另外,容器内部将不再拥有所有的端口资源,原因是部分端口资源已经被宿主机本身的服务占用,还有 部分端口已经用以 bridge 网络模式容器的端口映射。
Container网络模式
一种特殊host 网络模式
Container 网络模式是 Docker 中一种较为特别的网络的模式。在容器创建时使用– network=container:vm1指定。(vm1指定的是运行的容器名)
处于这个模式下的 Docker 容器会共享一个网络环境,这样两个容器之间可以使用localhost高效快速通 信。
缺陷:它并没有改善容器与宿主机以外世界通信的情况(和桥接模式一样,不能连接宿主机以外的其他 设备)。
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共 享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。 同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信
none模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网 络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网 卡、配置IP等。
这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过-- network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性
overlay 网络模式
Overlay 网络,也称为覆盖网络。主要用于docker集群部署。
Overlay 网络的实现方式和方案有多种。Docker自身集成了一种,基于VXLAN隧道技术实现。
Overlay 网络主要用于实现跨主机容器之间的通信。
应用场景:需要管理成百上千个跨主机的容器集群的网络时
macvlan 网络模式
macvlan网络模式,最主要的特征就是他们的通信会直接基于mac地址进行转发。
这时宿主机其实充当一个二层交换机。Docker会维护着一个MAC地址表,当宿主机网络收到一个数据包 后,直接根据mac地址找到对应的容器,再把数据交给对应的容器。
容器之间可以直接通过IP互通,通过宿主机上内建的虚拟网络设备(创建macvlan网络时自动创建), 但与主机无法直接利用IP互通。
应用场景:由于每个外来的数据包的目的mac地址就是容器的mac地址,这时每个容器对于外面网络来 说就相当于一个真实的物理网络设备。因此当需要让容器来的网络看起来是一个真实的物理机时,使用 macvlan模式
Macvlan是一个新的尝试,是真正的网络虚拟化技术的转折点。Linux实现非常轻量级,因为与传统的 Linux Bridge隔离相比,它们只是简单地与一个Linux以太网接口或子接口相关联,以实现网络之间的分 离和与物理网络的连接。
Macvlan提供了许多独特的功能,并有充足的空间进一步创新与各种模式。这些方法的两个高级优点是 绕过Linux网桥的正面性能以及移动部件少的简单性。删除传统上驻留在Docker主机NIC和容器接口之间 的网桥留下了一个非常简单的设置,包括容器接口,直接连接到Docker主机接口。由于在这些情况下没 有端口映射,因此可以轻松访问外部服务。
Macvlan Bridge模式每个容器都有唯一的MAC地址,用于跟踪Docker主机的MAC到端口映射。 Macvlan驱动程序网络连接到父Docker主机接口。示例是物理接口,例如eth0,用于802.1q VLAN标记 的子接口eth0.10(.10代表VLAN 10)或甚至绑定的主机适配器,将两个以太网接口捆绑为单个逻辑接 口。 指定的网关由网络基础设施提供的主机外部。 每个Macvlan Bridge模式的Docker网络彼此隔离, 一次只能有一个网络连接到父节点。
每个主机适配器有一个理论限制,每个主机适配器可以连接一个Docker网络。 同一子网内的任何容器都 可以与没有网关的同一网络中的任何其他容器进行通信macvlan bridge。 相同的docker network命令 适用于vlan驱动程序。 在Macvlan模式下,在两个网络/子网之间没有外部进程路由的情况下,单独网络 上的容器无法互相访问。这也适用于同一码头网络内的多个子网。
bridge网络
bridge网络表现形式就是docker0这个网络接口。容器默认都是通过 docker0这个接口进行通信。也可以通过docker0去和本机的以太网接口连接,这样容器内部才能访问互 联网
Docker 创建一个容器的时候,会执行如下操作:
- 创建一对虚拟接口/网卡,也就是veth pair,分别放到本地主机和新容器中;
- 本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 vetha596da4;
- 容器一端放到新容器中,并修改名字作为 eth0,这个网卡/接口只在容器的名字空间可见;
- 从网桥可用地址段中(也就是与该bridge对应的network)获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 vetha596da4。
完成这些之后,容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。 如果不指定--network,创建的容器默认都会挂到 docker0 上,使用本地主机上 docker0 接口的 IP 作为 所有容器的默认网关。
创建bridge网络
当有两个容器需要通讯时,需要知道相互之间的ip地址,但是当容器重启时ip地址会发生变化,为了解决此问题docker中可以使用--link来完成两个容器的关联,但是这个参数有一定的安全问题,所以不仅已使用
我们可以创建一个bridge网络来解决此问题
docker network create -d bridge mybridge
新建容器将其的网络与自定义网络绑定
docker run -itd --name nginx --network mybridge nginx:1.19.3-alpine
把一个运行中容器连接到mybridge网络
docker network connect mybridge nginx2
docker network inspect mybridge
none网络
注意,容器使用none模式,是没有物理地址和IP地址。我们可以进入到nginx1容器里,执行ip a命令看 看。只有一个lo接口,没有其他网络接口,没有IP。也就是说,使用none模式,这个容器是不能被其他 容器访问。这种使用场景很少,只有项目安全性很高的功能才能使用到。例如:密码加密算法容器
host网络
容器使用了host模式,说明容器和外层linux主机共享一套网络接口。VMware公司的虚 拟机管理软件,其中网络设置,也有host这个模式,作用也是一样,虚拟机里面使用网络和你自己外层 机器是一模一样的。这种容器和本机使用共享一套网络接口,缺点还是很明显的,例如我们知道web服 务器一般端口是80,共享了一套网络接口,那么你这台机器上只能启动一个nginx端口为80的服务器 了。否则,出现端口被占用的情况。
固定ip地址
docker network create -d bridge --subnet=172.172.0.0/24 --gateway 172.172.0.1 mynetwork
172.172.0.0/24: 24代表子码掩码是255.255.255.0
172.172.0.0/16: 16 代表子码掩码
docker network ls
docker run -itd --name nginx3 -p 80:80 --network mynetwork --ip 172.172.0.10 nginx:1.19.3-alpine
--net mynetwork:选择存在的网络
--ip 172.172.0.10:给nginx分配固定的IP地址
数据
容器中的管理数据主要有两种方式:
- 数据卷:Data Volumes 容器内数据直接映射到本地主机环境
- 数据卷容器:Data Volume Containers 使用特定容器维护数据卷
cp命令
当然还有最原始的copy方式,这个也是管理数据的方式,但是基本不会用到。 docker cp :用于容器与主机之间的数据拷贝
宿主机文件复制到容器内
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH
容器内文件复制到宿主机
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_
基础镜像
docker pull nginx:1.19.3-alpine
宿主机文件 copy to 容器内
宿主机的index.html页面覆盖容器内的index.html页面
docker run -itd --name nginx -p 80:80 nginx:1.19.3-alpine
cd /data
echo "laosiji" > /data/index.html
docker cp /data/index.html nginx:/usr/share/nginx/html/index.html
数据卷
数据卷(Data Volumes)是一个可供一个或多个容器使用的特殊目录,它将主机操作系统目录直接映射进 容器。
docker run -v /宿主机绝对路径目录:/容器内目录 镜像名
docker volume ls
docker volume inspect 卷名
数据卷容器
基础镜像
docker pull centos:7.8.2003
docker pull nginx:1.19.3-alpine
docker pull mysql:5.7.31
run命令
docker run
- --volumes-from:
如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器 也是一个容器,但是它的目的是专门用来提供数据卷供其他容器挂载。
发现创建好的数据卷容器是处于停止运行的状态,因为使用 —volumes-from 参数所挂载数据卷的容器 自己并不需要保持在运行状态。
docker run -d --name data-volume -v /data/nginx:/usr/share/nginx/html -v
/data/mysql:/var/lib/mysql centos:7.8.2003
docker run -itd --name nginx01 -p 80:80 --volumes-from data-volume nginx:1.19.3-
alpine
echo "lagouedu nginx" > /data/nginx/index.html
http://192.168.198.100
docker run -itd --name nginx02 -p 81:80 --volumes-from data-volume nginx:1.19.3-
alpine
http://192.168.198.100:81
docker run -itd --name mysql01 --restart always --privileged=true -p 3306:3306
-e MYSQL_ROOT_PASSWORD=admin --volumes-from data-volume mysql:5.7.31 --
character-set-server=utf8 --collation-server=utf8_general_ci
docker run -itd --name mysql02 --restart always --privileged=true -p 3307:3306
-e MYSQL_ROOT_PASSWORD=admin --volumes-from data-volume mysql:5.7.31 --
character-set-server=utf8 --collation-server=utf8_general_ci
docker-compose
yml配置文件及常用指令
Docker Compose 使用 YAML 文件来定义多服务的应用。YAML 是 JSON 的一个子集,因此也可以使用 JSON。
Docker Compose 默认使用文件名 docker-compose.yml。当然,也可以使用 -f 参数指定具体文件。
Docker Compose 的 YAML 文件包含 4 个一级 key:version、services、networks、volumes
- version 是必须指定的,而且总是位于文件的第一行。它定义了 Compose 文件格式(主要是API)的版本。注意,version 并非定义 Docker Compose 或 Docker 引擎的版本号。
- services 用于定义不同的应用服务。上边的例子定义了两个服务:一个名为 lagou-mysql数据库服务以及一个名为lagou-eureka的微服。Docker Compose 会将每个服务部署在各自的容器中。
- networks 用于指引 Docker 创建新的网络。默认情况下,Docker Compose 会创建 bridge 网络。这是一种单主机网络,只能够实现同一主机上容器的连接。当然,也可以使用 driver 属性来指定不同的网络类型。
- volumes 用于指引 Docker 来创建新的卷。
version: '3'
services:
my-mysql:
build:
context: ./mysql
environment:
MYSQL_ROOT_PASSWORD: admin
restart: always
container_name: my-mysql
volumes:
- /data/edu-bom/mysql/lagou:/var/lib/mysql
image: mysql:5.7
ports:
- 3306:3306
networks:
my-net:
my-eureka:
build:
context: ./edu-eureka-boot
restart: always
ports:
- 8761:8761
container_name: edu-eureka-boot
hostname: edu-eureka-boot
image: edu-eureka-boot:1.0
depends_on:
- my-mysql
networks:
my-net:
networks:
my-net:
volumes:
my-vol:
常用命令汇总
启动服务
docker-compose -f filename up -d
停止服务
docker-compose down
列出所有运行容器
docker-compose ps
查看服务日志
docker-compose logs
构建或者重新构建服务
docker-compose build
启动服务
docker-compose start
停止已运行的服务
docker-compose stop
重启服务
docker-compose restart
docker私有仓库
仓库镜像
docker pull registry:2.7.1
创建仓库容器
docker run -itd -p 5000:5000 --name registry --restart=always registry:2.7.1
添加私服仓库地址
编辑配置文件
vi /etc/docker/daemon.json
增加仓库配置信息
{ "insecure-registries":["192.168.198.101:5000"] }
重启docker
systemctl daemon-reload
systemctl restart docker
查看docker信息确认仓库是否添加
docker info
浏览器测试 http://192.168.198.101:5000/v2/_catalog
上传镜像
docker tag nginx:1.19.3-alpine 192.168.198.101:5000/nginx:v1 docker push 192.168.198.101:5000/nginx:v1
浏览器查看 http://192.168.198.101:5000/v2/nginx/tags/list
企业仓库
harbor官网地址 goharbor.io/
安装harbor
1.解压软件
cd /data
tar zxf harbor-offline-installer-v1.9.4.tgz
2.进入安装目录
cd harbor
3.修改配置文件
vi harbor.yml
3.1 修改私服镜像地址
hostname: 192.168.198.101
3.2 修改镜像地址访问端口号
port: 5000
3.3 harbor管理员登录系统密码
harbor_admin_password: Harbor12345
3.4 修改harbor映射卷目录
data_volume: /data/harbor
4.安装harbor
4.1 执行启动脚本,经过下述3个步骤后,成功安装harbor私服
./install.sh
4.2 准备安装环境:检查docker版本和docker-compose版本
4.3 加载harbor需要的镜像
4.4 准备编译环境
4.5 启动harbor。通过docker-compose方式启动服务
4.6 google浏览器访问harbor私服
http://192.168.198.101:5000
username: admin
password: Harbor12345
配置私服
vi /etc/docker/daemon.json
"insecure-registries":["192.168.198.101:5000"]
重启docker服务:
systemctl daemon-reload
systemctl restart docker
新建项目 在harbor中新建公共项目: mydockerimage
登录私服
docker login -u admin -p Harbor12345 192.168.198.101:5000
退出私服
docker logout 192.168.198.101:5000
上传nginx镜像
docker tag mariadb:10.5.2 192.168.198.101:5000/mydocker/nginx:1.19.3-alpine
docker push 192.168.198.101:5000/mydocker/nginx:1.19.3-alpine
docker pull 192.168.198.101:5000/mydocker/mariadb:10.5.2
Dockerfile
基于已有的镜像创建 commit命令
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
常用参数
- -a :提交的镜像作者;
- -c :使用Dockerfile指令来创建镜像;
- -m :提交时的说明文字;
- -p :在commit时,将容器暂停。
案例
结合docker cp命令自定义nginx的index页面
docker run -itd --name nginx -p 80:80 192.168.198.101:5000/mydocker/nginx:v1
cd /data
echo "laosiji" > /data/index.html
docker cp /data/index.html nginx:/usr/share/nginx/html/index.html
curl localhost
docker container commit -m "update index.html file" -a "wuxi" nginx
192.168.198.101:5000/mydocker/nginx:v2
docker images
docker rm -f nginx
docker run -itd --name nginx -p 80:80 192.168.198.101:5000/mydocker/nginx:v2
curl localhost
docker push 192.168.198.101:5000/mydocker/nginx:v2
Dockerfile命令
build命令
docker build 命令用于使用 Dockerfile 创建镜像。
docker build [OPTIONS] PATH | URL |
常用参数
build命令参数特别多。这里只给大家介绍几个常用的参数,如果小伙伴们想了解更多内容,请参考 docker官网手册
- --build-arg=[] :设置镜像创建时的变量;
- -f :指定要使用的Dockerfile路径;
- --rm :设置镜像成功后删除中间容器;
- --tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置 多个标签。
制作镜像
docker build --rm -t 192.168.198.101:5000/mydocker/mysql:5.7 .
docker images
运行镜像
docker run -itd --name mysql --restart always -p 3306:3306 -e
MYSQL_ROOT_PASSWORD=admin 192.168.198.101:5000/mydocker/mysql:5.7
docker logs -f mysql
docker exec -it mysql bash
date
观察时间是否与windows系统的时间一致。
测试mysql连接
docker exec -it mysql bash
mysql -uroot -padmin