Kubernetes-Service网络资源
nginx-php-mysql分开部署示例
apiVersion: "v1"
kind: "Pod"
metadata:
name: nginx-pod
labels:
app: nginx
spec:
volumes:
- name: nginx-data
hostPath:
path: /data/nginx
- name: nginx-code
hostPath:
path: /data/code
containers:
- name: nginx-container
image: nginx:alpine
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nginx-data
mountPath: /etc/nginx/conf.d/
- name: nginx-code
mountPath: /code
---
apiVersion: "v1"
kind: "Pod"
metadata:
name: php-pod
spec:
volumes:
- name: php-data
hostPath:
path: /data/php
containers:
- name: php-container
image: php:7.4.33-fpm
imagePullPolicy: IfNotPresent
volumeMounts:
- name: php-data
mountPath: /usr/local/etc/php-fpm.d/
---
apiVersion: "v1"
kind: "Pod"
metadata:
name: mysql-pod
spec:
volumes:
- name: mysql-data
hostPath:
path: /data/mysql
containers:
- name: mysql-container
image: mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: '123'
- name: MYSQL_DATABASE
value: 'wordpress'
- name: MYSQL_USER
value: 'wp'
- name: MYSQL_PASSWORD
value: '123'
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
## 结论
nginx访问php ip要写死
nginx与php需要同时部署相同的资源才能起一个服务
k8s的三种IP
Nodeport
节点对外提供访问的IP
ClusterIP
用来动态发现和负载均衡POD的IP
PodIP
提供pod使用的IP
## Service提供四种资源:
ExternalName
ClusterIP
NodePort
LoadBalancer
nginx示例(ClusterIP)
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-db
labels:
app: nginx-labels
spec:
replicas: 6
selector:
matchLabels:
app: nginx-labels
template:
metadata:
labels:
app: nginx-labels
spec:
containers:
- name: nginx-db
image: nginx:alpine
imagePullPolicy: IfNotPresent
ClusterIP
kind: Service
apiVersion: v1
metadata:
name: nginx-svc
spec:
selector:
# 寻找的是pod的标签而不是控制器的标签
app: nginx-labels
type: ClusterIP
ports:
- name: nginx-port
port: 80
targetPort: 80
protocol: TCP
# 查找service
[root@master-1 tmp]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 6d21h
nginx-svc ClusterIP 10.1.160.35 <none> 80/TCP 3d16h
# 查找service中nginx-svc的详细信息
[root@master-1 tmp]# kubectl describe svc nginx-svc
Name: nginx-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=nginx-labels
Type: ClusterIP
IP: 10.1.160.35
Port: nginx-port 80/TCP
TargetPort: 80/TCP
Endpoints: 10.2.1.51:80,10.2.1.52:80,10.2.2.72:80 + 3 more...
Session Affinity: None
Events: <none>
# 查看clusterip的nginx内容
[root@master-1 tmp]# curl 10.1.160.35
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
mysql示例(ClusterIP)
Deployment
# 编写资源清单
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-db
labels:
app: mysql-db
spec:
replicas: 1
selector:
matchLabels:
mysql: pod
template:
metadata:
labels:
mysql: pod
spec:
containers:
- name: mysql-pod
image: mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: "123"
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wp
- name: MYSQL_PASSWORD
value: "123"
# 启动
[root@master-1 tmp]# kubectl apply -f mysql-dp.yml
deployment.apps/mysql-db created
service
# 编写资源清单
kind: Service
apiVersion: v1
metadata:
name: mysql-svc
spec:
selector:
mysql: pod
type: ClusterIP
ports:
- name: mysql-port
port: 3306
targetPort: 3306
protocol: TCP
# 启动
[root@master-1 tmp]# kubectl apply -f mysql-svc.yml
service/mysql-svc created
# 查找mysql-svc的详细信息
[root@master-1 tmp]# kubectl describe svc mysql-svc
Name: mysql-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: mysql=pod
Type: ClusterIP
IP: 10.1.105.7
Port: nginx-port 3306/TCP
TargetPort: 3306/TCP
Endpoints: 10.2.2.76:3306
Session Affinity: None
Events: <none>
# 尝试连接
[root@node-2 ~]# mysql -uroot -p123 -h10.1.105.7
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
SVC的通信流程
1)启动任何pod时,每个pod都会配置nameserver coredns-svc
root@mysql-db-5bd9b8fbf4-2g4vj:/# cat /etc/resolv.conf
nameserver 10.1.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
2)所有pod通过svc找到coredns服务器
[root@master-1 tmp]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.1.0.10 <none> 53/UDP,53/TCP,9153/TCP 7d3h
[root@master-1 tmp]# kubectl describe svc -n kube-system kube-dns
Name: kube-dns
Namespace: kube-system
Labels: k8s-app=kube-dns
kubernetes.io/cluster-service=true
kubernetes.io/name=KubeDNS
Annotations: prometheus.io/port: 9153
prometheus.io/scrape: true
Selector: k8s-app=kube-dns
Type: ClusterIP
IP: 10.1.0.10
Port: dns 53/UDP
TargetPort: 53/UDP
Endpoints: 10.2.0.2:53,10.2.2.2:53
Port: dns-tcp 53/TCP
TargetPort: 53/TCP
Endpoints: 10.2.0.2:53,10.2.2.2:53
Port: metrics 9153/TCP
TargetPort: 9153/TCP
Endpoints: 10.2.0.2:9153,10.2.2.2:9153
Session Affinity: None
Events: <none>
3)当启动svc资源时,会见svc的名字和svc的ip地址,在coredns中解析
[root@master-1 tmp]# kubectl describe svc mysql-svc
Name: mysql-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: mysql=pod
Type: ClusterIP
IP: 10.1.105.7
Port: nginx-port 3306/TCP
TargetPort: 3306/TCP
Endpoints: 10.2.2.76:3306
Session Affinity: None
Events: <none>
任何pod只要ping svc的名称就可以进行通信
nginx示例(NodePort)
存在问题:
1)kubeadm中针对NodePort设置了端口范围:30000-32767
2)在nodeport中的端口映射,是四层,防火墙iptables转发的
3)一个nginx pod只能起一个网站,起多个不认识域名
# 编写资源清单
kind: Service
apiVersion: v1
metadata:
name: nginx-svc
spec:
selector:
app: nginx-labels
type: NodePort
ports:
- name: nginx-port
port: 80
targetPort: 80
protocol: TCP
nodePort: 30002
# 启动
[root@master-1 tmp]# kubectl apply -f 11.yml
service/nginx-svc configured
解决方法:
只写ClusterIP,不使用NodePort
在企业中,使用Ingress
NodePort缺陷
1.没有ingress之前,pod对外提供服务只能通过NodeIP:NodePort的形式,但是这种形式有缺点,一个节点上的PORT不能重复利用。比如某个服务占用了80,那么其他服务就不能在用这个端口了。
2.NodePort是4层代理,不能解析7层的http,不能通过域名区分流量
3.为了解决这个问题,我们需要用到资源控制器叫Ingress,作用就是提供一个统一的访问入口。工作在7层
4.虽然我们可以使用nginx/haproxy来实现类似的效果,但是传统部署不能动态的发现我们新创建的资源,必须手动修改配置文件并重启。
5.适用于k8s的ingress控制器主流的有nginx-ingress、traefik、haproxy-ingress
nginx-Ingress
部署nginx-ingress
# 拉取镜像
[root@node-1 ~]# docker pull nginx/nginx-ingress:1.7.2
[root@node-2 ~]# docker pull nginx/nginx-ingress:1.7.2
# 下载资源清单
https://github.com/kubeguide/K8sDefinitiveGuide-V5-Sourcecode/blob/main/Chapter04/4.6.1%20nginx-ingress-controller.yaml
# 修改名称
[root@master-1 tmp]# mv 4.6.1\ nginx-ingress-controller.yaml nginx-ingress.yaml
# 编写配置文件
## 将Deployment改成DaemonSet
kind: DaemonSet
## 删除副本数量
replicas: 1
## 删除ingress创建资源
# mywebsite-ingress.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mywebsite-ingress
spec:
rules:
- host: mywebsite.com
http:
paths:
- path: /demo
pathType: ImplementationSpecific
backend:
service:
name: webapp
port:
number: 8080
# test accessing service through ingress
# curl --resolve mywebsite.com:80:192.168.18.3 http://mywebsite.com/demo/
# test accessing service through ingress
## 删除节点标签选择器
nodeSelector:
role: ingress-nginx-controller
# 启动ingress
[root@master-1 tmp]# kubectl apply -f nginx-ingress.yaml
namespace/nginx-ingress created
serviceaccount/nginx-ingress created
clusterrole.rbac.authorization.k8s.io/nginx-ingress created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress created
secret/default-server-secret created
configmap/nginx-config created
daemonset.apps/nginx-ingress created
# 查看ingress
[root@master-1 tmp]# kubectl get pod -n nginx-ingress -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-28qrx 1/1 Running 0 49s 10.2.1.53 node-1 <none> <none>
nginx-ingress-xxr4w 1/1 Running 0 49s 10.2.2.77 node-2 <none> <none>
# 查看ingress资源
[root@master-1 tmp]# kubectl get ingress
## 注意:ingress必须创建在clusterip之上
[root@master-1 tmp]# vim nginx-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: nginx-svc
spec:
selector:
app: nginx-labels
type: ClusterIP
ports:
- name: nginx-port
port: 80
targetPort: 80
protocol: TCP
# 编写ingress资源
[root@master-1 tmp]# vim nginx-in.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: welcome-to-nginx
spec:
rules:
- host: www.ljy.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx-svc
port:
number: 80
# 启动
[root@master-1 tmp]# kubectl apply -f nginx-in.yaml
# 本地域名解析
10.0.0.111 www.ljy.com
规则解释:
spec:
rules: # 转发规则
- host: www.ljy.com # 匹配的域名
http: # 基于http协议解析
paths: # 基于路径进行匹配
- path: / # 匹配/路径
pathType: ImplementationSpecific # 路径类型
backend: # 匹配后跳转的后端服务
service: # 设置后端跳转到Service的配置
name: nginx-svc # 跳转到名为my-nginx的ClusterIP
port: # 跳转到的端口
number: 80 # Service端口号
pathType路径类型支持的类型:
ImplementationSpecific 系统默认,由IngressClass控制器提供
Exact 精确匹配URL路径,区分大小写
Prefix 匹配URL路径的前缀,区分大小写
连接不同名称空间的容器方法
# ping
ping service-name.namespace-name.svc.cluster.local
wordpress访问示例
mysql
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-db
labels:
app: mysql-db
spec:
replicas: 1
selector:
matchLabels:
mysql: pod
template:
metadata:
labels:
mysql: pod
spec:
containers:
- name: mysql-pod
image: mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: "123"
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wp
- name: MYSQL_PASSWORD
value: "123"
---
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
spec:
selector:
mysql: pod
type: ClusterIP
ports:
- name: mysql-port
port: 3306
targetPort: 3306
protocol: TCP
[root@master-1 tmp]# kubectl apply -f mysql.yml
[root@master-1 tmp]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-db-5bd9b8fbf4-2g4vj 1/1 Running 0 6h59m 10.2.2.76 node-2 <none> <none>
wordpress
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: wdport
env:
- name: WORDPRESS_DB_HOST
value: 10.2.2.76:3306 #连接数据库,这里的ip地址查看mysql启动时的ip
- name: WORDPRESS_DB_USER
value: wp
- name: WORDPRESS_DB_PASSWORD
value: "123"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
spec:
type: ClusterIP
selector:
app: wordpress
ports:
- name: wordpressport
protocol: TCP
port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wordpress-ingress
spec:
rules:
- host: blog.ljy.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: wordpress
port:
number: 80
# 启动
[root@master-1 tmp]# kubectl apply -f wordpress.yml
# 查看ingress资源
[root@master-1 tmp]# kubectl get ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
welcome-to-nginx <none> www.ljy.com 80 5h12m
wordpress-ingress <none> blog.ljy.com 80 105s
# 本地域名解析
blog.ljy.com