Docker 101 - 最基本的一些操作

文章目录

初学Docke的笔记。

--

官网:https://www.docker.com/

文档:https://docs.docker.com/

仓库:https://hub.docker.com/

常用命令

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

comments powered by Disqus