Docker总结

Posted by BenderFly on February 18, 2020

配置 Docker 镜像加速国内加速站点

一定要用阿里云的,最快。 容器镜像服务->镜像加速器

地址 报错:

docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).

vim /etc/docker/daemon.json
{
"insecure-registries":["主机的IP地址或者域名:5000"],
"registry-mirrors": ["https://pyuw8tc5.mirror.aliyuncs.com"]
}


sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://pyuw8tc5.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

查看docker信息

docker version :查看版本
docker info : 显示 Docker 系统信息,包括镜像和容器数。

镜像

查看镜像 列出本地镜像

docker images -a  #-a :列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层)

查找镜像 可以从Docker Hub 网址为: https://hub.docker.com/ 搜索镜像

docker search httpd
#运行镜像
docker run httpd
#删除镜像
docker rmi hello-world

docker build 命令用于使用 Dockerfile 创建镜像。

docker build -t runoob/ubuntu:v1 .   # 最后的.表示上下文路径,copy命令的路径就是根据上下文的相对路径
-f :指定要使用的Dockerfile路径;
--tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;

docker commit :从容器创建一个新的镜像。

docker commit -a "runoob.com" -m "my apache" a404c6c174a2  mymysql:v1   # -a作者,-m备注

删除本地一个或多少镜像

docker rmi -f runoob/ubuntu:v4
-f :强制删除

docker tag : 标记本地镜像,将其归入某一仓库。

docker tag ubuntu:15.10 runoob/ubuntu:v3  # 将镜像ubuntu:15.10标记为 runoob/ubuntu:v3 镜像。

docker history : 查看指定镜像的创建历史。

docker history runoob/ubuntu:v3

查看镜像、容器、数据卷所占用的空间

docker system df  

虚悬镜像(dangling image)由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 的镜像。

docker image ls -f dangling=true  # 查看
docker image prune # 删除

容器

创建容器 docker run :创建一个新的容器并运行

-h "mars": 指定容器的hostname;
-e username="ritchie": 设置环境变量;
--env-file=[]: 从指定文件读入环境变量;
--name="nginx-lb": 为容器指定一个名称;
--volume , -v:	绑定一个卷
docker run --name mynginx -d nginx:latest              # 使用docker镜像nginx:latest以后台模式启动一个容器,并将容器命名为mynginx。
docker run -P -d nginx:latest                          # 使用镜像nginx:latest以后台模式启动一个容器,并将容器的80端口映射到主机随机端口。
docker run -p 80:80 -v /data:/data -d nginx:latest     # 使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。
docker run -p 127.0.0.1:80:8080/tcp ubuntu bash        # 绑定容器的 8080 端口,并将其映射到本地主机 127.0.0.1 的 80 端口上。
docker run -it nginx:latest /bin/bash                  # 使用镜像nginx:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。docker run :创建一个新的容器并运行一个命令

运行容器

docker run --restart=always redis  # --estart 容器退出时自动重启,默认no
docker run --restart=on-failure:10 redis # 非零退出转态,重试10次
docker create  --name my_container  nginx:latest     #创建一个新的容器但不启动它
docker start my_container# 启动一个或多个已经被停止的容器
docker stop my_container#停止一个运行中的容器
docker restart my_container#重启容器
docker kill -s KILL mynginx #杀掉运行中的容器mynginx

docker rm #删除一个或多少容器
docker rm -f db01 db02  # 强制删除容器db01、db02
docker rm -l db         # 移除容器nginx01对容器db01的连接,连接名db
docker rm -v nginx01    # 删除容器nginx01,并删除容器挂载的数据卷
docker container prune  # 清理掉所有处于终止状态的容器

docker pause db01:暂停容器中所有的进程。
docker unpause db01:恢复容器中所有的进程。

查看容器信息

docker container ls
docker container ls -a
docker ps
docker ps -a   #显示所有的容器,包括未运行的。

要获取容器的输出信息

docker container logs
docker container logs [container ID or NAMES]查看容器信息

要获取容器的输出信息

docker container logs
docker container logs [container ID or NAMES]查看容器信息

docker logs -f mynginx  # -f : 跟踪日志输出
docker logs --since="2016-07-01" --tail=10 mynginx  # --since :显示某个开始时间的所有日志 --tail :仅列出最新N条容器日志

获取容器/镜像的元数据

docker inspect mysql:5.6

查看容器中运行的进程信息

docker container top 262242feaa88

列出指定的容器的端口映射

docker port mymysql  #查看容器mynginx的端口映射情况。

检查容器里文件结构的更改

docker diff mymysql

进入容器

docker attach 命令 (exit会导致容器的停止)
docker exec 命令(推荐使用)
docker exec -it 69d1 bash

容器与主机之间的数据拷贝

docker cp /www/runoob 96f7f14e99ab:/www/ # 将主机/www/runoob目录拷贝到容器96f7f14e99ab的/www目录下。
docker cp /www/runoob 96f7f14e99ab:/www  # 将主机/www/runoob目录拷贝到容器96f7f14e99ab中,目录重命名为www。
docker cp  96f7f14e99ab:/www /tmp/       # 将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中。

docker搭建本地私有仓库

1.拉取镜像仓库

docker pull registry 

2.启动镜像服务器registry 首先在在主机上新建一个目录,供存储镜像

cd /usr/local/
mkdir docker_registry 

启动镜像

docker run -d -p 5000:5000 --name=jackspeedregistry --restart=always --privileged=true  -v /usr/local/docker_registry:/var/lib/registry  docker.io/registry

解释

--privileged=true centos7中的安全模块selinux把权限禁止了, 加上这行是给容器增加执行权限
-v /usr/local/docker_registry:/var/lib/registry 把主机的/usr/local/docker_registry 目录挂载到registry容器的/var/lib/registry目录下,假如有删除容器操作,我们的镜像也不会被删除
-p IP:port:port 

3.从公有仓库拉取一个镜像下来,然后push到私有仓库中进行测试 当前用nginx镜像做测试

docker pull  nginx 
docker images 

4.给docker注册https协议,支持https访问

vim /etc/docker/daemon.json
{
"insecure-registries":["主机的IP地址或者域名:5000"],
"registry-mirrors": ["https://registry.docker-cn.com"]
}
注释:
insecure-registries--->开放注册https协议   # Docker 默认不允许非 HTTPS 方式推送镜像。所以要配置insecure-registries
registry-mirrors--->仓库源

5.新建一个tag,把docker.io/nginx名称变成域名或者IP/镜像名称

docker tag docker.io/nginx ip或者域名:5000/nginx

推送到本地仓库

docker push ip或者域名:5000/nginx 

6.用 curl 查看仓库中的镜像。

$ curl 127.0.0.1:5000/v2/_catalog
{"repositories":["ubuntu"]}

7.删除刚刚tag的镜像 (11.*****:5000/nginx刚才创建的镜像的tag)

docker rmi 111.*****:5000/nginx
docker rmi  nginx 

8.拉取刚刚自己创建的镜像

docker pull 111.*****:5000/nginx

login/logout

docker login : 登陆到一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub docker logout : 登出一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub

登陆到Docker Hub

docker login localhost:8080
docker login -u 用户名 -p 密码
cat ~/my_password.txt | docker login --username foo --password-stdin

--username , -u	:登陆的用户名
--password , -p :登陆的密码
--password-stdin :从标准输入password
登出Docker Hub
docker logout

仓库

docker pull : 从镜像仓库中拉取或者更新指定镜像
docker pull java

docker push : 将本地的镜像上传到镜像仓库,要先登陆到镜像仓库
docker push myapache:v1

docker search : 从Docker Hub查找镜像
docker search -s 10 java #从Docker Hub查找所有镜像名包含java,并且收藏数大于10的镜像

数据卷管理

-v或--volume:由三个字段组成,以冒号(:)分隔
第一个字段是卷的名称,对于匿名卷,将省略第一个字段。
第二个字段是文件或目录在容器中的安装路径。
第三个字段是可选的,并且是逗号分隔的选项列表,例如ro

--mount:包含多个键值对,<key>=<value>,以逗号分隔
type:        可以是bind,volume,或 tmpfs。
source:      这是卷的名称。对于匿名卷,将省略此字段。可以指定为source 或src。
destination: 容器内的挂载路径。可以指定为destination,dst或target。
readonly:   (如果存在)会使绑定安装以只读方式安装到容器中。
volume-opt:  可以多次指定的选项采用键值对。

创建和管理卷 创建卷

docker volume create my-vol

查看卷

docker volume ls
docker volume inspect my-vol

删除卷

docker volume rm my-vol

默认为type为volume,不存在则会创建volume

$ docker run -d --name devtest --mount source=myvol2,target=/app  nginx:latest
$ docker run -d --name devtest -v myvol2:/app nginx:latest

$ docker run -d --name=nginxtest --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly nginx:latest
$ docker run -d --name=nginxtest -v nginx-vol:/usr/share/nginx/html:ro nginx:latest

查看

docker inspect devtest

创建一个创建NFS卷的服务

NFSV3
docker service create -d --name nfs-service --mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/var/docker-nfs,volume-opt=o=addr=10.0.0.10'  nginx:latest

NFSV4
docker service create -d --name nfs-service  --mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/,"volume-opt=o=10.0.0.10,rw,nfsvers=4,async"' nginx:latest

volume共享

docker run -it -v /opt/dbdata --name dbdata test/mycentos:v1.0 /bin/bash        # 在/opt/dbdata目录下创建文件db.properties
docker run -it --name vol_a --volumes-from dbdata test/mycentos:v1.0 /bin/bash  # vol_a,vol_b容器的/opt/dbdata下都有db.properties文件。
docker run -it --name vol_b --volumes-from vol_a test/mycentos:v1.0 /bin/bash   # 在vol_b的/opt/dbdata下创建文件vol_b.txt时,容器dbdata,vol_a也都同时同步了。

可以使用多个–volumes-from

docker run -it --name vol_use --volumes-from vol_a --volumes-from vol_b test/mycentos:v1.0 /bin/bash # vol_a

删除匿名的volume:

docker run --rm -v /foo -v awesome:/bar busybox top # --rm当容器删除时删除/foo,但是保留awesome(非匿名)

删除所有未使用的volume,并释放磁盘

docker volume prune

备份

docker run -v /dbdata --name dbstore ubuntu /bin/bash
docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata  # 备份到/backup目录下的backup.tar

恢复

docker run -v /dbdata --name dbstore2 ubuntu /bin/bash
docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "tar xvf /backup/backup.tar -C /dbdata --strip=1" #strip删掉一级目录

导入导出

docker save : 将指定一个或多个image保存成 tar 归档文件。
docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3  #将镜像 runoob/ubuntu:v3 生成 my_ubuntu_v3.tar 文档
docker save -o images.tar postgres:9.6 mongo:3.4  #将镜像库中的postgres和mongo打包
-o :输出到的文件。

docker load : 导入使用 docker save 命令导出的镜像。
docker load -i images.tar
docker load < busybox.tar.gz
docker load --input fedora.tar
--input , -i : 指定导入的文件,代替 STDIN

docker export :将文件系统作为一个tar归档文件导出到STDOUT。
docker export -o mysql-`date +%Y%m%d`.tar a404c6c174a2  #将id为a404c6c174a2的容器按日期保存为tar文件。
-o :将输入内容写到文件 

docker import : 从归档文件中创建镜像。
docker import  my_ubuntu_v3.tar runoob/ubuntu:v4   #从镜像归档文件my_ubuntu_v3.tar创建镜像,命名为runoob/ubuntu:v4

save和export区别
docker save images_name:将一个镜像导出为文件,再使用docker load命令将文件导入为一个镜像,会保存该镜像的的所有历史记录。比docker export命令导出的文件大,因为会保存镜像的所有历史记录。
docker export container_id:将一个容器导出为文件,再使用docker import命令将容器导入成为一个新的镜像,但是相比docker save命令,容器文件会丢失所有元数据和历史记录,仅保存容器当时的状态,相当于虚拟机快照。

网络链接

$ docker network create -d bridge my-net    # -d 指定网络类型
$ docker run -itd --name test1 --network test-net ubuntu /bin/bash  #--name my-redis 指定名称 --network="bridge"  指定网络
$ docker run -itd --name test2 --network test-net ubuntu /bin/bash
$ docker exec -it test1 /bin/bash 
# ping test2

配置DNS

#查看
docker run -it --rm ubuntu  cat etc/resolv.conf
#配置
vim /etc/docker/daemon.json
{
  "dns" : [
    "114.114.114.114",
    "8.8.8.8"
  ]
}

Dockerfile

下面是一段简单的Dockerfile的例子:

FROM python:2.7                                    #FROM 是用于指定基础的 <image>:<tag>
MAINTAINER Angel_Kitty <angelkitty6698@gmail.com>  # 用于指定镜像创建者和联系方式

COPY . /app                                        # COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"] 复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径)到容器中的 <dest>(不存在则自动建立)
#ADD 指令和 COPY 的使用格式一致 ,ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。

WORKDIR /app                                       # WORKDIR 用于配合 RUN,CMD,ENTRYPOINT 命令设置当前工作路径。WORKDIR 指定的工作目录,必须是提前创建好的
# RUN ["可执行文件", "参数1", "参数2"] 
# RUN 用于容器内部执行命令。例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
RUN groupadd -r redis \
    && useradd -r -g redis redis # && 符号连接命令,这样执行后,只会创建 1 层镜像

USER redis                                         # USER 用于指定执行后续命令的用户和用户组,改变之后层的执行 RUN, CMD 以及 ENTRYPOINT 这类命令的身份 (用户和用户组必须提前已经存在)
USER <用户名>[:<用户组>]
              
EXPOSE 5000                                        # 仅仅只是声明端口。用来指定对外开放的端口,EXPOSE <端口1> [<端口2>...]
ENTRYPOINT ["python"]                              # ENTRYPOINT ["executable", "param1", "param2"] :推荐使用的 exec形式,docker run 的参数 --entrypoint 来替代
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参 


CMD ["app.py"]                                     # CMD ["executable","param1","param2"]:推荐使用的 exec 形式。 如果指定了ENTRYPOINT 则CMD作为他的参数调用
CMD <shell 命令> 
CMD ["<可执行文件或命令>","<param1>","<param2>",...] 
CMD ["<param1>","<param2>",...]  # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数


HEALTHCHECK --interval=5s --timeout=3s  CMD curl -fs http://localhost/ || exit 1

CMD service nginx start # 会被解析为CMD [ "sh", "-c", "service nginx start"] ,因此sh作为主进程
正确用法:
CMD ["nginx", "-g", "daemon off;"]

设置环境变量
两种格式
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

ENV VERSION=1.0 DEBUG=on \
    NAME="Happy Feet"
调用环境变量
$VERSION

ARG
构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。


HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK 支持下列选项:
--interval=<间隔>:两次健康检查的间隔,默认为 30 秒;
--timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
--retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。
在 HEALTHCHECK [选项] CMD 后面的命令,格式和 ENTRYPOINT 一样,分为 shell 格式,和 exec 格式。命令的返回值决定了该次健康检查的成功与否:0:成功;1:失败;2:保留,不要使用这个值。



ONBUILD <其它指令>
ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
FROM node:slim
RUN mkdir /app
WORKDIR /app
ONBUILD COPY ./package.json /app
ONBUILD RUN [ "npm", "install" ]
ONBUILD COPY . /app/
CMD [ "npm", "start" ]


多阶段构建
FROM golang:1.9-alpine as builder #使用 as 来为某一阶段命名
docker build --target builder -t username/imagename:tag . #只想构建 builder 阶段的镜像时,增加 --target=builder 参数即可
COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf  # --from=builder 上一阶段的镜像中复制文件,我们也可以复制任意镜像中的文件

构建镜像

docker build -t nginx:test .

docker-compose

二进制包安装docker-compose

$ sudo curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
$ docker-compose --version

卸载

sudo rm /usr/local/bin/docker-compose

私有仓库 docker-compose docker-compose github