[关闭]
@kklinan 2017-02-15T16:20:43.000000Z 字数 27936 阅读 1743

Docker笔记

Docker


快速了解Docker

安装方式

安装 Docker-compose

官方地址

  1. curl -L https://github.com/docker/compose/releases/download/1.9.0-rc1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
  2. chmod +x /usr/local/bin/docker-compose

体验Docker-compose

1、在目标文件夹下建立docker-compose.yaml
内容:

  1. version: '2'
  2. services:
  3. db:
  4. image: mysql:5.7
  5. volumes:
  6. - "./.data/db:/var/lib/mysql"
  7. restart: always
  8. environment:
  9. MYSQL_ROOT_PASSWORD: wordpress
  10. MYSQL_DATABASE: wordpress
  11. MYSQL_USER: wordpress
  12. MYSQL_PASSWORD: wordpress
  13. wordpress:
  14. depends_on:
  15. - db
  16. image: wordpress:latest
  17. links:
  18. - db
  19. ports:
  20. - "8000:80"
  21. restart: always
  22. environment:
  23. WORDPRESS_DB_HOST: db:3306
  24. WORDPRESS_DB_PASSWORD: wordpress

2、同目录下运行docker-compose up -d
查看 docker-compose ps
访问:http://localhost:8000/

常用命令

多数命令

参考:

  1. docker create -it ubuntu:latest #创建容器,且处于停止状态
  2. docker start #启动容器
  3. docker run #创建并启动容器
  4. docker run IMAGE env #查看镜像支持的环境变量
  5. docker stop #停止运行中容器
  6. docker stop $(docker ps -qa) #停止所有运行中的容器
  7. docker kill $(docker ps -q) #停止所有运行中的容器
  8. docker kill $(docker ps -a -q) #杀死所有正在运行的容器
  9. docker restart #重启容器
  10. docker images #显示本地已有镜像
  11. docker info #显示docker系统信息
  12. docker commit -m -a #提交更新后的镜像
  13. docker build #通过Dockerfile来构建镜像
  14. docker save -o mysql_5.6.tar mysql:5.6 #导出镜像到本地
  15. docker load < mysql_5.6.tar #载入镜像存储文件 镜像存储文件将保存完整记录,体积较大
  16. docker export <CONTAINER> > test.tar #导出容器
  17. docker import #导入容器快照 如: cat test.tar | docker import - test/ubuntu:v1.0 容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的转态)但导入时可以重新指定标签等元数据信息
  18. docker search #查找仓库中镜像
  19. docker push #将镜像推送到仓库
  20. docker pull #将仓库中镜像下载到本地 如:docker pull dl.dockerpoll.com:5000/ubuntu:latest
  21. docker rmi #移除镜像
  22. docker attach #运行中容器的stdin,进行命令执行的动作,多个窗口同步显示
  23. docker exec #类attach,但不会同步显示
  24. docker history #显示镜像的历史
  25. docker rename #重命名容器名称
  26. docker tag #设置镜像tag
  27. docker ps #查看正在运行的容器
  28. docker ps -a #查看所有容器
  29. docker ps -l #查看最后创建的容器
  30. docker rm #移除处于终止状态的容器
  31. docker rm $(docker ps -qa) #移除处于终止状态的容器
  32. docker rm -f #强行终止并删除一个运行中的容器
  33. docker rm -v #删除容器挂载的数据卷
  34. docker logs #从容器中去查看日志
  35. docker logs -f <容器名orID> #查看容器日志
  36. docker diff #列出容器中被改变的文件或者目录
  37. docker top #显示运行容器的进程信息
  38. docker cp #从容器中拷贝文件或者目录到本地
  39. docker inspect #查看容器详细信息 docker inspect <imageID> || 查看镜像中的特定信息 docker inspect -f {{".Os"}} <imageID>
  40. docker rmi $(docker images | grep none | awk '{print $3}' | sort -r) #删除所有镜像
  41. docker rm $(docker ps -a -q) #删除所有已经停止的容器
  42. docker rmi $(docker images -q -f dangling=true) #删除所有未打 dangling 标签的镜像
  43. docker rmi $(docker images -q) #删除所有镜像
  44. docker images --no-trunc| grep none | awk '{print $3}' | xargs -r docker rmi #删除为none的镜像,可以立马回收空间
  45. docker rm 'docker ps -a | grep Exited | awk '{print $1 }'' #删除退出了的容器
  46. docker rmi 'docker images -aq' #删除没有用的镜像。 (有容器运行的镜像不会被删除)
  47. docker port #查看映射端口配置

docker run 详解

例如:docker run -it -p 8080:80 --name cui -v /home/cui/Workspaces/docker/localhost/:/var/www/html phpseasa/ubuntu:lnp

  1. -d #容器运行在后台,此时不能使用--rm选项
  2. -i -t #和容器进行交互式操作
  3. --name #命名容器,没有该参数Docker deamon会生产UUID来标识
  4. --cidfile #将容器ID输入到指定文件中
  5. --add-host #添加一行到/etc/hosts
  6. --mac-address #设置MAC地址
  7. --dns #覆盖容器DNS设置
  8. --rm #退出容器时自动清除数据
  9. -m #调整容器的内存使用
  10. -c #调整容器的CPU优先级
  11. -e #设定环境变量
  12. --expose #运行时暴露端口,不创建和宿主机的映射
  13. -p #创建映射规则,将一个或者一组端口从容器里绑定到宿主机上,可多次使用
  14. -P #将Dockfile中暴露的端口映射动态映射到宿主机
  15. --link #容器互联 --link name:alias
  16. -v #创建数据卷挂载到容器,一次run中可多次使用

镜像

创建镜像

1、基于已有镜像

主要使用 docker commit

2、基于本地模板导入

在线操作系统模板:https://download.openvz.org/template/precreated/

$ cat centos-6-x86_64.tar.gz | docker import - centos:6-x86_64

搭建Docker Registry

$ docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry

访问: http://localhost:5000/v2/_catalog

创建本地TAG

docker tag centos:6-x86_64 localhost:5000/centos
docker push localhost:5000/centos
curl http://localhost:5000/v2/_catalog

下载本地仓库镜像

docker pull localhost:5000/centos
docker tag localhost:5000/centos centos:localhost #增加通用TAG

push到本地仓库报错解决方法:
/etc/default/docker加入如下代码:
DOCKER_OPTS="$DOCKER_OPTS --insecure-registry=192.168.2.102:5000"
然后重启docker:service docker restart
官方推荐使用Secure Registry

使用私有仓库

当积累了大量的自定义镜像文件后,发现通过公有仓库进行管理并不是十分方便;另只是希望内部进行共享,这时需要内部搭建私有仓库服务器。

在生产环境中,推荐使用负载均衡来提高仓库服务的性能;还可以利用HAProxy等方式对仓库服务进行容错。同时,为了安全考虑,可以为仓库访问启用HTTPS等加密协议来确保通信的安全。

使用docker-registry

这是一个基于Python的开源项目,可以通过容器运行和源代码安装两种方式来使用。

基于容器运行

docker run -d -p 5000:5000 registry
启动后关键参数是:指定配置文件和仓库存储路径。

指定本地路径(如: /home/userName/registry-conf)下的配置文件:
docker run -d -p 5000:5000 -v /home/userName/registry-conf:/registry-conf -e DOCKER_REGISTRY_CONFIG=/registry-conf/config.yml registry

通过-v配置仓库路径:
docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry

本地安装运行

Ubuntu:
sudo apt-get install -y build-essential python-dev libevent-dev python-pip liblzma-dev
sudo pip install gunicorn pyyaml flask flask-cors rsa
sudo pip install docker-registry

Centos:
sudo yum install -y python-devel libevent-devel python-pip gcc xz-devel
sudo pip install gunicorn pyyaml flask flask-cors rsa gevent
sudo python-pip install docker-registry

下载地址:https://github.com/docker/docker-registry
sudo apt-get install build-essential python-dev libevent-dev python-pip liblzma-dev libssl-dev libffi-dev
git clone https://github.com/docker/docker-registry.git
cd docker-registry
cp config/config_sample.yml config/config.yml
vim config/config.yml

修改local模板段的storage_path到本地的存储仓库的路径,如:/opt/data/registry
内容如下:
local: &local
<<: *common
storage: local
storage_path: _env:STORAGE_PATH:/opt/data/registry

#执行安装脚本
sudo python setup.py install
如果报错如下:

  1. Running M2Crypto-0.22.3/setup.py -q bdist_egg --dist-dir /tmp/easy_install-M8sTej/M2Crypto-0.22.3/egg-dist-tmp-AbQSLA
  2. unable to execute 'swig': No such file or directory
  3. error: Setup script exited with error: command 'swig' failed with exit XXXXX

安装swig:sudo apt-get install swig

通过软件包安装方式配置文件一般需要放在/usr/local/lib/python2.7/dist-packages/docker_registry/config/config.yml

启动命令:
sudo gunicorn --access-logfile /var/log/docker-registry/access.log --error-logfile /var/log/docker-registry/server.log -k gevent --max-requests 100 --graceful-timeout 3600 -t 3600 -b 127.0.0.1:5000 -w 1 docker_registry.wsgi:application

检测:
sudo curl 127.0.0.1:5000

配置服务脚本

创建/etc/init/docker-registry.conf
内容:

  1. description "Docker Registry"
  2. start on runlevel [2345]
  3. stop on runlevel [016]
  4. respawn
  5. respawn limit 10 5
  6. script
  7. exec gunicorn --access-logfile /var/log/docker-registry/access.log --error-logfile /var/log/docker-registry/server.log -k gevent --max-requests 100 --graceful-timeout 3600 -t 3600 -b localhost:5001 -w 8 docker_registry.wsgi:application
  8. end script

启动:
sudo service docker-registry start
访问:http://127.0.0.1:5001/

用户认证

配置Nginx代理

参考:搭建docker内网私服(docker-registry with nginx&ssl on centos)

docker-registry.conf

  1. upstream docker-registry {
  2. server localhost:5000;
  3. }
  4. server {
  5. listen 80;
  6. server_name local.registry.com; # your registry server_name
  7. # ssl on;
  8. # ssl_certificate /etc/ssl/certs/docker-registry;
  9. # ssl_certificate_key /etc/ssl/private/docker-registry;
  10. proxy_set_header Host $http_host; # required for Docker client sake
  11. proxy_set_header X-Real-IP $remote_addr; # pass on real client IP
  12. client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads
  13. # required to avoid HTTP 411: see Issue #1486 (https://github.com/dotcloud/docker/issues/1486)
  14. chunked_transfer_encoding on;
  15. location / {
  16. # let Nginx know about our auth file
  17. #auth_basic "Please Input username/password";
  18. #auth_basic_user_file docker-registry.htpasswd;
  19. proxy_pass http://docker-registry;
  20. }
  21. location /_ping {
  22. auth_basic off;
  23. proxy_pass http://docker-registry;
  24. }
  25. location /v1/_ping {
  26. auth_basic off;
  27. proxy_pass http://docker-registry;
  28. }
  29. }

#重启Nginx
sudo service nginx reload
vim /etc/hosts

127.0.0.1 local.registry.com

#上传镜像测试服务
docker tag sshd:dockerfile localhost:5000/sshd:dockerfile
docker push localhost:5000/sshd:dockerfile

关闭VPN访问:http://local.registry.com/v1/_ping
http://local.registry.com/v1/search

添加用户认证

将上面的Nginx配置文件中的

  1. #auth_basic "Please Input username/password";
  2. #auth_basic_user_file /usr/local/nginx/conf/passwd/docker-registry.htpasswd;

注释打开,
sudo mkdir -p /usr/local/nginx/conf/passwd/
sduo vim /usr/local/nginx/conf/passwd/docker-registry.htpasswd

admin:2sld49pC3.Bbk

使用crypt函数生成密码或安装htpasswd工具
在线生成工具:http://tool.oschina.net/htpasswd

访问:
- 浏览器访问http://local.registry.com/v1/search
账号:admin
密码:admin
- curl访问
curl USERNAME:PASSWORD@local.registry.com/v1/search

使用私有仓库批量上传镜像

批量上传指定镜像

vim push_images.sh
脚本内容:

  1. #!/bin/sh
  2. # This script will upload the given local images to a registry server ($registry is the default value).
  3. # See: https://github.com/yeasy/docker_practice/blob/master/_local/push_images.sh
  4. # Usage: push_images image1 [image2...]
  5. # Author: yeasy@github
  6. # Create: 2014-09-23
  7. #The registry server address where you want push the images into
  8. registry=127.0.0.1:5000
  9. ### DO NOT MODIFY THE FOLLOWING PART, UNLESS YOU KNOW WHAT IT MEANS ###
  10. echo_r () {
  11. [ $# -ne 1 ] && return 0
  12. echo -e "\033[31m$1\033[0m"
  13. }
  14. echo_g () {
  15. [ $# -ne 1 ] && return 0
  16. echo -e "\033[32m$1\033[0m"
  17. }
  18. echo_y () {
  19. [ $# -ne 1 ] && return 0
  20. echo -e "\033[33m$1\033[0m"
  21. }
  22. echo_b () {
  23. [ $# -ne 1 ] && return 0
  24. echo -e "\033[34m$1\033[0m"
  25. }
  26. usage() {
  27. sudo docker images
  28. echo "Usage: $0 registry1:tag1 [registry2:tag2...]"
  29. }
  30. [ $# -lt 1 ] && usage && exit
  31. echo_b "The registry server is $registry"
  32. for image in "$@"
  33. do
  34. echo_b "Uploading $image..."
  35. sudo docker tag $image $registry/$image
  36. sudo docker push $registry/$image
  37. sudo docker rmi $registry/$image
  38. echo_g "Done"
  39. done

建议将本脚本放在/usr/local/bin下,
给全部人员加上可执行权限:
sudo chmod a+x /usr/local/bin/push_imagegs.sh
./push_images.sh ubuntu:latest centos:centos7

上传本地所有镜像

vim push_all.sh
内容:

  1. #!/bin/sh
  2. # This script will upload all local images to a registry server ($registry is the default value).
  3. # This script requires the push_images, which can be found at https://github.com/yeasy/docker_practice/blob/master/_local/push_images.sh
  4. # Usage: push_all
  5. # Author: yeasy@github
  6. # Create: 2014-09-23
  7. for image in `sudo docker images|grep -v "REPOSITORY"|grep -v "<none>"|awk '{print $1":"$2}'`
  8. do
  9. push_images $image
  10. done

仓库配置文件

Registry利用配置文件提供了一些仓库的模板(flavor),可以直接使用进行开发或生产部署。

示例配置

  1. #All other flavors inherit the `common' config snippet
  2. common: &common
  3. issue: '"docker-registry server"'
  4. # 默认记录info和以上级别的日志
  5. loglevel: _env:LOGLEVEL:info
  6. # 是否启用debug模式
  7. debug: _env:DEBUG:false
  8. # 默认是standalone模式,不查询index服务
  9. standalone: _env:STANDALONE:true
  10. # 非standalone模式下的index服务默认是index.docker.io
  11. index_endpoint: _env:INDEX_ENDPOINT:https://index.docker.io
  12. # 默认不启用存储转向
  13. storage_redirect: _env:STORAGE_REDIRECT
  14. # 非standalone模式下启用基于口令串的认证
  15. disable_token_auth: _env:DISABLE_TOKEN_AUTH
  16. # 默认不使用特权
  17. privileged_key: _env:PRIVILEGED_KEY
  18. # 搜索后端支持
  19. search_backend: _env:SEARCH_BACKEND
  20. # SQLite搜索后端数据库地址
  21. sqlalchemy_index_database: _env:SQLALCHEMY_INDEX_DATABASE:sqlite:////tmp/docker-registry.db
  22. # 默认不启用镜像服务
  23. mirroring:
  24. source: _env:MIRROR_SOURCE # https://registry-1.docker.io
  25. source_index: _env:MIRROR_SOURCE_INDEX # https://index.docker.io
  26. tags_cache_ttl: _env:MIRROR_TAGS_CACHE_TTL:172800 # seconds
  27. cache:
  28. host: _env:CACHE_REDIS_HOST
  29. port: _env:CACHE_REDIS_PORT
  30. db: _env:CACHE_REDIS_DB:0
  31. password: _env:CACHE_REDIS_PASSWORD
  32. # 访问远端存储后端时,配置LRU缓存
  33. cache_lru:
  34. host: _env:CACHE_LRU_REDIS_HOST
  35. port: _env:CACHE_LRU_REDIS_PORT
  36. db: _env:CACHE_LRU_REDIS_DB:0
  37. password: _env:CACHE_LRU_REDIS_PASSWORD
  38. # 发生异常时发送邮件通知
  39. email_exceptions:
  40. smtp_host: _env:SMTP_HOST
  41. smtp_port: _env:SMTP_PORT:25
  42. smtp_login: _env:SMTP_LOGIN
  43. smtp_password: _env:SMTP_PASSWORD
  44. smtp_secure: _env:SMTP_SECURE:false
  45. from_addr: _env:SMTP_FROM_ADDR:docker-registry@localdomain.local
  46. to_addr: _env:SMTP_TO_ADDR:noise+dockerregistry@localdomain.local
  47. # 启用bugsnag
  48. bugsnag: _env:BUGSNAG
  49. # CORS支持,默认未启用
  50. cors:
  51. origins: _env:CORS_ORIGINS
  52. methods: _env:CORS_METHODS
  53. headers: _env:CORS_HEADERS:[Content-Type]
  54. expose_headers: _env:CORS_EXPOSE_HEADERS
  55. supports_credentials: _env:CORS_SUPPORTS_CREDENTIALS
  56. max_age: _env:CORS_MAX_AGE
  57. send_wildcard: _env:CORS_SEND_WILDCARD
  58. always_send: _env:CORS_ALWAYS_SEND
  59. automatic_options: _env:CORS_AUTOMATIC_OPTIONS
  60. vary_header: _env:CORS_VARY_HEADER
  61. resources: _env:CORS_RESOURCES
  62. local: &local
  63. <<: *common
  64. storage: local
  65. storage_path: _env:STORAGE_PATH:/tmp/registry
  66. s3: &s3
  67. <<: *common
  68. storage: s3
  69. s3_region: _env:AWS_REGION
  70. s3_bucket: _env:AWS_BUCKET
  71. boto_bucket: _env:AWS_BUCKET
  72. storage_path: _env:STORAGE_PATH:/registry
  73. s3_encrypt: _env:AWS_ENCRYPT:true
  74. s3_secure: _env:AWS_SECURE:true
  75. s3_access_key: _env:AWS_KEY
  76. s3_secret_key: _env:AWS_SECRET
  77. boto_host: _env:AWS_HOST
  78. boto_port: _env:AWS_PORT
  79. boto_calling_format: _env:AWS_CALLING_FORMAT
  80. # Ceph对象网关配置
  81. ceph-s3: &ceph-s3
  82. <<: *common
  83. storage: s3
  84. s3_region: ~
  85. s3_bucket: _env:AWS_BUCKET
  86. s3_encrypt: _env:AWS_ENCRYPT:false
  87. s3_secure: _env:AWS_SECURE:false
  88. storage_path: _env:STORAGE_PATH:/registry
  89. s3_access_key: _env:AWS_KEY
  90. s3_secret_key: _env:AWS_SECRET
  91. boto_bucket: _env:AWS_BUCKET
  92. boto_host: _env:AWS_HOST
  93. boto_port: _env:AWS_PORT
  94. boto_debug: _env:AWS_DEBUG:0
  95. boto_calling_format: _env:AWS_CALLING_FORMAT
  96. # Google云存储配置
  97. gcs:
  98. <<: *common
  99. storage: gcs
  100. boto_bucket: _env:GCS_BUCKET
  101. storage_path: _env:STORAGE_PATH:/registry
  102. gs_secure: _env:GCS_SECURE:true
  103. gs_access_key: _env:GCS_KEY
  104. gs_secret_key: _env:GCS_SECRET
  105. # 存储服务的OAuth 2.0认证
  106. oauth2: _env:GCS_OAUTH2:false
  107. # 存储镜像文件到Openstack Swift服务
  108. swift: &swift
  109. <<: *common
  110. storage: swift
  111. storage_path: _env:STORAGE_PATH:/registry
  112. # keystone authorization
  113. swift_authurl: _env:OS_AUTH_URL
  114. swift_container: _env:OS_CONTAINER
  115. swift_user: _env:OS_USERNAME
  116. swift_password: _env:OS_PASSWORD
  117. swift_tenant_name: _env:OS_TENANT_NAME
  118. swift_region_name: _env:OS_REGION_NAME
  119. # 存储镜像文件到Open Stack Glance服务
  120. # 参见: https://github.com/docker/openstack-docker
  121. glance: &glance
  122. <<: *common
  123. storage: glance
  124. storage_alternate: _env:GLANCE_STORAGE_ALTERNATE:file
  125. storage_path: _env:STORAGE_PATH:/tmp/registry
  126. openstack:
  127. <<: *glance
  128. # 存储镜像文件到Glance,标签信息到Swift
  129. glance-swift: &glance-swift
  130. <<: *swift
  131. storage: glance
  132. storage_alternate: swift
  133. openstack-swift:
  134. <<: *glance-swift
  135. elliptics:
  136. <<: *common
  137. storage: elliptics
  138. elliptics_nodes: _env:ELLIPTICS_NODES
  139. elliptics_wait_timeout: _env:ELLIPTICS_WAIT_TIMEOUT:60
  140. elliptics_check_timeout: _env:ELLIPTICS_CHECK_TIMEOUT:60
  141. elliptics_io_thread_num: _env:ELLIPTICS_IO_THREAD_NUM:2
  142. elliptics_net_thread_num: _env:ELLIPTICS_NET_THREAD_NUM:2
  143. elliptics_nonblocking_io_thread_num: _env:ELLIPTICS_NONBLOCKING_IO_THREAD_NUM:2
  144. elliptics_groups: _env:ELLIPTICS_GROUPS
  145. elliptics_verbosity: _env:ELLIPTICS_VERBOSITY:4
  146. elliptics_logfile: _env:ELLIPTICS_LOGFILE:/dev/stderr
  147. elliptics_addr_family: _env:ELLIPTICS_ADDR_FAMILY:2
  148. # 默认启用的配置选项
  149. dev: &dev
  150. <<: *local
  151. loglevel: _env:LOGLEVEL:debug
  152. debug: _env:DEBUG:true
  153. search_backend: _env:SEARCH_BACKEND:sqlalchemy
  154. # 用于测试
  155. test:
  156. <<: *dev
  157. index_endpoint: https://registry-stage.hub.docker.com
  158. standalone: true
  159. storage_path: _env:STORAGE_PATH:./tmp/test
  160. # 在环境变量SETTINGS_FLAVOR中指定启用哪个配置,例如$ export SETTINGS_FLAVOR=prod
  161. prod:
  162. <<: *s3
  163. storage_path: _env:STORAGE_PATH:/prod

模板

选项

基本选项如下:

搜索选项如下:

Docker注册服务器可以将仓库的索引信息放到数据库中,供通过GET方法访问/v1/search时使用。

镜像选项都放在mirroring字段下面,例如:

  1. common:
  2. mirroring:
  3. source: https://registry-1.docker.io
  4. source_index: https://index.docker.io
  5. tags_cache_ttl: 172800 # 2 days

默认并未启用。

缓存选项包括cache字段和cache_lru字段,例如:

  1. cache:
  2. host: _env:CACHE_REDIS_HOST
  3. port: _env:CACHE_REDIS_PORT
  4. db: _env:CACHE_REDIS_DB:0
  5. password: _env:CACHE_REDIS_PASSWORD
  6. # Enabling LRU cache for small files
  7. # This speeds up read/write on small files
  8. # when using a remote storage backend (like S3).
  9. ache_lru:
  10. host: _env:CACHE_LRU_REDIS_HOST
  11. port: _env:CACHE_LRU_REDIS_PORT
  12. db: _env:CACHE_LRU_REDIS_DB:0
  13. password: _env:CACHE_LRU_REDIS_PASSWORD

通过配置缓存(事先本地要启动一个LRU模式下的redis服务器),可以将小文件缓存在本地,加速仓库的查询性能。

Email选项为email_exceptions字段,通过配置该选项,当仓库发生异常时可自动发送Email。例如

  1. email_exceptions:
  2. smtp_host: _env:SMTP_HOST
  3. smtp_port: _env:SMTP_PORT:25
  4. smtp_login: _env:SMTP_LOGIN
  5. smtp_password: _env:SMTP_PASSWORD
  6. smtp_secure: _env:SMTP_SECURE:false
  7. from_addr: _env:SMTP_FROM_ADDR:docker-registry@localdomain.local
  8. to_addr: _env:SMTP_TO_ADDR:noise+dockerregistry@localdomain.local

存储选项为storage,该选项将选择事先存储的引擎,仓库默认自带两种类型的引擎:file和s3。用户如果需要其他引擎支持,可以通过下面的命令来进行搜索可用引擎并安装。

  1. $ pip search docker-registry-driver
  2. $ pip install docker-registry-driver-NAME

安装后,可能需要对引擎进行配置。目前支持的引擎包括:

file引擎
file引擎意味着存储到本地文件。当使用file引擎的时候,可以通过storag
e_path来指定存储的具体位置,以local模板为例,默认为/tmp/registry。

  1. local: &local
  2. <<: *common
  3. storage: local
  4. storage_path: _env:STORAGE_PATH:/tmp/registry

因此,我们在运行registry镜像时,可以挂载本地目录到这个位置,来保存仓库中的数据到本地,即

$ docker run -p 5000 -v /tmp/registry:/tmp/registry registry

s3引擎
s3引擎意味着存储到亚马逊的云服务。亚马逊s3引擎支持的选项包括:

  1. prod:
  2. storage: s3
  3. s3_region: us-west-1
  4. s3_bucket: acme-docker
  5. storage_path: /registry
  6. s3_access_key: AKIAHSHB43HS3J92MXZ
  7. s3_secret_key: xdDowwlK7TJajV1Y7EoOZrmuPEJlHYcNP2k4j49T

数据管理

数据卷

类似于Linux对目录或文件进行mount操作

创建一个sites容器,并创建一个数据卷挂载到容器的/data/sites目录:
docker run -it -v /data/sites --name sites ubuntu

docker挂载数据卷的默认权限是读写(rw),通过ro指定为只读,如:
docker run -d -p 8080:80 --name testName -v /data/sites:/data/sites:ro

docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
这样可以记录在容器内输入过的历史命令。

数据卷容器

创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata:
docker run -it -v /dbdata --name dbdata ubuntu

在其他容器中使用--volumes-from来挂载dbdata容器中的数据卷:
docker run -it --volumes-from dbdata --name db1 ubuntu
docker run -it --volumes-from dbdata --name db2 ubuntu

三者之间同步操作结果,共享文件。

如果删除了挂载的容器(包括dbdata、db1、db2),数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载这它的容器是显示使用docker rm -v 命令来指定同时删除关联的容器。

--volumes-from可多次使用;
且使用--volumes-from参数所挂载的数据卷容器自身并不需要保持运行转态。

利用数据卷容器迁移数据

备份数据

docker run --volumes-from dbdata -v $(pwd):/backup --name worker ubuntu tar cvf /backup/backup.tar /dbdata

利用Ubuntu镜像创建一个叫worker的容器,并挂载dbdata容器的数据卷;-v $(pwd):/backup是挂载本地的当前目录到worker容器的/backup目录。worker容器启动后,使用tar cvf /backup/backup.tar /dbdata命令将/dbdata下的内容备份为容器内的/backup/backup.tar,即宿主机当前目录下的backup.tar 。

恢复数据

首先创建一个带有数据卷的容器dbdata2
docker run -v /dbdata --name dbdata2 ubuntu
然后创建另一个新的容器,挂载dbdata2的容器,并使用untar解压备份文件到所挂载的容器卷中:
docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
然后在dbdata2容器中查看/dbdata目录。

网络基础配置

端口映射实现访问容器

从外部访问容器应用
端口映射:-p-P

** 映射所有接口地址**

hostPort:containerPort

docker run -d -p 5000:5000 training/webapp python app.py

多次使用-p绑定多个端口:
docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py

映射到指定地址的指定端口

ip:hostPort:containerPort

docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py

** 映射到指定地址的任意端口**

ip::containerPort

本地主机会自动分配一个端口:
docker run -d -p 127.0.0.1:5000 training/webapp python app.py
使用udp标记来指定udp端口:
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py

查看映射端口配置
docker port 容器名称或容器ID

容器互联实现容器间通信

参考文章:
- 连接容器 | Docker中文指南

1、创建一个db容器
docker run -d --name db training/postgres

2、创建一个web容器,并将它连接到db容器
docker run -d -P --name web --link db:db training/webapp python app.py
此时,两个容器已建立互联关系。

--link参数格式:--link name:alias,其中name是要链接的容器的名称,alias是这个链接的别名。
使用docker ps来查看容器的链接。

docker在两个互联的容器间创建了一个安全隧道,且不用映射它们的端口到宿主机上。在启动db容器的时候并没有使用-p-P 标记,从而避免暴露数据库端口到外部网络上。

docker通过两种方式为容器公开连接信息:
- 环境变量
- 更新/etc/hosts

使用env查看web容器的环境变量:
docker run --rm --name web2 --link db:db training/webapp env

结果:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=0478d8d00fb6
DB_PORT=tcp://172.17.0.3:5432
DB_PORT_5432_TCP=tcp://172.17.0.3:5432
DB_PORT_5432_TCP_ADDR=172.17.0.3
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_PROTO=tcp
DB_NAME=/web2/db
DB_ENV_PG_VERSION=9.3
HOME=/root

其中DB_开头的环境变量是供web容器链接db容器使用的。
除了环境变量外,docker还添加了父容器的/etc/hosts的文件。下面是父容器web的hosts文件:
docker run -it --rm --link db:db training/webapp /bin/bash
cat /etc/hosts

结果:
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 db cfa61a55111c
172.17.0.5 c04c9331a5a6

这里由两个hosts信息,第一个是web容器,web容器用自己的id作为默认主机名,第二个是db容器的ip和主机名。

在web容器中安装ping命令来测试跟db容器的连通,它会解析成172.17.0.3
apt-get install -yqq inetutils-ping
ping db

结果:
64 bytes from 172.17.0.3: icmp_seq=45 ttl=64 time=0.186 ms
64 bytes from 172.17.0.3: icmp_seq=46 ttl=64 time=0.067 ms
64 bytes from 172.17.0.3: icmp_seq=47 ttl=64 time=0.160 ms
64 bytes from 172.17.0.3: icmp_seq=48 ttl=64 time=0.068 ms

可以链接多个子容器到父容器上,比如可以链接多个web到db容器上。

使用Dockerfile创建镜像

基本结构

以#注释行
包含四部分:
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时执行命令

如:

  1. # This dockerfile uses the ubuntu image
  2. # VERSION 2 - EDITION 1
  3. # Author: docker_user
  4. # Command format: Instruction [arguments / command] ..
  5. # Base image to use, this must be set as the first line
  6. # 一行必须制定基于的基础镜像
  7. FROM ubuntu
  8. # Maintainer: docker_user <docker_user at email.com> (@docker_user)
  9. # 护者信息
  10. MAINTAINER docker_user docker_user@email.com
  11. # Commands to update the image
  12. # 镜像的操作指令
  13. RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
  14. RUN apt-get update && apt-get install -y nginx
  15. RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
  16. # Commands when creating a new container
  17. # 容器启动时执行指令
  18. CMD /usr/sbin/nginx

指令

指令的一般格式为 INSTRUCTION arguments,
指令包括 FROMMAINTAINERRUN 等。

1、FROM

指令的一般格式为 INSTRUCTION arguments , 指令包括 FROM 、 MAINTAINER 、 RUN 等。
格式为 FROM <image> 或 FROM <image>:<tag> 。
第一条指令必须为 FROM 指令。 并且, 如果在同一个Dockerfile中创建多个镜像时, 可以使用多个 FROM指令( 每个镜像一次) 。

2、MAINTAINER

格式为 MAINTAINER <name> , 指定维护者信息。

3、RUN

格式为 RUN <command> 或 RUN ["executable", "param1", "param2"] 。
前者将在 shell 终端中运行命令, 即 /bin/sh -c ;后者则使用 exec 执行。
指定使用其它终端可以通过第二种方式实现, 例如 RUN ["/bin/bash", "-c", "echo hello"] 。
每条 RUN 指令将在当前镜像基础上执行指定命令, 并提交为新的镜像。 当命令较长时可以使用 \ 来换行。

4、CMD

支持三种格式
- CMD ["executable","param1","param2"] 使用 exec 执行, 推荐方式;
- CMD command param1 param2 在 /bin/sh 中执行, 提供给需要交互的应用;
- CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;

指定启动容器时执行的命令, 每个 Dockerfile 只能有一条 CMD 命令。 如果指定了多条命令, 只有最后一条会被执行。
如果用户启动容器时候指定了运行的命令, 则会覆盖掉 CMD 指定的命令。

5、EXPOSE

格式为 EXPOSE <port> [<port>...] 。
例如: EXPOSE 22 80 8443
告诉 Docker 服务端容器暴露的端口号, 供互联系统使用。 在启动容器时需要通过 -P, Docker 主机会自动分配一个端口转发到指定的端口;使用-p则可以指定具体端口。

6、ENV

格式为 ENV <key> <value> 。 指定一个环境变量, 会被后续 RUN 指令使用, 并在容器运行时保持。
例如:

  1. ENV PG_MAJOR 9.3
  2. ENV PG_VERSION 9.3.4
  3. RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
  4. ENV PATH /usr/local/postgres-\$PG_MAJOR/bin:$PATH

7、ADD

格式为 ADD <src> <dest> 。
该命令将复制指定的 <src> 到容器中的 <dest> 。 其中 <src> 可以是Dockerfile所在目录的一个相对路
径;也可以是一个 URL;还可以是一个 tar 文件( 自动解压为目录) 。

8、COPY

格式为 COPY <src> <dest> 。
复制本地主机的 <src> ( 为 Dockerfile 所在目录的相对路径,文件或目录) 到容器中的 <dest> 。目标路径不存在时,会自动创建。
当使用本地目录为源目录时, 推荐使用 COPY 。

9、ENTRYPOINT

两种格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2 ( shell中执行) 。
配置容器启动后执行的命令, 并且不可被 docker run 提供的参数覆盖。
每个 Dockerfile 中只能有一个 ENTRYPOINT , 当指定多个时, 只有最后一个起效。

10、VOLUME

格式为 VOLUME ["/data"] 。
创建一个可以从本地主机或其他容器挂载的挂载点, 一般用来存放数据库和需要保持的数据等。

11、USER

格式为 USER daemon 。
指定运行容器时的用户名或 UID, 后续的 RUN 也会使用指定用户。
当服务不需要管理员权限时, 可以通过该命令指定运行用户。 并且可以在之前创建所需要的用户, 例
如: RUN groupadd -r postgres && useradd -r -g postgres postgres 。 要临时获取管理员权限可以
使用 gosu , 而不推荐 sudo 。

12、WORKDIR

格式为 WORKDIR /path/to/workdir 。
为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。
可以使用多个 WORKDIR 指令, 后续命令如果参数是相对路径, 则会基于之前命令指定的路径。 例如
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为 /a/b/c 。

13、ONBUILD

格式为 ONBUILD [INSTRUCTION] 。
配置当所创建的镜像作为其它新创建镜像的基础镜像时, 所执行的操作指令。
例如, Dockerfile 使用如下的内容创建了镜像 image-A 。
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
如果基于 image-A 创建新的镜像时, 新的Dockerfile中使用 FROM image-A 指定基础镜像时, 会自动执行
ONBUILD 指令内容, 等价于在后面添加了两条指令。
FROM image-A
#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src
使用 ONBUILD 指令的镜像, 推荐在标签中注明, 例如 ruby:1.9-onbuild 。

基于Dockerfile创建镜像

编写完成 Dockerfile 之后, 可以通过 docker build 命令来创建镜像。
基本的格式为 docker build [选项] 路径 , 该命令将读取指定路径下( 包括子目录) 的 Dockerfile, 并将该路径下所有内容发送给 Docker 服务端, 由服务端来创建镜像。 因此一般建议放置 Dockerfile 的目录为空目录。
也可以通过 .dockerignore 文件( 每一行添加一条匹配模式) 来让 Docker 忽略路径下的目录和文
件。
要指定镜像的标签信息, 可以通过 -t 选项.
例如,指定Dockfile所在路径为/tmp/docker_builder/,并且希望生成镜像标签为build_repo/fist_image,可以使用下面的命令:
docker build -t build_repo/fist_image /tmp/docker_builder/

创建支持SSH服务的镜像

  1. docker run -it ubuntu:14.04 /bin/bash
  2. sshd
  3. apt-get update
  4. apt-get install openssh-server
  5. mkdir -p /var/run/sshd
  6. /usr/sbin/sshd -D &
  7. netstat -tunlp
  8. #修改ssh服务的安全登录配置,取消pam登录限制
  9. sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
  10. mkdir root/.ssh
  11. vi /root/.ssh/authorized_keys
  12. vi /run.ssh
  13. > #!/bin/bash
  14. > /usr/sbin/sshd -D
  15. chmod +x run.sh
  16. exit

保存镜像:
docker commit 容器ID sshd:ubuntu
查看镜像:
docker images

docker run -p 10022:22 -d sshd:ubuntu /run.sh
docker ps
然后宿主机测试连接
ssh 127.0.0.1 -p 10022

1、创建目录
mkdir ssh_ubuntu
cd ssh_ubuntu
touch Dockerfile run.sh

2、编写run.sh 和 authorized_keys
vim run.sh

#!/bin/bash
/usr/sbin/sshd -D

在宿主机上生成SSH密钥,并创建authorized_keys文件 :
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub > authorized_keys

3、编写Dockerfile

  1. #设置继承镜像
  2. FROM ubuntu:14.04
  3. #作者信息
  4. MAINTAINER from www.healthdoc.cn by CUI (cui@healthdoc.cn)
  5. #开始运行命令,此处更改系统源
  6. RUN echo "deb http://mirrors.aliyun.com/ubuntu/ vivid main restricted universe multiverse" > /etc/apt/sources.list
  7. RUN echo "deb http://mirrors.aliyun.com/ubuntu/ vivid-security main restricted universe multiverse" >> /etc/apt/sources.list
  8. RUN echo "deb http://mirrors.aliyun.com/ubuntu/ vivid-updates main restricted universe multiverse" >> /etc/apt/sources.list
  9. RUN echo "deb http://mirrors.aliyun.com/ubuntu/ vivid-proposed main restricted universe multiverse" >> /etc/apt/sources.list
  10. RUN echo "deb http://mirrors.aliyun.com/ubuntu/ vivid-backports main restricted universe multiverse" >> /etc/apt/sources.list
  11. RUN echo "deb-src http://mirrors.aliyun.com/ubuntu/ vivid main restricted universe multiverse" >> /etc/apt/sources.list
  12. RUN echo "deb-src http://mirrors.aliyun.com/ubuntu/ vivid-security main restricted universe multiverse" >> /etc/apt/sources.list
  13. RUN echo "deb-src http://mirrors.aliyun.com/ubuntu/ vivid-updates main restricted universe multiverse" >> /etc/apt/sources.list
  14. RUN echo "deb-src http://mirrors.aliyun.com/ubuntu/ vivid-proposed main restricted universe multiverse" >> /etc/apt/sources.list
  15. RUN echo "deb-src http://mirrors.aliyun.com/ubuntu/ vivid-backports main restricted universe multiverse" >> /etc/apt/sources.list
  16. RUN apt-get update
  17. #安装ssh服务
  18. RUN apt-get install -y openssh-server
  19. RUN mkdir -p /var/run/sshd
  20. RUN mkdir -p /root/.ssh
  21. #取消pam登录限制
  22. RUN sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
  23. #复制配置文件到相应位置,并赋予执行权限
  24. ADD authorized_keys /root/.ssh/authorized_keys
  25. ADD run.sh /run.sh
  26. RUN chmod 755 /run.sh
  27. #开放端口
  28. EXPOSE 22
  29. #设置自启动命令
  30. CMD ["/run.sh"]

4、创建镜像
cd sshd_ubuntu
docker build -t sshd:dockerfile .

** 注意**:还有一个 . 是表示当前目录的Dockfile。-t 是表示设置tag。使用Dockerfile创建的自定义镜像,docker会自动删除中间临时创建的层,还需要注意每一步的操作和编写的dockerfile中命令的对应关系。
#查看镜像
docker images
#使用创建的sshd:dockerfile镜像来运行容器
docker run -d -p 10122:22 sshd:dockerfile
#宿主机测试SSH
ssh 127.0.0.1 -p 10122

对于是否需要为Docker容器启用SSH服务一直存在争论。Docker理念是一个容器只运行一个服务。另docker 1.3版本之前,attach进入容器容易出现卡死,1.3之后,推出了exec命令,但是从其他远程主机进入容器依然没有更好的解决方案。

WEB服务器与应用

数据库应用

编程语言

Docker容器集群

自定义网桥连接跨主机容器

Ambassador容器实现容器互联

其他方式实现容器互联

阿里云上使用Docker

参考:

ECS Docker实践文档

Docker核心技术

Docker安全

高级网络配置

Docker相关项目

容器管理:

常见问题汇总

1、本地的镜像文件存放在哪里?

与Docker相关的本地资源都存放在/var/lib/docker/目录下,其中container目录存放容器信息,graph目录存放镜像信息,aufs目录下存放具体的镜像层文件。

2、构建Docker镜像应该遵循哪些原则?

整体原则上,尽量保持镜像功能的明确和内容的精简,要点包括:

3、容器退出后,通过docker ps命令查看不到,数据会丢失么?

容器退出后会处于终止(exited)状态,此时可以通过docker ps -a查看。其中的数据也不会丢失,还可以通过docker start命令来启动它。只有删除掉容器才会清除所有数据。

4、如何给容器指定一个固定IP地址,而不是每次重启容器IP地址都会变?

参考pipwork工具等。

5、如何临时退出一个正在交互的容器的终端,而不终止它?

按Ctrl-p Ctrl-q。如果按Ctrl-c往往会让容器内应用进程终止,进而会终止容器。

6、仓库(Repository)、注册服务器(Registry)、注册索引(Index)有何关系?

首先,仓库是存放一组关联镜像的集合,比如同一个应用的不同版本的镜像。注册服务器是存放实际的镜像文件的地方。注册索引则负责维护用户的账号、权限、搜索、标签等的管理。因此,注册服务器利用注册索引来实现认证等管理。

7、从非官方仓库(例如dl.dockerpool.com)下载镜像时候,有时候会提示“Error:Invalid registry endpointhttps://dl.dockerpool.com:5000/v1/……”?

Docker自1.3.0版本往后,加强了对镜像安全性的验证,需要手动添加对非官方仓库的信任。
编辑Docker配置文件,在其中添加:
DOCKER_OPTS="--insecure-registry dl.dockerpool.com:5000"
之后,重启Docker服务即可。

8、Docker的配置文件放在哪里,如何修改配置?

Ubuntu系统的配置文件是/etc/default/docker,Centos系统的配置文件放在/etc/sysconfig/docker。

9、如何更改Docker的默认存储位置?

Docker的默认存储位置是/var/lib/docker,如果希望将Docker的本地文件存储到其他分区,可以使用Linux软连接的方式来完成。

  1. service docker stop
  2. mv /var/lib/docker /mnt/docker
  3. ln -s /mnt/docker /var/lib/docker
  4. ls /var/lib/docker
  5. service docker start

10、如何将一台宿主主机的docker环境迁移到另外一台宿主主机?

停止Docker服务。将整个docker存储文件夹复制到另外一台宿主主机,然后调整另外一台宿主主机的配置即可。

11、Docker Compose能管理跨主机的容器吗

Compose本身不支持跨主机管理容器的,因为它的实现中只能连接一个docker client。从一个到多个,中间就有调度的问题。配合swarm的话,swarm把多个主机的docker engine集群抽象成一个docker,这样再配合compose就可以实现跨主机的容器了。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注