• 容器编排学习(六)服务管理与用户权限管理


    一  service管理

    1  概述

    • 容器化带来的问题
    1. 自动调度:在 Pod 创建之前,用户无法预知 Pod 所在的节点,以及 Pod的IP 地址
    2. 一个已经存在的 Pod 在运行过程中,如果出现故障,Pod也会在新的节点使用新的IP 进行部署
    3. 应用程序访问服务的时候,地址也不能经常变换
    4. 多个相同的 Pod 如何访问他们上面的服务
    • Service 就是解决这些问题的方法

    2  服务的自动感知

    服务会创建一个 clusterIP 这个地址对应资源地址,不管pod 如何变化,服务总能找到对应的 Pod,且clusterIP保持不变

    3  服务的负载均衡

    如果服务后端对应多个 Pod,则会通过 IPTables/LVS 规则将访问的请求最终映射到 Pod 的容器内部,自动在多个容器间实现负载均衡

    4  服务的自动发现

    服务创建时会自动在内部 DNS 上注册域名

    域名:<服务名称>.<名称空间>.svc.cluster.local

    二  clusterIP 服务 

    1  概述

    默认的 ServiceType,通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。

    2  创建服务

    1. # 资源对象模板
    2. [root@master ~]# kubectl create service clusterip mysvc --tcp=80:80 --dry-run=client -o yaml
    3. [root@master ~]# vim mysvc.yaml
    4. ---
    5. kind: Service # 资源对象类型
    6. apiVersion: v1 # 版本
    7. metadata: # 元数据
    8. name: mysvc # 资源对象名称
    9. spec: # 详细信息
    10. type: ClusterIP # 服务类型
    11. selector: # 选择算符
    12. app: web # Pod标签
    13. ports: # 端口
    14. - protocol: TCP # 协议
    15. port: 80 # 监听的端口
    16. targetPort: 80 # 后端服务端口
    17. ********************************************
    18. selector:
    19. app: web # 引用标签
    20. ********************************************

    3  域名自动注册

    1. [root@master ~]# kubectl apply -f mysvc.yaml
    2. service/mysvc created
    3. [root@master ~]# kubectl get service
    4. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    5. kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 2d18h
    6. mysvc ClusterIP 10.245.5.18 <none> 80/TCP 8s

    4  解析域名

    1. # 安装工具软件包
    2. [root@master ~]# dnf install -y bind-utils
    3. # 查看 DNS 服务地址
    4. [root@master ~]# kubectl -n kube-system get service kube-dns
    5. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    6. kube-dns ClusterIP 10.245.0.10 <none> 53/UDP,53/TCP,9153/TCP 3d10h
    7. # 域名解析测试
    8. [root@master ~]# host mysvc.default.svc.cluster.local 10.245.0.10
    9. Using domain server:
    10. Name: 10.245.0.10
    11. Address: 10.245.0.10#53
    12. Aliases:
    13. mysvc.default.svc.cluster.local has address 10.245.5.18

    5  创建后端应用

    1. [root@master ~]# vim myweb.yaml
    2. ---
    3. kind: Pod
    4. apiVersion: v1
    5. metadata:
    6. name: web1
    7. labels:
    8. app: web # 服务靠标签寻找后端,定义标签
    9. spec:
    10. containers:
    11. - name: apache
    12. image: myos:httpd

    6  服务自动感知 

    1. [root@master ~]# kubectl apply -f myweb.yaml
    2. pod/web1 created
    3. [root@master ~]# curl http://10.245.5.18
    4. Welcome to The Apache.

    7  服务的负载均衡

    1. [root@master ~]# sed 's,web1,web2,' myweb.yaml |kubectl apply -f -
    2. pod/web2 created
    3. [root@master ~]# sed 's,web1,web3,' myweb.yaml |kubectl apply -f -
    4. pod/web3 created
    5. [root@master ~]# curl -s http://10.245.5.18/info.php |grep php_host
    6. php_host: web1
    7. [root@master ~]# curl -s http://10.245.5.18/info.php |grep php_host
    8. php_host: web2
    9. [root@master ~]# curl -s http://10.245.5.18/info.php |grep php_host
    10. php_host: web3

    8  服务的工作原理

    -kube-proxy是在所有节点上运行的代理。可以实现简单的数据转发,可以设置更新 IPTables/LVS 规则,在服务创建时,还提供服务地址DNS自动注册与服务发现功能

    9  使用服务固定IP

    ClusterIP 是随机分配的,如果想使用固定IP,可以自定义,但 IP 的范围必须符合服务的 CIDR

    1. [root@master ~]# vim mysvc.yaml
    2. ---
    3. kind: Service
    4. apiVersion: v1
    5. metadata:
    6. name: mysvc
    7. spec:
    8. type: ClusterIP
    9. clusterIP: 10.245.1.80 # 可以设置 ClusterIP,固定IP
    10. selector:
    11. app: web
    12. ports:
    13. - protocol: TCP
    14. port: 80
    15. targetPort: 80
    16. [root@master ~]# kubectl delete service mysvc
    17. service "mysvc" deleted
    18. [root@master ~]# kubectl apply -f mysvc.yaml
    19. service/mysvc created
    20. [root@master ~]# kubectl get service
    21. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    22. kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 2d18h
    23. mysvc ClusterIP 10.245.1.80 <none> 80/TCP 65s
    端口别名
    1. [root@master ~]# kubectl delete pod --all
    2. pod "web1" deleted
    3. pod "web2" deleted
    4. pod "web3" deleted
    5. [root@master ~]# vim mysvc.yaml
    6. ---
    7. kind: Service
    8. apiVersion: v1
    9. metadata:
    10. name: mysvc
    11. spec:
    12. type: ClusterIP
    13. clusterIP: 10.245.1.80
    14. selector:
    15. app: web
    16. ports:
    17. - protocol: TCP
    18. port: 80
    19. targetPort: myhttp # 使用别名查找后端服务端口
    20. [root@master ~]# kubectl apply -f mysvc.yaml
    21. service/mysvc configured
    22. [root@master ~]# vim myweb.yaml
    23. ---
    24. kind: Pod
    25. apiVersion: v1
    26. metadata:
    27. name: web1
    28. labels:
    29. app: web
    30. spec:
    31. containers:
    32. - name: apache
    33. image: myos:httpd
    34. ports: # 配置端口规范
    35. - name: myhttp # 端口别名
    36. protocol: TCP # 协议
    37. containerPort: 80 # 端口号
    38. [root@master ~]# kubectl apply -f myweb.yaml
    39. pod/web1 created
    40. [root@master ~]# curl http://10.245.1.80
    41. Welcome to The Apache.

    10  服务排错

    服务 web123 的使用 web1作为后端,提供 Cluster IP 服务

    1. ---
    2. kind: Service
    3. apiVersion: v1
    4. metadata:
    5. name: web123
    6. spec:
    7. type: ClusterIP
    8. clusterIP: 192.168.1.88
    9. selector:
    10. app: apache
    11. ports:
    12. - protocol: TCP
    13. port: 80
    14. targetPort: web

    三  对外发布应用

    1  发布服务

    clusterIP 服务可以解决集群内应用互访的问题,但外部的应用无法访问集群内的资源,某些应用需要访问集群内的资源,我们就需要对外发布服务

    2  服务类型

    • clusterIP:默认类型,可以实现 Pod的自动感知与负载均衡,是最核心的服务类型,但 clusterIP 不能对外发布服务,如果想对外发布服务可以使用 NodePort 或 Ingress
    • NodePort:使用基于端口映射(默认值:30000-32767)的方式对外发布服务,可以发布任意服务 (四层)
    • Ingress:使用Ingress 控制器(一般由 Nginx 或 HAProxy 构成)用来发布 http、https 服务 (七层)

    四  nodePort 服务

    对外发布服务
    1. [root@master ~]# cp -a mysvc.yaml mysvc1.yaml
    2. [root@master ~]# vim mysvc1.yaml
    3. ---
    4. kind: Service
    5. apiVersion: v1
    6. metadata:
    7. name: mysvc1
    8. spec:
    9. type: NodePort # 服务类型
    10. selector:
    11. app: web
    12. ports:
    13. - protocol: TCP
    14. port: 80
    15. nodePort: 30080 # 映射端口号
    16. targetPort: myhttp
    17. [root@master ~]# kubectl apply -f mysvc1.yaml
    18. service/mysvc configured
    19. [root@master ~]# kubectl get service
    20. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    21. kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 5d18h
    22. mysvc ClusterIP 10.245.1.80 <none> 80/TCP 17m
    23. mysvc1 NodePort 10.245.1.88 <none> 80:30080/TCP 7s
    24. [root@master ~]# curl http://node-0001:30080
    25. Welcome to The Apache.
    26. [root@master ~]# curl http://node-0002:30080
    27. Welcome to The Apache.
    28. [root@master ~]# curl http://node-0003:30080
    29. Welcome to The Apache.
    30. [root@master ~]# curl http://node-0004:30080
    31. Welcome to The Apache.
    32. [root@master ~]# curl http://node-0005:30080
    33. Welcome to The Apache.

    五  Ingress  服务

    1  概述

    Ingress 公开从集群外部到集群内服务的 HTTP 和 HTTPS路由。流量路由由 Ingress 资源上定义的规则控制。

    Ingress 控制器通常由负载均衡器来实现 (Nginx、HAProxy)

    2  安装控制器

    安装Ingress 控制器

    • Ingress 服务由(规则 + 控制器)组成
    • 规则负责制定策略,控制器负责执行
    • 如果没有控制器,单独设置规则无效

    获取控制器镜像及资源文件的地址: https://github.com/kubernetes/ingress-nginx

    1. # 导入镜像到私有仓库
    2. [root@master ~]# cd plugins/ingress
    3. [root@master ingress]# docker load -i ingress.tar.xz
    4. [root@master ingress]# docker images|while read i t _;do
    5. [[ "${t}" == "TAG" ]] && continue
    6. [[ "${i}" =~ ^"harbor:443/".+ ]] && continue
    7. docker tag ${i}:${t} harbor:443/plugins/${i##*/}:${t}
    8. docker push harbor:443/plugins/${i##*/}:${t}
    9. docker rmi ${i}:${t} harbor:443/plugins/${i##*/}:${t}
    10. done
    11. # 安装控制器
    12. [root@master ingress]# sed -ri 's,^(\s*image: )(.*/)?(.+)@.*,\1harbor:443/plugins/\3,' deploy.yaml
    13. 458: image: harbor:443/plugins/controller:v1.5.1
    14. 565: image: harbor:443/plugins/kube-webhook-certgen:v20220916-gd32f8c343
    15. 614: image: harbor:443/plugins/kube-webhook-certgen:v20220916-gd32f8c343
    16. [root@master ingress]# kubectl apply -f deploy.yaml
    17. # 通过标签指定在那台机器上发布应用
    18. [root@master ingress]# kubectl label nodes node-0001 ingress-ready="true"
    19. node/node-0001 labeled
    20. [root@master ingress]# kubectl -n ingress-nginx get pods
    21. NAME READY STATUS RESTARTS AGE
    22. ingress-nginx-admission-create--1-lm52c 0/1 Completed 0 29s
    23. ingress-nginx-admission-patch--1-sj2lz 0/1 Completed 0 29s
    24. ingress-nginx-controller-5664857866-tql24 1/1 Running 0 29s

    3  验证后端服务

    1. [root@master ~]# kubectl get pods,services
    2. NAME READY STATUS RESTARTS AGE
    3. pod/web1 1/1 Running 0 35m
    4. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    5. service/kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 31h
    6. service/mysvc ClusterIP 10.245.1.80 <none> 80/TCP 34m
    7. service/mysvc1 NodePort 10.245.1.88 <none> 80:30080/TCP 8s
    8. [root@master ~]# curl http://10.245.1.80
    9. Welcome to The Apache.

    4  配置  ingress 规则,对外发布服务

    1. [root@master ~]# kubectl get ingressclasses.networking.k8s.io
    2. NAME CONTROLLER PARAMETERS AGE
    3. nginx k8s.io/ingress-nginx <none> 5m7s
    4. # 资源对象模板
    5. [root@master ~]# kubectl create ingress mying --class=nginx --rule=nsd.tedu.cn/*=mysvc:80 --dry-run=client -o yaml
    6. [root@master ~]# vim mying.yaml
    7. ---
    8. kind: Ingress # 资源对象类型
    9. apiVersion: networking.k8s.io/v1 # 资源对象版本
    10. metadata: # 元数据
    11. name: mying # 资源对象名称
    12. spec: # 资源对象定义
    13. ingressClassName: nginx # 使用的类的名称
    14. rules: # ingress 规则定义
    15. - host: nsd.tedu.cn # 域名定义,没有可以不写
    16. http: # 协议
    17. paths: # 访问的路径定义
    18. - backend: # 后端服务
    19. service: # 服务声明
    20. name: mysvc # 服务名称
    21. port: # 端口号声明
    22. number: 80 # 访问服务的端口号
    23. path: / # 访问的 url 路径
    24. pathType: Prefix # 路径的类型,Exact、Prefix
    25. # 发布服务
    26. [root@master ~]# kubectl apply -f mying.yaml
    27. ingress.networking.k8s.io/mying created
    28. [root@master ~]# kubectl get ingress
    29. NAME CLASS HOSTS ADDRESS PORTS AGE
    30. mying nginx nsd.tedu.cn 192.168.1.51 80 70s
    31. # 访问验证
    32. [root@master ~]# curl -H "Host: nsd.tedu.cn" http://192.168.1.51
    33. Welcome to The Apache.

    六  web管理插件

    Dashboard

    <1> 概述

    Dashboard 是基于网页的 Kubernetes 用户界面

    Dashboard 同时展示了 Kubernetes集群中的资源状态信息和所有报错信息

    你可以使用 Dashboard 将应用部署到集群中,也可以对容器应用排错,还能管理集群资源。例如,你可以对应用弹性伸缩、发起滚动升级、重启等等

    Dashboard 官网地址:https://github.com/ kubernetes/dashboard

    <2> 安装Dashboard

    1. [root@master ~]# cd plugins/dashboard
    2. [root@master dashboard]# docker load -i dashboard.tar.xz
    3. [root@master dashboard]# docker images|while read i t _;do
    4. [[ "${t}" == "TAG" ]] && continue
    5. [[ "${i}" =~ ^"harbor:443/".+ ]] && continue
    6. docker tag ${i}:${t} harbor:443/plugins/${i##*/}:${t}
    7. docker push harbor:443/plugins/${i##*/}:${t}
    8. docker rmi ${i}:${t} harbor:443/plugins/${i##*/}:${t}
    9. done
    10. [root@master dashboard]# sed -ri 's,^(\s*image: )(.*/)?(.+),\1harbor:443/plugins/\3,' recommended.yaml
    11. 193: image: harbor:443/plugins/dashboard:v2.7.0
    12. 278: image: harbor:443/plugins/metrics-scraper:v1.0.8
    13. [root@master dashboard]# kubectl apply -f recommended.yaml
    14. [root@master dashboard]# kubectl -n kubernetes-dashboard get pods
    15. NAME READY STATUS RESTARTS AGE
    16. dashboard-metrics-scraper-66f6f56b59-b42ng 1/1 Running 0 67s
    17. kubernetes-dashboard-65ff57f4cf-lwtsk 1/1 Running 0 67s

    <3> 发布Dashboard服务

    1. # 查看服务状态
    2. [root@master dashboard]# kubectl -n kubernetes-dashboard get service
    3. NAME TYPE CLUSTER-IP PORT(S) AGE
    4. dashboard-metrics-scraper ClusterIP 10.245.205.236 8000/TCP 1m50s
    5. kubernetes-dashboard ClusterIP 10.245.215.40 443/TCP 1m51s
    6. # 获取服务资源对象文件
    7. [root@master dashboard]# sed -n '30,45p' recommended.yaml >dashboard-svc.yaml
    8. [root@master dashboard]# vim dashboard-svc.yaml
    9. ---
    10. kind: Service
    11. apiVersion: v1
    12. metadata:
    13. labels:
    14. k8s-app: kubernetes-dashboard
    15. name: kubernetes-dashboard
    16. namespace: kubernetes-dashboard
    17. spec:
    18. type: NodePort
    19. ports:
    20. - port: 443
    21. nodePort: 30443
    22. targetPort: 8443
    23. selector:
    24. k8s-app: kubernetes-dashboard
    25. [root@master dashboard]# kubectl apply -f dashboard-svc.yaml
    26. service/kubernetes-dashboard configured
    27. [root@master dashboard]# kubectl -n kubernetes-dashboard get service
    28. NAME TYPE CLUSTER-IP PORT(S) AGE
    29. dashboard-metrics-scraper ClusterIP 10.245.205.236 8000/TCP 5m50s
    30. kubernetes-dashboard NodePort 10.245.215.40 443:30443/TCP 5m51s
    • 通过浏览器访问 Dashboard 登录页面

    七  服务账号与权限

    1  用户概述

    <1>  用户认证

    所有 Kubernetes 集群都有两类用户:由 Kubernetes 管理的服务账号和普通用户。

    普通用户是以证书或秘钥形式签发,主要用途是认证和鉴权集群中并不包含用来代表普通用户账号的对象,普通用户的信息无法调用和查询。

    服务账号是 Kubernetes API 所管理的用户。它们被绑定到特定的名字空间,与一组 Seret 凭据相关联,供 Pod 调用以获得相应的授权。

    <2> 创建 ServiceAccount 服务账号

    1. # 资源对象模板
    2. [root@master ~]# kubectl -n kubernetes-dashboard create serviceaccount kube-admin --dry-run=client -o yaml
    3. [root@master ~]# vim admin-user.yaml
    4. ---
    5. kind: ServiceAccount
    6. apiVersion: v1 # 版本
    7. metadata: # 资源对象类型
    8. name: kube-admin # ServiceAccount
    9. namespace: kubernetes-dashboard # 名称空间
    10. [root@master ~]# kubectl apply -f admin-user.yaml
    11. serviceaccount/kube-admin created
    12. [root@master ~]# kubectl -n kubernetes-dashboard get serviceaccounts
    13. NAME SECRETS AGE
    14. default 0 16m
    15. kube-admin 0 11s
    16. kubernetes-dashboard 0 16m

    <3>  获取用户token

    1. [root@master ~]# kubectl -n kubernetes-dashboard create token kube-admin

    2 权限管理

    <1>  角色与鉴权

    如果想访问和管理 kubernetes 集群,就要对身份以及权限做验证,kubernetes 支持的鉴权模块有 Node、RBAC、ABAC、Webhook AP

    • Node:一种特殊用途的鉴权模式,专门对 kubelet 发出的请求进行鉴权。
    • RBAC:是一种基于组织中用户的角色来控制资源使用的方法
    • ABAC:基于属性的访问控制,是一种通过将用户属性与权限组合在一起像用户授权的方法
    • Webhook:是一个HTTP回调

    <2>  普通角色授权

    1. # 查询当前集群使用的鉴权方法
    2. [root@master ~]# kubectl cluster-info dump |grep authorization-mode
    3. "--authorization-mode=Node,RBAC",
    4. # 资源对象模板
    5. [root@master ~]# kubectl -n default create role myrole --resource=pods --verb=get,list --dry-run=client -o yaml
    6. [root@master ~]# kubectl -n default create rolebinding kube-admin-role --role=myrole --serviceaccount=kubernetes-dashboard:kube-admin --dry-run=client -o yaml
    7. [root@master ~]# vim myrole.yaml
    8. ---
    9. kind: Role
    10. apiVersion: rbac.authorization.k8s.io/v1
    11. metadata:
    12. name: myrole
    13. namespace: default
    14. rules:
    15. - apiGroups:
    16. - ""
    17. resources:
    18. - pods
    19. verbs:
    20. - get
    21. - list
    22. ---
    23. kind: RoleBinding
    24. apiVersion: rbac.authorization.k8s.io/v1
    25. metadata:
    26. name: kube-admin-role # 授权名称
    27. namespace: default
    28. roleRef: # 关联权限
    29. apiGroup: rbac.authorization.k8s.io # 角色对象组
    30. kind: Role # 角色对象
    31. name: myrole # 角色名称
    32. subjects: # 授权信息
    33. - kind: ServiceAccount # 账户资源对象
    34. name: kube-admin # 账户名称
    35. namespace: kubernetes-dashboard # 账户所在的名称空间
    36. [root@master ~]# kubectl apply -f myrole.yaml
    37. role.rbac.authorization.k8s.io/myrole created
    38. rolebinding.rbac.authorization.k8s.io/kube-admin-role created
    39. [root@master ~]# kubectl delete -f myrole.yaml
    40. role.rbac.authorization.k8s.io "myrole" deleted
    41. rolebinding.rbac.authorization.k8s.io "kube-admin-role" deleted

    <3>  RBAC 授权 

    RBAC 声明了四种 Kubernetes 对象:

    • Role:用来在某一个名称空间内创建授权角色,创建 Role时,必须指定所属的名字空间的名
    • ClusterRole:可以和 Role 相同完成授权。但属于集群范围,对所有名称空间有效。
    • RoleBinding:是将角色中定义的权限赋予一个或者一组用户,可以使用 Role或ClusterRole 完成授权。
    • ClusterRoleBinding 在集群范围执行授权,对所有名称空间有效,只能使用 clusterRole 完成授权

    <4> 资源对象角色与作用域

     <5>  资源对象权限

    <6>  自定义权限

    1. ---
    2. kind: Role
    3. apiVersion: rbac.authorization.k8s.io/v1
    4. metadata:
    5. name: myrole # 角色名称
    6. namespace: default
    7. rules: # 规则
    8. - apiGroups: # 资源对象所属组信息
    9. - "" # 分组信息
    10. resources: # 要设置权限的资源对象
    11. - pods # 授权资源对象名称
    12. verbs: # 权限设置
    13. - get # 权限
    14. - list # 权限

    <7> 集群管理员权限

    1. [root@master ~]# kubectl get clusterrole
    2. NAME CREATED AT
    3. admin 2022-06-24T08:11:17Z
    4. cluster-admin 2022-06-24T08:11:17Z
    5. ... ...
    6. # 资源对象模板
    7. [root@master ~]# kubectl create clusterrolebinding kube-admin-role --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:kube-admin --dry-run=client -o yaml
    8. [root@master ~]# vim admin-user.yaml
    9. ---
    10. kind: ServiceAccount
    11. apiVersion: v1
    12. metadata:
    13. name: kube-admin
    14. namespace: kubernetes-dashboard
    15. ---
    16. kind: ClusterRoleBinding
    17. apiVersion: rbac.authorization.k8s.io/v1
    18. metadata:
    19. name: kube-admin-role
    20. roleRef:
    21. apiGroup: rbac.authorization.k8s.io
    22. kind: ClusterRole
    23. name: cluster-admin
    24. subjects:
    25. - kind: ServiceAccount
    26. name: kube-admin
    27. namespace: kubernetes-dashboard
    28. [root@master ~]# kubectl apply -f admin-user.yaml
    29. serviceaccount/kube-admin unchanged
    30. clusterrolebinding.rbac.authorization.k8s.io/kube-admin-role created

  • 相关阅读:
    语音处理加窗分帧
    算法升级之路(二)
    一文读懂LSTM及手写LSTM结构
    对话阿里巴巴副总裁贾扬清:追求大模型,并不是一件坏事
    全志烧录工具LiveSuite使用注意事项
    Java中的抽象类和接口(Abstract Class and Interface)的区别
    WeCross应用搭建整理,遇到的一些问题,WeCross如何搭建?
    Stimulsoft Ultimate 2022.4.5 Crack
    Python3 面向对象
    FCN理论部分
  • 原文地址:https://blog.csdn.net/2301_79227925/article/details/132745473