docker部署实录
最近想玩docker,熟练docker和k8s,依此记录下开发历程
开发环境如下:
环境:ubuntu 20.04
阿里云ECS
内存1G
云盘40G
安装docker
apt-get安装docker
sudo apt-get update
sudo apt-get install docker.io
或者使用官方提供的安装版本
sudo apt-get install curl //如果没有curl
curl -sSL https://get.docker.com/ | sh
因为默认情况下,普通用户没有权限执行 docker 相关操作
所以需要将普通用户加入到 docker 用户组,并退出 shell 重新登录,即可不使用 sudo 来运行 docker 相关操作
sudo usermod -aG docker $USER //usermod命令用于修改用户帐号。-a 表示追加 -G表示修改用户所属的附加群组。
退出shell重启一下使其生效
查看是否安装成功
docker info
运行第一个docker例子
docker run hello-word
docker ps -a
docker镜像与容器操作
镜像(Image
)和容器(Container
)的关系,就像是面向对象程序设计中的 类
和 实例
一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
镜像常用操作
搜索可用镜像仓库
docker search //比如 docker search ubuntu
获取镜像
docker pull 镜像名称:版本号 //默认是latest
查看所有镜像
docker image ls
查看镜像、容器、数据卷所占用的空间
docker system df
删除镜像
docker image rm <镜像> //<镜像>可以是镜像id,可以是镜像名称,也可以是摘要
容器常用操作
简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。
启动容器
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
docker run //普通基于镜像新建一个容器并启动
docker run -it //交互式并且提供一个shell启动容器
docker run -it --rm //交互式并且提供一个shell启动容器,执行后删除 ,可以加参数–name
docker run -itd //-d的意思是在后台一直运行,与–rm相反的效果
此外还有很多参数options
-p //指定开容器的哪些端口 用docker ps -l 可以查看 或者docker port <容器id> 容器端口
docker run -p 宿主机端口:docker端口 … //表示绑定指定端口
-P //大P 表示对外公开Dockerfile中通过EXPOSE指令公开的端口
启动已终止容器
docker container start <容器id or name>
查看容器输出结果(有时候不一定会输出到宿主机上)
docker container logs <容器id or name>
终止容器
docker container stop <容器id or name>
重启容器
docker container restart <容器id or name>
某些时候需要进入容器进行操作,这就需要exec命令了
docker run 和 docker exec区别如下
“docker run”通常是在新创建的容器中所使用的命令。 它适用于在没有其他容器运行的情况下,您想要创建一个容器,并且要启动它,然后在其上运行一个进程。
“docker exec”适用于在现有容器中运行命令的情况。如果您已经拥有了一个正在运行的容器,并希望更改该容器或从中获取某些内容,那么使用“docker exec”命令就非常合适了。
在运行的容器中执行命令
docker exec -it <容器> <命令>
删除容器
docker container rm <容器>
清理所有处于终止状态的容器
docker container prune
docker部署项目
比如想部署一个在ubuntu:14.04版本下运行的项目。
首先需要在docker hub注册账号
https://hub.docker.com
然后开始制作我们的“定制化项目”
首先得有个操作系统底子,选用ubuntu:14.04
docker pull ubuntu:14.04
然后新建文件夹,写一个Dockerfile
mkdir myubuntu
vim Dockerfile
在Dockerfile里面写脚本文档
FROM ubuntu:14.04 //FROM是指基础镜像,一般是操作系统底子
MAINTAINER longbo <...@163.com> //一般是作者信息
RUN apt-get update && apt-get install -y vim gcc //RUN指要执行的指令,一般是安装环境啥的
RUN ...
...
...
然后编译Dockerfile制作镜像保存在本地仓库里
docker build -t myubuntu:v1 . //docker build -t表示docker build --tag 后面接名字和版本号
更改tag号,为push到远程仓库做准备
docker tag myubuntu:v1 suixinsama/myubuntu:v1 //更改镜像名称,要不然push不到仓库里
登陆远程仓库
docker login -u 用户名 -p 密码
提交镜像
qdocker push suixinsama/myubuntu:v1
over~
docker其他操作
copy文件,从宿主机->docker以及反方向
docker cp 容器名称:容器目录 需要拷贝的文件或目录
docker cp 需要拷贝的文件或目录 容器名称:容器目录
查看容器内进程
docker top <容器>
查看容器日志
docker logs -t <容器> //按时间戳显示容器日志
查看容器内部更多信息
docker inspect <容器> //里面有容器ip,开放端口等信息
在构建镜像的时候(docker build)想知道每一步怎么编译过来的,可以用如下指令
docker history <镜像id>
Dockerfile
Dockerfile主要由一些功能指令组成,非常灵活方便
FROM
基础镜像,必须是第一条指令
后续指令基于此基础镜像
如果本地仓库没有该基础镜像,则会去registry里面pull下来
MAINTAINER
维护作者信息
一般都是姓名邮箱啥的
RUN
镜像被构建时要运行的指令
比如apt-get update之类的
EXPOSE
容器需要打开的端口
后面直接接数字就行
CMD
容器启动时运行的指令
注意这里与RUN指令不同
CMD是只当容器启动的时候才会运行该指令
docker run 中的指令参数会覆盖掉CMD中的指令,要注意
加方括号以及带引号
ENTRYPOINT
与CMD类似,但是不会被指令覆盖
CMD和ENTRYPOINT实际用处好像并不大
WORKDIR
创建指定工作目录,容器启动时设置的指令,包括CMD和ENTRYPOINT都会在该目录下执行
更常用的方式是配合RUN
WORKDIR …1
RUN …
WORKDIR …2
RUN …2
如上,先切换到目录1再RUN1再切换到目录2再RUN2
最后CMD和ENTRYPOINT指令在dir2执行
docker run -w是指定工作路径,可以覆盖它
ENV
在构建镜像时设置环境变量
比如
ENV RVM_PATH /home/rvm/
这样可以使用环境变量
WORKDIR $RVM_PATH
docker run -e可以覆盖它,但只是运行时有效
USER
指定用户身份运行
USER long
以long这个用户身份运行
默认是root
VOLUME
作用是为容器添加卷
卷可以在容器间共享和重用
一般卷用来做数据库或者数据共享,都可以
VOLUME …(目录)
比如
VOLUME /opt/project
这会为基于此镜像创建的所有容器创建一个/opt/project的挂载点、
也可以指定多个卷
docker run -v 宿主机卷:容器卷:读写方式(ro|rw 只读或者读写) 也可以
卷的概念非常重要,可以理解为共享文件夹,有些时候需要频繁改动部分文件,所以不想把它做进image里面
这个时候卷就起到了非常强大的作用
ADD
将构建环境目录下的文件复制到镜像中
ADD 源文件 目的文件
ADD可以将压缩文件复制进去,复制进去后自动解压到相应目录下
COPY
和ADD类似
COPY 和 ADD 命令具有相同的特点:只复制目录中的内容而不包含目录自身
ADD比COPY更好用
ARG
类似于Makefile里的宏定义
在docker run中用–build-arg xxx=xxx来赋值