docker常用操作

安装docker环境

基本设置

安装Docker

设置Docker Hub镜像代理

可以登录 阿里云 容器镜像服务 镜像中心 -> 镜像搜索 查找。 例如 k8s.gcr.io/coredns:1.6.7 镜像可以用 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.7 代替。 一般情况下有如下对应关系:

docker pull k8s.gcr.io/xxx
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/xxx

Docker常用命令

基本命令

# 以 ubuntu 22.04 镜像创建一个新容器,然后在容器里执行 bin/echo "Hello world",--rm 运行后自动删除
docker run --rm ubuntu:22.04 /bin/echo "Hello world";cat /proc/version

# 交互运行容器,-i:允许标准stdin交互,-t: tty终端
docker run --rm -it ubuntu:22.04 /bin/bash

# 后台运行容器
docker run --rm -d --name testubuntu ubuntu:22.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
docker logs testubuntu # 查看容顺的标准输出stdout

docker ps -a # 查看运行的容器,-a:查看所有(默认只显示运行中的容器)
# 输出:
# CONTAINER ID: 容器 ID。
# IMAGE: 使用的镜像。
# COMMAND: 启动容器时运行的命令
# CREATED: 容器的创建时间
# STATUS: 容器状态有7种:created(已创建) restarting:重启中,running 或 Up:运行中,removing:迁移中,paused:暂停,exited:停止,dead:死亡
# PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
# NAMES: 容器名称,自动分配或指定

docker exec -it testubuntu /bin/bash # 进入容器shell环境
docker attach testubuntu  # 附着到容器标准stdin/stdout控制台,若中止控制台在运行的命令,容器会关闭
docker cp mynginx:/etc/nginx/nginx.conf /data/nginx/ # 从容器复制配置文件到本地

docker stop testubuntu # 停止容器

docker help

应习惯用docker --helpdocker ps --help方式查看各级功能的帮助信息。

docker --help

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Common Commands:
  run         Create and run a new container from an image
  exec        Execute a command in a running container
  ps          List containers
  build       Build an image from a Dockerfile
  pull        Download an image from a registry
  push        Upload an image to a registry
  images      List images
  login       Log in to a registry
  logout      Log out from a registry
  search      Search Docker Hub for images
  version     Show the Docker version information
  info        Display system-wide information

Management Commands:
  builder     Manage builds
  buildx*     Docker Buildx (Docker Inc., v0.11.2)
  compose*    Docker Compose (Docker Inc., v2.21.0)
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  plugin      Manage plugins
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Swarm Commands:
  config      Manage Swarm configs
  node        Manage Swarm nodes
  secret      Manage Swarm secrets
  service     Manage Swarm services
  stack       Manage Swarm stacks
  swarm       Manage Swarm

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

Global Options:
      --config string      Location of client config files (default "/root/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker
                           context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket to connect to
  -l, --log-level string   Set the logging level ("debug", "info", "warn", "error", "fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/root/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/root/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Run 'docker COMMAND --help' for more information on a command.

For more help on how to use Docker, head to https://docs.docker.com/go/guides/

容器连接

网络端口映射

docker run -d -P training/webapp python app.py
docker run -d -p 5000:5000 training/webapp python app.py
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py

# -P: 绑定随机主机端口,可以指定容器绑定的网络地址
# -p: 绑定到指定的主机端口
# 默认都是绑定 tcp 端口,可以在端口后面加上协议,如:-p:5001:5000/udp

# docker port <容器名|容器ID> # 快速查看绑定端口情况

容器互联

端口映射并不是唯一把 docker 连接到另一个容器的方法。

docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。

docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。

# 创建新的docker网络:bridge网桥,名称:test-net
# -d:参数指定 Docker 网络DRIVE类型,有 bridge、overlay(overlay网络类型用于Swarm mode)。
docker network create -d bridge mybridge
docker network inspect mybridge           # 查看网络的连接

# 连接容器
# 运行一个容器并连接到新建的 test-net 网络:
docker run -itd --name test1 --network mybridge ubuntu /bin/bash
# 再运行一个容器并加入到 test-net 网络:
docker run -itd --name test2 --network mybridge ubuntu /bin/bash

下面通过 ping 来证明 test1 容器和 test2 容器建立了互联关系。

如果 test1、test2 容器内中无 ping 命令,则在容器内执行以下命令安装 ping (即学即用:可以在一个容器里安装好,提交容器到镜像,在以新的镜像重新运行以上俩个容器)。

# 进入容器
docker exec -it test1 /bin/bash

# 安装 ping 工具
apt-get update
apt install iputils-ping

# ping测试
ping test2

如果你有多个容器之间需要互相连接,推荐使用 Docker Compose。

配置容器DNS

如果在容器启动时没有指定 --dns 和 --dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS。

在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS,或者在/etc/default/docker中用DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"来设置。

daemon.json配置优先(测试中,发现DOCKER-OPTS中参加没有生效)。

{
  "dns" : [ "114.114.114.114","61.139.2.69" ]
}

配置完,需要重启 docker 才能生效:

sudo systemctl daemon-reload
systemctl restart docker

手动指定容器的配置:如果只想在指定的容器设置 DNS,则可以使用以下命令:

docker run -it --rm -h host_ubuntu  --dns=114.114.114.114 --dns-search=test.com ubuntu

# --rm:容器退出时自动清理容器内部的文件系统。
# -h HOSTNAME 或者 --hostname=HOSTNAME:设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。
# --dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。
# --dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com。

查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息:

docker run -it --rm ubuntu cat etc/resolv.conf

docker compose

compose常用命令

docker-compose pull # 拉取工程中所有服务依赖的镜像
docker-compose pull nginx # 拉取工程中 nginx 服务依赖的镜像

# 创建、启动、服务状态
docker-compose up -d # 启动服务,-d:后台,缺省读取当前路径的docker-compose.yml文件,可用-f指定、也可多次-f指定多个yml文件
docker-compose up -d --force-recreate # 修改配置文件后,重启容器
docker-compose images [service] # 查看服务容器所对应的镜像
docker-compose port [service] 80 # 打印指定服务容器的某个端口所映射的宿主机端口
docker-compose ps [service]  # 列出工程中所有、指定服务的容器
docker-compose top [service] # 显示工程中所有、指定服务的容器正在运行的进程
docker-compose scale web=2 worker=3 # 服务扩展

# 容器操作
docker-compose logs -f --no-color # 跟踪日志输出,不用颜色区分

docker-compose start|restart|stop [service]   # 启动|停止|重启工程中所有、指定服务或网络
docker-compose pause|unpause [service]   # 暂停|恢复服务...
docker-compose down --rmi all # 停止并删除工程中所有服务的容器、网络、镜像

docker-compose run nginx echo "helloworld" # 在工程中指定服务的容器上执行 echo "helloworld"
docker-compose exec --index=1 nginx bash # 进入工程中指定服务的容器,index容器序号,默认index=1
docker-compose kill nginx # 通过发送 SIGKILL 信号停止工程中指定服务的容器

# 删除
docker-compose rm # 删除所有(停止状态)服务的容器
docker-compose rm -s [service] # 停止、并删除所有或指定服务
# -s, --stop:如果需要,先停止服务
# -f, --force:强制删除,不询问
# -v,删除附加到容器的任何匿名卷
# -v:删除工程中指定服务的容器

示例:compose部署Nginx

创建nginx工作目录

mkdir -p /data/nginx \
&& cd /data/nginx \
&& mkdir -p conf.d etc html logs www

目录结构:

/data/nginx/
├── conf.d
│   └── default.conf
├── docker-compose.yml
├── etc
├── html
│   ├── 50x.html
│   └── index.html
├── logs
├── nginx.conf
└── www

生成nginx配置文件

# 拉取image
docker pull nginx
docker images

# 启动一个容器
docker run -d --name mynginx nginx
docker ps

# 查看nginx配置文件
docker exec -it mynginx ls -la /etc/nginx /usr/share/nginx/html
# drwxr-xr-x 1 root root 4096 Jan 12 00:21 .
# drwxr-xr-x 1 root root 4096 Jan 13 02:48 ..
# drwxr-xr-x 1 root root 4096 Jan 13 02:48 conf.d
# -rw-r--r-- 1 root root 1007 Oct 24 13:46 fastcgi_params
# -rw-r--r-- 1 root root 5349 Oct 24 13:46 mime.types
# lrwxrwxrwx 1 root root   22 Oct 24 16:10 modules -> /usr/lib/nginx/modules
# -rw-r--r-- 1 root root  648 Oct 24 16:10 nginx.conf
# -rw-r--r-- 1 root root  636 Oct 24 13:46 scgi_params
# -rw-r--r-- 1 root root  664 Oct 24 13:46 uwsgi_params
 
# -rw-r--r-- 1 root root  497 Oct 24 13:46 50x.html
# -rw-r--r-- 1 root root  615 Oct 24 13:46 index.html

# 从容器复制配置文件
docker cp mynginx:/etc/nginx/nginx.conf /data/nginx/
docker cp mynginx:/etc/nginx/conf.d/ /data/nginx/
docker cp mynginx:/usr/share/nginx/html /data/nginx/
hostname >> /data/nginx/html/index.html # 添加个标记方便识别

# 停止并删除容器
docker stop mynginx
docker rm mynginx

docker-compose.yml

# docker-compose.yml
version: '3' # 依丛的compose版本
services:
  mynginx: # 服务名
    restart: always
    container_name: mynginx # 指定自定义容器名称,而不是生成的默认名称
    image: nginx # 使用官方的latest版本镜像
    ports:  # 端口映射
      - 8080:80 
      #- 8443:443
    volumes: # 挂载主机的数据卷或文件到容器,用来存储持久化的数据
      - /data/nginx/html:/usr/share/nginx/html
      - /data/nginx/www:/var/www
      - /data/nginx/logs:/var/log/nginx
      - /data/nginx/nginx.conf/:/etc/nginx/nginx.conf
      - /data/nginx/conf.d:/etc/nginx/conf.d
      #- /data/nginx/etc/cert:/etc/nginx/cert
    environment: # 设置容器中的环境变量
      - NGINX_PORT=80
      - TZ=Asia/Shanghai
    #network_mode: overlay # 设置容器网络模式:host,bridge,overlay,macvlan
    restart: always # 容器重启策略,默认no:不重启、always:总是启动、on-failure:非正常退出时才重启、unless-stopped:容器退出时重启

    # docker容器默认是以非特权用户身份运行,无法访问主机的设备文件、修改内核参数等,可减少潜在安全风险。
    # privileged:true将容器设置为特权模式(不安全),容器拥有与主机相同的权限,仅必要时才打开。
    # privileged: true
#volumes: # 在/var/lib/docker/volumes/目录下创建卷,可用docker volume ls查看
#  data:

部署nignx

# 进入docker-compose.yml所在目录
cd /data/nginx

# 创建并启动容器
docker-compose up -d
# 修改配置文件后,重启容器
docker-compose up -d --force-recreate

# compose会单独创建一个网络
# Creating network "nginx_default" with the default driver
# Creating mynginx ... done

# 检查容器状态
docker ps
docker-compose ps
# Name                Command               State                  Ports
# ---------------------------------------------------------------------------------------
# mynginx   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8080->80/tcp,:::8080->80/tcp

# nginx reload
docker exec <容器id> nginx -s reload
docker exec <容器id> service nginx reload

# 停止、启动容器
docker-compose stop|start

# 删除服务
docker-compose rm

Dockerfile

VirtualBox