暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

基于AWS EKS的K8S实践 - 如何打通云企业网集群内外服务调用

407



Hi~朋友,关注置顶防止错过消息


集群内服务的暴露方式?

  1. service

  2. ingress

service 通常用作集群内服务之前的通信,ingress 通常用于暴露给集群外的服务使用。

由于我们这里的需求是将集群内的服务暴露给集群外的服务使用,所以我们这里选择 ingress 。

ingress controller 如何选择?

单纯的 ingress 是没有任何实际作用的,ingress 需要搭配 ingress controller 才会有意义,我们这里的需求是将集群内的服务暴露给我们其他的服务使用,本质上这里还是要通过内网进行访问,我们这里选择的是 ingress alb controller,并且 ALB 的类型是 internal,也就是不面向互联网的类型。

安装 ingress controller

  1. 创建身份提供商,这里需要填入EKS的提供商URL(该URL可以从EKS控制台拿到),然后获取指纹,受众固定填写sts.amazonaws.com,如下图:

2. 创建一个role,假设名字为aws-test-eks-alb-controller-role,信任实体填写以下内容:

  1. {

  2. "Version": "2012-10-17",

  3. "Statement": [

  4. {

  5. "Effect": "Allow",

  6. "Principal": {

  7. "Federated": "arn:aws:iam::xxxxxx:oidc-provider/oidc.eks.ap-southeast-3.amazonaws.com/idxxxxxx"

  8. },

  9. "Action": "sts:AssumeRoleWithWebIdentity",

  10. "Condition": {

  11. "StringEquals": {

  12. "oidc.eks.ap-southeast-3.amazonaws.com/id/xxxxx:sub": "system:serviceaccount:kube-system:aws-load-balancer-controller",

  13. "oidc.eks.ap-southeast-3.amazonaws.com/id/xxxxx:aud": "sts.amazonaws.com"

  14. }

  15. }

  16. }

  17. ]

  18. }

3. 创建一个Policy,Policy内容如下,Policy创建成功以后附加到上面的role上:

  1. {

  2. "Version": "2012-10-17",

  3. "Statement": [

  4. {

  5. "Effect": "Allow",

  6. "Action": [

  7. "iam:CreateServiceLinkedRole"

  8. ],

  9. "Resource": "*",

  10. "Condition": {

  11. "StringEquals": {

  12. "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com"

  13. }

  14. }

  15. },

  16. {

  17. "Effect": "Allow",

  18. "Action": [

  19. "ec2:DescribeAccountAttributes",

  20. "ec2:DescribeAddresses",

  21. "ec2:DescribeAvailabilityZones",

  22. "ec2:DescribeInternetGateways",

  23. "ec2:DescribeVpcs",

  24. "ec2:DescribeVpcPeeringConnections",

  25. "ec2:DescribeSubnets",

  26. "ec2:DescribeSecurityGroups",

  27. "ec2:DescribeInstances",

  28. "ec2:DescribeNetworkInterfaces",

  29. "ec2:DescribeTags",

  30. "ec2:GetCoipPoolUsage",

  31. "ec2:DescribeCoipPools",

  32. "elasticloadbalancing:DescribeLoadBalancers",

  33. "elasticloadbalancing:DescribeLoadBalancerAttributes",

  34. "elasticloadbalancing:DescribeListeners",

  35. "elasticloadbalancing:DescribeListenerCertificates",

  36. "elasticloadbalancing:DescribeSSLPolicies",

  37. "elasticloadbalancing:DescribeRules",

  38. "elasticloadbalancing:DescribeTargetGroups",

  39. "elasticloadbalancing:DescribeTargetGroupAttributes",

  40. "elasticloadbalancing:DescribeTargetHealth",

  41. "elasticloadbalancing:DescribeTags"

  42. ],

  43. "Resource": "*"

  44. },

  45. {

  46. "Effect": "Allow",

  47. "Action": [

  48. "cognito-idp:DescribeUserPoolClient",

  49. "acm:ListCertificates",

  50. "acm:DescribeCertificate",

  51. "iam:ListServerCertificates",

  52. "iam:GetServerCertificate",

  53. "waf-regional:GetWebACL",

  54. "waf-regional:GetWebACLForResource",

  55. "waf-regional:AssociateWebACL",

  56. "waf-regional:DisassociateWebACL",

  57. "wafv2:GetWebACL",

  58. "wafv2:GetWebACLForResource",

  59. "wafv2:AssociateWebACL",

  60. "wafv2:DisassociateWebACL",

  61. "shield:GetSubscriptionState",

  62. "shield:DescribeProtection",

  63. "shield:CreateProtection",

  64. "shield:DeleteProtection"

  65. ],

  66. "Resource": "*"

  67. },

  68. {

  69. "Effect": "Allow",

  70. "Action": [

  71. "ec2:AuthorizeSecurityGroupIngress",

  72. "ec2:RevokeSecurityGroupIngress"

  73. ],

  74. "Resource": "*"

  75. },

  76. {

  77. "Effect": "Allow",

  78. "Action": [

  79. "ec2:CreateSecurityGroup"

  80. ],

  81. "Resource": "*"

  82. },

  83. {

  84. "Effect": "Allow",

  85. "Action": [

  86. "ec2:CreateTags"

  87. ],

  88. "Resource": "arn:aws:ec2:*:*:security-group/*",

  89. "Condition": {

  90. "StringEquals": {

  91. "ec2:CreateAction": "CreateSecurityGroup"

  92. },

  93. "Null": {

  94. "aws:RequestTag/elbv2.k8s.aws/cluster": "false"

  95. }

  96. }

  97. },

  98. {

  99. "Effect": "Allow",

  100. "Action": [

  101. "ec2:CreateTags",

  102. "ec2:DeleteTags"

  103. ],

  104. "Resource": "arn:aws:ec2:*:*:security-group/*",

  105. "Condition": {

  106. "Null": {

  107. "aws:RequestTag/elbv2.k8s.aws/cluster": "true",

  108. "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"

  109. }

  110. }

  111. },

  112. {

  113. "Effect": "Allow",

  114. "Action": [

  115. "ec2:AuthorizeSecurityGroupIngress",

  116. "ec2:RevokeSecurityGroupIngress",

  117. "ec2:DeleteSecurityGroup"

  118. ],

  119. "Resource": "*",

  120. "Condition": {

  121. "Null": {

  122. "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"

  123. }

  124. }

  125. },

  126. {

  127. "Effect": "Allow",

  128. "Action": [

  129. "elasticloadbalancing:CreateLoadBalancer",

  130. "elasticloadbalancing:CreateTargetGroup"

  131. ],

  132. "Resource": "*",

  133. "Condition": {

  134. "Null": {

  135. "aws:RequestTag/elbv2.k8s.aws/cluster": "false"

  136. }

  137. }

  138. },

  139. {

  140. "Effect": "Allow",

  141. "Action": [

  142. "elasticloadbalancing:CreateListener",

  143. "elasticloadbalancing:DeleteListener",

  144. "elasticloadbalancing:CreateRule",

  145. "elasticloadbalancing:DeleteRule"

  146. ],

  147. "Resource": "*"

  148. },

  149. {

  150. "Effect": "Allow",

  151. "Action": [

  152. "elasticloadbalancing:AddTags",

  153. "elasticloadbalancing:RemoveTags"

  154. ],

  155. "Resource": [

  156. "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",

  157. "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",

  158. "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"

  159. ],

  160. "Condition": {

  161. "Null": {

  162. "aws:RequestTag/elbv2.k8s.aws/cluster": "true",

  163. "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"

  164. }

  165. }

  166. },

  167. {

  168. "Effect": "Allow",

  169. "Action": [

  170. "elasticloadbalancing:AddTags",

  171. "elasticloadbalancing:RemoveTags"

  172. ],

  173. "Resource": [

  174. "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",

  175. "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",

  176. "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",

  177. "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"

  178. ]

  179. },

  180. {

  181. "Effect": "Allow",

  182. "Action": [

  183. "elasticloadbalancing:ModifyLoadBalancerAttributes",

  184. "elasticloadbalancing:SetIpAddressType",

  185. "elasticloadbalancing:SetSecurityGroups",

  186. "elasticloadbalancing:SetSubnets",

  187. "elasticloadbalancing:DeleteLoadBalancer",

  188. "elasticloadbalancing:ModifyTargetGroup",

  189. "elasticloadbalancing:ModifyTargetGroupAttributes",

  190. "elasticloadbalancing:DeleteTargetGroup"

  191. ],

  192. "Resource": "*",

  193. "Condition": {

  194. "Null": {

  195. "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"

  196. }

  197. }

  198. },

  199. {

  200. "Effect": "Allow",

  201. "Action": [

  202. "elasticloadbalancing:AddTags"

  203. ],

  204. "Resource": [

  205. "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",

  206. "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",

  207. "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"

  208. ],

  209. "Condition": {

  210. "StringEquals": {

  211. "elasticloadbalancing:CreateAction": [

  212. "CreateTargetGroup",

  213. "CreateLoadBalancer"

  214. ]

  215. },

  216. "Null": {

  217. "aws:RequestTag/elbv2.k8s.aws/cluster": "false"

  218. }

  219. }

  220. },

  221. {

  222. "Effect": "Allow",

  223. "Action": [

  224. "elasticloadbalancing:RegisterTargets",

  225. "elasticloadbalancing:DeregisterTargets"

  226. ],

  227. "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*"

  228. },

  229. {

  230. "Effect": "Allow",

  231. "Action": [

  232. "elasticloadbalancing:SetWebAcl",

  233. "elasticloadbalancing:ModifyListener",

  234. "elasticloadbalancing:AddListenerCertificates",

  235. "elasticloadbalancing:RemoveListenerCertificates",

  236. "elasticloadbalancing:ModifyRule"

  237. ],

  238. "Resource": "*"

  239. }

  240. ]

  241. }

4. 在kube-system的namespace下创建一个SA,SA的名称是aws-load-balancer-controller,SA的YAML文件定义如下:

  1. apiVersion: v1

  2. kind: ServiceAccount

  3. metadata:

  4. annotations:

  5. eks.amazonaws.com/role-arn: arn:aws:iam::xxxxx:role/aws-test-eks-alb-controller-role

  6. labels:

  7. app.kubernetes.io/component: controller

  8. app.kubernetes.io/name: aws-load-balancer-controller

  9. name: aws-load-balancer-controller

  10. namespace: kube-system

5. 获取ingress aws alb contorller的资源清单文件,修改后进行应用

  1. wget https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.5.1/v2_5_1_full.yaml

对资源文件中的内容进行修改,首先删除ServiceAccount(内容如下图),第三步我们已经创建过了。

其次我们需要修改Deployment中cluster-name变成我们的ESK集群名称,我的集群名称是test-eks,所以修改后的信息如下图:

最后应用我们的资源清单文件:

  1. kubectl apply -f v2_5_1_full.yaml

6. 获取ingress class类文件,并应用该资源文件

  1. wget https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.5.1/v2_5_1_ingclass.yaml


  2. kubectl apply -f v2_5_1_ingclass.yaml

ingress原理

通过ingress让集群外的服务访问我们集群内的服务,通过上图可以看出大约需要4个组件

  • Ingress Controller:这里我们选用的是aws的alb

  • Ingress:具体的ingress,这里面会配置路由规则,我这里是按照环境建立ingress

  • Service:服务,用来对Pod做负载均衡

  • Pod:具体的服务,这里的Pod我们通常不单独部署,一般通过Deployment组件进行维护

Service配置

假设我们的Pod已经配置好了,这里我们看一下Service的资源清单文件配置,如下:

  1. kind: Service

  2. apiVersion: v1

  3. metadata:

  4. name: test

  5. namespace: application-test

  6. annotations:

  7. alb.ingress.kubernetes.io/healthcheck-interval-seconds: '8'

  8. alb.ingress.kubernetes.io/healthcheck-path: /sys/health/check

  9. alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'

  10. alb.ingress.kubernetes.io/healthy-threshold-count: '3'

  11. alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'

  12. spec:

  13. ports:

  14. - protocol: TCP

  15. port: 80

  16. targetPort: 8009

  17. selector:

  18. app: xxxxx

  19. type: ClusterIP

关于Service我们这里不再赘述,我们主要关心和AWS相关的配置,也就是annotation的信息,anntation这里我们主要配置的是目标组里的健康监测信息,当我们对上述资源文件进行应用以后,目标组上健康检测信息配置和上图将会对齐,如下图:

Ingress配置

这里我们将会定义我们的ingress资源文件,推荐按照环境进行区分(毕竟我们的Service以及Pod都是和环境对应的),一个ingress资源文件将会建立一个ALB负责均衡器,ingress资源文件示例如下:

  1. kind: Ingress

  2. apiVersion: networking.k8s.io/v1

  3. metadata:

  4. name: alb-internal-ingress-backend

  5. namespace: application-test

  6. annotations:

  7. alb.ingress.kubernetes.io/load-balancer-name: test-k8s-application

  8. alb.ingress.kubernetes.io/scheme: internal

  9. alb.ingress.kubernetes.io/security-groups: sg-xxxx

  10. alb.ingress.kubernetes.io/subnets: 'subnet-xxxx,subnet-xxxx'

  11. alb.ingress.kubernetes.io/target-type: ip

  12. spec:

  13. ingressClassName: alb

  14. rules:

  15. - host: test.xxx.example.com

  16. http:

  17. paths:

  18. - path:

  19. pathType: Prefix

  20. backend:

  21. service:

  22. name: test

  23. port:

  24. number: 80

首先这里的ingressClassName必须指定为alb,这表明我们要使用alb controller对他进行控制,其次我们关注一下ingress的annotations:

  • alb.ingress.kubernetes.io/scheme:我们指定为internal,表明我们的alb不面向互联网,是面向内部网络的

  • alb.ingress.kubernetes.io/security-groups:指定alb上的安全组

  • alb.ingress.kubernetes.io/subnets:指定alb的子网

  • alb.ingress.kubernetes.io/target-type:指定目标组的注册类型,默认是实例,这里我们修改为IP,这个annotation也可以用在Service上

下面的rule表示域名test.xxx.example.com的请求将会被转发到test service的80端口,进而通过Service后端Pod负载上。

上述资源清单文件安装完成以后,会在AWS负载均衡器上创建一个alb,如下图:

我们通过nslookup命令接卸DNS名称,会发现他是个内网地址,说明和我们的ALB模式(面向内部)匹配如下图:

Route53配置

最后我们在Route53上增加一条test.xxx.example.com CNAME到AWS ALB DNS名称记录,这样我们其他的服务通过test.xxx.example.com这个域名即可调用到我们集群内部的服务。


【知识星球招募】


  知识星球正在初期搭建中,在星球中可以互相提问,分享经验,我也会在星球中分享基础技术架构的全流程搭建,包括但不仅限于DevOps,监控、Flink开发,Java开发(JVM、多线程、MySQL数据库)等相关技术类文章,期待大家的加入




文章转载自程序员修炼笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论