hello云胜

技术与生活

0%

apiserver宕机

1
2
[root@my-paas-master0 ~]# kubectl get node
Get "https://apiserver.cluster.local:6443/api/v1/nodes?limit=500": dial tcp 1x.xx.12.194:6443: connect: connection refused - error from a previous attempt: unexpected EOF

猜测apiserver宕机

image-20231030170055171

果然

主要还是因为etcd宕机

k8s环境中dns问题排查

问题:

1
2
3
4
5
6
7
8
9
10
11
[root@t-paas-k8s-0-master-0 test]# kubectl run -i --tty --image harbor-test.xxx.net/base/busybox:1.32 dns-test --restart=Never --rm /bin/sh
If you don't see a command prompt, try pressing enter.

/ # nslookup web-0.nginx
Server: 169.254.25.10
Address: 169.254.25.10:53

** server can't find web-0.nginx: NXDOMAIN

*** Can't find web-0.nginx: No answer

要先部署jdk

http://1x.xx.66.1/BCN8x/jdk-8u151-linux-x64.tar.gz

下载不讲

tar -zxvf jdk-8u151-linux-x64.tar.gz

修改环境变量,、

通过修改.bash_profile的方式。这种方式更安全,只对当前用户生效。

vim .bash_profile

在最后加上你自己的路径

export JAVA_HOME=/home/xxxadmin/jdk1.8.0_151

export PATH=$JAVA_HOME/bin:$PATH

执行source .bash_profile使环境变量生效

看一下java -version

java version “1.8.0_151”

Java(TM) SE Runtime Environment (build 1.8.0_151-b12)

Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

OK了

下载zookeeper安装包

http://1x.xx.66.1/BvEtB/zookeeper-3.4.5.tar.gz

这个自己去官网下载,不讲了

tar -zxvf zookeeper-3.4.12.tar.gz

建目录

cd zookeeper-3.4.12

mkdir log data

配置myid

注意,只有这一步是不一样的,在三台机器上分别执行:

echo ‘1’ > data/myid

echo ‘2’ > data/myid

echo ‘3’ > data/myid

修改配置文件

cd conf

cp zoo_sample.cfg zoo.cfg

vim zoo.cfg

把以前的dataDir注释掉

然后增加以下配置内容

dataDir=/home/xxxadmin/zookeeper-3.4.12/data

dataLogDir=/home/xxxadmin/zookeeper-3.4.12/log

server.1=1x.xx.42.153:2888:3888 server.2=1x.xx.42.154:2888:3888 server.3=1x.xx.42.155:2888:3888

server.x的x与上一步配置的myid是要对应起来的

2888端口号是表示这台服务器与集群中的Leader服务器交换信息的端口。

3888端口表示的是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,这个端口就是用来执行选举时服务器相互通信的端口。

autopurge.snapRetainCount=20

autopurge.purgeInterval=48

maxClientCnxns=0

防火墙打开相关端口

2181,2888,3888

启动

cd bin

./zkServer.sh start

./zkServer.sh stop ./zkServer.sh restart

./zkServer.sh status

问题排查:

可能因为某些问题,导致Zookeeper没起来。

./zkServer.sh start[xxxadmin@ppaasmmongo1 bin]$ ./zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /home/xxxadmin/zookeeper-3.4.12/bin/../conf/zoo.cfg

Error contacting service. It is probably not running.

这个时候去bin/zookeeper.out查看日志

一般常见的是java.net.NoRouteToHostException: No route to host (Host unreachable)

这个就是你防火墙没打开的问题

firewall-cmd –list-ports

如果是zk初始启动都没起来,这个时候日志也是也是没有输出的。

解决办法是:

可以使用前台启动,就可以看到日志了

zkServer.sh start-foreground

配置参数解释:

​ autopurge.snapRetainCount=20

​ autopurge.purgeInterval=48

此处我们的配置就是:保留48小时内的日志,并且保留20个文件

autopurge.purgeInterval 这个参数指定了清理频率,单位是小时,需要填写一个1或更大的整数,默认是0,表示不开启自己清理功能。

autopurge.snapRetainCount 这个参数和上面的参数搭配使用,这个参数指定了需要保留的文件数目。默认是保留3个。

maxClientCnxns 单个ip的最大连接数,默认是60个,可以改大点。设置成0,取消这个限制

ETCD备份与恢复

kubenenetes ETCD备份及恢复

对于kubernetes etcd的备份与恢复,总的流程是不变的,对于不同的部署方式,操作上可能略有同。流程如下:

  1. 备份etcd
  2. 停止kube-apiserver
  3. 停止etcd
  4. 恢复etcd
  5. 启动etcd
  6. 启动kube-apiserver
  7. 检查资源状态

使用kubesphere kk工具部署的kubernetes和使用sealos部署的kubernetes在etcd的部署上面略有不同,endpoint、证书位置等参数不同。kk部署的etcd,这些环境变量都存在/etc/etcd.env中。sealos部署的etcd,需要用户去/etc/kubernetes/manifest/etcd.yml查找相关配置。

备份etcd

在任意一台master上执行即可

1
2
3
4
5
etcdctl --endpoints=1x.xxx.5.148:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /tmp/etcd.db

恢复etcd

停止apiserver服务

此操作需要在所有master上执行。

kube-apiserver的启动方式是静态pod,所以只需将kube-apiserver的yml文件移除/etc/kubernetes/manifests,kubelete就会自动删除kube-apiserver的docker 容器。

1
2
3
4
mkdir /etc/kubernetes/manifests.bak
mv /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests.bak
#检查apiserver是否已经停止,返回为0则证明服务停止
ps -ef|grep kube-api|grep -v grep |wc -l0

停止etcd服务

此操作需要在所有master上执行

1
systemctl stop etcd

恢复etcd数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#拷贝备份数据到另外两台master
scp /tmp/etcd.db master-02:/tmp.db
scp /tmp/etcd.db master-03:/tmp.db
#在每台master上分别执行以下命令
#移走原来的etcd数据
mv /var/lib/etcd /var/lib/etcd.bac
#执行恢复操作
etcdctl snapshot restore /tmp/etcd.db --endpoints=$ETCD_ADVERTISE_CLIENT_URLS \ --name=$ETCD_NAME \
--cacert=$ETCD_TRUSTED_CA_FILE \
--key=$ETCD_KEY_FILE \
--cert=$ETCD_CERT_FILE \
--initial-advertise-peer-urls=$ETCD_INITIAL_ADVERTISE_PEER_URLS \
--initial-cluster-token=$ETCD_INITIAL_CLUSTER_TOKEN \
--initial-cluster=$ETCD_INITIAL_CLUSTER \
--data-dir=$ETCD_DATA_DIR

启动etcd

每台master执行

1
systemctl start etcd

启动kube-apiserver

每台master执行

1
2
3
mv /etc/kubernetes/manifests.bac/kube-apiserver.yaml /etc/kubernetes/manifests
#检查kube-apiserver服务是否启动
ps -ef|grep kube-api|grep -v grep

(93条消息) Kubernetes生产实践系列之七:通过etcd备份和恢复Kubernetes集群状态_cloudvtech的博客-CSDN博客

K8S的网络之Docker容器网络

虽然容器可以通过–net=host来指定使用宿主机的网络,但是这样就会引入共享网络资源的问题,比如端口冲突。所以一般情况下,我们希望容器进程能使用自己 Network Namespace 里的网络栈,即:拥有属于自己的 IP 地址和端口

那么这就出现了一个根本的问题

这个被隔离的容器进程,该如何跟其他 Network Namespace 里的容器进程进行交互呢

可以类比物理机进行思考,要让两台物理机互通,最简单的方法就是用一根网线把他们连起来。如果是多台物理机,我们就把他们都接到一台交换机上。

那么对于容器,也是同样的道理。

在 Linux 中,能够起到虚拟交换机作用的网络设备,是网桥(Bridge)。网桥是一个二层设备,工作在数据链路层。根据MAC地址将数据包转发到不同的端口。

Docker 会默认在宿主机上创建一个名叫 docker0 的网桥,

image-20221201150309559

凡是连接在 docker0 网桥上的容器,就都可以通过它来进行通信

那么,下一个问题,docker容器怎么连接到docker0网桥上?

答案就是叫做Veth Pair的虚拟设备

根据名字就可以知道,Veth Pair设备的特点就是,虚拟的,并且是成对的。

可以将veth pair想象成一根管子的两端。从这个口放进去的数据包,可以直接出现在对应的另一个口上。即使这两个虚拟网卡在不同的network namespace里。

做个实验

1
docker run -d -it --name busy-yys busybox

启动一个busybox容器,然后进入容器查看网卡

1
docker exec -it busy-yys /bin/sh

image-20221201154314069

看一下容器里的路由

1
2
3
4
5
# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 * 255.255.0.0 U 0 0 0 eth0

这个容器里有一张叫作 eth0 的网卡,它正是一个 Veth Pair 设备在容器里的这一端

根据第二条路由,所有对 172.17.0.0/16 网段的请求,也会被交给 eth0 来处理

再看宿主机上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# ifconfig


docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:1eff:fe0d:1279 prefixlen 64 scopeid 0x20<link>
ether 02:42:1e:0d:12:79 txqueuelen 0 (Ethernet)
RX packets 3 bytes 125 (125.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11 bytes 858 (858.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 1x.xxx.151.208 netmask 255.255.255.0 broadcast 1x.xxx.151.255
inet6 fe80::f816:3eff:fe35:5192 prefixlen 64 scopeid 0x20<link>
ether fa:16:3e:35:51:92 txqueuelen 1000 (Ethernet)
RX packets 1789919595 bytes 294856793516 (274.6 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1774732821 bytes 281152040711 (261.8 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0


veth066ee4f: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::7829:83ff:fe0e:c99 prefixlen 64 scopeid 0x20<link>
ether 7a:29:83:0e:0c:99 txqueuelen 0 (Ethernet)
RX packets 3 bytes 167 (167.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11 bytes 858 (858.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

虚拟设备veth066ee4f就是veth pair在宿主机上的另一端

然后查看一下网桥的情况

1
2
3
# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.02421e0d1279 no veth066ee4f

可以看到,虚拟网卡veth066ee4f已经被注册到网桥docker0上了。

(brctl通过yum -y install bridge-utils安装)

我们再启动一个容器

1
docker run -d -it --name busy-2 busybox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# docker exec -it busy-2 /bin/sh
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:656 (656.0 B) TX bytes:0 (0.0 B)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

看到busy-2的ip是172.17.0.2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
veth3950859: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
inet6 fe80::8ce9:31ff:fecf:6df0 prefixlen 64 scopeid 0x20<link>
ether 8e:e9:31:cf:6d:f0 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 656 (656.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

veth066ee4f: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::7829:83ff:fe0e:c99 prefixlen 64 scopeid 0x20<link>
ether 7a:29:83:0e:0c:99 txqueuelen 0 (Ethernet)
RX packets 3 bytes 167 (167.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11 bytes 858 (858.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

宿主机上增加了对应的veth

1
2
3
4
# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.02421e0d1279 no veth066ee4f
veth3950859

新增的veth:veth3950859,也增加到了网桥docker0上

容器ping容器

在容器里互相ping,发现可以ping通。

原理也很简单,从容器的route信息看到

1
172.17.0.0      *               255.255.0.0     U     0      0        0 eth0

gateway是*,表示这个网段172.17.0.0 /16是本地直连路由,不需要经过网关,应该经过本机的 eth0 网卡,通过二层网络直接发往目的主机 。

然后,对容器来说,本机的eth0,是veth pair的一端。根据前面的介绍,数据包会直接到宿主机上的另一端。

而另一端的虚拟网卡是插在网桥docker0上的。一旦插到网桥上,这个虚拟网卡的功能就只剩下接收数据包,对数据包的处理全部有网桥docker0掌握。

网桥docker0是一个二层设备,通过mac地址转发数据包。所以会通过arp广播,根据ip得到所有对应虚拟网卡的mac。

有了mac地址,网桥docker0就会将数据包发给对应的veth端口。

这样,数据包就会到达容器内对应的eth0口。

宿主机ping容器

同理,可以分析。在宿主机上直接ping 容器的ip,也是通的。

查看宿主机的route

1
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0

可以看到这一条规则。0.0.0.0和*一样,同表示这是一条直连规则。

也是到网桥docker0。后面就一样了。

容器ping宿主机

容器的数据包,直接出现在docker0上,本身就是通的。

容器ping其他主机

只要目标主机和容器的宿主机是通的

那么容器的数据包经过 docker0 网桥出现在宿主机上,之后根据宿主机的路由表里的路由规则,就可以到达目标主机。

其他主机ping容器

很明显,不会通的。因为其他主机上并没有这个网桥docker0。

网桥docker0只能处理本机的网络。

一台宿主机上的 docker0 网桥,和其他宿主机上的 docker0 网桥,没有任何关联,它们互相之间也没办法连通

进而根据这种网桥的思路,如果我们要做到跨主机的容器互通,一个办法就是打造一个集群公用的超级网桥,将所有的容器都注册上来。

那么就可以做到跨节点的容器互通了。

这也就是下面要说的k8s的overlay网络。

省流阅读:

遇到的故障是,redis 集群配置文件损坏导致无法启动

1
Unrecoverable error: corrupted cluster config file

总结写在前面:

  1. 集群的高可用性真的很重要

  2. 服务器总会宕机,网络总会故障

昨天周末,本来在家吃着火锅,唱着歌。正开心着,公司的电话来了,说有台服务器故障了,宕机重启了,让我看看有没有影响。

赶紧查了下,是redis集群的服务器,

还好,因为是集群环境,宕机一台并没有影响整个redis服务器的可用性。master节点直接选举漂走了。

而且redis服务都做了supervisor托管,宕机重启会启动redis。

但是查看了下,redis并没有能够启动。

查看redis的日志:显示配置文件损坏。

1
2
3
4
6305:C 04 Dec 11:44:21.621 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
6305:C 04 Dec 11:44:21.622 # Redis version=4.0.2, bits=64, commit=00000000, modified=0, pid=6305, just started
6305:C 04 Dec 11:44:21.622 # Configuration loaded
6305:M 04 Dec 11:44:21.623 # Unrecoverable error: corrupted cluster config file

因为集群cluster-config-file文件损坏引起,导致该节点无法启动

这里说的cluster-config-file文件 就是指 node-xxxx.conf文件

这里面存的是redis cluster的各个节点信息,也就是cluster nodes命令的结果

所以修改起来也简单:

删除损坏节点的node-xxxx.conf文件

1
mv  node-xxxx.conf node-xxxx.conf.bak

再启动redis节点

1
redis-server xxxx.conf > xxxx.log 2>&1 &

绝对路径启动

1
/opt/cachecloud/redis/src/redis-server /opt/cachecloud/conf/redis-cluster-6384.conf > /opt/cachecloud/logs/redis-6384-20231109.log 2>&1 &

以为应该完事了,接着奏乐,接着舞

但是

查看cluster nodes

1
2
3
4
5
6
7
1x.xx.x.x:6424> cluster nodes
d7f1a01f0552d684f512e4484493c0cc42c21efc 1x.xx.x.x:6447@16447 master,fail - 1670110148890 1670110146887 3 connected
28d50ee489cb75b8963d310864a5588bf493a0b3 1x.xx.x.x:6423@16423 master - 0 1670127954000 8 connected 0-5461
403f6048b98a6e979d414aa4a508c0d08cd75fa7 1x.xx.x.x:6446@16446 master,fail - 1670110150894 1670110147000 5 connected
0d6c3358103ca3ee300ecdd1832bd2fb82dd1219 1x.xx.x.x:6445@16445 slave,fail 28d50ee489cb75b8963d310864a5588bf493a0b3 1670110149892 1670110146000 8 connected
ae31858c30dbe272a0df53effac632a4fd1aa193 1x.xx.x.x:6424@16424 myself,master - 0 1670127952000 9 connected 5462-10923
ed891086ecc18d98b3812727c67577cf323c3a1e 1x.xx.x.x:6425@16425 master - 0 1670127954131 10 connected 10924-16383

原本宕机的master,倒是不见外,仍然认为自己是master,没有变成某个新master的salve。

这个时候我们需要把fail的节点移出集群,再加入集群

将fail节点移出集群

1
cluster forget d7f1a01f0552d684f512e4484493c0cc42c21efc

加入集群

1
CLUSTER MEET <ip> <port>   //将ip和port所指定的节点添加到集群当中,让它成为集群的一份子

指定为master节点的从节点

注意,这个时候是登录之前fail的节点操作

1
CLUSTER REPLICATE <node_id> //将当前节点设置为 node_id 指定的节点的从节点

终于好了。

  1. 编译
    按照官方说明:http://rocketmq.apache.org/docs/quick-start/

    git clone -b develop https://github.com/apache/rocketmq.git

cd rocketmq

mvn -Prelease-all -DskipTests clean install -U

cd distribution/target/apache-rocketmq

其中,mvn打包时超时,我用了下面的镜像。

1
2
3
4
5
6
7
<mirror>
<id>central</id>
<name>Maven Repository Switchboard</name>
<url>http://repo1.maven.org/maven2/</url>
<mirrorOf>central</mirrorOf>
</mirror>

  1. 环境
    centOS 6.5
  • 创建用户
    最好不要用root用户来搭建应用。

    useradd -d /home/rocketmq410 -m rocketmq410
    passwd rocketmq410

  • 切换用户

  • 下载jdk 1.8。并配置
    scp xxxadmin@1x.xxx.7.56:~/jdk-8u144-linux-x64.tar.gz ~
    解压tar -zxvf
    修改.bash_profile。这种方式更安全,只对当前用户生效。
    [rocketmq410@wuliutest001 ~]$ vim .bash_profile
    在最后加上

    export JAVA_HOME=/home/rocketmq410/jdk1.8.0_144

    export PATH=$JAVA_HOME/bin:$PATH

    source .bash_profile

  • 部署规划
    本次搭的是4主无备的集群。
    2个nameServer 1x.xxx.26.200 和 1x.xxx.26.201
    端口开在9876

  • 系统配置

    使用root权限

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf
    echo 'vm.min_free_kbytes=5000000' >> /etc/sysctl.conf
    echo 'vm.drop_caches=1' >> /etc/sysctl.conf
    echo 'vm.zone_reclaim_mode=0' >> /etc/sysctl.conf
    echo 'vm.max_map_count=655360' >> /etc/sysctl.conf
    echo 'vm.dirty_background_ratio=50' >> /etc/sysctl.conf
    echo 'vm.dirty_ratio=50' >> /etc/sysctl.conf
    echo 'vm.page-cluster=3' >> /etc/sysctl.conf
    echo 'vm.dirty_writeback_centisecs=360000' >> /etc/sysctl.conf
    echo 'vm.swappiness=10' >> /etc/sysctl.conf
    sysctl -p

    echo 'ulimit -n 655350' >> /etc/profile
    echo '* hard nofile 655350' >> /etc/security/limits.conf
    echo '* hard memlock unlimited' >> /etc/security/limits.conf
    echo '* soft memlock unlimited' >> /etc/security/limits.conf

    发现4.1.0版本的os.sh不好使。还是3.2.6版本里的echo好用。
    查看内核参数用cat /etc/sysctl.conf
    查看文件句柄 用 ulimit -a 或 -n
    还有一个参数

    1
    2
    3
    DISK=`df -k | sort -n -r -k 2 | awk -F/ 'NR==1 {gsub(/[0-9].*/,"",$3); print $3}'`
    [ "$DISK" = 'cciss' ] && DISK='cciss!c0d0'
    echo 'deadline' > /sys/block/${DISK}/queue/scheduler

    这个是设置io调度算法,细节google。注意两点:

    1. 之前用centos6.5。这个值默认是cfq。换了7.2后发现这个参数默认就是deadline。省了配置了。
    2. 我的系统第一句得到的DISK值是mapper。但是在echo时,发现/sys/block下根本没有mapper目录。其实应该是sda。所以mq提供的脚本可能有问题。供大家参考。

    使用root权限,执行一次os.sh
    仅执行一次就好,以前执行过,就不要再次执行了。 ~~
    ~~然而,并不会成功。报错:

    ~~ > -bash: ./os.sh: /bin/sh^M: bad interpreter: No such file or directory~~

    原因是,我之前的编译打包是在windows环境下。
    ~~此时的文件编码是dos的。要改成unix的。详见了我的另一篇文章。 ~~

    vim 打开文件。
    :set ff=unix ~~
    ~~同样处理其他用到的脚本。

    查询一下 cat /etc/sysctl.conf 或者 sysctl -a

  • 配置启动nameServer

    新建一个配置文件namesrv-a.properties,放在conf下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    listenPort=9876
    serverWorkerThreads=8
    serverCallbackExecutorThreads=0
    serverSelectorThreads=3
    serverOnewaySemaphoreValue=256
    serverAsyncSemaphoreValue=64
    serverChannelMaxIdleTimeSeconds=120
    serverSocketSndBufSize=2048
    serverSocketRcvBufSize=1024
    serverPooledByteBufAllocatorEnable=false

    在bin下,新建一个启动脚本startnamesrv.sh

    1
    2
    nohup ./mqnamesrv -c ../conf/namesrv-a.properties > ~/logs/ns.log &
    tail -100f ~/logs/ns.log

    执行startnamesrv.sh

    同样操作,配置好1x.xxx.26.201

  • 配置启动broker
    新建一个启动脚本,startbroker.sh

    1
    2
    nohup ./mqbroker -c ../conf/2m-noslave/broker-a.properties > ~/logs/broker-a.log &
    tail -100f ~/logs/broker-a.log

chmod +x startbroker.sh

配置broker-a.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
brokerClusterName=HopRocketMqClusterProduction
brokerName=broker-a-pro
# 相同的brokerName,brokerId是0为master,>0为slave
brokerId=0
# 清理commitlog的时间,默认就是04
deleteWhen=04
# commitlog保存时间,默认就是72
fileReservedTime=72
# 角色ASYNC_MASTER,SYNC_MASTER,SLAVE;
# ASYNC_MASTER:master接受消息成功即返回成功
# SYNC_MASTER:至少一个slave接受消息成功,才返回成功
brokerRole=ASYNC_MASTER
# 刷盘方式SYNC_FLUSH和ASYNC_FLUSH
flushDiskType=ASYNC_FLUSH

# netty的监听端口
listenPort=10922
# namesrv地址
namesrvAddr=1x.xxx.26.200:9876;1x.xxx.26.201:9876
# 获取本地地址
brokerIP1=1x.xxx.26.200
# 默认队列数量
defaultTopicQueueNums=8
# 自动创建Topic功能是否开启(线上建议关闭)
autoCreateTopicEnable=false
# 自动创建订阅组功能是否开启(线上建议关闭)
autoCreateSubscriptionGroup=false

# 磁盘空间最大使用率,超了拒收消息
diskMaxUsedSpaceRatio=80
# 存储commitlog路径
storePathRootDir=/home/rocketmq410/mqstore/rocketmqstore-a
storePathCommitLog=/home/rocketmq410/mqstore/rocketmqstore-a/commitlog

# 自动创建以服务器名字命名的Topic功能是否开启
brokerTopicEnable=false
# 自动创建以集群名字命名的Topic功能是否开启
clusterTopicEnable=false
# 是否拒绝接收事务消息
rejectTransactionMessage=false
# 是否从地址服务器寻找Name Server地址,正式发布后,默认值为false
fetchNamesrvAddrByAddressServer=false

# 以下全是默认值,删掉即可

# CommitLog刷盘间隔时间(单位毫秒)
flushIntervalCommitLog=1000
# 是否定时方式刷盘,默认是实时刷盘
flushCommitLogTimed=false
# 最大被拉取的消息字节数,消息在内存
maxTransferBytesOnMessageInMemory=262144
# 最大被拉取的消息个数,消息在内存
maxTransferCountOnMessageInMemory=32
# 最大被拉取的消息字节数,消息在磁盘
maxTransferBytesOnMessageInDisk=65536
# 最大被拉取的消息个数,消息在磁盘
maxTransferCountOnMessageInDisk=8
# 命中消息在内存的最大比例
accessMessageInMemoryMaxRatio=40
# 是否开启消息索引功能
messageIndexEnable=true
# 是否使用安全的消息索引功能,即可靠模式。
# 可靠模式下,异常宕机恢复慢
# 非可靠模式下,异常宕机恢复快
messageIndexSafe=false
# ha是主从同步相关配置
haMasterAddress=

新建存储commitlog的目录
mkdir -p /home/rocketmq410/mqstore/rocketmqstore-a/commitlog

执行startbroker.sh

  • 安装rocketmq-console
    git clone git@github.com:apache/rocketmq-externals.git
    cd rocketmq-console
    mvn clean package -Dmaven.test.skip=true
    上传
    写一个启动脚本,指定namesrv。
    nohup java -jar ./rocketmq-console-ng-1.0.0.jar --server.port=12580 --rocketmq.config.namesrvAddr=1x.xx.22.90:9877\;1x.xx.22.91:9877 > nohup.out &

  • admin cli命令
    查询消费进度
    ./mqadmin consumerProgress -g TestConsumer1 -n 1x.xxx.26.200:9876

  • 问题:

  1. client使用3.6.2版本,需要设置setVipChannelEnabled为false,否则发送失败。

  2. client使用3.6.2版本,代码日志可以看到消息已经消费成功,但是broker上的offset没变。
    client版本降为3.2.6问题解决。
    该问题在broker端是3.2.6版本上是一样的。

  3. 关于sendMessageWithVIPChannel,3.2.6以上的client默认是true
    broker的netty server会起两个通信服务。两个服务除了服务的端口号不一样,其他都一样。其中一个的端口(配置端口-2)作为vip通道,客户端可以启用本设置项把发送消息此vip通道。
    这个可以减少消息的丢失率。加快刷到硬盘的速度。这个通道很少生产者走的。所以,保证了消息稳定地到达了 broker 端,特别是 当 洪水般的消息涌过来的话,对于 金钱方面的消息,这个通道非常快速。

注意:
安装前一定要看好哪个路径下存储空间最大

修改文件夹owner:
chown -R rocketmq:rocketmq /data/rocketmq/

服务器的防火墙对应的端口没开,
你发邮件让他们开下,我现在是将防火墙关掉了,测试可以用了。
申请开通服务器端口
9870-9880,10920 - 10925,12580

centos7.2开通防火墙端口

firewall-cmd –zone=public –add-port=9870-9880/tcp –permanent

firewall-cmd –reload

变量

又分为环境变量和自定义变量

环境变量

使用 env 命令查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[api@kfxqtyglpt ~]$ env
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=1x.xx.179.212 60463 50023
SELINUX_USE_CURRENT_RANGE=
QTDIR=/usr/lib64/qt-3.3
QTINC=/usr/lib64/qt-3.3/include
SSH_TTY=/dev/pts/1
HISTORY_FILE=/var/log/usermonitor/usermonitor.log
JRE_HOME=/home/api/jdk1.7.0_25/jre
USER=api
MAVEN_HOME=/home/api/maven
MAIL=/var/spool/mail/api
PATH=/home/api/jdk1.7.0_25/bin:/home/api/maven/bin:/home/api/maven/bin:/home/api/jdk1.7.0_25/bin:/home/api/jdk1.7.0_25/jre/bin:/usr/local/nginx/sbin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/api/bin
JAVA_HOME=/home/api/jdk1.7.0_25
LANG=zh_CN.UTF-8

环境变量通常用全大写的形式

自定义变量

1
[api@kfxqtyglpt ~]$ myname=nanhai13

注意

  1. 变量未设定之前是空的
  2. 等号两边不能有空格

查看变量

1
2
3
4
[api@kfxqtyglpt ~]$ echo $myname
nanhai13
[api@kfxqtyglpt ~]$ echo ${myname}
nanhai13

推荐使用${}方式

特殊情况处理

  1. 数据内容有空格

    用单引号或者双引号括起来

    或者用转移字符\把空格转义了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [api@kfxqtyglpt ~]$ myname="nanhai 13"
    [api@kfxqtyglpt ~]$ echo ${myname}
    nanhai 13
    [api@kfxqtyglpt ~]$ myname='nanhai 14'
    [api@kfxqtyglpt ~]$ echo ${myname}
    nanhai 14
    [api@kfxqtyglpt ~]$ myname=nanhai\ 15
    [api@kfxqtyglpt ~]$ echo ${myname}
    nanhai 15
  2. 数据内容中引用其他变量

    用双引号括起。不能用单引号

    1
    2
    3
    [api@kfxqtyglpt ~]$ hello="hi ${myname}"
    [api@kfxqtyglpt ~]$ echo $hello
    hi nanhai 15

    如果用单引号

    1
    2
    3
    [api@kfxqtyglpt ~]$ hello='hi ${myname}'
    [api@kfxqtyglpt ~]$ echo $hello
    hi ${myname}

    可以看出单引号和双引号的区别了

  3. 数据内容中执行其他命令

    使用$()可以执行命令

    1
    2
    3
    [api@kfxqtyglpt ~]$ myversion=$(uname -r)
    [api@kfxqtyglpt ~]$ echo $myversion
    2.6.32-431.el6.x86_64

查看自定义变量

使用set命令。可以查看所有环境变量和自定义变量

删除自定义变量

unset命令

其他

$本身也是个变量

1
2
[api@kfxqtyglpt ~]$ echo $$
74292

$$显示当前shell的pid

?是上一个命令的结果

一般命令执行后都会回传一个执行结果。

执行成功一般回传0,如果执行出错,会回传错误码。

1
2
3
4
5
6
[api@kfxqtyglpt ~]$ echo $?
0
[api@kfxqtyglpt ~]$ name=66 66
-bash: 66: command not found
[api@kfxqtyglpt ~]$ echo $?
127

将自定义变量导出为环境变量

使用export命令,注意没有$符号

1
[api@kfxqtyglpt ~]$ export myname

使用env查看

1
2
3
4
[api@kfxqtyglpt ~]$ env
...
myname=nanhai 15
...

我们登入linux,取得一个bash命令窗口,就是开启了一个bash程序,这个bash有自己的pid

在这个shell下执行的所有命令都是这个shell程序的子程序

子程序会继承父程序的环境变量,但是不会继承父程序的自定义变量

1
2
3
4
5
6
7
8
9
10
11
12
[api@kfxqtyglpt ~]$ name=superman
[api@kfxqtyglpt ~]$ echo $name
superman
[api@kfxqtyglpt ~]$ bash ========>开启一个bash子程序
[api@kfxqtyglpt ~]$ echo $name

[api@kfxqtyglpt ~]$ exit ========>返回父程序
exit
[api@kfxqtyglpt ~]$ export name ========>export成环境变量
[api@kfxqtyglpt ~]$ bash
[api@kfxqtyglpt ~]$ echo $name
superman

读取输入值

编写shell脚本时经常会用到需要获取用户输入的功能。这就需要read命令

1
2
3
4
5
6
7
8
[api@kfxqtyglpt ~]$ read name
king
[api@kfxqtyglpt ~]$ echo ${name}
king
[api@kfxqtyglpt ~]$ read -p "输入名字:" -t 10 name
输入名字:aaaaa
[api@kfxqtyglpt ~]$ echo $name
aaaaa

read直接加变量名即可

参数-p可以加说明,-t是等待时间

声明变量的类型

默认定义的变量都是字符串类型,所以

1
2
3
[api@kfxqtyglpt ~]$ sum=10+20
[api@kfxqtyglpt ~]$ echo ${sum}
10+20

声明变量类型使用declare命令,参数

-a数组类型

-i整数类型

-x导出为环境变量

-r只读类型

1
2
3
4
5
[api@kfxqtyglpt ~]$ unset sum
[api@kfxqtyglpt ~]$ declare -i sum
[api@kfxqtyglpt ~]$ sum=10+20
[api@kfxqtyglpt ~]$ echo $sum
30

数组

直接使用中括号来定义即可,使用时需要用${}

1
2
3
4
5
[api@kfxqtyglpt ~]$ arr[0]=aa
[api@kfxqtyglpt ~]$ arr[1]=bb
[api@kfxqtyglpt ~]$ arr[2]=cc
[api@kfxqtyglpt ~]$ echo "${arr[0]},${arr[2]}"
aa,cc

tcpdump

tcpdump详解 - 清风软件测试 - 博客园 (cnblogs.com)

命令格式

tcpdump命令很灵活,参数比较多。所以上手比较难。

img

1
2
tcpdump [ -DenNqvX ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ]
[ -s snaplen ] [ -w file ] [ expression ]

img

options

抓包参数

  1. -c:指定要抓取的包数量

  2. -i interface:指定tcpdump需要监听的接口。默认会抓取第一个网络接口

  3. -n:对地址以数字方式显式,否则显式为主机名,也就是说-n选项不做主机名解析。不把ip转化成域名,直接显示 ip,避免执行 DNS lookups 的过程,速度会快很多

  4. -nn:除了-n的作用外,还把端口显示为数值,否则显示端口服务名。

  5. -N:不打印出host 的域名部分

  6. -Q:指定要抓取的包是流入还是流出的包。可以给定的值为”in”、”out”和”inout”,默认为”inout”。

  7. -s len:tcpdump 默认只会截取前 96 字节的内容,要想截取所有的报文内容,可以使用 -s numbernumber 就是你要截取的报文字节数,如果是 0 的话,表示截取报文全部内容。

定义输出

  1. -e:输出的每行中都将包括数据链路层头部信息,例如源MAC和目标MAC。
  2. -q:快速打印输出。即打印很少的协议相关信息,从而输出行都比较简短。
  3. -X:输出包的头部数据,会以16进制和ASCII两种方式同时输出。
  4. -XX:输出包的头部数据,会以16进制和ASCII两种方式同时输出,更详细。
  5. -v:当分析和打印的时候,产生详细的输出。
  6. -vv:产生比-v更详细的输出。
  7. -vvv:产生比-vv更详细的输出。
  8. -A:以ASCII码方式显示每一个数据包(不显示链路层头部信息). 在抓取包含网页数据的数据包时, 可方便查看数据

辅助参数

  1. -D:列出可用于抓包的接口。将会列出接口的数值编号和接口名,它们都可以用于”-i”后。

  2. -F:从文件中读取抓包的表达式。若使用该选项,则命令行中给定的其他表达式都将失效。

  3. -w:后接一个以 .pcap 后缀命令的文件名,就可以将 tcpdump 抓到的数据保存到文件中。

  4. -r:从给定的数据包文件中读取数据。使用”-“表示从标准输入中读取。

表达式或者理解成过滤器:proto dir type

  • 协议 proto:tcp, udp, icmp, ip, ip6, arp, rarp,ether,wlan, fddi, tr, decnet,若未给定协议类型,则匹配所有可能的类型

  • 方向过滤 direction :src, dst, src or dst, src and dst。比如src表示查询发送

  • 类型 type:host, net, port, portrange,例如:host 192.168.201.128 , net 128.3, port 20, portrange 6000-6008’

    表达式单元之间可以使用操作符” and / && / or / || / not / ! “进行连接,从而组成复杂的条件表达式==。如”host foo and not port ftp and not port ftp-data”,这表示筛选的数据包要满足”主机为foo且端口不是ftp(端口21)和ftp-data(端口20)的包”,常用端口和名字的对应关系可在linux系统中的/etc/service文件中找到。

    另外,同样的修饰符可省略,如”tcp dst port ftp or ftp-data or domain”与”tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain”意义相同,都表示包的协议为tcp且目的端口为ftp或ftp-data或domain(端口53)。

    使用括号”()”可以改变表达式的优先级,但需要注意的是括号会被shell解释,所以应该使用反斜线””转义为”()”,在需要的时候,还需要包围在引号中

输出解析

例如,解析一个tcp包

1
2
3
4
5
6
7
8
9
10
11
12
# tcpdump -i eth0 -c 5 -nn tcp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:02:29.875584 IP 1x.xxx.5.1.22 > 1x.xxx.6.178.53755: Flags [P.], seq 1422838589:1422838785, ack 262287789, win 302, options [nop,nop,TS val 695766271 ecr 804880858], length 196
11:02:29.875755 IP 1x.xxx.5.1.22 > 1x.xxx.6.178.53755: Flags [P.], seq 196:424, ack 1, win 302, options [nop,nop,TS val 695766271 ecr 804880858], length 228
11:02:29.875815 IP 1x.xxx.5.1.22 > 1x.xxx.6.178.53755: Flags [P.], seq 424:620, ack 1, win 302, options [nop,nop,TS val 695766272 ecr 804880858], length 196
11:02:29.875860 IP 1x.xxx.5.1.22 > 1x.xxx.6.178.53755: Flags [P.], seq 620:816, ack 1, win 302, options [nop,nop,TS val 695766272 ecr 804880858], length 196
11:02:29.875904 IP 1x.xxx.5.1.22 > 1x.xxx.6.178.53755: Flags [P.], seq 816:1012, ack 1, win 302, options [nop,nop,TS val 695766272 ecr 804880858], length 196
5 packets captured
5 packets received by filter
0 packets dropped by kernel

tcpdump的输出是很规整的

第一列: 时间

第二列:网络协议,这里是IP协议

第三列:发送方的ip和端口

第四列:箭头 >, 表示数据流向

第五列:接收方的ip和端口

第六列:冒号

第七列:数据包内容。包括Flags 标识符,seq 号,ack 号,win 窗口,数据长度 length,其中 [P.] 表示 PUSH 标志位为 1,更多标识符见下面

TCP 报文 Flags,有以下几种:

  • [S] : SYN(开始连接)
  • [P] : PSH(推送数据)
  • [F] : FIN (结束连接)
  • [R] : RST(重置连接)
  • [.] : 没有 Flag (意思是除上面四种类型外的其他情况,有可能是 ACK 也有可能是 URG)

示例

1. 默认启动

1
tcpdump

默认情况下,直接启动tcpdump将监视第一个网络接口(非lo口)上所有流通的数据包。这样抓取的结果会非常多,滚动非常快。

2 . 监视指定网络接口的数据包

1
tcpdump -i eth0

3. 监视指定主机的数据包,例如所有进入或离开某个服务器的数据包

1
tcpdump -i eth0 host 服务器ip 

4. 打印node1<–>node2或node1<–>node3之间通信的数据包

1
tcpdump -i eth0 host node1 and \(node2 or node3\)

5. 打印node1与任何其他主机之间通信的IP数据包,但不包括与node4之间的数据包

1
tcpdump -i eth0 host node1 and not node4

6. 截获主机node1 发送的所有数据

1
tcpdump -i eth0 src host node1

7. 监视所有发送到主机node1 的数据包

1
tcpdump -i eth0 dst host node1

8. 监视指定主机和端口的数据包

1
tcpdump -i eth0 port 8080 and host node1

9. 监视指定网络的数据包,如本机与192.168网段通信的数据包,”-c 10”表示只抓取10个包

1
tcpdump -i eth0 -c 10 net 192.168

10. 打印所有通过网关snup的ftp数据包

1
tcpdump 'gateway snup and (port ftp or ftp-data)'

注意,表达式被单引号括起来了,这可以防止shell对其中的括号进行错误解析

11. 抓取ping包

1
2
==指定主机抓ping包==
tcpdump -c 5 -nn -i eth0 icmp and src 192.168.100.62

12. 抓取到本机22端口包

1
tcpdump -c 10 -nn -i eth0 tcp dst port 22

13. 解析包数据

1
tcpdump -c 2 -q -XX -vvv -nn -i eth0 tcp dst port 22

1,下载安装包

2,linux系统配置

不使用hugepages

1
cat /proc/sys/vm/nr_hugepages

确保其值为零,如果不是请修改执行下面操作。

1
2
3
4
5
echo 0>/proc/sys/vm/nr_hugepages

echo never >> /sys/kernel/mm/transparent_hugepage/enabled

echo never >> /sys/kernel/mm/transparent_hugepage/defrag

软连接限制

65535已经是mongo推荐的设置的,不需要太大

echo ‘ulimit -n 655350’ >> /etc/profile

这里要到etc/security/limits.conf看看是否已经配置过了,如果配置过直接修改,不要echo了,无效 echo ‘* hard nofile 655350’ >> /etc/security/limits.conf

1
2
3
4
5
echo '* soft nofile 655350' **>>** /etc/security/limits.conf

echo '* soft nproc 655350' **>>** /etc/security/limits.conf

echo '* hard nproc 655350' **>>** /etc/security/limits.conf

3, 建用户

useradd -d /home/mongo364 -m mongo364

passwd mongo364

chage -M 99999 mongo364

建数据目录

mkdir -p /data01/mongodata/key

mkdir -p /data01/mongodata/shard1

mkdir /data01/mongodata/config-replica-set

修改文件夹owner: chown -R mongo364:mongo364 /data01/mongodata

在key目录下,建security文件,内容:lbipshardkey

chmod 400 security 设置只读

4,拷贝包,解压

注意:下面的配置文件中的security在第一轮都不要加,创建出超级帐号后,再加重启

注意:

path: “../log/shard1.log”

日志文件启动前要先建好

5,配置shard节点

vim startshard1.sh

numactl –interleave=all /home/mongo364/mongodb-linux-x86_64-rhel70-3.6.4/bin/mongod -f ./conf/shard1.conf

对应建配置文件.//shard1.conf

systemLog:

destination: file

path: “../log/shard1.log”

logAppend: true

storage:

journal:

​ enabled: true

dbPath: “/data06/mongodata/shard1”

directoryPerDB: true

engine: wiredTiger

wiredTiger:

​ engineConfig:

​ cacheSizeGB: 1

​ directoryForIndexes: true

​ journalCompressor: zlib

​ collectionConfig:

​ blockCompressor: zlib

​ indexConfig:

​ prefixCompression: true

security:

​ authorization: enabled

​ keyFile: “/data01/mongodata/key/security”

net:

​ port: 10000

​ bindIp: 1x.xx.23.223

processManagement:

​ fork: true

sharding:

​ clusterRole: shardsvr

replication:

​ oplogSizeMB: 200000

​ replSetName: shard1

同样把另外两个配好

启动

将三个节点,组合成一个shard

./mongo 1x.xx.23.223:10000

config = {_id: ‘shard3’, members: [

​ {_id: 0, host: ‘1x.xx.22.177:14000’},

​ {_id: 1, host: ‘1x.xx.23.244:14000’, arbiterOnly: true},

​ {_id: 2, host: ‘1x.xx.23.245:14000’}]

​ }

rs.initiate(config)

创建用户

进到primary节点

一定要use admin,否则是在test下

db.createUser({user: “root”, pwd: “xxx,123”, roles:[{role:”root”, db:”admin”}]}) db.createUser({user: “admin”, pwd: “xxx,123”, roles: [{role:”userAdminAnyDatabase”, db:”admin”}]})

db.system.users.find().pretty()

8.配置节点

vim startconfig-replica-set.sh

/home/mongo364/mongodb-linux-x86_64-rhel70-3.6.4/bin/mongod -f ./security/config-replica-set.conf

vim config-replica-set.conf

systemLog:

​ destination: file

​ path: “../log/configServer-replica-set.log”

​ logAppend: true

storage:

​ journal:

​ enabled: true

​ dbPath: “/data06/mongodata/config-replica-set”

​ directoryPerDB: true

​ engine: wiredTiger

​ wiredTiger:

​ engineConfig:

​ cacheSizeGB: 2

​ directoryForIndexes: true

​ journalCompressor: zlib

​ collectionConfig:

​ blockCompressor: zlib

​ indexConfig:

​ prefixCompression: true

net:

​ port: 40000

​ bindIp: 1x.xx.23.223

processManagement:

​ fork: true

sharding:

​ clusterRole: configsvr

replication:

​ replSetName: csReplSet

security:

​ authorization: enabled

​ keyFile: “/data06/mongodata/key/security”

登录:./mongo 1x.xx.23.223:40000

config = {_id: ‘csReplSet’,configsvr:true, members: [

​ {_id: 0, host: ‘1x.xx.23.223:40000’},

​ {_id: 1, host: ‘1x.xx.23.224:40000’},

​ {_id: 2, host: ‘1x.xx.23.226:40000’}] }

rs.initiate(config)

对secondary执行

SECONDARY> rs.slaveOk();

去到primary节点创建用户

db.createUser({user: “root”, pwd: “xxx,123”, roles:[{role:”root”, db:”admin”}]}) db.createUser({user: “admin”, pwd: “xxx,123”, roles: [{role:”userAdminAnyDatabase”, db:”admin”}]})

路由节点:

vim startmongos.sh

/home/mongo364/mongodb-linux-x86_64-rhel70-3.6.4/bin/mongos -f ./security/mongos.conf

mongos.conf

systemLog:

​ destination: file

​ path: “../log/mongos.log”

​ logAppend: true

net:

​ port: 49000

sharding:

​ configDB: csReplSet/1x.xx.23.223:40000,1x.xx.23.224:40000,1x.xx.23.226:40000

processManagement:

​ fork: true

security:

​ keyFile: “/data06/mongodata/key/security”

分别启动路由节点

开始加鉴权

各个配置文件加上security

关闭 重启

加分片

登入mongos 如 ./mongo localhost:49000

use admin

sh.addShard(“shard1/1x.xx.23.223:10000,1x.xx.23.224:10000,1x.xx.23.226:10000”)

sh.addShard(“shard2/1x.xx.23.244:20000,1x.xx.23.245:20000,1x.xx.23.226:20000”)

db.runCommand( { listshards : 1 } ) 可查看已加入的分片db.adminCommand({ listShards: 1 })

问题:

1, [main] permissions on /data06/mongodata/key/security are too open

权限太大,需要降低权限

chmod 400 security

2,yml解析错误

https://docs.mongodb.com/manual/reference/configuration-options/#replication-options

去看关键字对不对

注意::后面必须有个空格

组建复制集

rs.initiate(config)

{

​ “ok” : 0,

​ “errmsg” : “replSetInitiate quorum check failed because not all proposed set members responded affirmatively: 1x.xx.23.226:40000 failed with Connection refused, 1x.xx.23.224:40000 failed with Connection refused”,

​ “code” : 74,

​ “codeName” : “NodeNotFound”,

​ “$gleStats” : {

​ “lastOpTime” : Timestamp(0, 0),

​ “electionId” : ObjectId(“000000000000000000000000”)

​ }

}

配置文件中加 bindIp参数