NiceLeeのBlog 用爱发电 bilibili~

备忘录 Docker镜像的使用

2021-10-10
nIceLee

阅读:


由于使用不是很频繁,每次基本上都忘了,然后临时搜一下。现在做好笔记。

前言

将常用的命令放在这儿,再附加一个例子。

docker pull <镜像ID>:<TAG>
docker run -d -w <工作路径> -v <外部文件/文件夹绝对路径>:<内部挂载路径> -p <IP>:<外部端口>:<内部端口> --name <标识名称> <容器ID>:<版本号>

docker start <容器标识名称>
docker stop <容器标识名称>
# 检查容器状态
docker inspect <容器标识名称>
# 删除容器
docker rm -f <容器标识名称>
# 清理掉所有处于终止状态的容器。
docker container prune

例子

  • 下面我们要:
    • 配置好python环境,将一个简单的python web应用挂载到工作目录并运行。
    • 这个Web应用会打印以下内容:
      • 当前时间
      • 本地连接docker镜像的socket(ip, port)
      • Docker的某个环境变量
        其代码如下:
# 位于D:\Workspace\docker\test\index.py
from http.server import BaseHTTPRequestHandler, HTTPServer
from datetime import datetime
import os
class handler(BaseHTTPRequestHandler):
  def do_GET(self):
    self.send_response(200)
    self.send_header('Content-type', 'text/plain')
    self.end_headers()
    self.wfile.write(str(datetime.now().strftime('%Y-%m-%d %H:%M:%S\n')).encode())
    self.wfile.write(str(self.client_address).encode())
    self.wfile.write(b'\r\n')
    self.wfile.write(str(os.getenv('ENV_TEST')).encode())
    return
if __name__ == "__main__":
    http_server = HTTPServer(('', int(8997)), handler)
    http_server.serve_forever() 
  • 下面我们开始实现
docker pull python
docker run -d -v D:/Workspace/docker/test:/home \
    -w /home -p 127.0.0.1:8080:8997 -e ENV_TEST=1234 \
    --name test_web python:latest python index.py
    
    -d : 后台运行
    -v :将D:/Workspace/docker/test目录映射到容器内的/home,python应用就在这个目录下
    -w :将工作目录设为/home,配合后面的命令,就不要再cd目录了
    -p :将本地的8080端口映射到容器内的8997端口(TCP),127.0.0.1表示不接受外部网络请求
    -e :将环境变量ENV_TEST设为1234
    --name :将名称设为test_web,方便后面调用,而不用记录那一串hash值
    python:latest :在容器内运行python镜像
    python index.py : 运行web应用
    
docker stop test_web    #我停止了容器
docker start test_web   #我再次启动了容器(这里就没有必要再次docker run...)
docker inspect test_web #假设出了点问题,我想看看具体情况
# 还是搞不定,我决定到后台看看情况
docker exec test_web /bin/bash
# 或者
docker attach test_web          (退出后容器停止)
# 或者将-d换为-it(交互),再跑一遍实时看一下情况
docker run -it -v D:/Workspace/docker/test:/home -w /home -p 127.0.0.1:8081:8997 -e ENV_TEST=1234 --name test_web2 python:latest python index.py
# 上面那个容器没用了,我想把它删除
docker rm -f test_web2
# 让我们来看看容器们状态
docker ps -a
# 算了,没用的容器太多,把没在跑的全删掉算了
docker container prune

运行结果:

关于容器内访问宿主机网络

  • 在使用docker run创建Docker容器时,共有hostnonebridgeoverlaymacvlan等网络模式。
    详见https://docs.docker.com/network/

  • 一般情况下考虑前三种情况即可,当需要多容器之间网络共享时再考虑其它。
    • host模式:容器与宿主机在相同的网络命名空间下面,共享所有网络接口。模式简单并且性能高。但使用前请思考一下,什么叫容器,为什么使用容器??
    • none模式:容器不使用网络
    • bridge模式:使用 –net=bridge 指定,默认设置。
  • 使用示例:
    • docker run -it –net=<host none bridge …>

bridge模式下访问宿主机网络

  • 先讲一下大概的思路和原理
    容器与宿主机之间的网络是隔离的,因而localhost肯定访问不成功。
    此时,我们需要知道宿主机的IP。
    在获取到宿主机的IP后,我们实际上就可以在容器内访问宿主机了。 但这往往还不够,因为相同镜像在不同宿主机的容器内对应的IP可能是不相同的,我们不可能将它硬编码到应用代码里。
    放到配置文件里面是一条可行思路。不过更通用的一种做法是取一个别名,并将别名到IP的映射放到/etc/hosts文件中。 通知镜像使用者在运行时配置host: --add-host=<别名>:<IP>

  • 如何获取宿主机IP Windows下,我们可以使用ipconfig查看WSL对应的IP地址

无线局域网适配器 WLAN:

   媒体状态  . . . . . . . . . . . . : 媒体已断开连接
   连接特定的 DNS 后缀 . . . . . . . :

以太网适配器 以太网:

   连接特定的 DNS 后缀 . . . . . . . :
   本地链接 IPv6 地址. . . . . . . . : xxxx::xxxx:xxxx:xxxx:xxxx%xx
   IPv4 地址 . . . . . . . . . . . . : 192.168.1.110
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 192.168.1.1

以太网适配器 vEthernet (WSL):

   连接特定的 DNS 后缀 . . . . . . . :
   本地链接 IPv6 地址. . . . . . . . : xxxx::xxxx:xxxx:xxxx:xxxx%xx
   IPv4 地址 . . . . . . . . . . . . : 172.29.176.1
   子网掩码  . . . . . . . . . . . . : 255.255.240.0
   默认网关. . . . . . . . . . . . . :

Linux下,我们可以使用ifconfig查看docker0对应的IP地址。
当然使用其它命令也是可以的,比如
ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+'

  • 关于如何配置
    该问题可以转化为docker运行时如何配置容器的host。
    版本较新的docker贴心地提供了配置项,我们可以直接使用host-gateway而不必自己再去寻找宿主机的IP。如下:
--add-host=host.docker.internal:host-gateway

内容
隐藏