编辑/etc/sysconfig/kubelet 使用 KUBE_PROXY_NODE=ipvs 指定service的模式 那么ipvs使用的算法包括 : ip_vs ip_vs_rr ip_vs_sh
如果一个主机没有Cluster IP 那么我们就称为 Headless --> 将serveicename 解析到后端的pod上
k8s 的三个核心资源: pod 控制器 service
那么service是四层的负载均衡 ,不是七层的,只能是基于 iptables 或者是 ipvs ,如果用户访问的是https 的请求 ,那么对四层来说无法惊醒负载, 如果pod中的应用是HTTP的想要增强成HTTPS的,那么我们可以想一下其中的证书呀,私钥配置在什么地方,如果我们的调度器是lvs ,那么我们想提供HTTP 的服务 ,那么这个HTTP应该配置在那里? 注: 应该配置在后端主机上,不能配置在lvs上,所以我们必须在后端的每个服务器上配置 HTTPS ,配置证书,私钥 ,,等等 ,
无论是ipvs 还是 iptables ,都无法调度七层的应用,因此我们要使用http 或者 https 我们就必须使用七层的调度 ,将客户 -> 调度器 (使用七层) -> 后端 , 那么现在我们就只能换调度器 , k8s 采用(可以理解为加一层),后端配置的是不加https ,就是明文的htp, 那么我们使用一个独特的调度器,当用户试图访问的时候,我们不让他们到达后端的服务器,而是先到达调度器 (可以定义一个pod资源) , 然后在访问后端的服务器 ,这样原来的明文就可以被https访问到了 。
那么在K8s中我们有特定的方法来解决这个七层的负载的方法:
我们使用一个新的控制器称为 Ingress Controller ,这个和之前说的 DaemonSet ReplicaSet 都不太一样,----> 他们是作为manager来存在的 ,是master上的核心组件之一,而Ingress 是自己独立存在的一组组件pod资源,通常就是一组应用程序,这个应用程序就是拥有七层调度功能的一组应用程序,k8s上的选择有四种: 最不受待见的是HAproxy 默认的是 Nginx 现在服务网格当中Envoy 当前还有其他的,Traefik 所以我们在配置应用的是有三种选择 : Nginx Envoy traefik(为微服务设计而生) ,
但是它们最为调度器而言不止要调度一个后端服务,那么在后端的web服务有多种时(电商、api、..),使用调度器调度的时候我们怎么可以判断调度的究竟是我们想要的服务? : 1.我们可以考虑在Nginx上怎么调度,首先我们有四组upstream ,然后对客户端而言我们可以做四个虚拟主机 来进行以域名的形式访问。
在k8s 上有一类特殊的资源,Ingress资源,Ingress 和 Ingress Controller是两个概念 ,我们定义Ingres 的意义就是说定义我们期望Ingress Controller 如何给我们建一个前端(可能是虚拟主机也可能是url映射)而又给我们定义一个后端(有几个主机 Ingress 是通过srevice得到的),首先我们由一个service对后端的pod进行分类,而后Ingress基于这个分类识别出这几个pod的ip地址 ,然后生成配置信息注入到(以Nginx为例,那就是upstream 中)
那么在Igress实现的七层负载的过程是: 最外面的对节点的均衡 Externalname ---> 具体的某一节点上 NodePort ----> 节点上的 Ingresss Controller ---> 调度到具体的Ingress 上 ,因为Ingress 分别管理着一组pod资源 ----> 通过service 对这些pod进行分组传给Ingress 引用
那么下来我们要使用Ingress这个功能,我们要去创建一个Ingress Controller Pod 而后我们要定义后端的service 在将他们之间建立联系。我们下来看一个Ingress怎么定义 ? Ingress 也是标准的K8s资源 。我们一样使用explain的文档去查看类似的参数的定义,同样在包含的资源的清单中也会有: apiVersion kind metadata spec status
[root@server1 ~]# kubectl explain ingress
KIND: Ingress
VERSION: extensions/v1beta1
DESCRIPTION:
Ingress is a collection of rules that allow inbound connections to reach
the endpoints defined by a backend. An Ingress can be configured to give
services externally-reachable urls, load balance traffic, terminate SSL,
offer name based virtual hosting etc.
FIELDS:
apiVersion
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
kind
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
metadata
spec
status
spec字段的定义:
[root@server1 ~]# kubectl explain ingress.spec
KIND: Ingress
VERSION: extensions/v1beta1
RESOURCE: spec
DESCRIPTION:
Spec is the desired state of the Ingress. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
IngressSpec describes the Ingress the user wishes to exist.
FIELDS:
backend
rules <[]Object> 定义http的规则
A list of host rules used to configure the Ingress. If unspecified, or no
rule matches, all traffic is sent to the default backend.
tls <[]Object>
TLS configuration. Currently the Ingress only supports a single TLS port,
443. If multiple members of this list specify different hosts, they will be
multiplexed on the same port according to the hostname specified through
the SNI TLS extension, if the ingress controller fulfilling the ingress
supports SNI.
Ingress 有很多种类型,要么是映射的,要么是虚拟主机的,那么下来我们要看一下怎么部署一个Ingress Controller ,对k8s而言Ingress是作为附件存在的 ,整个K8s集群由: master node + 附件组成的。 附件: coredns + .. + Dashborad + Ingress
那么Ingress是一个集群的核心附件之一,下来我们实际的部署一个Ingress + nginx
第一步: 创建名称空间
示例: 使用命令创建名称空间:
[root@server1 ~]# kubectl create namespace dev
namespace/dev created
[root@server1 ~]# kubectl get ns
NAME STATUS AGE
default Active 17d
dev Active 18s
kube-public Active 17d
kube-system Active 17d
删除一个名称空间 : 名称空间/名称空间的名字
[root@server1 ~]# kubectl delete ns/dev
namespace "dev" deleted
第二步: 创建一个configmap 作用: 为Nginx 从外部注入配置
第三步: rbac 我们集群用到了 rbac 作用: 它是用来定义一些 cluster 角色、 授权 (必要的授予一个pod到达不了它本来访问的名称空间的权限)
第四步: rbac 启用以后,要创建 with-rbac 包括: 使用的镜像
第五步: 我们有可能要为其配置一个tcp-service-configmap 的资源
那么git 到本地可能会很慢,我们直接将其配置文件复制到本地 :
1. 创建名称空间 : 方法一:
[root@server1 ~]# kubectl create namespace ingress-nginx
namespace/ingress-nginx created
方法二:
注意: 在git 上将文件托下来的时候,一定要使用 raw 格式的数据,这样下载下来的才是一个原始的代码数据,要不然只能是一个html的页面。
那么我们复制连接的地址:https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/namespace.yaml
[root@server1 ~]# mkdir ingress-nginx
[root@server1 ~]# cd ingress-nginx/
[root@server1 ingress-nginx]# ls
[root@server1 ingress-nginx]# for file in namespace.yaml configmap.yaml rbac.yaml with-rbac.yaml ; do wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/$file; done
[root@server1 ingress-nginx]# ls
configmap.yaml namespace.yaml rbac.yaml with-rbac.yaml
下载完成以后我们要先执行namespace
[root@server1 ingress-nginx]# kubectl apply -f namespace.yaml
namespace/ingress-nginx created
后面的文件的先后关系没有那么重要 我们期望去按照某种顺序的时候,可以使用for循环
apply是针对目录的,它会自动的引用目录下的所有文件
[root@server1 ingress-nginx]# kubectl apply -f ./
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
namespace/ingress-nginx configured
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
在查看的时候这个镜像正在下载,那么我们不用直接等待,因为我最初在搭建的时候没有使用代理,所以可能k8s.io上的镜像会托不下来,我们等会来检查一下
[root@server1 ingress-nginx]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-769d8b56b7-scqh6 0/1 ContainerCreating 0 1m
经过后期的检查发现这个镜像位于github上,完全可以托下来,是严重不用担心
[root@server1 ingress-nginx]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-769d8b56b7-scqh6 1/1 Running 0 7m
那么我们试着去创建 Ingress , 为了 ingress 可以显示出来效果,那么我们可以部署一下后端的服务 ,自定义一个配置清单的Ingress Controller的控制器
那么因为资源清单会随着需求创建得越来越多,因此我们在创建资源得清单得时候,我们要做好把我们得配置文件归类得准备
[root@server1 ingress]# pwd
/root/mainfests/ingress
在部署控制器之前,我们得部署一个后端得service 或者pod 为ingress控制器做准备 ,那么在使用Pod控制器创建pod得使用我们要在控制器之上创建一个service ,那么Service得定义我们在官方的文档中查看发现必须是Headlist ,否则无法解析到pod的节点的ip地址。
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
release: canary
ports:
- name: http
targetPort: 80
port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v2
ports:
- name: http
containerPort: 80
[root@server1 ingress]# kubectl apply -f deploy-demo.yaml
service/myapp created
deployment.apps/myapp-deploy unchanged
[root@server1 ingress]# kubectl get svc 查看 svc的ClusterIP的类型,那么在现在的我们看到的是并不是无头的,那么使用这个我们来测试一下(我记得之前没有指定就是ClusterIP )
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1
myapp ClusterIP 10.105.120.214
myapp-svc ClusterIP None
redis ClusterIP 10.97.97.97
[root@server1 ingress]#
那么我们来回顾一下刚才的github上面的文件,里面有一个叫作: mandatory.yaml 这个文件是将所有的文件拼在一mandatory.yaml个文件当中,使用这一个文件我们就可以创建ingress的全部的事情。比手动的拼凑要更简单一些
下来我们要为我们的Ingress Controller创建一个 service NodePort ,否则 Ingress Controller是无法被集群外部的客户访问的 :
但是网上有现成的NodePort的资源配置清单,因此我们直接下载下来就可以了
[root@server1 ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
nodePort: 30080 我们指定的节点暴露的端口
- name: https
port: 443
targetPort: 443 后端的nginx的端口
protocol: TCP
nodePort: 30443 指定Nginx暴露的端口
selector:
app: ingress-nginx
---
[root@server1 ingress]# kubectl apply -f ./
service/myapp unchanged
deployment.apps/myapp-deploy unchanged
service/ingress-nginx created
[root@server1 ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.105.174.166
现在我们就可以在集群的外部尝试访问一下我们的Ingress 的服务 :
但是按理来说应该出现正常的调度: 出现的应该是 default backed - 404 但是却出现的是根本就访问不了这个30080的端口 ,提示:端口不能正常的访问, 那 继续向下 ,看看这个问题到后面能不能解决 ?
下来我们将我们的myapp关联到nginx上 :
[root@server1 ingress-nginx]# kubectl describe svc myapp
Name: myapp
Namespace: default
Labels:
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"myapp","namespace":"default"},"spec":{"ports":[{"name":"http","port":80,"targe...
Selector: app=myapp,release=canary
Type: ClusterIP
IP: 10.105.120.214
Port: http 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.102:80,10.244.1.103:80,10.244.2.99:80
Session Affinity: None
Events:
[root@server1 ingress]# vim ingress-myapp.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-myapp
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: myapp.magedu.com
http:
paths:
- path:
backend:
serviceName: myapp
servicePort: 80
[root@server1 ingress]# kubectl apply -f ingress-myapp.yaml
ingress.extensions/ingress-myapp created
[root@server1 ingress]# kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ingress-myapp myapp.magedu.com 80 13s
[root@server1 ingress]# kubectl describe ingress ingress-myapp 这个ingress一旦创建了以后会自动的注入到 ingress Controller中去, 会自动的转换成nginx的配置文件
Name: ingress-myapp
Namespace: default
Address:
Default backend: default-http-backend:80 (
Rules:
Host Path Backends
---- ---- --------
myapp.magedu.com
myapp:80 (
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-myapp","namespace":"default"},"spec":{"rules":[{"host":"myapp.magedu.com","http":{"paths":[{"backend":{"serviceName":"myapp","servicePort":80},"path":null}]}}]}}
kubernetes.io/ingress.class: nginx
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 49s nginx-ingress-controller Ingress default/ingress-myapp
[root@server1 ingress]#
[root@server1 ingress]# kubectl exec -n ingress-nginx -it nginx-ingress-controller-769d8b56b7-scqh6 -- /bin/sh
$ cat nginx.conf 使用交互式的命令进入到pod内部去,查看nginx的配置文件中有没有我们定义的
# Configuration checksum: 3855965695233399109
server {
server_name myapp.magedu.com ;
listen 80;
注意:nginx的负载是以域名进行负载的,因此我们必须要注意解析到本地的节点,