zoukankan      html  css  js  c++  java
  • Docker 学习笔记(三):数据、网络、系统权限、docker-compose

    一、Docker 数据管理

    Docker 持久化数据有两种方式:

    1. 使用数据卷:更安全,和主机耦合度低
    2. 将主机的目录挂载到容器中:更方便,主机和容器可以很方便地交换数据。

    数据卷相关的命令:

    docker volume create <volume name>  # 新建数据卷
    docker volume ls  # 列出所有数据卷
    docker volume inspect <volume name>  # 查看数据卷信息
    docker volume rm <volume name>  # 删除数据卷
    docker volume prune  # 清除所有未挂载的数据卷
    

    数据卷/文件夹的挂载命令:

    # 1. 挂载数据卷
    docker run -d -P 
        --name web 
        # -v my-vol:/wepapp 
        --mount source=my-vol,target=/webapp 
        training/webapp 
        python app.py
    
    
    # 2. 挂载宿主机的文件夹
    docker run -d -P 
        --name web 
        # -v /src/webapp:/opt/webapp:ro 
        --mount type=bind,source=/src/webapp,target=/opt/webapp,readonly 
        training/webapp 
        python app.py
    
    # P.S. 以前是使用 -v 参数,现在推荐使用 --mount
    

    数据卷的备份恢复

    数据卷的备份、恢复与内容查看,都必须通过容器进行!

    官方的推荐方法是,启动一个中间容器,挂载上对应的数据卷。
    然后进入该容器查看数据卷内容,使用 tar 命令进行数据卷内容的备份(打包成 tar.gz)/恢复(将 tar.gz 解压到数据卷中)。

    二、网络

    1. 外部访问容器

    使用端口映射 -p <宿主机端口>:<容器端口>(该参数可重复多次使用),或者 -P 将容器 EXPOSE 出来的端口随机映射到宿主机。

    2. 容器之间的互联

    比较方便的方案,是将容器加入自定义的 Docker 网络以实现多容器互联。

    1. 新建自定义网络

      docker network create --driver=bridge  <net name>  # 新建自定义网络,使用 bridge 模式
      
    2. 在运行容器时,通过 docker run --network=<net name> --name <container name> ... 将容器添加到该自定义网络
      然后在其中一个容器中 ping <container name>,该名称会直接被解析到对应的容器 ip。这样,容器之间就能以容器名称为 hostname 互联。

    3. 通过 docker container inspect 可获知容器在 docker0 上的 ip 地址,容器之间可以通过该 ip 通信。

      • 缺点:ip 是动态分配的!每次都要手动配。。

    如果容器较多,推荐使用 docker-compose 进行编排。

    3. 容器访问宿主机网络

    从 Docker 对这种连接方式的支持来看,显然是很不推荐用户这么干的。

    但是对个人用户而言,从容器访问宿主机,我觉得还是个挺常见的需求。

    可用方法如下:

    1. 通过宿主机的公网 ip 访问宿主机
      • 缺点:宿主机需要向公网开放对应的端口。
    2. 在运行容器时指定 --network=host,容器与宿主机共用网络
      • 缺点:容器与宿主机耦合度过高。而且可能出现端口冲突。
    3. 通过 ip addr show docker0 查看宿主机在网桥 docker0 上的 ip 地址(linux 下一般为 172.17.0.1),容器可通过该 ip 访问宿主机。
      • 缺点:不同宿主机在 docker0 上可能具有不同的 ip,需要运行时手动配置。
    4. 通过 shell 脚本获取 host ip:参见 Docker for Linux - Support host.docker.internal DNS name to host
    5. special DNS record for host.docker.internal + gateway.docker.internal 被 merged,就能直接使用 host.docker.internal 访问宿主机了。

    三、使用 nsenter 进入容器的网络 namespace

    查看 Docker 容器的连接数:

    docker inspect -f '{{.State.Pid}}' <containerid>  # 查找到容器的 pid
    sudo nsenter -t <pid> -n netstat | grep ESTABLISHED  # 通过 pid 检索所有连接
    

    三、系统权限

    一个系统上的 docker 容器,默认情况下是无法修改系统的公共内核参数的。这是一种隔离机制。

    如果某个容器抽风把系统参数改得一团糟,那所有容器都会崩溃,没有人会希望碰到这种情况。

    但是有的时候,我们确实需要在容器内修改整个系统的某些参数。比如在测试系统的时候,我们系统直接修改整个系统的时间,然后查看我们的应用能否应对这种问题。

    为了满足这种需求,Docker 提供了一组参数用来给容器设置额外的权限。

    Docker 容器的隔离是基于 Linux 的 Capability 机制实现的, Linux 的Capability 机制允许你将超级用户相关的高级权限划分成为不同的小单元. 目前 Docker 容器默认只用到了以下的 Capability:

    CHOWN, 
    DAC_OVERRIDE, 
    FSETID, 
    FOWNER, 
    MKNOD, 
    NET_RAW, 
    SETGID,  
    SETUID, 
    SETFCAP, 
    SETPCAP, 
    NET_BIND_SERVICE, 
    SYS_CHROOT, 
    KILL, 
    AUDIT_WRITE
    

    使用 --cap-add, --cap-drop 可以添加或禁用特定的权限。

    比如容器若要修改系统时间,就要求它拥有 SYS_TIME 权限,所以我们在运行容器时需要添加参数 --cap-add SYS_TIME

    然后在容器里运行 date --set "time-string",就能修改掉整个系统的时间。

    P.S. --privileged 参数也可以达到开放权限的作用, 与 --cap-add 的区别就是, --privileged 是将所有权限给容器,这相当危险!

    四、docker-compose

    用于编排多个容器,管理容器集群之间的协作关系。

    国内安装镜像:docker: install-compose

    常用命令

    1. docker-compose up:
      • (推荐在测试时使用)新建并启动容器,聚合输出容器组中所有容器的 logs,命令结束时(ctrl+c),会 stop 掉整个容器组。
      • (在生产环境下要添加该选项!)在 -d 模式(detached,分离模式)下运行。与默认行为的差别在与,命令结束后,容器组中的容器仍然会继续运行。
    2. docker-compose start: 启动终止的容器组。

    docker-compose 大部分命令都和 docker 完全类似。只是它是集群版本。

    docker-compose.yml 模板

    Docker Compose 模板文件

    参考

  • 相关阅读:
    API文档大集合
    jenkins 构建 job 并获取其状态的实现
    jenkins 插件乱码处理与文件上传
    更优雅的配置:docker/运维/业务中的环境变量
    部署仓库中 nginx 下游依赖配置改进
    dotnet core 在 MIPS64 下的移值进度:EA 版本已经发布
    tmux 编译安装过程
    各数据源的时间/日期的提取能力对比
    关于若干性能指标的阐述
    为缓存、外部接口调用添加超时处理
  • 原文地址:https://www.cnblogs.com/kirito-c/p/11184348.html
Copyright © 2011-2022 走看看