ingress文档

https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/service-resources/ingress-v1/

我们之前从k8s集群外部访问Pod,通过Service的类型NodePort的ip加端口号访问的

就是我们装了kube-proxy的组件的节点上,都会在node节点上有个pod端口号,通过node节点加pod端口号去访问,最终访问到pod资源

根据之前学习的,服务发现是这样来做的

我们为了给Pod提供各种各样的配置的时候使用configMap 关于密码相关的是secret 这是给Pod提供各种各样的配置的,还有内置的downwardAPI 这是Pod运行起来就产生的变量

还有Pod控制器:Deployment ,Deployment底层是Replicas 。除了这两种还有Daemoset,这个是给所有的节点上都运行对应的Pod。有状态应用用的statufulset,这三种是最主要的Pod控制器,都是为了管理Pod来实现的

还有HPA 自动化扩容Pod,通常是基于cpu使用率或者内存使用率,来扩容或者缩容,他是通过Deployment来完成的,HPA是通过控制Deployment,由Deployment来去完成Pod扩容的,这是HPA这种对象

还有给Pod提供PV和PVC,持久化存储的,我们基于NFS和ROOK-CEPH,PV/PVC和他俩直接有个CSI容器存储接口,storageClass存储类给对应的Pod提供持久化存储

还有日志收集EFK

Kubernetes 入口 Ingress-NGINX_NGINX

以上是架构图

k8s最主要的任务,把我们的pod的程序提供给互联网访问的,之前在虚拟机里,通过LVS NGINX或者HAProxy 负载均衡 反向代理 提供域名让互联网用户来访问的

虚拟机时代通常是,nginx之前挂两台LVS,LVS把流量转发给多台NGINX服务器

K8s我们现在可以通过Service 的NodePort在对应的Node节点上映射出端口号,通过端口号来访问某一个Service,从某一个Service对应某一个Pod,这样来完成的

这个不适合生产,service的端口号是随机的,不方便

当然也可以通过LVS NGINX 通过VIP来访问 反向代理负载均衡到Service

不过还是不行

生产上我们使用的是k8s提供的另外一种资源对象Ingress

Ingress

Ingress负责把k8s集群上的服务映射出去,通过一个域名的方式映射出去,Ingress本身可以理解为一个NGINX 服务器,Ingress和对应的某个Service绑定

之前我们呢NGINX是加虚拟主机,概念,虚拟主机是个域名,我们想反向代理加负载均衡还有upstream负载均衡 + paroxy_pass 反向代理

upstream guoguo {
#定义一个组
    server 172.16.20.2:80;
    server 172.16.20.3:80;
}
server {
    listen 80
    server_name images.guoguo.com;
    
    location / {
        proxy_pass http://guoguo;
                    #使用这个组
       }
}

在k8s里面也是这样Ingress理解为一个NGINX服务器,它怎么把请求转发到后端Pod的呢,在nginx是upstream ,定义一个组名 然后添加server 主机ip ,在Ingress上是和Service关联的,把Service 理解为upstream起的组的名称,Ingress本身就可以作为一个域名理解为domain 一个虚拟主机,然后proxy 到server_name

我们需要在k8s集群上安装一个Ingress控制器,Ingress控制器理解为NGINX ,他就是个NGINX。Ingress控制器不光NGINX,但是我们用的比较多的就是NGINX

安装Ingress控制器,然后生成一个Ingress资源对象,然后我们通过Ingress资源对象去编写各种各样的Ingress的域名。Ingress域名通常就是域名加Service来完成的。通过这个域名把服务发布出去,这样service就不需要运行NodePort 类型的了,因为不需要知道你的Service 的NodePort是谁,只需要知道你Service的IP,所以我们用的类型就是ClusterIP类型的

首先安装Ingress控制器

官方文档:https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal-clusters

首先安装 Helm

下载 Ingress Nginx Controller 安装包

更改对应的配置

需要修改的位置

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
#添加源
helm repo update
#更新
helm pull ingress-nginx/ingress-nginx --version 4.0.1
#下载

解压

root@k8s-master1:/apps# tar xf ingress-nginx-4.0.1.tgz
root@k8s-master1:/apps# cd ingress-nginx/
root@k8s-master1:/apps/ingress-nginx# ll
total 80
drwxr-xr-x 4 root root  4096 Sep 19 19:57 ./
drwxr-xr-x 8 root root  4096 Sep 19 19:57 ../
-rw-r--r-- 1 root root  8550 Aug 24  2021 CHANGELOG.md
-rw-r--r-- 1 root root   668 Aug 24  2021 Chart.yaml
drwxr-xr-x 2 root root  4096 Sep 19 19:57 ci/
-rw-r--r-- 1 root root   342 Aug 24  2021 .helmignore
-rw-r--r-- 1 root root   213 Aug 24  2021 OWNERS
-rw-r--r-- 1 root root  9870 Aug 24  2021 README.md
drwxr-xr-x 3 root root  4096 Sep 19 19:57 templates/
-rw-r--r-- 1 root root 25563 Aug 24  2021 values.yaml

我们需要下载需要用到的镜像,因为网络原因我们先下载并上传到私有仓库

docker pull k8s.gcr.io/ingress-nginx/controller:v1.0.0
docker pull k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0
docker pull k8s.gcr.io/defaultbackend-amd64:1.5

创建harbor仓库项目ingress-nginx


Kubernetes 入口 Ingress-NGINX_Ingress_02


给下载的镜像改名

root@images:/apps/harbor# docker tag k8s.gcr.io/ingress-nginx/controller:v1.0.0 images.guoguo.com/ingress-nginx/controller:v1.0.0
root@images:/apps/harbor# docker tag k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0 images.guoguo.com/ingress-nginx/kube-webhook-certgen:v1.0
root@images:/apps/harbor# docker tag k8s.gcr.io/defaultbackend-amd64:1.5 images.guoguo.com/ingress-nginx/defaultbackend-amd64:1.5

然后上传

root@images:/apps/harbor# docker images | grep images.guoguo.com/ingress-nginx/ | awk '{print $1":"$2}' | xargs -n1 docker push

然后去master1修改刚才下载的文件

root@k8s-master1:/apps/ingress-nginx# vim values.yaml
13     registry: k8s.gcr.io  #这里是仓库地址
#改为
 13     registry: images.guoguo.com
 #####
 
  19     digest: sha256:0851b34f69f69352bf168e6ccf30e1e20714a264ab1ecd1933e4d8c0fc3215c6  
  #这里需要注释掉  这是ssh256的验证码 我们自己的仓库没有这个
 #改为
   19     #digest: sha256:0851b34f69f69352bf168e6ccf30e1e20714a264ab1ecd1933e4d8c0fc3215c6
   #####
   
    58   dnsPolicy: ClusterFirst   #dns策略
    #改为
     58   dnsPolicy: ClusterFirstWithHostNet

    #####
    

   
    72   hostNetwork: false  #hostNetwork 设置为true  #对应的pod本身使用的宿主机的网络 我们改为true
#改为
  72   hostNetwork: true 
  #####
  563         registry: k8s.gcr.io #改为私有仓库
  #改为
563         registry: images.guoguo.com
########

  686     registry: k8s.gcr.io   #改为私有仓库
  687     image: defaultbackend-amd64   #这里没有项目 我们加个项目

  #改为
686     registry: images.guoguo.com
687     image: ingress-nginx/defaultbackend-amd64
#########

  
 
569         digest: sha256:f3b6b39a6062328c095337b4cadcefd1612348fdd5190b1dcbcb9b9e90bd8068  #这里需要注释掉
#改为
569        # digest: sha256:f3b6b39a6062328c095337b4cadcefd1612348fdd5190b1dcbcb9b9e90bd8068


#添加个节点选择器
269   nodeSelector:
270     kubernetes.io/os: linux
271     ingress: "true"    #添加这行 
#就是ingress控制器运行在拥有整个标签的node节点上  未来可以多加两个点做高可用


171   kind: Deployment
#改为 DaemonSet
171   kind: DaemonSet
#改为DaemonSet意味着符合要求的node节点都要运行一个 
###

 92     default: false
#改为
 92     default: true
 #将 ingress nginx 设置为默认的 ingressClass  ingress类
 #我们默认的ingressClassResource资源对象 使用的是nginx    实际就是nginx  里面很多配置都是和nginx类似的

这就改完了 我们上面添加了 个节点选择器 我们给其中一个node节点打标签 让此节点运行整个ingress

root@k8s-master1:/apps/ingress-nginx# kubectl label nodes k8s-node2.guoguo.com ingress=true
node/k8s-node2.guoguo.com labeled
#这样node2节点就符合了

创建个名称空间

root@k8s-master1:/apps/ingress-nginx# kubectl create namespace ingress-nginx
namespace/ingress-nginx created

然后我们就可以安装修改完的ingress-nginx

root@k8s-master1:/apps/ingress-nginx# helm install ingress-nginx -n ingress-nginx .

#上面是安装命令
helm uninstall -n ingress-nginx ingress-nginx
这个是卸载

直接安装

输出内容


NAME: ingress-nginx
LAST DEPLOYED: Tue Sep 19 20:53:13 2023
NAMESPACE: ingress-nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace ingress-nginx get services -o wide -w ingress-nginx-controller'

An example Ingress that makes use of the controller:

  apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class:
    name: example
    namespace: foo
  spec:
    rules:
      - host: www.example.com
        http:
          paths:
            - backend:
                serviceName: exampleService
                servicePort: 80
              path: /
    # This section is only required if TLS is to be enabled for the Ingress
    tls:
        - hosts:
            - www.example.com
          secretName: example-tls

If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:

  apiVersion: v1
  kind: Secret
  metadata:
    name: example-tls
    namespace: foo
  data:
    tls.crt: <base64 encoded cert>
    tls.key: <base64 encoded key>
  type: kubernetes.io/tls

这样就安装成功了

查看一下

root@k8s-master1:/apps/ingress-nginx# kubectl get pods -n ingress-nginx
NAME                             READY   STATUS    RESTARTS   AGE
ingress-nginx-controller-8cv6j   1/1     Running   0          19m
# 这个就是controller
root@k8s-master1:/apps/ingress-nginx# kubectl get svc -n ingress-nginx
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      
ingress-nginx-controller             LoadBalancer   10.110.70.108   <pending>     80:30929/TCP,443:32523/TCP   
                            #这个service是nodeport类型的             后面访问的所有的ingress映射的域名端口号80的话都是30929 
                            #                                                                          443的话 都是32523
ingress-nginx-controller-admission   ClusterIP      10.102.0.98     <none>        443/TCP                      

在生产上 我们都是在k8s集群上还是有两台lvs的(也可以两台nginx),这两台lvs负责把公司的80和443映射到,对应的node节点上的 上面的 30929 和32523

80映射 30929 443 映射到23523

Kubernetes 入口 Ingress-NGINX_NGINX_03

现在控制器就安装成功了

安装成功以后我们可以模拟一下,创建各种各样的ingres资源对象 配置清单

通过域名的方式来访问集群上的服务

查看一下 ingress 资源对象

root@k8s-master1:/apps/ingress-nginx# kubectl explain ingress
KIND:     Ingress  #类型
VERSION:  networking.k8s.io/v1  #版本  1.19 以后变成稳定版了  我们安装的是1.21.5 是稳定版了

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   <string>
     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/sig-architecture/api-conventions.md#resources

   kind <string>
     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/sig-architecture/api-conventions.md#types-kinds

   metadata     <Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

   spec <Object>
     Spec is the desired state of the Ingress. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

   status       <Object>
     Status is the current state of the Ingress. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

创建个ns

root@k8s-master1:/apps/ingress# kubectl create namespace test-ingress
namespace/test-ingress created

创建个deployment


root@k8s-master1:/apps/ingress# cat deployment-test-1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: test-ingress
spec:
  selector:
    matchLabels:
      app: nginx
      version: v2
  template:
    metadata:
      labels:
        app: nginx
        version: v2
    spec:
      containers:
      - name: nginx
        image: images.guoguo.com/apps/nginx:1.22.1
        ports:
        - containerPort: 80

查看一下

root@k8s-master1:/apps/ingress# kubectl get pods -n test-ingress -owide
NAME                    READY   STATUS    RESTARTS   AGE   IP           NODE                 
nginx-bc4d69dd6-c5tzm   1/1     Running   0          41s   10.244.2.8   k8s-node2.guoguo.com

访问一下pod ip

root@k8s-master1:/apps/ingress# curl 10.244.2.8
VERSION:NGINX:1.22.1

pod的ip 只要一更新就会变 deployment的地址不会变化,所以我们呢要把deployment 和service关联起来

root@k8s-master1:/apps/ingress# cat service-test-1.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: test-ingress
spec:
  type: ClusterIP
  selector:
    app: nginx
    version: v2
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
root@k8s-master1:/apps/ingress# kubectl get svc -n test-ingress
NAME    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   10.109.155.28   <none>        80/TCP    3m55s

访问一下

root@k8s-master1:/apps/ingress# curl $(kubectl get svc -n test-ingress  | awk 'NR==2{print $3}')
VERSION:NGINX:1.22.1
root@k8s-master1:/apps/ingress# curl 10.109.155.28
VERSION:NGINX:1.22.1

看的Endpoint 的ip和pod ip

root@k8s-master1:/apps/ingress# kubectl get endpoints -n test-ingress
NAME    ENDPOINTS       AGE
nginx   10.244.2.8:80   7m55s
root@k8s-master1:/apps/ingress# kubectl get pods -n test-ingress -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP           NODE                  
nginx-bc4d69dd6-c5tzm   1/1     Running   0          15m   10.244.2.8   k8s-node2.guoguo.com

然后我们现在可以写一个ingress 然后在集群外 通过一个域名的方式来访问 你对应的pod

看下格式

root@k8s-master1:/apps/ingress# kubectl explain Ingress.metadata
KIND:     Ingress
VERSION:  networking.k8s.io/v1

RESOURCE: metadata <Object>

DESCRIPTION:
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

     ObjectMeta is metadata that all persisted resources must have, which
     includes all objects users must create.

FIELDS:

   labels       <map[string]string>
     Map of string keys and values that can be used to organize and categorize
     (scope and select) objects. May match selectors of replication controllers
     and services. More info: http://kubernetes.io/docs/user-guide/labels
     
   name <string>
   #名称  自定义
     Name must be unique within a namespace. Is required when creating
     resources, although some resources may allow a client to request the
     generation of an appropriate name automatically. Name is primarily intended
     for creation idempotence and configuration definition. Cannot be updated.
     More info: http://kubernetes.io/docs/user-guide/identifiers#names

   namespace    <string>
   #名称空间
     Namespace defines the space within which each name must be unique. An empty
     namespace is equivalent to the "default" namespace, but "default" is the
     canonical representation. Not all objects are required to be scoped to a
     namespace - the value of this field for those objects will be empty.

     Must be a DNS_LABEL. Cannot be updated. More info:
     http://kubernetes.io/docs/user-guide/namespaces
     
     #其他没用的删掉了
     

最主要的是spec

root@k8s-master1:/apps/ingress# kubectl explain Ingress.spec
KIND:     Ingress
VERSION:  networking.k8s.io/v1

RESOURCE: spec <Object>

DESCRIPTION:
     Spec is the desired state of the Ingress. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

     IngressSpec describes the Ingress the user wishes to exist.

FIELDS:
   defaultBackend       <Object>
     DefaultBackend is the backend that should handle requests that don't match
     any rule. If Rules are not specified, DefaultBackend must be specified. If
     DefaultBackend is not set, the handling of requests that do not match any
     of the rules will be up to the Ingress controller.

   ingressClassName     <string>
   #使用的 Ingress 类的名称  这个在1.22以上版本必须写 ,我们现在用的1.21 写不写无所谓
     IngressClassName is the name of the IngressClass cluster resource. The
     associated IngressClass defines which controller will implement the
     resource. This replaces the deprecated `kubernetes.io/ingress.class`
     annotation. For backwards compatibility, when that annotation is set, it
     must be given precedence over this field. The controller may emit a warning
     if the field and annotation have different values. Implementations of this
     API should ignore Ingresses without a class specified. An IngressClass
     resource may be marked as default, which can be used to set a default value
     for this field. For more information, refer to the IngressClass
     documentation.

   rules        <[]Object>
   #规则  
   #就是nginx 里面虚拟主机server {  这些东西
   
   #}
   
     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>
   #如果域名是https的 用这个
     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.
root@k8s-master1:~# kubectl explain ingress.spec.rules
KIND:     Ingress
VERSION:  networking.k8s.io/v1

RESOURCE: rules <[]Object> #列表 说明可以写多个  一个host的就类似一个虚拟主机

DESCRIPTION:
     A list of host rules used to configure the Ingress. If unspecified, or no
     rule matches, all traffic is sent to the default backend.

     IngressRule represents the rules mapping the paths under a specified host
     to the related backend services. Incoming requests are first evaluated for
     a host match, then routed to the backend associated with the matching
     IngressRuleValue.

FIELDS:
   host <string>
   #这个就是虚拟主机里的hostname  就是定义一个可以解析的域名
     Host is the fully qualified domain name of a network host, as defined by
     RFC 3986. Note the following deviations from the "host" part of the URI as
     defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue
     can only apply to the IP in the Spec of the parent Ingress.
     2. The `:` delimiter is not respected because ports are not allowed.
     Currently the port of an Ingress is implicitly :80 for http and :443 for
     https. Both these may change in the future. Incoming requests are matched
     against the host before the IngressRuleValue. If the host is unspecified,
     the Ingress routes all traffic based on the specified IngressRuleValue.

     Host can be "precise" which is a domain name without the terminating dot of
     a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name
     prefixed with a single wildcard label (e.g. "*.foo.com"). The wildcard
     character '*' must appear by itself as the first DNS label and matches only
     a single label. You cannot have a wildcard label by itself (e.g. Host ==
     "*"). Requests will be matched against the Host field in the following way:
     1. If Host is precise, the request matches this rule if the http host
     header is equal to Host. 2. If Host is a wildcard, then the request matches
     this rule if the http host header is to equal to the suffix (removing the
     first label) of the wildcard rule.

   http <Object>
   #所使用的服务
root@k8s-master1:~# kubectl explain ingress.spec.rules.http
KIND:     Ingress
VERSION:  networking.k8s.io/v1

RESOURCE: http <Object>

DESCRIPTION:

     HTTPIngressRuleValue is a list of http selectors pointing to backends. In
     the example: http://<host>/<path>?<searchpart> -> backend where where parts
     of the url correspond to RFC 3986, this resource will be used to match
     against everything after the last '/' and before the first '?' or '#'.

FIELDS:
   paths        <[]Object> -required-
   #路径 继续
     A collection of paths that map requests to backends.
root@k8s-master1:~# kubectl explain ingress.spec.rules.http.paths
KIND:     Ingress
VERSION:  networking.k8s.io/v1

RESOURCE: paths <[]Object>

DESCRIPTION:
     A collection of paths that map requests to backends.

     HTTPIngressPath associates a path with a backend. Incoming urls matching
     the path are forwarded to the backend.

FIELDS:
   backend      <Object> -required-
   #后端  他的后面就是service
   #定义将流量转发的service
     Backend defines the referenced service endpoint to which the traffic will
     be forwarded to.

   path <string>
   #路径  访问的路径  如果你是/ 那就写/  相当于location /
     Path is matched against the path of an incoming request. Currently it can
     contain characters disallowed from the conventional "path" part of a URL as
     defined by RFC 3986. Paths must begin with a '/'. When unspecified, all
     paths from incoming requests are matched.

   pathType     <string>
   #路径的模式 有三选项 ImplementationSpecific 和 Prefix和 Exact
   #Exact:精确匹配请求路径。如果请求路径与 Ingress 规则中的路径完全匹配,则匹配成功。
   #Prefix:基于路径前缀进行匹配。路径前缀是将请求路径按照斜杠(/)分割得到的一组标签。匹配是按照路径元素逐个进行的。如果请求路径中的每个元素都是 Ingress 规则中路径的前缀,则匹配成功。注意,如果请求路径的最后一个元素是请求路径的最后一个元素的子字符串,则不匹配(例如,/foo/bar 匹配 /foo/bar/baz,但不匹配 /foo/barbaz)。
   #ImplementationSpecific:路径匹配的实现方式由 IngressClass 决定。实现可以将其视为与 Prefix 或 Exact 类型相同的单独 PathType,或者将其视为与 Exact 类型相同的实现。实现必须支持所有路径类型。
     PathType determines the interpretation of the Path matching. PathType can
     be one of the following values: * Exact: Matches the URL path exactly. *
     Prefix: Matches based on a URL path prefix split by '/'. Matching is done
     on a path element by element basis. A path element refers is the list of
     labels in the path split by the '/' separator. A request is a match for
     path p if every p is an element-wise prefix of p of the request path. Note
     that if the last element of the path is a substring of the last element in
     request path, it is not a match (e.g. /foo/bar matches /foo/bar/baz, but
     does not match /foo/barbaz).
     * ImplementationSpecific: Interpretation of the Path matching is up to the
     IngressClass. Implementations can treat this as a separate PathType or
     treat it identically to Prefix or Exact path types. Implementations are
     required to support all path types.

写一个

root@k8s-master1:~# kubectl explain ingress.spec.rules.http.paths.backend
KIND:     Ingress
VERSION:  networking.k8s.io/v1

RESOURCE: backend <Object>

DESCRIPTION:
     Backend defines the referenced service endpoint to which the traffic will
     be forwarded to.

     IngressBackend describes all endpoints for a given service and port.

FIELDS:
   resource     <Object>
     Resource is an ObjectRef to another Kubernetes resource in the namespace of
     the Ingress object. If resource is specified, a service.Name and
     service.Port must not be specified. This is a mutually exclusive setting
     with "Service".

   service      <Object>
   #service 的名字
   #这个service  理解成nginx的upstream 的定义的组名  
     Service references a Service as a Backend. This is a mutually exclusive
     setting with "Resource".

root@k8s-master1:/apps/ingress# cat ingress-1.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-test
  namespace: test-ingress
spec:
  rules:
  - host: www.guoguo.com
    http:
    - paths:
      - backend:
        service:
          name: nginx
          port: 80
        path: /
        pathType: ImplementationSpecific

已经创建出来了

root@k8s-master1:/apps/ingress# kubectl get ingress -n test-ingress -o wide
NAME            CLASS   HOSTS             ADDRESS   PORTS   AGE
ingress-test    nginx   www.guoguo.com              80      15h

看下pod所在的node节点

root@k8s-master1:/apps/ingress# kubectl get pods -n test-ingress  -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP            NODE                 
nginx-bc4d69dd6-c5tzm   1/1     Running   3          35h   10.244.2.16   k8s-node2.guoguo.com

然后加个hosts

root@k8s-master1:/apps/ingress# echo "172.17.18.12 www.guoguo.com" >> /etc/hosts

访问一下

root@k8s-master1:/apps/ingress# curl www.guoguo.com
VERSION:NGINX:1.22.1-www.guoguo.com:dir_/data/web/dir1/index.html

然后我们去宿主机也可以访问到

172.17.18.12 www.guoguo.com

将这条内容添加到下面hosts文件里面

C:\Windows\System32\drivers\etc\hosts

我用浏览器访问一直访问不到,可能因为杀毒软件的原因,然后我用Windows 的cmd可以访问的

Kubernetes 入口 Ingress-NGINX_NGINX_04

Kubernetes 入口 Ingress-NGINX_Ingress_05

浏览器也可以了

这就是Ingress,如果172.17.18.12 是个公网地址或者我们有公网地址 通过LVS或者NGINX就可以被访问了

这就是生产级别使用最多的方式

这是个简单的例子

继续!

其实Ingress和NGINX的一些规则都是差不多的

比如nginx里面有rewrite地址重写 Ingress也有 不过叫Redirect

ingress NGINX 域名重定向 Redirect

ingress好多功能是通过资源注解的方式来实现的

资源注解在

root@k8s-master1:/apps/ingress# kubectl explain ingress.metadata
KIND:     Ingress
VERSION:  networking.k8s.io/v1

RESOURCE: metadata <Object>

DESCRIPTION:
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

     ObjectMeta is metadata that all persisted resources must have, which
     includes all objects users must create.

FIELDS:
   annotations  <map[string]string>
   #资源注解
     Annotations is an unstructured key value map stored with a resource that
     may be set by external tools to store and retrieve arbitrary metadata. They
     are not queryable and should be preserved when modifying objects. More
     info: http://kubernetes.io/docs/user-guide/annotations

   labels       <map[string]string>
     Map of string keys and values that can be used to organize and categorize
     (scope and select) objects. May match selectors of replication controllers
     and services. More info: http://kubernetes.io/docs/user-guide/labels

   name <string>
     Name must be unique within a namespace. Is required when creating
     resources, although some resources may allow a client to request the
     generation of an appropriate name automatically. Name is primarily intended
     for creation idempotence and configuration definition. Cannot be updated.
     More info: http://kubernetes.io/docs/user-guide/identifiers#names

   namespace    <string>
     Namespace defines the space within which each name must be unique. An empty
     namespace is equivalent to the "default" namespace, but "default" is the
     canonical representation. Not all objects are required to be scoped to a
     namespace - the value of this field for those objects will be empty.

     Must be a DNS_LABEL. Cannot be updated. More info:
     http://kubernetes.io/docs/user-guide/namespaces
root@k8s-master1:/apps/ingress# kubectl explain ingress.metadata.annotations
KIND:     Ingress
VERSION:  networking.k8s.io/v1

FIELD:    annotations <map[string]string>

DESCRIPTION:
     Annotations is an unstructured key value map stored with a resource that
     may be set by external tools to store and retrieve arbitrary metadata. They
     are not queryable and should be preserved when modifying objects. More
     info: http://kubernetes.io/docs/user-guide/annotations
    

Redirect和nginx的rewrite 一样,比如访问abc.com被重定向到123.com

写一个


root@k8s-master1:/apps/ingress# cat ingress-2.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-test2
  namespace: test-ingress
  annotations:  #资源注解
    nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
    #就加这么一条内容                               #跳转到一个可以访问的域名
spec:
  rules:
  - host: test.guoguo.com  #当访问这个域名的 /时 跳转到百度
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific


Kubernetes 入口 Ingress-NGINX_Ingress_06

之前讲NGINX 有反向代理把对应的域名除了一些静态的web资源还有一些跳转到后端的某一个服务上去,事实上这就是前后端分离,这里面前后端分离叫Rewrite,之前前后端分离叫伪静态,用法可以理解为前后端分离的方式

创建一个

root@k8s-master1:/apps/ingress# cat pod-test-tomcat.yaml
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
  namespace: test-ingress
spec:
  type: ClusterIP
  selector:
    app: tomcat
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-dep
  namespace: test-ingress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
         app: tomcat
    spec:
      containers:
      - name: tomcat
        image: images.guoguo.com/apps/tomcat:v1
        ports:
        - containerPort: 8080

pod里面修改下

[root@tomcat-dep-7fbb5bdfb7-55tcf app]# cat /apps/tomcat/webapps/app/index.html
tomcat

这样我们访问IP/app/inde.html 就能访问到这里了

root@k8s-master1:/apps/ingress# kubectl get svc -n test-ingress
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
tomcat-svc   ClusterIP   10.103.248.18   <none>        80/TCP    13m
root@k8s-master1:/apps/ingress# curl 10.103.248.18/app/index.html
tomcat

这样就可以了

然后我们去创建ingress

ingress-nginx Rewrite 里面 支持正则


root@k8s-master1:/apps/ingress# cat ingress-4.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tomcat-rewrite
  namespace: test-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    #地址重写 
spec:
  rules:
  - host: rewrite.guoguo.com
    http:
      paths:
      - path: /app(/|$)(.*)
      #/app(/|$) 匹配 ingress 接收到的请求路径,其中 /app 是必须匹配的,后面(.+)匹配任意路径。
      #就是我访问app下任意内容 “.”什么结尾的 直接访问的 是/app/$2 这个$2是我们输入的/apps后的内容
      #就是相当于我把第一个小括号内容给删了  
      #比如访问 rewrite.guoguo.com/apps或者访问的是 rewrite.guoguo.com/apps/index.html
      #访问的是 rewrite.guoguo.com  rewrite.guoguo.com/index.html
        pathType: ImplementationSpecific
        backend:
          service:
            name: tomcat-svc
            port:
              number: 80

IngressNGINX错误代码重定向

修改 values.yaml 如下图所示位置:

root@k8s-master1:/apps/ingress# vim /apps/ingress-nginx/values.yaml

680 defaultBackend:
681   ##
682   enabled: false   #改为 true
683
684   name: defaultbackend
685   image:
686     registry: images.guoguo.com
687     image: ingress-nginx/defaultbackend-amd64 #就是访问错误地址 给重定向到这个镜像启动的pod里面


###改为


680 defaultBackend:
681   ##
682   enabled: true
683
684   name: defaultbackend
685   image:
686     registry: images.guoguo.com
687     image: ingress-nginx/defaultbackend-amd64

##########
 35
 36   # Will add custom configuration options to Nginx https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/
 37   config: {}
 38
 39   ## Annotations to be added to the controller config configuration configmap
 40   ##

#################改为

 35
 36   # Will add custom configuration options to Nginx https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/
 37   config:
 38     apiVersion: v1
 39     client_max_body_size: 20m
 40     custom-http-errors: "404,415,503"
 41
 42   ## Annotations to be added to the controller config configuration configmap

然后更新一下ingress

root@k8s-master1:/apps/ingress# cd /apps/ingress-nginx/
root@k8s-master1:/apps/ingress-nginx# helm upgrade ingress-nginx -n ingress-nginx .
root@k8s-master1:/apps/ingress-nginx# kubectl get pods -n ingress-nginx
NAME                                            READY   STATUS    RESTARTS   AGE
ingress-nginx-controller-rl2ds                  1/1     Running   0          17s
ingress-nginx-defaultbackend-7d46ddfb6f-kq7b6   1/1     Running   0          35s

给我们创建一个pod

root@k8s-master1:/apps/ingress-nginx# curl rewrite.guoguo.com
default backend - 404root@k8s-master1:/apps/ingress-nginx#
#就这块↑
#访问一个错误的地址 反馈的错误代码

Ingress NGINX SSL HTTPS

生产环境对外的服务, 一般需要配置 https 协议,使用 Ingress 也可以非常方便的添加 https 的证书。

由于我们是学习环境, 并没有权威证书,所以需要使用 OpenSSL 生成一个测试证书。如果 是生产环境,证书为在第三方公司购买的证书,无需自行生成:

#找个目录
root@k8s-master1:/apps/secrets# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=test.guoguo.com"
Can't load /root/.rnd into RNG
139872370074048:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/root/.rnd
Generating a RSA private key
..............................................................................+++++
.......+++++
writing new private key to 'tls.key'
-----
#然后创建secret
root@k8s-master1:/apps/secrets# kubectl create secret tls tls-web-secret --key=tls.key --cert=tls.crt -n test-ingress
secret/tls-web-secret created

将secret给Ingress来使用


root@k8s-master1:/apps/secrets# kubectl explain ingress.spec.tls
KIND:     Ingress
VERSION:  networking.k8s.io/v1

RESOURCE: tls <[]Object>

DESCRIPTION:
     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.

     IngressTLS describes the transport layer security associated with an
     Ingress.

FIELDS:
   hosts        <[]string>
   #域名
     Hosts are a list of hosts included in the TLS certificate. The values in
     this list must match the name/s used in the tlsSecret. Defaults to the
     wildcard host setting for the loadbalancer controller fulfilling this
     Ingress, if left unspecified.

   secretName   <string>
   #secret的名字
     SecretName is the name of the secret used to terminate TLS traffic on port
     443. Field is left optional to allow TLS routing based on SNI hostname
     alone. If the SNI host in a listener conflicts with the "Host" header field
     used by an IngressRule, the SNI host is used for termination and value of
     the Host header is used for routing.

写一个

root@k8s-master1:/apps/ingress# cat ingress-5.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ssl
  namespace: test-ingress
spec:
  rules:
  - host: test.guoguo.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: tomcat-svc
            port:
              number: 80
  tls:
  - hosts:
    - test.guoguo.com
    secretName: tls-web-secret
root@k8s-master1:/apps/ingress# kubectl get ingress -n test-ingress
NAME   CLASS   HOSTS             ADDRESS   PORTS     AGE
ssl    nginx   test.guoguo.com             80, 443   72s

因为我宿主机装了奇安信,这家伙权限贼高,不让修改hosts文件,我安装了个桌面版centos 访问的

Kubernetes 入口 Ingress-NGINX_Ingress_07

Ingress NGINX基本认证

就是和nginx一样,需要加用户密码验证才能访问

装个apache2 然后生成用户密码文件

然后添加到secret 然后给ingress用就ok了

安装apache

root@k8s-master1:/apps/ingress# apt -y install apche2

root@k8s-master1:/apps/ingress# htpasswd -c auth user1
New password:
Re-type new password:
Adding password for user user1

root@k8s-master1:/apps/ingress# ll
total 44
drwxr-xr-x  2 root root 4096 Sep 22 13:15 ./
drwxr-xr-x 10 root root 4096 Sep 22 11:01 ../
-rw-r--r--  1 root root   44 Sep 22 13:15 auth
root@k8s-master1:/apps/ingress# cat auth
user1:$apr1$xNQdj4gm$H5JbFYv1dqz.a.2TVPwci1

基于auth用户文件创建secret

root@k8s-master1:/apps/ingress# kubectl create secret generic basic-auth --from-file=./auth -n test-ingress
secret/basic-auth created


#类型通用 就存储密码和口令的 通用就可以  generic
# basic-auth secret的名字

然后创建ingress 引用 这个secret

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: auth
  namespace: test-ingress
  annotations:
    kubernetes.io/ingress.class: nginx  #class类nginx
    nginx.ingress.kubernetes.io/auth-realm: Please Input Your Username adn Password 
                                    ##这个是输入用户口令显示的内容 可自定义
    nginx.ingress.kubernetes.io/auth-secret: basic-auth #使用的secrets
    nginx.ingress.kubernetes.io/auth-type: basic  #secret类型是通用 basic
spec:
  rules:
  - host: auth.guoguo.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: tomcat-svc
            port:
              number: 80


Kubernetes 入口 Ingress-NGINX_Ingress_08

ngress NGINX 配置黑名单白名单

root@k8s-master1:/apps/ingress-nginx# vim /apps/ingress-nginx/values.yaml
#里面 在config字段 加如黑名单 block-cidrs: 172.17.0.5 禁止这个ip访问 nginx-ingress的所有域名
 37   config:
 38     apiVersion: v1
 39     client_max_body_size: 20m
 40     custom-http-errors: "404,415,503"
       #在这加黑名单 如下面
 37   config:
 38     apiVersion: v1
 39     client_max_body_size: 20m
 40     custom-http-errors: "404,415,503"
 41     block-cidrs: 172.17.0.5

       

更新配置

root@k8s-master1:/apps/ingress-nginx# helm upgrade ingress-nginx -n ingress-nginx .

Kubernetes 入口 Ingress-NGINX_Ingress_09

然后就访问不了了

然后我们去除黑名单 更新 继续

Ingress NGINX 白名单

白名单需要在配置清单里面加

如果加了白名单,那么只允许白名单里面的访问,其他均不可访问

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: auth
  namespace: test-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/auth-realm: Please Input Your Username adn Password
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/whitelist-source-range: 172.17.0.5
     #这条就是白名单 只允许白名单访问 其他都拒绝
spec:
  rules:
  - host: auth.guoguo.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: tomcat-svc
            port:
              number: 80


Kubernetes 入口 Ingress-NGINX_Ingress_10

Kubernetes 入口 Ingress-NGINX_Ingress_11

很多地方都可以用到白名单,比如关于数据库的连接访问,再就是公司内部的网段,只能允许公司内部访问

Ingress NGINX速率限制

有时候可能需要限制速率以降低后端压力, 或者限制单个 IP 每秒的访问速率防止攻击。 此 时可以使用Nginx 的 rate limit 进行配置

如果是个下载服务器,需要做速率限制,如果不做,一个人来下载就把带宽占满了

添加速率限制 , 限制只能有一个连接,只需要添加 nginx.ingress.kubernetes.io/limit-connections 为 1 即可:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: auth
  namespace: test-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/auth-realm: Please Input Your Username adn Password
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/whitelist-source-range: 172.17.0.5
    nginx.ingress.kubernetes.io/limit-connections: "1"
spec:
  rules:
  - host: auth.guoguo.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: tomcat-svc
            port:
              number: 80

继续

金丝雀发布

使用NGINX实现灰度/金丝雀发布

金丝雀发布和灰度发布是软件部署和发布的两种策略,旨在减少潜在的风险,测试新功能,并确保系统的稳定性。它们在软件开发和运维中有广泛的应用。

金丝雀发布(Canary Release)是一种软件发布策略,旨在减少潜在风险和问题,并逐步引入新版本的功能或代码。金丝雀发布的核心思想是逐步将新版本部署给一小部分用户或服务器,然后根据反馈和性能指标决定是否继续将新版本推广给更广泛的用户群体。以下是金丝雀发布的关键特点和步骤:

  1. 逐步增加流量:金丝雀发布从部署新版本的应用程序或服务开始,但只将一小部分流量引导到新版本上,通常是一个很小的百分比(例如,1%)。这意味着只有少数用户或服务器会受到新版本的影响。
  2. 监控和度量:在金丝雀发布期间,团队密切监控新版本的性能、稳定性和可用性。这包括使用指标和日志来追踪任何异常情况。
  3. 用户反馈:团队收集用户反馈,以了解他们对新功能或变化的看法。用户的反馈可以帮助识别潜在问题,并进行进一步的改进。
  4. 自动化回滚:如果在金丝雀发布期间发现了严重的问题或性能下降,团队可以快速回滚到稳定的旧版本,以减少对用户的不利影响。
  5. 逐步扩展:如果新版本在小范围内证明稳定和可靠,团队可以逐步增加新版本的流量份额,例如增加到5%、10%等,直到最终将新版本推广给全部用户或服务器。
  6. 持续反馈和优化:金丝雀发布过程通常是持续的,团队会不断收集反馈并进行优化,以确保新版本的质量。

金丝雀发布的优点包括:

  • 早期问题检测:通过逐步引入新版本,可以更早地检测到潜在问题,减少了对整个用户群体的影响。
  • 降低风险:如果新版本导致问题,可以快速回滚,减少了风险。
  • 收集用户反馈:可以从一小部分用户那里获得有价值的反馈,以改进新功能或变化。

金丝雀发布通常用于大型、复杂或关键的应用程序,以确保新版本的稳定性和性能,同时最小化潜在的故障。它需要仔细规划、自动化和监控,以确保顺利执行。

灰度发布(Gray Release),也称为渐进式发布,是一种软件发布策略,用于逐渐引入新版本的功能或代码到生产环境,以减少潜在的风险并确保系统的稳定性。灰度发布的核心思想是将新版本逐渐推送到不同的用户群体或服务器上,然后根据反馈和性能指标逐步增加新版本的范围。以下是灰度发布的关键特点和步骤:

  1. 分阶段发布:灰度发布从将新版本部署到一小部分用户或服务器开始,通常是一个低百分比(例如,5%)或一个特定的地理区域。
  2. 版本控制:使用流量管理工具或负载均衡器,将用户的请求定向到新版本或旧版本的应用程序中,这可以按照特定的策略来控制。
  3. 监控和度量:在灰度发布期间,团队密切监控新版本和旧版本的性能、稳定性和可用性。这包括使用指标和日志来追踪任何异常情况。
  4. 用户反馈:团队收集用户反馈,以了解他们对新功能或变化的看法。用户的反馈可以帮助识别潜在问题,并进行进一步的改进。
  5. 自动化回滚:如果在灰度发布期间发现了严重的问题或性能下降,团队可以快速回滚到稳定的旧版本,以减少对用户的不利影响。
  6. 逐步扩展:如果新版本在小范围内证明稳定和可靠,团队可以逐步增加新版本的范围,例如增加到10%、25%、50%等,直到最终将新版本推广给全部用户或服务器。
  7. 持续反馈和优化:灰度发布过程通常是持续的,团队会不断收集反馈并进行优化,以确保新版本的质量。

灰度发布的优点包括:

  • 逐步减小风险:通过逐步引入新版本,可以逐渐减小风险,确保新功能或变化不会对整个用户群体产生负面影响。
  • 更好的用户体验:可以获得一部分用户的实际反馈,以改进新功能或变化,以便提供更好的用户体验。
  • 高度可控性:可以根据需要灵活控制新版本的部署范围和速度。

灰度发布通常适用于大型、复杂或关键的应用程序,以确保新版本的稳定性和性能。它需要仔细规划、自动化和监控,以确保成功执行。此外,它也可以用于逐渐将新功能引入A/B测试中,以帮助决策制定者评估不同功能的效果。

开始 在互联网上发版: 比如现在版本是v1.0版本,现在需要更新,更新成v1.1 比如现在有5个 都是1.0版本,现在为了防止有问题,先升级一个为1.1版本,这个已经升级的1.1版本类似一个金丝雀,功能主要是去发现问题的,当前就一个版本和其他版本不一样,这个起到金丝雀作用,然后给这个1.1版本转给它一部分流量,根据比例给他转百分之10流量,这个机器如果有问题,那么这百分之10的请求就有问题,如果有问题,那其他机器的版本就不发布了,然后将这个金丝雀的1.1回退到1.0,如果1.1没有问题,那么全部都发1.1版本,这个叫金丝雀发布或者叫灰度发布

Kubernetes 入口 Ingress-NGINX_NGINX_12

还一个概念蓝绿发布

蓝绿发布

蓝绿发布比较好,但是浪费资源,比如我现在有两套完整的环境,有五台机器跑1.0 ,生产用被称为蓝。还有另外一模一样的环境5台也是跑1.0.成为绿,现在生产用的蓝,然后我现在把绿5台机器1.0全部发布1.1 这时候内部人员先测试,没问题后,然后生产不挂在蓝色,挂载绿色1.1版本。通常情况我们运行一天没问题,然后把蓝五台发版1.1,或者一直不发版也行,下次在升级1.2的时候就把蓝五台直接升1.2,然后再测试,然后再切换蓝

蓝绿发布同一时间在线一套环境,但是有两套完整的环境。一主一备的作用

蓝绿最简单,但是浪费机器,耗钱

一般生产上核心做蓝绿,非核心做灰度

蓝绿稳定性高

用Ingress实现灰度发布

先创建个ns 都放到这个ns里面 production 生产的意思

root@k8s-master1:/apps/ingress/new# kubectl create ns production
namespace/production created

在创建个svc

root@k8s-master1:/apps/ingress/new/svc# cat svc-production-1.yaml
apiVersion: v1
kind: Service
metadata:
  name: production-svc
  namespace: production
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80

然后创建deployment

我们用nginx的版本 1.22.1和1.24.0 来区别版本

root@k8s-master1:/apps/ingress/new/deployment# cat deployment-1.22.1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: production
  name: pod-1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: images.guoguo.com/apps/nginx:1.22.1
        ports:
        - containerPort: 80

然后创建ingress

root@k8s-master1:/apps/ingress/new/ingress# cat ingress-1.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-1
  namespace: production
spec:
  rules:
  - host: web.guoguo.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: production-svc
            port:
              number: 80

然后创建灰度版本

先创建ns

root@k8s-master1:/apps/ingress/new# kubectl create ns grayscale
namespace/grayscale created

创建svc

root@k8s-master1:/apps/ingress/new/svc# cat svc-production-2.yaml
apiVersion: v1
kind: Service
metadata:
  name: grayscale-svc
  namespace: grayscale
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80

然后再创建deployment

root@k8s-master1:/apps/ingress/new/deployment# cat deployment-1.24.0.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: grayscale
  name: pod-2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: images.guoguo.com/apps/nginx:1.24.0
        ports:
        - containerPort: 80

测一下

root@k8s-master1:/apps/ingress/new# kubectl get svc -n grayscale
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
grayscale-svc   ClusterIP   10.100.54.67   <none>        80/TCP    2m11s
root@k8s-master1:/apps/ingress/new# curl 10.100.54.67
VERSION:NGINX:1.24.0
root@k8s-master1:/apps/ingress/new# kubectl get svc -n production
NAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
production-svc   ClusterIP   10.99.94.125   <none>        80/TCP    54m
root@k8s-master1:/apps/ingress/new# curl 10.99.94.125
VERSION:NGINX:1.22.1

创建ingress

root@k8s-master1:/apps/ingress/new/ingress# cat ingress-2.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-2
  namespace: grayscale
  annotations:
    kubernetes.io/ingress.class: nginx         # class类
    nginx.ingress.kubernetes.io/canary: "true"  #使用灰度为真
    nginx.ingress.kubernetes.io/canary-weight: "10"  #给灰度发 百分之10流量
spec:
  rules:
  - host: web.guoguo.com  #域名要求一样
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: grayscalen-svc #指定灰度的svc
            port:
              number: 80

测试一下

root@k8s-master1:/apps/ingress/new/ingress# for i in  `seq 10` ;do curl web.guoguo.com; done
VERSION:NGINX:1.22.1
VERSION:NGINX:1.22.1
VERSION:NGINX:1.22.1
VERSION:NGINX:1.22.1
VERSION:NGINX:1.22.1
VERSION:NGINX:1.22.1
VERSION:NGINX:1.24.0  # 这里就是 灰度
VERSION:NGINX:1.22.1
VERSION:NGINX:1.22.1
VERSION:NGINX:1.22.1

这就可以做到灰度了!

如果最终没有测试没问题,就可以把所有应用发布就可以了

蓝绿比较简单,蓝绿做两套一模一样的,然后做个svc对应标签就可以了,改成不同的标签对应的不同deployment