k8s二進(jìn)制部署+高可用master

0.服務(wù)器規(guī)劃

角色 IP 組件

k8s-master1 192.168.31.63 kube-apiserver

kube-controller-manager

kube-scheduler

etcd

k8s-master2 192.168.31.64 kube-apiserver

kube-controller-manager

kube-scheduler

k8s-node1 192.168.31.65 kubelet

kube-proxy

docker

etcd

k8s-node2 192.168.31.66 kubelet

kube-proxy

docker

etcd

Load?Balancer(Master) 192.168.31.61

192.168.31.60 (VIP) Nginx L4

Load?Balancer(Backup) 192.168.31.62 Nginx L4

1.系統(tǒng)初始化

關(guān)閉防火墻:

# systemctl stop firewalld

# systemctl disable firewalld

關(guān)閉selinux:

# setenforce 0 # 臨時(shí)

# sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久

關(guān)閉swap:

# swapoff -a? # 臨時(shí)

# vim /etc/fstab? # 永久

同步系統(tǒng)時(shí)間:

# ntpdate time.windows.com

添加hosts:

# vim /etc/hosts

192.168.31.63 k8s-master1

192.168.31.64 k8s-master2

192.168.31.65 k8s-node1

192.168.31.66 k8s-node2

修改主機(jī)名:

hostnamectl set-hostname k8s-master1

2.Etcd集群

可在任意節(jié)點(diǎn)完成以下操作兄猩。

2.1 生成etcd證書

# cd TLS/etcd

安裝cfssl工具:

# ./cfssl.sh

修改請(qǐng)求文件中hosts字段包含所有etcd節(jié)點(diǎn)IP:

# vi server-csr.json

{

? ? "CN": "etcd",

? ? "hosts": [

? ? ? ? "192.168.31.63",

? ? ? ? "192.168.31.64",

? ? ? ? "192.168.31.65"

? ? ? ? ],

? ? "key": {

? ? ? ? "algo": "rsa",

? ? ? ? "size": 2048

? ? },

? ? "names": [

? ? ? ? {

? ? ? ? ? ? "C": "CN",

? ? ? ? ? ? "L": "BeiJing",

? ? ? ? ? ? "ST": "BeiJing"

? ? ? ? }

? ? ]

}

# ./generate_etcd_cert.sh

# ls *pem

ca-key.pem? ca.pem? server-key.pem? server.pem

2.2 部署三個(gè)Etcd節(jié)點(diǎn)

# tar zxvf etcd.tar.gz

# cd etcd

# cp TLS/etcd/ssl/{ca,server,server-key}.pem ssl

分別拷貝到Etcd三個(gè)節(jié)點(diǎn):

# scp –r etcd root@192.168.31.63:/opt

# scp etcd.service root@192.168.31.63:/usr/lib/systemd/system

登錄三個(gè)節(jié)點(diǎn)修改配置文件 名稱和IP:

# vi /opt/etcd/cfg/etcd.conf

#[Member]

ETCD_NAME="etcd-1"

ETCD_DATA_DIR="/var/lib/etcd/default.etcd"

ETCD_LISTEN_PEER_URLS="https://192.168.31.63:2380"

ETCD_LISTEN_CLIENT_URLS="https://192.168.31.63:2379"

#[Clustering]

ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.31.63:2380"

ETCD_ADVERTISE_CLIENT_URLS="https://192.168.31.63:2379"

ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.31.63:2380,etcd-2=https://192.168.31.64:2380,etcd-3=https://192.168.31.65:2380"

ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"

ETCD_INITIAL_CLUSTER_STATE="new"

# systemctl start etcd

# systemctl enable etcd

2.3 查看集群狀態(tài)

# /opt/etcd/bin/etcdctl \

> --ca-file=/opt/etcd/ssl/ca.pem --cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem \

> --endpoints="https://192.168.31.63:2379,https://192.168.31.64:2379,https://192.168.31.65:2379" \

> cluster-health

member 37f20611ff3d9209 is healthy: got healthy result from https://192.168.31.63:2379

member b10f0bac3883a232 is healthy: got healthy result from https://192.168.31.64:2379

member b46624837acedac9 is healthy: got healthy result from https://192.168.31.65:2379

cluster is healthy

3.部署Master Node

3.1生成apiserver證書

# cd TLS/k8s

修改請(qǐng)求文件中hosts字段包含所有etcd節(jié)點(diǎn)IP:

# vi server-csr.json

{

? ? "CN": "kubernetes",

? ? "hosts": [

? ? ? "10.0.0.1",

? ? ? "127.0.0.1",

? ? ? "kubernetes",

? ? ? "kubernetes.default",

? ? ? "kubernetes.default.svc",

? ? ? "kubernetes.default.svc.cluster",

? ? ? "kubernetes.default.svc.cluster.local",

? ? ? "192.168.31.60",

? ? ? "192.168.31.61",

? ? ? "192.168.31.62",

? ? ? "192.168.31.63",

? ? ? "192.168.31.64",

? ? ? "192.168.31.65",

? ? ? "192.168.31.66"

? ? ],

? ? "key": {

? ? ? ? "algo": "rsa",

? ? ? ? "size": 2048

? ? },

? ? "names": [

? ? ? ? {

? ? ? ? ? ? "C": "CN",

? ? ? ? ? ? "L": "BeiJing",

? ? ? ? ? ? "ST": "BeiJing",

? ? ? ? ? ? "O": "k8s",

? ? ? ? ? ? "OU": "System"

? ? ? ? }

? ? ]

}

# ./generate_k8s_cert.sh

# ls *pem

ca-key.pem? ca.pem? kube-proxy-key.pem? kube-proxy.pem? server-key.pem? server.pem

3.2 部署apiserver,controller-manager和scheduler

在Master節(jié)點(diǎn)完成以下操作肖卧。

二進(jìn)制包下載地址:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.16.md#v1161

二進(jìn)制文件位置:kubernetes/serverr/bin

# tar zxvf k8s-master.tar.gz

# cd kubernetes

# cp TLS/k8s/ssl/*.pem ssl

# cp –rf kubernetes /opt

# cp kube-apiserver.service kube-controller-manager.service kube-scheduler.service /usr/lib/systemd/system

# cat /opt/kubernetes/cfg/kube-apiserver.conf

KUBE_APISERVER_OPTS="--logtostderr=false \

--v=2 \

--log-dir=/opt/kubernetes/logs \

--etcd-servers=https://192.168.31.63:2379,https://192.168.31.64:2379,https://192.168.31.65:2379 \

--bind-address=192.168.31.63 \

--secure-port=6443 \

--advertise-address=192.168.31.63 \

……

# systemctl start kube-apiserver

# systemctl start kube-controller-manager

# systemctl start kube-scheduler

# systemctl enable kube-apiserver

# systemctl enable kube-controller-manager

# systemctl enable kube-scheduler

3.3 啟用TLS Bootstrapping

為kubelet TLS Bootstrapping 授權(quán):

# cat /opt/kubernetes/cfg/token.csv

c47ffb939f5ca36231d9e3121a252940,kubelet-bootstrap,10001,"system:node-bootstrapper"

格式:token,用戶,uid,用戶組

給kubelet-bootstrap授權(quán):

kubectl create clusterrolebinding kubelet-bootstrap \

--clusterrole=system:node-bootstrapper \

--user=kubelet-bootstrap

token也可自行生成替換:

head -c 16 /dev/urandom | od -An -t x | tr -d ' '

但apiserver配置的token必須要與node節(jié)點(diǎn)bootstrap.kubeconfig配置里一致窍蓝。

4.部署Worker Node

4.1安裝Docker

二進(jìn)制包下載地址:https://download.docker.com/linux/static/stable/x86_64/

# tar zxvf k8s-node.tar.gz

# tar zxvf docker-18.09.6.tgz

# mv docker/* /usr/bin

# mkdir /etc/docker

# mv daemon.json /etc/docker

# mv docker.service /usr/lib/systemd/system

# systemctl start docker

# systemctl enable docker

4.2 部署kubelet和kube-proxy

拷貝證書到Node:

# cd TLS/k8s

# scp ca.pem kube-proxy*.pem root@192.168.31.65:/opt/kubernetes/ssl/

# cp kube-apiserver.service kube-controller-manager.service kube-

# tar zxvf k8s-node.tar.gz

# mv kubernetes /opt

# cp kubelet.service kube-proxy.service /usr/lib/systemd/system

修改以下三個(gè)文件中IP地址:

# grep 192 *

bootstrap.kubeconfig:? ? server: https://192.168.31.63:6443

kubelet.kubeconfig:? ? server: https://192.168.31.63:6443

kube-proxy.kubeconfig:? ? server: https://192.168.31.63:6443

修改以下兩個(gè)文件中主機(jī)名:

# grep hostname *

kubelet.conf:--hostname-override=k8s-node1 \

kube-proxy-config.yml:hostnameOverride: k8s-node1

# systemctl start kubelet

# systemctl start kube-proxy

# systemctl enable kubelet

# systemctl enable kube-proxy

4.3 允許給Node頒發(fā)證書

# kubectl get csr

# kubectl certificate approve node-csr-MYUxbmf_nmPQjmH3LkbZRL2uTO-_FCzDQUoUfTy7YjI

# kubectl get node

4.4 部署CNI網(wǎng)絡(luò)

二進(jìn)制包下載地址:https://github.com/containernetworking/plugins/releases

# mkdir /opt/cni/bin /etc/cni/net.d

# tar zxvf cni-plugins-linux-amd64-v0.8.2.tgz –C /opt/cni/bin

確保kubelet啟用CNI:

# cat /opt/kubernetes/cfg/kubelet.conf

--network-plugin=cni

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/

在Master執(zhí)行:

kubectl apply –f kube-flannel.yaml

# kubectl get pods -n kube-system

NAME? ? ? ? ? ? ? ? ? ? ? ? ? READY? STATUS? ? RESTARTS? AGE

kube-flannel-ds-amd64-5xmhh? 1/1? ? Running? 6? ? ? ? ? 171m

kube-flannel-ds-amd64-ps5fx? 1/1? ? Running? 0? ? ? ? ? 150m

4.5 授權(quán)apiserver訪問kubelet

為提供安全性,kubelet禁止匿名訪問屋灌,必須授權(quán)才可以倔约。

# cat /opt/kubernetes/cfg/kubelet-config.yml

……

authentication:

? anonymous:

? ? enabled: false

? webhook:

? ? cacheTTL: 2m0s

? ? enabled: true

? x509:

clientCAFile: /opt/kubernetes/ssl/ca.pem

……

# kubectl apply –f apiserver-to-kubelet-rbac.yaml

5.部署Web UI和DNS

https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/

# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta4/aio/deploy/recommended.yaml

# vi recommended.yaml

kind: Service

apiVersion: v1

metadata:

? labels:

? ? k8s-app: kubernetes-dashboard

? name: kubernetes-dashboard

? namespace: kubernetes-dashboard

spec:

? type: NodePort

? ports:

? ? - port: 443

? ? ? targetPort: 8443

? ? ? nodePort: 30001

? selector:

? ? k8s-app: kubernetes-dashboard

# kubectl apply -f recommended.yaml

創(chuàng)建service account并綁定默認(rèn)cluster-admin管理員集群角色:

# cat dashboard-adminuser.yaml

apiVersion: v1

kind: ServiceAccount

metadata:

? name: admin-user

? namespace: kubernetes-dashboard

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

? name: admin-user

roleRef:

? apiGroup: rbac.authorization.k8s.io

? kind: ClusterRole

? name: cluster-admin

subjects:

- kind: ServiceAccount

? name: admin-user

? namespace: kubernetes-dashboard

獲取token:

# kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

訪問地址:http://NodeIP:30001

使用輸出的token登錄Dashboard佳遣。

# kubectl apply –f coredns.yaml

# kubectl get pods -n kube-system

6.Master高可用

5.1 部署Master組件(與Master1一致)

拷貝master1/opt/kubernetes和service文件:

# scp –r /opt/kubernetes root@192.168.31.64:/opt

# scp –r /opt/etcd/ssl root@192.168.31.64:/opt/etcd

# scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@192.168.31.64:/usr/lib/systemd/system

修改apiserver配置文件為本地IP:

# cat /opt/kubernetes/cfg/kube-apiserver.conf

KUBE_APISERVER_OPTS="--logtostderr=false \

--v=2 \

--log-dir=/opt/kubernetes/logs \

--etcd-servers=https://192.168.31.63:2379,https://192.168.31.64:2379,https://192.168.31.65:2379 \

--bind-address=192.168.31.64 \

--secure-port=6443 \

--advertise-address=192.168.31.64 \

……

# systemctl start kube-apiserver

# systemctl start kube-controller-manager

# systemctl start kube-scheduler

# systemctl enable kube-apiserver

# systemctl enable kube-controller-manager

# systemctl enable kube-scheduler

5.2 部署Nginx負(fù)載均衡

nginx rpm包:http://nginx.org/packages/rhel/7/x86_64/RPMS/

# rpm -vih http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.16.0-1.el7.ngx.x86_64.rpm

# vim /etc/nginx/nginx.conf

……

stream {

? ? log_format? main? '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';

? ? access_log? /var/log/nginx/k8s-access.log? main;

? ? upstream k8s-apiserver {

? ? ? ? ? ? ? ? server 192.168.31.63:6443;

? ? ? ? ? ? ? ? server 192.168.31.64:6443;

? ? ? ? ? ? }


? ? server {

? ? ? listen 6443;

? ? ? proxy_pass k8s-apiserver;

? ? }

}

……

# systemctl start nginx

# systemctl enable nginx

5.3 Nginx+Keepalived高可用

主節(jié)點(diǎn):

# yum install keepalived

# vi /etc/keepalived/keepalived.conf

global_defs {

? notification_email {

? ? acassen@firewall.loc

? ? failover@firewall.loc

? ? sysadmin@firewall.loc

? }

? notification_email_from Alexandre.Cassen@firewall.loc?

? smtp_server 127.0.0.1

? smtp_connect_timeout 30

? router_id NGINX_MASTER

}

vrrp_script check_nginx {

? ? script "/etc/keepalived/check_nginx.sh"

}

vrrp_instance VI_1 {

? ? state MASTER

? ? interface ens33

? ? virtual_router_id 51 # VRRP 路由 ID實(shí)例煤搜,每個(gè)實(shí)例是唯一的

? ? priority 100? ? # 優(yōu)先級(jí)免绿,備服務(wù)器設(shè)置 90

? ? advert_int 1? ? # 指定VRRP 心跳包通告間隔時(shí)間,默認(rèn)1秒

? ? authentication {

? ? ? ? auth_type PASS? ? ?

? ? ? ? auth_pass 1111

? ? }?

? ? virtual_ipaddress {

? ? ? ? 192.168.31.60/24

? ? }

? ? track_script {

? ? ? ? check_nginx

? ? }

}

# cat /etc/keepalived/check_nginx.sh

#!/bin/bash

count=$(ps -ef |grep nginx |egrep -cv "grep|$$")

if [ "$count" -eq 0 ];then

? ? exit 1

else

? ? exit 0

fi

# systemctl start keepalived

# systemctl enable keepalived

備節(jié)點(diǎn):

# cat /etc/keepalived/keepalived.conf


global_defs {

? notification_email {

? ? acassen@firewall.loc

? ? failover@firewall.loc

? ? sysadmin@firewall.loc

? }

? notification_email_from Alexandre.Cassen@firewall.loc?

? smtp_server 127.0.0.1

? smtp_connect_timeout 30

? router_id NGINX_BACKUP

}

vrrp_script check_nginx {

? ? script "/etc/keepalived/check_nginx.sh"

}

vrrp_instance VI_1 {

? ? state BACKUP

? ? interface ens33

? ? virtual_router_id 51 # VRRP 路由 ID實(shí)例擦盾,每個(gè)實(shí)例是唯一的

? ? priority 90? ? # 優(yōu)先級(jí)嘲驾,備服務(wù)器設(shè)置 90

? ? advert_int 1? ? # 指定VRRP 心跳包通告間隔時(shí)間,默認(rèn)1秒

? ? authentication {

? ? ? ? auth_type PASS? ? ?

? ? ? ? auth_pass 1111

? ? }?

? ? virtual_ipaddress {

? ? ? ? 192.168.31.60/24

? ? }

? ? track_script {

? ? ? ? check_nginx

? ? }

}

# cat /etc/keepalived/check_nginx.sh

#!/bin/bash

count=$(ps -ef |grep nginx |egrep -cv "grep|$$")

if [ "$count" -eq 0 ];then

? ? exit 1

else

? ? exit 0

fi

# systemctl start keepalived

# systemctl enable keepalived

測(cè)試:

# ip a

2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

? ? link/ether 00:0c:29:9d:ee:30 brd ff:ff:ff:ff:ff:ff

? ? inet 192.168.31.63/24 brd 192.168.31.255 scope global noprefixroute ens33

? ? ? valid_lft forever preferred_lft forever

? ? inet 192.168.31.60/24 scope global secondary ens33

? ? ? valid_lft forever preferred_lft forever

? ? inet6 fe80::20c:29ff:fe9d:ee30/64 scope link

? ? ? valid_lft forever preferred_lft forever

關(guān)閉nginx測(cè)試VIP是否漂移到備節(jié)點(diǎn)迹卢。

5.4 修改Node連接VIP

測(cè)試VIP是否正常工作:

# curl -k --header "Authorization: Bearer c47ffb939f5ca36231d9e3121a252940" https://192.168.31.60:6443/version

{

? "major": "1",

? "minor": "16",

? "gitVersion": "v1.16.0",

? "gitCommit": "2bd9643cee5b3b3a5ecbd3af49d09018f0773c77",

? "gitTreeState": "clean",

? "buildDate": "2019-09-18T14:27:17Z",

? "goVersion": "go1.12.9",

? "compiler": "gc",

? "platform": "linux/amd64"

}

將Node連接VIP:

# cd /opt/kubernetes/cfg

# grep 192 *

bootstrap.kubeconfig:? ? server: https://192.168.31.63:6443

kubelet.kubeconfig:? ? server: https://192.168.31.636443

kube-proxy.kubeconfig:? ? server: https://192.168.31.63:6443

批量修改:

sed -i 's#192.168.31.63#192.168.31.60#g' *

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辽故,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子榕暇,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彤枢,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡筒饰,警方通過查閱死者的電腦和手機(jī)缴啡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓷们,“玉大人业栅,你說我怎么就攤上這事∶危” “怎么了碘裕?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)攒钳。 經(jīng)常有香客問我帮孔,道長(zhǎng),這世上最難降的妖魔是什么不撑? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任文兢,我火速辦了婚禮,結(jié)果婚禮上焕檬,老公的妹妹穿的比我還像新娘姆坚。我一直安慰自己,他們只是感情好实愚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布兼呵。 她就那樣靜靜地躺著,像睡著了一般腊敲。 火紅的嫁衣襯著肌膚如雪击喂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天兔仰,我揣著相機(jī)與錄音茫负,去河邊找鬼。 笑死乎赴,一個(gè)胖子當(dāng)著我的面吹牛忍法,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播榕吼,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼饿序,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了羹蚣?” 一聲冷哼從身側(cè)響起原探,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后咽弦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體徒蟆,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年型型,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了段审。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡闹蒜,死狀恐怖寺枉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绷落,我是刑警寧澤姥闪,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站砌烁,受9級(jí)特大地震影響筐喳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜往弓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一疏唾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧函似,春花似錦槐脏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蔑担,卻和暖如春牌废,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背啤握。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工鸟缕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人排抬。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓懂从,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蹲蒲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子番甩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353