k8s服务发布基础

一、理论

service将多个pod整合为一个集群,service对外提供一个统一的IP地址。

kube proxy四种代理方式

UserSpace,已弃用,用户态转为内核态的过程消耗资源过大。

Iptables,kube proxy不转发,只维护iptables的规则。数据包通过iptables的规则转发,这种效率略低,当iptables的规则多的时候,读取规则相当于读取一张没有索引的表。

IpVs,kube proxy不转发,只维护iptables的规则,数据包通过iptables的规则转发,使用ipset来存储iptables的规则,可直接更新iptables规则。

KernelSpace,windows环境下的,这里不做介绍。

service的四种类型

Cluster IP(内部访问使用这个)

NodePort(让外部访问使用这个)

LoadBalancer(云环境的NodePort)

externalName(无头服务使用该类型)

无头服务是指服务没有入口地址(clusterIP),但是它有pod的地址,访问无头服务通过固定的服务名进行访问。

固定格式:无头服务名.命名空间.svc.cluster.local

二、实践

bash 复制代码
-- Cluster IP(外网访问不了) --
1、编写web服务资源清单
[root@k8s-master ~]# vim webapp-deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: nginx:1.7.9
        ports:
        - name: http
          containerPort: 80
          protocol: TCP

2、创建、查看pod
[root@k8s-master ~]# ku apply -f webapp-deployment.yaml 
deployment.apps/webapp created

[root@k8s-master ~]# ku get pod
NAME                      READY   STATUS    RESTARTS   AGE
webapp-84dc98755d-lp6st   1/1     Running   0          2m18s
webapp-84dc98755d-m6qfp   1/1     Running   0          2m18s


[root@k8s-master ~]# ku get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP              NODE         NOMINATED NODE   READINESS GATES
webapp-84dc98755d-lp6st   1/1     Running   0          2m30s   10.244.85.196   k8s-node01   <none>           <none>
webapp-84dc98755d-m6qfp   1/1     Running   0          2m30s   10.244.58.193   k8s-node02   <none>           <none>

3、访问

[root@k8s-master ~]# curl -I 10.244.85.196
HTTP/1.1 200 OK

[root@k8s-master ~]# curl -I 10.244.58.193
HTTP/1.1 200 OK

浏览器无法访问。

4、创建service,使用expose方式
[root@k8s-master ~]# ku expose deployment webapp
service/webapp exposed
[root@k8s-master ~]# ku get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   7d22h
webapp       ClusterIP   10.99.72.173   <none>        80/TCP    3s

[root@k8s-master ~]# curl -I 10.99.72.173
HTTP/1.1 200 OK

[root@k8s-master ~]# curl -I 10.99.72.173
HTTP/1.1 200 OK


浏览器无法访问。

5、使用资源清单方式创建service,编写service的资源清单
[root@k8s-master ~]# vim webapp-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  ports:
  - protocol: TCP
    port: 80		# service的端口
    targetPort: 80	# pod中容器的端口
  selector:
    app: webapp


6、创建service
[root@k8s-master ~]# ku create -f webapp-service.yaml 
Error from server (AlreadyExists): error when creating "webapp-service.yaml": services "webapp" already exists

[root@k8s-master ~]# ku get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   7d23h
webapp       ClusterIP   10.99.72.173   <none>        80/TCP    37m
[root@k8s-master ~]# ku delete svc webapp
service "webapp" deleted

[root@k8s-master ~]# ku create -f webapp-service.yaml 
service/webapp created

[root@k8s-master ~]# ku get svc 
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   7d23h
webapp       ClusterIP   10.106.101.137   <none>        80/TCP    50s

7、查看详细信息
[root@k8s-master ~]# ku describe svc webapp
Endpoints:         10.244.58.193:80,10.244.85.196:80

8、访问
[root@k8s-master ~]# curl -I 10.106.101.137
HTTP/1.1 200 OK

[root@k8s-master ~]# curl -I 10.106.101.137
HTTP/1.1 200 OK

-- NodePort(外部可访问) --
1、编写资源清单
[root@k8s-master ~]# vim webapp-svc-nodeport.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:	
  type: NodePort		# 指定类型为NodePort
  ports:
  - port: 80			# service的端口
    targetPort: 80		# pod中容器的端口
    nodePort: 30008		# 节点端口
  selector:
    app: webapp

2、创建
[root@k8s-master ~]# ku apply -f webapp-svc-nodeport.yaml 
service/webapp created
[root@k8s-master ~]# ku get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        7d23h
webapp       NodePort    10.104.14.137   <none>        80:30008/TCP   3s

3、访问
内部客户端
[root@k8s-master ~]# curl -I 10.104.14.137
HTTP/1.1 200 OK

外部客户端
浏览器访问	http://192.168.10.101:30008/
		http://192.168.10.102:30008/
		http://192.168.10.103:30008/


-- LoadBalancer (外部可访问) --
1、编写资源清单
[root@k8s-master ~]# vim webapp-svc-loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace: default
  labels:
    app: webapp
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: http		# 未指定端口,端口随机分配。
      protocol: TCP
      name: http
  selector:
    app: webapp

2、创建
[root@k8s-master ~]# ku apply -f webapp-svc-loadbalancer.yaml 
service/webapp created

[root@k8s-master ~]# ku get svc
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1        <none>        443/TCP        7d23h
webapp       LoadBalancer   10.108.130.185   <pending>     80:31654/TCP   5s
							31654就是随机分配的端口

3、访问
内部客户端
[root@k8s-master ~]# curl -I 10.108.130.185
HTTP/1.1 200 OK


外部客户端
http://192.168.10.101:31654/
http://192.168.10.102:31654/
http://192.168.10.103:31654/


更改service的类型及端口
[root@k8s-master ~]# ku edit svc webapp
  type: LoadBalancer
    nodePort: 31654

[root@k8s-master ~]# ku get svc
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1        <none>        443/TCP        7d23h
webapp       LoadBalancer   10.108.130.185   <pending>     80:31654/TCP   5s

[root@k8s-master ~]# ku edit svc webapp
service/webapp edited
    nodePort: 30000

[root@k8s-master ~]# ku  get svc
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1        <none>        443/TCP        7d23h
webapp       LoadBalancer   10.108.130.185   <pending>     80:30000/TCP   6m22s

[root@k8s-master ~]# ku edit svc webapp
  type: NodePort

[root@k8s-master ~]# ku edit svc webapp
service/webapp edited

[root@k8s-master ~]# ku get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        8d
webapp       NodePort    10.108.130.185   <none>        80:30000/TCP   8m20s

[root@k8s-master ~]# ku edit svc webapp
  type: ClusterIP


[root@k8s-master ~]# ku edit svc webapp
service/webapp edited

[root@k8s-master ~]# ku get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   8d
webapp       ClusterIP   10.108.130.185   <none>        80/TCP    9m6s




-- ExternalName(不同命名空间之间的pod通过域名互联) --
1、创建命名空间
[root@k8s-master ~]# ku create ns test01
namespace/test01 created
[root@k8s-master ~]# ku create ns test02
namespace/test02 created

2、创建pod
[root@k8s-master ~]# vim myapp01.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp01
  namespace: test01
spec:
  replicas: 1
  selector: #标签选择器
    matchLabels: #匹配的标签为
      app: myapp01
      release: canary
  template:
    metadata:
      labels:
        app: myapp01 #和上面的myapp要匹配
        release: canary
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http01
          containerPort: 80

[root@k8s-master ~]# ku create -f myapp01.yaml 
deployment.apps/myapp01 created

[root@k8s-master ~]# ku get pod -n test01
NAME                       READY   STATUS    RESTARTS   AGE
myapp01-696c886d6b-b5pz2   1/1     Running   0          75s


[root@k8s-master ~]# vim myapp02.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp02
  namespace: test02
spec:
  replicas: 1
  selector: #标签选择器
    matchLabels: #匹配的标签为
      app: myapp02
      release: canary
  template:
    metadata:
      labels:
        app: myapp02 #和上面的myapp要匹配
        release: canary
    spec:
      containers:
      - name: myapp02
        image: ikubernetes/myapp:v1
        ports:
        - name: http02
          containerPort: 80


[root@k8s-master ~]# ku get pod -n test02
NAME                       READY   STATUS    RESTARTS   AGE
myapp02-55ffcd5f64-22t52   1/1     Running   0          81s


3、创建service(本地的)
[root@k8s-master ~]# vim myapp-svc-headless01.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc01
  namespace: test01
spec:
  selector:
    app: myapp01 #挑选的pod还是myapp01。一个pod可以有多个service
    release: canary
  clusterIP: None #None表示是无头service
  ports:
  - port: 39320 #service ip中的端口
    targetPort: 80 #容器ip中的端口

[root@k8s-master ~]# ku create -f myapp-svc-headless01.yaml 
service/myapp-svc01 created

[root@k8s-master ~]# ku get svc -n test01
NAME          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE
myapp-svc01   ClusterIP   None         <none>        39320/TCP   7s

[root@k8s-master ~]# vim myapp-svc-headless02.yaml 
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc02
  namespace: test02
spec:
  selector:
    app: myapp02 #挑选的pod还是myapp。一个pod可以有多个service
    release: canary
  clusterIP: None #None表示是无头service
  ports:
  - port: 39320 #service ip中的端口
    targetPort: 80 #容器ip中的端口


[root@k8s-master ~]# ku create -f myapp-svc-headless02.yaml 
service/myapp-svc01 created

[root@k8s-master ~]# ku get svc -n test02
NAME              TYPE           CLUSTER-IP   EXTERNAL-IP                            PORT(S)     AGE
myapp-svc02       ClusterIP      None         <none>                                 39320/TCP   2m15s



4、创建service(让对方使用的)
[root@k8s-master ~]# vim myapp-svc-extername01.yaml 
kind: Service
apiVersion: v1
metadata:
  name: myapp-svcname02
  namespace: test01
spec:
  type: ExternalName
  externalName: myapp-svc02.test02.svc.cluster.local

myapp-svc02是对方服务的名称
test02是对方的表空间
svc.cluster.local 是后缀格式,不能更改。

[root@k8s-master ~]# ku create -f myapp-svc-extername01.yaml 
service/myapp-svcname02 created


[root@k8s-master ~]# vim myapp-svc-extername02.yaml 
kind: Service
apiVersion: v1
metadata:
  name: myapp-svcname01
  namespace: test02
spec:
  type: ExternalName
  externalName: myapp-svc01.test01.svc.cluster.local


[root@k8s-master ~]# ku create -f myapp-svc-extername02.yaml 
service/myapp-svcname01 created


5、访问测试
进入test01的pod
[root@k8s-master ~]# ku exec -it myapp01-696c886d6b-b5pz2 -n test01 -- /bin/sh
/ # nslookup myapp-svcname02
nslookup: can't resolve '(null)': Name does not resolve

Name:      myapp-svcname02
Address 1: 10.244.85.197 10-244-85-197.myapp-svc02.test02.svc.cluster.local
/ # ping myapp-svcname02
PING myapp-svcname02 (10.244.85.197): 56 data bytes
64 bytes from 10.244.85.197: seq=0 ttl=62 time=2.172 ms
64 bytes from 10.244.85.197: seq=1 ttl=62 time=1.467 ms
^C
--- myapp-svcname02 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 1.467/1.819/2.172 ms
/ # ping 10.244.85.197
PING 10.244.85.197 (10.244.85.197): 56 data bytes
64 bytes from 10.244.85.197: seq=0 ttl=62 time=0.949 ms
64 bytes from 10.244.85.197: seq=1 ttl=62 time=0.760 ms
^C
--- 10.244.85.197 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.760/0.854/0.949 ms


进入test02的pod
[root@k8s-master ~]# ku exec -it myapp02-55ffcd5f64-22t52 -n test02 -- /bin/sh
/ # nslookup myapp-svcname01
nslookup: can't resolve '(null)': Name does not resolve

Name:      myapp-svcname01
Address 1: 10.244.58.194 10-244-58-194.myapp-svc01.test01.svc.cluster.local
/ # ping myapp-svcname01
PING myapp-svcname01 (10.244.58.194): 56 data bytes
64 bytes from 10.244.58.194: seq=0 ttl=62 time=0.954 ms
64 bytes from 10.244.58.194: seq=1 ttl=62 time=1.092 ms
^C
--- myapp-svcname01 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.954/1.023/1.092 ms
/ # ping 10.244.58.194
PING 10.244.58.194 (10.244.58.194): 56 data bytes
64 bytes from 10.244.58.194: seq=0 ttl=62 time=0.969 ms
64 bytes from 10.244.58.194: seq=1 ttl=62 time=5.512 ms
64 bytes from 10.244.58.194: seq=2 ttl=62 time=5.082 ms
^C
--- 10.244.58.194 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.969/3.854/5.512 ms