# 官方提供@yunTaoScripts SERVICE 服务🔥🔥

loading

# POD的发布

  • 端口映射
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: port-container
  name: port-container
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: port-container
    ports:
    - containerPort: 80
      hostPort: 89
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
  • 使用主机网络
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: hostnetwork-container
  name: hostnetwork-container
spec:
  hostNetwork: true
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: hostnetwork-container
    ports:
    - containerPort: 80  
      hostPort: 80
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

WARNING

  • hostNetwork模式下,以下两个端口必须设为一致的,或者不写,否则报错。
ports:
- containerPort: 80  
  hostPort: 80

# 服务的发现

  • 服务的发现就是指如何访问到其他应用

# 直接通过clusterIP 实现服务访问

# 创建POD

kubectl run ng-pod --image=nginx --image-pull-policy=IfNotPresent

# 命令创建服务

kubectl expose pod ng-pod --port=81 --target-port=80 --name=s2

# yaml创建服务

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2022-05-26T05:10:04Z"
  labels:
    run: ng-pod
  name: s2
  namespace: 10-service
  resourceVersion: "1770504"
  uid: 73a3d6d3-f3a0-4c03-892c-5f5e8740a307
spec:
  clusterIP: 10.105.141.192
  clusterIPs:
  - 10.105.141.192
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 81
    protocol: TCP
    targetPort: 80
  selector:
    run: ng-pod
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

# kubectl get svc

NAME     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
marapp   ClusterIP   10.103.200.123   <none>        3306/TCP   3h20m
ng-pod   ClusterIP   10.99.175.244    <none>        80/TCP     34m
curl 10.99.175.244

关于port和targetPort

  • 如果创建命令时 不写targetPort,默认和port保持一致,如果此时port 并不是容器暴露端口,那就会导致服务访问失败。

# 通过环境变量实现服务发现

  • kubectl run busybox --rm -it --image=busybox --image-pull-policy=IfNotPresent sh
  • env | grep -i service | grep -vi kube
S2_SERVICE_HOST=10.105.141.192
S2_SERVICE_PORT=81
NG_POD_SERVICE_HOST=10.109.93.56
NG_POD_SERVICE_PORT=81
  • 配置MYSQL应用
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: marapp
  name: marapp
spec:
  containers:
  - image: mariadb
    name: marapp
    imagePullPolicy: IfNotPresent
    env:
    - name: MARIADB_ROOT_PASSWORD
      value: "123"
    - name: MYSQL_DATABASE         #需要创建数据库,名称无所谓
      value: wordpress
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

  • 配置MYSQL服务 kubectl expose pod marapp --port=3306
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2022-05-26T06:05:26Z"
  labels:
    run: marapp
  name: marapp
  namespace: 10-service
  resourceVersion: "1776257"
  uid: c952d867-aa0c-4842-9663-43e92923c063
spec:
  clusterIP: 10.103.200.123
  clusterIPs:
  - 10.103.200.123
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 3306
    protocol: TCP
    targetPort: 3306
  selector:
    run: marapp
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
  • 配置wordpress 应用
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: wordpress
  name: wordpress
spec:
  containers:
  - image: wordpress
    name: wordpress
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80 
      hostPort: 8090   
    env:
    - name: WORDPRESS_DB_USER
      value: root
    - name: WORDPRESS_DB_PASSWORD
      value: '123'
    - name: WORDPRESS_DB_NAME        ####指定之前创建的数据库。
      value: wordpress
    - name: WORDPRESS_DB_HOST
      value: $(MARAPP_SERVICE_HOST)  #####此处使用了环境变量,也可以直接使用ClusterIP
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

以下需要注意⚠️

  1. 只能获取相同namespace里的变量。
  2. 变量的获取有先后顺序,引用的SERVICE变量必须要先创建服务,之后其他后创建的pod会自动识别服务变量。
  3. 变量的命名格式:
    • 大写servicename_SERVICE_HOST
    • 大写servicename_SERVICE_PORT

# 通过DNS的方式实现服务发现

  • 在kube-system里有coredns服务,可以自动发现所有命名空间里的服务的clusterIP,所以,在同一个命名空间里,一个服务访问另外一个服务的时候,可以直接通过服务名来访问。
  • 只要创建了一个服务(不管在哪个ns里创建的),都会自动向kube-system里的 coredns注册。
  • 如果是不同的命名空间,可以通过 服务名.命名空间名服务名.命名空间.svc.cluster.local 来访问。

# 在其他命名空间

kubectl exec -it yuntao-test-ctsm1 bash -n 03-pod
root@yuntao-test-ctsm1:/# curl ng-pod.10-service     #######<- 需要加命名空间才能访问
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

# 在当前命名空间

kubectl run cent --rm -it --image=centos:centos7.9.2009 --image-pull-policy=IfNotPresent sh
sh-4.2# curl ng-pod                                    #######<- 无需加命名空间就能访问
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

# 服务的发布

  • 所谓发布指的是,如何让集群之外的主机能访问服务。

# nodePort

  • 命令行创建 kubectl expose pod ng-pod --port=81 --target-port=80 --type=NodePort --name=node-service
  • 通过yaml创建nodePort
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2022-05-27T00:56:46Z"
  labels:
    run: ng-pod
  name: node-service
  namespace: 10-service
  resourceVersion: "1890103"
  uid: 6ad8ed01-9b15-49be-958c-8c118eb6174e
spec:
  clusterIP: 10.103.157.217
  clusterIPs:
  - 10.103.157.217
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 30284
    port: 81
    protocol: TCP
    targetPort: 80
  selector:
    run: ng-pod
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

TIP

  • port是针对 service的。
  • targetPort针对pod的,如果不指定默认等于port。
  • nodePort是针对节点的。

# loadBalancer

# 命令行创建 loadbalancer

  • kubectl expose pod ng-pod --port=80 --type=LoadBalancer --name=load-service

loadbalancer

原生k8s不支持loadbalancer服务,需要第三方支持,创建完后处于pending状态。

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
load-service LoadBalancer 10.100.193.122 <pending> 80:31501/TCP 22m

# 安装loadbalancer服务

  • kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml

  • kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml

下载配置文件

  • 提前下文件,虚拟机可能下不下来。

# 配置地址池

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 10.211.55.240-10.211.55.250

kubectl get svc

地址池需要和节点同网段。另外访问的端口和clusterip相同 ,而后面的31501 是指pod所在节点的端口。

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
load-service LoadBalancer 10.100.193.122 10.211.55.240 80:31501/TCP 41m

# ingress

  • ingress本身通过nginx实现,它可以实现七层的域名到service 的转发。

# 安装ingress

  • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml

下载配置文件

  • 提前更改镜像配置文件,虚拟机可能下不下来。
  • ingressClassName: nginx,这个需要通过kubectl get ingressclass 获取。
  • 注意nginx ingress的 service 发布方式,域名需要绑定到对应节点ip。
  • 如果采用loadbalancer,注意绑定IP是分配的ip,即使无法ping通,但是也可以访问。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx    
  rules:
  - host: www.yuntao1.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: s1
            port:
              number: 80

  - host: www.yuntao2.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: s2
            port:
              number: 80
      - path: /cka
        pathType: Prefix
        backend:
          service:
            name: s3
            port:
              number: 80

# externalIp

kubectl expose deployment dp-nginx --external-ip=10.211.55.111 --port=80
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2022-05-28T04:08:33Z"
  labels:
    app: dp-nginx
  name: dp-nginx
  namespace: 10-service
  resourceVersion: "2020947"
  uid: beca0220-29cd-4d8e-b6c1-9a402e29b205
spec:
  clusterIP: 10.103.116.161
  clusterIPs:
  - 10.103.116.161
  externalIPs:
  - 10.211.55.111
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: dp-nginx
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

kubectl get svc

  • externalIp需要指定集群节点
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dp-nginx ClusterIP 10.103.116.161 10.211.55.111 80/TCP 9m