服务原理

容器化的问题:

1.自动调度 无法预知pod所在节点,pod的IP地址

2.有故障时,换新节点新ip进行部署

service就是解决这些问题

自动跟踪  clusterip不变 都能找到对应pod  主要靠后端pod的标签

负载均衡 通过iptables/LVS规则将访问的请求最终映射到Pod容器内部,自动在多个容器之间实现负载均衡

自动发现 服务创建时会自动在内部DNS上注册域名 <服务名称>.<名称空间>.svc.cluster.local服务

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

ClusterIP服务

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

 

自动注册域名

[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

有错时检查IP 标签 端口号

别名 找端口不一致targetPort

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

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

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

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

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

NodePort

使用基于端口映射(默认值:30000-32767)的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(规则+控制器)

一般由nginx或HAproxy构成,用来发布http、https服务(七层)

规则负责制定策略          控制器负责执行

如果没有控制器,单独设置规则无效

用户----Ingress-----ClusterIP------后端Pod

 Prefix宽松模式        Exact严格模式

后端服务

[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:
  - host: nsd.tedu.cn
    http:
      paths:
      - backend:
          service:
            name: mysvc
            port:
              number: 80
        path: /
        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.

web管理插件(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 -ri 's,^(\s+image: ).+/(.+),\1registry:5000/plugins/\2,' 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

发布Dashboard服务

基于网页的kubernetes用户界面,各种操作

[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 -ri 's,^(\s+image: ).+/(.+),\1registry:5000/plugins/\2,' 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

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

服务账号与权限

serviceaccount

  • Node
  • RBAC 对组织中的角色授权,给哪个用户绑定上,哪个用户就牛逼
  • ABAC 对用户的授权,我在哪,哪就牛逼

apiVersion等价于apiGroups/version

通过 kubectl api-resources 看到

[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 编码的令牌数据>

角色与鉴权

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

[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社区为您提供最前沿的新闻资讯和知识内容

更多推荐