docker基础知识

1、认识

1.什么是docker

Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,听从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。node

Docker 自开源后受到普遍的关注和讨论,以致于dotCloud 公司后来都更名为 Docker Inc。Redhat已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中普遍应用。python

Docker的主要目标:mysql

经过对应用组件的封装、分发、部署、运行等生命周期的管理,达到应用级别的一次封装,处处运行。linux

小贴士:这里的应用组件,能够是WEB应用,也能够是一套数据库服务,甚至能够是一个操做系统编译器ios

2.为何使用docker

Docker容器虚拟化的优势:nginx

  • 环境隔离;

经过cgroups和namesapce进行实现资源隔离,实现一台机器运行多个容器互不影响。git

  • 更快速的交付部署;

使用docker,开发人员能够利用镜像快速构建一套标准的研发环境;开发完成后,测试和运维人员能够直接经过使用相同的环境来部署代码。Docker能够快速建立和删除容器,实现快速迭代,大量节约开发、测试、部署的时间。而且,各个步骤都有明确的配置和操做,整个过程全程课件,使团队里更容易理解应用建立和工做的过程。github

  • 更高效的资源利用;

docker容器的运行不须要额外的虚拟化管理程序的支持,它是内核级的虚拟化,能够实现更高的性能,同时对资源的额外需求很低。web

  • 更易迁移扩展;

docker容器几乎能够在任意的平台上运行,包括乌力吉、虚拟机、公有云、私有云、我的电脑、服务器等,这种兼容性让用户能够在不一样平台之间轻松的迁移应用。sql

  • 更简单的更新管理。

使用Dockerfile,只须要小小的配置修改,就能够替代以往的大量的更新工做。而且全部修改都是以增量的方式进行分发和更新,从而实现自动化和高效的容器管理。

3.虚拟化与docker

虚拟化定义:虚拟化是一种资源管理技术,是将计算机的各类实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户能够比本来的配置更好的方式来应用这些资源。这些资源的新虚拟部分是不受现有资源的架设方式,地域或物理配置所限制。通常所指的虚拟化资源包括计算能力和数据存储。

系统虚拟化,Hypervisor Virtualization,全虚拟化。在 Host 中经过 Hypervisor 层实现安装多个 GuestOS,每一个 GuestOS 都有本身的内核,和主机的内核不一样,GuestOS 之间彻底隔离。

容器虚拟化,Operating System Virtualization ,使用 Linux 内核中的 namespaces 和 cgroups 实现进程组之间的隔离。是用内核技术实现的隔离,因此它是一个共享内核的虚拟化技术。

容器虚拟化没有 GuestOS,使用 Docker 时下载的镜像,只是为运行 App 提供的一个依赖的环境,是一个删减版本的系统镜像。通常状况下系统虚拟化没有容器虚拟化的运行效率高,可是系统安全性高不少。

优越性:

你在一台机器能够开10个虚拟机,若是用docker能够开100个容器,就是这么霸气

4.docker官网注册

注册一个docker帐号:https://hub.docker.com/

完成注册,我用的qq邮箱,等了10分钟才收到。

收到后激活邮箱,进行登陆

登陆完毕

2、核心概念和安装

1.环境介绍

​ 操做系统:CentOS7 7.6 X64

​ docker版本:18.06.1-ce

要求: 内核版本最低为3.10

查看当前内核版本: uname –r

更改网卡配置:vim /etc/sysconfig/network-scripts/ifcfg-enp0s3ONBOOT="yes"

2.经过yum方式安装docker

新增通常用户,并加入到sudo组,如下命令均使用通常用户执行

第一步:更新yum源: sudo yum update

第二步:增长docker的yum源

# sudo vim /etc/yum.repos.d/docker.repo
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/ 
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg

第三步:经过yum安装docker:sudo yum install docker

第四步:启动docker服务:sudo systemctl start docker.service

第五步:查看版本信息,经过测试用例验证docker是否安装成功:docker version

测试:sudo docker run hello-world

第六步:docker配置

设置docker开机启动:sudo chkconfig docker on

docker卸载

​ 查看安装包:sudo yum list installed | grepdocker

​ 移除安装包:sudo yum -y remove docker.x86_64

​ 清除全部docker依赖文件:sudo rm -rf /var/lib/docker

3.Docker的核心概念

3.1 Docker核心概念之镜像

Docker 镜像就是一个只读的模板。

例如:一个镜像能够包含一个完整的 centos操做系统环境,里面仅安装了 Apache 或用户须要的其它应用程序。

镜像能够用来建立 Docker 容器。

建立Docker镜像有几种方式,多数是在一个现有镜像基础上建立新镜像,由于几乎你须要的任何东西都有了公共镜像,包括全部主流Linux发行版,你应该不会找不到你须要的镜像。不过,就算你想从头构建一个镜像,也有好几种方法。

要建立一个镜像,你能够拿一个镜像,对它进行修改来建立它的子镜像 。

3.2 Docker核心概念之容器

Docker 利用容器来运行应用。

容器是从镜像建立的运行实例。它能够被启动、开始、中止、删除。每一个容器都是相互隔离的、保证安全的平台。

能够把容器看作是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

注:镜像是只读的,容器在启动的时候建立一层可写层做为最上层。

3.3 Docker核心概念之仓库

仓库是集中存放镜像文件的场所。

有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上每每存放着多个仓库,每一个仓库中又包含了多个镜像,每一个镜像有不一样的标签(tag)。Centos的6.0和7.0就是tag。

3、镜像的经常使用操做

1.获取镜像

命令:

docker pull <域名>/<namespace>/<repo>:<tag>

​ 好比:sudo docker pull centos

说明:

​ 镜像是Docker运行容器的前提。

​ 用户可使用docker pull 命令从网络上下载镜像。对于镜像来讲,若是不显式地指定tag,则默认会选择latest标签,即下载仓库中最新版本的镜像。

​ 默认是从docker官方下载的。只有docker官方的能够不须要增长命名空间直接进行下载。

2.查看镜像列表

命令:

docker images

说明:

​ 使用docker images命令能够列出本地主机上已有的镜像。

​ 信息含义:来自于哪一个仓库、镜像的标签信息、镜像的ID号(惟一)、建立时间、镜像大小。

3.查看镜像信息

命令:

docker inspect <image_id>

说明:

​ docker inspect命令返回的是一个JSON的格式消息,若是咱们只要其中的一项内容时,能够经过-f参数来指定。Image_id一般可使用该镜像ID的前若干个字符组成的可区分字符串来替代完成的ID。

sudo docker inspect -f {{.DockerVersion}} image_id
# DockerVersion前面有一个点号,查询指定的内容

4.查找镜像

命令:

docker search <image_name>

说明:

​ 使用docker search命令能够搜索远端仓库中共享的镜像,默认搜索Docker hub官方仓库中的镜像。

5.删除镜像

命令:

docker rmi <image>:<tag>

说明:

​ 使用docker rmi命令能够删除镜像,其中image能够为标签或ID。

注意:

  • 当同一个镜像拥有多个标签,docker rmi只是删除该镜像多个标签中的指定标签而已,而不影响镜像文件。

  • 当有该镜像建立的容器存在时,镜像文件默认是没法被删除的。

  • 若是一个镜像就有一个tag的话,删除tag就删除了镜像的自己。

若是镜像里面有容器正在运行,删除镜像的话,会提示error,系统默认是不容许删除的,若是强制删除须要加入-f操做,可是docker是不建议这么操做的,由于你删除了镜像其实容器并未删除,直接致使容器找不到镜像,这样会比较混乱。

一个镜像作一个tag:sudo docker tag image_id image:tag

执行删除tag操做:sudo docker rmi image:tag

运行一个镜像里面的容器:$ sudo docker run centos echo 'Docker hahaha'

查看运行中的容器:sudo docker ps -a

6.建立镜像

命令:

docker commit <options> <container_id><repository:tag>

参数说明:

​ -a , --author : 做者信息

​ -m , --meassage : 提交消息

​ -p , --pause=true : 提交时暂停容器运行

说明:

​ 基于已有的镜像的容器的建立。

例子:以centos为例子建立

运行centos,-ti把容器内标准绑定到终端并运行bash,这样开跟传统的linux操做系统没什么两样,如今咱们直接在容器内运行。这个内部系统都是极简的只保留咱们的一些系统的运行参数,里面不少vi命令可能都是没有的。

$ sudo docker run -ti centos
[root@158183a8ae93 /]# echo '1111' > 1.txt
[root@158183a8ae93 /]# exit

退出容器exit。

容器建立成镜像的方法:

​ 经过某个容器d1d6706627f1 建立对应的镜像,有点相似git。注意,是根据容器ID建立的,可使用docker pa -a事先查看容器ID

命令:docker commit -a 'author' -m 'message' container_id image_name

sudo docker commit -a 'Sandu' -m 'create a docker version' 158183a8ae93 centos11/test

7.迁出镜像

命令:

docker save -o <image>.tar <image>:<tag>

参数说明:

​ -o:设置存储压缩后的文件名称

说明:

​ 可使用docker save命令来迁出镜像,其中image能够为标签或ID。

8.载入镜像

命令:

docker load --input <image>.tar `

说明:

​ 使用docker load命令能够载入镜像,其中image能够为标签或ID。这将导入镜像及相关的元数据信息(包括标签等),可使用docker images命令进行查看。能够先删除以前的镜像而后再导入,或者在一台新机器上部署docker环境后再导入

默认载入的镜像没有镜像名称和tag,使用下面的命令建立:sudo docker tag image_id image_name,tag自动为latest

9.上传镜像

命令:

docker push <域名>/<namespace>/<repo>:<tag>

说明:

​ 可使用docker push命令上传镜像到仓库,默认上传到DockerHub官方仓库(须要登陆)。

# 登录到docker官网
$ sudo docker login

# 输入帐号密码,提示:Login Succeeded

# 而后开始上传镜像,注意:image_name的/前部分名称要与官网注册的名称一致,不然提示:denied: requested access to the resource is denied
# 可使用tag方式复制一份镜像并重命名的方式来上传镜像
# sudo docker tag image_id  xxxx/iamge_name  # xxxx要与在官网上注册的Docker ID保持一致
$ sudo docker push image_name

4、容器的经常使用操做

1.建立容器

Docker的容器十分轻量级,用户能够随时建立或删除容器。

​ 新建容器:docker create

​ Example:docker create –it centos

说明:使用docker create命令建立的容器处于中止状态,可使用docker start命令启动它。

$ sudo docker create -it centos
$ sudo docker ps -a
CONTAINER ID   IMAGE     COMMAND      CREATED        STATUS          PORTS               NAMES
00e0a9ee7fe2   centos   "/bin/bash"    8 seconds ago     Created       affectionate_mahavira

新建并启动容器:`docker run

​ Example: docker run centos /bin/echo “Hello World”

说明: 等价于先执行docker create命令,再执行docker start命令。

docker run 背后的故事:

  • 1 检查本地是否存在制定的镜像,不存在就从公有仓库下载。

  • 2 利用本地镜像建立并启动一个容器。

  • 3 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层。

  • 4 从宿主机配置的网桥接口桥接一个虚拟接口到容器中去。

  • 5 从地址池配置一个IP地址给容器。

  • 6 执行用户的指定的用户程序。

  • 7 执行完毕后容器被终止。

一条简单的命令:

docker run -i –t centos /bin/bash

  • -t : 让docker分配一个伪终端并绑定到容器的标准输入上。

  • -i : 让容器的标准输入保持打开。

在交互模式下,用户能够经过所建立的终端来输入命令,exit命令退出容器。

退出后,容器自动处于终止状态。

守护台运行:

​ 更多的时候,须要让Docker容器运行在后台以守护态(daemonized)形式运行。用户能够经过添加-d参数来实现。

Example:

docker run -d centos /bin/bash -c "while true;do echo hello world;sleep 1;done"

补充:

​ 查看日志: docker logs <container_id>

docker logs –f <container_id>动态的查看日志,相似查看tomcat的日志同样

2.终止容器

可使用docker stop命令来终止一个运行中的容器。

docker stop <container_id>

注意:当容器中的应用终结时,容器也会自动中止。

查看终止的容器:docker ps -a

查看运行的容器:docker ps

从新启动容器:docker start <container_id>

3.进入容器

在使用-d参数时,容器启动后会进入后台,用户没法看到容器中的信息。

docker exec <options> <container_id> <command>

Exec能够直接在容器内部运行命令。前提是容器正在运行。

进入容器:

docker exec -i –t <container_id> bash

区别:

  • run 运行一个容器后,进入容器的话,exit退出后,容器也直接退出

  • exec 进入容器后,exit退出后,容器不退出仍在后台运行

4.删除容器

可使用docker rm命令删除终止状态的容器。

docker rm image_name|image_id

若是删除正在运行的容器,须要中止容器而后进行删除。

无论容器是否运行,可使用docker rm –f命令进行删除。

5.导入和导出容器

导出容器是指导出一个已经建立的容器到一个文件,无论容器是否处于运行状态。可使用docker export命令。

docker export <container_id>

Example:

docker export container_id > test.tar

sudo docker export 7adfb980d640 > test_contain_id.tar

导出的文件又可使用docker import命令导入,成为镜像。

Example:

cat test_contain_id.tar | docker import - image_name:latest

注意:不知为啥,通常用户没法导入,须要使用root用户才能够导入成功

5、仓库

1.Docker Hub

仓库是集中存放镜像的地方。

目前Docker官方仓库维护了一个公共仓库https://hub.docker.com,其中已经包括15000多个的镜像。

大部分需求均可以经过在Docker Hub中直接下来镜像来实现。

登录:

能够经过执行docker login命令来输入用户名、密码和邮箱来完成注册登陆。

基本操做

用户无需登陆能够经过 docker search命令来查找官方仓库中的镜像,并利用docker pull下载到本地,能够经过docker push命令将本地镜像推送到docker hub。

先tag一下复制一个镜像,而后把镜像push到服务器上。

2.建立和使用私有仓库

使用registry镜像建立私有仓库

能够经过docker官方提供的registry镜像来搭建一套本地私有仓库。

镜像地址:https://hub.docker.com/_/registry/

命令:

docker run -e SEARCH_BACKEND=sqlalchemy -e SQLALCHEMY_INDEX_DATABASE=sqlite:////tmp/docker-registry.db -d --name registry -p 5000:5000 registry

命令参数:

  • -e设定环境变量

  • -d从后台启动的方式镜像启动

  • -name 启动的容器起个名字

  • -p 暴露端口,容器内部的5000绑定到宿主机的5000端口上。

  • registry镜像自己

  • SEARCH_BACKEND=sqlalchemy默认索引是能够查询的

参考地址:

https://github.com/docker/docker-registry#search-engine-options

https://hub.docker.com/_/registry/

# 1. 先配置,提早解决后续出现的问题:http: server gave HTTP response to HTTPS client 
[sandu@bogon ~]$ sudo vim /etc/doker/daemon.json # 没有该文件的话就建立一个
{ "insecure-registries":["192.168.0.192:5000"] } # ip为本机的ip,5000端口为后续使用的端口
# 重启docker服务
[sandu@bogon ~]$ sudo systemctl daemon-reload
[sandu@bogon ~]$ sudo systemctl restart docker.service
# 2. 登录docker
[sandu@bogon ~]$ sudo docker login
# 3.拉取私有仓库镜像
[sandu@bogon ~]$ sudo docker run -e SEARCH_BACKEND=sqlalchemy -e SQLALCHEMY_INDEX_DATABASE=sqlite:////tmp/docker-registry.db -d --name registry -p 5000:5000 registry
[sudo] password for sandu: 
Unable to find image 'registry:latest' locally
Trying to pull repository docker.io/library/registry ... 
latest: Pulling from docker.io/library/registry
c87736221ed0: Pull complete 
1cc8e0bb44df: Pull complete 
54d33bcb37f5: Pull complete 
e8afc091c171: Pull complete 
b4541f6d3db6: Pull complete 
Digest: sha256:8004747f1e8cd820a148fb7499d71a76d45ff66bac6a29129bfdbfdc0154d146
Status: Downloaded newer image for docker.io/registry:latest
1cec256c7e63bb6b29cbeb7ae1b3b25fc53fbb86122b950eee788f553ce14619

# 查看当前运行的容器
[sandu@bogon ~]$ sudo docker ps
CONTAINER ID  IMAGE   COMMAND              CREATED           STATUS      PORTS               NAMES
630bf936586d  registry "/entrypoint.sh /e..."   9 minutes ago       Up 9 minutes  0.0.0.0:5000->5000/tcp   registry

# 查看现有镜像
[sandu@bogon ~]$ sudo docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos     latest              9f38484d220f        4 months ago        202 MB
docker.io/registry   latest              f32a97de94e1        5 months ago        25.8 MB

# 4.拉取一个公共镜像,修改后打算上传到私有仓库,须要给该镜像从新赋值一个tag
[sandu@bogon ~]$ sudo docker tag docker.io/centos 192.168.0.192:5000/sanduzxcvbnm/test2_registry
# 注意:前面的参数是打算上传到私有仓库的镜像,后面那个是从新赋值的tag,最前面的是私有仓库地址,中间的是在docker官网注册的用户名,后者是镜像名

[sandu@bogon ~]$ sudo docker images
REPOSITORY                                       TAG                 IMAGE ID            CREATED             SIZE
192.168.0.192:5000/sanduzxcvbnm/test2_registry   latest              9f38484d220f        5 months ago        202 MB
docker.io/centos                                 latest              9f38484d220f        5 months ago        202 MB
docker.io/registry                               latest              f32a97de94e1        5 months ago        25.8 MB

# 5.上传镜像到私有仓库
[sandu@bogon ~]$ sudo docker push 192.168.0.192:5000/sanduzxcvbnm/test2_registry

3.仓库加速服务

加速下载官方镜像。

推荐服务:https://dashboard.daocloud.io/

点击加速器:https://dashboard.daocloud.io/mirror

4.仓库管理

Registry Web UI 用于镜像的查询,删除。

镜像地址:https://hub.docker.com/r/atcol/docker-registry-ui/

# 拉取管理仓库的web镜像,把私有仓库绑定到管理仓库web并启动
[sandu@bogon ~]$ sudo docker run -d --name registry_ui -p 8080:8080 -e REG1=http://192.168.0.192:5000/v1/ atcol/docker-registry-ui

# 问题
界面上虽然能看到本身建立的私有仓库信息,可是界面提示:ping faild
查看日志:docker logs -f registry_ui,报错信息以下:
2019-08-12 03:24:00,187 [http-nio-8080-exec-5] ERROR web.RepositoryService  - Failed to ping http://192.168.0.192:5000/v1/_ping: 404 : Not Found

此问题留待之后解决,初步判断是须要给私有仓库添加认证信息

6、数据管理

1.数据卷

数据卷是一个可供容器使用的特殊目录,有以下特性:

  • 数据卷能够在容器之间共享和重用

  • 数据卷修改会当即生效

  • 数据卷的更新不会影响镜像

  • 若是有容器使用数据卷,该卷会一直存在

准备工做:

​ 建立一个目录,并在目录里面建立文件,文件内写入内容。

[root@bogon ~]# cd /tmp/
[root@bogon tmp]# mkdir webapp
[root@bogon tmp]# cd webapp/
[root@bogon webapp]# echo '数据卷' > 1.txt
[root@bogon webapp]# cat 1.txt
数据卷
[root@bogon webapp]#

1.1在容器内建立数据卷

在使用docker run的命令时,使用 -v 标记能够在容器内建立一个数据卷,而且能够指定挂在一个本地已有的目录到容器中做为数据卷:

建立启动app1容器并挂载数据卷,注意,此时是在tmp目录下进行的操做

echo ${pwd} 命令标识当前目录

[root@bogon tmp]# docker run -d --name app1 -it -v ${pwd}/webapp:/root/webapp centos bash

经过目录跟容器内创建了一层关系,数据卷发生变化后,容器内和容器外都会随之发生改变。例如容器挂载一个文件,当容器挂了后,文件不会丢失。

注意:默认挂载的数据卷的权限是rw(可读写),若是要求ro(只读),则须要加上对应的ro参数,命令可改成:

docker run -d --name app1 -it -v ${pwd}/webapp:/root/webapp:ro centos bash

# 建立启动app1容器并挂载数据卷,前者/tmp/webapp是本机路径,后者/tmp/webapp1是容器路径
[root@bogon webapp]# docker run -d -it --name app1 -v /tmp/webapp:/tmp/webapp1 centos bash
# 进入容器找到/tmp目录可查看到已挂载的数据卷
[root@bogon webapp]# docker exec -it app1 bash
[root@11755ef11dc1 /]# cd /tmp/
[root@11755ef11dc1 tmp]# ll
total 4
-rwx------. 1 root root 836 Mar  5 17:36 ks-script-eC059Y
drwxr-xr-x. 2 root root  32 Aug 13 06:30 webapp1
-rw-------. 1 root root   0 Mar  5 17:34 yum.log
# 数据卷目录与容器内目录有映射关系,因此无论是在容器内部修改数据卷仍是在外部修改数据卷,相对应的数据卷都会发生改变。
# 在容器内修改文件数据后,exit退出容器,进入本机路径查看文件,会发现文件也发生了变化.
# 只读权限是没法写入数据的

2.数据卷容器

数据卷容器用于用户须要在容器间共享一些持续更新的数据,数据卷容器专门提供数据卷供其它容器挂载使用。

2.1 建立数据卷容器

Example:

建立数据卷容器db1

docker run -d --name db1 -v /dbdata -ti centos bash

建立容器db2与db1共享dbdata的数据

docker run -d --name db2 --volumes-from db1 -ti centos bash

# 建立数据卷容器db1
[root@bogon tmp]# docker run -d --name db1 -v /tmp/dbdata/ -it centos bash
# 建立数据卷容器db2,使用db1的数据卷
[root@bogon tmp]# docker run -d --name db2 --volumes-from db1 -it centos bash
# 在容器db1和容器db2任意一个容器修改/tmp/dbdata/的内容,在两个容器内均生效

2.2 数据卷容器的删除

若是删除了挂载的容器,数据卷并不会被自动删除,若是要删除一个数据卷,必须在删除最后一个还挂载它的容器时显示使用docker rm -v 命令指定同时删除关联的容器。能够利用数据卷容器对其中的数据卷进行备份、恢复,以实现数据的迁移。

2.3 数据卷容器的备份

使用下面的命令来备份dbdata数据卷容器内的数据卷:

docker run --volumes-from /tmp/dbdata -v ${PWD}:/backup --name worker centos \tar cvf /backup/backup.tar /tmp/dbdata

说明:

利用centos镜像建立一个容器worker。

使用`--volumes-from /tmp/dbdata参数来让worker容器挂载dbdata的数据卷。

使用${pwd}:/backup参数来挂载本地目录到worker容器的/backup目录。

worker启动后,使用tar命令将/tmp/dbdata下的内容备份为容器内的/backup/backup.tar。

2.4 数据卷容器的恢复

若是恢复数据到一个容器,能够参照下面的操做。首先建立一个带有数据卷的容器dbdata2:

` docker run -d -v /dbdata --name dbdata2 centos /bin/bash

而后建立另外一个新的容器,挂载dbdata2的容器,并使用tar命令解压备份文件到挂载的容器卷中便可:

docker run --volumes-fromd bdata2 -v ${pwd}:/backup centos tar xvf /backup/backup.tar

7、网络

1.容器对外服务

当容器内运行一些网络应用,要让外部访问这些应用时,能够经过 -P 或 -p 参数来指定端口映射。

使用 -P 映射时,Docker会随机映射一个49000 ~49900 的端口至容器内部开放的端口:

docker run -d -P --name mysql mysql:5.6

经过docker ps能够看到端口映射关系。

能够经过映射在宿主机的端口来访问对应容器内的服务。

映射到指定宿主机的端口:

# 从官网拉取并运行MySQL5.6镜像,并设置镜像内的MySQL链接密码
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.6
# -e 是环境变量的意思 运行容器内的环境变量设置mysql的密码
# 默认使用宿主机的3306端口

映射到指定地址的指定端口,为例:

docker run -d -p 3306:3306 --name -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql mysql:5.6

若不加上-e参数,则会报错:

error: database is uninitialized and password option is not specified You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD

[root@bogon log]# docker ps
CONTAINER ID   IMAGE   COMMAND     CREATED   STATUS       PORTS           NAMES
9f298b7aeb6e  mysql:5.6   "docker-entrypoint..."   3 seconds ago       Up 2 seconds        0.0.0.0:3306->3306/tcp   mysql
# 0.0.0.0表示任意主机均能访问

外部访问宿主机的3306直接映射到容器的3306链接到数据库

映射到指定地址的指定端口,以127.0.0.1为例:

docker run -d -p 127.0.0.1:3306:3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw --name mysql mysql:5.6

[root@bogon log]# docker ps
CONTAINER ID   IMAGE    COMMAND    CREATED    STATUS   PORTS      NAMES
082f503397da   mysql:5.6    "docker-entrypoint..."   3 seconds ago   Up 2 seconds    127.0.0.1:3306->3306/tcp   quirky_franklin
# 127.0.0.1 表示仅本机才能访问,没有使用--name指定容器名则随机生成一个

映射到指定地址的任意端口,以127.0.0.1为例:

docker run -d -p 127.0.0.1::3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw --name mysqlmysql:5.6

[root@bogon log]# docker ps
CONTAINER ID   IMAGE   COMMAND  CREATED  STATUS   PORTS    NAMES
29293afe0d7a   mysql:5.6   "docker-entrypoint..."   4 seconds ago   Up 3 seconds   127.0.0.1:32768->3306/tcp   unruffled_curran
# 宿主机没有指定端口,则随机使用一个端口跟容器3306端口作映射

查看映射端口配置:

docker port mysql 3306

[root@bogon log]# docker port 29293afe0d7a
3306/tcp -> 127.0.0.1:32768

2.容器间相互通讯

经过映射宿主机的端口实现容器的互联。

使用--link参数可让容器之间安全的进行交互。

建立一个数据库容器:

docker run -d -e MYSQL_ROOT_PASSWORD=my-secret-pw --name mysqldb mysql:5.6

建立一个web容器并和数据库容器创建链接:

docker run -d --name Webapp -p 8000:8080 --link mysqldb:MySQL tomcat

上边的MySQL别名就相似dns解析的方式,我给这个容器起了个别名叫MySQL,我就经过这个别名就能够找到对应的这个mysqldb容器

mysqldb容器和web容器创建互联关系。

--link参数的格式为--link name:alias,其中name是要链接的容器名称,alias是这个链接的别名。

[root@bogon log]# docker run -d -e MYSQL_ROOT_PASSWORD=my-secret-pw --name mysqldb mysql:5.6
5978df27095f87193bf6dbffd5cf7c1e315b19129687c4409757b83923a70c02
[root@bogon log]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
5978df27095f        mysql:5.6           "docker-entrypoint..."   5 seconds ago       Up 4 seconds        3306/tcp            mysqldb
[root@bogon log]# docker run -d --name webapp -p 8000:8080 --link mysqldb:MySQL tomcat 
Unable to find image 'tomcat:latest' locally
Trying to pull repository docker.io/library/tomcat ... 
latest: Pulling from docker.io/library/tomcat
9cc2ad81d40d: Pull complete 
8e391ba3712a: Pull complete 
Digest: sha256:ddb9336dcd0ff66874db84880d58f6571bfa737cf6390bc38a66d1f78a857be6
Status: Downloaded newer image for docker.io/tomcat:latest
690b944739532e1ce55dfe49b5e3b24ddd5a13f8030d384c975f87631a8a5056
[root@bogon log]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                    NAMES
690b94473953        tomcat              "catalina.sh run"        3 seconds ago        Up 2 seconds        0.0.0.0:8000->8080/tcp   webapp
5978df27095f        mysql:5.6           "docker-entrypoint..."   About a minute ago   Up About a minute   3306/tcp                 mysqldb
[root@bogon log]# docker exec -it webapp bash
root@690b94473953:/usr/local/tomcat# ping MySQL
PING MySQL (172.17.0.2) 56(84) bytes of data.
64 bytes from MySQL (172.17.0.2): icmp_seq=1 ttl=64 time=0.119 ms
64 bytes from MySQL (172.17.0.2): icmp_seq=2 ttl=64 time=0.078 ms
^Z
[1]+  Stopped                 ping MySQL

可使用docker ps(PORT字段)来查看容器的链接。

Docker在两个容器之间建立了安全隧道,并且不用映射它们的端口到宿主机上。在启动mysqldb的时候并无使用-p和-P标记,从而避免的了暴露数据库的端口到外部的网络上。

link就是容器直接互相通讯的

Docker经过两种方式为容器公开链接信息:

1 环境变量:

使用env命令来查看。

EX:docker run --rm --name test --link dblink:dblink ubuntu env

2 更新/etc/hosts文件

查看/etc/hosts文件。

八 、Dockerfile

1. 利用Dockerfile建立镜像

什么是Dockerfile?

定义:Dockerfile是一个文本格式的配置文件,用户可使用Dockerfile快速建立自定义镜像。

基本结构:

Dockerfile由一行行的命令语句组成。而且支持以#开头的注释行。

通常Dockerfile分为四个部分:基础镜像信息、维护者信息、镜像操做指令和容器启动时的指令。

Dockerfile示例:

#This is a Dockerfile

#Author:liming

#第一行必须指定基础镜像

FROM ubuntu

#维护者信息

MAINTAINER 394498036@qq.com

#镜像的操做指令

RUN apt-get update

RUN apt-getinstall -y nginx

RUN echo “\ndaemonoff:” >> /etc/nginx/nginx.conf

#容器启动时的指令

CMD /usr/sbin/nginx

建立命令:

docker build –t=“<镜像名称>” .

注意:执行此命令要和Dockerfile在同级目录,文件名称必须为Dockerfile。命令后面的”.”表示在当前目录下执行。

2.Dockerfile指令集

1 FROM

格式为 FROM :

第一条指令必须为FROM指令,用于指定基础镜像。

2 MAINTAINER

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

3 RUN

格式为 RUN ,会在shell终端运行命令。

4 EXPOSE

格式为 EXPOSE [ ...],容器须要暴露的端口号。镜像启动能够经过 –P 或 -p 进行端口映射的绑定。

5 ENV

格式为 ENV

指定一个环境变量,能够被后续的RUN引用,而且在容器中记录该环境变量。

6 ADD

格式为 ADD

该命令将复制指定的 到容器中的 。其中 能够是Dockerfile所在目录的一个相对路径;也能够是url,还能够是tar文件(自动解压)。

7 VOLUME

格式为 VOLUME [path]。

建立一个能够从本地主机或其余容器挂载点,通常用来存放须要保持的数据。

8 USER

格式为 USER

指定运行容器时的用户名,后续的RUN也会指定该用户。

9 WORKDIR

格式为 WORKDIR

指定工做空间,运行完WORKDIR后,后续执行的RUN、CMD、ENTRYPOINT都会在此目录下执行。

10 COPY

格式为 COPY

复制本地主机的 到容器中的 ,目标路径不存在时,会自动建立。

当使用本地目录为源目录时,推荐使用COPY。

11 CMD

推荐格式为 CMD [“executable”,”param1”,”param2”] 。

做为ENTRYPOINT的默认参数为 CMD[”param1”,”param2”]。

指定容器的启动命令,每一个Dockerfile只能有一条CMD命令,若是指定多条,只有最后一条会执行。

用户启动容器时指定运行命令,会覆盖掉Dockerfile中的CMD命令。

12 ENTRYPOINT

格式为 ENTRYPOINT [“executable”,”param1”,”param2”]。

配置容器启动后的命令,可被docker run提供的--entrypoint参数覆盖。

每一个Dockerfile只能有一条ENTRYPOINT命令,若是指定多条,只有最后一条会执行。

3.容器内安装工具的方法

yum 或者apt-get

4.Dockerfile最佳实践

1 错误定位

每一个Dockerfile的指令能够生成新的一层镜像,若是经过Dockerfile建立镜像出错,能够根据出错所在步骤的上一层启动容器,而后手工执行出错层的命令,以达到调试目的。

2 好的使用习惯

一、使用缓存
Dockerfile的每条指令都会将结果提交为新的镜像,下一个指令将会基于上一步指令的镜像的基础上构建,若是一个镜像存在相同的父镜像和指令(除了ADD),Docker将会使用镜像而不是执行该指令,即缓存。

为了有效地利用缓存,你须要保持你的Dockerfile一致,而且尽可能在末尾修改。我全部的Dockerfile的前五行都是这样的:

FROM ubuntu
MAINTAINER Michael Crosby <michael@crosbymichael.com>
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y


更改MAINTAINER指令会使Docker强制执行RUN指令来更新apt,而不是使用缓存。

因此,咱们应该使用经常使用且不变的Dockerfile开始(译者注:上面的例子)指令来利用缓存。

二、使用标签
除非你正在用Docker作实验,不然你应当经过-t选项来docker build新的镜像以便于标记构建的镜像。一个简单的可读标签将帮助你管理每一个建立的镜像。

docker build -t="crosbymichael/sentry" .


注意,始终经过-t标记来构建镜像。

三、公开端口
两个Docker的核心概念是可重复和可移植。镜像应该能够运行在任何主机上而且运行尽量多的次数。在Dockerfile中你有能力映射私有和公有端口,可是你永远不要经过Dockerfile映射公有端口。经过映射公有端口到主机上,你将只能运行一个容器化应用程序实例。(译者注:运行多个端口不就冲突啦)

#private and public mapping
EXPOSE 80:8080

#private only
EXPOSE 80


若是镜像的使用者关心容器公有映射了哪一个公有端口,他们能够在运行镜像时经过-p参数设置,不然,Docker会自动为容器分配端口。

切勿在Dockerfile映射公有端口。

四、CMD与ENTRYPOINT的语法
CMD和ENTRYPOINT指令都很是简单,但它们都有一个隐藏的容易出错的“功能”,若是你不知道的话可能会在这里踩坑,这些指令支持两种不一样的语法。

CMD /bin/echo
#or
CMD ["/bin/echo"]


这看起来好像没什么问题,但仔细一看其实两种方式差距很大。若是你使用第二个语法:CMD(或ENTRYPOINT)是一个数组,它执行的命令彻底像你指望的那样。若是使用第一种语法,Docker会在你的命令前面加上/bin/sh -c,我记得一直都是这样。

若是你不知道Docker修改了CMD命令,在命令前加上/bin/sh -c可能会致使一些意想不到的问题以及难以理解的功能。所以,在使用这两个指令时你应当使用数组语法,由于数组语法会确切地执行你打算执行的命令。

使用CMD和ENTRYPOINT时,请务必使用数组语法。

五、CMD和ENTRYPOINT 结合使用更好
docker run命令中的参数都会传递给ENTRYPOINT指令,而不用担忧它被覆盖(跟CMD不一样)。当与CMD一块儿使用时ENTRYPOINT的表现会更好。让咱们来研究一下个人Rethinkdb Dockerfile,看看如何使用它。

#Dockerfile for Rethinkdb 
#http://www.rethinkdb.com/

FROM ubuntu

MAINTAINER Michael Crosby <michael@crosbymichael.com>

RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y

RUN apt-get install -y python-software-properties
RUN add-apt-repository ppa:rethinkdb/ppa
RUN apt-get update
RUN apt-get install -y rethinkdb

#Rethinkdb process
EXPOSE 28015
#Rethinkdb admin console
EXPOSE 8080

#Create the /rethinkdb_data dir structure
RUN /usr/bin/rethinkdb create

ENTRYPOINT ["/usr/bin/rethinkdb"]

CMD ["--help"]


这是Docker化Rethinkdb的全部配置文件。在开始咱们有标准的5行来确保基础镜像是最新的、端口的公开等。当ENTRYPOINT指令出现时,咱们知道每次运行该镜像,在docker run过程当中传递的全部参数将成为ENTRYPOINT(/usr/bin/rethinkdb)的参数。

在Dockerfile中我还设置了一个默认CMD参数--help。这样作是为了docker run期间若是没有参数的传递,rethinkdb将会给用户显示默认的帮助文档。这是你所指望的与rethinkdb交互相同的功能。

docker run crosbymichael/rethinkdb


输出

Running 'rethinkdb' will create a new data directory or use an existing one,
and serve as a RethinkDB cluster node.
File path options:
-d [ --directory ] path           specify directory to store data and metadata
--io-threads n                    how many simultaneous I/O operations can happen
                                at the same time

Machine name options:
-n [ --machine-name ] arg         the name for this machine (as will appear in
                                the metadata).  If not specified, it will be
                                randomly chosen from a short list of names.

Network options:
--bind {all | addr}               add the address of a local interface to listen
                                on when accepting connections; loopback
                                addresses are enabled by default
--cluster-port port               port for receiving connections from other nodes
--driver-port port                port for rethinkdb protocol client drivers
-o [ --port-offset ] offset       all ports used locally will have this value
                                added
-j [ --join ] host:port           host and port of a rethinkdb node to connect to
.................


如今,让咱们带上--bind all参数来运行容器。

docker run crosbymichael/rethinkdb --bind all


输出

info: Running rethinkdb 1.7.1-0ubuntu1~precise (GCC 4.6.3)...
info: Running on Linux 3.2.0-45-virtual x86_64
info: Loading data from directory /rethinkdb_data
warn: Could not turn off filesystem caching for database file: "/rethinkdb_data/metadata" (Is the file located on a filesystem that doesn't support direct I/O (e.g. some encrypted or journaled file systems)?) This can cause performance problems.
warn: Could not turn off filesystem caching for database file: "/rethinkdb_data/auth_metadata" (Is the file located on a filesystem that doesn't support direct I/O (e.g. some encrypted or journaled file systems)?) This can cause performance problems.
info: Listening for intracluster connections on port 29015
info: Listening for client driver connections on port 28015
info: Listening for administrative HTTP connections on port 8080
info: Listening on addresses: 127.0.0.1, 172.16.42.13
info: Server ready
info: Someone asked for the nonwhitelisted file /js/handlebars.runtime-1.0.0.beta.6.js, if this should be accessible add it to the whitelist.


就这样,一个全面的能够访问db和管理控制台的Rethinkdb实例就运行起来了,你能够用与镜像交互同样的方式来与其交互。虽然简单小巧但它的功能很是强大。

CMD和ENTRYPOINT 结合在一块儿使用更好。

我但愿这篇文章能够帮助你使用Dockerfiles以及构建镜像。Dockerfile是Docker的重要一部分,不管你是构建或是使用镜像,它都很是简单并且使用方便。我打算投入更多的时间来提供一个完整的、功能强大但简单的解决方案来使用Dockerfile构建Docker镜像。

一、不要开机初始化
容器模型是进程而不是机器。若是你认为你须要开机初始化,那么你就错了。

二、可信任构建
即便你不喜欢这个题目但它是很棒的一个功能。我把大部分 GitHub 仓库添加到可信任构建,所以当我提交一个新镜像以后不久,就在等待索引。另外,我没必要再建立单独的 Dockerfile 仓库与他人分享,它们都在同一个地方。

请记住,这不是你尝试新东西的试验场。在你推送以前,请在本地先构建一下。Docker 能够确保你在本地的构建和运行,与你推送到任何地方的构建和运行是同样的。本地开发和测试、提交和推送、以及等待索引上的官方镜像都是创建在可信任构建的基础之上的。

三、不要在构建中升级版本
更新将发生在基础镜像里,你不须要在你的容器内来apt-get upgrade更新。由于在隔离状况下,若是更新时试图修改 init 或改变容器内的设备,更新可能会常常失败。它还可能会产生不一致的镜像,由于你再也不有你的应用程序该如何运行以及包含在镜像中依赖的哪一种版本的正确源文件。

若是基础镜像须要安全更新,那么让上游的知道,让他们给你们更新,并确保你再次构建的一致性。

四、使用小型基础镜像
有些镜像比其余的更臃肿。我建议使用debian:jessie做为你的基础镜像。若是你熟悉Ubuntu,你将发现一个更轻量和巧妙的自制 debian,它足够小而且没有包含任何不须要的包。

五、使用特定的标签
对于你的基础镜像这是很是重要的。Dockerfile 中FROM应始终包含依赖的基础镜像的完整仓库名和标签。好比说FROM debian:jessie而不只仅是FROM debian。

六、常见指令组合
您的apt-get update应该与apt-get install组合。此外,你应该采起\的优点使用多行来进行安装。

#Dockerfile for https://index.docker.io/u/crosbymichael/python/ 
FROM debian:jessie

RUN apt-get update && apt-get install -y \
git \
libxml2-dev \
python \
build-essential \
make \
gcc \
python-dev \
locales \
python-pip

RUN dpkg-reconfigure locales && \
locale-gen C.UTF-8 && \
/usr/sbin/update-locale LANG=C.UTF-8

ENV LC_ALL C.UTF-8


谨记层和缓存都是不错的。不要惧怕过多的层,由于缓存是大救星。固然,你应当尽可能使用上游的包。

七、使用本身的基础镜像
我不是在谈论运行 debbootstrap 来制做本身的 debian。你不是 tianon(Tianon Gravi),没有人想要你认为别人须要你的 500mb 的狗屎垃圾基础镜像。我说的是,若是你要运行 python 应用程序须要有一个python基础镜像。前面示例中用于构建 crosbymichael/python 的 Dockerfile 也被用于其余不少构建 Python 应用程序的镜像。

FROM crosbymichael/python

RUN pip install butterfly
RUN echo "root\nroot\n" | passwd root

EXPOSE 9191
ENTRYPOINT ["butterfly.server.py"]
CMD ["--port=9191", "--host=0.0.0.0"]


另外一个:

FROM crosbymichael/python

RUN pip install --upgrade youtube_dl && mkdir /download
WORKDIR /download
ENTRYPOINT ["youtube-dl"]
CMD ["--help"]


正如你看到的,这使得使用你的基础镜像很是小,从而使你集中精力在应用程序上。

九 、持续系统集成了解下git

1.什么是持续集成?

持续集成(Continuous integration,简称CI)。

​ 根据敏捷大师Martin Fowler的定义,“持续集成是一种软件开发实践。在持续集成中,团队成员频繁集成他们的工做成果,通常每人天天至少集成一次,也能够屡次。每次集成会通过自动构建(包括自动测试)的检验,以尽快发现集成错误。许多团队发现这种方法能够显著减小集成引发的问题,并能够加快团队合做软件开发的速度。

为何要持续集成?

​ 1 快速发现错误:每完成一点更新,就集成到主干,能够快速发现错误,定位错误也比较容易。

​ 2 防止分支大幅偏离主干:若是不是常常集成,主干又在不断更新,会致使之后集成的难度变大,甚至难以集成。

下面是持续集成的图谱介绍:

​ 1 将更改提交到代码管理仓库

​ 2 持续集成服务器收到请求拉取变动代码

​ 3 持续集成服务器编译代码

​ 4 持续集成服务器跑代码相关测试

​ 5 持续集成服务器测试结束

​ 6 持续集成服务器对结果进行反馈Docker在持续集成中的做用:Docker提供代码编译、打包、测试的相关环境。

优点:

​ 1 环境能够是是任意版本

​ 2 节省空间

​ 3 环境相对隔离

2.什么是Git?

​ Git是一个开源的分布式版本控制系统,能够有效、高速的处理从很小到很是大的项目版本管理。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

Git经常使用命令:

1 初始化git项目

git init

2 查看当前项目状态

git status

3 新建文件并再次查看状态

echo “# My Project” > README.md

git status

4 记录当前操做,记录新加入的文件并再次查看状态

git add README.md

git status

5 记录当前更改并加以信息描述

git commit 文件名 -m ’add my first project’

6 查看提交历史

git log

7 新建远程仓库

git remote add origin https://github.com/limingios/git-test.git

8 同步到远程仓库

git push -u origin master

9 从远程代码库同步到本地

git pull origin master

10 与同步前对比变动

git diff HEAD

11 查看当前更改变动

git diff --staged

12 恢复到为更改状态

​ git reset README.md

13 覆盖本地文件

​ git checkout octocat.txt

14 新建分支

​ git branch feature1

15 切换分支

​ git checkout feature1

16 删除本地分支

​ git branch –d feature1

10、jenkins的使用

11、Github+Jenkins+Docker持续集成

相关文章
相关标签/搜索