Docker 101 - 最基本的一些操作
文章目录
初学Docke的笔记。
--
常用命令
1docker version
2docker info
3docker [command] --help
镜像(image)
1docker images
2
3# 搜索image
4docker search
5# 通过--filter过滤
6docker search mysql --filter=stars=3000 # 显示stars超过3000的mysql镜像
7
8# 下载
9docker pull 镜像名[:tag]
10
11# 删除 -f force
12docker rmi -f 镜像id
13docker rmi -f 镜像id 镜像id # 删除多个镜像
14docker rmi -f $(docker images -aq) # 删除所有镜像
15
16# 查看镜像怎么构建出来的
17docker history 镜像id
18
19# push到dockerhub
20docker container commit c16378f943fe rhel-httpd:latest
21docker image tag rhel-httpd:latest registry-host:5000/myadmin/rhel-httpd:latest
22docker image push registry-host:5000/myadmin/rhel-httpd:latest
容器(container)
1# 运行容器
2docker run -it centos /bin/bash
3--name="Name" 给容器取名
4-d 后台运行 (后台运行时如果发现自己没有应用就会自动停止)
5-it 交互运行
6-p 指定端口 主机端口:容器端口
7-P 随机指定端口
8--link 另一个容器名 之后就可直接在容器内 ping 另一个容器名了(写进了/etc/hosts)
9
10# 列出运行中的容器
11docker ps
12-a 列出所有
13-n=2 列出最近创建的两个容器
14-q 只列出容器id
15
16# 退出容器
17exit 退出并停止 # 在mac里测试时没停止
18快捷键:control(Ctrl)+p+q 只退出不停止
19
20# 删除容器
21docker rm 容器id
22
23# 启动重启停止杀死容器
24docker start 容器id
25docker restart
26docker stop
27docker kill
1# 日志 -f Follow log output; -t timestamps; -n number
2docker logs 容器id
3
4# 查看容器里进程
5docker top 容器id
6
7# 查看容器所有信息
8docker inspect 容器id
9
10# 进入容器执行命令
11docker exec -it 容器id bashshell
12
13# 进入容器
14docker attach 容器id
15
16# 从容器内拷贝文件到主机
17docker cp 容器id:容器内路径 主机路径 # 没在运行也能拷贝出来
18
19# 提交容器成镜像
20docker commit -m="提交描述信息" -a="作者" 容器id image名字:tag
容器数据卷(Volume)
基本使用
1# 直接使用命令挂载 -v
2docker run -it -v /home/test:/home centos /bin/bash
3# 然后本机的/home下就有了/home/test目录,之后这个目录就会和容器内的/home目录连接。
4# 可以在'docker inspect 容器id'命令中的“Mounts”条目看到。
安装mysql
1# 可以映射多个目录
2# 安装mysql https://hub.docker.com/_/mysql
3# 注意需要设置密码
4docker 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
匿名与具名挂载
1# 只写容器内的路径 称为匿名挂载 使用下面命令可以查看到是一串数字字母。
2docker volume ls
3
4-v abaaba:/etc/nginx #abaaba是指定的volume的名字,称为具名挂载
5docker volume inspect abaaba # 查看volume的具体信息
改变读写权限
1# 通过ro rw改变读写权限
2# ro read only 这个路径只能通过宿主机来操作,容器内无法操作
3# rw read write
4docker run -d -P --name nginx01 -v abaaba:/etc/nginx:ro nginx
5docker run -d -P --name nginx01 -v abaaba:/etc/nginx:rw nginx
多个容器间同步数据
1# 使用 --volumes-from
2# 就算删了docker01,docker02上面仍然有文件
3docker run -it --name docker02 --volumes-from docker01 centos
4
5# eg2
6docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
7
8docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 --volumes-from mysql01 mysql:5.7
关于volume存放的位置
这些卷默认在/var/lib/docker/volumes
目录下 (Linux, Mac)
mac上在vm中,于是找不到上述目录,stackoverflow上有这个问题,其中有一个解决方案,使用以下命令可以是上述目录出现:
1docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
- -it goes for Keep STDIN open even if not attached + Allocate pseudo-TTY
- --privileged "gives all capabilities to the container. Allows special cases like running [docker](https://docs.docker.com/engine/reference/commandline/run/#:~:text=The --privileged flag gives,like running Docker within Docker.)" .
- --pid defines to use the host VM namespace.
- debian the actual image to use.
- nsenter a debian's tool to run programs in different namespaces
- -t is the target PID
- -m mount the provided PID namespace.
- -u enter the Unix Time Sharing (UTS) namespace.
- -n enter the provided PID network namespace.
- -i enter the provided PID IPC namespace.
网络
https://docs.docker.com/network/
1docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
2
3docker network connect NETWORK CONTAINER
Dockerfile
官网地址:https://docs.docker.com/engine/reference/builder/
菜鸟教程:https://www.runoob.com/docker/docker-dockerfile.html
是一段命令脚本,用来构建docker镜像,一般命名为Dockerfile。每个命令都是一层。
FROM, MAINTAINER, RUN, ADD, WORKDIR, VOLUME, EXPOSE, CMD, ENTRYPOINT, ONBUILD, COPY, ENV...
1docker build -f Dockerfile -t myimage:0.1 .
- FROM- 镜像从那里来
1FROM nginx
-
MAINTAINER- 镜像维护者信息 姓名<邮箱?
-
RUN- 在 docker build时运行,每一次RUN都会构建一层。
1# 为防止过多无意义的层,可以像这样写。 && 用于连接命令
2FROM centos
3RUN yum -y install wget \
4 && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
5 && tar -xvf redis.tar.gz
- ADD- 添加文件,如果是压缩文件也解压
1ADD jdk-8ull-linux-x64.tar.gz /usr/local/
- COPY- 添加文件,以复制的形式
1COPY readme.txt /usr/local/readme.txt
-
WORKDIR- 镜像的工作目录
-
VOLUME- 定义数据卷,如果没有定义则使用默认
-
EXPOSE- 暴露端口
-
CMD- 容器启动的命令,如果有多个则以最后一个为准,也可以为ENTRYPOINT提供参数,CMD在docker run 时运行,CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
1array form: CMD ["<可执行文件或命令>","<param1>","<param2>",...]
2CMD ["ls", "-a"]
- ENTRYPOINT- 容器进入时执行的命令
1ENTRYPOINT ["ls", "-a"]
2# 这时 docker run -it xxxxx -l 就能执行 ls -al命令.
3# 而下面形式的用法使用同样的docker run命令时不会报错,但是只会执行 ls -a.
4ENTRYPOINT ls -a
- ENV- 配置环境变量
1ENV JAVA_HOME /usr/local/jdk1.8.0_11
2ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
3
4ENV MYPATH /usr/local
5WORKDIR $MYPATH
-
USER- 指定后续执行的用户组和用户
-
HEALTHCHECH- 健康检测指令
-
ARG- 与 ENV 作用一致,不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
1# eg:Springboot项目
2FROM java:8
3
4COPY *.jar /app.jar
5
6CMD ["server.port=8080"]
7
8EXPOSE 8080
9
10ENTRYPOINT ["java","-jar","/app.jar"]
后续工作
Docker文档中Networking、Compose、Swarm等内容:https://docs.docker.com/engine/
官网的best practice:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
8个docker开发模式:http://hokstad.com/docker/patterns
Docker网络相关的几篇文章:
几个容器网络的解决方案:
概述与对比:Battlefield: Calico, Flannel, Weave and Docker Overlay Network
-
工具集netshoot:https://github.com/nicolaka/netshoot