service引入主要是解决Pod的动态变化,提供统一访问入口:
Pod与Service的关系:
ClusterIP:默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟IP
NodePort:在 ClusterIP 基础上为Service在每台机器上绑定一个端口,这样可以通过 NodeIP:NodePort来访问服务
LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到 NodeIP:NodePort
ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用,没有任何类型代理被创建,这只有Kubernetes 1.7或更高版本的kube-dns才支持
默认类型,自动分配一个仅Cluster内部能够访问的虚拟IP
编写xx.yaml文件
[root@master manifest]# cat network.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: notwork
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: web
release: v1
template:
metadata:
labels:
app: web
release: v1
spec:
containers:
- name: web
image: nginx
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: ClusterIP # 指定ClusterIP类型
selector:
app: web
ports:
- name: web
port: 80
targetPort: 80
[root@master manifest]# kubectl create -f network.yaml deployment.apps/notwork created
service/web created
#查看ip地址
[root@master ~]# kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/notwork-6cb9497c86-hz8jm 1/1 Running 0 6s
pod/notwork-6cb9497c86-sfjbk 1/1 Running 0 6s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 443/TCP 7d23h
service/web ClusterIP 10.107.190.89 80/TCP 6s
#访问
[root@master ~]# curl 10.107.190.89
Welcome to nginx!
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
在每个节点上启用一个端口来暴露服务,可以在集群外部访问。也会分配一个稳定内部集群Ip地址。
访问地址:<任意NodeIP>:
端口范围: 30000-32767
[root@master manifest]# cat network.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: notwork
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: web
release: v1
template:
metadata:
labels:
app: web
release: v1
spec:
containers:
- name: web
image: nginx
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: NodePort
namespace: default
selector:
app: web
ports:
- name: web
port: 80
targetPort: 80
nodePort: 30008
[root@master manifest]# kubectl create -f network.yaml
deployment.apps/notwork created
service/web created
[root@master ~]# kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/notwork-6cb9497c86-5ljbx 1/1 Running 0 40s
pod/notwork-6cb9497c86-6pvkq 1/1 Running 0 40s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 443/TCP 7d23h
service/web NodePort 10.109.242.11 80:30008/TCP 40s
[root@master ~]#
[root@master ~]# iptables -t nat -nvL | grep 'web'
0 0 KUBE-MARK-MASQ tcp -- * * !10.244.0.0/16 10.109.242.11 /* default/web:web cluster IP */ tcp dpt:80
0 0 KUBE-SVC-FZQ4YMPBOOYJKQMV tcp -- * * 0.0.0.0/0 10.109.242.11 /* default/web:web cluster IP */ tcp dpt:80
0 0 KUBE-MARK-MASQ tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/web:web */ tcp dpt:30008
0 0 KUBE-SVC-FZQ4YMPBOOYJKQMV tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/web:web */ tcp dpt:30008
0 0 KUBE-SEP-FS5AJG4JGP4NFZBK all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/web:web */ statistic mode random probability 0.50000000000
0 0 KUBE-SEP-DF4DTEZSYVN2RXLA all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/web:web */
0 0 KUBE-MARK-MASQ all -- * * 10.244.2.143 0.0.0.0/0 /* default/web:web */
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/web:web */ tcp to:10.244.2.143:80
0 0 KUBE-MARK-MASQ all -- * * 10.244.2.144 0.0.0.0/0 /* default/web:web */
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/web:web */ tcp to:10.244.2.144:80
[root@master ~]#
#宿主机ip+<自定义端口号>
[root@master ~]# curl 192.168.244.146:30008
Welcome to nginx!
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
ExternalName:经过返回 CNAME 和它的值,能够将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。没有任何类型代理被建立。
须要注意的是:Service 可以将一个接收 port 映射到任意的 targetPort。默认状况下,targetPort 将被设置为与 port 字段相同的值。
[root@master manifest]# cat network.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: notwork
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: web
release: v1
template:
metadata:
labels:
app: web
release: v1
spec:
containers:
- name: web
image: nginx
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
type: ExternalName
externalName: tom.k8s.example.com
[root@master manifest]# kubectl create -f network.yaml
deployment.apps/notwork created
service/web created
[root@master ~]# kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/notwork-6cb9497c86-76td2 1/1 Running 0 14s
pod/notwork-6cb9497c86-9cg49 1/1 Running 0 14s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 443/TCP 7d23h
service/web ExternalName tom.k8s.example.com 14s
[root@master ~]#
这种类型的Service经过返回CNAME和它的值,能够将服务映射到externalName字段的内容(例如:amu.k8s.example.com;能够实现跨namespace名称空间访问)。ExternalName Service是Service的特例,它没有selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群外部的服务,它经过返回该外部服务的别名这种方式提供服务。
若是外部的 IP 路由到集群中一个或多个 Node 上,Kubernetes Service 会被暴露给这些 externalIPs。经过外部 IP(做为目的 IP 地址)进入到集群,打到 Service 端口上的流量,将会被路由到 Service 的 Endpoint 上。
externalIPs 不会被 Kubernetes 管理,它属于集群管理员的职责范畴。
[root@master manifest]# cat network.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: notwork
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: web
release: v1
template:
metadata:
labels:
app: web
release: v1
spec:
containers:
- name: web
image: httpd
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
selector:
app: web
release: v1
ports:
- name: web
port: 80
targetPort: 80
externalIPs:
- 10.0.0.230
[root@master ~]# kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/notwork-7b5664dc66-w4jbq 1/1 Running 0 13m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 443/TCP 8d
service/web ClusterIP 10.101.72.35 10.0.0.230 80/TCP 13m
[root@master ~]# curl 10.101.72.35
It works!
service代理模式
kubeadm方式修改ipvs模式
kubectl edit configmap kube-proxy -n kube-system
.....
mode:"ipvs"
.....
kubectl delete pod kube-proxy-btz4p -n kube-system
注意:
vim kube-proxy-config.yaml
mode: ipvs
ipvs:
scheduler: "rr"
systemctl restart kube-proxy
流程:客户端 -> NodePort/ClusterIP(iptables/Ipvs负载均衡规则) -> 分布在各节点Pod
查看负载均衡规则:
iptables-save | grep
ipvsadm -L -n
创建一个deployment 副本数3.然后滚动更新镜像版本,并记录这个更新记录,最后在回滚到上一个版本
[root@master manifest]# cat test3.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
revisionHistoryLimit: 5
strategy:
rollingUpdate:
maxSurge: 40
maxUnavailable: 50%
type: RollingUpdate
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: httpd
imagePullPolicy: IfNotPresent
[root@master manifest]# kubectl create -f test3.yaml
deployment.apps/web created
#查看历史记录
[root@master manifest]# kubectl rollout history deployment/web
deployment.apps/web
REVISION CHANGE-CAUSE
1
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-8487457bf4-7zfmx 1/1 Running 0 41s
web-8487457bf4-9fx2g 1/1 Running 0 41s
web-8487457bf4-zl5kj 1/1 Running 0 41s
#修改镜像版本
......
spec:
containers:
- name: web
image: httpd #随便改镜像
imagePullPolicy: IfNotPresent
[root@master manifest]# kubectl apply -f test3.yaml
deployment.apps/web unchanged
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-66dd47b7cd-4v6mr 0/1 Terminating 0 10m
web-66dd47b7cd-qnngq 0/1 Terminating 0 10m
web-66dd47b7cd-wwtpz 0/1 Terminating 0 10m
web-7bbbccf79c-fhk6g 1/1 Running 0 10s
web-7bbbccf79c-mvq9j 1/1 Running 0 10s
web-7bbbccf79c-n7z42 1/1 Running 0 10s
[root@master ~]# kubectl rollout history deployment/web
deployment.apps/web
REVISION CHANGE-CAUSE
1
2
3
#回滚
[root@master ~]# kubectl rollout undo deployment/web --to-revision=2
deployment.apps/web rolled back
[root@master ~]# kubectl rollout history deployment/web
deployment.apps/web
REVISION CHANGE-CAUSE
1
3
4
给一个应用扩容副本数为5
[root@master manifest]# cat test3.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 5 # 改为5
revisionHistoryLimit: 5 #历史记录
strategy:
rollingUpdate:
maxSurge: 40
maxUnavailable: 50%
type: RollingUpdate
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: sktystwd/apache:v0.1
imagePullPolicy: IfNotPresent
[root@master manifest]# kubectl apply -f test3.yaml
deployment.apps/web configured
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-7bbbccf79c-4jd27 1/1 Running 0 39s
web-7bbbccf79c-8gncv 1/1 Running 0 39s
web-7bbbccf79c-jqbzj 1/1 Running 0 39s
web-7bbbccf79c-mj6x7 1/1 Running 0 39s
web-7bbbccf79c-rhj56 1/1 Running 0 39s
创建一个pod,其中运行着nginx、redis、memcached 3个容器
[root@master manifest]# cat test4.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: test
labels:
app: tests
spec:
containers:
- image: nginx
name: nginx
- image: redis
name: redis
- image: memcached
name: memcached
[root@master manifest]# kubectl create -f test4.yaml
pod/test created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test 3/3 Running 0 95s
给一个pod创建service,并可以通过ClusterIP/NodePort访问
[root@master manifest]# cat test5.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: httpd
release: v1
template:
metadata:
labels:
app: httpd
release: v1
spec:
containers:
- name: httpd
image: httpd
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
type: NodePort
selector:
app: httpd
release: v1
ports:
- name: httpd
port: 80
targetPort: 80
nodePort: 31888
[root@master ~]# kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/httpd-66cf97c986-94bff 1/1 Running 0 10s
pod/test-66dd47b7cd-mrtl7 1/1 Running 0 2m50s
pod/web-6cb9497c86-qkkbb 1/1 Running 0 5m32s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 443/TCP 8d
service/web NodePort 10.110.155.23 80:31888/TCP 10s
[root@master ~]# curl 10.110.155.23
It works!
[root@master ~]# curl 192.168.244.146:31888
It works!
创建deployment和service,使用busybox容器nslookup解析service
[root@master manifest]# kubectl run max --image busybox -- sleep 1200
pod/max created
[root@master manifest]# kubectl exec -it max -- /bin/sh
/ # nslookup kubernetes
Server: 10.96.0.10
Address: 10.96.0.10:53
** server can't find kubernetes.default.svc.cluster.local: NXDOMAIN
*** Can't find kubernetes.svc.cluster.local: No answer
*** Can't find kubernetes.cluster.local: No answer
*** Can't find kubernetes.example.com: No answer
*** Can't find kubernetes.default.svc.cluster.local: No answer
*** Can't find kubernetes.svc.cluster.local: No answer
*** Can't find kubernetes.cluster.local: No answer
*** Can't find kubernetes.example.com: No answer
/ #