云端技术驾驭DAY15——ClusterIP服务、Ingress服务、Dashboard插件、k8s角色的认证与授权

往期回顾:
云端技术驾驭DAY01------云计算底层技术奥秘、云服务器磁盘技术、虚拟化管理、公有云概述
云端技术驾驭DAY02------华为云管理、云主机管理、跳板机配置、制作私有镜像模板
云端技术驾驭DAY03------云主机网站部署、web集群部署、Elasticsearch安装
云端技术驾驭DAY04------Logstash安装部署及插件模块
云端技术驾驭DAY06------容器技术概述、镜像与容器管理、定制简单镜像、容器内安装部署服务
云端技术驾驭DAY07------Dockerfile详解、容器镜像制作、私有仓库
云端技术驾驭DAY08------部署容器服务、Compose微服务管理、harbor仓库部署及管理
云端技术驾驭DAY09------k8s集群安装部署、calico插件部署、计算节点配置管理
云端技术驾驭DAY10------kubectl命令详解、Pod创建过程、Pod的生命周期、定制Pod、资源对象文件
云端技术驾驭DAY11------资源对象文件、Pod自定义命令、多容器Pod、资源监控工具
云端技术驾驭DAY12------Pod调度策略、Pod标签管理、Pod资源配额与限额、全局资源配额与限额策略
云端技术驾驭DAY13------Pod污点、容忍策略、Pod优先级与抢占、容器安全
云端技术驾驭DAY14------存储卷管理、临时卷、持久卷、PV/PVC管理

云端技术驾驭DAY15

服务管理

Service

服务原理
  • 容器化带来的问题
    • 自动调度:在Pod创建之前,用户无法预知Pod所在的节点以及Pod的IP地址
    • 一个已经存在的Pod在运行过程中,如果出现故障,Pod也会在新的节点使用新的IP进行部署
    • 应用程序访问服务的时候,地址也不能经常变换
    • 多个相同的Pod如何访问它们上面的服务
  • Service就是解决这些问题的方法
  • 服务的自动感知
    • 服务会创建一个cluster IP这个地址对应资源地址,不管Pod如何变化,服务总能找到对应的Pod,且cluster IP保持不变
  • 服务的负载均衡
    • 如果服务后端对应多个Pod,则会通过IPTables/LVS规则将访问的请求最终映射到Pod的容器内部,自动在多个容器间实现负载均衡
  • 服务的自动发现
    • 服务创建时会自动在内部DNS上注册域名
    • 域名:<服务名称>.<名称空间>.svc.cluster.local
Cluster IP 服务
  • Cluster IP 类型

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

      [root@master ~]# vim mysvc.yaml

      apiVersion: v1
      kind: Service # 资源对象类型
      metadata:
      name: mysvc # 资源对象名称
      spec:
      ports:

      • port: 80 # 监听的端口
        protocol: TCP # 协议
        targetPort: 80 # 后端服务端口
        selector: # 选择算符
        app: web # Pod标签
        type: ClusterIP # 服务类型

      [root@master ~]# kubectl apply -f mysvc.yaml
      service/mysvc created
      [root@master ~]# kubectl get services
      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
      kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 7d19h
      mysvc ClusterIP 10.245.74.82 <none> 80/TCP 7s

  • 服务的自动发现(域名自动注册)

    [root@master ~]# dnf -y install bind-utils

    [root@master ~]# kubectl -n kube-system get service kube-dns # 查看 DNS 服务地址
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
    kube-dns ClusterIP 10.245.0.10 <none> 53/UDP,53/TCP,9153/TCP

    [root@master ~]# host mysvc.default.svc.cluster.local 10.245.0.10 # 域名解析测试
    Using domain server:
    Name: 10.245.0.10
    Address: 10.245.0.10#53
    Aliases:

    mysvc.default.svc.cluster.local has address 10.245.74.82

    [root@master ~]# vim myweb.yaml # 创建后端应用

    kind: Pod
    apiVersion: v1
    metadata:
    name: web1
    labels:
    app: web # 服务靠标签寻找后端
    spec:
    containers:
    - name: apache
    image: myos:httpd

    [root@master ~]# kubectl apply -f myweb.yaml
    pod/web1 created
    [root@master ~]# curl 10.245.74.82
    Welcome to The Apache.

  • 负载均衡

    [root@master ~]# sed 's,web1,web2,' myweb.yaml | kubectl apply -f -
    pod/web2 created
    [root@master ~]# sed 's,web1,web3,' myweb.yaml | kubectl apply -f -
    pod/web3 created
    [root@master ~]# curl 10.245.74.82/info.php | grep php_host
    php_host: web3
    [root@master ~]# curl 10.245.74.82/info.php | grep php_host
    php_host: web2
    [root@master ~]# curl 10.245.74.82/info.php | grep php_host
    php_host: web1

  • Cluster IP 服务的工作原理

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

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

    • 通过kubectl cluster-info dump | grep -i service-cluster-ip-range查看IP范围

      [root@master ~]# vim mysvc.yaml

      apiVersion: v1
      kind: Service
      metadata:
      name: mysvc
      spec:
      ports:

      • port: 80
        protocol: TCP
        targetPort: 80
        selector:
        app: web
        type: ClusterIP
        clusterIP: 10.245.1.80

      [root@master ~]# kubectl delete service mysvc
      service "mysvc" deleted
      [root@master ~]# kubectl apply -f mysvc.yaml
      service/mysvc created
      [root@master ~]# kubectl get services
      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
      kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 7d20h
      mysvc ClusterIP 10.245.1.80 <none> 80/TCP 7s

  • 端口别名

    • 当两个作为后端的Pod端口号不一样时,可以使用端口别名

      [root@master ~]# vim mysvc.yaml

      apiVersion: v1
      kind: Service
      metadata:
      name: mysvc
      spec:
      ports:

      • port: 80
        protocol: TCP
        targetPort: myhttp # 使用别名查找后端服务端口
        selector:
        app: web
        type: ClusterIP
        clusterIP: 10.245.1.80

      [root@master ~]# vim myweb.yaml

      kind: Pod
      apiVersion: v1
      metadata:
      name: web1
      labels:
      app: web
      spec:
      containers:

      • name: apache
        image: myos:httpd
        ports: # 配置端口规范
        • name: myhttp # 声明端口别名
          protocol: TCP # 协议
          containerPort: 80 # 端口号

      [root@master ~]# kubectl delete service mysvc
      service "mysvc" deleted
      [root@master ~]# kubectl apply -f mysvc.yaml
      service/mysvc created
      [root@master ~]# kubectl apply -f myweb.yaml
      pod/web1 created
      [root@master ~]# curl 10.245.1.80 # 通过别名和指定IP访问成功
      Welcome to The Apache.

对外发布应用

服务类型
  • 发布服务
    • ClusterIP服务可以解决集群内应用互访的问题,但外部的应用无法访问集群内的资源,某些应用需要访问集群内的资源,我们就需要对外发布服务
  • 服务类型
    • ClusterIP默认类型可以实现Pod的自动感知与负载均衡,是最核心的服务类型,但ClusterIp不能对外发布服务,如果想对外发布服务可以使用NodePort或Ingress
NodePort服务
  • NortPort概述

    • 使用基于端口映射(默认值:30000-32767)的方式对外发布服务,可以发布任意服务(四层)
  • 服务资源文件

    [root@master ~]# vim mysvc1.yaml

    kind: Service
    apiVersion: v1
    metadata:
    name: mysvc1
    spec:
    type: NodePort # 指定服务类型
    selector:
    app: web
    ports:
    - protocol: TCP
    port: 80
    nodePort: 30080 # 可选,不指定则使用随机端口
    targetPort: 80

    [root@master ~]# kubectl apply -f mysvc1.yaml
    service/mysvc1 created
    [root@master ~]# kubectl get services
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 7d21h
    mysvc1 NodePort 10.245.238.47 <none> 80:30080/TCP 6m29s

  • 访问nodePort服务

    root@master ~]# curl node-0001:30080
    Welcome to The Apache.
    [root@master ~]# curl node-0002:30080
    Welcome to The Apache.
    [root@master ~]# curl node-0003:30080
    Welcome to The Apache.
    [root@master ~]# curl node-0004:30080
    Welcome to The Apache.
    [root@master ~]# curl node-0005:30080
    Welcome to The Apache.

Ingress服务
  • Ingress概述

    • 使用Ingress控制器(一般由Nginx或HAProxy构成),用来发布http、https服务(七层)
  • Ingress控制器镜像地址:github.com/kubernetes/ingress-nginx

  • Ingress安装

    [root@master ingress]# docker load -i ingress.tar.xz # 导入Ingress镜像
    [root@master ingress]# docker images|while read i t _;do # 上传镜像

    [[ "{t}" == "TAG" ]] && continue [[ "{i}" =~ ^"harbor:443/".+ ]] && continue
    docker tag {i}:{t} harbor:443/plugins/{i##*/}:{t}
    docker push harbor:443/plugins/{i##*/}:{t}
    docker rmi {i}:{t} harbor:443/plugins/{i##*/}:{t}
    done

    [root@master ingress]# sed -ri 's,^(\simage: )(./)?(.+)@.*,\1harbor:443/plugins/\3,' deploy.yaml # 修改以下三行
    458: image: harbor:443/plugins/controller:v1.5.1
    565: image: harbor:443/plugins/kube-webhook-certgen:v20220916-gd32f8c343
    614: image: harbor:443/plugins/kube-webhook-certgen:v20220916-gd32f8c343

    [root@master ingress]# kubectl apply -f deploy.yaml
    [root@master ingress]# kubectl label nodes node-0001 ingress-ready="true" # 通过标签指定在那台机器上发布应用
    node/node-0001 labeled
    [root@master ~]# kubectl -n ingress-nginx get pods
    NAME READY STATUS RESTARTS AGE
    ingress-nginx-admission-create-bnk2n 0/1 Completed 0 2m12s
    ingress-nginx-admission-patch-jsbxh 0/1 Completed 0 2m12s
    ingress-nginx-controller-bbbb5f675-m4tck 1/1 Running 0 2m12s

配置Ingress规则
  • 保证ClusterIP 访问正常

    [root@master ~]# kubectl get pods,service
    NAME READY STATUS RESTARTS AGE
    pod/web1 1/1 Running 1 (31m ago) 3h52m

    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    service/kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 8d
    service/mysvc ClusterIP 10.245.1.80 <none> 80/TCP 16m
    service/mysvc1 NodePort 10.245.209.208 <none> 80:30080/TCP 3h1m
    [root@master ~]# curl 10.245.1.80
    Welcome to The Apache.

  • 配置规则

    • 资源对象模板:kubectl create ingress mying --class=nginx --rule=nsd.tedu.cn/*=mysvc:80 --dry-run=client -o yaml

      [root@master ~]# vim mying.yaml

      kind: Ingress
      apiVersion: networking.k8s.io/v1
      metadata:
      name: mying
      spec:
      ingressClassName: nginx # 使用的类名称
      rules: # ingress 规则定义

      • host: mying.cn # 域名定义,可以不写
        http: # 协议
        paths: # 访问的路径定义
        • path: / # 访问的url路径
          pathType: Prefix # 路径的类型[Exact Prefix]
          backend: # 后端服务
          service: # 服务声明
          name: mysvc # 服务名称
          port: # 端口号声明
          number: 80 # 访问服务的端口号
  • 发布服务

    [root@master ~]# kubectl apply -f mying.yaml
    ingress.networking.k8s.io/mying created
    [root@master ~]# kubectl get ingress
    NAME CLASS HOSTS ADDRESS PORTS AGE
    mying nginx mying.cn 80 12s
    [root@master ~]# kubectl get ingress
    NAME CLASS HOSTS ADDRESS PORTS AGE
    mying nginx mying.cn 192.168.1.51 80 14m
    [root@master ~]# curl -H "Host: mying.cn" http://192.168.1.51
    Welcome to The Apache.

WEB管理工具

Dashboard

Dashboard概述
  • Dashboard是什么?
    • Dashboard是给予网页的Kubernetes用户界面
    • Dashboard同时展示了Kubernetes集群中的资源状态信息和所有报错信息
    • 可以使用Dashboard将应用部署到集群中,也可以对容器应用排错,还能管理集群资源
    • 地址:github.com/kubernetes/dashboard
Dashboard安装
  • 导入镜像到私有仓库中

    [root@master dashboard]# docker load -i dashboard.tar.xz
    [root@master dashboard]# docker images|while read i t _;do

    [[ "{t}" == "TAG" ]] && continue [[ "{i}" =~ ^"harbor:443/".+ ]] && continue
    docker tag {i}:{t} harbor:443/plugins/{i##*/}:{t}
    docker push harbor:443/plugins/{i##*/}:{t}
    docker rmi {i}:{t} harbor:443/plugins/{i##*/}:{t}
    done
    [root@master dashboard]# sed -ri 's,^(\simage: )(./)?(.+),\1harbor:443/plugins/\3,' recommended.yaml
    193: image: harbor:443/plugins/dashboard:v2.7.0
    278: image: harbor:443/plugins/metrics-scraper:v1.0.8
    [root@master dashboard]# kubectl apply -f recommended.yaml
    [root@master dashboard]# kubectl -n kubernetes-dashboard get pods
    NAME READY STATUS RESTARTS AGE
    dashboard-metrics-scraper-66f6f56b59-trznx 1/1 Running 0 28s
    kubernetes-dashboard-65ff57f4cf-7dn87 1/1 Running 0 28s

发布服务
  • 导出服务资源文件

    [root@master dashboard]# sed -n '30,45p' recommended.yaml > dashboard-svc.yaml
    [root@master dashboard]# vim dashboard-svc.yaml

    kind: Service
    apiVersion: v1
    metadata:
    labels:
    k8s-app: kubernetes-dashboard
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard
    spec:
    type: NodePort # 添加类型,以NodePort形式发布
    ports:
    - port: 443
    nodePort: 30443 # 指定端口
    targetPort: 8443
    selector:
    k8s-app: kubernetes-dashboard

    [root@master dashboard]# kubectl apply -f dashboard-svc.yaml
    service/kubernetes-dashboard configured
    [root@master dashboard]# kubectl -n kubernetes-dashboard get services
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    dashboard-metrics-scraper ClusterIP 10.245.155.177 <none> 8000/TCP 8m14s
    kubernetes-dashboard NodePort 10.245.210.63 <none> 443:30443/TCP 8m14s

  • 添加监听器,前端端口设置为30443,并监听任意一个节点的30443端口

  • 使用弹性公网 IP绑定ELB

  • 发布成功后,通过浏览器访问https://公网IP:30443,出现如下界面即成功

认证与授权

ServiceAccount

用户概述
  • 用户认证
    • 所有k8s集群都有两类用户:由k8s管理的服务帐号和普通用户
    • 普通用户是以证书或密钥形式签发,主要用途是认证和鉴权,集群中并不包含用来代表普通用户帐号的对象,普通用户的信息无法调用和查询
    • 服务帐号是Kubernetes API所管理的用户。它们被绑定到特定的名称空间,与一组Secret凭据相关联,供Pod调用以获得相应的授权
创建ServiceAccount
  • 编写ServiceAccout资源对象文件

    [root@master dashboard]# vim admin-user.yaml

    kind: ServiceAccount
    apiVersion: v1
    metadata:
    name: kube-admin
    namespace: kubernetes-dashboard

    [root@master dashboard]# kubectl apply -f admin-user.yaml
    serviceaccount/kube-admin created
    [root@master dashboard]# kubectl -n kubernetes-dashboard get sa
    NAME SECRETS AGE
    default 0 30m
    kube-admin 0 11s
    kubernetes-dashboard 0 30m

  • 创建登陆用token

    [root@master dashboard]# kubectl -n kubernetes-dashboard create token kube-admin
    eyJhbGciOiJSUzI1NiIsImtpZCI6Im... ... # 这一串字符就是登陆用的token

权限管理

角色与授权
  • 如果想访问和管理k8s集群,就要对身份以及权限做验证,k8s支持的鉴权模块有Node、RBAC、ABAC、Webhook API

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

    [root@master dashboard]# kubectl cluster-info dump | grep authorization-mode
    "--authorization-mode=Node,RBAC",

RBAC授权
  • RBAC声明了四种k8s对象:
    • Role:用来在某一名称空间内创建授权角色,创建Role时,必须指定所属的名称空间的名字
    • Cluster:可以和Role相同完成授权,但属于集群范围,对所有名称空间有效
    • RoleBinding:是将角色中定义的权限赋予一个或者一组用户,可以使用Role或ClusterRole完成授权
    • ClusterRoleBinding:在集群范围执行授权,对所有名称空间有效,只能使用ClusterRole完成授权
  • 资源对象角色与作用域
资源对象 描述 作用域
ServiceAccount 服务账号,为 Pod 中运行的进程提供了一个身份 单一名称空间
Role 角色,包含一组代表相关权限的规则 单一名称空间
ClusterRole 角色,包含一组代表相关权限的规则 全集群
RoleBinding 将权限赋予用户,Role、ClusterRole 均可使用 单一名称空间
ClusterRoleBinding 将权限赋予用户,只可以使用 ClusterRole 全集群
  • 资源对象权限
create delete deletecollection get list patch update watch
创建 删除 删除集合 获取属性 获取列表 补丁 更新 监控
  • 创建自定义角色

    资源对象模板

    [root@master ~]# kubectl -n default create role myrole --resource=pods --verb=get,list --dry-run=client -o yaml
    [root@master ~]# kubectl -n default create rolebinding kube-admin-role --role=myrole --serviceaccount=kubernetes-dashboard:kube-admin --dry-run=client -o yaml

    [root@master ~]# vim myrole.yaml

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
    name: myrole # 角色名称
    namespace: default
    rules: # 规则

    • apiGroups: # 资源对象所属组信息
      • "" # 分组信息
        resources: # 要设置权限的资源对象
      • pods # 授权资源对象名称
        verbs: # 权限设置
      • get # 权限
      • list # 权限
  • 给kube-admin赋予普通用户权限

    ... ... # 接着上面的写

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
    name: kube-admin-role # 授权策略名称
    namespace: default
    roleRef: # 关联权限
    apiGroup: rbac.authorization.k8s.io # 角色对象组
    kind: Role # 角色对象
    name: myrole # 角色名称
    subjects: # 授权信息

    • kind: ServiceAccount # 帐号资源对象
      name: kube-admin # 帐号名称
      namespace: kubernetes-dashboard # 帐号所在的名称空间

    [root@master dashboard]# kubectl apply -f myrole.yaml
    role.rbac.authorization.k8s.io/myrole created
    rolebinding.rbac.authorization.k8s.io/kube-admin-role created

  • 给kube-admin赋予集群管理员权限

    ... ...

    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
    name: kube-admin-role
    namespace: default
    roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: ClusterRole
    name: cluster-admin
    subjects:

    • kind: ServiceAccount
      name: kube-admin
      namespace: kubernetes-dashboard

    [root@master dashboard]# kubectl apply -f myrole.yaml
    role.rbac.authorization.k8s.io/myrole created
    clusterrolebinding.rbac.authorization.k8s.io/kube-admin-role created

  • 授予管理员权限后,再次登陆Dashboard可以管理集群信息

相关推荐
蓁蓁啊1 小时前
GIT使用SSH 多账户配置
运维·git·ssh
程序猿小三4 小时前
Linux下基于关键词文件搜索
linux·运维·服务器
虚拟指尖5 小时前
Ubuntu编译安装COLMAP【实测编译成功】
linux·运维·ubuntu
椎4956 小时前
苍穹外卖前端nginx错误之一解决
运维·前端·nginx
刘某的Cloud6 小时前
parted磁盘管理
linux·运维·系统·parted
极验6 小时前
iPhone17实体卡槽消失?eSIM 普及下的安全挑战与应对
大数据·运维·安全
爱倒腾的老唐6 小时前
24、Linux 路由管理
linux·运维·网络
yannan201903136 小时前
Docker容器
运维·docker·容器
_清浅6 小时前
计算机网络【第六章-应用层】
运维·服务器·计算机网络
正在努力的小河6 小时前
Linux 自带的 LED 灯驱动实验
linux·运维·服务器