Docker快速上手教程

494 阅读11分钟

今天来说下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

使用脚本安装出错不易排查,这里使用手动安装的方式。

  1. 依次输入如下命令进行安装。
# 查看操作系统版本
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
  1. 启动docker服务并设置开机自启。
sudo systemctl start docker
# 设置docker开机自启
systemctl enable docker
  1. 验证docker是否安装成功。
sudo docker run hello-world # 若出现Hello from Docker!则docker安装成功
  1. 将普通用户添加到docker组
# 将普通用户添加到docker组,避免每次都添加sudo
sudo usermod -aG docker Robofly
  1. 配置国内镜像源地址来加快拉取镜像的速度。

    新建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"
                        ]
}
  1. 使用systemctl daemon-reload systemctl restart docker重启docker。
  2. 输入docker info查看镜像是否配置成功,如下显示即为配置成功。

:申请阿里云的需要先注册一个自己的阿里云账户,然后登录阿里云搜索容器镜像服务,点击镜像工具选择镜像加速器,申请自己的加速器地址即可。

Docker常用操作

镜像

docker镜像类似于一个虚拟机镜像,可以将它理解为一个只读的模板。镜像是创建容器的基础。

镜像的基础操作

  1. 列出本机镜像:docker images
  2. 获取一个新镜像:docker pull 镜像名 直接加镜像名会拉取最新的,最新的不稳定,一般先去 官网 搜索相应版本的镜像,复制命令进行拉取。
  3. 搜索镜像:docker search 镜像名 在官网搜索效果更好。
  4. 删除镜像。
    • docker rmi 镜像id如果显示不能删一个被容器使用的镜像,此时可以先删掉容器再删镜像
    • docker ps -a查看所有容器(运行中和停止的容器都有,docker ps只能查看运行中的容器)
    • docker rm 容器id删除容器;docker rmi 镜像id删除镜像成功
    • 也可以用docker rmi 镜像名:TAG镜像名加版本号删除
  5. 清理镜像:docker image prune -f

镜像的高级操作

  1. 创建镜像。

    基于已有容器创建: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所在目录
  1. 保存镜像和加载镜像。
    • docker save -o 文件名.tar 镜像名:版本号保存镜像,保存后可以发给他人使用
    • docker load -i 文件名.tar加载导入他人的镜像
  2. 镜像添加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利用容器可以来运行和隔离应用。容器是从镜像创建的应用实例,容器彼此之间是相互隔离的。

容器的基础操作

  1. 创建容器。
    • 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会显示容器运行时长
  2. 停止容器。
    • exit在容器中输入会退出容器
    • docker stop 容器id关闭容器
  3. 进入容器:docker exec -it 容器id /bin/bash指明bash是为了不让容器停止,此时的bash表示进入容器后用bash交互。
  4. 删除容器。
    • docker rm 容器id删除容器
    • docker rm 容器id -f强制删除容器
  5. 导入导出容器
    • docker import 文件名 -- 镜像名容器导入时会成为镜像,故导入时设的是镜像名
    • docker export -o 导出的路径和文件名.tar 容器id导出
  6. 查看容器:docker container inspect 容器id查看容器详情。
  7. 容器和主机之间复制文件。
    • docker cp 文件路径加文件名 容器id:路径复制主机文件到容器内。
    • docker cp 容器id:文件路径加文件名 主机路径复制容器内文件到主机。

容器的高级操作

  1. 端口映射。
# 使用-p来指定映射规则,使用多次-p可以映射多个端口
docker run -d -p 2222:22 -p 8888:80 centos_java8_sshd:1.0
# 查看容器端口绑定情况
docker port 容器id
  1. 容器互联。

    端口映射并不是唯一把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
  1. 桥接网络直连容器。

    用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部署大数据集群的内容。

今天的内容就到这里,喜欢的话点个关注吧!