• 18-1、k8s 对外服务之ingress


    一、什么是ingress

    原来的项目是部署在一台电脑上的,这样爬取速度虽然很快,但是我们还能提升,联想到分布式的思想,我们是否可以通过多台电脑进行配合爬取,这样我们的爬取速度就能大幅度提升。                              
    k8s对外暴露服务service的主要方式是NodePort与LoadBalance,但是随着集群中微服务的增多,NodePort方式缺点是会占用很多集群机器的端口,
    LoadBalance方式最大的缺点是每个service一个LB,有点浪费和麻烦,而且需要k8s的支持。
    ingress则只需要一个NodePort或者一个LoadBalance就可以满足所有service对外服务的需求,所以通常情况下 我们会设计一个Ingress来做路由的转发,方便统一管理。效果如图:      

     实际上,ingress相当于一个7层的负载均衡器,是k8s对反向代理的抽象,工作原理类似于nginx,可以理解为在Ingress里建立一个映射规则, ingress controller通过监听Ingress这个api对象里的配置规则并转化成nginx的配置,然后对外部提供服务。

    1.1、Ingress组成

    主要分为两部分:
        Ingresscontroller:是流量的入口,核心是一个deployment,封装了一个web前端负载均衡器,同时在其基础上实现动态感知Ingress并根据Ingress的定义动态生成前端web负载均衡器的配置文件,比如 Nginx Ingress Controller 本质上就是一个 Nginx,只不过它能根据 Ingress 资源的定义动态生成 Nginx 的配置文件,然后动态 Reload。   实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer。
      ingress resourcesIngress描述具体的路由规则,一个类型为Ingress的k8s api对象,这部分则是面向开发人员。该资源对象定义了不同主机名(域名)及URL和对应后端Service的绑定,根据不同的路径路由http和https流量。
     Ingress Controller是将Ingress这种变化生成一段Nginx的配置,然后将这个配置通过Kubernetes API写到Nginx的Pod中,然后reload。
    (注意:写入 nginx.conf 的不是service的地址,而是service backend 的 pod 的地址,避免在 service 再增加一层负载均衡转发)

        从上图看出,实际上请求进来还是被负载均衡器拦截了,比如nginx,然后ingress controller通过跟ingress交互得知某个域名对应哪个service, 再通过跟kubernetes API交互得知service地址等信息,综合以后生成配置文件实时写入负载均衡器(nginx),然后负载均衡器reload该规则便可实现服务发现,即动态映射。

    1.2、Ingress作用

    1. 基于http-header的路由
    2. 基于path的路由
    3. 单个ingress的timeout
    4. 请求速率limit
    5. rewrite规则
    Ingress 可以提供负载平衡、SSL终止 和 基于名称的虚拟主机。
    当然在实际应用中,最新版本 Kubernetes 已经将 Nginx 与 Ingress Controller 合并为一个组件,所以 Nginx 无需单独部署, 只需要部署 Ingress Controller 即可。

    二、helm 裸机部署 Nginx Ingress Controller   

    基于 Nginx 的 Ingress Controller 有两种,一种是 k8s 社区提供的  ingress-nginx ,另一种是 Nginx 社区提供的  kubernetes-igress ,关于两者的区别见  这里
    yaml文件中的镜像不能下载可以换其他的image:
    nginx-ingress.yaml:
    1. apiVersion: v1
    2. kind: Namespace
    3. metadata:
    4. labels:
    5. app.kubernetes.io/instance: ingress-nginx
    6. app.kubernetes.io/name: ingress-nginx
    7. name: ingress-nginx
    8. ---
    9. apiVersion: v1
    10. automountServiceAccountToken: true
    11. kind: ServiceAccount
    12. metadata:
    13. labels:
    14. app.kubernetes.io/component: controller
    15. app.kubernetes.io/instance: ingress-nginx
    16. app.kubernetes.io/name: ingress-nginx
    17. app.kubernetes.io/part-of: ingress-nginx
    18. app.kubernetes.io/version: 1.2.0
    19. name: ingress-nginx
    20. namespace: ingress-nginx
    21. ---
    22. apiVersion: v1
    23. kind: ServiceAccount
    24. metadata:
    25. labels:
    26. app.kubernetes.io/component: admission-webhook
    27. app.kubernetes.io/instance: ingress-nginx
    28. app.kubernetes.io/name: ingress-nginx
    29. app.kubernetes.io/part-of: ingress-nginx
    30. app.kubernetes.io/version: 1.2.0
    31. name: ingress-nginx-admission
    32. namespace: ingress-nginx
    33. ---
    34. apiVersion: rbac.authorization.k8s.io/v1
    35. kind: Role
    36. metadata:
    37. labels:
    38. app.kubernetes.io/component: controller
    39. app.kubernetes.io/instance: ingress-nginx
    40. app.kubernetes.io/name: ingress-nginx
    41. app.kubernetes.io/part-of: ingress-nginx
    42. app.kubernetes.io/version: 1.2.0
    43. name: ingress-nginx
    44. namespace: ingress-nginx
    45. rules:
    46. - apiGroups:
    47. - ""
    48. resources:
    49. - namespaces
    50. verbs:
    51. - get
    52. - apiGroups:
    53. - ""
    54. resources:
    55. - configmaps
    56. - pods
    57. - secrets
    58. - endpoints
    59. verbs:
    60. - get
    61. - list
    62. - watch
    63. - apiGroups:
    64. - ""
    65. resources:
    66. - services
    67. verbs:
    68. - get
    69. - list
    70. - watch
    71. - apiGroups:
    72. - networking.k8s.io
    73. resources:
    74. - ingresses
    75. verbs:
    76. - get
    77. - list
    78. - watch
    79. - apiGroups:
    80. - networking.k8s.io
    81. resources:
    82. - ingresses/status
    83. verbs:
    84. - update
    85. - apiGroups:
    86. - networking.k8s.io
    87. resources:
    88. - ingressclasses
    89. verbs:
    90. - get
    91. - list
    92. - watch
    93. - apiGroups:
    94. - ""
    95. resourceNames:
    96. - ingress-controller-leader
    97. resources:
    98. - configmaps
    99. verbs:
    100. - get
    101. - update
    102. - apiGroups:
    103. - ""
    104. resources:
    105. - configmaps
    106. verbs:
    107. - create
    108. - apiGroups:
    109. - ""
    110. resources:
    111. - events
    112. verbs:
    113. - create
    114. - patch
    115. ---
    116. apiVersion: rbac.authorization.k8s.io/v1
    117. kind: Role
    118. metadata:
    119. labels:
    120. app.kubernetes.io/component: admission-webhook
    121. app.kubernetes.io/instance: ingress-nginx
    122. app.kubernetes.io/name: ingress-nginx
    123. app.kubernetes.io/part-of: ingress-nginx
    124. app.kubernetes.io/version: 1.2.0
    125. name: ingress-nginx-admission
    126. namespace: ingress-nginx
    127. rules:
    128. - apiGroups:
    129. - ""
    130. resources:
    131. - secrets
    132. verbs:
    133. - get
    134. - create
    135. ---
    136. apiVersion: rbac.authorization.k8s.io/v1
    137. kind: ClusterRole
    138. metadata:
    139. labels:
    140. app.kubernetes.io/instance: ingress-nginx
    141. app.kubernetes.io/name: ingress-nginx
    142. app.kubernetes.io/part-of: ingress-nginx
    143. app.kubernetes.io/version: 1.2.0
    144. name: ingress-nginx
    145. rules:
    146. - apiGroups:
    147. - ""
    148. resources:
    149. - configmaps
    150. - endpoints
    151. - nodes
    152. - pods
    153. - secrets
    154. - namespaces
    155. verbs:
    156. - list
    157. - watch
    158. - apiGroups:
    159. - ""
    160. resources:
    161. - nodes
    162. verbs:
    163. - get
    164. - apiGroups:
    165. - ""
    166. resources:
    167. - services
    168. verbs:
    169. - get
    170. - list
    171. - watch
    172. - apiGroups:
    173. - networking.k8s.io
    174. resources:
    175. - ingresses
    176. verbs:
    177. - get
    178. - list
    179. - watch
    180. - apiGroups:
    181. - ""
    182. resources:
    183. - events
    184. verbs:
    185. - create
    186. - patch
    187. - apiGroups:
    188. - networking.k8s.io
    189. resources:
    190. - ingresses/status
    191. verbs:
    192. - update
    193. - apiGroups:
    194. - networking.k8s.io
    195. resources:
    196. - ingressclasses
    197. verbs:
    198. - get
    199. - list
    200. - watch
    201. ---
    202. apiVersion: rbac.authorization.k8s.io/v1
    203. kind: ClusterRole
    204. metadata:
    205. labels:
    206. app.kubernetes.io/component: admission-webhook
    207. app.kubernetes.io/instance: ingress-nginx
    208. app.kubernetes.io/name: ingress-nginx
    209. app.kubernetes.io/part-of: ingress-nginx
    210. app.kubernetes.io/version: 1.2.0
    211. name: ingress-nginx-admission
    212. rules:
    213. - apiGroups:
    214. - admissionregistration.k8s.io
    215. resources:
    216. - validatingwebhookconfigurations
    217. verbs:
    218. - get
    219. - update
    220. ---
    221. apiVersion: rbac.authorization.k8s.io/v1
    222. kind: RoleBinding
    223. metadata:
    224. labels:
    225. app.kubernetes.io/component: controller
    226. app.kubernetes.io/instance: ingress-nginx
    227. app.kubernetes.io/name: ingress-nginx
    228. app.kubernetes.io/part-of: ingress-nginx
    229. app.kubernetes.io/version: 1.2.0
    230. name: ingress-nginx
    231. namespace: ingress-nginx
    232. roleRef:
    233. apiGroup: rbac.authorization.k8s.io
    234. kind: Role
    235. name: ingress-nginx
    236. subjects:
    237. - kind: ServiceAccount
    238. name: ingress-nginx
    239. namespace: ingress-nginx
    240. ---
    241. apiVersion: rbac.authorization.k8s.io/v1
    242. kind: RoleBinding
    243. metadata:
    244. labels:
    245. app.kubernetes.io/component: admission-webhook
    246. app.kubernetes.io/instance: ingress-nginx
    247. app.kubernetes.io/name: ingress-nginx
    248. app.kubernetes.io/part-of: ingress-nginx
    249. app.kubernetes.io/version: 1.2.0
    250. name: ingress-nginx-admission
    251. namespace: ingress-nginx
    252. roleRef:
    253. apiGroup: rbac.authorization.k8s.io
    254. kind: Role
    255. name: ingress-nginx-admission
    256. subjects:
    257. - kind: ServiceAccount
    258. name: ingress-nginx-admission
    259. namespace: ingress-nginx
    260. ---
    261. apiVersion: rbac.authorization.k8s.io/v1
    262. kind: ClusterRoleBinding
    263. metadata:
    264. labels:
    265. app.kubernetes.io/instance: ingress-nginx
    266. app.kubernetes.io/name: ingress-nginx
    267. app.kubernetes.io/part-of: ingress-nginx
    268. app.kubernetes.io/version: 1.2.0
    269. name: ingress-nginx
    270. roleRef:
    271. apiGroup: rbac.authorization.k8s.io
    272. kind: ClusterRole
    273. name: ingress-nginx
    274. subjects:
    275. - kind: ServiceAccount
    276. name: ingress-nginx
    277. namespace: ingress-nginx
    278. ---
    279. apiVersion: rbac.authorization.k8s.io/v1
    280. kind: ClusterRoleBinding
    281. metadata:
    282. labels:
    283. app.kubernetes.io/component: admission-webhook
    284. app.kubernetes.io/instance: ingress-nginx
    285. app.kubernetes.io/name: ingress-nginx
    286. app.kubernetes.io/part-of: ingress-nginx
    287. app.kubernetes.io/version: 1.2.0
    288. name: ingress-nginx-admission
    289. roleRef:
    290. apiGroup: rbac.authorization.k8s.io
    291. kind: ClusterRole
    292. name: ingress-nginx-admission
    293. subjects:
    294. - kind: ServiceAccount
    295. name: ingress-nginx-admission
    296. namespace: ingress-nginx
    297. ---
    298. apiVersion: v1
    299. data:
    300. allow-snippet-annotations: "true"
    301. kind: ConfigMap
    302. metadata:
    303. labels:
    304. app.kubernetes.io/component: controller
    305. app.kubernetes.io/instance: ingress-nginx
    306. app.kubernetes.io/name: ingress-nginx
    307. app.kubernetes.io/part-of: ingress-nginx
    308. app.kubernetes.io/version: 1.2.0
    309. name: ingress-nginx-controller
    310. namespace: ingress-nginx
    311. ---
    312. apiVersion: v1
    313. kind: Service
    314. metadata:
    315. labels:
    316. app.kubernetes.io/component: controller
    317. app.kubernetes.io/instance: ingress-nginx
    318. app.kubernetes.io/name: ingress-nginx
    319. app.kubernetes.io/part-of: ingress-nginx
    320. app.kubernetes.io/version: 1.2.0
    321. name: ingress-nginx-controller
    322. namespace: ingress-nginx
    323. spec:
    324. ports:
    325. - appProtocol: http
    326. name: http
    327. port: 80
    328. protocol: TCP
    329. targetPort: http
    330. - appProtocol: https
    331. name: https
    332. port: 443
    333. protocol: TCP
    334. targetPort: https
    335. selector:
    336. app.kubernetes.io/component: controller
    337. app.kubernetes.io/instance: ingress-nginx
    338. app.kubernetes.io/name: ingress-nginx
    339. type: NodePort
    340. ---
    341. apiVersion: v1
    342. kind: Service
    343. metadata:
    344. labels:
    345. app.kubernetes.io/component: controller
    346. app.kubernetes.io/instance: ingress-nginx
    347. app.kubernetes.io/name: ingress-nginx
    348. app.kubernetes.io/part-of: ingress-nginx
    349. app.kubernetes.io/version: 1.2.0
    350. name: ingress-nginx-controller-admission
    351. namespace: ingress-nginx
    352. spec:
    353. ports:
    354. - appProtocol: https
    355. name: https-webhook
    356. port: 443
    357. targetPort: webhook
    358. selector:
    359. app.kubernetes.io/component: controller
    360. app.kubernetes.io/instance: ingress-nginx
    361. app.kubernetes.io/name: ingress-nginx
    362. type: ClusterIP
    363. ---
    364. apiVersion: apps/v1
    365. kind: Deployment
    366. metadata:
    367. labels:
    368. app.kubernetes.io/component: controller
    369. app.kubernetes.io/instance: ingress-nginx
    370. app.kubernetes.io/name: ingress-nginx
    371. app.kubernetes.io/part-of: ingress-nginx
    372. app.kubernetes.io/version: 1.2.0
    373. name: ingress-nginx-controller
    374. namespace: ingress-nginx
    375. spec:
    376. minReadySeconds: 0
    377. revisionHistoryLimit: 10
    378. selector:
    379. matchLabels:
    380. app.kubernetes.io/component: controller
    381. app.kubernetes.io/instance: ingress-nginx
    382. app.kubernetes.io/name: ingress-nginx
    383. template:
    384. metadata:
    385. labels:
    386. app.kubernetes.io/component: controller
    387. app.kubernetes.io/instance: ingress-nginx
    388. app.kubernetes.io/name: ingress-nginx
    389. spec:
    390. containers:
    391. - args:
    392. - /nginx-ingress-controller
    393. - --election-id=ingress-controller-leader
    394. - --controller-class=k8s.io/ingress-nginx
    395. - --ingress-class=nginx
    396. - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
    397. - --validating-webhook=:8443
    398. - --validating-webhook-certificate=/usr/local/certificates/cert
    399. - --validating-webhook-key=/usr/local/certificates/key
    400. env:
    401. - name: POD_NAME
    402. valueFrom:
    403. fieldRef:
    404. fieldPath: metadata.name
    405. - name: POD_NAMESPACE
    406. valueFrom:
    407. fieldRef:
    408. fieldPath: metadata.namespace
    409. - name: LD_PRELOAD
    410. value: /usr/local/lib/libmimalloc.so
    411. image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.1
    412. imagePullPolicy: IfNotPresent
    413. lifecycle:
    414. preStop:
    415. exec:
    416. command:
    417. - /wait-shutdown
    418. livenessProbe:
    419. failureThreshold: 5
    420. httpGet:
    421. path: /healthz
    422. port: 10254
    423. scheme: HTTP
    424. initialDelaySeconds: 10
    425. periodSeconds: 10
    426. successThreshold: 1
    427. timeoutSeconds: 1
    428. name: controller
    429. ports:
    430. - containerPort: 80
    431. name: http
    432. protocol: TCP
    433. - containerPort: 443
    434. name: https
    435. protocol: TCP
    436. - containerPort: 8443
    437. name: webhook
    438. protocol: TCP
    439. readinessProbe:
    440. failureThreshold: 3
    441. httpGet:
    442. path: /healthz
    443. port: 10254
    444. scheme: HTTP
    445. initialDelaySeconds: 10
    446. periodSeconds: 10
    447. successThreshold: 1
    448. timeoutSeconds: 1
    449. resources:
    450. requests:
    451. cpu: 100m
    452. memory: 90Mi
    453. securityContext:
    454. allowPrivilegeEscalation: true
    455. capabilities:
    456. add:
    457. - NET_BIND_SERVICE
    458. drop:
    459. - ALL
    460. runAsUser: 101
    461. volumeMounts:
    462. - mountPath: /usr/local/certificates/
    463. name: webhook-cert
    464. readOnly: true
    465. dnsPolicy: ClusterFirst
    466. nodeSelector:
    467. kubernetes.io/os: linux
    468. serviceAccountName: ingress-nginx
    469. terminationGracePeriodSeconds: 300
    470. volumes:
    471. - name: webhook-cert
    472. secret:
    473. secretName: ingress-nginx-admission
    474. ---
    475. apiVersion: batch/v1
    476. kind: Job
    477. metadata:
    478. labels:
    479. app.kubernetes.io/component: admission-webhook
    480. app.kubernetes.io/instance: ingress-nginx
    481. app.kubernetes.io/name: ingress-nginx
    482. app.kubernetes.io/part-of: ingress-nginx
    483. app.kubernetes.io/version: 1.2.0
    484. name: ingress-nginx-admission-create
    485. namespace: ingress-nginx
    486. spec:
    487. template:
    488. metadata:
    489. labels:
    490. app.kubernetes.io/component: admission-webhook
    491. app.kubernetes.io/instance: ingress-nginx
    492. app.kubernetes.io/name: ingress-nginx
    493. app.kubernetes.io/part-of: ingress-nginx
    494. app.kubernetes.io/version: 1.2.0
    495. name: ingress-nginx-admission-create
    496. spec:
    497. containers:
    498. - args:
    499. - create
    500. - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
    501. - --namespace=$(POD_NAMESPACE)
    502. - --secret-name=ingress-nginx-admission
    503. env:
    504. - name: POD_NAMESPACE
    505. valueFrom:
    506. fieldRef:
    507. fieldPath: metadata.namespace
    508. image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
    509. imagePullPolicy: IfNotPresent
    510. name: create
    511. securityContext:
    512. allowPrivilegeEscalation: false
    513. nodeSelector:
    514. kubernetes.io/os: linux
    515. restartPolicy: OnFailure
    516. securityContext:
    517. fsGroup: 2000
    518. runAsNonRoot: true
    519. runAsUser: 2000
    520. serviceAccountName: ingress-nginx-admission
    521. ---
    522. apiVersion: batch/v1
    523. kind: Job
    524. metadata:
    525. labels:
    526. app.kubernetes.io/component: admission-webhook
    527. app.kubernetes.io/instance: ingress-nginx
    528. app.kubernetes.io/name: ingress-nginx
    529. app.kubernetes.io/part-of: ingress-nginx
    530. app.kubernetes.io/version: 1.2.0
    531. name: ingress-nginx-admission-patch
    532. namespace: ingress-nginx
    533. spec:
    534. template:
    535. metadata:
    536. labels:
    537. app.kubernetes.io/component: admission-webhook
    538. app.kubernetes.io/instance: ingress-nginx
    539. app.kubernetes.io/name: ingress-nginx
    540. app.kubernetes.io/part-of: ingress-nginx
    541. app.kubernetes.io/version: 1.2.0
    542. name: ingress-nginx-admission-patch
    543. spec:
    544. containers:
    545. - args:
    546. - patch
    547. - --webhook-name=ingress-nginx-admission
    548. - --namespace=$(POD_NAMESPACE)
    549. - --patch-mutating=false
    550. - --secret-name=ingress-nginx-admission
    551. - --patch-failure-policy=Fail
    552. env:
    553. - name: POD_NAMESPACE
    554. valueFrom:
    555. fieldRef:
    556. fieldPath: metadata.namespace
    557. image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
    558. imagePullPolicy: IfNotPresent
    559. name: patch
    560. securityContext:
    561. allowPrivilegeEscalation: false
    562. nodeSelector:
    563. kubernetes.io/os: linux
    564. restartPolicy: OnFailure
    565. securityContext:
    566. fsGroup: 2000
    567. runAsNonRoot: true
    568. runAsUser: 2000
    569. serviceAccountName: ingress-nginx-admission
    570. ---
    571. apiVersion: networking.k8s.io/v1
    572. kind: IngressClass
    573. metadata:
    574. labels:
    575. app.kubernetes.io/component: controller
    576. app.kubernetes.io/instance: ingress-nginx
    577. app.kubernetes.io/name: ingress-nginx
    578. app.kubernetes.io/part-of: ingress-nginx
    579. app.kubernetes.io/version: 1.2.0
    580. name: nginx
    581. spec:
    582. controller: k8s.io/ingress-nginx
    583. ---
    584. apiVersion: admissionregistration.k8s.io/v1
    585. kind: ValidatingWebhookConfiguration
    586. metadata:
    587. labels:
    588. app.kubernetes.io/component: admission-webhook
    589. app.kubernetes.io/instance: ingress-nginx
    590. app.kubernetes.io/name: ingress-nginx
    591. app.kubernetes.io/part-of: ingress-nginx
    592. app.kubernetes.io/version: 1.2.0
    593. name: ingress-nginx-admission
    594. webhooks:
    595. - admissionReviewVersions:
    596. - v1
    597. clientConfig:
    598. service:
    599. name: ingress-nginx-controller-admission
    600. namespace: ingress-nginx
    601. path: /networking/v1/ingresses
    602. failurePolicy: Fail
    603. matchPolicy: Equivalent
    604. name: validate.nginx.ingress.kubernetes.io
    605. rules:
    606. - apiGroups:
    607. - networking.k8s.io
    608. apiVersions:
    609. - v1
    610. operations:
    611. - CREATE
    612. - UPDATE
    613. resources:
    614. - ingresses
    615. sideEffects: None
    执行命令kubectl apply -f nginx-ingress.yaml

    查看:kubectl get pods -n ingress-nginx -o wide:

    三、Ingress resource

    一个最小的Ingress资源示例:service/networking/minimal-ingress.yaml
    1. apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: minimal-ingress
    5.   annotations:
    6.     nginx.ingress.kubernetes.io/rewrite-target: /
    7. spec:
    8.   ingressClassName: nginx-example
    9.   rules:
    10.   - http:
    11.       paths:
    12.       - path: /testpath
    13.         pathType: Prefix
    14.         backend:
    15.           service:
    16.             name: test
    17.             port:
    18.               number: 80
    1、Ingress需要apiVersion、kind、metadata字段;
    2、Ingress对象的名称必须是有效的 DNS subdomain name .
     
    3、Ingress spec包含配置负载均衡器 或 代理服务器所需的所有信息,最重要的是它包含与所有传入请求匹配的规则列表。Ingress resource仅支持引导HTTP(S)流量的规则。
    4、 Ingress rules:
        每个HTTP规则都包含以下信息:
    • host:可选主机,在此示例中,未指定主机,因此该规则适用于通过指定 IP 地址的所有入站 HTTP 流量。 如果提供了主机(例如 foo.bar.com),则规则适用于该主机。
    • paths列表(例如 /testpath),每个路径都有一个关联的 backend,该后端使用  service.name 和  service.port.name 或  service.port.number 定义。 在负载均衡器将流量定向到引用的服务之前,host和path都必须匹配传入请求的内容。
    • backend是Service文档中描述的服务和端口名称的组合,或者是通过 CRD 的自定义资源后端。 对与规则的主机和路径匹配的 Ingress 的 HTTP(和 HTTPS)请求将发送到列出的后端。
    defaultBackend通常在 Ingress controller中配置,以服务与规范中的路径不匹配的任何请求。

    3.1、DefaultBackend

    没有rules的 Ingress 将所有流量发送到单个默认后端。 defaultBackend 通常是   Ingress controller 的配置选项,并且未在 Ingress resource中指定。
    如果没有任何主机或路径与 Ingress 对象中的 HTTP 请求匹配,则流量将路由到您的默认后端。
    使用 kubectl get service -n kube-system查看在命名空间 kube-system 是否有 default-back-end 服务。
    若没有,使用下面的 yaml 文件 创建 default-back-end 服务
    backend.yaml:
    1. apiVersion: v1
    2. kind: Service
    3. metadata:
    4.   name: default-http-backend
    5.   namespace: kube-system
    6. spec:
    7.   selector:
    8.     app: ingress-nginx-controller
    9.   ports:
    10.     - protocol: TCP
    11.       port: 80
    12.       targetPort: 80

    3.2、Resource backends

    资源后端是与 Ingress 对象位于同一命名空间中的另一个 Kubernetes 资源的 ObjectRef。service/networking/ingress-resource-backend.yaml:
    1. apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: ingress-resource-backend
    5. spec:
    6.   defaultBackend:
    7.     resource:
    8.       apiGroup: k8s.example.com
    9.       kind: StorageBucket
    10.       name: static-assets
    11.   rules:
    12.     - http:
    13.         paths:
    14.           - path: /icons
    15.             pathType: ImplementationSpecific
    16.             backend:
    17.               resource:
    18.                 apiGroup: k8s.example.com
    19.                 kind: StorageBucket
    20.                 name: icon-assets
    创建好Ingress后,使用 kubectl describe ingress ingress-resource-backend查看:
    1. Name: ingress-resource-backend
    2. Namespace: default
    3. Address:
    4. Default backend: APIGroup: k8s.example.com, Kind: StorageBucket, Name: static-assets
    5. Rules:
    6. Host Path Backends
    7. ---- ---- --------
    8. *
    9. /icons APIGroup: k8s.example.com, Kind: StorageBucket, Name: icon-assets
    10. Annotations:
    11. Events:

    3.3、Path types

    Ingress中的每条path都需要相应的 pathType,不包含显示 pathType的路径将无法通过验证。
    支持三种路径类型:
    • ImplementationSpecific 使用这种路径类型,匹配取决于 IngressClass。 实现可以将其视为单独的 pathType 或将其视为 Prefix 或 Exact 路径类型。
    • Exact 精确匹配 URL 路径并区分大小写。
    • Prefix 基于由 / 分隔的 URL 路径 前缀进行匹配 。 匹配区分大小写 ,并在逐个元素的路径元素基础上完成。 路径元素是指由 / 分隔符分割的路径中的标签列表。 如果每个 p 都是请求路径的 p 的元素前缀,则请求是路径 p 的匹配项。
    在某些情况下,一个 Ingress 中的多个路径paths将匹配一个请求。 在这些情况下,将 优先考虑最长的匹配路径 。 如果两条路径仍然相等匹配,则具有 精确路径类型的路径将优先于前缀路径类型。

    3.4、Hostname wildcards(主机名通配符)

    Host可以是精确匹配(例如“ foo.bar.com”)或通配符(例如“ *. foo.com”)。 精确匹配要求 HTTP 主机标头与主机字段匹配。 通配符匹配要求 HTTP 主机标头等于通配符规则的后缀。
    service/networking/ingress-wildcard-host.yaml:
    1. apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: ingress-wildcard-host
    5. spec:
    6.   rules:
    7.   - host: "foo.bar.com"
    8.     http:
    9.       paths:
    10.       - pathType: Prefix # 前缀匹配
    11.         path: "/bar"
    12.         backend:
    13.           service:
    14.             name: service1
    15.             port:
    16.               number: 80
    17.   - host: "*.foo.com" # 主机名通配符
    18.     http:
    19.       paths:
    20.       - pathType: Prefix
    21.         path: "/foo"
    22.         backend:
    23.           service:
    24.             name: service2
    25.             port:
    26.               number: 80

    3.5、Ingress class

    Ingresses可由不同的controllers实现 通常具有不同的配置。每个 Ingress 都应该指定一个类,一个对 IngressClass 资源的引用,该资源包含额外的配置,包括应该实现该类的控制器的名称。
    service/networking/external-lb.yaml:
    1. apiVersion: networking.k8s.io/v1
    2. kind: IngressClass
    3. metadata:
    4.   name: external-lb
    5. spec:
    6.   controller: example.com/ingress-controller # 要使用的具体参数类型取决于您在 IngressClass 的 .spec.controller 字段中指定的入口控制器
    7.   parameters:
    8.     apiGroup: k8s.example.com
    9.     kind: IngressParameters
    10.     name: external-lb

    四、Type of Ingress

    4.1、Ingress backed by a single Service

    现有的 Kubernetes 概念允许您公开单个服务(请参阅替代方案 alternatives)。 您也可以通过指定没有规则的默认后端来使用 Ingress 执行此操作。
    service/networking/test-ingress.yaml:
    1. apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: test-ingress
    5. spec:
    6.   defaultBackend:
    7.     service:
    8.       name: test
    9.       port:
    10.         number: 80
    kubectl apply -f后查看Ingress的状态  kubectl get ingress test-ingress
    1. NAME CLASS HOSTS ADDRESS PORTS AGE
    2. test-ingress external-lb * 203.0.113.123 80 59s
    3. 其中 203.0.113.123 是 Ingress controller为满足这个 Ingress 而分配的 IP。

    4.2、Simple fanout

    根据请求的HTTP URI将流量从单个IP地址路由到多个服务。Ingress允许你将负载均衡器的数量降至最低。
    上图中的设置将需要如下的Ingress:
    service/networking/simple-fanout-example.yaml:
    1. apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: simple-fanout-example
    5. spec:
    6.   rules:
    7.   - host: foo.bar.com
    8.     http:
    9.       paths:
    10.       - path: /foo
    11.         pathType: Prefix
    12.         backend:
    13.           service:
    14.             name: service1
    15.             port:
    16.               number: 4200
    17.       - path: /bar
    18.         pathType: Prefix
    19.         backend:
    20.           service:
    21.             name: service2
    22.             port:
    23.               number: 8080
    kubectl apply -f后查看Ingress的状态  kubectl describe ingress simple-fanout-example
    1. ​Name: simple-fanout-example
    2. Namespace: default
    3. Address: 178.91.123.132
    4. Default backend: default-http-backend:80 (10.8.2.3:8080)
    5. Rules:
    6. Host Path Backends
    7. ---- ---- --------
    8. foo.bar.com
    9. /foo service1:4200 (10.8.0.90:4200)
    10. /bar service2:8080 (10.8.0.91:8080)
    11. Events:
    12. Type Reason Age From Message
    13. ---- ------ ---- ---- -------
    14. Normal ADD 22s loadbalancer-controller default/test

    4.3、Name based virtual hosting(基于名称的虚拟主机)

    基于名称的虚拟主机支持 将 HTTP 流量路由到同一 IP 地址的多个主机名
    以下 Ingress 告诉后端负载均衡器根据 Host 标头路由请求:
    service/networking/name-virtual-host-ingress.yaml:
    1. apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: name-virtual-host-ingress
    5. spec:
    6.   rules:
    7.   - host: foo.bar.com
    8.     http:
    9.       paths:
    10.       - pathType: Prefix
    11.         path: "/"
    12.         backend:
    13.           service:
    14.             name: service1
    15.             port:
    16.               number: 80
    17.   - host: bar.foo.com
    18.     http:
    19.       paths:
    20.       - pathType: Prefix
    21.         path: "/"
    22.         backend:
    23.           service:
    24.             name: service2
    25.             port:
    26.               number: 80
    如果您创建了一个没有在规则中定义任何主机的 Ingress 资源,则可以匹配到您的 Ingress 控制器 IP 地址的任何 Web 流量,而无需基于名称的虚拟主机
    例如,以下 Ingress 将对 first.bar.com 请求的流量路由到 service1,将 second.bar.com 请求到 service2,并将请求主机标头与 first.bar.comsecond.bar.com 不匹配的任何流量路由到 service3 .
    service/networking/name-virtual-host-ingress-no-third-host.yaml:
    1. ​apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: name-virtual-host-ingress-no-third-host
    5. spec:
    6.   rules:
    7.   - host: first.bar.com
    8.     http:
    9.       paths:
    10.       - pathType: Prefix
    11.         path: "/"
    12.         backend:
    13.           service:
    14.             name: service1
    15.             port:
    16.               number: 80
    17.   - host: second.bar.com
    18.     http:
    19.       paths:
    20.       - pathType: Prefix
    21.         path: "/"
    22.         backend:
    23.           service:
    24.             name: service2
    25.             port:
    26.               number: 80
    27.   - http:
    28.       paths:
    29.       - pathType: Prefix
    30.         path: "/"
    31.         backend:
    32.           service:
    33.             name: service3
    34.             port:
    35.               number: 80

    五、TLS

    可以通过指定包含 TLS 私钥和证书的 Secret来保护 Ingress。 Ingress 资源仅支持单个 TLS 端口 443,并假定 TLS 在i ngress point 终止(到 Service 及其 Pod 的流量是明文形式)。 如果 Ingress 中的 TLS 配置部分指定了不同的主机,则它们根据通过 SNI TLS 扩展指定的主机名在同一端口上多路复用(前提是 Ingress 控制器支持 SNI)。 TLS的secret 必须包含名为 tls.crt 和 tls.key 的密钥,其中包含用于 TLS 的证书和私钥。 例如:

    执行命令生成ssl证书

    openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=CHINA/O=EDU"

    生成secret:

    kubectl create secret tls testsecret-tls --key tls.key --cert tls.crt

    或者yaml生成:testsecret-tls.yaml:

    1. apiVersion: v1
    2. kind: Secret
    3. metadata:
    4.   name: testsecret-tls
    5.   namespace: default
    6. data:
    7.   tls.crt: base64 encoded cert # 私钥文件crt值
    8.   tls.key: base64 encoded key # ssl证书文件key值
    9. type: kubernetes.io/tls
    在 Ingress 中引用这个 secret 会告诉 Ingress controller 使用 TLS 保护从客户端到负载均衡器的通道。 您需要确保您创建的 TLS 机密来自包含通用名称 (CN) 的证书,也称为 https-example.foo.com 的完全限定域名 (FQDN)。
    Note:
        请记住, TLS 不适用于默认规则,因为必须为所有可能的子域颁发证书。 因此,tls 部分中的主机需要显式匹配规则部分中的主机。
    service/networking/tls-example-ingress.yaml:
    1. ​apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: tls-example-ingress
    5. spec:
    6.   tls:
    7.   - hosts:
    8.       - https-example.foo.com
    9.     secretName: testsecret-tls
    10.   rules:
    11.   - host: https-example.foo.com
    12.     http:
    13.       paths:
    14.       - path: /
    15.         pathType: Prefix
    16.         backend:
    17.           service:
    18.             name: service1
    19.             port:
    20.               number: 80

    六、通过Ingress暴露的域名访问

    6.1、部署好nginx服务

    nginx-deployment.yaml:
    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4.   name: nginx-deployment
    5. spec:
    6.   selector:           
    7.     matchLabels:
    8.       app: nginx
    9.   replicas: 1
    10.   template:
    11.     metadata:
    12.       labels:
    13.         app: nginx
    14.     spec:
    15.       containers:
    16.       - name: nginx
    17.         image: nginx
    18.         ports:
    19.         - containerPort: 80
    20. ---
    21. kind: Service
    22. apiVersion: v1
    23. metadata:
    24.   name: nginx-svc
    25. spec:
    26.   selector:
    27.     app: nginx
    28.   ports:
    29.     - port: 80
    30.       targetPort: 80
    31.       nodePort: 30080
    32.   type: NodePort
    NodePort方式访问外网:
    1. apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: test-ingress
    5.   annotations:
    6.     kubernetes.io/ingress.class: "nginx" # Nginx Ingress Controller 根据该注解自动发现 Ingress
    7. spec:
    8.   rules:
    9.   - host: www.baidu2.com # 对外访问的域名
    10.     http:
    11.       paths:
    12.       - path: /
    13.         pathType: Prefix
    14.         backend:
    15.           service:
    16.             name: nginx-svc # 对外暴露的 Service 名称
    17.             port:
    18.               number: 80 # nginx service 监听的端口

    6.2、通过helm部署 Nginx Ingress Controller

    见章节二

    6.3、创建ingress

    test-ingress.yaml:  创建的 Ingress 必须要和对外暴露的 Service 在同一命名空间下!
    1. ​apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: test-ingress
    5.   annotations:
    6.     kubernetes.io/ingress.class: "nginx" # Nginx Ingress Controller 根据该注解自动发现 Ingress
    7. spec:
    8.   rules:
    9.   - host: www.baidu2.com # 对外访问的域名
    10.     http:
    11.       paths:
    12.       - path: /
    13.         pathType: Prefix
    14.         backend:
    15.           service:
    16.             name: nginx-svc # 对外暴露的 Service 名称
    17.             port:
    18.               number: 80 # nginx service 监听的端口
    执行 kubectl apply -f  test-ingress.yaml创建ingress。
    kubectl get ingress查看ingress:

    6.4、通过ingress暴露域名访问

    因为没有域名,简单模拟,在master节点机器的/etc/hosts添加 10.244.2.113 www.baidu2.com 注意10.244.2.113是Nginx Ingress Controller的IP。这种只能在集群内部访问( 访问端口是80 ),其他人电脑无法访问。
    若要其他人电脑也能访问,则添加 192.168.11.45  www.baidu2.com , 192.168.11.45是ingress-nginx所在的主机,也是master节点。此时的访问地址: http://www.baidu2.com:31046/
    master节点上直接用域名访问:curl  www.baidu2.com
    master节点虚拟机网页访问: http://www.baidu2.com

    6.5、https配置访问

    见章节五
    1. apiVersion: v1
    2. kind: Secret
    3. metadata:
    4.   name: testsecret-tls
    5.   namespace: default
    6. data:
    7.   tls.crt: base64 encoded cert # 私钥文件crt值
    8.   tls.key: base64 encoded key # ssl证书文件key值
    9. type: kubernetes.io/tls
    修改ingress文件:
    1. ​apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: test-ingress
    5.   annotations:
    6.     kubernetes.io/ingress.class: "nginx"
    7. spec:
    8.   rules:
    9.   - host: www.baidu2.com
    10.     http:
    11.       paths:
    12.       - path: /
    13.         pathType: Prefix
    14.         backend:
    15.           service:
    16.             name: nginx-svc
    17.             port:
    18.               number: 80
    19.   tls:
    20.   - hosts:
    21.     - www.baidu2.com
    22.     secretName: testsecret-tls
    验证https方式访问:
    看看ingress-controller的实现方式,进入ingress-controller的pod:
    kubectl -n ingress-nginx exec -it ingress-nginx-controller-59f89cb466-q8xmw bash
    查看nginx.conf文件,cat /etc/nginx/nginx.conf:

    6.6、集群外访问(外网访问)

    在/etc/hosts文件添加10.244.2.113 www.baidu2.com这种只能在集群内部访问(端口是80或者443),其他人电脑无法访问。
    若要其他人电脑也能访问,则添加 192.168.11.45  www.baidu2.com , 192.168.11.45是ingress-nginx所在的主机,也是master节点。此时访问端口是31046(http访问)或32393(https访问)
    在其他电脑上修改hosts文件,添加  192.168.11.45  www.baidu2.com
    其他电脑访问:
        配置https前:  http://www.baidu2.com:31046/
        配置https后:  https://www.baidu2.com:32393/

    6.7、再部署一个服务tomcat

    k8s_tomcat.yaml:
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4.   name: k8s-tomcat
    5.   labels:
    6.     app: k8s
    7. spec:
    8.   containers:
    9.     - name: k8s-tomcat
    10.       image: tomcat
    11.       ports:
    12.         - containerPort: 8080
    13. ---
    14. apiVersion: v1
    15. kind: Service
    16. metadata:
    17.   name: k8s-tomcat-svc
    18. spec:
    19.   selector:
    20.     app: k8s
    21.   type: NodePort
    22.   ports:
    23.     - protocol: TCP
    24.       port: 8080
    25.       targetPort: 8080

    执行命令kubectl apply -f k8s_tomcat.yaml部署tomacat。

    修改ingress文件:test-ingress.yaml
    1. ​apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4.   name: test-ingress
    5.   annotations:
    6.     kubernetes.io/ingress.class: "nginx"
    7. spec:
    8.   rules:
    9.   - host: www.baidu2.com
    10.     http:
    11.       paths:
    12.       - path: /
    13.         pathType: Prefix
    14.         backend:
    15.           service:
    16.             name: nginx-svc
    17.             port:
    18.               number: 80
    19.   - host: tomact.com
    20.     http:
    21.       paths:
    22.       - path: /
    23.         pathType: Prefix
    24.         backend:
    25.           service:
    26.             name: k8s-tomcat-svc
    27.             port:
    28.               number: 8080
    29.   tls:
    30.   - hosts:
    31.     - www.baidu2.com
    32.     - tomact.com
    33.     secretName: testsecret-tls
    在其他电脑上修改hosts文件,添加  192.168.11.45  tomact.com, 网页访问: https://tomact.com:32393

    七、参考

  • 相关阅读:
    Spring Security 中的 RememberMe 登录,so easy!
    Spring Cloud Zookeeper 优雅下线优化
    【字符串】KMP算法
    【深度学习笔记】计算机视觉——单发多框检测(SSD)
    Unbuntu-18-network-issue
    概念解析 | 神经网络中的位置编码(Positional Encoding)
    生物活化量子点纳米载体/离子/功能化量子点修饰细胞膜/纳米颗粒修饰细胞膜荧光探针的制备
    Java基础
    SparkCore系列-10、Spark 内核调度
    五年!!专科学历让我懂得了互联网
  • 原文地址:https://blog.csdn.net/leiwuhen92/article/details/128076218