docker详解
2017-08-17 14:33
204 查看
搜索镜像
docker search java运行
docker run -it --rm ubuntu:14.04 bash root@e7009c6ce357:/# cat /etc/os-release NAME="Ubuntu" VERSION="14.04.5 LTS, Trusty Tahr" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 14.04.5 LTS" VERSION_ID="14.04" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" root@e7009c6ce357:/# exit exit
-it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
–rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 –rm 可以避免浪费空间。
ubuntu:14.04:这是指用 ubuntu:14.04 镜像为基础来启动容器。
bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。
列出镜像
docker images中间层
docker images -adocker images ubuntu
docker images ubuntu:16.04
docker images -f since=mongo:3.2
docker images -f label=com.example.version=0.1
docker images -q
docker images –format “{{.ID}}: {{.Repository}}”
docker images –format “table {{.ID}}\t{{.Repository}}\t{{.Tag}}”
attach 进入容器
docker attach container-test //推荐 docker exec -it web1 /bin/sh
Dockerfile
$ mkdir mynginx $ cd mynginx $ touch Dockerfile
其内容为:
FROM nginx RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
构建镜像
docker build -t nginx:v1 . //运行 curl localhost:80 docker run --name web1 -d -p 80:80 nginx:v1 //8080端口访问 curl localhost:8080 docker run --name web2 -d -p 8080:80 nginx:v1
RUN 多命令
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
其他构建
docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14压缩包构建
docker build http://server/context.tar.gzCOPY
COPY package.json /usr/src/app/<源路径> 可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的 filepath.Match 规则,如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
ADD
不如直接使用 RUN 指令,然后使用 wget 或者 curl 工具下载,处理权限、解压缩、然后清理无用文件更合理。因此,这个功能其实并不实用,而且不推荐使用
CMD 容器启动命令
在运行时可以指定新的命令来替代镜像设置中的这个默认命令,比如,ubuntu 镜像默认的 CMD 是 /bin/bash,如果我们直接 docker run -it ubuntu 的话,会直接进入 bash。
我们也可以在运行时指定运行别的命令,如 docker run -it ubuntu cat /etc/os-release。
这就是用 cat /etc/os-release 命令替换了默认的 /bin/bash 命令了,输出了系统版本信息
正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行。比如:
CMD [“nginx”, “-g”, “daemon off;”]
ENTRYPOINT
FROM ubuntu:16.04 RUN apt-get update \ && apt-get install -y curl \ && rm -rf /var/lib/apt/lists/* ENTRYPOINT [ "curl", "-s", "http://ip.cn" ] //-i传递给curl docker run myip -i
场景2
这些准备工作是和容器 CMD 无关的,无论 CMD是什么,都需要事先进行一个预处理的工作。这种情况下,
可以写一个脚本,然后放入 ENTRYPOINT 中去执行,而这个脚本会将接到的参数(也就是 )作为命令,
在脚本最后执行。比如官方镜像 redis 中就是这么做的:
FROM alpine:3.4
…
RUN addgroup -S redis && adduser -S -G redis redis
…
ENTRYPOINT [“docker-entrypoint.sh”]
EXPOSE 6379
CMD [ “redis-server” ]
可以看到其中为了 redis 服务创建了 redis 用户,并在最后指定了 ENTRYPOINT 为 docker-entrypoint.sh 脚本。
#!/bin/sh ... # allow the container to be started with `--user` if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then chown -R redis . exec su-exec redis "$0" "$@" fi exec "$@"
该脚本的内容就是根据 CMD 的内容来判断,
如果是 redis-server 的话,则切换到 redis 用户身份启动服务器,
否则依旧使用 root 身份执行。比如:
$ docker run -it redis id
uid=0(root) gid=0(root) groups=0(root)
ENV
ENV NODE_VERSION 7.2.0 RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ && grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \ && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \ && rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \ && ln -s /usr/local/bin/node /usr/local/bin/nodejs
下列指令可以支持环境变量展开:
ADD、COPY、ENV、EXPOSE、LABEL、USER、WORKDIR、VOLUME、STOPSIGNAL、ONBUILD。
VOLUME
VOLUME /datadocker run -d -v mydata:/data xxxx
EXPOSE 声明端口
WORKDIR 指定工作目录
USER 指定当前用户
HEALTHCHECK 健康检查
–interval=<间隔>:两次健康检查的间隔,默认为 30 秒;–timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
–retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。
案例
假设我们有个镜像是个最简单的 Web 服务,我们希望增加健康检查来判断其 Web 服务是否在正常工作,我们可以用 curl 来帮助判断,其 Dockerfile 的 HEALTHCHECK 可以这么写:
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 作为健康检查命令。
使用 docker build 来构建这个镜像:
docker build -t myweb:v1 .
构建好了后,我们启动一个容器:
docker run -d --name web -p 80:80 myweb:v1
当运行该镜像后,可以通过 docker ps 看到最初的状态为 (health: starting):
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 03e28eb00bd0 myweb:v1 "nginx -g 'daemon off" 3 seconds ago Up 2 seconds (health: starting) 80/tcp, 443/tcp web
在等待几秒钟后,再次 docker ps,就会看到健康状态变化为了 (healthy)。
如果健康检查连续失败超过了重试次数,状态就会变为 (unhealthy)。
为了帮助排障,健康检查命令的输出(包括 stdout 以及 stderr)都会被存储于健康状态里,可以用 docker inspect 来查看。
$ docker inspect --format '{{json .State.Health}}' web | python -m json.tool { "FailingStreak": 0, "Log": [ { "End": "2016-11-25T14:35:37.940957051Z", "ExitCode": 0, "Output": "<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\n body {\n width: 35em;\n margin: 0 auto;\n font-family: Tahoma, Verdana, Arial, sans-serif;\n }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.</p>\n\n<p>For online documentation and support please refer to\n<a href=\"http://nginx.org/\">nginx.org</a>.<br/>\nCommercial support is available at\n<a href=\"http://nginx.com/\">nginx.com</a>.</p>\n\n<p><em>Thank you for using nginx.</em></p>\n</body>\n</html>\n", "Start": "2016-11-25T14:35:37.780192565Z" } ], "Status": "healthy" }
ONBUILD
mynodeFROM node:slim RUN mkdir /app WORKDIR /app CMD [ "npm", "start" ]
other
FROM my-node COPY ./package.json /app RUN [ "npm", "install" ] COPY . /app/
转变为
FROM node:slim RUN mkdir /app WORKDIR /app ONBUILD COPY ./package.json /app ONBUILD RUN [ "npm", "install" ] ONBUILD COPY . /app/ CMD [ "npm", "start" ]
rmi删除本地镜像
docker rmi [选项] <镜像1> [<镜像2> ...] docker images docker rmi 501 docker rmi centos docker rmi $(docker images -q -f dangling=true) docker rmi $(docker images -q redis) docker rmi $(docker images -q -f before=mongo:3.2)
启动
sudo docker run ubuntu:14.04 /bin/echo 'Hello world' sudo docker run -t -i ubuntu:14.04 /bin/bash docker ps -a docker start web1
后台启动
前台打印sudo docker run ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
后台启动
sudo docker run ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
docker stop web1
docker restart web1
导出容器
sudo docker export 7691a814370e > ubuntu.tar导入容器
cat ubuntu.tar | sudo docker import - test/ubuntu:v1.0$ sudo docker images
sudo docker import http://example.com/exampleimage.tgz example/imagerepo
*注:用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,
也可以使用 docker import 来导入一个容器快照到本地镜像库。
这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),
而镜像存储文件将保存完整记录,体积也要大。
此外,从容器快照文件导入时可以重新指定标签等元数据信息。
删除所有容器
docker rm $(docker ps -a -q)
私有库registry 镜像来运行。
$ sudo docker run -d -p 5000:5000 registry
指定路径
sudo docker run -d -p 5000:5000 -v /home/root/registry-conf:/registry-conf -e DOCKER_REGISTRY_CONFIG=/registry-conf/config.yml registry docker push 172.16.1.17:5000/registry
数据卷
sudo docker run -d -P --name web -v /webapp training/webapp python app.py sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
数据库数据卷
sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres 然后,在其他容器中使用 --volumes-from 来挂载 dbdata 容器中的数据卷。 sudo docker run -d --volumes-from dbdata --name db1 training/postgres sudo docker run -d --volumes-from dbdata --name db2 training/postgres sudo docker run -d --name db3 --volumes-from db1 training/postgres
备份
sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
恢复
如果要恢复数据到一个容器,首先创建一个带有空数据卷的容器 dbdata2。$ sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
然后创建另一个容器,挂载 dbdata2 容器卷中的数据卷,并使用 untar 解压备份文件到挂载的容器卷中。
$ sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
为了查看/验证恢复的数据,可以再启动一个容器挂载同样的容器卷来查看
$ sudo docker run --volumes-from dbdata2 busybox /bin/ls /dbdata
安装compose
curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose docker-compose --version
compose补全工具
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/dockercompose > /etc/bash_completion.d/docker-compose
目录
├── docker-compose.yml └──eureka ├── Dockerfile └── microservice-discovery-eureka-0.0.1-SNAPSHOT.jar
docker-compose.yml
eureka: build: ./eureka ports: - "8761:8761" expose: - 8761
在 docker-compose.yml 所在路径执⾏:
docker-compose up
tomcat
docker run --name web2 -p 8000:8080 -d -v /root/tomcat/web1/logs:/usr/local/tomcat/logs tomcat:7
web
compose-haproxy-web ├── docker-compose.yml ├── haproxy │ └── haproxy.cfg └──web ├── Dockerfile ├── index.html └── index.py ## Dockerfile FROM python:2.7 WORKDIR /code ADD . /code EXPOSE 80 CMD python index.py
haproxy.cfg
global log 127.0.0.1 local0 log 127.0.0.1 local1 notice defaults log global mode http option httplog option dontlognull timeout connect 5000ms timeout client 50000ms timeout server 50000ms listen stats bind 0.0.0.0:70 stats enable stats uri / frontend balancer bind 0.0.0.0:80 mode http default_backend web_backends backend web_backends mode http option forwardfor balance roundrobin server weba weba:80 check server webb webb:80 check server webc webc:80 check option httpchk GET / http-check expect status 200
docker-compose.yml
weba: build: ./web expose: - 80 webb: build: ./web expose: - 80 webc: build: ./web expose: - 80 haproxy: image: haproxy:latest volumes: - ./haproxy:/haproxy-override - ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.c fg:ro links: - weba - webb - webc ports: - "80:80" - "70:70" expose: - "80" - "70"
sudo docker-compose up
zk
docker run --name some-zookeeper --restart always -d zookeeper docker run --name some-app --link some-zookeeper:zookeeper -d application-that-uses-zookeeper docker run -it --rm --link some-zookeeper:zookeeper zookeeper zkCli.sh -server zookeeper
集群 docker-compose.xml
version: ‘2’services:
zoo1:
image: zookeeper
restart: always
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
zoo2: image: zookeeper restart: always ports: - 2182:2181 environment: ZOO_MY_ID: 2 ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888 zoo3: image: zookeeper restart: always ports: - 2183:2181 environment: ZOO_MY_ID: 3 ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
nginx集群
docker-compose.yml version: '2' services: App1: image: nginx ports: - "8080:80" networks: - "netName1" volumes: - /opt/conf/:/mnt App2: image: nginx ports: - "8081:80" networks: - "netName1" volumes: - /opt/conf/:/mnt App3: image: nginx ports: - "8082:80" networks: - "netName2" networks: netName1: driver: bridge netName2: driver: bridge
docker-compose restart #重启所有容器
[root@docker compose]# docker-compose restart App1 #重启App1
[root@docker compose]# docker-compose stop #停止所有容器
[root@docker compose]# docker-compose stop App1 #停止App1
[root@docker compose]# docker-compose exec App1 bash
root@dd01fa7315ae:/# ping App2
django
FROM python:2.7 ENV PYTHONUNBUFFERED 1 RUN mkdir /code WORKDIR /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/ requirements.txt 文件里面写明需要安装的具体依赖包名 。 Django psycopg2 db: image: postgres web: build: . command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/code ports: - "8000:8000" links: - db docker-compose run web django-admin.py startproject django_example .
rail
FROM ruby RUN apt-get update -qq && apt-get install -y build-essential lib pq-dev RUN mkdir /myapp WORKDIR /myapp ADD Gemfile /myapp/Gemfile RUN bundle install ADD . /myapp db: image: postgres ports: - "5432" web: build: . command: bundle exec rackup -p 3000 volumes: - .:/myapp ports: - "3000:3000" links: - db docker-compose run web rails new . --force --database=postgresql --skip-bundle
wordpress
wordpress.org/latest.tar.gz | tar -xvzf -Machine
sudo curl -L https://github.com/docker/machine/releases/download/v0.3.1-rc1/docker-machine_linux-amd64 > /usr/local/bin/docker-machine chmod +x /usr/local/bin/docker-machine curl -L https://github.com/docker/machine/releases/download/v0.12.1/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine && chmod +x /tmp/docker-machine && sudo cp /tmp/docker-machine /usr/local/bin/docker-machine docker-machine create -d generic --generic-ip-address=192.168.236.129 --generic-ssh-user=user test
swarm
docker pull swarm docker run --rm swarm -v sudo docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock sudo dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise 192.168.236.128:4000 consul://192.168.236.128:8500 docker run -d swarm join --advertise=192.168.236.128:2375 consul://192.168.236.128:8500 docker run --rm swarm create 946d65606f7c2f49766e4dddac5b4365 docker run --rm swarm join --addr=192.168.0.2:2375 token://946d65606f7c2f49766e4dddac5b4365 \ time="2015-12-09T08:59:43Z" level=info msg="Registering on the discovery service every 20s..." addr="192.168.0.2:2375" \ discovery="token://946d65606f7c2f49766e4dddac5b4365"
etcd
curl -L https://github.com/coreos/etcd/releases/download/v2.3.4/etcd-v2.3.4-linux-amd64.tar.gz -o etcd-v2.3.4-linux-amd64.tar.gz tar xzvf etcd-v2.3.4-linux-amd64.tar.gz cd etcd-v2.3.4-linux-amd64 ./etcd docker run --net=host -d quay.io/coreos/etcd:v3.2.1 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data docker run --name kubernetes --net=host -d -v /var/run/docker.sock:/var/run/docker.sock \ gcr.io/google_containers/hyperkube:v0.17.0 /hyperkube kubelet \ --api_servers=http://localhost:8080 --v=2 --address=0.0.0.0 \ --enable_server --hostname_override=127.0.0.1 --config=/etc/kubernetes/manifests docker run --name hyperkube -d --net=host --privileged gcr.io/google_containers/hyperkube:v0.17.0 /hyperkube proxy --master=http://127.0.0.1:8080 --v=2
相关文章推荐
- Docker的安装配置及使用详解
- Docker命令使用详解
- Dockerfile 指令详解
- Docker命令详解
- Docker的安装配置及使用详解
- 详解Docker与FastDFS的安装命令及使用
- Docker Dockerfile详解
- Docker新手实践及部署NGINX的步骤详解
- 详解Docker中安装配置Oracle数据库
- 详解Docker容器可视化监控中心搭建
- docker-1.12 run命令运行以及参数详解
- docker run命令详解-yellowcong
- Docker命令查询详解
- Docker的学习--命令使用详解
- docker命令详解(一)
- docker数据驱动详解
- docker命令详解之(run中--link)
- docker镜像存储详解
- 【docker】docker run命令详解