关注“Java艺术”一起来充电吧!
docker
容器化部署应用可以简化应用的部署流程。假设部署一个应用需要在机器上安装和配置nginx
、tomcat
,如果需要新增一台服务器,或者切换服务器,那么就要重复同样的操作,安装nginx
、tomcat
并配置。容器化部署就是一次配置到处使用,将安装nginx
配置nginx
这一系列工作制作成一个镜像,在服务器上通过docker
拉取镜像并启动容器即可,基于此实现集群自动伸缩。
docker
入门简单,用好难,特别是制作镜像。随便做一个镜像就是1g
大小,这该怎么用。如果每次部署都要拉1g
的镜像,想想都可怕。如果在Dockerfile
中使用yum
安装一些软件,build
的时间会很长,加上镜像太大,传输也耗时。应尽量使用安装包安装替换yum
安装,以及使用尽量小的基础镜像。
使用Dockerfile
构建镜像,我们可以理解为,docker
基于Dockerfile
中的FROM
基础镜像,启动了一个容器,然后在容器中执行Dockerfile
中定义的脚本,执行完成后再打包成镜像。
docker
的镜像是分层的,你可以先定制一个基础镜像,再通过基础镜像去实现差异化定制。比如部署一个java
项目,每台机制都需要jdk
,但并不是每台机器都需要安装nginx
,那么就可以先制作一个jdk
基础镜像。当然,制作jdk
基础镜像也是基于更底层的基础镜像,比如centos
。然后再基于jdk基础镜像制作nginx镜像,再制作应用镜像。制作应用镜像如果需要用到nginx
就可以基于nginx
镜像,不需要依赖nginx
的就可以直接基于jdk
镜像。
docker
的命令不需要记,动动手去试一试就记住了,记不住可以使用docker -help
查看命令。新版本docker
将命令规范了,如docker image
是镜像相关的,docker container
是容器相关的,同样,也可以使用docker container -help
来查看命令帮助。
Docker的端口、网络与容器卷
学习doker
除了镜像制作之外,还需要理解这三点:端口映射、网络模式、容器卷(volume
)。
将宿主机端口映射到容器的端口,外部通过访问宿主机端口从而访问容器内应用。如容器中redis使用的端口是6379
,可以将宿主机的10880
端口与容器的6379
端口映射,外部通过宿主机ip
和10880
端口访问容器中的redis
。
### 使用镜像运行容器
### -p 10880:6379 将宿主机10880端口映射到容器6379端口
[root@wujiuye01 redis-app]# docker container run -itd --name simple-redis \
-p 10880:6379 wujiuye/simple-redis:5.0.7
05676da445839b1f4a1995148b4656d029721503a16d67edad37956fe7ea9f3a
### 宿主机访问容器中的redis
[root@wujiuye01 redis-app]# /root/redis/redis-5.0.5/src/redis-cli -p 10880
127.0.0.1:10880>
docker
支持5
种网络模式,这里不做详细分析,因为我不是很了解。在启动容器时,可以指定使用哪种网络模式:docker container run --network [网络模式]
。
bridge
: 默认使用,docket
启动后默认创建一个docker0
网桥,默认创建的容器也是添加到这个网桥中。
host
: 容器不会获得一个独立的network namespace
,而是与宿主机共用一个。
volume
)应用部署在一台服务器上运行会产生日记,不能随着容器的删除而导致日记被删除,所以需要将容器中的工作目录与宿主机的目录映射。或者说mysql
容器,容器移除而数据库文件不能删除。docker
为我们提供了三种不同的方式将容器卷或宿主机目录从宿主机挂载到容器中:volume
、bind mount
、tmpfs
。
docker
管理宿主文件系统的一部分(/var/lib/docker/volumes/容器id
)
创建容器卷:docker volume create test-vol
查看容器卷:docker volume inspect test-vol
将容器卷挂载到容器的目录:docker container run -itd --name test --mount src=test-vol,dst=/data/apps/test wujiuye/test:1.0.0
--mount src=test-vol,dst=/data/apps/test
: 将容器卷挂载到容器的/data/apps/test
目录。
将文件放到容器的/data/apps/test
目录下,可以在宿主机的/var/lib/docker/volumes/test-vol
目录看到,反过来也是一样的。如果不指定--mount
,默认也是使用volumes
,并且容器卷的名称就是容器id
,也是在/var/lib/docker/volume/目录下。
### 创建容器卷
[root@wujiuye01 docker]# docker volume create test-vol
test-vol
### 查看容器卷信息
[root@wujiuye01 docker]# docker volume inspect test-vol
[
{
"CreatedAt": "2020-01-04T17:57:08+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/test-vol/_data",
"Name": "test-vol",
"Options": {},
"Scope": "local"
}
]
### 将容器卷挂载到容器
[root@wujiuye01 docker]# docker container run -itd --name test \
--mount src=test-vol,dst=/data/apps/test wujiuye/test:1.0.0
可以存储在宿主机系统的任意目录,宿主机的目录必须存在。如果宿主机新增磁盘是挂载在/data
目录的,建议使用这种。如使用aws
的ec2
实例。
docker container run -itd --name test --mount type=bind,src=宿主机目录,dst=容器目录 wujiuye/test:1.0.0
将指定的宿主机目录挂载到容器的指定目录。将文件放到<容器指定目录>
下,可以在<宿主机指定目录>
看到,反过来也是一样的。
挂载存储在宿主机系统的内存中,不会写入宿主机的文件系统
Docker的安装与启动
# 较旧的 Docker 版本称为 docker 或 docker-engine 。如果已安装这些程序,请卸载它们以及相关的依赖项。
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 安装所需的软件包。yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data 和 lvm2
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
# 设置稳定的仓库。
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 安装最新版本的 Docker Engine-Community 和 containerd
sudo yum install docker-ce docker-ce-cli containerd.io
## 停止
sudo systemctl stop docker
## 启动
sudo systemctl start docker
Docker使用简单事例
准备redis
安装包和配置文件,新建一个Dockerfile
文件,目录结构如下:
-rw-r--r-- 1 root root 583 Jan 4 18:56 Dockerfile
-rw-r--r-- 1 root root 1984203 Jan 4 18:52 redis-5.0.7.tar.gz
-rw-r--r-- 1 root root 61797 Jan 4 18:52 redis.conf
编写Dockerfile
文件,基于centos:7
镜像
FROM centos:7
MAINTAINER wujiuye
# 使用ps 命令 :ps -ef|grep redis
RUN yum install -y procps
# redis安装包和配置文件
ADD redis-5.0.7.tar.gz /usr/local/redis/
COPY redis.conf /usr/local/redis/local-redis.conf
# 安装gcc
RUN yum install gcc -y
# 安装make
RUN yum install make -y
# 编译redis
RUN cd /usr/local/redis/redis-5.0.7 && \
make
RUN yum clean all
EXPOSE 6379
# 启动redis
ENTRYPOINT /usr/local/redis/redis-5.0.7/src/redis-server
CMD ["/usr/local/redis/local-redis.conf"]
1、COPY
、ADD
命令的src
只能使用相对路径,需要将文件拷贝到Dockerfile
的同级目录下
2、不要将redis
安装包与redis
配置文件COPY
或ADD
到容器的挂载目录下,否则因宿主机的源目录下没有这些文件,容器启动起来就找不到这些文件。构建镜像时将文件放在容器的/data/apps/
目录下,而启动容器时配置宿主机目录挂载到容器的/data/apps/
,docker
会将镜像中原有的/data/apps/
目录移除,才可以挂载。
3、RUM
运行多条命令可使用&&
符号连接,也可以写多个RUN
### 目录下的文件
[root@wujiuye01 redis-app]# ls
Dockerfile redis-5.0.7.tar.gz redis.conf
### 构建镜像
[root@wujiuye01 redis-app]# docker image build --tag wujiuye/simple-redis:5.0.7 .
....
Successfully built 2aab79854763
Successfully tagged wujiuye/simple-redis:5.0.7
--tag
打标签,最后的‘.’
是Dockerfile
文件所在的位置。
docker container run \
--rm -itd \
--ulimit nofile=102400:102400 \
--name=simple-redis \
-p 10880:6379 \ # 可写多个
--mount type=bind,src=/data/redis-app/,dst=/usr/local/redis \
wujiuye/simple-redis:5.0.7
--rm
: 如果容器存在则删除,只是移除容器,正在运行的容器不会停止
--name=simple-redis
: 给容器取一个名字
-itd
: -i
、-t
、-d
的结合
--ulimit nofile=102400:102400
设置ulimit
-p 10880:6379
宿主机与容器的端口映射
--mount type=bind,src=...,dst=...
文件系统为bind mount
,src
为宿主机的目录,dst
为容器中的目录
[root@wujiuye01 redis-app]# docker container ls
### 容器id 使用的镜像 容器执行的命令 创建时间 容器状态 端口信息 容器名称
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
05676da44583 wujiuye/simple-redis:5.0.7 "/bin/sh -c /usr/loc…" 6 minutes ago Up 6 minutes 0.0.0.0:10880->6379/tcp simple-redis
在测试完镜像可用之后,可以选择push到远程仓库,也可自己搭建一个镜像仓库。
1)、注册hub.docker.com
账号,id
不要随便填写,如:wujiuye
2)、创建一个仓库,如:wujiuye/simple-redis
3)、如果需要,将本地的镜像打标签,对应到远程仓库,如:docker tag local/test-redis:1.0.5 wujiuye/simple-redis:5.0.7
。本地镜像与远程仓库镜像标签不同时使用。
4)、docker login
输入用户名密码登陆
5)、docker push wujiuye/simple-redis:5.0.7
推送镜像至远程仓库
[root@wujiuye01 redis-app]# docker push wujiuye/simple-redis:5.0.7
The push refers to repository [docker.io/wujiuye/simple-redis]
dafbadcc43aa: Pushing [==> ] 1.281MB/23.62MB
879a0e8874ba: Pushing [=============================> ] 66.96MB/111.8MB
ccc522a455bc: Pushing [> ] 549.9kB/100.2MB
879a0e8874ba: Pushing [================================> ] 73.04MB/111.8MB
ccc522a455bc: Pushing [> ] 1.107MB/100.2MB
ff7b8add839d: Pushing [=================> ] 51.75MB/146.8MB
dca066a10cae: Pushing [> ] 557.1kB/100.8MB
77b174a6a187: Waiting
容器停止
1)、docker kill [容器名]
可选参数:
--signal: 发送信号量
2)、docker stop []
删除容器和镜像
1)、删除所有镜像:docker rmi $(docker images -q)
2)、删除所有容器:
1)、先停止所有容器:docker stop $(docker ps -a -q)
2)、删除所有容器:docker rm $(docker ps -a -q)
删除某个镜像:
1)、docker image rm [repository,如:wujiuye/simple-redis:5.0.7]
2)、docker image rm [镜像id]
删除某个容器:
docker container rm [容器名称 或 容器id]
公众号:Java艺术
扫码关注最新动态