您现在的位置是:首页 >技术教程 >K8S---Service网站首页技术教程
K8S---Service
服务原理
容器化的问题:
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
[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