Docker 配置与实践清单
Posted 分布式实验室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker 配置与实践清单相关的知识,希望对你有一定的参考价值。
# 更改 Ubuntu 默认源地址
$ sudo sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
# 安装必备的系统命令
$ sudo apt-get install -y python-software-properties
$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ apt-cache policy docker-ce # 列举 docker-ce 版本
$ apt-get install docker-ce=17.03.2-ce....
# 配置开机自启动
$ sudo systemctl enable docker
# 取消开机自启动
$ sudo systemctl disable docker
# 使用 systemctl 命令行修改
$ sudo systemctl edit docker.service
# 或者查找配置地址并使用 Vim 修改
$ systemctl status docker
# 修改文件内容
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock --insecure-registry 10.196.108.176:5000 --dns 114.114.114.114 --dns 8.8.8.8 --dns 8.8.4.4 -g /mnt
# 重新载入服务配置
$ sudo systemctl daemon-reload
# 重启 Docker
$ sudo systemctl restart docker.service
# 判断是否配置成功
$ sudo netstat -lntp | grep dockerd
# 在主节点启动 Swarm
$ docker swarm init
# 查看 Swarm 密钥
$ docker swarm join-token -q worker
# 在主节点启动 Procontainer
$ docker run -it -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
# 在主节点启动 Registry
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
# 将子节点加入到 Swarm
$ docker swarm join
--token ${TOKEN}
10.196.108.176:2377
$ docker run -i -t -e SERVER_ADDR=ss.server.ip -e SERVER_PORT=port -e PASSWORD=123456 bluebu/shadowsocks-privoxy
$ apt install python3-pip
$ pip3 install https://github.com/shadowsocks/shadowsocks/archive/master.zip -U
{
"server": "...",
"server_port": ...,
"local_port": 1080,
"password": "..."
"method": "chacha20-ietf-poly1305",
"timeout": 600
}
$ sslocal -c config.json
listen-address 0.0.0.0:8118 # 所有 interface 上监听流量
forward-socks5 / 127.0.0.1:1080 . # 流量导向本机上的 ss 代理
HTTP_PROXY=127.0.0.1:8118 HTTPS_PROXY=127.0.0.1:8118 curl https://www.google.com
[Environment]
Environment="HTTP_PROXY=127.0.0.1:8118" "HTTPS_PROXY=127.0.0.1:8118" "NO_PROXY=localhost,127.0.0.1,1.1.1.2,1.1.1.3,1.1.1.4"
...
$ sudo docker build -t myrepo/myapp /tmp/test1/
$ docker build -t username/image_name:tag_name .
$ docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
# 拉取镜像
$ docker pull image_name
# 将某个容器保存为镜像
$ docker commit -m “commit message” -a “author” container_name username/image_name:tag
复制代码Docker 支持将镜像保存为文件,以方便镜像的导出与加载:
# 保存镜像
$ docker save --output saved-image.tar my-image:1.0.0
$ docker save my-image:1.0.0 > saved-image.tar
$ docker save my_image:my_tag | gzip > my_image.tar.gz
# 导入镜像
$ docker load --input saved-image.tar
$ docker load < saved-image.tar
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
mynewimage latest 4d2eab1c0b9a 5 minutes ago 278.1 MB
ubuntu 14.04 ad892dd21d60 11 days ago 275.5 MB
<none> <none> 6b0a59aa7c48 11 days ago 169.4 MB
<none> <none> 6cfa4d1f33fb 7 weeks ago 0 B
已使用镜像(used image): 指所有已被容器(包括已停止的)关联的镜像。即 docker ps -a 看到的所有容器使用的镜像。
未引用镜像(unreferenced image):没有被分配或使用在容器中的镜像,但它有 Tag 信息。
悬空镜像(dangling image):未配置任何 Tag (也就无法被引用)的镜像,所以悬空。这通常是由于镜像 build 的时候没有指定 -t 参数配置 Tag 导致的。
# 列举未使用的
$ docker images --filter "dangling=true"
# 删除所有无用的镜像
$ docker rmi $(docker images -q -f dangling=true)
#
# MongoDB Dockerfile
#
# https://github.com/dockerfile/mongodb
#
# Pull base image.
FROM dockerfile/ubuntu
ENV SOURCE http://downloads-distro.mongodb.org/repo/ubuntu-upstart
# Install MongoDB.
RUN
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 &&
echo 'deb $SOURCE dist 10gen' > /etc/apt/sources.list.d/mongodb.list &&
apt-get update &&
apt-get install -y mongodb-org &&
rm -rf /var/lib/apt/lists/*
ENV PATH /usr/local/mongo/bin:$PATH
# Define mountable directories.
VOLUME ["/data/db"]
# Define working directory.
WORKDIR /data
# Define default command.
CMD ["mongod"]
# Expose ports.
# - 27017: process
# - 28017: http
EXPOSE 27017
EXPOSE 28017
指令名 | 格式 | 描述 | 备注 |
---|---|---|---|
FROM | 格式为 FROM <image> 或FROM <image>:<tag> |
第一条指令必须为 FROM 指令。 |
如果在同一个 Dockerfile 中创建多个镜像时,可以使用多个 FROM 指令(每个镜像一次) |
MAINTAINER | 格式为 MAINTAINER <name> |
指定维护者信息。 | |
RUN | RUN <command> 或 RUN ["executable", "param1", "param2"] |
前者将在 shell 终端中运行命令,即 /bin/sh -c ;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"] |
每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 来换行。 |
CMD | 支持三种格式,CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数; |
指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。 |
|
EXPOSE | EXPOSE <port> [<port>...] |
告诉 Docker 服务端容器暴露的端口号,供互联系统使用 | 在启动容器时需要通过 -p 来指定端口映射,Docker 主机会自动分配一个端口转发到指定的端口 |
ENV | ENV<key><value> 。指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持 |
||
ADD | ADD<src><dest> |
该命令将复制指定的 <src> 到容器中的 <dest> 。 |
<src> 可以是 Dockerfile 所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录) |
COPY | COPY <src><dest> |
复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径)到容器中的 dest |
当使用本地目录为源目录时,推荐使用 COPY |
ENTRYPOINT | ENTRYPOINT ["executable", "param1", "param2"] ,使用指定可执行文件执行;ENTRYPOINT command param1 param2 ,会在 Shell 中执行 |
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。每个 Dockerfile 中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效。 |
|
VOLUME | VOLUME ["/data"] |
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等 | |
USER | USER daemon |
指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户 |
|
WORKDIR | WORKDIR /path/to/workdir |
为后续的 RUN 、CMD 、ENTRYPOINT 指令配置工作目录 |
可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径 |
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres;要临时获取管理员权限可以使用 gosu,而不推荐 sudo。
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
# docker run -it <image>
# Hello world
# docker run -it <image> John
# Hello John
FROM ubuntu:latest
RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY my_first_process my_first_process
COPY my_second_process my_second_process
CMD ["/usr/bin/supervisord"]
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
# 拉取公共镜像
$ docker pull ubuntu:16.04
# 为镜像添加 Registry 信息
$ docker tag ubuntu:16.04 custom-domain:5000/my-ubuntu
# 将其推送到私有镜像库
$ docker push custom-domain:5000/my-ubuntu
# 从私有镜像库中拉取镜像
$ docker pull custom-domain:5000/my-ubuntu
-v /mnt/registry:/var/lib/registry
{ "insecure-registries": ["myregistry.example.com:5000"] }
$ mkdir auth
$ docker run
--entrypoint htpasswd
registry:2 -Bbn cscan cscancscan > ~/auth/htpasswd
$ openssl req -new -newkey rsa:4096 -days 365
-subj "/CN=localhost"
-nodes -x509
-keyout ~/certs/domain.key
-out ~/certs/domain.crt
registry-srv:
restart: always
image: registry:2
ports:
- 5000:5000
environment:
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
REGISTRY_HTTP_TLS_KEY: /certs/domain.key
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
volumes:
- /opt/registry:/var/lib/registry
- ~/certs:/certs
- ~/auth:/auth
$ docker-compose up -d
# 登录到镜像服务器
$ docker login myregistrydomain.com:5000
docker create:创建一个容器但是不启动。
docker rename:允许重命名容器。
docker run:在同一个操作中创建并启动一个容器。
docker rm:删除容器。
docker update:更新容器的资源限制。
-i 即使在没有附着的情况下依然保持 STDIN 处于开启。单纯使用 -i 命令是不会出现 root@689d580b6416:/ 这种前缀
-t 分配一个伪 TTY 控制台
# 创建,并且启动某个容器以执行某个命令
$ docker run -ti --name container_name image_name command
# 创建,启动容器执行某个命令然后删除该容器
$ docker run --rm -ti image_name command
# 创建,启动容器,并且映射卷与端口,同时设置环境变量
$ docker run -it --rm -p 8080:8080 -v /path/to/agent.jar:/agent.jar -e JAVA_OPTS=”-javaagent:/agent.jar” tomcat:8.0.29-jre8
# 创建容器,指定网络
$ docker run --network=<NETWORK>
标志值 | 描述 |
---|---|
-p 8080:80 |
将容器的 80 端口映射到 Docker 主机的 8080 端口(TCP) |
-p 8080:80/udp |
将容器的 80 端口映射到 Docker 主机的 8080 端口(UDP) |
-p 8080:80/tcp -p 8080:80/udp |
将容器的 80 端口映射到 Docker 主机的 8080 端口(TCP 和 UDP) |
# 启动/停止某个容器
$ docker [start|stop] container_name
# 在某个容器内执行某条命令
$ docker exec -ti container_name command.sh
# 查看某个容器的输出日志
$ docker logs -ft container_name
docker ps 查看运行中的所有容器。
docker logs 从容器中获取日志。(你也可以使用自定义日志驱动,不过在 1.10 中,它只支持 json-file 和 journald)
docker events 从容器中获取事件(events)。
docker port 查看容器的公开端口。
docker top 查看容器中活动进程。
docker stats 查看容器的资源使用情况统计信息。
docker diff 查看容器的 FS 中有变化文件信息。
# 根据条件过滤查询
$ docker ps --filter "name=nostalgic"
# 显示正在运行的容器列表
$ docker stats --all
no:不进行重启
on-failure:当容器以非零状态码退出时重启容器
unless-stopped:当某个容器被显性关闭或者 Docker 本身关闭或重启时重启
always:无论出现任何情况都重启容器
# 设置重启策略
# Off, On-failure, Unless-stopped, Always
$ docker run -dit — restart unless-stopped [CONTAINER]
# 关闭所有正在运行的容器
$ docker kill $(docker ps -q)
# 移除所有停止的容器
$ docker rm $(docker ps -a -q)
# 根据状态移除
$ docker rm $(docker ps -q -f 'status=exited')
# 根据标签移除
$ docker rm $(docker ps -a | grep rabbitmq | awk '{print $1}')
$ docker rm $(docker ps -a | grep "46 hours ago")
docker cp 在容器和本地文件系统之间复制文件或文件夹。
docker export 将容器的文件系统切换为压缩包(tarball archive stream)输出到 STDOUT。
$ docker stats redis1 redis2
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
redis1 0.07% 796 KB / 64 MB 1.21% 788 B / 648 B 3.568 MB / 512 KB
$ docker run -it -m 300M ubuntu:14.04 /bin/bash
# 指定容器可占用的 CPU 核编号,0-3 表示占用四个核,1、3 表示占用两个核
$ docker run -it --cpuset-cpus="1,3" ubuntu /bin/bash
# 最多允许占用单 CPU 50% 的计算资源,如果双核 CPU,则可以设置为 1.5 等
$ docker run -it --cpus=".5" ubuntu /bin/bash
# 不同的值能够指定不同的容器权重,用于动态分配 CPU 资源
$ docker run -it --cpu-shares="512" ubuntu /bin/bash
# 限制单个容器最多占用 20G 空间,将应用于任何新建容器。
$ --storage-opt dm.basesize=20G
$ btrfs qgroup limit -e 50G /var/lib/docker/btrfs/subvolumes/<CONTAINER_ID>
docker run -it --device=/dev/ttyUSB0 debian bash
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash
数据卷可以在容器之间共享和重用
对数据卷的修改会立马生效
对数据卷的更新,不会影响镜像
卷会一直存在,直到没有容器使用
数据卷的使用,类似于 Linux 下对目录或文件进行 mount
# the following creates a tmpfs volume called foo with a size of 100 megabyte and uid of 1000.
$ docker volume create --driver local
--opt type=tmpfs
--opt device=tmpfs
--opt o=size=100m,uid=1000
foo
$ docker volume create --driver local
--opt type=nfs
--opt o=addr=192.168.1.1,rw
--opt device=:/path/to/dir
foo
$ docker run -d
-it
--name devtest
-v myvol2:/app
nginx:latest
"Mounts": [
{
"Type": "volume",
"Name": "myvol2",
"Source": "/var/lib/docker/volumes/myvol2/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
# 挂载目录
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
# 挂载文件
$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
# Docker 挂载数据卷的默认权限是读写,用户也可以通过 `:ro` 指定为只读。
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro
training/webapp python app.py
VOLUME /data
bridge:默认的网络驱动,常用于多个应用运行与独立容器中并且需要相互通讯的时候。
host:移除容器与 Docker 主机之间的网络隔离,直接使用宿主机所在的网络。底层与宿主机共用一个 Network Namespace,容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。
Overlay:Overlay 网络用语连接多个 Docker Daemon,保证 Docker Swarm 服务的正常运行;独立的容器与 Swarm 服务,或者不同宿主机上的容器同样能够通过 Overlay 进行通信。
none:对于指定容器禁止所有的网络通信。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
f707aa0ef50d bridge bridge local
97dd7a032d96 host host local
d5a1bed0b12d none null local
# 创建新的网络
$ docker network create --driver bridge isolated
# 指定网段,宿主机会作为默认网关
$ docker network create --driver=bridge --subnet=192.168.2.0/24 --gateway=192.168.2.10 new_subnet
# 创建时将某个容器连接到网络
$ docker run --network=isolated -itd --name=docker-nginx nginx
# 将某个运行中容器连接到某个网络
$ docker network connect multi-host-network container1
-h HOSTNAME or --hostname=HOSTNAME 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts 。但它在容器外部看不到,既不会在 docker ps 中显示,也不会在其他的容器的 /etc/hosts 看到。
--link=CONTAINER_NAME:ALIAS 选项会在创建容器的时候,添加一个其他容器的主机名到 /etc/hosts 文件中,让新容器的进程可以使用主机名 ALIAS 就可以连接它。
--dns=IP_ADDRESS 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。
--dns-search=DOMAIN 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的 主机时,DNS 不仅搜索 host,还会搜索 host.example.com 。 注意:如果没有上述最后 2 个选项, Docker 会默认用主机上的 /etc/resolv.conf 来配置容器。
# 查看当前目录下的文件空间占用
$ du -h --max-depth=1 | sort
# 空间占用总体分析
$ docker system df
# 输出空间占用细节
$ docker system df -v
# 输出容器的空间占用
$ docker ps -s
# 一并清除所有未使用的镜像和悬空镜像
$ docker system prune --all
# 列举悬空镜像
$ docker images -f dangling=true
# 删除全部悬空镜像
$ docker image prune
# 删除所有未被使用的镜像
$ docker image prune -a
# 删除指定模式的镜像
$ docker images -a | grep "pattern" | awk '{print $3}' | xargs docker rmi
# 删除全部镜像
$ docker rmi $(docker images -a -q)
# 删除全部停止的容器
$ docker rm $(docker ps -a -f status=exited -q)
# 根据指定模式删除容器
$ docker rm $(docker ps -a -f status=exited -f status=created -q)
$ docker rm $(docker ps -a | grep rabbitmq | awk '{print $1}')
# 删除全部容器
$ docker stop $(docker ps -a -q)
$ docker rm $(docker ps -a -q)
# 列举并删除未被使用的卷
$ docker volume ls -f dangling=true
$ docker volume prune
# 根据指定的模式删除卷
$ docker volume prune --filter "label!=keep"
# 删除未被关联的网络
$ docker network prune
$ docker network prune --filter "until=24h"
复制代码我们也可以手动指定日志文件的尺寸或者清空日志文件:
# 设置日志文件最大尺寸
$ dockerd ... --log-opt max-size=10m --log-opt max-file=3
# 清空当前日志文件
truncate -s 0 /var/lib/docker/containers/*/*-json.log
# 指定 Docker Compose 文件版本
version: '3'
services:
web:
# 指定从本地目录进行编译
build: .
# 指定导出端口
ports:
- '5000:5000'
# 替换默认的 CMD 命令
command: python app.py
# 将本地目录绑定到容器内目录
volumes:
- .:/code
redis:
# 镜像的 ID
image: 'redis:alpine'
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
cache = redis.Redis(host='redis', port=6379)
# 交互式启动
$ docker-compose up
# 守护进程式启动
$ docker-compose up -d
# 查看运行情况
$ docker-compose ps
# 关闭
$ docker-compose stop
# 移除内部卷
$ docker-compose down --volumes
version: "3.2"
services:
web:
image: nginx:alpine
volumes:
- type: volume
source: mydata
target: /data
volume:
nocopy: true
- type: bind
source: ./static
target: /opt/app/static
db:
image: postgres:latest
volumes:
- "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
- "dbdata:/var/lib/postgresql/data"
volumes:
mydata:
dbdata:
# 创建一个新的服务
$ docker service create
--image nginx
--replicas 2
nginx
# 更新服务
$ docker service update
--image nginx:alpine
nginx
# 删除服务
$ docker service rm nginx
# 缩容,而不是直接删除服务
$ docker service scale nginx=0
# 扩容
$ docker service scale nginx=5
# 列出所有的服务
$ docker service ls
# 列出一个服务的所有实例(包括服务的健康状况)
$ docker service ps nginx
# 服务的详细信息
$ docker service inspect nginx
$ docker stack deploy application
version: '3'
services:
web:
image: registry.gitlab.com/example/example # you need to use external image
command: npm run prod
ports:
- 80:80
deploy:
replicas: 6
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
https://github.com/wxyyxc1992/Awesome-Links/blob/master/Infrastructure/Virtualization/Container/Docker/Docker-Links.md
https://github.com/wxyyxc1992/Awesome-CheatSheet/blob/master/Infrastructure/OS/Linux/Linux-Commands-CheatSheet.md
https://github.com/wxyyxc1992/Backend-Boilerplate/tree/master/infra/docker
https://mirrors.ustc.edu.cn/help/docker-ce.html
https://docs.docker.com/config/containers/multi-service_container/
以上是关于Docker 配置与实践清单的主要内容,如果未能解决你的问题,请参考以下文章
Docker&Kubernetes ❀ Kubernetes集群实践与部署笔记知识点梳理
Docker&Kubernetes ❀ Kubernetes集群YAML语法与不同等级属性资源配置清单参数查询方法
Docker&Kubernetes ❀ Kubernetes集群YAML语法与不同等级属性资源配置清单参数查询方法