云原生之k8s服务管理

文章目录

服务管理

Service

服务原理

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

[root@master ~] kubectl create service clusterip websvc --tcp=80:80 --dry-run=client -o yaml # 资源清单文件
[root@master ~] vim websvc.yaml
---
kind: Service
apiVersion: v1
metadata:
  name: websvc
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

[root@master ~] kubectl apply -f websvc.yaml 
service/websvc created
[root@master ~] kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)
kubernetes   ClusterIP   10.245.0.1      <none>        443/TCP
websvc       ClusterIP   10.245.5.18     <none>        80/TCP

创建后端应用
[root@master ~] vim web1.yaml 
---
kind: Pod
apiVersion: v1
metadata:
  name: web1
  labels:
    app: web   # 服务靠标签寻找后端
spec:
  containers:
  - name: apache
    image: myos:httpd

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

ClusterIP服务

  1. ClusterIP类型
  • 默认的ServiceType,通过集群的内部IP暴露服务,选择该值时服务只能够在集群内部访问
  1. 域名自动注册
bash 复制代码
解析域名
[root@master ~] dnf install -y bind-utils# 安装工具软件包
# 查看 DNS 服务地址
[root@master ~] kubectl -n kube-system get service kube-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 websvc.default.svc.cluster.local 10.245.0.10
Using domain server:
Name: 10.245.0.10
Address: 10.245.0.10#53
Aliases: 

websvc.default.svc.cluster.local has address 10.245.5.18


服务自动感知
[root@master ~] kubectl delete pods --all
pod "web1" deleted
[root@master ~] kubectl create -f web1.yml 
pod/web11 created
[root@master ~] curl 10.245.167.50  #删除Pod后访问CLUSTER-IP仍能收到响应
Welcome to The Apache.

负载均衡
[root@master ~] sed 's,web1,web2,' web1.yaml |kubectl apply -f -
pod/web2 created
[root@master ~] sed 's,web1,web3,' web1.yaml |kubectl apply -f -
pod/web3 created
[root@master ~] curl -s http://10.245.5.18/info.php |grep php_host
php_host:       web1
[root@master ~] curl -s http://10.245.5.18/info.php |grep php_host
php_host:       web2
[root@master ~] curl -s http://10.245.5.18/info.php |grep php_host
php_host:       web3

固定 IP 服务
[root@master ~] vim websvc.yaml 
---
kind: Service
apiVersion: v1
metadata:
  name: websvc
spec:
  type: ClusterIP
  clusterIP: 10.245.1.80    # 可以设置 ClusterIP
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

[root@master ~] kubectl replace --force -f websvc.yaml 
service "websvc" deleted
service/websvc replaced
[root@master ~] kubectl get service
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)
kubernetes   ClusterIP   10.245.0.1    <none>        443/TCP
websvc       ClusterIP   10.245.1.80   <none>        80/TCP

端口别名
[root@master ~] vim websvc.yaml 
---
kind: Service
apiVersion: v1
metadata:
  name: websvc
spec:
  type: ClusterIP
  clusterIP: 10.245.1.80
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: myhttp    # 使用别名查找后端服务端口

[root@master ~] kubectl replace --force -f websvc.yaml 
service "websvc" deleted
service/websvc replaced

[root@master ~] kubectl delete pod --all
pod "web1" deleted
pod "web2" deleted
pod "web3" deleted

[root@master ~] vim web1.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 apply -f web1.yaml
pod/web1 created
[root@master ~] curl http://10.245.1.80
Welcome to The Apache.
  1. 服务的工作原理
  • kube-proxy是在所有节点上运行的代理。可以实现简单的数据转发,可以设置更新IPTables/LVS规则,在服务创建时,还提供服务地址DNS自动注册与服务发现功能

对外发布应用

服务类型

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

NodePort服务

  1. NodePort与Ingress
  • NodePort:使用基本端口映射(默认值:30000-3267)的方式对外发布服务,可以发布任意服务(四层)
  • 使用Ingress控制器(一般由Nginx或HAProxy构成),用来发布http、https服务(七层)
  1. 服务资源清单文件
bash 复制代码
[root@master ~] vim nodeport.yml
---
kind: Service
apiVersion: v1
metadata:
  name: mysvc
spec: 
  type: NodePort   #指定服务类型
  selector:
    app: web
  ports:
  - protocol: TCP
    nodePort: 31234 #可选配置,不指定端口使用随机端口
    port: 80
    targetPort: 80
[root@master ~] kubectl apply -f mysvc.yaml 
service/mysvc configured
[root@master ~] kubectl get service
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)
kubernetes   ClusterIP   10.245.0.1    <none>        443/TCP
websvc       ClusterIP   10.245.1.80   <none>        80/TCP
mysvc        NodePort    10.245.3.88   <none>        80:30080/TCP

Nodeport会在所有节点映射端口,可以访问任意节点
[root@master ~] curl http://node-0001:30080
Welcome to The Apache.
[root@master ~] curl http://node-0002:30080
Welcome to The Apache.
[root@master ~] curl http://node-0003:30080
Welcome to The Apache.
[root@master ~] curl http://node-0004:30080
Welcome to The Apache.
[root@master ~] curl http://node-0005:30080
Welcome to The Apache.

Ingress安装

  1. Ingress是什么?
  • Ingress公开从集群外部到集群内服务的HTTP和HTTPS路由。流量路由由Ingress资源上定义的规则控制
  • Ingress控制器通常由负载均衡器来实现(Nginx、HAProxy)
  1. 安装Ingress控制器
  • Ingress服务由(规则+控制器)组成
  • 规则负责制定策略,控制器负责执行
  • 如果没有控制器,单独设置规则无效
bash 复制代码
[root@master ~] cd plugins/ingress
[root@master ingress] docker load -i ingress.tar.xz
[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,^(\s*image: )(.*/)?(.+),\1harbor:443/plugins/\3,' deploy.yaml
443:    image: registry.k8s.io/ingress-nginx/controller:v1.9.6
546:    image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20231226-1a7112e06
599:    image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20231226-1a7112e06

[root@master ingress] kubectl apply -f deploy.yaml
[root@master ingress] kubectl -n ingress-nginx get pods
NAME                                        READY   STATUS      RESTARTS
ingress-nginx-admission-create--1-lm52c     0/1     Completed   0
ingress-nginx-admission-patch--1-sj2lz      0/1     Completed   0
ingress-nginx-controller-5664857866-tql24   1/1     Running     0

配置Ingress规则

bash 复制代码
验证后端服务
[root@master ~] kubectl get pods,services 
NAME       READY   STATUS    RESTARTS   AGE
pod/web1   1/1     Running   0          35m

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)
service/kubernetes   ClusterIP   10.245.0.1    <none>        443/TCP
service/websvc       ClusterIP   10.245.1.80   <none>        80/TCP
service/mysvc        NodePort    10.245.3.88   <none>        80:30080/TCP

[root@master ~] curl http://10.245.1.80
Welcome to The Apache.

对外发布服务
# 查询 ingress 控制器类名称
[root@master ~] kubectl get ingressclasses.networking.k8s.io 
NAME    CONTROLLER             PARAMETERS   AGE
nginx   k8s.io/ingress-nginx   <none>       5m7s

# 资源清单文件
[root@master ~] 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:
  - host: nsd.tedu.cn
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: websvc
            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
mying   nginx   nsd.tedu.cn   192.168.1.51   80
[root@master ~] curl -H "Host: nsd.tedu.cn" http://192.168.1.51
Welcome to The Apache.

Dashboard

概述

  1. Dashboard 是什么?
  • Dashboard 是基于网页的 Kubernetes 用户界面。
  • Dashboard 同时展示了 Kubernetes 集群中的资源状态信息和所有报错信息。
  • 你可以使用 Dashboard 将应用部署到集群中,也可以对容器应用排错,还能管理集群资源。例如,你可以对应用弹性伸缩、发起滚动升级、重启等等。
  1. 安装
bash 复制代码
[root@master ~] cd plugins/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,^(\s*image: )(.*/)?(.+),\1harbor:443/plugins/\3,' recommended.yaml
193:    image: kubernetesui/dashboard:v2.7.0
278:    image: kubernetesui/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
dashboard-metrics-scraper-66f6f56b59-b42ng   1/1     Running   0
kubernetes-dashboard-65ff57f4cf-lwtsk        1/1     Running   0
  1. 发布服务
bash 复制代码
# 查看服务状态
[root@master dashboard] kubectl -n kubernetes-dashboard get service
NAME                        TYPE        CLUSTER-IP       PORT(S)
dashboard-metrics-scraper   ClusterIP   10.245.205.236   8000/TCP
kubernetes-dashboard        ClusterIP   10.245.215.40    443/TCP
# 获取服务资源对象文件
[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
  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 service
NAME                        TYPE        CLUSTER-IP       PORT(S)
dashboard-metrics-scraper   ClusterIP   10.245.205.236   8000/TCP
kubernetes-dashboard        NodePort    10.245.215.40    443:30443/TCP

认证和授权

ServiceAccount

用户概述

用户认证

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

创建ServiceAccount

  1. 创建服务账号
bash 复制代码
# 资源对象模板
[root@master ~] kubectl -n kubernetes-dashboard create serviceaccount kube-admin --dry-run=client -o yaml
[root@master ~] vim admin-user.yaml
---
kind: ServiceAccount
apiVersion: v1
metadata:
  name: kube-admin
  namespace: kubernetes-dashboard

[root@master ~] kubectl apply -f admin-user.yaml 
serviceaccount/kube-admin created
[root@master ~] kubectl -n kubernetes-dashboard get serviceaccounts 
NAME                   SECRETS   AGE
default                0         16m
kube-admin             0         11s
kubernetes-dashboard   0         16m
  1. 获取用户 token
bash 复制代码
[root@master ~] kubectl -n kubernetes-dashboard create token kube-admin  # 生成Base64 编码的令牌数据

权限管理

资源对象 描述 作用域
ServiceAccount 服务账号,为 Pod 中运行的进程提供了一个身份 单一名称空间
Role 角色,包含一组代表相关权限的规则 单一名称空间
ClusterRole 角色,包含一组代表相关权限的规则 全集群
RoleBinding 将权限赋予用户,Role、ClusterRole 均可使用 单一名称空间
ClusterRoleBinding 将权限赋予用户,只可以使用 ClusterRole 全集群

资源对象权限

create delete deletecollection get list patch update watch
创建 删除 删除集合 获取属性 获取列表 补丁 更新 监控

角色与授权

  1. 如果想访问和管理kubernetes集群,就要对身份以及权限做验证,kubernetes支持的鉴权模块有Node、RBAC、ABAC、Webhook API
  • Node:一种特殊用途的鉴权模式,专门对kubelet发出的请求进行鉴权
  • RBAC:是一种基于组织中用户的角色来控制资源使用的方法
  • ABAC:基于属性的访问控制,是一种通过将用户属性与权限组合在一起向用户授权的方法
  • Webhook:是一个HTTP回调
  1. RBAC授权(RBAC声明了四种Kubernetes对象)
  • Role:用来在某一个名称空间内创建授权角色,创建Role时,必须指定所属的名字空间的名字
  • ClusterRole:可以和Role相同完成授权。但属于集群范围,对所有名称空间有效
  • RoleBinding:是将角色中定义的权限赋予一个或者一组用户,可以使用Role或ClusterRole完成授权
  • ClusterRoleBinding在集群范围执行授权,对所有名称空间有效,只能使用ClusterRole完成授权
bash 复制代码
普通角色
[root@master ~] kubectl cluster-info dump |grep authorization-mode
                            "--authorization-mode=Node,RBAC",

# 资源对象模板
[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

---
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 ~] kubectl apply -f myrole.yaml 
role.rbac.authorization.k8s.io/myrole created
rolebinding.rbac.authorization.k8s.io/kube-admin-role created

[root@master ~] kubectl delete -f myrole.yaml 
role.rbac.authorization.k8s.io "myrole" deleted
rolebinding.rbac.authorization.k8s.io "kube-admin-role" deleted

集群管理员
[root@master ~] kubectl get clusterrole
NAME                              CREATED AT
admin                             2022-06-24T08:11:17Z
cluster-admin                     2022-06-24T08:11:17Z
... ...

# 资源对象模板
[root@master ~] kubectl create clusterrolebinding kube-admin-role --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:kube-admin --dry-run=client -o yaml
[root@master ~] vim admin-user.yaml 
---
kind: ServiceAccount
apiVersion: v1
metadata:
  name: kube-admin
  namespace: kubernetes-dashboard

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

[root@master ~] kubectl apply -f admin-user.yaml 
serviceaccount/kube-admin unchanged
clusterrolebinding.rbac.authorization.k8s.io/kube-admin-role created
相关推荐
颜淡慕潇10 分钟前
【K8S系列】kubectl describe pod显示ImagePullBackOff,如何进一步排查?
后端·云原生·容器·kubernetes
Linux运维日记30 分钟前
k8s1.31版本最新版本集群使用容器镜像仓库Harbor
linux·docker·云原生·容器·kubernetes
一名路过的小码农2 小时前
ceph 18.2.4二次开发,docker镜像制作
ceph·docker·容器
AI_小站2 小时前
RAG 示例:使用 langchain、Redis、llama.cpp 构建一个 kubernetes 知识库问答
人工智能·程序人生·langchain·kubernetes·llama·知识库·rag
xiangshangdemayi5 小时前
Windows环境GeoServer打包Docker极速入门
windows·docker·容器·geoserver·打包·数据挂载
程序员JerrySUN5 小时前
熟悉的 Docker,陌生的 Podman
linux·docker·容器·系统架构·podman
gobeyye6 小时前
Docker 用法详解
运维·docker·容器
怡雪~7 小时前
centos7.9搭建k8s集群
云原生·容器·kubernetes
雪碧聊技术8 小时前
Docker3:docker基础1
运维·docker·容器·docker常见命令