docker使用问题总结

概念解读

系统虚拟化与容器虚拟化

系统虚拟化,Hypervisor Virtualization,全虚拟化。在 Host 中通过 Hypervisor 层实现安装多个 GuestOS。每个 GuestOS 都有自己的内核,和主机的内核不同,GuestOS 之间完全隔离。
容器虚拟化,Operating System Virtualization ,使用 Linux 内核中的 namespaces 和 cgroups实现进程组之间的隔离。是用内核技术实现的隔离,所以它是一个共享内核的虚拟化技术。

注:容器虚拟化没有 GuestOS,使用 Docker 时下载的镜像,只是为运行 App 提供的一个依赖的环境,是一个删减版本的系统镜像。一般情况下系统虚拟化没有容器虚拟化的运行效率高,但是系统安全性高很多。

知识点总结

Dockerfile编写

  • 将RUN apt-get update和apt-get install组合成一条RUN声明。
    如果将apt-get update放在一条单独的RUN声明中会导致缓存问题以及后续的apt-get install失败。
  • 指令过apt-get install相关指令后,需要清理掉apt缓存。
     rm -rf /var/lib/apt/lists/*

注意:官方的 Debian 和 Ubuntu 镜像会自动运行apt-get clean,所以不需要显示的调用apt-get clean。

  • ADD和COPY的使用
    • 虽然ADD和COPY功能类似,但一般优先使用COPY。因为它比ADD更透明。
    • COPY只支持简单将本地文件拷贝到容器中,而ADD有一些并不明显的功能(比如本地 tar 提取和远程 URL 支持)。因此,ADD的最佳用例是将本地 tar 文件自动提取到镜像中。
    • 如果你的 Dockerfiles 有多个步骤需要使用上下文中不同的文件。单独COPY每个文件,而不是一次性COPY完。这将保证每个步骤的构建缓存只在特定的文件变化时失效。
    • 为了让镜像尽量小,最好不要使用ADD指令从远程 URL 获取包,而是使用curl和wget。这样你可以在文件提取完之后删掉不再需要的文件,可以避免在镜像中额外添加一层。
      注:ADD指令不能和其他指令合并,所以前者ADD指令会单独产生一层镜像。而后者可以将获取、提取、安装、删除合并到同一条RUN指令中,只有一层镜像。

docker空间管理

 ## 查看空间
     docker system df
 ## 查看volume容器
    docker volume ls(查看volume容器id:docker volume ls -qf dangling=true)
 ##  删除所有容器
    docker rm `docker ps -a -q`
 ## 删除所有关闭的容器
    docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs docker rm(docker rm $(sudo docker ps -a -q)##  批量删除孤单volume
    docker volume ls -qf dangling=true
 ## 删除所有none的镜像
   docker rmi $(docker images | grep "none" | awk '{print $3}')
 ## 删除所有dangling镜像(即无tag的镜像):
   docker rmi $(docker images | grep "^" | awk "{print $3}")
 ## 删除所有dangling数据卷(即无用的Volume):
   docker volume rm $(docker volume ls -qf dangling=true)

docker swarm基本指令

  • docker swarm init(初始化集群)
  • docker swarm join-token manager(在manger上输入,查看加入集群的命令)
  • docker node ls(查看集群节点)
  • Swarm集群销毁
    • worker离开集群:docker swarm leave
    • manager离开集群:docker swarm leave --force

Error处理

  1. 使用docker pull image拉取镜像时,报错:

error pulling image configuration: Get https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/9c/9cc7800b3f3c4b830822b790074cc5ad91623a9e7b06af2c6c410e66a79fbb76/data?verify=1548498329-Y8TZwPzM%2FGMu6bHC0QqdbENW2WE%3D: x509: certificate has expired or is not yet valid

解决方法:将当前主机时间与网络时间同步
- 把当前时区调整为上海就是+8区,想改其他时区也可以去看看/usr/share/zoneinfo目录
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

  • 用ntpdate同步标准时间: ntpdate us.pool.ntp.org(需要安装ntpdate)
  1. 执行docker相关指令时,报错

net/http: TLS handshake timeout

解决方法:不用官方的dockhub了,转而使用国内的仓库daocloud

   $ echo "DOCKER_OPTS=\"\$DOCKER_OPTS --registry-mirror=http://f2d6cb40.m.daocloud.io\"" | sudo tee -a /etc/default/docker
   $ sudo service docker restart

或者报错:

ERROR: Service ‘kn-nginx’ failed to build: Get https://registry-1.docker.io/v2/library/nginx/manifests/latest: Get https://auth.docker.io/token?scope=repository%3Alibrary%2Fnginx%3Apull&service=registry.docker.io: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

原因同上,采用另一种解决方法:

  • 首先打开配置文件daemon.json,centos上安装后有此文件,但是ubuntu上需要自己创建文件:
vim /etc/docker/daemon.json

在文件中加入:

   {
       "registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]
   }
  • 然后重启守护进程:
    sudo systemctl daemon-reload
    sudo systemctl restart docker
  1. 同一台主机上的两个container A和B互联有三种方式
  • A映射到主机端口portA,B映射到主机端口portB,A连接B时,通过主机host_ip:portB的方式连接
    报错:
    > No route to the host

    解决方法/解决方法:修改防火墙信息
    (1)防火墙配置文件的增加一条规则

      <rule family="ipv4">
          <source address="172.17.0.1/16"/>
      <accept/>
      rule>

(2) 重启防火墙:systemctl restart firewalld.service
注意:或通过一条命令搞定
firewall-cmd --permanent --zone=public --add-rich-rule='rule family=ipv4 source address=172.17.0.0/16 accept' && firewall-cmd --reload
其中,对于通过docker run运行的容器address为网卡docker0,通过docker service运行的容器相对为172.18.0.1/16

  • 通过–link参数
  • 通过创建network
  1. 报错信息:

docker WARNING: IPv4 forwarding is disabled. Networking will not work.

解决方法:修改网络配置

  • vi /etc/sysctl.conf 添加 net.ipv4.ip_forward=1
  • 重启network: systemctl restart network
  • 查看修改结果: sysctl net.ipv4.ip_forward

5. 编写docker-compose配置文件时格式报错
解决方法:YAML、YML在线格式化校验工具
注:不要使用Tab,能空格就输入空格来对齐。

  1. 关闭防火墙时(systemctl stop firewalld)会清空docker规则
    解决方法:重建docker0网络恢复
    pkill docker
    iptables-t nat -F
    ifconfig docker0 down
    brctl delbr docker0
    docker-d
    service docker restart
  1. dockerfile创建mysql 时,如果将mysql数据通过volume挂载到宿主机中时,可能会出现无法创建数据库的问题
    解决方法:
    此时要清空宿主机对应volume的目录

  2. 使用docker swarm集群部署时报错

  • 执行docker swarm join --token ** 时,报错:

Error response from daemon: error while validating Root CA Certificate: x509: certificate has expired or is not yet valid

解决方法:同步节点之间的时间

yum install -y ntp
ntpdate asia.pool.ntp.org
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  • 集群部署报错:

Error response from daemon: manager stopped: can’t initialize raft node: rpc error: code = Unknown desc = could not connect to prospective new cluster member using its advertised address: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = “transport: Error while dialing dial tcp 192.168.190.127:2377: connect: no route to host”

解决方法:主机上存在多张网卡时,最好使用 docker swarm init --advertise-addr ip 绑定网卡ip

参考资料:

Dockerfile编写:https://blog.csdn.net/wo18237095579/article/details/80540571
Docker网络模式:https://www.cnblogs.com/zuxing/articles/8780661.html
SOA架构与微服务架构的区别:https://blog.csdn.net/zpoison/article/details/80729052
SpringBoot与SpringCloud的关系:https://www.imooc.com/article/details/id/24920
docker compose部署实例:https://www.jianshu.com/p/5f503bdcc4b4
docker文档:
https://idig8.com/category/docker/docker-up/page/2/
http://dockone.io/article/879
k8s环境搭建:
https://blog.csdn.net/qq_32971807/article/details/54693254
https://mritd.me/2016/10/29/set-up-kubernetes-cluster-by-kubeadm/#rpm

你可能感兴趣的:(docker)