Docker学习笔记

-目录-

为什么使用Docker

环境方便移植组装,应用可以把包和依赖发布到镜像,这样任何docker即可直接拉下来,构建环境,运行软件。

原理

三个基本概念

容器隔离原理

Docker 原理

Docker Image分层

Docker镜像是由一系列层来构建的,由Dockerfile控制各层,最顶层是可修改的容器层,下面都是镜像层,最下面是。注意:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

Container RW
---------
Image Vim R
Image Emacs R
Image Apache R
Baseimage ubuntu R
--------- 
Kernel R

对镜像中数据的访问使用了写时拷贝技术:

Docker和虚拟机

命令

镜像相关

镜像搜索与安装

$docker search imagename
$docker pull imagename

镜像删除

需要与之关联的容器已删除

$docker rmi imageID
# 删除所有镜像
$docker rmi $(docker images -aq)

本地镜像列表

$docker images

镜像构建与发布

前提是已经有了Dokerfile。

$docker build .

容器相关

创建并启动容器(创建实例)

$docker run imagename

进入与退出容器

若在run里加入-d后台运行,想要进入使用以下命令

$docker attach dockerID # 退出后停止docker
$docker exec dockerID -it # (命令行)退出后不停止
$docker exit

显示(正在运行)容器

$docker ps

停止/运行/重启容器

$docker stop dockerID
$docker start dockerID # 与run的区别是一个是创建实例一个是已经创建好,停止后再启动
$docker restart dockerID

删除容器

容器需要是已经停止

$docker rm -f dockerID
$docker rm -f $(docker ps -aq)

查看网络端口映射

$docker port dockerID

查看程序内部标准输出

$docker logs

查看容器内部运行进程

$docker top

查看容器详细信息

$docker inspect

动态修改环境变量

  1. 停止容器
  2. 停止服务
  3. 修改/var/lib/docker/containers/dockerID/config.v2.json里的Env列表,注:该json就是docker inspect dockerID显示的那个json
  4. 启动服务
  5. 启动容器
$docker stop containerID
$service docker stop 
$cd /var/lib/docker/containers
# 找到dockerID进入,修改config.v2.json并修改
$service docker start
$docker start containerID

注意,在ubuntu下需要提升cd权限,在su下进行使用sudo -s 进行相关更改后exit退出su权限,注意在su下要万分小心的更改东西。

知识

挂载

挂载可以实现数据持久化,使得删除容器后数据还在。所谓挂载就是把容器内文件目录与宿主机(docker engine)的某个目录(称为“卷”)进行双向绑定。

挂载方式

docker卷的默认工作目录是/var/lib/docker/volumes,如果在指定挂载时没有提供宿主机的绝对路径,那么就会在工作目录下直接创建卷(相对路径)。如果提供了名称,卷就是这个名称;如果没提供就会是一段随机字符。通常使用具名挂载。

那么挂载简单的可以分为三种:使用如下:

具名只提供了一个名称或者说是相对路径、匿名则没有提供路径,所以二者都是直接放在工作目录下,具名只是为随机的卷名重命名而已。而machinepath一般都是/开头的绝对路径,自然也就是指定目录了。

例如:

# 具名挂载例子
$docker run -v mysqlOnMachine:/etc mysql
...
$cd /var/lib/docker/volumes
$ls
... ... mysqlOnMachine# 在卷工作目录下看到了具名挂载的那个卷

权限设置

还可以设置容器对这个卷的权限,readonly ro,readwirte rw。若是ro则容器不能更改此卷只能在宿主机更改。

$docker run -v vname:dockerpath:rw imagename

docker间共享卷

多个docker可以共享一个持久化空间,即是共享一个宿主机空间。使用如下

# 创建一个容器docker2,和已经创建了的docker1共享卷
$docker run --volumes-from docker1 docker2

Dockerfile

Dockerfile是docker的构建文件。是一个命令-参数脚本。

特点:

Dockerfile编写模板

FROM centos 				# 基础镜像

MAINTAINER name<mail.com> 	# 维护者信息

ENV MYPATH /user			# 环境变量

WORKDIR	$MYPATH				# 设置工作目录,别人进入该docker时所在目录,不然就是根目录了

RUN yum -y install vim		# 在docker build时执行命令
RUN yum -y net-tools

VOLUME [“volumename”]   	# 相当于-v。匿名挂载,这里的volumename是docker内的目录,若没有,则创建。这个目录和宿主机的某个目录是同步的,宿主机目录在卷工作目录下。

COPY /home /mydockerhome	# 添加文件,源 目标。目标不存在会自动创建

EXPOSE 80					# 相当于-p,仅仅是声明,并没有绑定。方便配置而已

CMD ls -a 					# 在docker run时执行命令,为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。如果Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效

ENTRYPOINT -a				# 在docker run时执行命令,类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。如果Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。ENTRYPOINT和CMD配合实现定参和变参。

ONBUILD ls -a				# 触发指令,有新的image继承本image时

更多dockerfile参见

坑

ubuntu每次都需要加sudo

原因:

docker server没有将当前用户加入su组

解决:

$sudo groupadd docker     #添加docker用户组
$sudo gpasswd -a $USER docker     #将登陆用户加入到docker用户组中
$newgrp docker     #更新用户组
$docker ps    #测试docker命令是否可以使用sudo正常使用

创建centos时没有指定bash导致无法交互

解决:

关闭docker,启动docker加入-i选项

$docker stop centosID
$docker start -i centosID

防火墙禁用全部INPORT导致外网无法访问服务

解决:

# 全开,应该依赖VPS的防火墙
$iptables -I INPUT -j ACCEPT

没有指定终端 无法进入容器

解决:

把-it放在dockername前面,放在dockername前面是指令

$docker exec -it myhduhelp /bin/sh
© 2019 - 2023 · YuYoung's Blog