docker常用命令&最佳实践

添加源


yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

安装docker引擎

yum install docker-ce docker-ce-cli containerd.io

docker安装完成后会自动在宿主机创建docker用户组

docker以服务方式安装,centos7使用systemctl管理服务

systemctl start docker

启动容器

docker run -d -p 80:80 --add-host A.COM:127.0.0.1 imageName  
-d 以分离模式运行容器(在后台)
-p 80:80 宿主机端口:容器端口,将主机的 80 端口映射到容器中的 80 端口
ip:hostPort:containerPort
--add-host 传递hosts映射到容器内部
imageName 容器所使用的镜像

优化--add-host

可以使用awk来拼接宿主机的hosts文件

cat /etc/hosts | awk   'NF && $1!~/^#/ && NR>3  {print "--add-host " $2 ":" $1}'

docker run -d -p 80:80 $(cat /etc/hosts | awk   'NF && $1!~/^#/ && NR>3  {print "--add-host " $2 ":" $1}') imageName  

# NF 跳过空白行
# $1!~/^#/ 跳过注释行
# NR>3跳过第三行

# 

docker file
CMD ["node", "src/index.js"]
CMD指令指定从该映像启动容器时要运行的默认命令,CMD会被docker run -it覆盖(被外部参数覆盖)

构建镜像

docker build  -t ImageName:TagName dir  
-t − 给镜像加一个Tag  
ImageName − 给镜像起的名称  
TagName − 给镜像的Tag名  
Dir − Dockerfile所在目录  

管理镜像

docker image 

列出所有镜像

docker image ls 

查看容器情况

docker ps

停止容器ID为containerID的容器

docker stop containerID

删除容器ID为containerID的容器

docker rm dontainerDI

执行一个命令

docker exec containerID command

例:

docker exec 02dee0073f73 ls

进入容器内部

docker exec -it containername bash

实现数据持久化(数据不随着容器结束而结束)

将数据从宿主机挂载到容器中:

  1. volumes(常用)
docker管理宿主机文件系统的一部分,
默认位于/var/lib/docker/volumes目录中
  1. bind mounts(比较常用)
可以存储在宿主机系统的任意位置,
!!! 注意此模式在不同的宿主机系统时不可移植
所以bind mount不能出现在ockerfile中
绑定的目录在容器中无法看到,可以到宿主机中查看
  1. tmpfs(一般不会用)
挂载在宿主机系统的内存中

管理卷

docker volume


#创建自定义卷
docker volume create vloumename-vol


#查看所有容器卷
docker volume ls

#查看指定容器卷信息
docker volume inspect volumename-vol

#删除自定义数据卷
docker volume rm volumename-vol

使用卷

#将edc-nginx-vol卷挂载到/usr/share/nginx/html
#docker run 通过 -v 挂载数据卷
# docker run -d -it --name=edc-nginx -p 8800:80 
-v edc-nginx-vol:/usr/share/nginx/html nginx

#在数据卷里边的东西是可以持久化的。如果下次还需要创建一个nginx容器,那么还是复用当前数据卷里面的文件

#还可以启动多个nginx容器实例,并且共享同一个数据卷,复用性和扩展性较强

创建的卷为目录,实际文件可进入卷进行查看(数据在卷中的_data目录中)

bind mounts

#指定了将宿主机上的 /app/wwwroot 目录挂载到 /usr/share/nginx/html 
docker run -d -it --name=edc-nginx -v /app/wwwroot:/usr/share/nginx/html nginx

验证绑定

docker inspect edc-nginx

重新加载consul配置

docker exec consul-server consul reload

bind mount

  容器以宿主机文件夹为准
  可以自定义文件路径
  通常用于向容器提供额外的数据

volume

  宿主有数据时,以宿主机为准

  宿主无数据,从容器复制过来,再以宿主机为准
  
  
  

容器网路

默认情况下,容器独立运行,并对同一台机器上的其他进程或容器一无所知

创建网络

docker network create networkName

查看网络

docker network ls

使用网络,通过network指定

docker run -dp 3000:3000 
   -w /app -v "$(pwd):/app" 
   --network todo-app 
   -e MYSQL_HOST=mysql 
   -e MYSQL_USER=root 
   -e MYSQL_PASSWORD=secret 
   -e MYSQL_DB=todos 
   node:12-alpine 
   sh -c "yarn install && yarn run dev"

在容器内部使用network时只需要将网络名称当成主机域名即可,
docker内部能够将其识别为对应的ip(类似A记录,A networkName 172.1.1.1)

Docker Compose(帮助定义和共享多容器应用程序)

安装

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

#添加可执行权限
sudo chmod +x /usr/local/bin/docker-compose

#创建软链接
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

定义docker-compose.yml

#docker-compose.yml
#compose版本(https://docs.docker.com/compose/compose-file/)
version: "3.7"
services: # 定义服务
    app:  # 服务名称将自动成为网络别名
      image: node:12-alpine  #
      command: sh -c "yarn install && yarn run dev"
      ports: 
        - 3000:3000
      working_dir: /app
      volumes:
        - ./:/app  # 工作目录:卷(可以使用当前目录的相对路径)
                   # docker-compose中定义的卷不会自动创建
                   # 需要在顶级volumes: 中定义卷
      environment:
        MYSQL_HOST: mysql
        MYSQL_USER: root
        MYSQL_PASSWORD: secret
        MYSQL_DB: todos
    mysql:
       image: mysql:5.7
       volumes:
         - todo-mysql-data:/var/lib/mysql
       environment:  # 环境变量
         MYSQL_ROOT_PASSWORD: secret
         MYSQL_DATABASE: todos

volumes: # 定义卷
   todo-mysql-data:

运行docker-compose

docker-compose up -d

# -d 后台启动所有容器

查看日志

docker-compose logs -f

查看具体某个服务的日志

docker-compose logs -f serviceName

停止并移除资源

docker-compose down

# 如果要删除卷,需要添加--volumes

导入导出容器

docker export containerID > imageName.tar

docker import - newContainer < imageName.tar

导入导出镜像

#docker images 列出所有镜像
docker save -o redis.tar redis:5.0.2
docker load --input ubuntu_14.04.tar

//给指定的镜像打赏标签
docker tag 镜像id aspnetsdk

安全扫描

使用py3安装方式

yum install python3 -y

pip3 install dockerscan
dockerscan image analyze new.tar 

切换源

docker容器自动启动

docker run添加参数 --restart=

no             不自动重启容器. (默认value)
on-failure     容器发生error而退出(容器退出状态不为0)重启容器
unless-stopped 在容器已经stop掉或Docker stoped/restarted的时候才重启容器
always         在容器已经stop掉或Docker stoped/restarted的时候才重启容器

更新容器的配置docker update

docker update --cpu-shares 512 f361b7d8465


Options:
      --blkio-weight uint16        Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
      --cpu-period int             Limit CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int              Limit CPU CFS (Completely Fair Scheduler) quota
      --cpu-rt-period int          Limit the CPU real-time period in microseconds
      --cpu-rt-runtime int         Limit the CPU real-time runtime in microseconds
  -c, --cpu-shares int             CPU shares (relative weight)
      --cpus decimal               Number of CPUs
      --cpuset-cpus string         CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string         MEMs in which to allow execution (0-3, 0,1)
      --kernel-memory bytes        Kernel memory limit
  -m, --memory bytes               Memory limit
      --memory-reservation bytes   Memory soft limit
      --memory-swap bytes          Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --pids-limit int             Tune container pids limit (set -1 for unlimited)
      --restart string             Restart policy to apply when a container exits


docker rm : 删除一个或多个 容器

docker rmi : 删除一个或多个 镜像

docker prune: 用来删除不再使用的 docker 对象

dockerfile中切换用户

RUN useradd -ms /bin/bash testuser

USER testuser

dockerfile内切换.net5源(debian)

RUN sed -i "s#http://deb.debian.org#http://mirrors.aliyun.com#g" /etc/apt/sources.list
RUN cat /etc/apt/sources.list
RUN rm -Rf /var/lib/apt/lists/*
RUN apt-get update

dockerfile中解决时区与宿主机不同步问题

RUN rm -rf /etc/localtime && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

最佳实践

  1. 一定要打上标签
语义化镜像方便使用者
如不指定则默认为latest
  1. 使用镜像时指定特定的版本标签(确保DockerFile保持不变),禁用latest
总是使用特定版本的标签,而不是使用latest
总是拉取latest将导致版本错误而难以排查
  1. 容器职责单一
不要在一个容器运行多个服务
后续水平扩展困难
降低CI速度
  1. 以非root身份运行容器
容器中的应用默认以root身份运行
  1. 不要运行不必要的服务(如ssh)
保证容器精简,尽可能最大程度的提高性能,降低风险
如非必要则不开启相应的服务
不在容器中开启ssh,二十通过docker exec登录容器
  1. 不加载不需要的程序,优先使用最小功能集的基础镜像
尽可能的移除不需要的依赖,加速CI过程
占用更少存储
冷启动(拉取镜像)更快
攻击面更少
  1. 在容器内加入性能监控工具
从应用级监控应用和容器
App dynamics、 Newrelic 
  1. 镜像溯源LABEL
需要保证镜像可追踪
镜像是怎样创建的。
验证镜像在创建后未经更改。
验证镜像的内容。
扫描镜像是否有安全漏洞(Clair提供自动容器漏洞和安全扫描,基于常见的漏洞和公开(CVE))


在Dockerfile中通过LABEL设置相关信息
FROM testimage
LABEL author=test
  1. 不在镜像中存储敏感数据
避免出现任何敏感数据,一旦镜像推送到公共hub将导致问题
避免在Dockerfile中复制敏感数据,敏感数据存储在安全系统中再与容器相连
  1. 数据和日志
不在容器存储数据和日志,容器是瞬态、无状态应用程序的理想选择,存储在容器中的所有数据都应该是短暂的,关闭容器后数据将丢失。
  1. 提倡使用Dockerfile格式检查工具
留待后查,同时方便他人
联系我:renhanlinbsl@163.com
原文地址:https://www.cnblogs.com/ives/p/15118831.html