Docker 学习笔记
人生第一次接触 Docker 是一次寻找科学上网线路的途中。当时有个还在测试阶段的 Carina 免费使用,需要手机验证,移动可以收到验证码。这应该是我第一次接触 Docker,最后这个网站不堪重负被玩坏了。那时候虽然已经用了五六年 Centos,但对于容器技术还不是那么了解,手动配置 dirct-lvm 模式就花了一个晚上的时间。 现在 Devicemapper 也少了,昨天晚上装完 Docker,默认存储引擎已经是 Overlay2。
安装与卸载
安装
# yum install -y yum-utils device-mapper-perisitent-data lvm2
# yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# yum makecache fast
# yum install docker-ce -y
# systemctl start docker
# docker run hello-world
# docker version
注:若在运行
docker run hello-world
时报错:Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? 可执行 Docker 的重启指令进行解决:# systemctl daemon-reload
# systemctl restart docker
# docker run hello-world
卸载
# yum remove docker-ce
# rm -rf /var/lib/docker
镜像管理
简单来说,Docker 镜像就是一个不包含 Linux 内核而又精简的 Linux 操作系统。
Docker Hub 是由 Docker 公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。如果疲于打开网页,使用命令行同样可以搜索镜像。
# docker search [image-name]
一些 Docker 镜像管理中常用的命令
命令 | 作用 |
---|---|
search | 在官方库中搜索一个镜像 |
pull | 从官方库中下载一个镜像 |
push | 提交一个镜像到仓库 |
images | 查看本机镜像 |
commit | 提交一个修改的镜像 |
build | 通过 Dockerfile 构建一个镜像 |
rmi | 删除一个镜像,但前提是必须停止和删除容器 |
export | 将指定容器打包为tar |
import | 导入一个指定容器包 |
save | 保存一个镜像或容器 |
load | 加载一个镜像或容器 |
下载来的镜像根据存储驱动不同而存放的位置不同。但 Docker 相关文件均存储在
/var/lib/docker
目录下。容器管理
创建容器的常用选项
命令 | 作用 |
---|---|
-i | 以可交互的方式打开一个容器 |
-t | 为容器分配一个伪终端 |
-d | 以守护进程的方式打开 |
使用方法举例:
docker run -itd ubuntu
更多参数还需参考官方文档中关于 Docker Run 的内容,或者
docker run --help
。容器的基本操作
命令 | 作用 |
---|---|
ps -a | 查看运行和不运行的容器 |
attach | 以标准输入输出方式进入一个容器 |
rm | 删除一个容器 |
stop | 停止一个容器 |
kill | 强制挂起一个容器 |
rename | 重命名一个容器 |
inspect | 查看一个容器的属性 |
exec | 在某个容器中执行某个命令 |
top | 容器中所运行的进程 |
port | 查看映射的端口信息 |
cp | 将宿主机文件拷贝到容器中 |
logs | 查看容器的标准输出 |
update | 动态修改容器运行参数 |
events | 查看 docker 运行的所有事件 |
容器数据的持久化
在容器启动初始化时,如果容器使用的宿主机挂载点有数据,这些数据就会拷贝到容器中。数据卷可以在容器直接共享和重用。可以直接对数据卷里的内容进行修改。数据卷的变化不会影响镜像的更新。卷会一直存在,即使挂载数据卷的容器已经删除。
- 数据卷
将宿主机目录挂载到容器目录docker run -itd --name webfile -v /home/webfile:/data/files Ubuntu
/home/webfile
为宿主机目录,/data/files
是容器中目录,目录不存在会自动创建。 - 容器数据卷
将一个运行的容器作为数据卷,让其他容器通过挂载这个容器实现数据共享。docker run -itd -v /data --name dvdata ubuntu docker run -itd --name webfile --volumes-from dvdata ubuntu
网络管理
5种网络模式
- bridge: 默认网络,Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中;IP地址段是172.17.0.1/16。
- host: 容器不会获得一个独立的network namespace,而是与宿主机共用一个网络命名空间。
- none: 获取独立的network namespace,但不为容器进行任何网络配置。
- container: 与指定的容器使用同一个network namespace,网卡配置也都是相同的。
- custom ( User-defined ) : 自定义网桥,默认与bridge网络一样。
Docker 信息包过滤原理
Docker 主要通过 netfilter/iptables 实现网络通信的信息包过滤。,netfilter组件是Linux内核集成的信息包过滤系统,它维护一个信息包过滤表,这个表 用于控制信息包过滤处理的规则集。而iptables只是一个在用户空间的工具,用于增删改查这个过滤表的规则。
表 | 链 |
---|---|
filter( 过滤 ) | INPUT, OUTPUT, FORWARD |
nat( 地址转换 ) | PREROUTING, POSTROUTING, OUTPUT |
mangle ( 拆包,修改,封装 ) | INPUT. OUTPUT, PREROUTING, POSTROUTING, OUTPUT |
raw ( 数据包状态跟踪 ) | PREROUTING, OUTPUT |
容器访问
- 容器访问外部
# iptables -t nat -nL Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE tcp -- 172.17.0.2 172.18.0.2 tcp dpt:80
- 外部访问容器
# iptables -t nat -nL Chain DOCKER (2 references) target prot opt source destination DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:88 to:172.18.0.2:8
桥接宿主机网络
- 临时生效( 使用brctl,重启后失效 )
# br_name=br0 // 设置网桥名称 # brctl addbr $br_name // 添加网桥 # ip addr add 192.168.1.120/24 dev $br_name // 给网桥设置IP # ip addr del 192.168.1.120/24 dev eth0 // 删除已存在的eth0网卡配置 # ip link set $br_name up // 激活网桥 # brctl addif $br_name eth0 // 添加eth0到网桥 # vi /etc/default/docker // 在Docker启动时桥接这个网桥 DOCKER_OPTS="-b=br0" # systemctl restart docker // 重启使配置生效
- 永久生效 ( 修改系统网络配置 )
# vi /etc/network/interfaces auto eth0 iface eth0 inet static auto br0 iface br0 inet static address 192.168.1.120 netmask 255.255.255.0 gateway 192.168.1.1 dns-nameservers 192.168.1.1 bridge_ports eth0
使用 Pipework 分配固定 ip
简单用法如下,具体用法可以查看 Pipework 的 Readme
# git clone https://github.com/jpetazzo/pipework.git
# cp pipework/pipework /usr/local/bin/
# docker run -itd --net=none --name test01 ubuntu
# pipework br0 test01 192.168.1.88/24@192.168.1.1
Dockerfile
常用指令
指令 | 描述 | 示范 |
---|---|---|
FROM | 构建的新镜像是基于哪个镜像 | FROM centos:6 |
MAINTAINER | 镜像维护者的姓名或邮箱地址 | MAINTAINER Cubat |
RUN | 构建镜像时运行的 Shell 命令 | RUN ["yum", "install", "nginx" ] , RUN yum install nginx |
CMD | 运行镜像时执行的 Shell 命令,使用默认参数 | CMD ["-c", "/start.sh"] , CMD [ "/usr/sbin/sshd", "-D"] , CMD /usr/sbin/sshd -D |
EXPOSE | 声明容器运行的服务端口 | EXPOSE 80 443 |
ENV | 设置容器内部的环境变量 | ENV MYSQL_ROOT_PASSWORD 123123 |
ADD | 拷贝文件或目录到镜像,如果是 URL 或压缩包会自动下载或自动解压 | ADD <src> <dest> , ADD ["<src>", "<dest>"] , ADD http://www.aaa.bbb/ccc.tar.gz /var/www/html , ADD ccc.tar.gz /var/www/html |
COPY | 拷贝文件或目录到镜像上,但不会自动解压 | COPY ./start.sh /start.sh |
ENTRYPOINT | 运行容器时执行的 Shell 命令,可自定义参数 | ENTRYPOINT ["/bin/bash", "-c", "/start.sh"] , ENTRYPOINT /bin/bash -c '/start.sh' |
VOLUME | 指定容器挂载点到宿主机自动生成的目录或其他容器 | VOLUME ["/var/lib/mysql"] |
USER | 为 RUN, CMD, ENTRYPOINT 执行命令指定运行用户 | USER <user>[:<group>] or USER <UID>[:<GID>] , USER cubat |
WORKDIR | 为 RUN, CMD, ENTRYPOINT, COPY, ADD 设置工作目录 | WORKDIR /home/docker |
HEALTHCHECK | 健康检查 | HEALTHCHECK --interval=5m --timeout=3s \ CMD curl -f http://localhost/ || exit 1 |
ARG | 在构建镜像时指定参数 | ARG user \ USER $user |
ONBUILD | 镜像dockerfile文件不加 ONBUILD,其他子项目会引用同一份package文件。加了 ONBUILD ,子项目就会应用对应项目的package文件 | RUN python-build —dir /app/src |
STOPSIGNAL | 为了让容器内的应用程序在接收到signal之后可以先做一些事情,实现容器的平滑退出,如果不做任何处理,容器将在一段时间之后强制退出,会造成业务的强制中断,这个时间默认是10s | SIGKILL |
Dockerfile 优化思路
- 减少镜像层数,尽量把命令统一到一层内完成
- 注意清理镜像构建过程中的中间产物
- 优化网络请求,修改源
- 尽量使用构建缓存
- 多阶段进行镜像构建
Build 镜像命令使用
- 用法
# docker build [OPTIONS] PATH | URL | - OPTIONS: -t --tag list # 镜像名称 -f --file string # 指定 Dockerfile 文件位置
- 例子
docker build . # 默认找当前目录以Dockerfile为命名的文件 docker build -t cubat/myapp . docker build -t cubat/myapp -f /path/Dockerfile /path docker build -t cubat/myapp - < Dockerfile docker build -t cubat/myapp - < context.tar.gz docker build -t cubat/myapp http://www.example.com/Dockerfile docker build -f cubat/myapp http://www.example.com/contex.tar.gz
- 构建支持 SSH 服务的镜像
FROM centos:6 MAINTAINER cubat ENV ROOT_PASSWORD 123456 RUN yum install -y openssh-server RUN echo $ROOT_PASSWORD |passwd --stdin root RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key CMD ["/usr/sbin/sshd", "-D"] EXPOSE 22
搭建私有仓库
下载 Registry 镜像并启动
# docker pull registry
# docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry
查看镜像仓库中的镜像
# curl http://192.168.1.120:5000/v2/_catalog
{"repositories":[]}
私有仓库管理
- 在本机 Docker 上配置私有仓库为可信任
# vi /etc/docker/daemon.json {"insecure-registries":["192.168.1.120:5000"]} # systemctl restart docker
- 为镜像打上标签
# docker tag centos:6 192.168.1.120:5000/centos:6
- 上传
# docker push 192.168.1.120:5000/centos:6
- 下载
# docker pull 192.168.1.120:5000/centos:6
- 列出镜像标签
# curl http://192.168.1.120:5000/v2/centos/tags/list
DockerHub 的使用
- 登录
docker login --username=xxx--password=xxx
- 镜像打标签
docker tag wordpress:v1 cubat/wordpress:v1
- 上传
# docker push cubat/wordpress:v1
- 搜索测试
# docker search cubat
- 下载
# docker pull cubat/wordpress:v1
图形管理界面
- DockerUI 是一个基于 Docker API 提供图形化页面简单的容器管理系统,支持容器管理、镜像管理。
- Shipyard是基于Docker API实现的容器图形管理系统,支持container、images、engine、cluster等功能,可满足基本的容器部署需求。不过目前开发者已经停止维护,并且没有找到继任的维护者。
- cAdvisor+InfluxDB+Grafana。这是目前较为常用的容器监控方案。cAdvisor容器数据采集->InfluxDB容器数据存储->Grafana可视化展示
评论
发表评论