Dockerdocker学习docker

Docker使用手册

2017-12-13  本文已影响729人  xld

docker官网教程(学习一样新东西最快的方法是去看官方文档,讲解的清楚,教程简单,但是包括的面十分的广,只记录自己觉得有用的命令,详细请去官网查看Docker start),其中也发现一篇很好的教程,简洁明了,我也在这里学到了很多,也摘录总结在了这里,推荐大家去Docker--从入门到实践进行学习。也可以fork那个项目下来进行贡献。如果网速有问题可以docker一个,直接本地访问(教程提供的方法,我只是搬运一下)

$ docker pull dockerpracticecn/docker_practice

$ docker run -it --rm -p 4000:80 dockerpracticecn/docker_practice

访问127.0.0.1:4000即可

了解docker的祖师级别的语句,如同代码里的hello-world

docker run hello-world

查看版本

docker --version

Dockerfile

# Use an official Python runtime as a parent image
FROM python:2.7-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

requirements.txt

Flask
Redis

app.py

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

创建app(注意有个点)

docker build -t friendlyhello .

找到新建的镜像

$ docker images

REPOSITORY            TAG                 IMAGE ID
friendlyhello         latest              326387cea39

跑起来

docker run -d -p 4000:80 friendlyhello

访问http://localhost:4000即可


好不容易创建了一个镜像,想分享一下,肿么办

登录

docker login

打标签

docker tag image username/repository:tag
举个例子
docker tag image yugougou/get-started:part2
这里的于狗狗是你的用户名,get-started是仓库名

公布镜像

docker push username/repository:tag
例如
docker push yugougou/get-started:part2

测试(拉一把 看看能不能跑起来)

docker run -p 4000:80 username/repository:tag
例如一个
docker run -p 4000:80 yugougou/get-started:part2

如果能成功跑起来,那就没什么问题了

docker-compose.yml(里面有services还有networks)

version: "3"
services:
  web:
    # replace username/repo:tag with your name and image details
    image: yugougou/get-started:part2
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
    networks:
      - webnet
networks:
  webnet:

启动第一个负载均衡的app,肯定是少不了要用集群的,这里使用的镜像就是上一节我们制作的镜像。

docker swarm init

启动它 给他起一个漂亮的名字

docker stack deploy -c docker-compose.yml getstartedlab

看看我们起的服务如何

docker service ls


yugougou@yugougoudeMacBook-Pro:~/Desktop $docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                        PORTS
9cinwb60b78b        getstartedlab_web   replicated          10/10               yugougou/get-started:part2   *:80->80/tcp

看看服务里的任务有哪些吧

docker service ps getstartedlab_web

yugougou@yugougoudeMacBook-Pro:~/Desktop $docker service ps getstartedlab_web
ID                  NAME                   IMAGE                        NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
tgbba2qixjoa        getstartedlab_web.1    yugougou/get-started:part2   moby                Running             Running 6 minutes ago
eg9oo085u2ud        getstartedlab_web.2    yugougou/get-started:part2   moby                Running             Running 6 minutes ago
yjc31x8ac2o0        getstartedlab_web.3    yugougou/get-started:part2   moby                Running             Running 6 minutes ago
dmoye5s5n09x        getstartedlab_web.4    yugougou/get-started:part2   moby                Running             Running 6 minutes ago
q16fo41swnai        getstartedlab_web.5    yugougou/get-started:part2   moby                Running             Running 6 minutes ago
idkc65whadin        getstartedlab_web.6    yugougou/get-started:part2   moby                Running             Running 6 minutes ago
s6k7b8o81m35        getstartedlab_web.7    yugougou/get-started:part2   moby                Running             Running 6 minutes ago
rtod8scwkwt7        getstartedlab_web.8    yugougou/get-started:part2   moby                Running             Running 6 minutes ago
z29qubyqa29b        getstartedlab_web.9    yugougou/get-started:part2   moby                Running             Running 6 minutes ago
pbq7qr4e8jhv        getstartedlab_web.10   yugougou/get-started:part2   moby                Running             Running 6 minutes ago

只查看端口

docker ps -q

哎呀 发现之前的编排文件dockerfile里的副本主机起的不够,肿么办,面对这种状况,分两步,第一步打开冰箱,不是 第一步修改dockerfile,然后重启喽,记得名字不要写错

yuzhipeng@yuzhipengdeMacBook-Pro:~/Desktop $docker stack deploy -c docker-compose.yml getstartedlab
Updating service getstartedlab_web (id: 9cinwb60b78bmon03mjakt6mb)

其实我什么也没有改--__--

关掉app(关掉之前用docker service ls 看看)

docker stack rm getstartedlab

(关掉之前用docker service ls 看看)

砸了集群

docker swarm leave --force

(再用docker service ls看看)


大家好 我是分隔符

docker run hello-world
docker --version
docker pull --help

运行jenkins(需要制定端口):
docker run --name myjenkins -p 8080:8080 index.alauda.cn/alaudaorg/alauda-jenkins

查看:
docker ps -a | grep jenkins

进入docker
docker exec -ti c3c bash

编辑docker
cat /var/run/docker.sock

docker login index.alauda.cn

docker-compose up -d

拉取并运行镜像: docker run --name webserver -d -p 80:80 nginx

删除容器: docker container rm webserver

停止容器:docker stop containername

进入容器修改: docker exec -i -t webserver bash

今天要总结一下近期来使用学习docker的经验,很早之前就想来摸索一下docker,但是前些日子一直在忙于找工作,没什么时间,但是现在找到的公司做的是基于docker平台开发paas服务的公司,所以借机好好刷一把docker


Docker的安装

sudo apt-get update

安装 这是用比较新的方法 也可以用

sudo apt-get install docker.io

但是这个下载的版本会比较低 不建议这样下载

sudo apt-get install curl

 curl -sSL  https://get.docker.com/  | sh

下载完毕启动Docker的守护进程

sudo service docker start

检查Docker是否安装成功

sduo docker run hello-world

如果提示Hello from Docker!

当然是里面有提示,并不是一开始的提示就是这个,说明安装成功了提示(Ubnable to find image 'hello-world lateset' locally)

如果不想总是输入sudo 可以输入以下命令解决

sudo usermod -aG docker yuzhipeng


体验Docker

使用docker指令创建 启动几个Docker应用,比如WordPress,gitlab服务

这几个应用下载的话会比较慢 要等几分钟

sudo docker run --name db --env MYSQL_ROOT_PASSWORD=example -d mariadb

sudo docker run --name MyWordPress --link db:mysql -p 8080:80 -d wordpress

--name参数创建了两个Docker容器,db和MyWordPress 通过docker ps可以查到名字

通过ifconfig查看本机的IP地址,在本机地址后加上端口号8080,会有惊喜。简直不能更爽

这个我在京东云上部署了一下,感觉用起来很快,部署效果非常好,比之前部署项目快的过,真的是几条命令就可以跑起来服务,厉害了 访问

sudo docker run --name gitlab-postgresql -d --env 'DB_NAME=gitlabhq_production' --env 'DB_USER=gitlab' --env 'DB_PASS=password' sameersbn/postgresql:9.4-12

然后启动redis

sudo docker run  --name gitlab-redis -d sameersbn/redis:latest 

最后启动gitlab

sudo docker run --name gitlab -d --link gitlab-postgresql:postgresql --link gitlab-redis:redisio --publish 10022:22 --publish 10080:80 --env  'GITLAB_PORT=10080' --env 'GITLAB_SSH_PORT=10022' --env 'GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alpha-numeric-string' sameersbn/gitlab:8.4.4

后来就可以访问端口10080即可进入gitlab,确实是太好用了,这时候用户名为root,密码是yu123456 连接(如果可用) 点击进入


sudo docker run --name=postgresql-redmine -d --env='DB_NAME=redmine_production' --env='DB_USER=redmine' --env='DB_PASS=password' sameersbn/postgresql:9.4-12

 docker run --name=redmine -d --link=postgresql-redmine:postgresql --publish=10083:80 --env='REDMINE_PORT=10083' sameersbn/redmine:3.2.0-4


10分钟小任务认识Docker

版本号

docker version

查找镜像 (镜像的全称是 <username>/<repository>)

docker search tutorial

下载镜像

docker pull learn/tutorial

docker ps -l

用docker run来创建和运行docker容器(docker可以创建容器并在容器中运行指定的命令)

docker run learn/tutorial echo "hello world"

修改容器(安装ping)

docker run learn/tutorial apt-get install -y ping

通过docker ps -l找出安装过ping包的容器的ID号,

docker ps -l

然后将容器提交为新的镜像,这时会返回一个新的ID便是新生成的镜像的ID

docker commit 09c2e9353f01 learn/ping

在基于新镜像的容器中执行 ping www.google.com这条指令(新镜像要使用全名 learn/ping)

docker run learn/ping ping www.google.com

查询容器信息

docker ps 查询所有运行的容器

docker inspect a102 查看单个容器的信息(根据docker ps列出的容器名,选取前三四个字符即可)

新镜像上传仓库

docker images 查询本机的镜像列表

查询结果中有

REPOSITORY                                                                      TAG                 IMAGE ID            CREATED             SIZE
learn/ping                                                                      latest              714c84471b9f        11 minutes ago      139MB

所以把镜像推送到Docker官仓

docker push learn/ping


Docker常用词

查看所有的镜像

docker images

查看相关进程

sudo docker ps

查看版本

docker version

ps只是看一些大体容器内容 inspect是看容器的详细内容

docker ps

docker inspect gitlab

docker push michelesr/ping


docker基础概念与常用命令

1.仓库、镜像、容器

2.基本指令

docker指令操作对象主要针对四个方面:

1 针对守护进程的系统资源设置和全局信息的获取: docker info, docker deamon
2 针对Docker仓库的查询,下载 : docker search, docker pull
3 针对docker镜像的查询,创建与删除: docker images, docker build
4 针对docker容器的查询,创建,开启,停止: docker ps, docker run
5 支持赋值,变量解析,嵌套

docker+命令关键字(command)+一系列参数([arg ])

例如

docker run --name MyWordPress --link db:mysql -p 8080:80 -d wordpress

基于wordpress镜像创建容器MyWordPress,通过docker ps可以查到名字MyWordPress,使用的镜像是woedpress的容器

获取帮助

docker command --help


Docker容器管理

容器标识符

每一个容器创建后都有一个CONTAINER ID作为容器的唯一的标识符,后续对容器的操作都是通过CONTAINER ID来完成,一般docker ps展示前16位,如果查询所有可以使用docker ps --no-trunc

查询容器状态

 docker ps -a | grep d0131ae38d9d

停止容器

docker stop d0131ae38d9d

运行容器

docker start d0131ae38d9d

CONTAINER ID比较难记忆,所以创建容器时会有--name来给容器起一个别名 所以用别名也可以

查询容器信息(使用-f时可以用golang的模板提取出制定信息)

docker inspect -f {{.NetworkSettings.IPAddress}} MyWordPress

查询日志

docker logs MyWordPress

查询容器占用的系统资源

docker stats MyWordPress

容器内部命令

需求:登入Docker容器执行命令

方案: Docker提供原生的方式支持登入docker exec

docker exec + 容器名 + 容器内执行的命令

查看MyWordPress容器内的进程

docker exec MyWordPress ps aux

在容器内连续执行命令 加上 -it 参数即可,相当于以root身份登入,完成后通过 exit 退出

docker exec -it MyWordPress /bin/bash

Docker理念是‘一个容器一个进程’,如果一个服务由多个进程组成,就创建多个容器组成一个系统

在同一个主机下,docker run命令提供 ‘--link’建立容器之间的互联,而且他们是有顺序的,比如如果创建B容器的时候需要使用 ‘--link containerA’,那么创建B的时候,那么
在创建B容器的时候A容器必须已经创建且已经启动

对于WordPress,数据库容器(db)要先于Apache容器(MyWordPress)启动,所以启动方式应该是

docker start db
docker start MyWordPress

停止WordPress服务,先停止Apache容器(MyWordPress),再停止数据库容器(db),或者同时停止这两个容器

docker stop db MyWordPress

安装 Docker compose:(在https://github.com/docker/compose/releases/download这里可以找到随时更新的命令)

curl -L https://github.com/docker/compose/releases/download/1.18.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

使用1:

  1. 首先关掉WordPress的两个容器

docker stop db MyWordPress

  1. 创建一个文件夹 ~/wordpress,文件夹下创建docker-compose.yml的文件:
    wordpress:
    image: wordpress
    links:
    - db:mysql
    ports:
    - 8080:80
    db:
    image: mariadb
    environment:
    MYSQL_ROOT_PASSWORD: example
    作用:创建了两个容器wordpress跟db,使用image指定了使用的镜像

  2. 创建启动WordPress服务

cd ~/wordpress &&docker-compose up

  1. 检测
    开另一个命令终端, 输入docker ps查看容器

这是启动停止就变的简单了,

启动:

docker-compose start

停止:

docker-compose stop

  1. 删除原来的容器

查看所有容器(删除与未删除的)

docker ps -a

删除(根据名字(NAMES)来删除)

docker rm MyWordPress db

硬删的话就用 docker rm -f

使用2:gitlab改造
原来的用法

首先启动postgresql

sudo docker run --name gitlab-postgresql -d --env 'DB_NAME=gitlabhq_production' --env 'DB_USER=gitlab' --env 'DB_PASS=password' sameersbn/postgresql:9.4-12


然后启动redis

sudo docker run  --name gitlab-redis -d sameersbn/redis:latest 

最后启动gitlab

sudo docker run --name gitlab -d --link gitlab-postgresql:postgresql --link gitlab-redis:redisio --publish 10022:22 --publish 10080:80 --env  'GITLAB_PORT=10080' --env 'GITLAB_SSH_PORT=10022' --env 'GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alpha-numeric-string' sameersbn/gitlab:8.4.4

改造结果

postgresql:
  image: sameersbn/postgresql:9.4-12
  environment:
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production

redis:
  image: sameersbn/redis:latest

gitlab:
  image: sameersbn/gitlab:8.4.4
  links:
    - redis:redisio
    - postgresql:postgresql
  ports:
    - "18008:80"
    - "18009:22"
  environment:
    - GITLAB_PORT=18008
    - GITLAB_SSH_PORT=18009
    - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphaumeric-srting

创建一个项目~/gitlab,然后将上面放在docker-compose.yaml并放在该项目下

删除旧容器:

docker rm -f gitlab gitlab-redis gitlab-postgresql

启动新容器组

cd ~/gitlab/ && docker-compose up -d

登录
http://23.99.104.249:18008/
root/yu123456

Docker镜像管理

docker镜像查看

docker images -a

查看镜像分了多少层

docker history sameersbn/redis

方式:通过对容器的可写层修改来生成新镜像

问题:如果底层镜像出了问题,或者达到两个文件系统允许的最多层数(aufs最多支持128层)

解决方式: dockerfile

Docker 仓库管理

作用:镜像的存储,是镜像分发部署的关键

两种: 官方共有仓库 Docker hub,自己搭建私有仓库

docker push ubuntu

搜索镜像:

docker search centos

下载镜像:

docker pull centos

使用docker-registry构建

方式1:

从Docker-registry拉取镜像

docker run -p 5000:5000 registry

Docker 网络和存储管理

Docker在启动是默认自动创建网桥设备Docker0,同一个host的容器与容器之间可以通过docker0 通信

容器与外部网络之间通信使用NAT

  1. docker可以在容器内部创建一个数据卷,但是在删除之后,如果没有其他容器引用该数据卷,对应的Host目录就会被删除。
  2. 不想被删除的话,可以挂载Host的目录到数据卷,作为容器的数据卷(将Host上的/data/volume1挂载容器中的 /volume1可以在Host与容器之间进行数据交换,这时容器中的数据可以写到volume1上,即使容器被删除,数据仍然保留到Host上)
  3. 挂载Host的文件作为数据卷
    主要应用于Host与容器之间共享配置文件,否则每个配置文件一个镜像会造成镜像版本过多,管理不便

数据卷容器

备份、恢复和迁移数据卷

Docker 小点

容器:

按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

运行镜像
   $ docker run -it --rm \
    ubuntu:16.04 \
    bash

docker image ls

docker system df

docker image rm imageid
docker image rm $(docker image ls -q redis) //删除大法

$ docker run --name webserver -d -p 80:80 nginx

Dockerfile

书写Dockerfile
touch Dockerfile
vi Dockerfile
//键入
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

Dockerfile 中每一个指令都会建立一层,RUN 也不例外。每一个 RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后,commit 这一层的修改,构成新的镜像。
一个比较屌的镜像 (其实run指令里面的命令就是shell命令)

FROM debian:jessie

RUN buildDeps='gcc libc6-dev make' \
    && apt-get update \
    && apt-get install -y $buildDeps \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
    && mkdir -p /usr/src/redis \
    && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
    && make -C /usr/src/redis \
    && make -C /usr/src/redis install \
    && rm -rf /var/lib/apt/lists/* \
    && rm redis.tar.gz \
    && rm -r /usr/src/redis \
    && apt-get purge -y --auto-remove $buildDeps

所有的命令只有一个目的,就是编译、安装 redis 可执行文件。因此没有必要建立很多层,这只是一层的事情。因此,这里没有使用很多个 RUN 对应不同的命令,而是仅仅使用一个 RUN 指令,并使用 && 将各个所需命令串联起来。

一组命令的最后添加了清理工作的命令,删除了为了编译构建所需要的软件,清理了所有下载、展开的文件,并且还清理了 apt 缓存文件。这是很重要的一步

Dockerfile 支持 Shell 类的行尾添加 \ 的命令换行方式,以及行首 # 进行注释的格式

运行Dockerfile

$ docker build -t nginx:v3 . //假设该该目录下含有Dockerfile 注意后面有个点,后面会解释

指定了最终镜像的名称 -t nginx:v3


生成的镜像

查看镜像运行历史

docker history nginx:v3

通过镜像运行容器
docker run --name web2 -d -p 81:80 nginx:v2

此时通过127.0.0.1:81访问即可访问到docker服务

点的解释(镜像构建上下文(Context))

> COPY ./package.json /app/

这并不是要复制执行 docker build 命令所在的目录下的 package.json,也不是复制 Dockerfile 所在目录下的 package.json,而是复制 上下文(context) 目录下的 package.json。

Dockerfile命令

COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]

COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。比如:

COPY package.json /usr/src/app/

<源路径> 可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的 filepath.Match 规则,如:

COPY hom* /mydir/
COPY hom?.txt /mydir/

<目标路径> 可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。

<ENTRYPOINT> "<CMD>"

示例

FROM ubuntu:16.04
RUN apt-get update \
    && apt-get install -y curl \
    && rm -rf /var/lib/apt/lists/*
CMD [ "curl", "-s", "http://ip.cn" ]
$ docker run myip
当前 IP:61.148.226.66 来自:北京市 联通

嗯,这么看起来好像可以直接把镜像当做命令使用了,不过命令总有参数,如果我们希望加参数呢?比如从上面的 CMD 中可以看到实质的命令是 curl,那么如果我们希望显示 HTTP 头信息,就需要加上 -i 参数。那么我们可以直接加 -i 参数给 docker run myip 么?

$ docker run myip -i
docker: Error response from daemon: invalid header field value "oci runtime error: container_linux.go:247: starting container process caused \"exec: \\\"-i\\\": executable file not found in $PATH\"\n".

显然出了问题,但是entrypoint就不会有这样的问题

RUN apt-get update \
    && apt-get install -y curl \
    && rm -rf /var/lib/apt/lists/*
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]

这次我们再来尝试直接使用

docker run myip -i:

$ docker run myip
当前 IP:61.148.226.66 来自:北京市 联通

$ docker run myip -i
HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Tue, 22 Nov 2016 05:12:40 GMT
Content-Type: text/html; charset=UTF-8
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.24-1~dotdeb+7.1
X-Cache: MISS from cache-2
X-Cache-Lookup: MISS from cache-2:80
X-Cache: MISS from proxy-2_6
Transfer-Encoding: chunked
Via: 1.1 cache-2:80, 1.1 proxy-2_6:8006
Connection: keep-alive

当前 IP:61.148.226.66 来自:北京市 联通

没有问题,最后的-i被entrypoint当做参数加进去了。

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

这个指令很简单,就是设置环境变量而已,无论是后面的其它指令,如 RUN,还是运行时的应用,都可以直接使用这里定义的环境变量。对含有空格的值用双引号括起来的办法

ENV VERSION=1.0 DEBUG=on \
    NAME="Happy Feet"

构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是,ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用 ARG 保存密码之类的信息,因为 docker history 还是可以看到所有值的。

Dockerfile 中的 ARG 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 docker build 中用 --build-arg <参数名>=<值> 来覆盖。

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

之前我们说过,容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,后面的章节我们会进一步介绍 Docker 卷的概念。为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
VOLUME /data
这里的 /data 目录就会在运行时自动挂载为匿名卷,任何向 /data 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置。比如:

docker run -d -v mydata:/data xxxx
在这行命令中,就使用了 mydata 这个命名卷挂载到了 /data 这个位置,替代了 Dockerfile 中定义的匿名卷的挂载配置。

RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN [ "redis-server" ]
FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s \
  CMD curl -fs http://localhost/ || exit 1

这里我们设置了每 5 秒检查一次(这里为了试验所以间隔非常短,实际应该相对较长),如果健康检查命令超过 3 秒没响应就视为失败,并且使用

curl -fs http://localhost/ || exit 1

作为健康检查命令。

上一篇下一篇

猜你喜欢

热点阅读