Docker 是 Linux 虚拟化的一种封装,提供简单易用的容器使用接口。 它将应用程序与该程序的依赖,打包在一个文件里面。所以有了 Docker,就不用担心环境问题。
说到虚拟化,很容易想到虚拟器。Docker 和虚拟机有很大的区别,虚拟机一般是在系统上运行的另外一个系统,需要消耗大量的系统资源,而 Docker 可以理解为一个系统上的不同用户,他们都是运行的同一个系统上,性能消耗少,而且启动速度很快。
Linux 下安装
这里使用的 Centos7,Docker 要求 CentOS 系统的内核版本高于 3.10,如果你的内核版本过低需要升级内核才能支持 Docker
注意 OpenVZ 架构的 VPS 是不支持升级内核的,KVM 是支持的,或者使用云服务器。
more /etc/centos-release # 查看centos系统版本
uname -r # 查看内核版本
如果没有源的话导入下官方的源就行了,这里是官方的教程
# 卸载旧版本
yum -y remove docker docker-common docker-selinux docker-engine
yum update
# 安装
yum install docker
安装完毕输入docker version
查看是否安装完毕,分为客户端和服务端。
在安装 docker 时,默认的安装位置是/var/lib/docker
,后面下载的镜像也是在这个位置
如果提示 Cannot connect to the Docker daemon 表示服务端没启动,通过systemctl start docker
命令启动 docker
Client:
Version: 1.13.1
API version: 1.26
Package version: docker-1.13.1-91.git07f3374.el7.centos.x86_64
Go version: go1.10.3
Git commit: 07f3374/1.13.1
Built: Wed Feb 13 17:10:12 2019
OS/Arch: linux/amd64
Server:
Version: 1.13.1
API version: 1.26 (minimum version 1.12)
Package version: docker-1.13.1-91.git07f3374.el7.centos.x86_64
Go version: go1.10.3
Git commit: 07f3374/1.13.1
Built: Wed Feb 13 17:10:12 2019
OS/Arch: linux/amd64
Experimental: false
Windows 下安装
有两个 Docker for Windows 和 Docker Toolbox,二者的工作原理都是在虚拟机的 Linux 环境下安装 Docker
Docker for Windows 使用的是 Windows 自带的 Hyper-v 虚拟技术,因此对系统的要求是 Win10 专业版
Docker Toolbox 则使用的是 Virtualbox,如果本机已经安装过 Virtualbox 在安装过程中可以选择不安装 Virtualbox,
通过 docker-machine
命令,可以创建一个 运行 docker 的运行环境,通过docker-machine env
切换不同的 docker 环境。从这里也可以看到在 windows 上执行的 docker 命令其实是转发到 Linux 里面的(TCP)
注意 docker-machine 在创建虚拟机的过程中会去 Github 上下载最新的系统镜像,由于网路原因等待过程可能会很久,也可以自己手动去下载然后放到~/.docker/machine/cache/boot2docker.iso
。
# Docker安装目录下,在git-bash通过执行脚本创建
./start.sh
## 也可以手动创建运行环境
docker-machine create -d virtualbox default
docker-machine start default
docker-machine env default
docker-machine ls
docker-machine ssh default
创建完毕,docker info
若显示无法连接服务端,由于每次重启 IP 会变化,需要更新下 IP 到环境变量里面,再重启终端就好了
docker-machine restart default
docker-machine env default # 将default机器的连接IP写到环境变量
# 关闭终端重新进入刷新最新的环境变量,再次查看应该就成功了
docker info
Registry 仓库
docker 镜像托管和 git 仓库托管是很像的,对比 GitHub ,官方的镜像仓库是Docker Hub,拥有大量的高质量的官方镜像,当拉取镜像时,默认使用就是官方镜像。由于国内网络环境下载镜像很慢,可以通过配置仓库的镜像地址加速下载。如果临时加速的话可以 docker pull mirror.ccs.tencentyun.com/bitnami/etcd:3.4.14 && docker tag bitnami/etcd:3.4.14
Linux 环境下更改配置文件/etc/docker/daemon.json
{
"registry-mirrors": ["https://mirror.ccs.tencentyun.com", "https://dockerproxy.com", "https://hub-mirror.c.163.com"]
}
systemctl restart docker
docker info # Registry Mirrors
Windows 的 Docker Toolbox 环境下
docker-machine ssh default
sudo vi /var/lib/boot2docker/profile # linux 环境,
docker-machine stop
docker-machine start
修改内容,在 EXTRA_ARGS 参数下追加--registry-mirror
EXTRA_ARGS='
--label provider=virtualbox
--registry-mirror https://hub-mirror.c.163.com
--registry-mirror https://docker.mirrors.ustc.edu.cn
'
除了下载外,你也可以推送镜像到仓库,以阿里云的容器镜像服务为例
docker tag nginx registry.cn-hangzhou.aliyuncs.com/xxx/xxx:v1.0
docker login --username=177****@qq.com registry.cn-hangzhou.aliyuncs.com
docker push registry.cn-hangzhou.aliyuncs.com/xxx/xxx:v1.0
或者修改/etc/conf.d/docker
文件也可以达到目的
DOCKER_OPTS="-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375 --registry-mirror=https://hub-mirror.c.163.com"
image 相关命令
Docker 把应用程序及其依赖打包在 image 文件里面。
image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。
# 列出本地镜像
docker image ls
# 删除镜像,若改镜像已生成容器实例,需要把所有实例删除才可以删除镜像
docker image rm [imageName]
docker rmi
# 从远端下载镜像,比如从官方库下载hello-world项目docker image pull [域名/IP][:端口/][用户名/][项目名][:标签]
# 除了项目名外都有默认值,下面的两条命令是等价的
docker image pull docker.io/library/hello-world:latest
docker image pull hello-world
container 相关命令
image 文件生成的容器实例,本身也是一个文件,称为容器文件。
# 列出本机正在运行的容器,可以得到容器 ID 进行后继操作
docker container ls
# 列出本机所有容器,包括终止运行的容器
docker container ls --all
# 生成一个正在运行的容器实例,本地没有会自动执行 docker image pull
# 运行同一个镜像每次都会生成一个新的容器
# 如 docker container run hello-world,该应用运行完后会自动退出。有些容器不会自动终止,因为提供的是服务
# --name 自定义容器名字,否则是一个随机串
# --rm 容器停止后自动删除
# -d 开启 Daemon 模式,后台运行
# -p 端口映射,主机端口:容器端口
# -v 路径映射,两边必须都是绝对路径,模式 rw,ro 主机路径:容器路径[:模式],$PWD表示当前外部主机的目录
docker container run [imageName]
# 用来启动已经生成、已经停止运行的容器文件
docker container start/stop/restart [containerID]
# 删除容器实例,若在运行无法删除, 需要先stop
docker container rm [containerID]
# 强制终止容器运行,相当于向容器里面的主进程发出 SIGKILL 信号
docker container kill [containerID]
# 终止容器运行,相当于向容器里面的主进程发出 SIGTERM 信号,然后过一段时间再发出 SIGKILL 信号
# 应用程序收到 SIGTERM 信号以后,可以自行进行收尾清理工作。
docker container stop [containerID]
如果需要查看容器创建时的启动命令,可以使用 inspect,不过内容太多,可以使用runlike
docker container inspect 3186de74c6be
pip3 install runlike
runlike 3186de74c6be
其他命令
使用docker stats
命令可以方便的看出正在运行的容器的 CPU 占用等信息
使用docker search [imageName]
用于从镜像仓库搜索可用的镜像
使用docker cp
用于容器与主机之间的数据拷贝;
如docker cp /www/site01 96f7f14e99ab:/www/
将 site01 目录的内容拷贝到 ID 为 96f7f14e99ab 的容器中
使用docker search [imageName]
从镜像仓库搜索镜像
使用docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
可以运行容器中的脚本,前提是容器正在运行;
它有 3 个参数可选-d :分离模式: 在后台运行
,-i :即使没有附加也保持STDIN 打开
,-t :分配一个伪终端
;
比如docker exec -it 8b57a62e9e1f bash
实际上是/bin/bash
可以进入容器中中断,并可以进行交互。
默认一些常用软件是没有的,想要安装额外的软件可以:
apt-get update
apt-get install vi
apt-get install telnet
# ifconfig
apt-get install net-tools
比如docker exec 8b57a62e9e1f env
可以查看容器的环境变量
使用docker inspect [conatiner]
查看改容器的更多详细信息,比如 IPAddress 字段表示容器的 IP 地址
[root@localhost ~]# docker exec app01-mysql env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=6faa0da5db0c
MYSQL_ROOT_PASSWORD=123456
GOSU_VERSION=1.7
MYSQL_MAJOR=8.0
MYSQL_VERSION=8.0.15-1debian9
HOME=/root
安装 tomcat
# 下载镜像到本地
docker pull tomcat
# 后台运行
# 自定义名字
# 端口映射
# 路径映射
docker container run -d --name app01 -p 80:8080 -v /home/app01:/usr/local/tomcat/webapps/app01 tomcat
# 上传代码到/home/app01
# 重启应用
docker container restart app01
# 访问http://127.0.0.1:80/index.jsp
安装 mysql
# 使用命令搜寻镜像
docker search mysql
docker pull mysql
# MYSQL_DATABASE=testdb 同时创建一个testdb的数据库
docker run --name app02 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=testdb -d mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
设置外部访问权限
docker exec -it app02 /bin/bash
mysql -u root -p
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
FLUSH PRIVILEGES;
容器之间通信
启动 docker 时,docker 进程会创建一个名为 docker0 的虚拟网桥,用于宿主机与容器之间的通信。当启动一个 docker 容器时,docker 容器将会附加到虚拟网桥上,容器内的报文通过 docker0 向外转发。
docker inspect app01
docker inspect app01
# 宿主机通过ifconfig查看网络
多个容器之间通过 IP 通信,缺点是容器重启后自己的 IP 会改变,link 机智很好的解决了这个问题,且可以安全的传递一些连接信息给其它的容器
删除之前创建的容器
docker container stop app01 app02
docker container rm app01 app02
# 创建mysql容器命名为app02
docker run --name app02 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=testdb -d mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
# 创建tomcat容器命名为app01,并链接到app02
docker container run -d --name app01 -p 80:8080 --link app02:app01db -v /home/app01:/usr/local/tomcat/webapps/app01 tomcat
# 进入tomcat容器
docker exec -it app01 bash
# 查看系统变量,可以看到mysql容器内的一些变量
env
# 测试连通
# 64 bytes from app01db (172.17.0.2): icmp_seq=1 ttl=64 time=0.949 ms
ping app01db
telnet app01db 3306
Java 代码测试数据库
String JDBC_DRIVER = "com.mysql.jdbc.Driver";
String DB_URL = "jdbc:mysql://app01db:3306/testdb";
String USER = "root";
String PASS = "123456";
如果报错Unable to load authentication plugin 'caching_sha2_password'
表示 mysql 版本太高,jdbc 太低,问题不大,百度即可解决。但是说明已经可以访问到数据库了。
Docker Compose 工具
综上,容器之间通信,命令行提供容器之间的连接信息不便于管理。
Docker 公司推出了 Docker Compose,可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的 compose 配置文件。默认是 docker-compose.xml,或者使用-f 命令指定配置文件
安装
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
新建 docker-compose.yml 文件,写入下面的内容
app02:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=testdb
app01:
image: tomcat
links:
- app02:app01db
ports:
- 80:8080
volumes:
- /home/app01:/usr/local/tomcat/webapps/app01
docker-compose up
启动,或者docker-compose up -d
在后台运行
docker-compose ps
产看正在运行的容器
Name Command State Ports
-------------------------------------------------------------------------
root_app01_1 catalina.sh run Up 0.0.0.0:80->8080/tcp
root_app02_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
基本的使用就是这样…
自定义镜像
有两种方式创建属于自己的镜像
-
根据 container 生成镜像
进入到一个运行的容器中,比如执行一些操作如安装软件,然后再提交改变生成镜像
docker container exec -it 1a548378cf20 sh touch demo.txt exit docker container stop 1a548378cf20 # docker container diff 1a548378cf20 docker commit -m "install app" 1a548378cf20 customer-image:v1.0.1 docker image ls # docker push customer-image:v1.0.1 # docker run -p 10086:80 -d customer-image:v1.0.1
-
通过 Dockerfile 来生成自定义镜像
注意,每次的 RUN/COPY 等操作都会生成一层,为了镜像的大小可以吧多个 RUN 的命令合并成一个
FROM openjdk:8 # RUN mkdir -p /work COPY ./demo.jar /work/demo.jar WORKDIR /work CMD [ "java", "-jar", "demo.jar" ] EXPOSE 80
生成镜像,注意所处的目录不要有多余的文件,因为会把当前目录临时拷贝到容器内
docker image build -t spring:v1.0.0 .
注意
在 Docker Toolbox 环境下,容器绑定宿主机端口后并不能通过 127.0.0.1,因为在 Docker Toolbox 环境下宿主机是虚拟机, 应使用docker-machine ip default
去访问