docker的基本命令
基础命令 https://yeasy.gitbook.io/docker_practice/data_management/volume
// 容器命令 1. docker command --help 查看对应命令的用法 2. docker ps -a 查看所有docker进程(无论是否在运行) -l最后一次创建的容器 3. docker logs containerId 查看容器日志 4. docker start/restart containerId 启动容器 5. docker stop containerId 停止容器 6. docker rm -f continerId 强制删除容器 docker container prune 清理掉所有终止的容器 7. docker port/top containerId/name 查看容器端口映射到主机端口和进程 8. docker inspect containerId/name 查看容器元数据 9. docker stats 显示容器资源使用情况 10. docker cp containerId:src_path dest_path 容器和主机之间拷贝数据 11. docker create --name test nginx 创建一个容器但是不启动 12. docker export containerId > ubuntu.tar 导出容器镜像到ubuntu.tar
docker inspect containerId --format "{{.State.Pid}}" 查看容器的pid
// 镜像命令 1. docker pull/push image 拉推镜像 2. docker images 查看镜像 3. docker search imageName 搜索镜像 4. docker rmi imagesName 删除镜像 5. docker commit -m="update" -a="user" old-containerId new-containerName 更新镜像 6. docker build -t runoob/ubuntu:v1 . 用当前文件夹的Dockerfile文件构建一个镜像 7. docker tag imageId runoob/ubuntu:v2 为镜像打一个新tag 8. cat ubuntu.tar | docker import - test/ubuntu:v1 将快照导入到容器test/ubuntu中 // 网络命令 1. docker network ls 查看网络 brctl show 查看宿主机的网桥 2. docker network create -d bridge test-net 创建一个网络,有bridge、overlay和macvlan两种类型
3. docker network inspect networkName 查看网络的详细信息(例如:哪些容器在这个网络下)
4. docker network connect networkName containerId 将容器加入到网络中,实现不同网络中的容器互通(在container中增加一块网卡) // 存储命令 1. docker volume ls 查看数据卷 2. docker volume create my-vol 创建一个数据卷(实际上是在宿主机上创建一个目录,可以将这个目录挂载到容器中)
3. docker volume inspect my-vol 查看数据卷的详细信息,可以看到数据卷的挂载位置 // 系统命令 1. docker info 显示docker系统的信息
1、docker run
1. docker run ubuntu:15.10 /bin/echo "hello world" 以ubuntu:15.10为镜像起一个容器,并在容器中执行相关命令
2. docker run -it --rm --name "xx" ubuntu:15.10 /bin/bash 进入到容器内部交互:-i 可以交互 -t 打开一个终端
3. docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done" 在后台以进程方式运行容器
4. docker run -d -p 127.0.0.1:5001:5000 training/web python app.py 绑定容器5001端口到主机5000端口
2、docker exec/attach
docker attach containerId 进入到在后台运行的容器,但是在退出时会导致容器停止
docker exec -it containerId /bin/bash
3、网络(docker默认创建 none、host、bridge)
将两个容器加入到同一个网络(ip通信)
1. docker network create -d bridge test-net 创建一个网络
2. docker run -itd --name testnet1 --network test-net ubuntu:15.10 /bin/bash
3. docker run -itd --name testnet2 --network test-net ubuntu:15.10 /bin/bash
DNS server(容器名通信)
用户定义的网络下的容器,可以使用容器名进行通信(默认bridge不行,自定义的bridge类型的可以)
joined通信(多个容器共享一个网络栈)
1. docker run -itd --name web1 httpd
2. docker run -itd --name=container:web1 busybox
上面两个容器可以直接使用127.0.0.1通信
外部世界访问容器:通过-p进行端口映射,将容器端口绑定到主机端口,通过主机IP:映射主机端口进行访问。
每一个映射的端口,host都会启动一个docker-proxy进程来处理访问容器的流量。
容器访问外部世界:docker网卡 -》NAT地址转换 -》host网卡
创建指定ip网段的网络(该模式下可以设置容器ip为静态ip --ip 172.22.16.5)
1. docker network create -d bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 test-net-2
容器与宿主机:
4、存储
容器的存储由一个最上面的可读写容器层和若干个只读的镜像层组成,修改镜像层的数据会先将数据复制到容器层,在容器层修改。
(无状态存储)storage driver为用户提供一个单一的合并之后的统一视图,docker提供多种storage driver。
(持久化存储)data volume,本质是docker host的目录或文件,可以挂载到容器上。
docker run -d -v ~/hostdir:/usr/local/apache2/htdocs httpd 将主机目录挂载到容器上(bind volume)。如果不指定hostdir,则会自动挂到一个默认目录(可以使用docker volume inspect查找),并将容器目录中的内容复制到host上(managed volume)。
可以创建一个容器或者构建一个镜像专门用于挂载数据。
5、Dockerfile
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// Dockerfile命令 docker引擎构建,本地提供一个上下文环境 FROM base-image 基础镜像 scratch 空白镜像 RUN 构建镜像时执行的命令,每个RUN表示一层,可以用 && 串联 MAINTAINER 镜像维护者 COPY <源路径> <目标路径> 复制上下文文件或目录到容器指定路径 ADD 类似COPY CMD 容器运行时执行的命令 // 多个CMD则只执行最后一个 ENTRYPOINT 类似CMD ENV 设置环境变量 EXPOSE 声明端口 VOLUME 挂载数据卷 docker run -v 修改挂载点 WORKDIR 指定工作目录 LABEL <key>=<value> 给镜像添加元数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
FROM centos:latest WORKDIR /root/dockertest 容器工作目录 ADD ./main ./main 将当前文件夹的文件拷贝到工作目录 EXPOSE 8125 ENTRYPOINT ["./main"]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 第一阶段:编译应用程序 FROM golang:1.16 AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . # 第二阶段:构建镜像 FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/app . CMD ["./app"]
CMD和ENTRYPOINT都支持下面两种格式
ENTRYPOINT ["executable", "param1", "param2"] (exec 格式,首选,直接运行)
ENTRYPOINT command param1 param2 (shell 格式,使用/bin/sh -c运行)
1、都可以用来执行一个启动程序,存在多个时,最后一个生效
2、都可以被覆盖,覆盖cmd只需要docker run image的时候加在后面即可,覆盖entrypoint则需要使用 --entrypoint
3、两者可组合使用,CMD用作传参
4、不一定需要定义cmd和entrypoint,有的不定义会报错
6、Compose(类似于k8s的编排系统)
通过yaml文件一次定义和运行多个容器
7、docker machine + docker swarm(集群管理工具)
类似于k8s的管理工具
8、关于docker的一些知识
1.linux分为内核版本(bootfs)和发行版本(rootfs),容器共享宿主机的内核版本,可以在发行版本上有区别;发行版其实就是(centos,ubuntu等之间的区分); 2.docker是一个c/s系统,containerd驻留在server端,用于管理容器,而runc定义了容器运行时,用于创建和运行容器; 3.容器是运行在宿主机上的一个进程,linux操作系统通过namespace对不同的进程进行资源隔离,通过cgroups进行资源限制; docker的每个进程提有六种默认的namespace资源隔离(sudo ls -l /proc/pid/ns可具体查看): mnt -- 文件系统隔离;ipc -- 进程间通信隔离;net -- 网络隔离;uts -- 主机名隔离;pid -- 进程隔离;user -- 用户隔离; mnt namespace需要设置挂载点才能让容器视图生效;使用chroot可以改变某个进程的根目录,例如:chroot $HOME/test /bin/bash 改变bash进程的根目录为test; 容器进程的根目录下挂载了一个rootfs文件系统 cgroups资源限制暴露给用户的接口是资源的文件系统(mount -t cgroup查看具体的资源系统): 进到/sys/fs/cgroup/cpu目录可以发现linux通过一些配置文件来对cpu资源进行限制,将pid加入到tasks中,则配置文件会对这个pid生效;
docker exec进入到某个容器其实就是将exec这个进程加入到了容器进程的namespace中; 4.docker的联合文件系统可以将不同的镜像层文件在运行时载到同一个目录下 aufs文件系统:https://cloud.tencent.com/developer/article/1825495