Docker学习笔记
安装Docker
安装
参照Docker官方文档
安装完成后,关闭系统防火墙
启动Docker
systemctl start docker
查看docker状态
systemctl status docker
配置镜像
参考阿里云容器镜像服务 (aliyun.com)
使用Docker
镜像操作
帮助文档:
docker --help
部分命令可能需要使用管理员权限,通过执行如下命令可以避免:
sudo chmod a+rw /var/run/docker.sock
案例:拉取Nginx
docker pull nginx
默认是latest,如果需要指定版本:
docker pull nginx:1.10.1
查看:
docker images
打包:
docker save -o nginx.tar nginx:latest
删除:
docker rmi nginx:latest
读取:
docker load -i nginx.tar
容器操作
容器保护三个状态:
- 运行:进程正常运行
- 暂停:进程暂停,CPU不再运行,并不释放内存
- 停止:进程终止,回收进程占用的内存、CPU等资源
其中:
-
docker run:创建并运行一个容器,处于运行状态
-
docker pause:让一个运行的容器暂停
-
docker unpause:让一个容器从暂停状态恢复运行
-
docker stop:停止一个运行的容器
-
docker start:让一个停止的容器再次运行
-
docker rm:删除一个容器
-
docker inspect xx:查看容器属性
案例:运行nginx
-
创建一个容器:
docker run --name containerName -p 80:80 -d nginx
docker run
:创建并运行一个容器--name
: 给容器起一个名字,比如叫做mn-p
:将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口-d
:后台运行容器nginx
:镜像名称,例如nginx
-
进入容器中:
docker exec -it mynginx bash
-
查看运行中的容器:
docker ps # 加-a收看所有容器(包括暂停的) docker ps -a
-
进入容器中并执行命令:
docker exec -it mynginx bash
- docker exec :进入容器内部,执行一个命令
- -it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
- mynginx :要进入的容器的名称
- bash:进入容器后执行的命令,bash是一个linux终端交互命令
-
可以在主机的浏览器中打开该ip的80端口,即可看到网页!
-
暂停,停止如上图所示
数据卷操作
介绍
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性。
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
注意携带参数:
--privileged=true
如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,
在SELinux里面挂教目录被禁止掉了,如果要开启,我们一般使用--privleged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也即使用该参数,containe内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。
**数据卷(volume)**是一个虚拟目录,指向宿主机文件系统中的某个目录。
一旦完成数据卷挂载,对容器的一切操作都会作用在数据卷对应的宿主机目录了。
这样,我们操作宿主机的/var/lib/docker/volumes/html目录,就等于操作容器内的/usr/share/nginx/html目录了
解决了如下问题:
命令
常用命令:
数据卷操作的基本语法如下:
docker volume [COMMAND]
docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:
- create 创建一个volume
- inspect 显示一个或多个volume的信息
- ls 列出所有的volume
- prune 删除未使用的volume
- rm 删除一个或多个指定的volume
可以在run的同时进行创建
docker run --name mynginx \
-v html:/usr/share/nginx/html:rw
-p 80:80 \
-d nginx
rw
表示可读+可写(默认)ro
read only,容器内部只能读,不能写
案例
案例:给nginx挂载一个数据卷
-
创建
docker volume create html
-
启动nginx
docker run --name mynginx \ -v html:/usr/share/nginx/html -p 80:80 \ -d nginx
-
如果上一步之前没有创建volume,会自动创建
案例:给mysql挂载本地目录
# 先拉取
docker pull mysql
# 创建目录
mkdir /tmp/mysql/conf -p
mkdir /tmp/mysql/data -p
# 创建一个配置文件(内容略)
mkdir /tmp/mysql/conf/mcf.conf
# 运行
sudo docker run \
--name some-mysql \
-e MYSQL_ROOT_PASSWORD=123 \
-d mysql \
-v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf \
-v /tmp/mysql/data:/var/lib/mysql
继承
docker run -it --privileged=true --volumes-from u1 --name u2 ubuntu
制作镜像
UnionFS(联合文件系统): 是一种分层,轻量级并且高性能的文件系统,支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像,可以制作各种具体的应用镜像。
特性: 一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
Docker镜像加载原理: Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system): 主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system): 在boofs之上。包含的就是典型Linux系统中的/dev, /proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
Docker镜像层都是只读的,容器层是可写的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称为“容器层”,“容器层”之下的都叫“镜像层”。
commit
假如要给Ubuntu镜像安装一个Vim:(原始Ubuntu是不带的)
# 在容器中:
# 升级
sudo apt update
sudo apt upgrade
# 安装
sudo apt install vim
# 在主机中:
# 提交容器副本使其成为一个新的镜像
docker commit -m="描述信息" -a="作者" fcbfa3e82fc1 company/mycontainer:1.3
# 查看一下
docker images
发布到阿里云
具体要在阿里云查看
DockerFile
简介
是用来构建Docker镜像的文本文件,对镜像进行定制
语法:
- 每条保留字指令都必须为大写字母,且后面要跟随至少一个参数
- 指令按照从上到下,顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层并对镜像进行提交
大致流程:
- docker 从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似
docker commit
的操作提交一个新的镜像层 - docker 再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有的指令都执行完成
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段:
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
命令
# 基础镜像,当前的镜像是基于哪个镜像的,第一条必须是FROM
FROM
# 镜像维护者的姓名和邮箱地址
MAINTAINER
# 容器构建时需要运行的命令,两种格式:
# 1. shell 格式
# 2. exec 格式
# 在 docker build 时运行
RUN apt install vim
RUN ["./test.out", "dev", "offline"]
# 对外暴露的端口
EXPOSE 3306
# 指定在创建容器后,终端默认登录进来的工作目录,相当于一个落脚点
WORKDIR /usr/local/tomcat
# 指定以什么身份执行,一般不填,为root
USER root
# 设置环境变量
ENV MY_PATH /usr/mytest
# 这个环境变量可以在后续任何RUN指令中使用
WORKDIR $MY_PATH
# 将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
ADD
# 类似于ADD 拷贝文件和目录到镜像中
COPY
# 指定容器启动后要做的事情 格式和RUN相似
# 在指定了ENTRYPOINT指令后,用CMD指定具体的参数
# 可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
CMD ["catalina.sh", "run"]
# 也是指定一个容器启动时要运行的命令
# 类似于CMD,但是不会被docker run 后面的命令覆盖
# 且这些命令行参数会被当做参数送给ENTRYPOINT指令指定的程序
ENTRYPOINT ["nginx", "-c"]
# ENTRYPOINT 案例
ENTRYPOINT ["nginx", "-c"]
CMD ["/etc/nginx/nginx.conf"]
# 运行1:
docker run nginx:test
# 结果: nginx -c /etc/nginx/nginx.conf
# 运行2:
docker run nginx:test /etc/nginx/new.conf
# 结果: nginx -c /etc/nginx/new.conf
案例
centos+jdk8+ifconfig+vim
在此网站上下载JDK,如:jdk-8u171-linux-x64.tar.gz
,放在Dockerfile同级目录下
FROM centos
MAINTAINER lymtics<xxxxxx@xxx.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 安装VIM
RUN yum -y install vim
# 安装ifconfig
RUN yum -y install net-tools
# 安装java8及其库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
# 配置Java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jav:$JAVA_HOME/lib/tools.java:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
# 前面两个都不会执行
CMD echo $MYPATH
CMD echo "SUCCESS"
# 这个可以执行
CMD /bin/bash
命令行:
docker build -t centos-java:1.5 .
虚悬镜像:
仓库,标签名都是docker image prune
删除
评论区