docker的理念回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么容器删除,数据就会丢失!
需求:数据可以持久化,如MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器的目录,挂载到Linux上面!
总结:容器的持久化和同步,容器间的数据可以共享!
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
#测试
[root@localhost home]# docker run -it -v /home/ceshi:/home centos /bin/bash
好处:以后只需要在本地修改即可,容器内会自动同步!
实战:安装MySQL
思考:MySQL数据持久化问题
#获取mysql镜像
[root@localhost ~]# docker pull mysql:8.0.19
#运行数据需要进行挂载,安装启动mysql的时候,是需要设置密码的,这是需要注意的!
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root@localhost home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=luohai --name mysql01 mysql:8.0.19
1.如果需要设置docker中MySQL自启,使用命令:docker update mysql --restart=always 容器id;
2.docker设置开机自启,使用命令:system enable docker;
结论:假设我们把容器删除,但发现挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能!
具名和匿名挂载
#匿名挂载
-v 容器内路径
docker run -d -p 3344:80 --name nginx01 -v /etc/nginx nginx
#查看所有的volume的情况
docker volume ls
DRIVER VOLUME NAME
local 420a1630be757f08db1bad67827986a3c304016fac719feecb508e26d5f4a8d6
#以上的这种就是匿名挂载,我们在-v时只写了容器内的路径,没有写容器外的路径!
#具名挂载
[root@localhost ~]# docker run -d -p 3355:80 --name nginx02 -v juming-nginx:/etc/nginx nginx
008442b3f965cf5d71f8d03c58955c7c0b56dee95ed1a202bbb63cb754a3238b
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 420a1630be757f08db1bad67827986a3c304016fac719feecb508e26d5f4a8d6
local f537a36b2b231c2352b1b61d512a515d1163724b316d8e3a924b1ba7077fdead
local juming-nginx
#通过 -v 卷名:容器内路径
#查看下这个卷的路径
[root@localhost ~]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2023-10-16T10:56:11+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
所有的docker容器内的卷,在没有指定目录的情况下都是在/var/lib/docker/volumes/xxxxx/_data
我们通过具名挂载可以方便找到我们的一个卷,大多数情况使用的是具名挂载
#如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
拓展:
#通过-v 容器内路径:ro rw 改读写权限
ro readonly #只读
rw readwrite #可读可写
# 一旦设置了容器的权限,容器对我们挂载出来的内容就有限定了
docker run -d -p 3355:80 --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -p 3355:80 --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# 加了ro就说明这个路径只能通过宿主机来操作,容器内部是只读的无法操作!
初识DockerFile
DockerFile就是用来构建docker镜像的构建文件!命令脚本!
#通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个命令,每个命令就是一层
#开始体验测试下
#创建一个dockerfile文件,名字可以随机,建议Dockerfile
#文件中的内容 指定(大写)参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "---end---"
CMD /bin/bash
#这里的每个命令,就是镜像的一层
[root@localhost docker-test-volume]# docker build -f dockerfile1 -t luohai/centos:.
[+] Building 0.0s (5/5) FINISHED docker:default
=> [internal] load build definition from dockerfile1 0.0s
=> => transferring dockerfile: 116B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:latest 0.0s
=> CACHED [1/1] FROM docker.io/library/centos 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:139235ade34847ff60bb087950d6bfc135d69865c42012862ca936647598ae1e 0.0s
=> => naming to docker.io/luohai/centos:1.0 0.0s
[root@localhost docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat01 1.0 e348b62e0ea8 2 weeks ago 430MB
redis latest da63666bbe9a 3 weeks ago 138MB
nginx latest 61395b4c586d 3 weeks ago 187MB
tomcat 9.0 3740ba5d8885 6 weeks ago 427MB
tomcat latest d0ed0a728666 6 weeks ago 426MB
centos latest 5d0da3dc9764 2 years ago 231MB
luohai/centos 1.0 139235ade348 2 years ago 231MB
luohai/centos latest 139235ade348 2 years ago 231MB
mysql 8.0.19 0c27e8e5fcfa 3 years ago 546MB
elasticsearch 7.6.2 f29a1ee41030 3 years ago 791MB
#启动并查看刚才创建的镜像
[root@localhost docker-test-volume]# docker run -it 139235ade348 /bin/bash
[root@a1721236746a /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Oct 17 02:32 dev
drwxr-xr-x. 1 root root 66 Oct 17 02:32 etc
drwxr-xr-x. 2 root root 6 Nov 3 2020 home
lrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------. 2 root root 6 Sep 15 2021 lost+found
drwxr-xr-x. 2 root root 6 Nov 3 2020 media
drwxr-xr-x. 2 root root 6 Nov 3 2020 mnt
drwxr-xr-x. 2 root root 6 Nov 3 2020 opt
dr-xr-xr-x 189 root root 0 Oct 17 02:32 proc
dr-xr-x---. 2 root root 162 Sep 15 2021 root
drwxr-xr-x. 11 root root 163 Sep 15 2021 run
lrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Oct 17 02:32 sys
drwxrwxrwt. 7 root root 171 Sep 15 2021 tmp
drwxr-xr-x. 12 root root 144 Sep 15 2021 usr
drwxr-xr-x. 20 root root 262 Sep 15 2021 var
drwxr-xr-x 2 root root 6 Oct 17 02:32 volume01
drwxr-xr-x 2 root root 6 Oct 17 02:32 volume02
#通过已经创建的docker01来创建docker02
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9da4ef749d67 luohai/centos "/bin/sh -c /bin/bash" 3 days ago Up 3 days docker01
[root@localhost ~]# docker run -it --name docker02 --volumes-from docker01 luohai/centos
[root@27179874b178 /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Oct 20 03:37 dev
drwxr-xr-x. 1 root root 66 Oct 20 03:37 etc
drwxr-xr-x. 2 root root 6 Nov 3 2020 home
lrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------. 2 root root 6 Sep 15 2021 lost+found
drwxr-xr-x. 2 root root 6 Nov 3 2020 media
drwxr-xr-x. 2 root root 6 Nov 3 2020 mnt
drwxr-xr-x. 2 root root 6 Nov 3 2020 opt
dr-xr-xr-x 188 root root 0 Oct 20 03:37 proc
dr-xr-x---. 2 root root 162 Sep 15 2021 root
drwxr-xr-x. 11 root root 163 Sep 15 2021 run
lrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Oct 17 02:32 sys
drwxrwxrwt. 7 root root 171 Sep 15 2021 tmp
drwxr-xr-x. 12 root root 144 Sep 15 2021 usr
drwxr-xr-x. 20 root root 262 Sep 15 2021 var
drwxr-xr-x 2 root root 26 Oct 17 03:20 volume01
drwxr-xr-x 2 root root 6 Oct 17 03:11 volume02
DockerFile
DockerFile介绍
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
1、编写一个dockerfile文件
2、doker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像(DockerHub、阿里云镜像仓库!)
DockerFile构建过程
基础知识:
1、每个保留关键字(指令)都必须是大写字母
2、执行从上到下顺序执行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交!
dockerfile是面向开发的,我们以后要发布项目,做镜像就需要编写dockerfile文件
Docker镜像逐渐成为企业交付的标准
DockerFile:构建文件,定义了一切的步骤,相当于源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务的
DockerFile指令
FORM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOST # 暴露端口配置
CMD # 指定这个容器启动时候要运行的命令,只有一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承DockerFile这个时候会运行ONBUILD的指定,触发指令
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV #构建的时候设置环境变量
实战测试
Docker Hub中99%镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置进行构建的
创建一个自己的centos
#1、编写Dockerfile的文件
FROM centos
MAINTAINER luohai<luohai@sina.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash
#2、通过这个文件构建镜像
#命令 docker build -f dockerfile文件路径 -t 镜像名:[tag] .
docker build -f mydockerfile -t mycentos:0.1 .
#3、查看镜像构建的过程
docker history 镜像ID
CMD和ENTRYPOINT的区别
CMD #指定这个容器启动的时候运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
实战:Tomcat镜像
1、准备镜像文件tomcat压缩包,jdk压缩包
2、编写dockerfile文件,官方命名Dockerfile,build会自动寻找这个文件,就不需要-f指定
FROM centos
MAINTAINER luohai<530850031@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u181-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.52.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_181
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.52
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.52
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.52/bin/startup.sh && tail -f /usr/local/apache-tomcat-9.0.52/bin/logs/catalina.out
错误描述:
=> ERROR [3/4] RUN yum -y install vim
------
> [3/4] RUN yum -y install vim:
#0 1.627 CentOS Linux 8 - AppStream 61 B/s | 38 B 00:00
#0 1.664 Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
------
--------------------
5 | WORKDIR $MYPATH
6 |
7 | >>> RUN yum -y install vim
8 | RUN yum -y install net-tools
9 |
--------------------
ERROR: failed to solve: process "/bin/sh -c yum -y install vim" did not complete successfully: exit code: 1
分析问题:
> [3/4] RUN yum -y install vim:
#0 1.627 CentOS Linux 8 - AppStream 61 B/s | 38 B 00:00
#0 1.664 Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
由上错误描述可知:问题是由于最新版本CentOS Linux 8中vim软件资源下载失败导致。
解决问题:
添加版本信息并修改为7即可。
# centos系统作为底层
FROM centos:7
# 作者信息及邮箱
MAINTAINER xxxx@xxx.com
# 将readme.txt复制到容器的/usr/local/readme.txt
COPY readme.txt /usr/local/readme.txt
# 添加两个压缩包到 /usr/local之中,会自动解压缩
ADD jdk-8u181-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.52.tar.gz /usr/local/
# 定义环境变量
ENV MYPATH /usr/local
# 设置工作目录
WORKDIR $MYPATH
# 配置jdk环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_181
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# 配置tomcat环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.52
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.52
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin/
# 暴露端口
EXPOSE 8080
# 执行命令
CMD /usr/local/apache-tomcat-9.0.52/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.52/logs/catalina.out
3、构建镜像
docker build -t mytomcat .
4、启动镜像
docker run -d -p 9090:8080 --name lhtomcat -v /home/soft/test:/usr/local/apache-tomcat-9.0.52/webapps/test -v /home/soft/tomcatlogs:/usr/local/apache-tomcat-9.0.52/logs mytomcat
5、测试发布网页
新建一个WEB-INF目录,再添加一个index.html
再在WEB-INF中新建一个web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
</web-app>
<!DOCTYPE html>
<html>
<head>
<title>text</title>
</head>
<meta charset="utf-8">
<body bgcolor="white">
<h1 align="center" >
<font color="purple red" face="华文楷体" size="10">text</font>
</h1>
<p>
<table border="1" width="700" height="100" bgcolor="white" align="center">
<tr bgcolor="red purple">
测试 测试 测试
</tr>
</table>
</p>
</body>
</html>
访问 localhost:9090/test
项目部署成功,访问ok!
若发现容器启动后,tomcat官方网页可以打开,但index.html打不开的话,重启容器即可
#CentOS配置文件位置:/etc/yum.repos.d/CentOS-Base.repo
#解决docker安装vim失败的方法
首先,进入到 yum 的 repos 目录
cd /etc/yum.repos.d/
其次,修改 centos 文件内容
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
然后,生成缓存更新(第一次更新,速度稍微有点慢,耐心等待两分钟左右)
yum makecache
最后,运行 yum update 并重新安装 vim
yum update -y
yum -y install vim
Docker网络
1、拉取一个新的tomcat容器来进行测试
[root@localhost soft]# docker run -d -p 8081:8080 --name tomcat01 tomcat
#查看容器内部的网络地址:ip addr
#解决容器中没有ip addr | ifconfig | ping命令
apt update && apt install -y iproute2 && apt install -y net-tools && apt install -y iputils-ping
#linux 可以ping通docker容器内部
[root@localhost soft]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.145 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.073 ms
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的技术是evth-pair技术!
141: veth5ef5047@if140: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 8a:72:0d:c0:2e:ac brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::8872:dff:fec0:2eac/64 scope link
valid_lft forever preferred_lft forever
# 我们发现这个容器带来的网卡都是一对一对的
# veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连接协议,一端彼此相连
# 正因为有这个特性,veth-pair充当一个桥梁,连接各种虚拟网络设备
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用veth-pair技术
#容器和容器之间是可以ping通的!
自定义网络
查看所有的docker网络
命令:docker network ls
[root@localhost soft]# docker network ls
NETWORK ID NAME DRIVER SCOPE
899c6ab8e1a8 bridge bridge local
3f38988a90c0 host host local
b6e2988fdeb2 none null local
网络模式
bridge:桥接docker(默认,自己创建的也是使用bridge)
none:不配置网络
host:和宿主机共享网络
container:容器网络连通!(用的少!局限很大)
测试
#我们以前以前 直接启动的命令,默认是加了--net bridge,这个就是我们的docker0
#docker0的特点:默认域名是不能访问,--link可以打通连接
#我们可以自定义一个网络!
# --driver bridge
# --subnet 192.168.0.0/16 192.168.0.2 192.168.255.255
# --gateway 192.168.0.1
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
ad487eca3fef2ba01a44d00a82bb62fd7af73d7feb7a0b134f343d88728c3d7c
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
899c6ab8e1a8 bridge bridge local
3f38988a90c0 host host local
ad487eca3fef mynet bridge local
b6e2988fdeb2 none null local
查看自己创建的网络
[root@localhost ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "ad487eca3fef2ba01a44d00a82bb62fd7af73d7feb7a0b134f343d88728c3d7c",
"Created": "2023-10-31T14:43:21.221912848+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
网络连通
#测试打通 tomcat01 -mynet
#连通之后就是将tomcat01放到了mynet网络下
[root@localhost ~]# docker network connect mynet tomcat01
[root@localhost ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "ad487eca3fef2ba01a44d00a82bb62fd7af73d7feb7a0b134f343d88728c3d7c",
"Created": "2023-10-31T14:43:21.221912848+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"396ad337953ace43237a303a701855b8fe44d68ae85b19c7e2760dcda8d73f7d": {
"Name": "tomcat01",
"EndpointID": "01bc9cd6f24457eaed002a5bd608bf103c337661bde30ea61bddd1562fca7168",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
"b4c93e3dfcf8f8f32e2ee66b85672691a6c4b3561493bee0e827f34eb4be588e": {
"Name": "tomcat-net-02",
"EndpointID": "962e18b4e538882e3bea89b2a95206f40542341872c8511da0a1bf1619a1b289",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"d73489c789478dad0ee4d40b41b5f27b8ddecfb940b8ad0dc76ed18634c4fcaf": {
"Name": "tomcat-net-01",
"EndpointID": "1609a9ec047e9ff9523a9341734f905cf9df55ab8245877515b11a4fbdacb06c",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
实战:Redis集群部署
#创建网卡
docker network create redis --subnet 172.38.0.0/16
#通过脚本一次创建6个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
# 通过脚本一次启动6个redis容器
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
done
#进入redis容器命令
docker exec -it redis-1 /bin/sh
#创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1