Kubernetes

服务管理

Service

容器化带来的问题

自动调度:在Pod创建之前无法预知Pod所在的节点,以及Pod的IP地址

​ 一个已经存在的Pod在运行过程中,如果出现故障,Pod也会在新的节点上使用新的IP部署

​ 应用程序访问服务的时候,地址也不能经常变化

​ 多个相同的Pod如何访问他们上面的服务

Service就是解决这些问题的方法

服务的自动跟踪

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自动注册域名

[root@master ~]# vim mysvc.yaml
---
kind: Service
apiVersion: v1
metadata:
  name: mysvc
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

[root@master ~]# kubectl apply -f mysvc.yaml 
service/mysvc created
[root@master ~]# kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.245.0.1      <none>        443/TCP   2d18h
mysvc        ClusterIP   10.245.1.80     <none>        80/TCP    8s
[root@master ~]# yum install -y bind-utils
[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.1.80
后端Pod

[root@master ~]# vim myweb.yaml 
---
kind: Pod
apiVersion: v1
metadata:
  name: myweb
  labels:
    app: web
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  containers:
  - name: apache
    image: myos:httpd
    imagePullPolicy: IfNotPresent
    ports:
    - name: myhttp
      protocol: TCP
      containerPort: 80

[root@master ~]# sed 's,myweb,web1,' myweb.yaml |kubectl apply -f - 
pod/web1 created
[root@master ~]# curl http://10.245.1.80
Welcome to The Apache.

# service 靠标签寻找 Pod
[root@master ~]# kubectl label pod web1 app-
pod/web1 labeled
[root@master ~]# curl http://10.245.1.80
curl: (7) Failed connect to 10.245.1.80:80; Connection refused
[root@master ~]# kubectl label pod web1 app=web
pod/web1 labeled
[root@master ~]# curl http://10.245.1.80
Welcome to The Apache.
多个Pod负载均衡

[root@master ~]# sed 's,myweb,web2,' myweb.yaml |kubectl apply -f -
pod/web2 created
[root@master ~]# sed 's,myweb,web3,' myweb.yaml |kubectl apply -f -
pod/web3 created
[root@master ~]# curl -s http://10.245.1.80/info.php |grep php_host
php_host:       web1
[root@master ~]# curl -s http://10.245.1.80/info.php |grep php_host
php_host:       web2
[root@master ~]# curl -s http://10.245.1.80/info.php |grep php_host
php_host:       web3
为服务设置固定IP

[root@master ~]# vim mysvc.yaml 
---
kind: Service
apiVersion: v1
metadata:
  name: mysvc
spec:
  type: ClusterIP
  clusterIP: 10.245.1.80
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: myhttp

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

对外发布应用

服务类型

发布服务

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

服务类型

K8S的ServiceTypes允许指定不同的Service类型,以满足不同的需求,有效的类型有:ClusterIP、NodePort、LoadBalancer、ExternalName

ClusterIP:默认类型,只能在集群内部使用,可以实现Pod的自动跟踪和负载均衡,是最核心的服务类型

NodePort:将真实的节点的端口映射到ClusterIP服务上,来对外暴露服务的类型

LoadBalancer:使用云供应商的负载均衡服务器,通过外部路由将流量转发到NodePort和ClusterIP服务上

ExternalName:通过CNAME和对应值,可以将外部服务映射到ExternalName字段的内容

对外发布服务
  • 使用基于端口映射(默认值:30000-32767)的NodePort对外发布服务,可以发布任意服务(四层)
  • 使用Ingress控制器(一般由Nginx或HAProxy构成),用来发布http、https服务(七层)
  • LoadBalancer:使用外部云服务或ExternalIPs(需要特定的服务或付费支持)
NodePort
[root@master ~]# vim mysvc.yaml
---
kind: Service
apiVersion: v1
metadata:
  name: mysvc
spec:
  type: NodePort
  clusterIP: 10.245.1.80
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    nodePort: 30080
    targetPort: myhttp

[root@master ~]# kubectl apply -f mysvc.yaml 
service/mysvc configured
[root@master ~]# kubectl get service
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.245.0.1    <none>        443/TCP        5d18h
mysvc        NodePort    10.245.1.80   <none>        80:30080/TCP   17m

[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.
Ingress

在这里插入图片描述

安装控制器
第五阶段/kubernetes/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}" =~ ^"registry:5000/".+ ]] && continue
    docker tag ${i}:${t} registry:5000/plugins/${i##*/}:${t}
    docker push registry:5000/plugins/${i##*/}:${t}
    docker rmi ${i}:${t} registry:5000/plugins/${i##*/}:${t}
done
[root@master ingress]# sed 's,\(image: \).*/\(.*\),\1registry:5000/plugins/\2,' -i deploy.yaml
328:    image: registry:5000/plugins/controller:v1.1.0
609:    image: registry:5000/plugins/kube-webhook-certgen:v1.1.1
661:    image: registry:5000/plugins/kube-webhook-certgen:v1.1.1

[root@master ingress]# kubectl apply -f deploy.yaml
[root@master ingress]# kubectl -n ingress-nginx get pods
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create--1-lm52c     0/1     Completed   0          29s
ingress-nginx-admission-patch--1-sj2lz      0/1     Completed   0          29s
ingress-nginx-controller-5664857866-tql24   0/1     Running     0          29s
创建后端服务
[root@master ~]# vim mysvc.yaml 
---
kind: Service
apiVersion: v1
metadata:
  name: mysvc
spec:
  type: ClusterIP
  clusterIP: 10.245.1.80
  selector:
    app: web
  ports:
  - protocol: TCP
    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)   AGE
kubernetes   ClusterIP   10.245.0.1    <none>        443/TCP   5d19h
mysvc        ClusterIP   10.245.1.80   <none>        80/TCP    36m
[root@master ~]# kubectl get pods -l app=web --show-labels 
NAME   READY   STATUS    RESTARTS   AGE   LABELS
web1   1/1     Running   0          36m   app=web
web2   1/1     Running   0          34m   app=web
web3   1/1     Running   0          34m   app=web
[root@master ~]# curl http://10.245.1.80
Welcome to The Apache.
对外发布服务
[root@master ~]# kubectl get ingressclasses.networking.k8s.io 
NAME    CONTROLLER             PARAMETERS   AGE
nginx   k8s.io/ingress-nginx   <none>       5m7s
[root@master ~]# vim mying.yaml
---
kind: Ingress	#资源对象类型
apiVersion: networking.k8s.io/v1	#资源对象版本
metadata:	#元数据
  name: mying	#资源对象名称
spec:	#资源对象定义
  ingressClassName: nginx	#使用的类名称
  rules:	#Ingress规则定义
  - host: nsd.tedu.cn	#域名定义,没有可以不写
    http:	#协议
      paths:	#访问路径定义
      - backend:	#后端服务
          service:	#服务声明
            name: mysvc	#服务名称
            port:	#端口号声明
              number: 80	#访问服务的端口号
        path: /	#访问的URL路径
        pathType: Prefix	#路径的类型

[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   nsd.tedu.cn   192.168.1.51   80      70s
[root@master ~]# curl -H "Host: nsd.tedu.cn" http://192.168.1.51
Welcome to The Apache.

WED管理工具

Dashboard

Dashboard是什么?

Dashboard是基于页面的kubernetes用户界面

展现了kubernetes集群中的资源状态信息和所有报错信息

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

安装Dashboard
安装Dashboard
第五阶段/kubernetes/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}" =~ ^"registry:5000/".+ ]] && continue
    docker tag ${i}:${t} registry:5000/plugins/${i##*/}:${t}
    docker push registry:5000/plugins/${i##*/}:${t}
    docker rmi ${i}:${t} registry:5000/plugins/${i##*/}:${t}
done
[root@master dashboard]# sed 's,\(image: \).*/\(.*\),\1registry:5000/plugins/\2,' -i recommended.yaml
190:    image: registry:5000/plugins/dashboard:v2.4.0
275:    image: registry:5000/plugins/metrics-scraper:v1.0.7
[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-844d8585c9-w26m4   1/1     Running   0          10s
kubernetes-dashboard-6c58946f65-4bdtb        1/1     Running   0          10s
[root@master dashboard]# kubectl -n kubernetes-dashboard get service
NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
dashboard-metrics-scraper   ClusterIP   10.245.205.236   <none>        8000/TCP   13s
kubernetes-dashboard        ClusterIP   10.245.215.40    <none>        443/TCP    14s
发布Dashboard服务
[root@master dashboard]# sed -n '30,45p' recommended.yaml |tee 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       EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.245.205.236   <none>        8000/TCP        5m50s
kubernetes-dashboard        NodePort    10.245.215.40    <none>        443:30443/TCP   5m51s
通过浏览器访问 Dashboard 登录页面

登录Dashboard界面需要获取授权账号的token

认证与授权

ServiceAccount

用户认证

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

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

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

创建ServiceAccount
[root@master ~]# vim admin-user.yaml
---
kind: ServiceAccount
apiVersion: v1
metadata:
  name: dashboard-admin
  namespace: kubernetes-dashboard

[root@master ~]# kubectl apply -f admin-user.yaml 
serviceaccount/dashboard-admin created
[root@master ~]# kubectl -n kubernetes-dashboard get serviceaccounts 
NAME                   SECRETS   AGE
dashboard-admin        1         61s
default                1         79m
kubernetes-dashboard   1         79m
[root@master ~]# kubectl -n kubernetes-dashboard describe serviceaccounts dashboard-admin 
Name:                dashboard-admin
Namespace:           kubernetes-dashboard
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   dashboard-admin-token-6kf8l
Tokens:              dashboard-admin-token-6kf8l
Events:              <none>
[root@master ~]# kubectl -n kubernetes-dashboard describe secrets dashboard-admin-token-6kf8l 
Name:         dashboard-admin-token-6kf8l
Namespace:    kubernetes-dashboard
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: dashboard-admin
              kubernetes.io/service-account.uid: 0cfe4f55-8cc3-42fd-b88b-84f49604ae56

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1099 bytes
namespace:  20 bytes
token:      <Base64 编码的令牌数据>

角色与授权

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

[root@master ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml 
    - --authorization-mode=Node,RBAC
 
[root@master ~]# vim myrole.yaml 
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: myrole
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list

---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: dashboard-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: myrole
subjects:
- kind: ServiceAccount
  name: dashboard-admin
  namespace: kubernetes-dashboard

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

[root@master ~]# kubectl delete -f myrole.yaml 
role.rbac.authorization.k8s.io "myrole" deleted
rolebinding.rbac.authorization.k8s.io "dashboard-admin" deleted
使用ClusterRole授管理员权限

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

[root@master ~]# cat admin-user.yaml 
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-admin
  namespace: kubernetes-dashboard

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

[root@master ~]# kubectl apply -f admin-user.yaml 
serviceaccount/dashboard-admin unchanged
clusterrolebinding.rbac.authorization.k8s.io/dashboard-admin created
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐