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 运行的所有事件

容器数据的持久化

在容器启动初始化时,如果容器使用的宿主机挂载点有数据,这些数据就会拷贝到容器中。数据卷可以在容器直接共享和重用。可以直接对数据卷里的内容进行修改。数据卷的变化不会影响镜像的更新。卷会一直存在,即使挂载数据卷的容器已经删除。
  1. 数据卷
    将宿主机目录挂载到容器目录
    docker run -itd --name webfile -v /home/webfile:/data/files Ubuntu
    
    /home/webfile 为宿主机目录,/data/files 是容器中目录,目录不存在会自动创建。
  2. 容器数据卷
    将一个运行的容器作为数据卷,让其他容器通过挂载这个容器实现数据共享。
    docker run -itd -v /data --name dvdata ubuntu
    docker run -itd --name webfile --volumes-from dvdata ubuntu
    

网络管理

5种网络模式

  1. bridge: 默认网络,Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中;IP地址段是172.17.0.1/16。
  2. host: 容器不会获得一个独立的network namespace,而是与宿主机共用一个网络命名空间。
  3. none: 获取独立的network namespace,但不为容器进行任何网络配置。
  4. container: 与指定的容器使用同一个network namespace,网卡配置也都是相同的。
  5. 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

容器访问

  1. 容器访问外部
    # 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
    
  2. 外部访问容器
    # 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
    

桥接宿主机网络

  1. 临时生效( 使用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  // 重启使配置生效
    
  2. 永久生效 ( 修改系统网络配置 )
    # 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/ &#124;&#124; exit 1
ARG 在构建镜像时指定参数 ARG user \ USER $user
ONBUILD 镜像dockerfile文件不加 ONBUILD,其他子项目会引用同一份package文件。加了 ONBUILD ,子项目就会应用对应项目的package文件 RUN python-build —dir /app/src
STOPSIGNAL 为了让容器内的应用程序在接收到signal之后可以先做一些事情,实现容器的平滑退出,如果不做任何处理,容器将在一段时间之后强制退出,会造成业务的强制中断,这个时间默认是10s SIGKILL

Dockerfile 优化思路

  1. 减少镜像层数,尽量把命令统一到一层内完成
  2. 注意清理镜像构建过程中的中间产物
  3. 优化网络请求,修改源
  4. 尽量使用构建缓存
  5. 多阶段进行镜像构建

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
    

图形管理界面

  1. DockerUI 是一个基于 Docker API 提供图形化页面简单的容器管理系统,支持容器管理、镜像管理。
  2. Shipyard是基于Docker API实现的容器图形管理系统,支持container、images、engine、cluster等功能,可满足基本的容器部署需求。不过目前开发者已经停止维护,并且没有找到继任的维护者。
  3. cAdvisor+InfluxDB+Grafana。这是目前较为常用的容器监控方案。cAdvisor容器数据采集->InfluxDB容器数据存储->Grafana可视化展示

参考资料

评论