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
卷
实现数据持久化(数据不随着容器结束而结束)
将数据从宿主机挂载到容器中:
- volumes(常用)
docker管理宿主机文件系统的一部分,
默认位于/var/lib/docker/volumes目录中
- bind mounts(比较常用)
可以存储在宿主机系统的任意位置,
!!! 注意此模式在不同的宿主机系统时不可移植
所以bind mount不能出现在ockerfile中
绑定的目录在容器中无法看到,可以到宿主机中查看
- 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
最佳实践
- 一定要打上标签
语义化镜像方便使用者
如不指定则默认为latest
- 使用镜像时指定特定的版本标签(确保DockerFile保持不变),禁用latest
总是使用特定版本的标签,而不是使用latest
总是拉取latest将导致版本错误而难以排查
- 容器职责单一
不要在一个容器运行多个服务
后续水平扩展困难
降低CI速度
- 以非root身份运行容器
容器中的应用默认以root身份运行
- 不要运行不必要的服务(如ssh)
保证容器精简,尽可能最大程度的提高性能,降低风险
如非必要则不开启相应的服务
不在容器中开启ssh,二十通过docker exec登录容器
- 不加载不需要的程序,优先使用最小功能集的基础镜像
尽可能的移除不需要的依赖,加速CI过程
占用更少存储
冷启动(拉取镜像)更快
攻击面更少
- 在容器内加入性能监控工具
从应用级监控应用和容器
App dynamics、 Newrelic
- 镜像溯源LABEL
需要保证镜像可追踪
镜像是怎样创建的。
验证镜像在创建后未经更改。
验证镜像的内容。
扫描镜像是否有安全漏洞(Clair提供自动容器漏洞和安全扫描,基于常见的漏洞和公开(CVE))
在Dockerfile中通过LABEL设置相关信息
FROM testimage
LABEL author=test
- 不在镜像中存储敏感数据
避免出现任何敏感数据,一旦镜像推送到公共hub将导致问题
避免在Dockerfile中复制敏感数据,敏感数据存储在安全系统中再与容器相连
- 数据和日志
不在容器存储数据和日志,容器是瞬态、无状态应用程序的理想选择,存储在容器中的所有数据都应该是短暂的,关闭容器后数据将丢失。
- 提倡使用Dockerfile格式检查工具
联系我:renhanlinbsl@163.com