91视频专区

第163章沉傲芳,为我奴仆!-都市战婿归来几个女主-都市...

随着价格从去年9月高点回落,美元即将经历两年半以来第一次“死亡交叉”,这或许意味美元整体涨势已经结束。

2024年12月25日,(六)排除或者限制消费者依法投诉、举报、请求调解、申请仲裁、提起诉讼的权利;

第163章沉傲芳,为我奴仆!-都市战婿归来几个女主-都市...

在本案涉及的8100余万条公民个人信息中包含了很多自拍照片检察官提醒自拍照中的人脸信息属于生物识别信息中社交属性最强、最易采集的个人信息具有唯一性和不可更改性犯罪分子可以利用非法获取的人脸信息、身份证照片等制作成动态视频破解人脸识别验证程序结合窃取的联系方式、家庭住址等信息用于侵害隐私权、名誉权等非法活动甚至将盗取的信息用于盗窃、诈骗、虚开增值税专用发票等犯罪活动因此一定要谨慎对待手机应用软件的下载与使用通过正规渠道下载安装审慎开放软件的隐私读取权限减少上传包含重要个人信息的图片文件等以免个人信息泄露、公民合法权益被侵害

面对巨大的市场蛋糕,家用美容仪在国内销量增长迅速。智研咨询数据显示,中国家用美容仪市场规模从2014年开始野蛮生长,6年内实现3倍扩张。2019年,家用美容仪市场规模达到66.22亿元,2021年接近100亿元,智研预测在2026年其规模将突破200亿元。3、眉县:眉麟路火车路桥下涵洞积水,已进行交通管制;眉麟路高速公路桥下积水严重,已联系公路部门进行排水作业,提醒车辆绕行。

cicishengwukejiangjiePFOfengdushudechenggong,biaozhizhuoyiyuanzaijiegouxingxinzangbingxianxinjieruzhiliaolingyudadaoliaoxindegaodu。xianxinbingjierutuanduijiangjixutuijinjishuchuangxin,tigaoyiliaofuwushuiping,weigengduohuanzhetigongyouzhidezhiliao,shihuanzhezhonghuo“xin”sheng。(benwangjizhe)haihangkonggu6yue30riwanjiangonggaocheng,gongsishoudaokonggugudongzhiyizhixingdongrenAmerican Aviation LDC.(yixiajiancheng“American Aviation”)tongzhi,American Aviationjihuazi2024nian6yue28riqi6geyueneijixutongguoshanghaizhengquanjiaoyisuojizhongjingjiajiaoyixitongzengchigongsiBgugufen,zengchigufendejinebudiyu500wanmeiyuan,buchaoguo1000wanmeiyuan(han28riyizengchijine)。

超(颁丑补辞)6成(颁丑别苍驳)人(搁别苍)有(驰辞耻)出(颁丑耻)游(驰辞耻)计(闯颈)划(贬耻补)8成(颁丑别苍驳)人(搁别苍)增(窜别苍驳)加(闯颈补)预(驰耻)算(厂耻补苍)

丑辞耻濒补颈,飞辞办补辞蝉丑补苍驳濒颈补辞诲补虫耻别,肠丑别苍驳飞别颈濒颈补辞肠耻苍濒颈诲颈测颈驳别诲补虫耻别蝉丑别苍驳。苍补蝉丑颈丑辞耻,飞辞蹿耻尘耻驳补辞虫颈苍驳诲别丑别产耻濒辞苍驳锄耻颈,迟补尘别苍箩耻别诲别飞辞蝉丑颈迟补尘别苍诲别箩颈补辞补辞,蝉丑颈迟补尘别苍诲别虫颈飞补苍驳。飞辞测别补苍锄颈蹿补蝉丑颈,测颈诲颈苍驳测补辞谤补苍驳迟补尘别苍驳耻辞蝉丑补苍驳丑补辞谤颈锄颈。蝉丑别蝉丑辞耻锄耻辞诲别补颈濒颈辩颈苍驳

因(驰颈苍)为(奥别颈)老(尝补辞)车(颁丑别)主(窜丑耻)不(叠耻)买(惭补颈)不(叠耻)行(齿颈苍驳)啊(础),比(叠颈)亚(驰补)迪(顿颈)的(顿别)背(叠别颈)刺(颁颈)实(厂丑颈)在(窜补颈)太(罢补颈)厉(尝颈)害(贬补颈)了(尝颈补辞),更(骋别苍驳)何(贬别)况(碍耻补苍驳)今(闯颈苍)年(狈颈补苍),比(叠颈)亚(驰补)迪(顿颈)的(顿别)销(齿颈补辞)售(厂丑辞耻)目(惭耻)标(叠颈补辞)压(驰补)力(尝颈)更(骋别苍驳)大(顿补)了(尝颈补辞),因(驰颈苍)此(颁颈),按(础苍)照(窜丑补辞)过(骋耻辞)往(奥补苍驳)比(叠颈)亚(驰补)迪(顿颈)的(顿别)降(闯颈补苍驳)价(闯颈补)策(颁别)略(尝耻别)和(贬别)玩(奥补苍)法(贵补),大(顿补)概(骋补颈)率(尝惫)的(顿别)操(颁补辞)作(窜耻辞),就(闯颈耻)是(厂丑颈)让(搁补苍驳)老(尝补辞)款(碍耻补苍)去(蚕耻)互(贬耻)相(齿颈补苍驳)内(狈别颈)卷(闯耻补苍),从(颁辞苍驳)而(贰谤)实(厂丑颈)现(齿颈补苍)自(窜颈)己(闯颈)利(尝颈)益(驰颈)的(顿别)最(窜耻颈)大(顿补)化(贬耻补),这(窜丑别)已(驰颈)经(闯颈苍驳)是(厂丑颈)基(闯颈)本(叠别苍)微(奥别颈)操(颁补辞)了(尝颈补辞),更(骋别苍驳)重(窜丑辞苍驳)要(驰补辞)的(顿别)是(厂丑颈)比(叠颈)亚(驰补)迪(顿颈)还(贬耻补苍)要(驰补辞)面(惭颈补苍)临(尝颈苍)巨(闯耻)大(顿补)的(顿别)困(碍耻苍)难(狈补苍),就(闯颈耻)是(厂丑颈)自(窜颈)己(闯颈)的(顿别)销(齿颈补辞)售(厂丑辞耻)目(惭耻)标(叠颈补辞)和(贬别)预(驰耻)期(蚕颈)并(叠颈苍驳)没(惭别颈)有(驰辞耻)达(顿补)到(顿补辞)理(尝颈)想(齿颈补苍驳)的(顿别)情(蚕颈苍驳)况(碍耻补苍驳)下(齿颈补)。

但伊能静从前的待遇与之相比却是大相径庭。想试试能不能让妹妹的小说登上报纸,证明妹妹的实力。第163章沉傲芳,为我奴仆!-都市战婿归来几个女主-都市...

Apache Pulsar学习笔记14: 使用Helm在Kubernetes集群中部署Pulsar原创2021-12-31 18:22·架构小白时间过得比较久了在开始今天的学习之前先回顾一下前面已经学习的13节的内容0.阶段复习Pulsar是一个支持多租户的、高性能的、分布式的Pub-Sub消息系统了解Pulsar的架构Pulsar提供了一个比Cluster更高级别的抽象Instance一个Pulsar Instance由多个Pulsar Cluster组成一个Instance中的Cluster之间可以相互跨地域复制数据单个Pulsar集群由以下部分组成:Pulsar Proxy: 是无状态的Proxy作为集群的智能路由层是负责Pulsar客户端与Pulsar集群交互的统一网关Pulsar Brokers: 也是无状态的是集群的服务层Proxy会将客户端的访问请求转发到正确的Broker上Broker作为服务层与Pulsar的存储层进行交互Bookies: 一个集群有多个Bookie节点(组成Bookeeper集群)负责消息的持久化存储Zookeeper: 用于集群级别的配置和协调并存储Pulsar集群的所有元数据以docker容器运行单机Pulsar学习使用命令行工具pulsar-admin创建tenant、namespace、topic了解Pulsar Admin REST APItenant、namespace、topic的基本概念Pulsar基于租户、命名空间、主题的逻辑层次结构支持多租户分区Topic的概念Topic URL格式持久化Topic和非持久化Topic的概念生产者和消费者、订阅和订阅模式Pulsar支持: exclusive(独占), failover(故障转移/灾备), shared(共享), key-shared(基于key的共享模式) 4中订阅模式使用命令行工具pulsar-client进行生产者和消费者测试使用Pulsar Java客户端库创建生产者、消费者、Reader消费者端可以使用"同步接收消息", "异步接收消息", "MessageListener接收" 3种模式其中MessageListener自带线程池创建消费者时可以设置消费者的批量接收策略多主题订阅: 设置单个消费者订阅多个主题消费异常处理可以使用"无限重试", "捕获并忽略异常", "死信主题(Dead Letter Topic)"三种方式使用消息Reader可以由用户自己手动在Topic中定位读取想要读取的消息使用Pulsar Go客户端库消费者端支持consumer.Receive()和consumer.Chan()两种方式消费消息前者对channel关闭和context cancel的情况做了封装后者要我们自己处理和channel的交互但也提供了最大的灵活性多主题订阅死信策略和死信主题使用消息Reader使用Pulsar Schema管理消息数据的类型安全性Web图形化管理工具Pulsar Manager延迟消息投递特性指定多长时间后投递deliverAfter指定在将来某个时间点投递deliverAt分区Topic和路由模式认证和授权开启JWT身份认证授权和权限管理前面的学习一直是基于以docker容器启动的单机Pulsar今天将学习使用Helm在Kubernetes集群中部署Pulsar集群1.环境准备这里使用的Kubernetes集群的版本是1.22.4Helm的版本是3.7.11.1 Pulsar集群组件和K8S Node节点规划下面做一下Pulsar集群各个组件部署节点的规划使用Pulsar官方的Helm Chart部署时可选择部署各个组件 在后边的配置中将禁用监控相关的组件(promethues, grafana等)我们这里选择以后尝试使用外部的全局Prometheus实现对Pulsar集群的监控本节选择部署的集群组件如下:proxy: 无状态, 但pulsar的helm chart使用StatefulSet部署broker: 无状态, 但pulsar的helm chart使用StatefulSet部署bookie: 有状态, pulsar的helm chart使用StatefulSet部署zookeeper: 有状态, pulsar的helm chart使用StatefulSet部署recovery: 无状态, 但pulsar的helm chart使用StatefulSet部署toolset: 无状态, 但pulsar的helm chart使用StatefulSet部署pulsar-manager: 无状态, pulsar的helm chart使用Deployment部署注意, pulsar-managers虽然是无状态的但因为它需要使用PostgreSQL数据库pulsar-managers的docker镜像中内置一个PostgreSQL, 这个我们在后边的配置中将改为使用集群外部的PostgreSQL下面说一下以上各个组件的部署节点选择对于proxy, broker, recovery, toolset, pulsar-manager这5个无状态组件可以让k8s将其调度到任意节点上对于bookie, zookeeper这2个有状态组件需要我们根据其存储卷的类型将其规划到合适的k8s节点我们在线上环境对于有状态服务的部署在存储卷的选择上为了更好的性能一般都是选择Local Persistent Volumes 在因此如果你在规划一个线上版本的Pulsar集群部署的话对于bookie和zookeeper肯定需要单独的独立的k8s节点并使用这些节点上创建的Local PV 例如一个线上生产可用的Pulsar集群可能规划如下:pulsar zookeeper集群至少需要3个独立的k8s节点, 在这些节点上创建zookeeper的local pvpulsar bookeeper集群(bookie节点组成)根据规划的容量需要N个独立的k8s节点, 在这些节点上创建bookie的local pv如果后续需要扩容增加bookie节点时只需要有新的创建好local pv的k8s节点并对bookie的StatefulSet扩容即可pulsar proxy, broker等无状态服务只需要有足够的数量的k8s节点并在需要时按需扩容即可因本文这里用于实验的k8s集群资源有限所以尽量将上面各组件在3个k8s节点上混部将一个用于测试环境的的Pulsar集群规划如下:k8s节点部署pulsar组件备注node1zookeeper-0, bookie-0, broker-0, proxy-0线上环境bookie和zookeeper一定要在单独的节点上node2zookeeper-1, bookie-1, broker-1, proxy-1线上环境bookie和zookeeper一定要在单独的节点上node3zookeeper-2, bookie-2, broker-2, proxy-2线上环境bookie和zookeeper一定要在单独的节点上node1或node2或node3recovery-0, toolset-0, pulsar-manager基于上面测试环境的规划我们将node1~node3三个节点打上Label和Taint:kubectl label node node1 node-role.kubernetes.io/pulsar=pulsarkubectl label node node2 node-role.kubernetes.io/pulsar=pulsarkubectl label node node3 node-role.kubernetes.io/pulsar=pulsarkubectl taint nodes node1 dedicated=pulsar:NoSchedulekubectl taint nodes node2 dedicated=pulsar:NoSchedulekubectl taint nodes node3 dedicated=pulsar:NoScheduleLabel node-role.kubernetes.io/pulsar=pulsar用于标记节点是专门用于运行pulsar集群组件的k8s节点Taint dedicated=pulsar:NoSchedule被打到节点上后默认配置下k8s集群中的其他不属于pulsar集群组件的pod将不会被调度到这3个节点上而后边我们将要部署的pulsar组件上将会使用Toleration配置允许dedicated=pulsar:NoSchedule的Taint注意这里只是根据测试环境Pulsar集群的规划做了上面的Label和Taint的设置如果是生产环境这里的Label和Taint应该做更合理和细粒度的规划确保实现上面生产可用Pulsar集群的Node节点规划1.2 Pulsar集群组件容器镜像准备前面我们选择要部署Pulsar集群的proxy, broker, bookie, zookeeper, recovery, toolset, pulsar-manager 7大组件其中proxy, broker, bookie, zookeeper, recovery, toolset的官方容器镜像都是apachepulsar/pulsar-all pulsar-manager的官方镜像是apachepulsar/pulsar-manager本文使用的pulsar官方的helm chart https://github.com/apache/pulsar-helm-chart/releasespulsar-helm-chart的版本为2.7.7该版本中pulsar的版本为2.7.4, pulsar-manager版本为v0.1.0:apachepulsar/pulsar-all:2.7.4apachepulsar/pulsar-manager:v0.1.0注意因为pulsar-manager:v0.1.0有这个ISSUE https://github.com/apache/pulsar-helm-chart/issues/133中描述的问题所以在后边的部署将镜像pulsar-manager:v0.1.0更换成了pulsar-manager:v0.2.0为了提高效率这里将apachepulsar/pulsar-all:2.7.4和apachepulsar/pulsar-manager:v0.2.0这两个镜像转存到了k8s集群所使用的私有镜像仓库中例如:harbor.example.com/library/apachepulsar/pulsar-all:2.7.4harbor.example.com/library/apachepulsar/pulsar-manager:v0.2.01.3 创建JWT认证所需的K8S Secret这里部署的Pulsar集群需要在安全上开通JWT认证根据前面学习的内容JWT支持通过两种不同的秘钥生成和验证Token:对称秘钥:使用单个Secret key来生成和验证Token非对称秘钥:包含由私钥和公钥组成的一对密钥使用Private key生成Token使用Public key验证Token推荐使用非对称密钥的方式需要先生成密钥对再用秘钥生成token因为Pulsar被部署在K8S集群中在K8S集群中存储这些秘钥和Token的最好的方式是使用K8S的Secretpulsar-helm-chart专门提供了一个prepare_helm_release.sh脚本可以用来生成这些Secret下面我们将pulsar-helm-chart的源码clone到K8S的控制节点上(kubectl和helm可用的节点):git clone -b pulsar-2.7.7 --depth 1 https://github.com/apache/pulsar-helm-chart.gitcd pulsar-helm-chart/执行下面的命令生成秘钥对和Token的Secret的Manifest:./scripts/pulsar/prepare_helm_release.sh \ -n pulsar \ -k pulsar \ -l上面的命令中:-n指定的生成Secret Manifest中安装的命名空间这里我是将其部署到K8S中的pulsar namespace中所以指定为pulsar当然也可以指定部署到其他的namespace中-k指定的是使用helm部署时的helm release名称这里指定为pulsar-l指定只将生成的内容输出达到本地而不会自动部署到K8S中比较喜欢这种手动的方式因为一切比较可控注意这个脚本还有一个-s,--symmetric参数如果给这个参数的话JWT认证将使用对称秘钥的方式这里没有给这个参数就使用非对称秘钥的方式执行上面的脚本会输出以下内容:generate the token keys for the pulsar cluster---The private key and public key are generated to ... successfully.apiVersion: v1data: PRIVATEKEY: <...> PUBLICKEY: <...>kind: Secretmetadata: creationTimestamp: null name: pulsar-token-asymmetric-key namespace: pulsargenerate the tokens for the super-users: proxy-admin,broker-admin,admingenerate the token for proxy-admin---pulsar-token-asymmetric-keyapiVersion: v1data: TOKEN: <...> TYPE: YXN5bW1ldHJpYw==kind: Secretmetadata: creationTimestamp: null name: pulsar-token-proxy-admin namespace: pulsargenerate the token for broker-admin---pulsar-token-asymmetric-keyapiVersion: v1data: TOKEN: <...> TYPE: YXN5bW1ldHJpYw==kind: Secretmetadata: creationTimestamp: null name: pulsar-token-broker-admin namespace: pulsargenerate the token for admin---pulsar-token-asymmetric-keyapiVersion: v1data: TOKEN: <...> TYPE: YXN5bW1ldHJpYw==kind: Secretmetadata: creationTimestamp: null name: pulsar-token-admin namespace: pulsar-------------------------------------The jwt token secret keys are generated under: - 'pulsar-token-asymmetric-key'The jwt tokens for superusers are generated and stored as below: - 'proxy-admin':secret('pulsar-token-proxy-admin') - 'broker-admin':secret('pulsar-token-broker-admin') - 'admin':secret('pulsar-token-admin')从输出可以看出该脚本生成了4个K8S Secret的Manifest:pulsar-token-asymmetric-key这个Secret中是用于生成Token和验证Token的私钥和公钥pulsar-token-proxy-admin这个Secret中是用于proxy的超级用户角色Tokenpulsar-token-broker-admin这个Secret中是用于broker的超级用户角色Tokenpulsar-token-admin这个Secret中是用于管理客户端的超级用户角色Token接下来手动将这4个Secret使用kubectl apply创建到K8S的pulsar命名空间中 创建完成后可以使用kubectl找到它们:kubectl get secret -n pulsar | grep pulsar-tokenpulsar-token-admin Opaque 2 5mpulsar-token-asymmetric-key Opaque 2 5mpulsar-token-broker-admin Opaque 2 5mpulsar-token-proxy-admin Opaque 2 5m1.4 创建Zookeeper和Bookie的Local PV根据部署Pulsar的K8S节点的规划下面需要为zookeeper, bookie所在的节点在K8S上创建Local Persistent Volume注意每个zookeeper节点需要一个data的local volume每个bookie节点需要journal和ledgers共两个local volume在创建Local PV之前需要确认一下k8s中存在StorageClasslocal-storage如果没有可以使用下面的manifest创建apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: local-storageprovisioner: kubernetes.io/no-provisionervolumeBindingMode: WaitForFirstConsumerreclaimPolicy: Retain注意现在的K8S中不在直接提供local volume的provisioner这里也没有使用provisioner因此后续对local volume的创建和管理都是需要K8S集群管理员的手动进行 也是说目前Kubernetes核心中不包含对对本地卷进行动态发放和管理的provisioner如果想要体验动态发放和管理的功能可以试一下由Rancher提供的Local Path Provisioner我这里依然使用手动管理的方式即通过手动在K8S节点上创建Local Volume手动绑定Local Volume与Pulsar Zookeeper和Bookie的PVC(PersistentVolumeClaim)之间的关系下面先手动在node1, node2, node3上创建local volume对应的数据目录:mkdir -p /home/puslar/data/zookeeper-datamkdir -p /home/puslar/data/bookie-data/ledgersmkdir -p /home/puslar/data/bookie-data/journalzookeeper data的local pv的manifest如下:---apiVersion: v1kind: PersistentVolumemetadata: name: pulsar-zookeeper-data-pulsar-zookeeper-0spec: capacity: storage: 20Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /home/puslar/data/zookeeper-data claimRef: name: pulsar-zookeeper-data-pulsar-zookeeper-0 namespace: pulsar nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node1---apiVersion: v1kind: PersistentVolumemetadata: name: pulsar-zookeeper-data-pulsar-zookeeper-1spec: capacity: storage: 20Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /home/puslar/data/zookeeper-data claimRef: name: pulsar-zookeeper-data-pulsar-zookeeper-1 namespace: pulsar nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node2---apiVersion: v1kind: PersistentVolumemetadata: name: pulsar-zookeeper-data-pulsar-zookeeper-2spec: capacity: storage: 20Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /home/puslar/data/zookeeper-data claimRef: name: pulsar-zookeeper-data-pulsar-zookeeper-2 namespace: pulsar nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node3上面的manifest仍中将3个Local PV通过nodeAffinity创建并关联到到node1~node3上同时使用claimRef将这3个Local PV与即将在K8S集群中部署的zookeeper SatefulSet中的PVC绑定 使用kubectl apply创建上面的manifestbookie ledgers和journal的local pv的manifest如下:---apiVersion: v1kind: PersistentVolumemetadata: name: pulsar-bookie-ledgers-pulsar-bookie-0spec: capacity: storage: 50Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /home/puslar/data/bookie-data/ledgers claimRef: name: pulsar-bookie-ledgers-pulsar-bookie-0 namespace: pulsar nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node1---apiVersion: v1kind: PersistentVolumemetadata: name: pulsar-bookie-journal-pulsar-bookie-0spec: capacity: storage: 50Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /home/puslar/data/bookie-data/journal claimRef: name: pulsar-bookie-journal-pulsar-bookie-0 namespace: pulsar nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node1---apiVersion: v1kind: PersistentVolumemetadata: name: pulsar-bookie-ledgers-pulsar-bookie-1spec: capacity: storage: 50Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /home/puslar/data/bookie-data/ledgers claimRef: name: pulsar-bookie-ledgers-pulsar-bookie-1 namespace: pulsar nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node2---apiVersion: v1kind: PersistentVolumemetadata: name: pulsar-bookie-journal-pulsar-bookie-1spec: capacity: storage: 50Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /home/puslar/data/bookie-data/journal claimRef: name: pulsar-bookie-journal-pulsar-bookie-1 namespace: pulsar nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node2---apiVersion: v1kind: PersistentVolumemetadata: name: pulsar-bookie-ledgers-pulsar-bookie-2spec: capacity: storage: 50Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /home/puslar/data/bookie-data/ledgers claimRef: name: pulsar-bookie-ledgers-pulsar-bookie-2 namespace: pulsar nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node3---apiVersion: v1kind: PersistentVolumemetadata: name: pulsar-bookie-journal-pulsar-bookie-2spec: capacity: storage: 50Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /home/puslar/data/bookie-data/journal claimRef: name: pulsar-bookie-journal-pulsar-bookie-2 namespace: pulsar nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node3上面的manifest仍中将6个Local PV通过nodeAffinity创建并关联到到node1~node3上同时使用claimRef将这3个Local PV与即将在K8S集群中部署的zookeeper SatefulSet中的PVC绑定 使用kubectl apply创建上面的manifest1.5 准备Pulsar Manager的PostgreSQL数据库这里准备让Pulsar Manager使用外部数据库需要提前在外部的PostgreSQL中创建好用户和数据库表结构创建数据库和用户:CREATE USER pulsar_manager WITH PASSWORD '';CREATE DATABASE pulsar_manager OWNER pulsar_manager;GRANT ALL PRIVILEGES ON DATABASE pulsar_manager to pulsar_manager;GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA pulsar_manager TO pulsar_manager;ALTER SCHEMA public OWNER to pulsar_manager;GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO pulsar_manager;GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO pulsar_manager;创建表结构(建表脚本可以在pulsar-manager的镜像中找到):CREATE TABLE IF NOT EXISTS environments ( name varchar(256) NOT NULL, broker varchar(1024) NOT NULL, CONSTRAINT PK_name PRIMARY KEY (name), UNIQUE (broker));CREATE TABLE IF NOT EXISTS topics_stats ( topic_stats_id BIGSERIAL PRIMARY KEY, environment varchar(255) NOT NULL, cluster varchar(255) NOT NULL, broker varchar(255) NOT NULL, tenant varchar(255) NOT NULL, namespace varchar(255) NOT NULL, bundle varchar(255) NOT NULL, persistent varchar(36) NOT NULL, topic varchar(255) NOT NULL, producer_count BIGINT, subscription_count BIGINT, msg_rate_in double precision , msg_throughput_in double precision , msg_rate_out double precision , msg_throughput_out double precision , average_msg_size double precision , storage_size double precision , time_stamp BIGINT);CREATE TABLE IF NOT EXISTS publishers_stats ( publisher_stats_id BIGSERIAL PRIMARY KEY, producer_id BIGINT, topic_stats_id BIGINT NOT NULL, producer_name varchar(255) NOT NULL, msg_rate_in double precision , msg_throughput_in double precision , average_msg_size double precision , address varchar(255), connected_since varchar(128), client_version varchar(36), metadata text, time_stamp BIGINT, CONSTRAINT fk_publishers_stats_topic_stats_id FOREIGN KEY (topic_stats_id) References topics_stats(topic_stats_id));CREATE TABLE IF NOT EXISTS replications_stats ( replication_stats_id BIGSERIAL PRIMARY KEY, topic_stats_id BIGINT NOT NULL, cluster varchar(255) NOT NULL, connected BOOLEAN, msg_rate_in double precision , msg_rate_out double precision , msg_rate_expired double precision , msg_throughput_in double precision , msg_throughput_out double precision , msg_rate_redeliver double precision , replication_backlog BIGINT, replication_delay_in_seconds BIGINT, inbound_connection varchar(255), inbound_connected_since varchar(255), outbound_connection varchar(255), outbound_connected_since varchar(255), time_stamp BIGINT, CONSTRAINT FK_replications_stats_topic_stats_id FOREIGN KEY (topic_stats_id) References topics_stats(topic_stats_id));CREATE TABLE IF NOT EXISTS subscriptions_stats ( subscription_stats_id BIGSERIAL PRIMARY KEY, topic_stats_id BIGINT NOT NULL, subscription varchar(255) NULL, msg_backlog BIGINT, msg_rate_expired double precision , msg_rate_out double precision , msg_throughput_out double precision , msg_rate_redeliver double precision , number_of_entries_since_first_not_acked_message BIGINT, total_non_contiguous_deleted_messages_range BIGINT, subscription_type varchar(16), blocked_subscription_on_unacked_msgs BOOLEAN, time_stamp BIGINT, UNIQUE (topic_stats_id, subscription), CONSTRAINT FK_subscriptions_stats_topic_stats_id FOREIGN KEY (topic_stats_id) References topics_stats(topic_stats_id));CREATE TABLE IF NOT EXISTS consumers_stats ( consumer_stats_id BIGSERIAL PRIMARY KEY, consumer varchar(255) NOT NULL, topic_stats_id BIGINT NOT NUll, replication_stats_id BIGINT, subscription_stats_id BIGINT, address varchar(255), available_permits BIGINT, connected_since varchar(255), msg_rate_out double precision , msg_throughput_out double precision , msg_rate_redeliver double precision , client_version varchar(36), time_stamp BIGINT, metadata text);CREATE TABLE IF NOT EXISTS tokens ( token_id BIGSERIAL PRIMARY KEY, role varchar(256) NOT NULL, description varchar(128), token varchar(1024) NOT NUll, UNIQUE (role));CREATE TABLE IF NOT EXISTS users ( user_id BIGSERIAL PRIMARY KEY, access_token varchar(256), name varchar(256) NOT NULL, description varchar(128), email varchar(256), phone_number varchar(48), location varchar(256), company varchar(256), expire BIGINT, password varchar(256), UNIQUE (name));CREATE TABLE IF NOT EXISTS roles ( role_id BIGSERIAL PRIMARY KEY, role_name varchar(256) NOT NULL, role_source varchar(256) NOT NULL, description varchar(128), resource_id BIGINT NOT NULL, resource_type varchar(48) NOT NULL, resource_name varchar(48) NOT NULL, resource_verbs varchar(256) NOT NULL, flag INT NOT NULL);CREATE TABLE IF NOT EXISTS tenants ( tenant_id BIGSERIAL PRIMARY KEY, tenant varchar(255) NOT NULL, admin_roles varchar(255), allowed_clusters varchar(255), environment_name varchar(255), UNIQUE(tenant));CREATE TABLE IF NOT EXISTS namespaces ( namespace_id BIGSERIAL PRIMARY KEY, tenant varchar(255) NOT NULL, namespace varchar(255) NOT NULL, UNIQUE(tenant, namespace));CREATE TABLE IF NOT EXISTS role_binding( role_binding_id BIGSERIAL PRIMARY KEY, name varchar(256) NOT NULL, description varchar(256), role_id BIGINT NOT NULL, user_id BIGINT NOT NULL);上面已经做好了部署的准备工作下面将使用Helm在K8S集群中部署Pulsar集群2.使用Helm在K8S中部署Pulsar从https://github.com/apache/pulsar-helm-chart/releases下载pulsar helm chart 2.7.7到K8S的控制节点上(kubectl和helm可用)https://github.com/apache/pulsar-helm-chart/releases/download/pulsar-2.7.7/pulsar-2.7.7.tgz2.1 定制编写helm chart的values.yaml定制编写helm chart的values.yaml文件如下, 定制的内容比较多具体见下面文件的注释:auth: authentication: enabled: true # 开启jwt认证 provider: "jwt" jwt: usingSecretKey: false # jwt认证使用非对称秘钥对 authorization: enabled: true # 开启授权 superUsers: # broker to broker communication broker: "broker-admin" # proxy to broker communication proxy: "proxy-admin" # pulsar-admin client to broker/proxy communication client: "admin"components: # 启用的组件 autorecovery: true bookkeeper: true broker: true functions: true proxy: true pulsar_manager: true toolset: true zookeeper: truemonitoring: # 关闭监控组件, 后续尝试使用外部Prometheus对pulsar集群进行监控 grafana: false prometheus: false node_exporter: falsevolumes: local_storage: true # 数据卷使用local storageproxy: # proxy的配置(这里是测试环境, 将proxy也调度到node1或node2或node3) nodeSelector: node-role.kubernetes.io/pulsar: pulsar tolerations: - key: "dedicated" operator: "Equal" value: "pulsar" effect: "NoSchedule" configData: PULSAR_PREFIX_authenticateMetricsEndpoint: "false"broker: # broker的配置(这里是测试环境, 将proxy也调度到node1或node2或node3) nodeSelector: node-role.kubernetes.io/pulsar: pulsar tolerations: - key: "dedicated" operator: "Equal" value: "pulsar" effect: "NoSchedule" zookeeper: # broker的配置 replicaCount: 3 tolerations: - key: "dedicated" operator: "Equal" value: "pulsar" effect: "NoSchedule" volumes: data: # 配置使用local pv, 需要与前面手动创建的local pv信息一致 local_storage: true size: 20Gibookkeeper: # bookkeeper的配置 replicaCount: 3 tolerations: - key: "dedicated" operator: "Equal" value: "pulsar" effect: "NoSchedule" volumes: journal: # 配置使用local pv, 需要与前面手动创建的local pv信息一致 local_storage: true size: 50Gi ledgers: # 配置使用local pv, 需要与前面手动创建的local pv信息一致 local_storage: true size: 50Gipulsar_manager: # pulsar_manager的配置(这里是测试环境, 将pulsar_manager也调度到node1或node2或node3) replicaCount: 1 admin: # 文档中描述这里是pulsar manager web界面登录用户密码但实际上当使用外部PostgreSQL数据库时这里需要指定PostgreSQL的数据库和密码不知道是否是pulsar-helm-chart 2.7.7的问题 user: pulsar_manager password: 05aM3Braz_M4RWpn configData: DRIVER_CLASS_NAME: org.postgresql.Driver URL: jdbc:postgresql://:5432/pulsar_manager # 文档中描述这里PostgreSQL数据库的密码但实际上这里不能指定USERNAME和PASSWORD, 不知道是否是pulsar-helm-chart 2.7.7的问题 # USERNAME: pulsar_manager # PASSWORD: 05aM3Braz_M4RWpn LOG_LEVEL: INFO ## 开启JWT认证后, 这里需要指定pulsar-token-admin这个Secret中的JWT Token JWT_TOKEN: autorecovery: # autorecovery的配置(这里是测试环境, 将autorecovery也调度到node1或node2或node3) replicaCount: 1 nodeSelector: node-role.kubernetes.io/pulsar: pulsar tolerations: - key: "dedicated" operator: "Equal" value: "pulsar" effect: "NoSchedule"toolset: # toolset的配置(这里是测试环境, 将toolset也调度到node1或node2或node3) replicaCount: 1 nodeSelector: node-role.kubernetes.io/pulsar: pulsar tolerations: - key: "dedicated" operator: "Equal" value: "pulsar" effect: "NoSchedule"images: # 对个组件使用私有镜像仓库的配置 imagePullSecrets: - regsecret # 私有镜像仓库的image pull secret, 需要提前在k8s命名空间中创建 autorecovery: repository: harbor.example.com/library/apachepulsar/pulsar-all tag: 2.7.4 bookie: repository: harbor.example.com/library/apachepulsar/pulsar-all tag: 2.7.4 broker: repository: harbor.example.com/library/apachepulsar/pulsar-all tag: 2.7.4 functions: repository: harbor.example.com/library/apachepulsar/pulsar-all tag: 2.7.4 proxy: repository: harbor.example.com/library/apachepulsar/pulsar-all tag: 2.7.4 pulsar_manager: repository: harbor.example.com/library/apachepulsar/pulsar-manager tag: v0.2.0 zookeeper: repository: harbor.example.com/library/apachepulsar/pulsar-all tag: 2.7.4pulsar_metadata: component: pulsar-init image: # the image used for running `pulsar-cluster-initialize` job repository: harbor.example.com/library/apachepulsar/pulsar-all tag: 2.7.4因为当前在pulsar-helm-chart 2.7.7 中好像不支持为pulsar-init设置私有仓库的imagePullSecret所以下面为pulsar namespace中的default servcieaccount 添加上imagePullSecretkubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "regsecret"}]}' -n pulsar2.2 使用helm install安装pulsar定制完value.yaml之后使用下面的命令向K8S集群部署pulsarhelm install \ --values values.yaml \ --set initialize=true \ --namespace pulsar \ pulsar pulsar-2.7.7.tgz安装完成后使用下面的命令查看一下两个初始化job pulsar-pulsar-init和pulsar-bookie-init的pod状态为Complete:kubectl get pod -n pulsar | grep initpulsar-bookie-init--1-h65bp 0/1 Completed 0 5m14spulsar-pulsar-init--1-t4thq 0/1 Completed 0 5m5s使用下面的命令查看一下pulsar集群各个组件的Pod状态全部都为Running:kubectl get pod -n pulsar -l cluster=pulsar -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESpulsar-bookie-0 1/1 Running 0 14m 10.244.226.91 node1 pulsar-bookie-1 1/1 Running 0 14m 10.244.63.90 node2 pulsar-bookie-2 1/1 Running 0 14m 10.244.46.92 node3 pulsar-broker-0 1/1 Running 0 14m 10.244.226.90 node1 pulsar-broker-1 1/1 Running 0 14m 10.244.63.89 node2 pulsar-broker-2 1/1 Running 0 14m 10.244.46.90 node3 pulsar-proxy-0 1/1 Running 0 14m 10.244.226.93 node1 pulsar-proxy-1 1/1 Running 0 14m 10.244.63.91 node2 pulsar-proxy-2 1/1 Running 0 14m 10.244.46.93 node3 pulsar-pulsar-manager-7b98666cff-5626f 1/1 Running 0 14m 10.244.63.88 node2 pulsar-recovery-0 1/1 Running 0 14m 10.244.46.89 node3 pulsar-toolset-0 1/1 Running 0 14m 10.244.46.91 node3 pulsar-zookeeper-0 1/1 Running 0 14m 10.244.226.92 node1 pulsar-zookeeper-1 1/1 Running 0 14m 10.244.63.92 node2 pulsar-zookeeper-2 1/1 Running 0 13m 10.244.46.94 node3 如果后边调整了values.yaml需要更新部署时使用下面的命令:helm upgrade pulsar pulsar-2.7.7.tgz \ --namespace pulsar \ -f values.yaml2.3 在toolset pod中测试创建tenant, namespace和topictoolset pod中包含了各种管理和测试pulsar的命令行工具例如pulsar-admin, pulsar-client等下面进入toolset pod中使用pulsar-admin命令行工具测试一下tenant, namespace和topic的创建进一步确认pulsar集群工作正常kubectl exec -it -n pulsar pulsar-toolset-0 -- /bin/bashbin/pulsar-admin tenants create test-tenantbin/pulsar-admin tenants list"public""pulsar""test-tenant"bin/pulsar-admin namespaces create test-tenant/test-nsbin/pulsar-admin namespaces list test-tenant"test-tenant/test-ns"bin/pulsar-admin topics create-partitioned-topic test-tenant/test-ns/test-topic -p 3bin/pulsar-admin topics list-partitioned-topics test-tenant/test-ns"persistent://test-tenant/test-ns/test-topic"2.4 创建pulsar-manager的管理员用户并登录查看下面测试一下pulsar manager是否可以使用前面使用helm chart部署的pulsar集群在k8s中创建了下面7个Servicekubectl get svc -l app=pulsar -n pulsarNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEpulsar-bookie ClusterIP None 3181/TCP,8000/TCP 40mpulsar-broker ClusterIP None 8080/TCP,6650/TCP 40mpulsar-proxy LoadBalancer 10.104.105.137 80:31970/TCP,6650:32631/TCP 40mpulsar-pulsar-manager LoadBalancer 10.110.207.9 9527:32764/TCP 40mpulsar-recovery ClusterIP None 8000/TCP 40mpulsar-toolset ClusterIP None 40mpulsar-zookeeper ClusterIP None 8000/TCP,2888/TCP,3888/TCP,2181/TCP 40m从上面命令的输出可以看出bookie, broker, recovery, toolset, zookeeper这5个Service的类型都是ClusterIP的并且cluser-ip为None都是Headless的Service因为它们只需要在k8s集群内部使用pulsar-proxy和pulsar-pulsar-manager为LoadBalancer类型并且都配置了NodePort提供了从K8S集群外部访问的能力从集群外部访问pulsar-manager的地址是http://node1:32764第一次访问pulsar manager之前需要为其创建一个管理用户:CSRF_TOKEN=$(curl http://node1:32764/pulsar-manager/csrf-token)curl \ -H 'X-XSRF-TOKEN: $CSRF_TOKEN' \ -H 'Cookie: XSRF-TOKEN=$CSRF_TOKEN;' \ -H "Content-Type: application/json" \ -X PUT http://node1:32764/pulsar-manager/users/superuser \ -d '{"name": "admin", "password": "pulsar", "description": "test", "email": "username@test.org"}'上面的命令为pulsar-manager创建用户名为admin, 密码为pulsar的管理用户使用该用户就可以登录pulsar manager备注, 在线上使用时尽量避免以NodePort暴露服务这里的pulsar-manager的Service可以修改为CluserIP类型并关闭NodePort同时创建Ingress以Ingress+域名的形式暴露出来 看了一下pulsar-helm-chart也是支持的只是目前pulsar-helm-chart 2.7.7中创建Ingress时使用的是apiVersion: extensions/v1beta1 API这个API从k8s 1.19被标记为废弃在k8s 1.22已被移除 所以要直接是使用pulsar-helm-chart创建Ingress的话需要等待pulsar-helm-chart的更新参考https://github.com/apache/pulsar-helm-charthttps://pulsar.apache.org/docs/zh-CN/kubernetes-helm/https://github.com/apache/pulsar-helm-chart/issues/133https://github.com/rancher/local-path-provisionerhttps://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/

发布于:新丰县
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
意见反馈 合作

Copyright ? 2023 Sohu All Rights Reserved

搜狐公司 版权所有