Skip to content

Docker

安装

镜像加速

常用命令

帮助命令

bash
docker version     #显示docker的版本信息。
docker info        #显示docker的系统信息,包括镜像和容器的数量,更详细
docker 命令 --help  #帮助命令

#例如:方便查看语法格式,可选参数等,十分爽到
docker images --help
docker search --help
docker pull --help

镜像命令

bash
docker images #查看所有本地主机上的镜像
docker search #搜索镜像
docker pull   #下载镜像
docker rmi    #删除镜像

1. docker images

bash
docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   3 months ago   13.3kB

#1.解释
#REPOSITORY   # 镜像的仓库源
#TAG        # 镜像的标签(版本)  ---lastest 表示最新版本
#IMAGE ID     # 镜像的id
#CREATED     # 镜像的创建时间
#SIZE        # 镜像的大小

#2.可选项(常用的2个)
Options:
  -a, --all         Show all images (default hides intermediate images) #列出所有镜像
  -q, --quiet       Only show numeric IDs # 只显示镜像的id

#3.示例
# docker images -a  #列出所有镜像详细信息
# docker images -aq #列出所有镜像的id
bash
# docker search mysql

#1.可选参数filter
Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output
# --filter=STARS=3000   #过滤,搜索出来的镜像收藏STARS数量大于3000的

#2.示例:
# docker search mysql --filter=STARS=3000

3. docker pull

bash
# 下载镜像 docker pull 镜像名[:tag]
# 上方的tag表示的是镜像的版本,如果不加就是默认下载的最新版
# docker pull mysql
Using default tag: latest           #下载的最新版
latest: Pulling from library/mysql
69692152171a: Pull complete         #分层下载: docker image 的核心 联合文件系统
1651b0be3df3: Pull complete
951da7386bc8: Pull complete
0f86c95aa242: Pull complete
37ba2d8bd4fe: Pull complete
6d278bb05e94: Pull complete
497efbd93a3e: Pull complete
f7fddf10c2c2: Pull complete
16415d159dfb: Pull complete
0e530ffc6b73: Pull complete
b0a4a1a77178: Pull complete
cd90f92aa9ef: Pull complete
Digest: sha256:d50098d7fcb25b1fcb24e2d3247cae3fc55815d64fec640dc395840f8fa80969 #签名,防伪标志
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址

#知道真实地址:
#所以docker pull mysql等价于docker pull docker.io/library/mysql:latest

4. docker rmi

bash
#1.首先我们查询出docker中的镜像
# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
mysql         5.7       2c9028880e58   4 weeks ago    447MB
mysql         latest    c0cdc95609f1   4 weeks ago    556MB
hello-world   latest    d1165f221234   3 months ago   13.3kB

#2.删除镜像,可以通过REPOSITORY或者IMAGE ID来删除
docker rmi -f 镜像id #删除指定id的镜像
#咱们尝试通过mysql5.7的image id来删除它
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker rmi -f 2c9028880e58
Untagged: mysql:5.7
Untagged: mysql@sha256:a682e3c78fc5bd941e9db080b4796c75f69a28a8cad65677c23f7a9f18ba21fa
Deleted: sha256:2c9028880e5814e8923c278d7e2059f9066d56608a21cd3f83a01e3337bacd68
Deleted: sha256:c49c5c776f1bc87cdfff451ef39ce16a1ef45829e10203f4d9a153a6889ec15e
Deleted: sha256:8345316eca77700e62470611446529113579712a787d356e5c8656a41c244aee
Deleted: sha256:8ae51b87111404bd3e3bde4115ea2fe3fd2bb2cf67158460423c361a24df156b
Deleted: sha256:9d5afda6f6dcf8dd59aef5c02099f1d3b3b0c9ae4f2bb7a61627613e8cdfe562

#3.了解删除全部镜像的命令
docker rmi -f $(docker images -aq) #删除全部的镜像
#通过docker images -aq查询出来的所有镜像进行删除

# docker images -aq | xargs docker rmi

5. docker commit

bash
# 命令和git原理类似
docker commit -m="描述信息" -a="作者名字" 容器id 目标镜像名:[版本TAG]

容器命令

bash
docker run 镜像id     #新建容器并启动
docker ps             #列出所有运行的容器 docker container list
docker rm 容器id      #删除指定容器
docker start 容器id   #启动容器
docker restart 容器id #重启容器
docker stop 容器id   #停止当前正在运行的容器
docker kill 容器id   #强制停止当前容器

1. 新建容器并启动

bash
docker run [可选参数] image | docker container run [可选参数] image
#参数说明
--name="Name"  #容器名字,比如:tomcat01 tomcat02 用来区分容器
-d         #后台方式运行
-it         #使用交互方式运行,进入容器查看内容
-p         #指定容器的端口,-p 8080(宿主机):8080(容器)
  #-p,这个是小写p。主要用法有几种:
 #1.-p 主机端口:容器端口(常用)
 #2.-p 容器端口
 #3.容器端口
 #4.-p ip:主机端口:容器端口
-P     #大写P,随机指定端口

例子:

bash
#1.使用命令运行并进入容器,通过的是bash命令
# docker run -it centos bin/bash
# ls
bin  etc   lib   lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
#4.退出容器到主机
# exit

2. 列出容器

bash
docker ps 命令     #列出当前正在运行的容器
  -a, --all         #列出当前正在运行的容器 + 历史运行过的容器
  -n=?, --last int   #列出最近创建的?个容器 ?为1则只列出最近创建的一个容器,为2则列出2个
  -q, --quiet        #只列出容器的编号

3. 退出容器

bash
exit       #容器直接退出
ctrl +P +Q  #容器不停止退出  ---注意:这个很有用的操作

4. 删除容器

bash
docker rm 容器id               #删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -rf
docker rm -f $(docker ps -aq)    #删除所有的容器,又是参数传递方式,搜出来的结果删
docker ps -a -q|xargs docker rm  #删除所有的容器

5. 后台启动容器

bash
#1.后台运行centos
# docker run -d centos
dfec0e9a77be8a277779477dc0d5d74b2be42e182cd4cd62efa92547f6833b3a
#2.查看运行中的容器,发现没有
# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 问题docker ps. 发现centos 停止了
# 常见的坑,docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止。
#Docker容器后台运行,必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(比如运行ping,sleep),就是会自动退出的。
#(这样想docker发现启动了也提供不了服务,没有东西需要它就自己关闭了,即是快速开,快速关)
# 比如nginx,容器启动后,发现自己没有提供服务,就会立刻停止自杀,就是没有程序了

6. 查看日志

bash
#1.查看
docker logs --help
#可选项
Options:
      --details        Show extra details provided to logs
  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
      --tail string    Number of lines to show from the end of the logs (default "all")
  -t, --timestamps     Show timestamps
      --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)

# docker run -d centos /bin/sh -c "while true;do echo 6666;sleep 1;done" #模拟日志

#2.显示日志
-tf                           #显示日志信息(一直更新)
--tail number                  #需要显示日志条数
docker logs -t --tail n 容器id #查看n行日志
docker logs -ft 容器id         #跟着日志

7. 容器中进程信息 ps

bash
docker top 容器id

8. 查看镜像的元数据

bash
docker inspect 容器id

9. 进入当前正在运行的容器

bash
#我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
#====================方式一====================
#1.命令
docker exec -it 容器id bashshell

#2.测试
#进入容器
docker exec -it 0694e2e1032c bin/bash
#进入容器之后我们想干嘛干嘛,比如使用ls命令查看东西之类
ls
bin  etc   lib   lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr

#====================方式二====================
#1.命令
docker attach 容器id
#2.测试
docker attach 0694e2e1032c
正在执行当前的代码...
#方式一和方式二的区别
#docker exec   #进入当前容器后开启一个新的终端,可以在里面操作。(常用)
#docker attach #进入容器正在执行的终端,不会启动新的进程

10 .从容器内拷贝到主机

bash
#1.命令
docker cp 容器id:容器内路径(文件名)  主机目的路径
#2.测试
docker cp 0694e2e1032c:/hello.java /home
#将容器内部的/hello.java移动到主机的/home目录下,即使容器关闭了,也可以拷贝出来

#拷贝是一个手动过程,未来我们使用-v卷的技术,可以实现自动同步

11. 其他

shell
#elasticsearch非常占内存,我们可以修改配置文件,进行限制内存使用#修改配置文件 -e 环境配置修改
# 在我们之前的启动命令中加入:-e ES_JAVA_OPTS="-Xms64m -Xmx512m",限定内存在64mb-512mb之间
docker run -d --name elasticsearch2 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

容器数据卷

容器的持久化和同步操作!容器间也是可以数据共享的!

1. -v 挂载

shell
#1. 语法:主要是这个-v
docker run -it -v 主机目录:容器内目录  -p 主机端口:容器内端口

#2. run一个centos容器,并使用目录挂载
# /home/ceshi:主机home目录下的ceshi文件夹  映射:centos容器中的/home
# 将容器里边的home目录挂载到linux的home下边的ceshi目录
docker run -it -v /home/ceshi:/home centos /bin/bash

#3.  docker inspect 容器id 查看是否挂载成功
[root@iZ2vc28obhvfham8wewhh0Z /]# docker inspect 54db68df3d7f
#具体看下图的Mounts部分,以后两个地址的内的数据可以相互同步的

2. mysql 数据持久化

shell
#1. 获取mysql镜像
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker pull mysql:5.7

#2. 运行容器的时候需要做数据挂载,此处我们挂载了配置文件以及数据目录(有两个哦),同时咱们也配置了mysql的密码
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
-- name 容器名字
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

#3. 启动成功之后,我们可以在本地去连接上服务器的mysql,如下图所示
#咱们走的是3310端口,3310端口映射了容器的3306端口,所以说我们本质还是访问到的容器

3. 具名匿名挂载

shell
#1. 匿名挂载
-v 容器内路径!,这里我们没有写主机的路径,那么它就会自动的生成一个目录
#1-1. 使用命令匿名挂载
docker run -d -P --name nginx01 -v /etc/nginx nginx

#1-1. 查看所有volume(卷)的情况
[root@iZ2vc28obhvfham8wewhh0Z data]# docker volume ls
DRIVER    VOLUME NAME(卷名字,这个一串乱码其实是真实存在的目录)
local     dd3decdb4e2533d16d216ba19d8797c2ad95b4a2a1b6a90f87eb98bbed3b3758
# 注:这里发现,这种就是匿名挂载,我们在 -v只写了容器内的路径,没有写容器外的路径!

#2. 具名挂载
#2-1. 使用命令具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
# 注1:juming-nginx:/etc/nginx,给/etc/nginx命名为juming-nginx,并没有写主机地址哈
# 注2:说白了就是 -v 卷名:容器内路径

#2-2. 查看一下这个卷
[root@iZ2vc28obhvfham8wewhh0Z data]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2021-06-25T20:18:22+08:00",
        "Driver": "local",
        "Labels": null,
        #注意看这儿:下方就是我们挂载到主机的具体路径了
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

总结

shell
# 三种挂载: 匿名挂载、具名挂载、指定路径挂载
-v 容器内路径         #匿名挂载
-v 卷名:容器内路径      #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的

扩展

shell
# 通过 -v 容器内路径: ro rw 改变读写权限
ro #readonly 只读
rw #readwrite 可读可写
$ docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
$ docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx

# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!

4. 数据卷容器

  • 父容器:A 去挂载 B,那么 B 就是 A 的父容器
  • 数据卷容器:被挂载的容器
shell
docker run -it --name docker02 --volumes-from docker01 centos

容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。

但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!

Dockerfile

Dockerfile 指令

shell
FROM     # from:基础镜像,一切从这里开始构建
MAINTAINER  # maintainer:镜像是谁写的, 姓名+邮箱
RUN     # run:镜像构建的时候需要运行的命令
ADD     # add:步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR    # workdir:镜像的工作目录
VOLUME    # volume:挂载的目录位置
EXPOSE    # expose:暴露端口配置
CMD     # cmd:指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT   # entrypoint:指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD    # onbuild:当构建一个被继承DockerFile这个时候就会运行onbuild的指令,是触发指令
COPY    # copy:类似ADD,将我们文件拷贝到镜像中
ENV     # env:构建的时候设置环境变量!
shell
FROM centos
MAINTAINER tom<a@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash
shell
docker build -f dockerfile-centos -t mycentos:0.1 .

CMD 与 ENTRYPOINT

shell
CMD         # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT   # 指定这个容器启动的时候要运行的命令,可以追加命令

Docker 网络

1. 原理

shell
#我们发现这个容器带来网卡,都是一对对的
# veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
# 正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术

情况一:路由器可以直接去访问容器

img

情况二:容器之间的访问,比如 Tomcat01 去访问 Tomcat02,路由器就是作为一个中间商

img

shell
#Tomcat01和Tomcat02是共用的一个路由器,docker0
#所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip

Docker 使用的是 Linux 的桥接,宿主机是一个 Docker 容器的网桥 docker0

img

本质就是在 hosts 配置中添加映射,现在使用 Docker 已经不建议使用–-link 了!

3. 自定义网络

网络模式:

  • bridge :桥接 docker(默认,自己创建也是用 bridge 模式)
  • none :不配置网络,一般不用
  • host :和宿主机共享网络
  • container :容器网络连通(用得少!局限很大)
shell
# 我们直接启动的命令 --net bridge,而这个就是我们的docker0
# bridge就是docker0
#"--net bridge"就是默认参数
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat
#------------------------------------------------------
#------------------------------------------------------

#自定义网络:

#1. 清理环境,删除之前的容器
docker rm -f  $(docker ps -aq)

#2. 创建一个子网为“192.168.0.0/16”,网关(路由)为“192.168.0.1”,网络名字为“mynet”的网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

#3. 查看创建的网络
docker network ls

#4. 创建两个个tomcat使用我们自定义的网络
docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat

#5. 然后查看我们自定义的网络,如下图所示
docker network inspect 56505443b59d

#6. 我们再来ping容器
docker exec -it tomcat-net-01 ping tomcat-net-02
docker exec -it tomcat-net-01 ping 192.168.0.3

4. 网络联通

img

shell
#语法:docker network connect [OPTIONS] NETWORK CONTAINER
#1. 之前删除的tomcat01和tomcat02创建好
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat02 tomcat

#2. 打通tomcat01和mynet
docker network connect mynet tomcat01

#3. 查看网络配置,如下图所示:
docker network inspect mynet
# 要将tomcat01 连通 tomcat—net-01 ,连通就是将 tomcat01加到 mynet网络
# 一个容器两个ip(tomcat01)

#4. 现在我们再ping一下
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it tomcat01 ping tomcat-net-02

5.测试

shell
#1. 先移除之前的容器
docker rm -f $(docker ps -aq)

#2. 创建redis的网卡
docker network create redis --subnet 172.38.0.0/16

#3. 通过脚本去写配置文件
for port in $(seq 1 6);\
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >> /mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

#4. 通过脚本创建六个redis文件
for port in $(seq 1 6);\
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
#5. 然后依次运行
docker exec -it redis-1 /bin/sh
docker exec -it redis-2 /bin/sh
docker exec -it redis-3 /bin/sh
docker exec -it redis-4 /bin/sh
docker exec -it redis-5 /bin/sh
docker exec -it redis-6 /bin/sh

#6. 创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379  --cluster-replicas 1

Docker Compose

定义运行多个容器

地址:https://docs.docker.com/compose/gettingstarted/

https://docs.docker.com/compose/wordpress/

shell
docker-compose down         # 关闭容器
docker-compose up --build   # 重新构建
docker-compose up -d

Docker Swarm

4 台机器,xshell 同步操作

img

Manager nodes

使用Raft实现,管理者保持整个群和所有运行在它的服务的一致内部状态

  • 管理集群状态
  • 调度

可故障的管理节点数:(N-1)/2

3 个最多可以有一个故障

5 个最多可以有两个故障

一个几圈最多简易有 7 个管理节点

增加更多的管理者并不意味着可扩展性或更高的性能。一般来说,情况正好相反

Worker nodes

  • 执行容器

命令

初始化

shell
docker swarm init --help

ip addr # 获取自己的ip(用内网的不要流量)

docker swarm init --advertise-addr 172.16.250.97
Swarm initialized: current node (otdyxbk2ffbogdqq1kigysj1d) is now a manager.
To add a worker to this swarm, run the following command:
    docker swarm join --token SWMTKN-1-3vovnwb5pkkno2i3u2a42yrxc1dk51zxvto5hrm4asgn37syfn-0xkrprkuyyhrx7cidg381pdir 172.16.250.97:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
shell
# 获取令牌
docker swarm join-token manager
docker swarm join-token worker

# 加入swarm
docker swarm join --token SWMTKN-1-3vovnwb5pkkno2i3u2a42yrxc1dk51zxvto5hrm4asgn37syfn-0xkrprkuyyhrx7cidg381pdir 172.16.250.97:2377

# 离开swarm
docker swarm leave
shell
docker run     # 容器启动! 不具有扩缩容器
docker service # 服务! 具有扩缩容器,滚动更新!
shell
# 查看服务列表
docker service ls

# 查看服务信息
docker service ps servicename

# 扩缩容
docker service update --replicas 3 my-nginx
docker service scale my-nginx=5

# 移除
docker service rm

service 如何工作

services diagram

任务和调度

services flow

副本和服务

global vs replicated services

reference

狂神 Docker 学习笔记_Lemonyuki 的博客-CSDN 博客

Docker 入门学习笔记(21h/2d 4.14-16) (u19900101.github.io)

sh
# grep 筛选 -v 不匹配
docker images | grep -v 'latest' | awk 'NR>1 {print $3}' | xargs docker rmi
# awk 'NR>1 && $2!="latest" {print $3}':从第二行开始筛选标签不为 latest 的镜像 ID。
docker images my-app | awk 'NR>1 && $2!="latest" {print $3}' | xargs docker rmi