【容器应用系列教程】Kubernetes服务管理Service
一、关于Service
- 业务的访问入口
- 负载均衡功能
- 服务名称
- 命名格式:
服务名称.命名空间.svc.cluster.local
- 例子:
wordpress.default.svc.cluster.local
- 命名格式:
- 依赖于
coreDNS
组件- 服务发现
- 创建服务时,会自动在
coreDNS
中注册名称、IP的解析关系 - 创建
pod
时,pod
会自动使用DNS
解析对应的服务名称
- 创建服务时,会自动在
- 服务发现
Service
服务、POD
依赖于标签选择器建立对应关系
查看刚创建Kubernetes
自带的2
个默认的Service
svc
为service
的简写
[root@k8s-master opt]# kubectl get svc -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.16.0.1 <none> 443/TCP 4d3h
[root@k8s-master opt]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 172.16.0.10 <none> 53/UDP,53/TCP,9153/TCP 4d3h
二、Service
的类型
ClusterIP
- 仅在集群内部可以被访问
NodePort
- 将服务发布到物理机
LoadBalance
- 适用于公有云场景
三、ClusterIP
类型
- 有
clusterIP
的服务- 集群内部服务
A
访问服务B
时,DNS
组件会将其解析到服务B
对应的IP
上
- 集群内部服务
- 无
clusterIP
的服务- 集群内部服务
A
访问服务B
时,由于服务B
没有IP
,DNS
会直接解析到对应的Pod
地址上 - 缺点
- 由于直接解析到
Pod
上,失去了kube-proxy
提供的负载均衡,在该Pod
宕机时,会导致服务无法正常访问
- 由于直接解析到
- 集群内部服务
1.创建一个有ClusterIP
的服务
[root@k8s-master wordpress]# vim nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: wordpress
spec:
replicas: 2
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
--- #创建不同的服务,可以使用分隔符隔开
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: wordpress
spec:
ports:
- port: 80
selector:
app: nginx
[root@k8s-master wordpress]# kubectl create -f ./nginx.yml
deployment.apps/nginx created
service/nginx created
查看servive
和Pod
[root@k8s-master wordpress]# kubectl get svc -n wordpress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 172.16.14.75 <none> 80/TCP 16s
[root@k8s-master wordpress]# kubectl get pods -n wordpress -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-75b69bd684-2dwkk 1/1 Running 0 2m40s 192.168.242.153 k8s-node02.linux.com <none> <none>
nginx-75b69bd684-8fp7t 1/1 Running 0 2m40s 192.168.201.216 k8s-node01.linux.com <none> <none>
创建测试容器
clusterIP
模式的service
只能集群内部进行访问
[root@k8s-master wordpress]# vim centos.yml
apiVersion: v1
kind: Pod
metadata:
name: centos
namespace: wordpress
spec:
containers:
- name: centos
image: centos:7
imagePullPolicy: IfNotPresent
tty: true
resources:
requests:
memory: "1G"
cpu: "500m"
limits:
memory: "2G"
cpu: "1"
[root@k8s-master wordpress]# kubectl create -f centos.yml
pod/centos created
访问测试
注意,短域名只能在同
namespace
下适用,如果service
和pod
不在同一个namesapce
那么只能使用全域名访问
[root@k8s-master wordpress]# kubectl exec -it centos -n wordpress -- bash
[root@centos /]# curl nginx
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
[root@centos /]# curl nginx.wordpress.svc.cluster.local
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
2.创建一个无clusterIP
的服务
[root@k8s-master wordpress]# vim nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: wordpress
spec:
replicas: 2
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: wordpress
spec:
clusterIP: None #指定无IP
ports:
- port: 80
selector:
app: nginx
[root@k8s-master wordpress]# kubectl create -f nginx.yml
deployment.apps/nginx created
查看service
和Pod
[root@k8s-master wordpress]# kubectl get svc -n wordpress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP None <none> 80/TCP 79s
[root@k8s-master wordpress]# kubectl get pod -n wordpress -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
centos 1/1 Running 0 12m 192.168.242.154 k8s-node02.linux.com <none> <none>
nginx-75b69bd684-gdp9b 1/1 Running 0 3m55s 192.168.201.217 k8s-node01.linux.com <none> <none>
nginx-75b69bd684-htvbh 1/1 Running 0 3m55s 192.168.201.218 k8s-node01.linux.com <none> <none>
测试访问
可以看到
DNS
解析的IP
是Pod
上面的IP
[root@k8s-master wordpress]# kubectl exec -it centos -n wordpress -- bash
[root@centos /]# ping nginx.wordpress.svc.cluster.local
PING nginx.wordpress.svc.cluster.local (192.168.201.217) 56(84) bytes of data.
64 bytes from 192-168-201-217.nginx.wordpress.svc.cluster.local (192.168.201.217): icmp_seq=1 ttl=62 time=0.231 ms
64 bytes from 192-168-201-217.nginx.wordpress.svc.cluster.local (192.168.201.217): icmp_seq=2 ttl=62 time=0.238 ms
[root@centos /]# curl nginx.wordpress.svc.cluster.local
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
四、NodePort
类型
该类型的服务会将服务端口暴露在物理机上,可以借助物理机直接访问
1.创建NodePort
[root@k8s-master wordpress]# vim nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: wordpress
spec:
replicas: 2
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: wordpress
spec:
type: NodePort #类型NodePort
ports:
- port: 80
nodePort: 30002 #端口范围在30000-32767
selector:
app: nginx
[root@k8s-master wordpress]# kubectl create -f nginx.yml
deployment.apps/nginx created
service/nginx created
查看Pod
运行在哪个node
上
[root@k8s-master wordpress]# kubectl get pods -n wordpress -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-75b69bd684-jls9n 1/1 Running 0 2m30s 192.168.201.219 k8s-node01.linux.com <none> <none>
nginx-75b69bd684-lphpv 1/1 Running 0 2m30s 192.168.242.155 k8s-node02.linux.com <none> <none>
查看Service
[root@k8s-master wordpress]# kubectl get svc -n wordpress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 172.16.125.146 <none> 80:30002/TCP 3m19s
物理机访问测试
这里填写是物理机的
IP
2.实验
使用Kubernetes
部署Wordpress
创建命名空间
[root@k8s-master wordpress]# kubectl create ns wordpress
编写数据库yml
[root@k8s-master wordpress]# vim wp-mysql.yml
apiVersion: apps/v1
kind: Deployment #类型
metadata:
name: wp-mysql
namespace: wordpress #加入到wordpress命名空间
spec:
replicas: 1 #1个副本集
selector:
matchLabels:
app: wp-mysql #此处标签应该和下面你的容器标签对应
strategy: #滚动更新策略
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template: #容器的标签
metadata:
labels:
app: wp-mysql
spec:
containers:
- name: wp-mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
env: #传递变量
- name: MYSQL_ROOT_PASSWORD
value: "WWW.1.com" #设置root用户密码
resources: #资源限制
requests:
memory: "1G"
cpu: "1"
limits:
memory: "2G"
cpu: "2"
---
apiVersion: v1
kind: Service
metadata:
name: wp-mysql
namespace: wordpress #加入到wordpress命名标签
spec:
ports:
- port: 3306
selector:
app: wp-mysql #此处标签对应上面容器的标签
[root@k8s-master wordpress]# kubectl create -f wp-mysql.yml
[root@k8s-master wordpress]# kubectl get pod -n wordpress
NAME READY STATUS RESTARTS AGE
wp-mysql-cbcd75979-2dxkm 1/1 Running 0 3m36s
[root@k8s-master wordpress]# kubectl get svc -n wordpress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wp-mysql ClusterIP 172.16.166.18 <none> 3306/TCP 4m9s
创建wordpress
用到的库和用户
[root@k8s-master wordpress]# kubectl exec -it wp-mysql-cbcd75979-2dxkm -n wordpress -- bash
bash-4.2# mysql -uroot -pWWW.1.com
mysql> create database wordpress charset utf8mb4;
Query OK, 1 row affected (0.00 sec)
mysql> grant all on wordpress.* to 'wordpress'@'%' identified by 'WWW.1.com';
Query OK, 0 rows affected, 1 warning (0.00 sec)
编辑wordpress
的yml
文件
[root@k8s-master wordpress]# vim wordpress.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
namespace: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: wp-mysql #此处数据库地址为cronDNS解析地址,也可以是全名,wp-mysql.wordpress.svc.cluster.local
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: WWW.1.com
- name: WORDPRESS_DB_NAME
value: wordpress
- name: WORDPRESS_TABLE_PREFIX
value: wp_
resources:
requests:
memory: "1G"
cpu: "1"
limits:
memory: "2G"
cpu: "2"
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
namespace: wordpress
spec:
type: NodePort
ports:
- port: 80
nodePort: 30005
selector:
app: wordpress
[root@k8s-master wordpress]# kubectl create -f wordpress.yml
[root@k8s-master wordpress]# kubectl get pod -n wordpress -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
wordpress-657f59cdf5-82f7v 1/1 Running 0 2m42s 192.168.201.221 k8s-node01.linux.com <none> <none>
wp-mysql-cbcd75979-2dxkm 1/1 Running 0 16m 192.168.242.156 k8s-node02.linux.com <none> <none>
[root@k8s-master wordpress]# kubectl get svc -n wordpress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wordpress NodePort 172.16.200.34 <none> 3306:30005/TCP 2m16s
wp-mysql ClusterIP 172.16.166.18 <none> 3306/TCP 16m
访问测试
后面安装配置过程省略
五、Ingress发布服务
1.关于Ingress
- 之前在
k8s
集群内部对外暴露服务的方式用的是nodePort
,但采用NodePort
方式暴露服务面临问题是,服务一旦多起来,NodePort
在每个节点上开启的端口会及其庞大,而且难以维护 - 因此,后续出现了一种新的方式,称为
ingress
;ingress
类似于coreDNS
是作为k8s
的插件存在的,借助ingress
一样可对外暴露服务 - 基于
ingress
暴露服务时,类似于七层调度,对外可提供一个主机名,将不同的服务以不同的端口方式映射到该主机名上,客户端直接通过主机名进行访问
2.Ingress
核心组件
ingress
- 一种资源对象,用于描述服务规则
ingress-controller
Ingress Controller
通过与Kubernetes API
交互,动态的去感知集群中Ingress
规则变化,然后读取他,按照他自己模板生成一段Nginx
配置,再写到Nginx Pod
里,最后reload
一下
3.Ingress
服务名访问实现方式
nginx
haproxy
traefik
4.Ingress-nginx
部署
A.准备Ingress-nginx
的yaml
文件
可以前往
Github
仓库地址下载想要的版本:https://github.com/kubernetes/ingress-nginx
或者使用我这里准备好的yaml
文件:https://pan.baidu.com/s/1l9cF-AShYicLk1arwVboEw?pwd=jge3
由于本人使用的kubernetes
版本是1.20.7
所以使用ingress-nginx_v1.3.1
版本
B.修改igress-nginx.yml
文件
如果使用的是我提供的
yml
文件,可以不做修改
#添加配置Pod网络模式为host
416行 hostNetwork: true
#修改镜像下载地址为国内地址
439行 image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.3.1
536行 image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.3.0
585行 image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.3.0
C、部署Ingress-nginx_v1.3.1
[root@k8s-master wordpress]# kubectl create -f ./ingress-nginx-deploy_v1.3.1.yaml
[root@k8s-master wordpress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-h2mpq 0/1 Completed 0 153m
ingress-nginx-admission-patch-2v2vc 0/1 Completed 1 153m
ingress-nginx-controller-64ff7cd7cf-58qkl 1/1 Running 0 153m
[root@k8s-master wordpress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 172.16.100.79 <pending> 80:32754/TCP,443:31928/TCP 153m
ingress-nginx-controller-admission ClusterIP 172.16.18.128 <none> 443/TCP 153m
D.准备Pod
[root@k8s-master wordpress]# vim nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: wordpress
spec:
replicas: 2
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: wordpress
spec: #创建一个clusterIP类型
ports:
- port: 80
selector:
app: nginx
[root@k8s-master wordpress]# kubectl create -f nginx.yml
deployment.apps/nginx created
service/nginx created
E.准备ingress
[root@k8s-master wordpress]# vim ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-wp
namespace: wordpress #命名空间
annotations: #注释说明信息
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: ng.linux.com
http:
paths:
- path:
backend:
serviceName: nginx #对应的svc服务名
servicePort: 80 #svc服务对应的端口
[root@k8s-master wordpress]# kubectl create -f ingress.yml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.extensions/ingress-wp created
F.访问测试
查看ingress
[root@k8s-master wordpress]# kubectl get ingress -n wordpress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-wp <none> ng.linux.com 80 54s
查看controller
跑在哪个物理机上
我这里跑在
node1
上
controller
运行在哪个服务器上,决定我们的解析地址在哪里
[root@k8s-master wordpress]# kubectl get pods -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create-h2mpq 0/1 Completed 0 172m 192.168.242.159 k8s-node02.linux.com <none> <none>
ingress-nginx-admission-patch-2v2vc 0/1 Completed 1 172m 192.168.201.225 k8s-node01.linux.com <none> <none>
ingress-nginx-controller-64ff7cd7cf-58qkl 1/1 Running 0 172m 192.168.140.11 k8s-node01.linux.com <none> <none>
配置域名解析
路径:
C:\Windows\System32\drivers\etc\hosts
访问测试
5.实验:使用Ingress-nginx
发布wordpress
A.创建命名空间
[root@k8s-master wordpress]# kubectl create ns wordpress
B.创建Mysql
容器
[root@k8s-master wordpress]# vim wp-mysql.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wp-mysql
namespace: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wp-mysql
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: wp-mysql
spec:
containers:
- name: wp-mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "WWW.1.com"
resources:
requests:
memory: "1G"
cpu: "1"
limits:
memory: "2G"
cpu: "2"
---
apiVersion: v1
kind: Service
metadata:
name: wp-mysql
namespace: wordpress
spec:
ports:
- port: 3306
selector:
app: wp-mysql
[root@k8s-master wordpress]# kubectl create -f wp-mysql.yml
deployment.apps/wp-mysql created
service/wp-mysql created
C.创建wordpress
用到的库和用户
[root@k8s-master wordpress]# kubectl -it exec wp-mysql-cbcd75979-tfk9r -n wordpress -- bash
bash-4.2# mysql -uroot -pWWW.1.com
mysql> create database wordpress charset utf8mb4;
Query OK, 1 row affected (0.00 sec)
mysql> grant all on wordpress.* to 'wordpress'@'%' identified by 'redhat';
Query OK, 0 rows affected, 1 warning (0.00 sec)
D.创建Wordpress
容器
[root@k8s-master wordpress]# vim wordpress.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
namespace: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: wp-mysql
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: redhat
- name: WORDPRESS_DB_NAME
value: wordpress
- name: WORDPRESS_TABLE_PREFIX
value: wp_
resources:
requests:
memory: "1G"
cpu: "1"
limits:
memory: "2G"
cpu: "2"
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
namespace: wordpress
spec: #注意服务类型为clusterIP
ports:
- port: 80
selector:
app: wordpress
[root@k8s-master wordpress]# kubectl create -f wordpress.yml
deployment.apps/wordpress created
service/wordpress created
查看服务
[root@k8s-master wordpress]# kubectl get svc -n wordpress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wordpress ClusterIP 172.16.67.252 <none> 80/TCP 88s
wp-mysql ClusterIP 172.16.192.50 <none> 3306/TCP 9m23s
E.创建Ingress
服务
[root@k8s-master wordpress]# vim ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-wp
namespace: wordpress #指定命名空间
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: wp.linux.com #自定义访问域名
http:
paths:
- path:
backend:
serviceName: wordpress #此处服务名,应该对应wordpress的服务名字
servicePort: 80
[root@k8s-master wordpress]# kubectl create -f ingress.yml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.extensions/ingress-wp created
查看Ingress
[root@k8s-master wordpress]# kubectl get ingress -n wordpress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-wp <none> wp.linux.com 80 46s
查看controller
容器在哪台实体机上
controller
跑在哪台机器上,决定我们解析地址在哪里
[root@k8s-master wordpress]# kubectl get pod -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create-h2mpq 0/1 Completed 0 10h 192.168.242.159 k8s-node02.linux.com <none> <none>
ingress-nginx-admission-patch-2v2vc 0/1 Completed 1 10h 192.168.201.225 k8s-node01.linux.com <none> <none>
ingress-nginx-controller-64ff7cd7cf-58qkl 1/1 Running 0 10h 192.168.140.11 k8s-node01.linux.com <none> <none>
F.修改host
文件
路径:
C:\Windows\System32\drivers\etc\hosts