TMaize Blog

Docker的使用

Docker 是 Linux 虚拟化的一种封装,提供简单易用的容器使用接口。 它将应用程序与该程序的依赖,打包在一个文件里面。所以有了 Docker,就不用担心环境问题。

说到虚拟化,很容易想到虚拟器。Docker 和虚拟机有很大的区别,虚拟机一般是在系统上运行的另外一个系统,需要消耗大量的系统资源,而 Docker 可以理解为一个系统上的不同用户,他们都是运行的同一个系统上,性能消耗少,而且启动速度很快。

有点像网吧公用一台主机,然后每台机器都有自己的局域网 ip 和操作系统

升级内核

注意 OpenVZ 架构的 VPS 是不支持升级内核的,KVM 是支持的,或者使用云服务器。

Docker 要求 CentOS 系统的内核版本高于 3.10,如果你的内核版本过低需要升级内核才能支持 Docker

more /etc/centos-release # 查看centos系统版本
uname -r # 查看内核版本

升级内核,我直接安装就成功了。不行的话去网上找下教程

yum install kernel

安装 Docker

安装失败的话导入下官方的源就行了,这里是官方的教程

# 卸载旧版本
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

image 相关命令

Docker 把应用程序及其依赖打包在 image 文件里面。

image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。

# 列出本地镜像
docker image ls

# 删除镜像,若改镜像已生成容器实例,需要把所有实例删除才可以删除镜像
docker image rm [imageName]

# 从远端下载镜像,比如从官方库下载hello-world项目docker image pull library/hello-world
docker image pull [path]

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]

其他命令

使用docker stats命令可以方便的看出正在运行的容器的 CPU 占用等信息

docker-stats

使用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

使用官方镜像仓库

Docker 官方的镜像仓库是docker hub,如果速度慢可以使用国内的阿里云的镜像仓库

安装 tomcat

image-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

基本的使用就是这样…

自定义镜像

还可以自己编写 Dockerfile 来生成自定义镜像

mkdir app
cd app
cp -r /home/app01 .
touch Dockerfile

编写 Dockerfile,这样就把我们的 app01 变成了一个镜像文件。

关于 mysql,我们可以FROM centos从零下载安装 Java,tomcat,mysql,然后形成一个 tomcat-mysql-app01 的镜像文件,这种目前水平写不出来

FROM tomcat
COPY ./app01 /usr/local/tomcat/webapps/app01
EXPOSE 8080

构建 imagedocker image build -t tomcat-with-app01 .

运行镜像docker container run -p 80:8080 tomcat-with-app01

参考

Docker 官方文档

docker hub

阮一峰 - Docker 入门教程

阮一峰 - Docker 微服务教程

菜鸟教程 - Docker 命令大全