hello云胜

技术与生活

0%

Kubesphere问题

1,联邦添加新集群后,用户权限不同步

image-20220519175256746

临时解决

1
kubectl -n kube-federation-system rollout restart deployment kubefed-admission-webhook
1
kubectl -n kube-federation-system rollout restart deployment kubefed-controller-manager

2.devops流水线中配置maven为私服image-20220523161532297

K8S网络组件

网络组建解决的问题,将不同节点上的Docker容器之间的互相访问先打通,使整个k8s集群互通。

目前已经有多个开源组件支持容器网络模型。本节介绍几个常见的网络组件及其安装配置方法,包括Flannel、Open vSwitch、直接路由和Calico。

Docker的网络模型

默认的Docker网络模型提供了一个IP地址段是172.17.0.0/16的docker0网桥。每个容器都会在这个子网内获得IP地址,并且将docker0网桥的IP地址(172.17.42.1)作为其默认网关。

使用ifconfig看一下

1
2
3
4
5
6
7
8
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:a4:46:17:9a txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

需要注意的是,Docker宿主机外面的网络不需要知道任何关于这个172.17.0.0/16的信息或者知道如何连接到其内部,因为Docker的宿主机针对容器发出的数据,在物理网卡地址后面都做了IP伪装MASQUERADE(隐含NAT)。也就是说,在网络上看到的任何容器数据流都来源于那台Docker节点的物理IP地址。这里所说的网络都指连接这些主机的物理网络。

这个模型便于使用,但是并不完美,需要依赖端口映射的机制。

在Kubernetes的网络模型中,每台主机上的docker0网桥都是可以被路由到的。也就是说,在部署了一个Pod时,在同一个集群内,各主机都可以访问其他主机上的Pod IP,并不需要在主机上做端口映射。

也就是说k8s的网络组建做了这层路由功能。

Flannel

Flannel之所以可以搭建Kubernetes依赖的底层网络,是因为它能实现以下两点。
(1)它能协助Kubernetes,给每一个Node上的Docker容器都分配互相不冲突的IP地址。
(2)它能在这些IP地址之间建立一个覆盖网络(Overlay Network),通过这个覆盖网络,将数据包原封不动地传递到目标容器内。

现在,通过下图来看看Flannel是如何实现这两点的。

img

可以看到,Flannel首先创建了一个名为flannel0的网桥,而且这个网桥的一端连接docker0网桥,另一端连接一个叫作flanneld的服务进程。

flanneld进程并不简单,它上连etcd,利用etcd来管理可分配的IP地址段资源,同时监控etcd中每个Pod的实际地址,并在内存中建立了一个Pod节点路由表;它下连docker0和物理网络,使用内存中的Pod节点路由表,将docker0发给它的数据包包装起来,利用物理网络的连接将数据包投递到目标flanneld上,从而完成Pod到Pod之间的直接地址通信。
Flannel之间的底层通信协议的可选技术包括UDP、VxLan、AWS VPC等多种方式。通过源flanneld封包、目标flanneld解包,最终docker0收到的就是原始的数据,对容器应用来说是透明的,感觉不到中间Flannel的存在。

我们看一下Flannel是如何做到为不同Node上的Pod分配的IP不产生冲突的。其实想到Flannel使用了集中的etcd存储就很容易理解了。它每次分配的地址段都在同一个公共区域获取,这样大家自然能够互相协调,不产生冲突了。而且在Flannel分配好地址段后,后面的事情是由Docker完成的,Flannel通过修改Docker的启动参数将分配给它的地址段传递进去:

–bip 172.17.18.1/24
通过这些操作,Flannel就控制了每个Node上的docker0地址段的地址,也就保障了所有Pod的IP地址在同一个水平网络中且不产生冲突了。

Flannel完美地实现了对Kubernetes网络的支持,但是它引入了多个网络组件,在网络通信时需要转到flannel0网络接口,再转到用户态的flanneld程序,到对端后还需要走这个过程的反过程,所以也会引入一些网络的时延损耗。

另外,Flannel模型默认采用了UDP作为底层传输协议,UDP本身是非可靠协议,虽然两端的TCP实现了可靠传输,但在大流量、高并发的应用场景下还需要反复测试,确保没有问题。

Open vSwitch

​ 在了解了Flannel后,我们再看看Open vSwitch是怎么解决上述两个问题的。
​ Open vSwitch是一个开源的虚拟交换机软件,有点儿像Linux中的bridge,但是功能要复杂得多。Open vSwitch的网桥可以直接建立多种通信通道(隧道),例如Open vSwitch with GRE/VxLAN。这些通道的建立可以很容易地通过OVS的配置命令实现。在Kubernetes、Docker场景下,我们主要是建立L3到L3的隧道。举个例子来看看Open vSwitch with GRE/VxLAN的网络架构如下图:

img

首先,为了避免Docker创建的docker0地址产生冲突(因为Docker Daemon启动且给docker0选择子网地址时只有几个备选列表,很容易产生冲突),我们可以将docker0网桥删除,手动建立一个Linux网桥,然后手动给这个网桥配置IP地址范围。
其次,建立Open vSwitch的网桥ovs,使用ovs-vsctl命令给ovs网桥增加gre端口,在添加gre端口时要将目标连接的NodeIP地址设置为对端的IP地址。对每一个对端IP地址都需要这么操作(对于大型集群网络,这可是个体力活,要做自动化脚本来完成)。
最后,将ovs的网桥作为网络接口,加入Docker的网桥上(docker0或者自己手工建立的新网桥)。
重启ovs网桥和Docker的网桥,并添加一个Docker的地址段到Docker网桥的路由规则项,就可以将两个容器的网络连接起来了。

1.网络通信过程

当容器内的应用访问另一个容器的地址时,数据包会通过容器内的默认路由发送给docker0网桥。ovs的网桥是作为docker0网桥的端口存在的,它会将数据发送给ovs网桥。ovs网络已经通过配置建立了和其他ovs网桥的GRE/VxLAN隧道,自然能将数据送达对端的Node,并送往docker0及Pod。
通过新增的路由项,Node本身的应用数据也被路由到docker0网桥上,和刚才的通信过程一样,自然也可以访问其他Node上的Pod。

2.OVS with GRE/VxLAN组网方式的特点

OVS的优势是,作为开源虚拟交换机软件,它相对成熟和稳定,而且支持各类网络隧道协议,通过了OpenStack等项目的考验。

另一方面,在前面介绍Flannel时可知,Flannel除了支持建立覆盖网络,保证Pod到Pod的无缝通信,还和Kubernetes、Docker架构体系紧密结合。Flannel能够感知Kubernetes的Service,动态维护自己的路由表,还通过etcd来协助Docker对整个Kubernetes集群中docker0的子网地址分配。而我们在使用OVS时,很多事情就需要手工完成。

无论事OVS还是Flannel,通过覆盖网络提供的Pod到Pod通信都会引入一些额外的通信开销,如果是对网络依赖特别重的应用,则需要评估对业务的影响。

直接路由

我们知道,docker0网桥上的IP地址在Node网络上是看不到的。从一个Node到一个Node内的docker0是不通的,因为它不知道某个IP地址在哪里。如果能够让这些机器知道对端docker0地址在哪里,就可以让这些docker0互相通信了。这样,在所有Node上运行的Pod就都可以互相通信了。

我们可以通过部署MultiLayer Switch(MLS)来实现这一点,在MLS中配置每个docker0子网地址到Node地址的路由项,通过MLS将docker0的IP寻址定向到对应的Node上。
另外,我们可以将这些docker0和Node的匹配关系配置在Linux操作系统的路由项中,这样通信发起的Node就能够根据这些路由信息直接找到目标Pod所在的Node,将数据传输过去。

img

我们在每个Node的路由表中增加对方所有docker0的路由项。

在大规模集群中,在每个Node上都需要配置到其他docker0/Node的路由项,这会带来很大的工作量;并且在新增机器时,对所有Node都需要修改配置;在重启机器时,如果docker0的地址有变化,则也需要修改所有Node的配置,这显然是非常复杂的。

为了管理这些动态变化的docker0地址,动态地让其他Node都感知到它,还可以使用动态路由发现协议来同步这些变化。在运行动态路由发现协议代理的Node时,会将本机LOCAL路由表的IP地址通过组播协议发布出去,同时监听其他Node的组播包。通过这样的信息交换,Node上的路由规则就都能够相互学习。当然,路由发现协议本身还是很复杂的,感兴趣的话,可以查阅相关规范。在实现这些动态路由发现协议的开源软件中,常用的有Quagga(http://www.quagga.net)、Zebra等。

Calico

Calico是一个基于BGP的纯三层的网络方案,与OpenStack、Kubernetes、AWS、GCE等云平台都能够良好地集成。Calico在每个计算节点都利用Linux Kernel实现了一个高效的vRouter来负责数据转发。每个vRouter都通过BGP1协议把在本节点上运行的容器的路由信息向整个Calico网络广播,并自动设置到达其他节点的路由转发规则。Calico保证所有容器之间的数据流量都是通过IP路由的方式完成互联互通的。Calico节点组网时可以直接利用数据中心的网络结构(L2或者L3),不需要额外的NAT、隧道或者Overlay Network,没有额外的封包解包,能够节约CPU运算,提高网络效率。

Calico在小规模集群中可以直接互联,在大规模集群中可以通过额外的BGP route reflector来完成。

此外,Calico基于iptables还提供了丰富的网络策略,实现了Kubernetes的Network Policy策略,提供容器间网络可达性限制的功能。

Calico的系统架构如下图所示:

img

Calico的主要组件如下。

  • Felix:Calico Agent,运行在每个Node上,负责为容器设置网络资源(IP地址、路由规则、iptables规则等),保证跨主机容器网络互通。
  • etcd:Calico使用的后端存储。
  • BGP Client:负责把Felix在各Node上设置的路由信息通过BGP协议广播到Calico网络。
  • Route Reflector:通过一个或者多个BGP Route Reflector来完成大规模集群的分级路由分发。
  • CalicoCtl:Calico命令行管理工具。

IP Pool可以使用两种模式:BGP或IPIP。使用IPIP模式时,设置CALICO_IPV4POOL_IPIP=”always”,不使用IPIP模式时,设置CALICO_IPV4POOL_IPIP=”off”,此时将使用BGP模式。

IPIP是一种将各Node的路由之间做一个tunnel,再把两个网络连接起来的模式,启用IPIP模式时,Calico将在各Node上创建一个名为tunl0的虚拟网络接口。

BGP模式则直接使用物理机作为虚拟路由器(vRouter),不再创建额外的tunnel。

如果使用的是overlay,podip是不能被外界访问到的。

如果没有使用overlay网络,podip能不能被外界访问取决于使用何种CNI网络接口插件

KubeBuilder

问题:

  1. bash: /root/k8s-operator/vm-operator/bin/controller-gen: 没有那个文件或目录

    在kubebuild init之后没有bin目录

    应该是网络原因下载不到controller-gen

    解决:

    自己编译一个,然后放过来

    1
    2
    3
    # git clone https://github.com/kubernetes-sigs/controller-tools.git
    # cd controller-gen
    # go install ./cmd/{controller-gen,type-scaffold}

    编译后的文件在GOPATH的bin目录下

    然后创建bin目录,controller-gen放过去一份

    或者

    修改Makefile文件

    image-20221028174108562

默认的Makefile是找当前目录下的bin目录下

可以修改为自己的controller-gen所在的目录

我是将controller-gen加到了/usr/local/bin下了

K8S的Service实现原理

image-20221206103239718

image-20221206104114920

正是我们的三个pod的ip

image-20221206104154512

所以我们发给service 10.97.36.78:80的请求,就会被IPVS 模块转发到某一个后端 Pod 。

K8S服务的外部访问方式

我们在K8S中部署的服务,访问来源可以分成k8s集群内部和集群外部。集群内部的访问通过clusterIp可以互通。集群外部的访问就略微麻烦一下。有以下几种方式可供选择。NodePort、LoadBalancer和Ingress。

ClusterIp

ClusterIp是K8S的默认服务,会给你的service创建一个集群内的虚拟IP,集群内的其他pod都可以通过该ip访问service。集群外部无法访问。

但是我们可以通过 Kubernetes 的 proxy 模式来访问服务。

原理如图:

img

这种方式是在你本地的电脑上启动kubectl proxy服务。所以只能用于你本地电脑临时性的访问k8s集群内的服务,一般只用于我们临时调试使用。

NodePort

NodePort的原理是在每一台k8s的工作节点上开放一个端口,端口和service进行对应。

img

端口的可选范围是30000-32767。这样就限制了我们的服务数量,但是端口数量基本上是够用的。

外部用户通过工作节点的ip+端口进行访问。

这样做的一个问题是我们将工作节点的ip暴露给了用户。导致后续该机器一旦停机就会造成故障。

LoadBalancer

LoadBalancer 服务是暴露服务到 internet 的标准方式。但是这种方式需要基于与服务商提供的loadBalancer服务,

换言之,要花钱的。

img

Ingress

img

Nginx

看Ingress的工作方式和Nginx非常相似。所以我们也可以在K8S集群中启动Nginx服务进行服务代理。

K8S上部署一个redis

部署单节点redis

使用的镜像是官方的redis:5.0.5-alpine

查看一下镜像,

1
docker inspect redis:5.0.5-alpine

确认一些关键信息

image-20230615110211901

redis确实是官方的redis。

默认的启动命令是redis-server。

工作目录是/data

这些信息可以帮助我们确认,配置文件等重要数据的挂载位置。

附上yaml文件

前提准备

  1. 挂载卷使用pvc,提前创建好storageClass。我是使用nfs作了provisioner
  2. 创建自己的namespace

redis-configmap.yaml

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
namespace: ks-system
data:
redis-config: |
dir /data/data
requirepass HS76afsdb67

redis-pvc.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: ks-system
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: nfs-client
volumeMode: Filesystem

redis-deploy.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ks-system
name: redis
labels:
app: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
volumes:
- name: redis-data
persistentVolumeClaim:
claimName: redis-pvc
- name: config
configMap:
name: redis-config
items:
- key: redis-config
path: redis.conf
containers:
- name: redis
image: redis:5.0.5-alpine
command:
- "sh"
- "-c"
- "redis-server /data/conf/redis.conf"
ports:
- containerPort: 6379
protocol: TCP
resources:
limits:
cpu: "1"
volumeMounts:
- name: redis-data
mountPath: /data/data
- name: config
mountPath: /data/conf

redis-svc.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: ks-system
labels:
app: redis
spec:
type: NodePort
ports:
- name: redis-port
port: 6379
targetPort: 6379
selector:
app: redis

K8S中的资源管理QoS

K8S中的资源管理是通过pod的reources-requests和reources-limits进行的。

首先K8S中的资源分为两类:

  • 可压缩资源。就是cpu这种,特点是当资源不足时,Pod 只会“饥饿”,但不会退出
  • 不可压缩资源,就是内存这种。当内存不足时,Pod 就会因为 OOM(Out-Of-Memory)被内核杀掉

requests & limits

1
2
3
4
5
6
7
8
9
10
11
spec:
containers:
- name: hostnames
image: mirrorgooglecontainers/serve_hostname
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 100Mi

由于 Pod 可以由多个 Container 组成,所以 CPU 和内存资源的限额,是配置在每个Container 的定义上的。这样,Pod 整体的资源配置,就由这些 Container 的配置值累加得到

cpu:100m

指的就是 100 millicpu,也就是 0.1 个 CPU 的意思。这样,这个容器只就会被分配到 1 个 CPU 10%的计算能力

也可以写成 cpu:0.1。 但是推荐100m 的写法,毕竟这才是 Kubernetes 内部通用的 CPU 表示方式

Kubernetes 里为 CPU 设置的单位是“CPU 的个数”。比如,cpu=1 指的就是,这个 Pod 的 CPU 限额是 1 个 CPU。当然,具体“1 个 CPU”在宿主机上如何解释,是 1个 CPU 核心,还是 1 个 vCPU,还是 1 个 CPU 的超线程(Hyperthread),完全取决于宿主机的 CPU 实现方式。Kubernetes 只负责保证 Pod 能够使用到“1 个 CPU”的计算能力

memory: 100Mi

内存的单位这里用的是Mi

Mi和M的区别

1
1Mi=1024*1024;1M=1000*1000

requests & limits的区别

这两者的区别其实非常简单:

在调度的时候,kube-scheduler 是均价 requests 的值进行计算。

而在真正设置 Cgroup参数的时候 kubelet 则会按照 limits 的值来进行设置

也就是requests 是在调度时使用,limit是进行资源限制使用。

QoS级别

根据不同的 requests 和 limits 的设置方式,k8s会将这个 Pod 划分到不同的 QoS 级别当中

Guaranteed 类别 :

Pod 里的每一个 Container 都同时设置了 requests 和 limits,并且 requests 和limits 值相等的时候,k8s会将这个pod的qosClass 字段设置为Guaranteed。

比如上面的例子。

image-20221207142436863

需要注意的是,当 Pod 仅设置了 limits 没有设置 requests 的时候,Kubernetes 会自动为它设置与 limits 相同的 requests 值,所以,这也属于 Guaranteed

Burstable 类别

不满足 Guaranteed类别的条件,还设置了request参数。常见的情况就是request和limit不相等。

BestEffort类别

request和limit参数都没有任何配置,就是BestEffort

区分这三种级别有什么用处呢

当宿主机资源紧张的时候,kubelet 对 Pod 进行Eviction资源回收时需要用到的 。

具体地说,当 Kubernetes 所管理的宿主机上不可压缩资源短缺时,就有可能触发Eviction。比如,可用内存(memory.available)、可用的宿主机磁盘空间。

而当 Eviction 发生的时候,kubelet 具体会挑选哪些 Pod 进行删除操作,就需要参考这些Pod 的 QoS 类别了

首先干掉BestEffort级别的,然后是Burstable 类别 ,最后才是Guaranteed 类别。

绑核cpuset

可以通过设置 cpuset 把容器绑定到某个 CPU 的核上

这种情况下,由于操作系统在 CPU 之间进行上下文切换的次数大大减少,容器里应用的性能会得到大幅提升。

事实上,cpuset 方式,是生产环境里部署在线应用类型的 Pod 时,非常常用的一种方式

听起来很高级,在k8s做到却很简单。只需要两步

  1. Pod 的配置是 Guaranteed 的 QoS 类型
  2. CPU 资源的 requests 和 limits 设置为同一个相等的整数值

比如:

1
2
3
4
5
6
7
resources:
requests:
cpu: 2
memory: 100Mi
limits:
cpu: 2
memory: 100Mi

这时候,该 Pod 就会被绑定在 2 个独占的 CPU 核上。当然,具体是哪两个 CPU 核,是由kubelet 为你分配的。

K8S原始文件

k8s的证书:/etc/kubernetes/pki

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-rw-r--r-- 1 root root 1322 7月  12 2021 apiserver.crt
-rw-r--r-- 1 root root 1094 7月 12 2021 apiserver-etcd-client.crt
-rw-r--r-- 1 root root 1679 7月 12 2021 apiserver-etcd-client.key
-rw-r--r-- 1 root root 1679 7月 12 2021 apiserver.key
-rw-r--r-- 1 root root 1103 7月 12 2021 apiserver-kubelet-client.crt
-rw-r--r-- 1 root root 1675 7月 12 2021 apiserver-kubelet-client.key
-rw-r--r-- 1 root root 1029 7月 12 2021 ca.crt
-rw-r--r-- 1 root root 1679 7月 12 2021 ca.key
drwxr-xr-x 2 root root 4096 7月 12 2021 etcd
-rw-r--r-- 1 root root 1038 7月 12 2021 front-proxy-ca.crt
-rw-r--r-- 1 root root 1679 7月 12 2021 front-proxy-ca.key
-rw-r--r-- 1 root root 1058 7月 12 2021 front-proxy-client.crt
-rw-r--r-- 1 root root 1679 7月 12 2021 front-proxy-client.key
-rw-r--r-- 1 root root 1675 7月 12 2021 sa.key
-rw-r--r-- 1 root root 451 7月 12 2021 sa.pub

连接配置文件:/etc/kubernetes

1
2
3
4
-rw-r--r-- 1 root root 5467 7月  12 2021 admin.conf
-rw-r--r-- 1 root root 5507 7月 12 2021 controller-manager.conf
-rw-r--r-- 1 root root 1927 7月 12 2021 kubelet.conf
-rw-r--r-- 1 root root 5451 7月 12 2021 scheduler.conf

这几个conf就是其他几个组件访问 kube-apiserver 所需的配置文件,直接加载相应的文件,使用里面的信息与 kube-apiserver 建立安全连接。

etcd,api-server,scheduler,controller-manager等master的组件是怎么启动的?

在/etc/kubernetes/manifests目录下

1
2
3
4
-rw------- 1 root root 1882 7月  12 2021 etcd.yaml
-rw------- 1 root root 2909 7月 12 2021 kube-apiserver.yaml
-rw------- 1 root root 2831 7月 12 2021 kube-controller-manager.yaml
-rw------- 1 root root 1332 7月 12 2021 kube-scheduler.yaml

kubelet 启动时,它会自动检查这个目 录,加载所有的 Pod YAML 文件,然后在这台机器上启动它们。

Ingress

service nodeport的问题:

  1. 端口有限,默认30000-32767 只有2768个。(可以自己改,但最大也就65535)

  2. 不安全,直接访问主机端口

  3. 负载均衡能力有限,4层复杂均衡。只能进行最基本的策略。

整体架构图

image-20211103102638681

ingress方案:

  1. service不再使用nodeport,全内网部署
  2. 在部分机器上部署ingress-nginx。这个nginx是k8s管理的。所以可以路由到所有服务。
  3. ingress-nginx被ingress-controller管理,通过编写ingress-rule进行配置变更
  4. ingress-nginx相互之间数据同步
  5. 外网负载均衡将流量打给ingress-nginx

安装

Ingress | Kubernetes

Installation Guide - NGINX Ingress Controller (kubernetes.github.io)

注意提前拉取镜像

可以使用demonset,使每台机器部署一个

可以给node打标签,设置哪些机器部署ingress

Ingress rule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: itdachang-ingress
namespace: default
spec:
defaultBackend: ## 指定所有未匹配的默认后端
service:
name: php-apache
port:
number: 80
rules:
- host: itdachang.com
http:
paths:
- path: /abc
pathType: Prefix
backend:
service:
name: my-nginx-svc
port:
number: 80

nginx的全局配置

通过配置config-map

1
2
3
4
5
kubectl edit cm ingress-nginx-controller -n ingress-nginx
编辑配置加上
data:
配置项: 配置值

所有配置项参考 https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/

nginx开启功能

metadata里通过Annotations开启功能

路径重写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2 //只保留第二部分,把前面的上下文去掉了
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- path: /something(/|$)(.*)
pathType: Prefix
backend:
service:
name: http-svc
port:
number: 80

会话保持

基于cookie粘连

Sticky Sessions - NGINX Ingress Controller (kubernetes.github.io)

annotations

nginx.ingress.kubernetes.io/affinity

SSL

  1. 搞证书

    自己玩:

    1
    2
    3
    openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE:tls.key}
    -out ${CERT_FILE:tls.cert} -subj
    "/CN=${HOST:xxx.com}/O=${HOST:xxx.com}"

    买个域名,申请个免费证书DV

    这种下载的证书可能是pem文件,直接改成crt就行

  2. 配置secret

    1
    kubectl create secret tls xxx-tls --key tls.key --cert tls.cert
  3. 在ingress中使用

    1
    2
    3
    4
    5
    6
    spec:
    tls:
    - hosts:
    - itdachang.com
    secretName: itdachang-tls

金丝雀

Annotations - NGINX Ingress Controller (kubernetes.github.io)