今天来说下docker,docker是一个开源的应用容器引擎,可以让开发者打包应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上。
Docker简介
什么是docker
docker是一个用Go语言实现的开源项目,可以将程序以及依赖打包,这样你的程序就可以在任何环境下都有一致的表现,不必再为环境问题而头疼。
说到docker不得不提到容器,港口的集装箱大家都知道,其实容器和集装箱概念上很相似,集装箱相互隔离可以长期使用,能快速装载和卸载,容器也具有这些特点。那么我们在容器中运行程序,也就能够达到隔离、多次使用和快速部署的目的。
docker在容器的基础上进行了进一步的封装,从文件系统和网络互联到进程隔离等,简化了容器的创建和维护,这就是docker受欢迎的原因。
docker的优势
可以更高效的利用系统资源、更快速的启动时间、一致的运行环境、持续交付和部署、更轻松的迁移、更轻松的维护和扩展。
与传统虚拟机的比较
特性 | docker | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为MB | 一般为GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
隔离性 | 安全隔离 | 完全隔离 |
如上表可以看到,虚拟机的创建需要占用很多的资源,而这些资源很大一部分浪费在了无用的操作系统上。反观docker,它对资源的占用极少,只部署应用不必浪费资源在无用的操作系统上,正是如此docker可以在秒级启动。
CentOS上安装Docker
docker目前支持centos7及以后的版本,内核版本必须为3.10。
卸载旧版本docker
没安装过可不用执行下面的命令。
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装docker
使用脚本安装出错不易排查,这里使用手动安装的方式。
- 依次输入如下命令进行安装。
# 查看操作系统版本
cat /etc/redhat-release
# 查看内核版本
uname -r
# 安装依赖的软件包
sudo yum install -y gcc gcc-c++ yum-utils device-mapper-persistent-data lvm2
# 配置国内比较快的阿里云yum源
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo(国外服务器用)
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新yum软件包索引
sudo yum makecache fast
# 安装最新版本的docker引擎(社区版)
sudo yum -y install docker-ce docker-ce-cli containerd.io
- 启动docker服务并设置开机自启。
sudo systemctl start docker
# 设置docker开机自启
systemctl enable docker
- 验证docker是否安装成功。
sudo docker run hello-world # 若出现Hello from Docker!则docker安装成功
- 将普通用户添加到docker组
# 将普通用户添加到docker组,避免每次都添加sudo
sudo usermod -aG docker Robofly
-
配置国内镜像源地址来加快拉取镜像的速度。
新建json文件并添加相应的镜像源地址信息(注意将阿里云的地址替换成自己的地址,阿里云容器服务的申请步骤在后面的注)
vim /etc/docker/daemon.json
{
"registry-mirrors": [
//网易镜像加速地址
"http://hub-mirror.c.163.com",
//中国科技大学镜像加速地址
"https://docker.mirrors.ustc.edu.cn",
//阿里云镜像加速地址
"https://xxxxxxxx.mirror.aliyuncs.com"
]
}
- 使用
systemctl daemon-reload
systemctl restart docker
重启docker。 - 输入
docker info
查看镜像是否配置成功,如下显示即为配置成功。
注:申请阿里云的需要先注册一个自己的阿里云账户,然后登录阿里云搜索容器镜像服务,点击镜像工具选择镜像加速器,申请自己的加速器地址即可。
Docker常用操作
镜像
docker镜像类似于一个虚拟机镜像,可以将它理解为一个只读的模板。镜像是创建容器的基础。
镜像的基础操作
- 列出本机镜像:
docker images
- 获取一个新镜像:
docker pull 镜像名
直接加镜像名会拉取最新的,最新的不稳定,一般先去 官网 搜索相应版本的镜像,复制命令进行拉取。 - 搜索镜像:
docker search 镜像名
在官网搜索效果更好。 - 删除镜像。
docker rmi 镜像id
如果显示不能删一个被容器使用的镜像,此时可以先删掉容器再删镜像docker ps -a
查看所有容器(运行中和停止的容器都有,docker ps
只能查看运行中的容器)docker rm 容器id
删除容器;docker rmi 镜像id
删除镜像成功- 也可以用
docker rmi 镜像名:TAG
镜像名加版本号删除
- 清理镜像:
docker image prune -f
镜像的高级操作
-
创建镜像。
基于已有容器创建:
docker commit -m '注释' -a '作者' 容器id 镜像名:版本号
基于dockerfile创建(最常用的方式):Dockerfile是一个文本文件,是利用给定的指令来描述基于某个父镜像创建新镜像的过程。
创建支持JDK的镜像步骤:
- 在机器中新建一个目录,目录中放入jdk安装包,并新建一个文件名为Dockerfile的文件添加以下内容:
# 每一条指令都会在镜像上创建新的层,每一个指令的前缀都必须是大写的
FROM centos:centos7.5.1804 # 指定使用那个镜像源
RUN mkdir -p /opt/package # 告诉docker在镜像内执行命令
RUN mkdir -p /opt/programfiles
COPY jdk-8u301-linux-x64.tar.gz /opt/package/ # 把文件copy到镜像中,源文件必须是相对路径不能是绝对路径
RUN tar -zxvf /opt/package/jdk-8u301-linux-x64.tar.gz -C /opt/programfiles
ENV JAVA_HOME=/opt/programfiles/jdk1.8.0_301 # 在镜像中设置环境变量
ENV PATH=$JAVA_HOME/bin:$PATH
RUN rm -rf /opt/package/jdk-8u301-linux-x64.tar.gz
- 创建镜像,并等待创建成功。
docker build -t centos_java8:1.0 . # -t指明镜像名字和标签,.表示Dockerfile所在目录
- 保存镜像和加载镜像。
docker save -o 文件名.tar 镜像名:版本号
保存镜像,保存后可以发给他人使用docker load -i 文件名.tar
加载导入他人的镜像
- 镜像添加ssh服务。
- 创建文件
vim Dockerfile
,并添加以下内容:
# 设置继承镜像
FROM centos_java8:1.0
# 提供者信息
Robofly (donggaofei888@163.com)
# 更换国内阿里云yum源
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
RUN yum makecache
# 安装sshd
RUN yum install -y openssh-server openssh-clients
RUN sed -i '/^HostKey/'d /etc/ssh/sshd_config
RUN echo 'HostKey /etc/ssh/ssh_host_rsa_key'>>/etc/ssh/sshd_config
# 生成 ssh-key
RUN ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key
# 更改 root 用户登录密码为
RUN echo 'root:123456' | chpasswd
# 开放 22 端口
EXPOSE 22
# 镜像运行时启动sshd
RUN mkdir -p /opt
RUN echo '#!/bin/bash' >> /opt/run.sh
RUN echo '/usr/sbin/sshd -D' >> /opt/run.sh
RUN chmod +x /opt/run.sh
CMD ["/opt/run.sh"]
- 创建镜像,并等待创建成功。
docker build -t centos_java8_sshd:1.0 ./
- 运行容器测试镜像
# 把容器的22端口映射到宿主机的2222端口, 通过ssh连接宿主机器的2222端口就可以连接到容器
docker run -d -p 2222:22 centos_java8_sshd:1.0
容器
docker容器类似于一个轻量级的沙箱,docker利用容器可以来运行和隔离应用。容器是从镜像创建的应用实例,容器彼此之间是相互隔离的。
容器的基础操作
- 创建容器。
docker pull centos:centos7.5.1804
拉取指定版本的镜像(此处用centos镜像为例)docker images
查看拉取的镜像docker create -it centos:centos7.5.1804(或者用镜像id) /bin/bash
创建容器(i表示将来可以在容器中进行标准输入,t表示终端,/bin/bash表示启动容器时会自动启动一个bash shell来进行交互)docker start 容器id
启动容器,此时status会显示容器运行时长
- 停止容器。
exit
在容器中输入会退出容器docker stop 容器id
关闭容器
- 进入容器:
docker exec -it 容器id /bin/bash
指明bash是为了不让容器停止,此时的bash表示进入容器后用bash交互。 - 删除容器。
docker rm 容器id
删除容器docker rm 容器id -f
强制删除容器
- 导入导出容器
docker import 文件名 -- 镜像名
容器导入时会成为镜像,故导入时设的是镜像名docker export -o 导出的路径和文件名.tar 容器id
导出
- 查看容器:
docker container inspect 容器id
查看容器详情。 - 容器和主机之间复制文件。
docker cp 文件路径加文件名 容器id:路径
复制主机文件到容器内。docker cp 容器id:文件路径加文件名 主机路径
复制容器内文件到主机。
容器的高级操作
- 端口映射。
# 使用-p来指定映射规则,使用多次-p可以映射多个端口
docker run -d -p 2222:22 -p 8888:80 centos_java8_sshd:1.0
# 查看容器端口绑定情况
docker port 容器id
-
容器互联。
端口映射并不是唯一把docker连接到另一个容器的方法。
- 容器命名
# 创建容器的时候docker会自动分配一个随机的容器名,不过可以在创建容器的时候指定容器名
docker run -d --name node1 centos_java8_sshd:1.0
# --name 参数:指定容器名
-
docker的网络
docker会创建三个网络:bridge/host/none,可以通过network ls命令查看宿主机中所有的网络,其中bridge网桥模式在实际项目中常用。以交互模式启动两个容器,在没有指定网络的情况下,容器会连接到默认的bridge网络。此时宿主机和容器之间是可以互相访问到的,但每次启动容器的时候IP地址会变化。
-
自定义bridge网络,实现容器间通信
docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过容器名进行通信。
# 创建自定义bridge网络,网络名net1
docker network create --driver bridge net1
# 删除上步使用过的容器
docker rm -f node1
docker rm -f node2
# 新建并启动node1和node2容器,加入net1网络
docker run -d --name node1 --network net1 centos_java8_sshd:1.0
docker run -d --name node2 --network net1 centos_java8_sshd:1.0
# 进入node1看是否能ping通node2
ssh root@node1ip
ping node2ip
-
桥接网络直连容器。
用pipework工具让容器采用桥接模式与node1处于同一网段可以实现直连容器。
- 安装
# 在node1上安装git
sudo yum install -y git
# 下载pipework
git clone https://github.com/jpetazzo/pipework.git
# 把pipework脚本添加到path中
sudo cp pipework/pipework /usr/bin/
# 安装brctl工具
sudo yum install bridge-utils
-
配置
删除原来的容器node1和node2
# 删除所有容器, 慎用
docker rm -f $(docker ps -aq)
在宿主机上实现桥接网络
# 我的宿主机网络信息
IPADDR=192.168.1.102 # IP地址(网卡:ens33)
GATEWAY=192.168.1.2 # 网关
DNS1=114.114.114.114 # 域名解析器
# 在宿主机(hadoop102)上执行如下命令,必须作为一条命令一次执行
sudo brctl addbr br0; \ # 添加网桥br0
sudo ip link set dev br0 up; \ # 启动网桥br0
sudo ip addr del 192.168.1.102/24 dev ens33 ; \ # 给ens33去掉ip
sudo ip addr add 192.168.1.102/24 dev br0 ; \ # 给网桥分配ip(使用刚才ens33去掉的ip)
sudo brctl addif br0 ens33 ; \ # 把ens33搭在br0上
sudo ip route add default via 192.168.1.2 dev br0 # 给br0添加新路由(根据虚拟机网关指定)
创建两个容器
docker run -d --name node11 centos_java8_sshd:1.0
docker run -d --name node12 centos_java8_sshd:1.0
给两个容器添加IP并搭到br0上
sudo pipework br0 node11 192.168.1.202/24@192.168.1.2
sudo pipework br0 node12 192.168.1.203/24@192.168.1.2
# br0:网桥名;node11:容器名;192.168.1.202/24:容器IP,24指掩码;192.168.1.2:网关地址
- 测试
# 进入node11去ping另一个容器和window来测试网络
ssh root@192.168.1.202
# 用ssh软件直连容器测试
-
脚本
上面的配置都是临时生效,重启后需要重新配置,这里写个脚本统一执行。
vim /home/dgf/bin/docker.sh
# 启动容器
docker start node11
docker start node22
# 搭建网桥
sudo brctl addbr br0; \
sudo ip link set dev br0 up; \
sudo ip addr del 192.168.1.102/24 dev ens33 ; \
sudo ip addr add 192.168.1.102/24 dev br0 ; \
sudo brctl addif br0 ens33 ; \
sudo ip route add default via 192.168.1.2 dev br0
# 等网桥配置完成
sleep 5
# 给容器配置ip和网关
sudo pipework br0 node11 192.168.1.202/24@192.168.1.2
sudo pipework br0 node22 192.168.1.203/24@192.168.1.2
最后,大数据场景下集群中的节点不可能一个个的进行安装配置,这时可以考虑使用docker来搭建,通过自定义Dockerfile文件可以实现轻松部署集群。今天就不讨论部署集群时Dockerfile文件的编写了,以后有机会再更新docker部署大数据集群的内容。
今天的内容就到这里,喜欢的话点个关注吧!