【Docker】基本概念及语法与环境搭建

智码拓荒者
• 阅读 4446

一、Docker的简介

什么是Docker

docker是一个开源的应用容器引擎,基于go语言开发并遵循了apache2.0协议开源。docker是一种容器技术,它可以对软件及其依赖进行标准化的打包;容器之间先对独立,基于容器运行的应用之间也是相互隔离的;并且容器之间是共享一个OS kernel的,充分利用服务器资源,容器可以运行在很多主流的操作系统之上。

容器和虚拟机的区别

容器时在linux上运行,并与其它容器共享主机的内核,它运行一个独立的进程,不占用其它任何可执行文件的内存,非常轻量。虚拟机运行的是一个完成的操作系统,通过虚拟机管理程序对主机资源进行虚拟访问,相比之下需要的资源更多。
【Docker】基本概念及语法与环境搭建

  • 容器是app层面的隔离
  • 虚拟机是物理资源层面的隔离

docker架构和底层技术简介

docker本质就是宿主机的一个进程,docker是通过namespace实现资源隔离,通过cgroup实现资源限制,通过写时复制技术(copy-on-write)实现了高效的文件操作(类似虚拟机的磁盘比如分配500g并不是实际占用物理磁盘500g)
【Docker】基本概念及语法与环境搭建

底层技术简介

namespace名称空间

namespace的六项隔离
namepace系统调用参数隔离内容
UTSCLONE_NEWUTS主机名与域名
IPCCLONE_NEWWIPC信号量、消息队列和共享内存
PIDCLONE_NEWPID进程编号
NEWWORDCLONE_NEWNET网络设备、网络栈、端口等
MOUNTCLONE_NEWNS挂载点(文件系统)
USERCLONE_NEWUSER用户和用户组(3.8以后的内核才支持)

control group控制组

cgroup的功能
  • 资源限制:可以对任务使用的资源总额进行限制
  • 优先级分配:通过分配的cpu时间片数量以及磁盘IO带宽大小,实际上相当于控制了任务运行优先级
  • 资源统计:可以统计系统的资源使用量,如cpu时长,内存用量等
  • 任务控制:cgroup可以对任务执行挂起、恢复等操作

二、Docker的环境搭建

CentOS安装docker

  • 前往官网下载页
  • 卸载docker及相关依赖

    sudo yum remove docker \
        docker-client \
        docker-client-latest \
        docker-common \
        docker-latest \
        docker-latest-logrotate \
        docker-logrotate \
        docker-engine
  • 安装yum-utils工具包

    sudo yum install -y yum-utils
  • 添加docker仓库

    sudo yum-config-manager \
      --add-repo \
      https://download.docker.com/linux/centos/docker-ce.repo
  • 安装最新版docker引擎(社区版)

    sudo yum install docker-ce docker-ce-cli containerd.io
  • 安装指定版本的docker引擎

    #查询docker版本,版本从高到低排序
    yum list docker-ce --showduplicates | sort -r
    
    #安装指定版本的docker,替换<VERSION_STRING>即可
    #sudo yum install -y docker-ce-20.10.13-3.el7 docker-ce-cli-20.10.13-3.el7 containerd.io
    sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
    
  • 启动docker

    sudo systemctl start docker
  • 查看docker版本

    sudo docker version

    【Docker】基本概念及语法与环境搭建

  • 检验docker引擎被成功安装

    sudo docker run hello-world

    【Docker】基本概念及语法与环境搭建

三、Docker的镜像、容器和仓库

【Docker】基本概念及语法与环境搭建
docker基于linux内核空间,在基础镜像的基础上一层层构建出用户镜像。容器是镜像的运行实例。通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括运行应用程序所需要的所有内容包含代码,运行时间,库、环境变量、和配置文件。

Docker image镜像

Docker镜像是什么

docker镜像就是一个只读模板,比如,一个镜像可以包含一个完整的centos,里面仅安装apache或用户的其他应用,镜像可以用来创建docker容器。

  • 文件(root filesystem)和meta data的集合
  • image是分层的,并且每一层都可以添加、修改、删除文件,成为一个新的image
  • 不同的image可以共享相同的layer
  • image本身是read-only只读的

Docker镜像地址

从官方dockerhub拉取镜像非常慢,可以试试国内的镜像源。

【Docker】基本概念及语法与环境搭建

Docker添加镜像地址

对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

{
  "registry-mirrors": ["https://hub-mirror.c.163.com","https://reg-mirror.qiniu.com"]
}
#重新加载配置,重启docker server
systemctl daemon-reload  
systemctl restart docker

Docker镜像相关命令

  • 查看本地已有的镜像列表

    docker image ls
    
    docker images

    【Docker】基本概念及语法与环境搭建

  • 删除镜像

    docker image rm f6509bac4980
    
    #简写
    docker rmi f6509bac4980
  • 构建镜像

    #根据dockerfile构建一个镜像
    docker image build
    
    #从一个被改变的容器创建一个新的镜像
    docker container commit
    
    #简写,从一个被改变的容器创建一个新的镜像
    docker commit
  • 从镜像仓库拉取镜像

    #默认从docker hub拉取
    docker pull ubuntu:14.04
  • 查看指定镜像的创建历史

    #通过镜像名称
    docker history mysql:5.7
    
    #通过镜像ID
    docker history f6509bac4980
  • 镜像的发布docker hub官网

    #首先登陆,输入dockhub的用户名和密码进行登陆
    docker login
    
    #将本地镜像推送到dockerhub,这种方式是不被推荐的,因为镜像是如何构建的是透明的
    #正确的做法应该是用dockerhub关联github,通过dockerhub自动拉取保存在github中的
    #dockerfile,并自动帮我们构建镜像,这样的镜像就会显得安全可靠。
    docker push neojayway/hello-world:latest

    【Docker】基本概念及语法与环境搭建

Dockerfile语法及实践

dockerfile语法

FROM关键字
#制作base image
FROM scratch

#使用base image
FROM centos

FROM ubuntu:14.04

说明:为了安全起见,尽量使用官方的镜像作为基础镜像

LABEL关键字
LABEL version="1.0"
LABEL description="this is description"

说明:此关键字的作用是定义镜像的元数据,类似于注释及帮助信息,还是非常必要的

RUN关键字
RUM yum update && yum install -y vim \
python-dev #反斜线换行

说明:RUN关键字用来执行命令并创建新的image layer层,值得注意的是每运行一次RUN,都会生成一层layer,为了避免无用分层,务必合并多条命令成一行,反斜线\换行,&&合并成多条命令

shell命令格式
RUN yum install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"
exec命令格式
#exec命令格式执行命令,仅仅是单纯的执行命令,没有以shell环境去执行
RUN ["yum", "install", "-y", "vim"]
CMD ["/bin/echo", "hello docker"]
ENTRYPOINT ["/bin/echo", "hello docker"]

#未指定以bash shell环境去执行,$name不会被变量替换
ENTRYPOINT ["/bin/echo", "hello $name"]

#指定以bash shell环境去执行,$name才会被变量替换
ENTRYPOINT ["/bin/bash", "-c", "echo hello $name"]
CMD关键字
FROM centos
ENV name docker
CMD echo "hello $name"
  • 将以上dockerfile构建成镜像并执行docker run [image]会输出“hello docker”
  • 执行docker run -it [image] /bin/bash就不会输出“hello docker”了

说明:该关键字的作用是设置容器启动后默认执行的命令和参数,如果docker run指定了其它命令,CMD命令将会被忽略,如果定义了多个CMD,只有最后一个会执行

ENTRYPOINT关键字
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 27017
CMD ["mongod"]

说明:设置容器启动时运行的命令,让容器以应用程序或者服务的形式运行,不会被忽略,一定会执行

WORKDIR关键字
#如果不存在此目录,则会自动创建目录,并进入目录 
WORKDIR /test 
WORKDIT demo 
RUN $PWD #输出结果应为/test/demo

说明:WORKDIR设定当前工作目录,进入目录应当使用WORKDIR,避免使用RUN cd,因为RUN会新增层,还有尽量使用绝对目录。

ADD和COPY关键字
ADD test.tar.gz / #添加到根目录并解压缩
COPY hello /

说明:AND and COPY本地文件添加到Docker Image里面,大部分情况,COPY优于ADD,ADD相比COPY有解压缩的功能。如需要添加远程文件或目录,请使用RUN关键字执行curl或者wget命令。

ENV关键字
ENV MYSQL\_VERSION 5.7 #设置常量 
RUN apt-get install -y mysql-servier= "${MYSQL_VERSION}" \ && rm -rf /var/lib/apt/lists/* #引用常量

说明:设置常量,增加可维护性

VOLUME关键字
EXPOSE关键字

Docker container容器

Docker container容器是什么

docker利用容器来运行应用,容器是从镜像创建的运行实例,它可以被启动,开始、停止、删除、每个容器都是互相隔离的,保证安全的平台,可以吧容器看做是要给简易版的linux环境(包括root用户权限、镜像空间、用户空间和网络空间等)和运行再其中的应用程序

【Docker】基本概念及语法与环境搭建

  • 容器通过image创建(copy)
  • 容器在imagelayer之上建立要一个container layer(可读写)
  • image负责app的存储和分发,container负责运行app
  • 容器与镜像的关系类似于类和实例的关系

Docker容器相关命令

  • 查看容器列表

    #当前正在运行的容器列表
    docker container ls
    
    #列出所有容器,包含已退出的
    docker container ls -a
    
    docker ps -a

    【Docker】基本概念及语法与环境搭建

  • 运行一个容器

    docker run centos
    
    #指定容器名字,以后台进程方式运行
    docker run -d --name=demo neojayway/hello-world
    
    #以交互模式运行一个容器
    docker run -it centos
  • 限制容器资源

    #限制容器内存为200M
    docker run --memory=200M neojayway/hello-world
    
    #设置cpu相对权重
    docker run --cpu-shares=10 neojayway/hello-world
  • 删除容器

    #指定容器ID删除
    docker container rm d02f80816fbb
    
    #简写
    docker rm d02f80816fbb
    
    #删除所有的容器,-q选项只列出容器ID
    docker rm $(docker container ls -aq)
    
    #删除退出状态的容器,-q选项只列出容器ID
    docker rm $(docker container ls -f "status=exited" -q)
  • 进入容器

    #以交互方式进入指定的容器中
    docker exec -it 11a767d3a588 /bin/bash
    
    #查看指定容器的ip地址
    docker exec -it 11a767d3a588 ip a
  • 停止容器

    docker container stop 11a767d3a588
    
    #简写
    docker stop 11a767d3a588
  • 启动容器

    docker container start 11a767d3a588
    
    #简写
    docker start 11a767d3a588
    
    #指定名称启动容器
    docker start demo
  • 检查容器

    #简写,查看容器的详细信息
    docker inspect 11a767d3a588
    
    #指定名称检查容器
    docker inspect demo
  • 查看容器日志

    #简写,查看容器运行输出的一些日志
    docker logs 11a767d3a588

Docker repository仓库

Docker repository仓库是什么

仓库是集中存储镜像文件的地方,registry是仓库注册服务,实际上仓库注册服务器上存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为两种,即公有仓库和私有仓库,最大的公开仓库是docker Hub,存放了数量庞大的镜像供用户下载,国内的docker pool,这里仓库的概念与Git类似,registry可以理解为github这样的托管服务

四、Docker的网络

Linux网络命名空间

网络命名空间(network namespace)为命名空间内的所有进程提供了全新隔离的网络协议栈。这包括网络接口,路由表和iptables规则。通过使用网络命名空间就可以实现网络虚拟环境,实现彼此之间的网络隔离,Docker中的网络隔离也是基于此实现的。

利用Linux网络命名空间模拟docker网络通信

运行docker容器并观察其网络信息
#分别运行以下两个容器,busybox是非常小的linux image,
docker run -d --name test1 busybox /bin/sh -c "while true; do sleep 3600; done"
docker run -d --name test2 busybox /bin/sh -c "while true; do sleep 3600; done"

#查看容器的网络命名空间
docker exec aa809330a169 ip a

#进入容器
docker exec -it aa809330a169 /bin/sh

#验证容器之间的网络是否也是可达的
docker exec aa809330a169 ping 172.17.0.2

【Docker】基本概念及语法与环境搭建

【Docker】基本概念及语法与环境搭建

【Docker】基本概念及语法与环境搭建

说明:宿主机上docker容器之间的网络是互通,借助于linux网络命名空间,每个docker容器有着不同的命名空间。

Linux网络命名空间模拟docker网络通信

实验通过创建两个两个linux网络命名空间,以及一对虚拟网卡接口对(veth pair),然后分别将虚拟接口分别附加到网络命名空间中,并为虚拟接口设置ip并启用,然后测试两个命名空间的网络可达性。
【Docker】基本概念及语法与环境搭建

手动创建linux网络命名空间
#查看本机的网络命名空间列表
ip netns list

#新建网络命名空间
ip netns add test1
ip netns add test2

#删除网络命名空间
ip netns delete test1

【Docker】基本概念及语法与环境搭建

查看手动创建linux网络命名空间
查看网络命名空间信息
ip netns exec test1 ip a

#查看网络命名空间中的连接
ip netns exec test1 ip link

#将本地回环连接状态启用,所谓连接需要连接两个网卡端点,只有一端是无法up的
ip netns exec test1 ip link set dev lo up

【Docker】基本概念及语法与环境搭建

说明:此新建的网络命名空间中仅有一个本地回环接口,没有地址并且状态还是down的。

创建虚拟网卡对(veth pair)
#创建 veth-test1 和 veth-test2 一对虚拟网卡接口
ip link add veth-test1 type veth peer name veth-test2

【Docker】基本概念及语法与环境搭建

说明:此时宿主机上多了两个虚拟网卡接口,就是我们上面创建的一条链接(veth pair),我们需要将这两个虚拟网卡接口分别添加到上面创建的test1、test2命名空间中。

为网络命名空间添加虚拟网卡接口
#分别将这一对虚拟网卡接口添加给对应的网络命名空间
ip link set veth-test1 netns test1
ip link set veth-test2 netns test2

【Docker】基本概念及语法与环境搭建

说明:此时宿主机上的两个虚拟网卡接口小时不见,test1、test2命名空间中分别被添加了虚拟网卡接口veth-test1、veth-test2,但是此时这两个虚拟接口仍然没有分配地址等资源。

为网络命名空间中虚拟网卡接口添加ip地址等资源
#分别为网络命名空间下的虚拟接口附加ip地址和子网掩码资源
ip netns exec test1 ip addr add 192.168.1.1/24 dev veth-test1
ip netns exec test2 ip addr add 192.168.1.2/24 dev veth-test2
启动虚拟网卡接口
ip netns exec test1 ip link set dev veth-test1 up
ip netns exec test2 ip link set dev veth-test2 up

【Docker】基本概念及语法与环境搭建

测试网络命名空间虚拟网卡接口可达性
ip netns exec test1 ping 192.168.1.2

【Docker】基本概念及语法与环境搭建

docker桥网络

如下图所示,docker容器之间并不是直接连通的,而是通过中间的桥接点docker0做中转,docker0是宿主机默认网络命名空间里的虚拟接口,各个容器与桥节点docker0之间的连接通过虚拟网卡接口对实现,实现了容器间互通;然后docker0通过NAT(网路地址转换)与宿主机的eth0虚拟接口连通,则容器可以借助宿主机访问外网的能力。
【Docker】基本概念及语法与环境搭建
【Docker】基本概念及语法与环境搭建

docker桥网络相关详情查看命令

#安装桥网络相关工具包
yum install -y bridge-utils

#查看桥网络列表,如哪些虚拟接口已连接到桥网络上了
brctl show

#查看docker桥网络详情,如哪些容器连接到了桥网络上
docker network inspect bridge

【Docker】基本概念及语法与环境搭建

【Docker】基本概念及语法与环境搭建

docker容器网络之host和none

上面介绍了bridge网络,接下来介绍host和none网络。对于none网络,使用none网络的容器是无法被外界访问的,容器内部的网络命名空间是被孤立的,也只有一个本地回环端点,只能在宿主机本地进入容器内部的方式;
【Docker】基本概念及语法与环境搭建

  • docker容器网络之none

    #运行容器,采用none网络
    docker run -d --name none-nw --network none centos /bin/sh -c "while true; do sleep 3600; done"

    【Docker】基本概念及语法与环境搭建

  • docker容器网络之host

    #运行容器,采用host网络
    docker run -d --name host-nw --network host centos /bin/sh -c "while true; do sleep 3600; done"

    【Docker】基本概念及语法与环境搭建

【Docker】基本概念及语法与环境搭建

说明:采用host网络运行容器,容器同样不会单独分配ip,因为它完全是用宿主机的网络命名空间。

docker容器之间的link

试想一下,一台宿主机上有两个容器,一个容器中跑了一个mysql服务,另外一个容器中跑了一个web服务,web服务需要访问mysql服务,而两个容器的ip又是动态的,那么如何能使web服务能够通过指定容器名称就能访问到mysql服务,容器之间的link就可以做到。

docker run -d --name test1 busybox /bin/sh -c "while true; do sleep 3600; done"

#test2容器连接test1,是有方向的
docker run -d --name test2 --link test1 centos /bin/sh -c "while true; do sleep 3600; done"

【Docker】基本概念及语法与环境搭建

说明:test2容器与test1容器之间link了,test2容器可以直接以test1容器名称测试容器直接的可达性。

docker容器之间的采用新建的bridge连接

默认情况下docker容器之间是通过docker0这个默认的bridge连接的,我们也可以新建一个bridge,然后指定容器使用这个我们自定义的bridge,与默认的bridge的区别在于,指定使用自定义的bridge的容器会默认相互link(添加DNS记录),这样容器之间可以通过容器名称通信了。

新建bridge
#创建bridge,-d指定driver
docker network create -d bridge my-bridge

#查看docker的网络名称空间
docker network ls

#查看桥网络
brctl show

【Docker】基本概念及语法与环境搭建

容器采用自定义的bridge网络
#--network指定bridge网络,不指定则使用默认docker0
docker run -d --name test2 --network my-bridge centos /bin/sh -c "while true; do sleep 3600; done"

#将已经存在的容器添加到自定义容器上了,此时test1容器同时连接到多个桥网络上了
docker network connect my-bridge test1

【Docker】基本概念及语法与环境搭建

【Docker】基本概念及语法与环境搭建

docker容器的端口映射

docker容器中服务的端口需要在宿主机中一个端口进行绑定映射,这样才能被外部访问到。

#启动一个Nginx服务,将容器的80端口与宿主机的80端口映射
docker run -d -p 80:80 --name web nginx

【Docker】基本概念及语法与环境搭建

五、Docker部署简单实验

Windows docker desktop单机容器部署

#windows docker desktop运行mysql容器
docker run -d --name mysql-ho36 -p3306:3306 -v mysql-vol-data-ho36:/var/lib/mysql -v mysql-vol-conf-ho36:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.39

#windows docker desktop运行mongo容器
docker run -d --name mongo-ho36 -p27017:27017 -v mongo-volume-ho36:/data/db -v mongo-volume-ho36:/data/configdb -e MONGO_INITDB_ROOT_USERNAME=mongoadmin -e MONGO_INITDB_ROOT_PASSWORD=123456 -m 2G mongo:4.4.17-rc2

#windows docker desktop运行es容器
docker run -d --name es-ho36 -p9200:9200 -p9300:9300 -v es-vol-data-ho36:/usr/share/elasticsearch/data -v es-vol-plugins-ho36:/usr/share/elasticsearch/plugins -e "discovery.type=single-node" -e "cluster.name=es.ho36" -e "bootstrap.memory_lock=true" -m 2G --ulimit memlock=-1:-1 elasticsearch:7.17.6

#进入容器安装IK分词插件
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.17.6/elasticsearch-analysis-ik-7.17.6.zip

#windows docker desktop运行neo4j容器
docker run -d --name neo4j-ho36 -p7474:7474 -p7687:7687 -v neo4j-vol-data-ho36:/data -v neo4j-vol-logs-ho36:/logs -e NEO4J_AUTH=neo4j/123456 neo4j:3.5.28

#windows docker desktop运行reids容器
docker run -d --name redis-ho36 -p6379:6379 -v redis-vol-data-ho36:/data redis:6.2.7 --requirepass "123456"

单机多容器部署

在单台虚拟机上运行两个容器,一个容器运行redis服务,一个容器运行Python web小程序,并且web小程序需要访问到另一个容器中的redis服务。

  • 创建容器运行redis服务

    #运行一个redis服务,同宿主机不同容器之间访问,无需映射端口
    docker run -d --name redis redis
  • 编写Python web小程序app.py

    from flask import Flask
    from redis import Redis
    import os
    import socket
    
    app = Flask(__name__)
    redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
    
    
    @app.route('/')
    def hello():
      redis.incr('hits')
      return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname())
    
    
    if __name__ == "__main__":
      app.run(host="0.0.0.0", port=5000, debug=True)

说明:此web小程序暴露一个http端点,访问一次此端点则借助于redis服务记录一次访问量。

  • 新建Dockerfile

    FROM python:2.7
    LABEL maintaner="neojayway liu_rmr@163.com"
    COPY . /app
    WORKDIR /app
    RUN pip install flask redis
    EXPOSE 5000
    CMD [ "python", "app.py" ]
  • 构建flask-redis镜像,请运行容器
    【Docker】基本概念及语法与环境搭建

    #通过Dockerfile构建镜像
    docker build -t flask-redis /home/docker_practice/demo1/
    
    #运行容器,-e通过设置环境变量,使得容器内部可以读取,直接通过redis服务容器的名称访问redis
    docker run -d -p 5000:5000 --link redis --name flask-redis -e REDIS_HOST=redis flask-redis
  • 验证

    curl 127.0.0.1:5000

    【Docker】基本概念及语法与环境搭建

容器部署单实例elasticsearch

#虚拟内存区域被限制调整
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
sysctl -p 
    

#宿主机创建相关空目录,供容器挂载(数据目录、插件目录、配置目录、日志目录)
mkdir -p $HOME/ho_product_test/elasticsearch/data
mkdir -p $HOME/ho_product_test/elasticsearch/plugins
mkdir -p $HOME/ho_product_test/elasticsearch/config
mkdir -p $HOME/ho_product_test/elasticsearch/logs


#先启动容器,目的在于将容器中的相关(数据目录、插件目录、配置目录、日志目录)拷贝到宿主机相关目录
docker run -d \
--name es-ho36 \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e "cluster.name=es.ho36" \
elasticsearch:7.6.1
    
docker cp es-ho36:/usr/share/elasticsearch/config $HOME/ho_product_test/elasticsearch
docker cp es-ho36:/usr/share/elasticsearch/data $HOME/ho_product_test/elasticsearch
docker cp es-ho36:/usr/share/elasticsearch/plugins $HOME/ho_product_test/elasticsearch
docker cp es-ho36:/usr/share/elasticsearch/logs $HOME/ho_product_test/elasticsearch

#删除临时容器
docker rm -f es-ho36

#进入插件文件夹
cd $HOME/ho_product_test/elasticsearch/plugins

#创建文件夹并进入
mkdir analysis-ik && cd analysis-ik

#下载分词器
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.6.1/elasticsearch-analysis-ik-7.6.1.zip

#解压分词器
unzip elasticsearch-analysis-ik-7.6.1.zip

#删除压缩包
rm elasticsearch-analysis-ik-7.6.1.zip

#容器中运行es的用户是elasticsearch(uid:gid - 1000:0)授予0号组足够的权限
chmod -R g+rwx $HOME/ho_product_test/elasticsearch
chgrp -R 0 $HOME/ho_product_test/elasticsearch


#正式运行es容器(--publish-all随机映射所有es端口)
docker run \
-d \
--name es-ho36 \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e "cluster.name=es.ho36" \
-e "bootstrap.memory_lock=true" --ulimit memlock=-1:-1 \
--ulimit nofile=65535:65535 \
-v $HOME/ho_product_test/elasticsearch/data:/usr/share/elasticsearch/data \
-v $HOME/ho_product_test/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-v $HOME/ho_product_test/elasticsearch/config:/usr/share/elasticsearch/config \
-v $HOME/ho_product_test/elasticsearch/logs:/usr/share/elasticsearch/logs \
--restart=always  elasticsearch:7.6.1

容器部署单实例neo4j

#将SELinux设置为permissive模式(相当于将其禁用)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

#宿主机创建相关空目录,供容器挂载(数据目录、插件目录、配置目录、日志目录。。。)
mkdir -p $HOME/ho_product_test/neo4j

#运行neo4j容器,需要关闭selinux
docker run \
-d \
--restart always \
--name neo4j-ho36 \
--publish=7474:7474 --publish=7687:7687 \
--env NEO4J_AUTH=neo4j/Dms@8023 \
neo4j:3.5.28

docker cp neo4j-ho36:/data $HOME/ho_product_test/neo4j
docker cp neo4j-ho36:/var/lib/neo4j/plugins $HOME/ho_product_test/neo4j
docker cp neo4j-ho36:/var/lib/neo4j/conf $HOME/ho_product_test/neo4j
docker cp neo4j-ho36:/logs $HOME/ho_product_test/neo4j
docker cp neo4j-ho36:/var/lib/neo4j/import $HOME/ho_product_test/neo4j

#简单设置权限
chmod -R 777 $HOME/ho_product_test/neo4j
    
#删除临时容器
docker rm -f neo4j-ho36


#运行neo4j容器,需要关闭selinux
docker run \
-d \
--restart always \
--name neo4j-ho36 \
--publish=7474:7474 --publish=7687:7687 \
--volume=$HOME/ho_product_test/neo4j/data:/var/lib/neo4j/data \
--volume=$HOME/ho_product_test/neo4j/logs:/var/lib/neo4j/logs \
--volume=$HOME/ho_product_test/neo4j/conf:/var/lib/neo4j/conf \
--volume=$HOME/ho_product_test/neo4j/import:/var/lib/neo4j/import \
--volume=$HOME/ho_product_test/neo4j/plugins:/var/lib/neo4j/plugins \
--env NEO4J_AUTH=neo4j/123456 \
neo4j:3.5.28

容器部署单实例MongoDB

MongoDB官方镜像库

docker run \
-d \
--restart always \
--name mongo4 \
--publish=27017:27017 \
mongo:4.2.22

#准备相关目录用于容器卷挂载
mkdir $HOME/mongo4
touch $HOME/mongo4/mongod.log
docker cp mongo4:/etc/mongod.conf.orig $HOME/mongo4/mongod.conf.orig

#简单设置权限
chmod -R 777 $HOME/mongo4
    
#删除临时容器
docker rm -f mongo4

#使用自定义配置运行容器,默认MongoDB不会读取配置文件
docker run \
-d \
--net=host \
--restart always \
--name mongo4 \
--publish=27017:27017 \
--volume=$HOME/mongo4/mongod.conf.orig:/etc/mongod.conf.orig \
--volume=$HOME/mongo4/mongodb:/var/lib/mongodb \
--volume=$HOME/mongo4/mongod.log:/var/log/mongodb/mongod.log \
-e MONGO_INITDB_ROOT_USERNAME=root \
-e MONGO_INITDB_ROOT_PASSWORD=123456 \
mongo:4.2.22 \
--config /etc/mongod.conf.orig

容器化部署RocketMQ

简介

关于RocketMQ基于docker容器化部署请参考官方rocketmq-docker(git仓库)
提供了做种部署脚本,比如docker单实例部署、docker-compose集群部署、k8s集群部署。

部署

  • 克隆rocketmq-docker(git仓库)
git clone https://github.com/apache/rocketmq-docker.git

【Docker】基本概念及语法与环境搭建

  • 执行stage.sh脚本

    #指定rocketmq镜像tag,例如4.9.1
    sh stage.sh RMQ-VERSION
  • 单节点部署
cd stages/4.9.1 
./play-docker.sh alpine
#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

start_namesrv_broker()
{
    TAG_SUFFIX=$1
    # Start nameserver
    docker run -d -v `pwd`/data/namesrv/logs:/home/rocketmq/logs --name rmqnamesrv -p 9876:9876 apache/rocketmq:4.9.1${TAG_SUFFIX} sh mqnamesrv
    # Start Broker
    docker run -d -v `pwd`/data/broker/logs:/home/rocketmq/logs -v `pwd`/data/broker/store:/home/rocketmq/store --name rmqbroker --link rmqnamesrv:namesrv -e "NAMESRV_ADDR=namesrv:9876" -p 10909:10909 -p 10911:10911 -p 10912:10912 apache/rocketmq:4.9.1${TAG_SUFFIX} sh mqbroker
}

if [ $# -lt 1 ]; then
    echo -e "Usage: sh $0 BaseImage"
    exit -1
fi

export BASE_IMAGE=$1

echo "Play RocketMQ docker image of tag 4.9.1-${BASE_IMAGE}"

RMQ_CONTAINER=$(docker ps -a|awk '/rmq/ {print $1}')
if [[ -n "$RMQ_CONTAINER" ]]; then
   echo "Removing RocketMQ Container..."
   docker rm -fv $RMQ_CONTAINER
   # Wait till the existing containers are removed
   sleep 5
fi

prepare_dir()
{
    dirs=("data/namesrv/logs" "data/broker/logs" "data/broker/store")

    for dir in ${dirs[@]}
    do
        if [ ! -d "`pwd`/${dir}" ]; then
            mkdir -p "`pwd`/${dir}"
            chmod a+rw "`pwd`/${dir}"
        fi
    done
}

prepare_dir

echo "Starting RocketMQ nodes..."

case "${BASE_IMAGE}" in
    alpine)
        start_namesrv_broker -alpine
    ;;
    centos)
        start_namesrv_broker
    ;;
    *)
        echo "${BASE_IMAGE} is not supported, supported base images: centos, alpine"
        exit -1
    ;;
esac

# Service unavailable when not ready
# sleep 20

# Produce messages
# sh ./play-producer.sh
  • docker-compose集群部署
cd stages/4.9.1 
./play-docker-compose.sh
#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

RMQ_CONTAINER=$(docker ps -a|awk '/rmq/ {print $1}')
if [[ -n "$RMQ_CONTAINER" ]]; then
   echo "Removing RocketMQ Container..."
   docker rm -fv $RMQ_CONTAINER
   # Wait till the existing containers are removed
   sleep 5
fi

prepare_dir()
{
    dirs=("docker-compose/data/namesrv/logs" "docker-compose/data/broker/logs" "docker-compose/data/broker/store" "docker-compose/data1/broker/logs" "docker-compose/data1/broker/store")

    for dir in ${dirs[@]}
    do
        if [ ! -d "`pwd`/${dir}" ]; then
            mkdir -p "`pwd`/${dir}"
            chmod a+rw "`pwd`/${dir}"
        fi
    done
}

prepare_dir

# Run nameserver and broker
docker-compose -f ./docker-compose/docker-compose.yml up -d
version: '2'
services:
  #Service for nameserver
  namesrv:
    image: apache/rocketmq:4.9.1
    container_name: rmqnamesrv
    ports:
      - 9876:9876
    environment:
      - JAVA_OPT_EXT=-server -Xms256m -Xmx256m -Xmn256m
    volumes:
      - ./data/namesrv/logs:/home/rocketmq/logs
    command: sh mqnamesrv

  #Service for broker
  broker:
    image: apache/rocketmq:4.9.1
    container_name: rmqbroker
    links:
      - namesrv
    ports:
      - 10909:10909
      - 10911:10911
      - 10912:10912
    environment:
      - NAMESRV_ADDR=namesrv:9876
      - JAVA_OPT_EXT=-server -Xms512m -Xmx512m -Xmn256m
    volumes:
      - ./data/broker/logs:/home/rocketmq/logs
      - ./data/broker/store:/home/rocketmq/store
      - ./data/broker/conf/broker.conf:/opt/rocketmq-4.9.1/conf/broker.conf
    command: sh mqbroker -c /opt/rocketmq-4.9.1/conf/broker.conf

  #Service for another broker -- broker1
  broker1:
    image: apache/rocketmq:4.9.1
    container_name: rmqbroker-b
    links:
      - namesrv
    ports:
      - 10929:10909
      - 10931:10911
      - 10932:10912
    environment:
      - NAMESRV_ADDR=namesrv:9876
      - JAVA_OPT_EXT=-server -Xms512m -Xmx512m -Xmn256m
    volumes:
      - ./data1/broker/logs:/home/rocketmq/logs
      - ./data1/broker/store:/home/rocketmq/store
      - ./data1/broker/conf/broker.conf:/opt/rocketmq-4.9.1/conf/broker.conf
    command: sh mqbroker -c /opt/rocketmq-4.9.1/conf/broker.conf
   
  #Service for rocketmq-dashboard
  dashboard:
    image: apacherocketmq/rocketmq-dashboard:1.0.0
    container_name: rocketmq-dashboard
    ports:
      - 9527:8080
    links:
      - namesrv
    depends_on:
      - namesrv
    environment:
      - NAMESRV_ADDR=namesrv:9876
  • 基于Kubernetes集群部署
cd stages/4.9.1 
./play-kubernetes.sh
  • RocketMQ-Dledger高可用集群部署

    #注意此特性需要rocketmq版本4.4.0及以上
    cd stages/4.9.1
    ./play-docker-dledger.sh
    
点赞
收藏
评论区
推荐文章
Stella981 Stella981
4年前
Docker基础(1) 原理篇
Docker是什么Docker的构成Docker的分层和写时拷贝策略Docker与主流虚拟机的区别Docker镜像与容器的关系镜像的变更管理Docker是什么Docker是一个开源的应用容器引擎。它的理念是“Buildonce,Runanywhere,Configureonce
Stella981 Stella981
4年前
Docker Compose安装
1.Docker社区开发了很多工具,用于对多个docker容器进行编配。编配的过程实际上就是管理运行在多个docker容器里面的应用,而这些docker容器可能运行在多个不同的宿主机上。2.DockerCompose是一个比较简单的docker容器的编配工具,以前的名称叫Fig,由Orchard团队开发的开源Docker编配工具,在2014年被Do
Stella981 Stella981
4年前
Docker 微服务教程安装WordPress
Docker是一个容器工具,提供虚拟环境。很多人认为,它改变了我们对软件的认识。站在Docker的角度,软件就是容器的组合:业务逻辑容器、数据库容器、储存容器、队列容器......Docker使得软件可以拆分成若干个标准化容器,然后像搭积木一样组合起来。!(https://oscimg.oschina.net/oscnet/fc61b0e
Stella981 Stella981
4年前
Docker学习之路
Docker学习之路Docker简介Docker是什么?Docker是一个开源项目,Go语言实现,遵从了Apache2.0协议,项目代码在GitHub上进行维护。Docker项目的目标是实现轻量级的操作系统虚拟化解决方案。Docker的基础是Linux容器(LXC)等技术。下面的图片比较了Do
Stella981 Stella981
4年前
Docker(一):Docker入门
简介Docker是一个开源的容器引擎,可以帮助我们更快的交付应用。Docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序进行管理。可更快的打包、测试以及部署应用程序,并可减少从编写到部署代码的周期。Docker架构!(https://img2018.cnblogs.com/blog/1040
Stella981 Stella981
4年前
CentOS7安装Docker详细实践
一、Docker简介Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 一个完整的Docker有以下几个部分组成:1.DockerClient客户端2.DockerDae
Stella981 Stella981
4年前
Docker是什么
一.Docker概念简介Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源。Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似iPho
Stella981 Stella981
4年前
Docker初学
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。这次首先说一下docker的三个重要内容:仓库:注册服务器是一个存放仓库的地方,在里面可以存放多个仓库。每个仓库集中存放同
Stella981 Stella981
4年前
Docker及其相关技术
什么是Docker在容器技术(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.cnblogs.com%2Fdy2903%2Fp%2F8331020.html)中,我们讲到了Docker就是一个应用容器引擎,可以将应用及依赖打包,然后发布到Linux上。相对于
Stella981 Stella981
4年前
Docker 容器介绍
Docker容器介绍_Docker_是一个基于_Go_语言的开源应用容器引擎,它既能实现虚拟化,又可用于将应用服务打包成轻量、可移植的容器,从而可以发布到任何_Linux_平台。除了优秀了沙箱机制外,_Docker_容器的开销也极低。正如其名,_Docker_所做的事情正是以一个集装箱的身份承载应用服务的运行
Stella981 Stella981
4年前
Docker是什么,有什么用?一看就明白
!(https://oscimg.oschina.net/oscnet/0228dafbae90d0634ad850b7338e067bfb4.jpg)Docker是一个基于轻量级虚拟化技术的容器,整个项目基于Go语言开发,并采用了Apache2.0协议。Docker可以将我们的应用程序打包封装到一个容器中,该容器包含了应用程序的代码、运行环境、依