一、日志收集案例-容器内置日志收集
在容器内置日志收集服务进程,收集当前容器的业务容器日志等。
1、构建包含 filebeat 的业务镜像
Dockerfile
#tomcat web1
FROM y73.harbor.com/y73/tomcat-base:v8.5.43
ADD catalina.sh /apps/tomcat/bin/catalina.sh
ADD server.xml /apps/tomcat/conf/server.xml
#ADD myapp/* /data/tomcat/webapps/myapp/
ADD myapp.tar.gz /data/tomcat/webapps/myapp/
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
ADD filebeat.yml /etc/filebeat/filebeat.yml
RUN chown -R tomcat.tomcat /data/ /apps/
#ADD filebeat-7.5.1-x86_64.rpm /tmp/
#RUN cd /tmp && yum localinstall -y filebeat-7.5.1-amd64.deb
EXPOSE 8080 8443
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
build-command.sh
root@k8s-deploy:/yaml/20220821/ELK cases/3.container-filebeat-process/1.webapp-filebeat-image-Dockerfile# cat build-command.sh
#!/bin/bash
TAG=$1
docker build -t y73.harboe.com/y73/tomcat-app1:${TAG} .
#sleep 3
docker push y73.harboe.com/y73/tomcat-app1:${TAG}
#nerdctl build -t y73.harboe.com/y73/tomcat-app1:${TAG} .
#nerdctl push y73.harboe.com/y73/tomcat-app1:${TAG}
filebeat.yml:filebeat 配置文件,定义如何从容器拿日志以及传给 kafka
root@k8s-deploy:/yaml/20220821/ELK cases/3.container-filebeat-process/1.webapp-filebeat-image-Dockerfile# vim filebeat.yml
filebeat.inputs:
- type: log
enabled: true # 是否启用
paths:
- /apps/tomcat/logs/catalina.out # 容器内的启动日志路径
fields:
type: filebeat-tomcat-catalina
- type: log
enabled: true
paths:
- /apps/tomcat/logs/localhost_access_log.*.txt # 容器内的访问日志路径
fields:
type: filebeat-tomcat-accesslog
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
setup.template.settings:
index.number_of_shards: 1
setup.kibana:
output.kafka:
hosts: ["192.168.0.125:9092"]
required_acks: 1
topic: "filebeat-magedu-app1"
compression: gzip
max_message_bytes: 1000000
#output.redis:
# hosts: ["172.31.2.105:6379"]
# key: "k8s-magedu-app1"
# db: 1
# timeout: 5
# password: "123456"
catalina.sh:tomcat 启动脚本,可以网上找模板,主要修改以下内容
JAVA_OPTS="-server -Xms1g -Xmx1g -Xss512k -Xmn1g -XX:CMSInitiatingOccupancyFraction=65 -XX:+UseFastAccessorMethods -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=10 -XX:NewSize=2048M -XX:MaxNewSize=2048M -XX:NewRatio=2 -XX:PermSize=128m -XX:MaxPermSize=512m -XX:CMSFullGCsBeforeCompaction=5 -XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled"
run_tomcat.sh:该脚本在容器内执行 tail -f
命令,使得 tomcat 独占前台;并在后台启动 filebeat
#!/bin/bash
#echo "nameserver 223.6.6.6" > /etc/resolv.conf
#echo "192.168.7.248 k8s-vip.example.com" >> /etc/hosts
/usr/share/filebeat/bin/filebeat -e -c /etc/filebeat/filebeat.yml -path.home /usr/share/filebeat -path.config /etc/filebeat -path.data /var/lib/filebeat -path.logs /var/log/filebeat &
su - tomcat -c "/apps/tomcat/bin/catalina.sh start"
tail -f /etc/hosts
server.xml:自行定义 tomcat 访问路径,其他配置不变
<Host name="localhost" appBase="/data/tomcat/webapps" unpackWARs="false" autoDeploy="false">
执行构建脚本
./build-command.sh
2、部署 web 服务
允许一个 tomcat 业务应用,其中每个 Pod 只有一个容器,每个容器内置 filebeat 进程
root@k8s-deploy:/yaml/20220821/ELK cases/3.container-filebeat-process# vim 3.tomcat-app1.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: magedu-tomcat-app1-filebeat-deployment-label
name: magedu-tomcat-app1-filebeat-deployment
namespace: magedu
spec:
replicas: 5
selector:
matchLabels:
app: magedu-tomcat-app1-filebeat-selector
template:
metadata:
labels:
app: magedu-tomcat-app1-filebeat-selector
spec:
containers:
- name: magedu-tomcat-app1-filebeat-container
image: y73.harboe.com/y73/tomcat-app1:v1-filebeat
imagePullPolicy: IfNotPresent
#imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
resources:
limits:
cpu: 300m
memory: "256Mi"
requests:
cpu: 300m
memory: "256Mi"
创建 service 允许从外部访问 tomcat
root@k8s-deploy:/yaml/20220821/ELK cases/3.container-filebeat-process# vim 4.tomcat-service.yaml
---
kind: Service
apiVersion: v1
metadata:
labels:
app: magedu-tomcat-app1-filebeat-service-label
name: magedu-tomcat-app1-filebeat-service
namespace: magedu
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 30092
selector:
app: magedu-tomcat-app1-filebeat-selector
如果是以 Pod 形式部署 filebeat (即在k8s集群层面部署)还需要给 filebeat 定义各种权限,本例是内置在容器内部所以不需要
root@k8s-deploy:/yaml/20220821/ELK cases/3.container-filebeat-process# vim 2.filebeat-serviceaccount.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: filebeat-serviceaccount-clusterrole
labels:
k8s-app: filebeat-serviceaccount-clusterrole
rules:
- apiGroups: [""] # "" indicates the core API group
resources:
- namespaces
- pods
- nodes
verbs:
- get
- watch
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: filebeat-serviceaccount-clusterrolebinding
subjects:
- kind: ServiceAccount
name: default
namespace: magedu
roleRef:
kind: ClusterRole
name: filebeat-serviceaccount-clusterrole
apiGroup: rbac.authorization.k8s.io
3、修改 logstash 配置文件
和上文一样,在 /etc/logstash/conf.d/
目录新增 logstash 配置文件,定义 filebeat 如何将收集的日志传给 ES。
root@logsatsh01:/etc/logstash/conf.d# vim filebeat-log-to-es.conf
input {
kafka {
bootstrap_servers => "192.168.0.125:9092,192.168.0.126:9092,192.168.0.127:9092"
topics => ["filebeat-magedu-app1"]
codec => "json"
}
}
output {
if [fields][type] == "filebeat-tomcat-catalina" {
elasticsearch {
hosts => ["192.168.0.122:9200","192.168.0.123:9200","192.168.0.124:9200"]
index => "filebeat-tomcat-catalina-%{+YYYY.MM.dd}"
}}
if [fields][type] == "filebeat-tomcat-accesslog" {
elasticsearch {
hosts => ["192.168.0.122:9200","192.168.0.123:9200","192.168.0.124:9200"]
index => "filebeat-tomcat-accesslog-%{+YYYY.MM.dd}"
}}
}
之后重启 logstash 并查看日志观察有无报错
root@logsatsh01:/etc/logstash/conf.d# systemctl restart logstash.service
root@logsatsh01:/etc/logstash/conf.d# tail -f /var/log/logstash/logstash-plain.log
4、进行验证
1、kafka 客户端验证
2、Elasticsearch
没有启动日志索引,可以增加副本数量或者进入 Pod 直接往启动日志里写数据
3、kibana
操作步骤和上面一样
二、overlay与underlay通信总结
网络二层通信
在计算机网络中,网络二层通信指的是在数据链路层(也称为第二层)进行的通信。数据链路层的主要功能是将数据帧从一个网络节点传输到另一个网络节点。
数据链路层的实现通常需要两个重要的协议:MAC(Media Access Control,媒体访问控制)协议和LLC(Logical Link Control,逻辑链路控制)协议。
MAC协议是数据链路层中最重要的协议之一,它规定了数据帧的格式和传输方式。MAC协议使用一个唯一的地址(MAC地址)来标识每个网络设备。当一台设备要向另一台设备发送数据帧时,它首先会在网络中广播一个请求信号,请求其他设备暂停发送数据。这个过程称为“争用”,只有一个设备能够赢得争用并获得发送数据的权利。一旦设备获得发送数据的权利,它会将数据帧发送到目标设备的MAC地址。
LLC协议则负责控制数据帧的流量,以及提供一些错误检测和纠正的功能。它定义了一些逻辑连接类型和控制消息,用于控制数据链路层的数据传输和错误处理。
总的来说,网络二层通信通过MAC协议和LLC协议实现。在这个过程中,每个设备都有一个唯一的MAC地址,数据帧会根据目标设备的MAC地址进行路由,而LLC协议则负责控制数据帧的传输和错误处理,确保数据的可靠性和完整性。
VLAN
VLAN(Virtual Local Area Network,虚拟局域网)是一种逻辑上的网络,将一个物理局域网(LAN)划分为多个逻辑子网。这些逻辑子网可以跨越多个物理设备,但是它们在逻辑上被视为独立的网络。
VLAN的作用主要有以下几个方面:
- 增强网络安全性:VLAN可以将不同的用户和设备隔离在不同的逻辑子网中,以减少网络攻击和数据泄露的风险。
- 简化网络管理:通过VLAN,管理员可以将不同的用户和设备划分到不同的逻辑子网中,从而更容易管理网络和配置网络策略。
- 提高网络性能:VLAN可以将网络流量隔离在不同的逻辑子网中,从而减少网络拥塞和冲突,提高网络性能和可靠性。
- 支持虚拟化:VLAN可以为不同的虚拟机创建不同的逻辑子网,从而实现虚拟机之间的隔离和互访。
实现VLAN通常需要交换机或路由器等设备支持VLAN技术,并进行相应的配置。在配置VLAN时,管理员需要为每个VLAN分配一个唯一的VLAN ID,以及为每个端口配置相应的VLAN成员关系。这样,当数据包到达交换机或路由器时,设备就可以根据VLAN ID进行路由,将数据包转发到正确的VLAN中。
VXLAN
VXLAN(Virtual Extensible LAN)是一种虚拟化技术,用于扩展数据中心的二层网络。VXLAN通过在传统的Ethernet帧上封装一个额外的头部,将一个虚拟网络的二层数据包从底层物理网络中隔离出来,从而实现跨物理网络的虚拟网络通信。
VXLAN的主要作用如下:
- 扩展网络:VXLAN允许在数据中心内创建更多的虚拟网络,使得网络能够更加灵活地满足不同的业务需求,同时减少网络中的广播和多播流量,提高网络性能和可靠性。
- 隔离虚拟网络:VXLAN通过封装和解封装的过程,将不同的虚拟网络之间的流量相互隔离,避免虚拟网络之间的冲突和干扰,从而提高网络安全性。
- 支持跨数据中心:VXLAN可以扩展到多个数据中心,允许在不同的数据中心之间建立虚拟网络通信,实现数据中心间的互连。
VXLAN的实现通常需要三个组成部分:
- VXLAN网络标识符(VNI):它是一个24位的标识符,用于唯一地标识一个VXLAN虚拟网络。
- VTEP(VXLAN Tunnel End Point):它是VXLAN网络的出入口,负责将数据帧封装到VXLAN报文中,并将其发送到目的地。VTEP可以是一个物理设备或虚拟设备。
- VTEP之间的通信机制:VTEP之间需要进行通信,以实现虚拟网络之间的互通。VXLAN通常使用UDP作为底层传输协议,通过在UDP报文中封装VXLAN报文,从而实现VTEP之间的通信。
总的来说,VXLAN是一种虚拟化技术,可以扩展数据中心的二层网络,并提高网络的灵活性、可靠性和安全性。VXLAN通过在数据帧上封装额外的头部来实现,需要VTEP之间的通信机制来支持虚拟网络之间的互通。
overlay
Overlay网络模型是一种在宿主机网络之上创建虚拟网络的方式。在这种模型下,Kubernetes会在每个节点上运行一个代理程序,这个代理程序会创建一个虚拟的网络层,其中包含了所有运行在该节点上的容器。当一个容器需要与另一个容器通信时,它会发送一个网络包到虚拟网络中的目标地址,然后代理程序会将该包转发到目标容器。
Overlay网络模型的优点在于它可以允许跨主机的容器通信,这是因为虚拟网络层被建立在宿主机网络之上。此外,它也可以提供一些额外的网络安全性,比如在虚拟网络层上加密数据包等。
然而,Overlay网络模型的缺点在于它需要额外的网络开销,因为代理程序需要在虚拟网络层和宿主机网络之间进行转发。这会导致一些性能上的问题,并且也需要消耗额外的计算资源。
underlay
Underlay网络模型是一种直接使用宿主机网络的方式。在这种模型下,Kubernetes会在每个节点上创建一个网桥,并为每个容器分配一个独立的IP地址。当一个容器需要与另一个容器通信时,它会将网络包发送到目标IP地址,然后网桥会将该包转发到目标容器。
Underlay网络模型的优点在于它可以提供更快的网络传输速度,因为网络包不需要经过代理程序的转发。此外,它也不需要消耗额外的计算资源,因为它直接使用宿主机网络。
然而,Underlay网络模型的缺点在于它不能够支持跨主机的容器通信,因为每个容器只有一个独立的IP地址。此外,它也不提供额外的网络安全性,因为数据包在宿主机网络上传输时没有加密等保护。
Underlay网络模型在实现上有不同的方式,其中两种常用的方式是Macvlan和Ipvlan。
- Macvlan
Macvlan是一种将物理网卡的MAC地址与容器的虚拟网卡一一映射的方式,实现容器直接使用物理网络进行通信。这种方式在容器与物理网络之间建立了一条直接的通信路径,因此网络性能较高。
Macvlan共有4种实现方式:
- Private Macvlan:在物理网卡上创建一组虚拟接口,每个虚拟接口与一个容器的虚拟接口绑定,容器可以直接使用物理网络进行通信。这种方式可以实现容器与物理网络的完全隔离。
- VEPA(Virtual Ethernet Port Aggregator)Macvlan:在交换机中创建VEPA端口,将VEPA端口绑定到物理网卡上,然后将容器的虚拟接口绑定到VEPA端口上,容器可以直接使用物理网络进行通信。这种方式可以使容器具有直接的MAC地址和IP地址,并且可以与物理网络中的其他设备直接通信。
- Passthru Macvlan:在物理网卡上创建一个虚拟接口,然后将这个虚拟接口直接暴露给容器,容器的虚拟接口直接绑定到这个虚拟接口上。这种方式可以使容器具有直接的MAC地址和IP地址,并且可以与物理网络中的其他设备直接通信。
- Bridge Macvlan:在物理网卡上创建一个Linux网桥,然后将这个网桥与物理网卡进行桥接,容器的虚拟接口绑定到这个网桥上,容器可以直接使用物理网络进行通信。这种方式可以使容器具有直接的MAC地址和IP地址,并且可以与物理网络中的其他设备直接通信。
- Ipvlan
Ipvlan是一种将物理网络的IP地址与容器的虚拟网卡一一映射的方式,实现容器直接使用物理网络进行通信。与Macvlan不同的是,Ipvlan不需要映射MAC地址,而是将容器虚拟接口直接绑定到物理网络的接口上。
Ipvlan分为两种实现方式:
- L2 Ipvlan:将容器的虚拟接口绑定到物理网络的接口上,容器可以直接使用物理网络进行通信。这种方式可以实现容器与物理网络的完全隔离。
- L3 Ipvlan:在L2 Ipvlan的基础上,为每个容器分配一个唯一的IP地址,并将这个IP地址绑定到容器的虚拟接口上。这种方式可以使容器具有直接的IP地址,并且可以直接从外部网络访问容器。
k8s Pod 通信
underlay案例
首先进行IP地址规划,本例中我的宿主机网络是192.168.0.0/24。划分三个子网,分别给node节点、service 和 Pod 使用。
假设要将 192.168.0.0/24 这个网段划分成 3 个子网,则需要重新分配 IP 地址范围、子网掩码、广播地址和可用地址数量等参数。下面是一种可能的划分方式:
- 子网 1:node 节点使用
- IP 地址范围:192.168.0.1 - 192.168.0.63
- 子网掩码:255.255.255.192 (/26)
- 广播地址:192.168.0.63
- 可用地址数量:62
- 子网 2:service 使用
- IP 地址范围:192.168.0.64 - 192.168.0.127
- 子网掩码:255.255.255.192 (/26)
- 广播地址:192.168.0.127
- 可用地址数量:62
- 子网 3:Pod 使用
- IP 地址范围:192.168.0.128 - 192.168.0.254
- 子网掩码:255.255.255.128 (/25)
- 广播地址:192.168.0.255
- 可用地址数量:126
1、环境准备
1、安装docker
使用 kubeadm 部署一套新的 k8s 集群,首先安装 docker 作为运行时。
# step 1: 安装必要的一些系统工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安装GPG证书
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新并安装Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce
docker 参数优化,使用镜像加速并把 Cgroup Driver 改为 systemd 。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://gjsamcgt.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2、安装 cri-dockerd
k8s不再直接支持 docker ,需要安装 cri-dockerd。
cri-dockerd
是一个实验性的容器运行时,它将 Docker 容器引擎 (dockerd
) 作为 CRI (Container Runtime Interface) 的实现。CRI 是 Kubernetes 使用的标准容器运行时接口,它定义了 Kubernetes 如何与容器运行时交互,包括如何启动、停止、监视容器等。
通过使用 cri-dockerd
,Kubernetes 可以使用 Docker 作为底层容器引擎来运行容器。cri-dockerd
的实现方式是使用 Docker 引擎作为容器运行时,并将其作为 CRI 插件实现。这样,Kubernetes 可以像使用其他 CRI 兼容的容器运行时一样,使用 Docker 引擎来运行容器。
需要注意的是,cri-dockerd
是一个实验性的项目,不建议在生产环境中使用。它可能会受到 Docker 引擎自身的限制和限制,同时也可能会受到 Kubernetes 和 CRI 规范的限制。因此,在选择容器运行时时,建议使用官方支持的容器运行时,如 Containerd 或 CRI-O。
root@k8s-node3:~# wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.1/cri-dockerd-0.3.1.amd64.tgz
root@k8s-node3:~# tar xvf cri-dockerd-0.3.1.amd64.tgz
cri-dockerd/
cri-dockerd/cri-dockerd
root@k8s-node3:~# cp cri-dockerd/cri-dockerd /usr/local/bin
root@k8s-node3:~# cri-dockerd --version
cri-dockerd 0.3.1 (7e528b98)
配置 cri-docker.service 文件。
其中,ExecStart
参数指定了启动 cri-dockerd
的命令行参数,包括 --network-plugin=cni
表示使用 CNI 网络插件、--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.7
表示使用阿里云镜像仓库中的 pause:3.7
镜像作为 Pod 的 Infra Container。
root@k8s-master:~# vim /lib/systemd/system/cri-docker.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket
[Service]
Type=notify
ExecStart=/usr/local/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.7
ExecReload=/bin/kill -S HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
配置 cri-docker.socket文件.
该 socket 文件用于与 cri-dockerd
服务进行通信,让 kubelet 通过 CRI 调用 Docker API。当 kubelet 启动时,它将使用该 socket 文件建立到 cri-dockerd
服务的连接。其他组件可以通过连接到该 socket 文件来使用 Docker 容器运行时的功能。
root@k8s-node3:~# vim /lib/systemd/system/cri-docker.socket
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-dockerd.service
[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=socket.target
启动
systemctl daemon-reload && systemctl restart cri-docker.service && systemctl enable cri-docker.service && systemctl enable --now cri-docker.socket
2、部署集群
1、使用 kubeadm 部署集群
所有节点安装 kubectl、kubelet、kubeadm。本例使用1.24.4版本
apt-get update && apt-get install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
apt-get update
apt install -y kubeadm=1.24.4-00 kubelet=1.24.4-00 kubectl=1.24.4-00
# 验证版本
root@k8s-node3:~# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.4", GitCommit:"95ee5ab382d64cfe6c28967f36b53970b8374491", GitTreeState:"clean", BuildDate:"2022-08-17T18:52:53Z", GoVersion:"go1.18.5", Compiler:"gc", Platform:"linux/amd64"}
2、初始化集群
1、镜像准备
在 master 节点提前下载好需要的镜像
# kubeadm config images list --kubernetes-version v1.24.4
k8s.gcr.io/kube-apiserver:v1.24.4
k8s.gcr.io/kube-controller-manager:v1.24.4
k8s.gcr.io/kube-scheduler:v1.24.4
k8s.gcr.io/kube-proxy:v1.24.4
k8s.gcr.io/pause:3.7
k8s.gcr.io/etcd:3.5.3-0
k8s.gcr.io/coredns/coredns:v1.8.6
将其替换成国内的源,并编辑脚本。
# vim images-down.sh
#!/bin/bash
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.24.4
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.24.4
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.24.4
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.24.4
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.7
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.3-0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.6
# bash images-down.sh
2、初始化 kubernetes
root@k8s-master:~# kubeadm init --apiserver-advertise-address=192.168.0.129 --apiserver-bind-port=6443 --kubernetes-version=v1.24.4 --pod-network-cidr=10.200.0.0/16 --service-cidr=192.168.0.64/26 --service-dns-domain=cluster.local --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --ignore-preflight-errors=swap --cri-socket unix:///var/run/cri-dockerd.sock
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.0.129:6443 --token iev3zc.g2n1zrp0tv6d8e6v \
--discovery-token-ca-cert-hash sha256:94e470e5a0bb202b2af62c07b393597fec3159fe8e7fe977c21c6d8faf870576
root@k8s-master:~# mkdir -p $HOME/.kube
root@k8s-master:~# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
root@k8s-master:~# sudo chown $(id -u):$(id -g) $HOME/.kube/config
root@k8s-master:~# export KUBECONFIG=/etc/kubernetes/admin.conf
3、添加 node 节点
要在后面加上 --cri-socket unix:///var/run/cri-dockerd.sock
,否则报错。
root@k8s-node1:~# kubeadm join 192.168.0.129:6443 --token iev3zc.g2n1zrp0tv6d8e6v --discovery-token-ca-cert-hash sha256:94e470e5a0bb202b2af62c07b393597fec3159fe8e7fe977c21c6d8faf870576 --cri-socket unix:///var/run/cri-dockerd.sock
root@k8s-master:~# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master NotReady control-plane 10m v1.24.4
k8s-node1 NotReady <none> 18s v1.24.4
k8s-node2 NotReady <none> 12s v1.24.4
k8s-node3 NotReady <none> 6s v1.24.4
4、分发 kubeconfig 认证文件
把 master 节点上的认证文件分发给三个 node 节点
root@k8s-node1:~# mkdir -p /root/.kube
root@k8s-master:~# scp /root/.kube/config 192.168.0.130:/root/.kube
3、创建 underlay 网络
1、helm 环境准备
root@k8s-master:~# wget https://get.helm.sh/helm-v3.11.1-linux-amd64.tar.gz
root@k8s-master:~# cp linux-amd64/helm /usr/local/bin/
root@k8s-master:~# helm version
version.BuildInfo{Version:"v3.11.1", GitCommit:"293b50c65d4d56187cd4e2f390f0ada46b4c4737", GitTreeState:"clean", GoVersion:"go1.18.10"}
2、部署 hybridnet
添加 helm 源
root@k8s-master:~# helm repo add hybridnet https://alibaba.github.io/hybridnet/
"hybridnet" has been added to your repositories
root@k8s-master:~# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "hybridnet" chart repository
Update Complete. ⎈Happy Helming!⎈
配置 overlay Pod 网络,使用第二步“初始化kubernetes”里设置的 Pod cidr 10.200.0.0/16。不指定默认使用100.64.0.0/16
root@k8s-master:~# helm install hybridnet hybridnet/hybridnet -n kube-system --set init.cidr=10.200.0.0/16
W0220 14:46:52.030718 93997 warnings.go:70] spec.template.spec.nodeSelector[beta.kubernetes.io/os]: deprecated since v1.14; use "kubernetes.io/os" instead
W0220 14:46:52.030744 93997 warnings.go:70] spec.template.metadata.annotations[scheduler.alpha.kubernetes.io/critical-pod]: non-functional in v1.16+; use the "priorityClassName" field instead
NAME: hybridnet
LAST DEPLOYED: Mon Feb 20 14:46:51 2023
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
部署 hybridnet
发现 Pod 没被调度,describe 查看是label问题。
给 node 节点打上标签后恢复正常
root@k8s-master:~# kubectl label node k8s-node1 node-role.kubernetes.io/master=
node/k8s-node1 labeled
root@k8s-master:~# kubectl label node k8s-node2 node-role.kubernetes.io/master=
node/k8s-node2 labeled
root@k8s-master:~# kubectl label node k8s-node3 node-role.kubernetes.io/master=
node/k8s-node3 labeled
3、创建 underlay 网络
创建 underlay 网络并于 node 节点关联,给 node 节点添加 network=underlay-nethost 标签
root@k8s-master:~# kubectl label node k8s-node1 network=underlay-nethost
node/k8s-node1 labeled
root@k8s-master:~# kubectl label node k8s-node2 network=underlay-nethost
node/k8s-node2 labeled
root@k8s-master:~# kubectl label node k8s-node3 network=underlay-nethost
node/k8s-node3 labeled
root@k8s-master:/yaml/20220828-case/2.underlay-cases-files# vim 1.create-underlay-network.yaml
---
apiVersion: networking.alibaba.com/v1
kind: Network
metadata:
name: underlay-network1
spec:
netID: 0
type: Underlay
nodeSelector: # 节点选择,在哪些节点创建 underlay 网络
network: "underlay-nethost"
---
apiVersion: networking.alibaba.com/v1
kind: Subnet
metadata:
name: underlay-network1
spec:
network: underlay-network1
netID: 0
range:
version: "4"
cidr: "192.168.0.0/24" # 大的子网
gateway: "192.168.0.1" # 外部网关地址,可在node节点使用 route -n 命令查看
start: "192.168.0.128" # 在前面的子网划分里,规定了 192.168.0.128/25 是给Pod使用的
end: "192.168.0.254"
4、部署 web 服务
1、使用 overlay 网络
目前默认使用 overlay 网络
root@k8s-master:/yaml/20220828-case/2.underlay-cases-files# vim 2.tomcat-app1-overlay.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: myserver-tomcat-app1-deployment-overlay-label
name: myserver-tomcat-app1-deployment-overlay
namespace: myserver
spec:
replicas: 1
selector:
matchLabels:
app: myserver-tomcat-app1-overlay-selector
template:
metadata:
labels:
app: myserver-tomcat-app1-overlay-selector
spec:
nodeName: k8s-node2
containers:
- name: myserver-tomcat-app1-container
#image: tomcat:7.0.93-alpine
image: registry.cn-hangzhou.aliyuncs.com/zhangshijie/tomcat-app1:v1
imagePullPolicy: IfNotPresent
##imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
# resources:
# limits:
# cpu: 0.5
# memory: "512Mi"
# requests:
# cpu: 0.5
# memory: "512Mi"
---
kind: Service
apiVersion: v1
metadata:
labels:
app: myserver-tomcat-app1-service-overlay-label
name: myserver-tomcat-app1-service-overlay
namespace: myserver
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 30003
selector:
app: myserver-tomcat-app1-overlay-selector
2、使用 underlay 网络
underlay Pod 可以和 overlay Pod 共存(混合使用)。
在本例中,使用underlay网络,可以从集群外部直接访问 Pod 的IP,其实用不到 service ,
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: myserver-tomcat-app1-deployment-underlay-label
name: myserver-tomcat-app1-deployment-underlay
namespace: myserver
spec:
replicas: 1
selector:
matchLabels:
app: myserver-tomcat-app1-underlay-selector
template:
metadata:
labels:
app: myserver-tomcat-app1-underlay-selector
annotations: #使用Underlay或者Overlay网络
networking.alibaba.com/network-type: Underlay
spec:
#nodeName: k8s-node2.example.com
containers:
- name: myserver-tomcat-app1-container
#image: tomcat:7.0.93-alpine
image: registry.cn-hangzhou.aliyuncs.com/zhangshijie/tomcat-app1:v2
imagePullPolicy: IfNotPresent
##imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
# resources:
# limits:
# cpu: 0.5
# memory: "512Mi"
# requests:
# cpu: 0.5
# memory: "512Mi"
---
kind: Service
apiVersion: v1
metadata:
labels:
app: myserver-tomcat-app1-service-underlay-label
name: myserver-tomcat-app1-service-underlay
namespace: myserver
spec:
# type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
#nodePort: 40003
selector:
app: myserver-tomcat-app1-underlay-selector
直接访问 Pod 的8080端口,访问成功。
3、通过 service IP 访问 Pod
很多时候 Pod IP是动态变化的,service IP 删除再重建是不会变化的,可以通过它来访问服务。
查看 service 信息
root@k8s-master:~# kubectl get svc -n myserver
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myserver-tomcat-app1-service-overlay NodePort 192.168.0.125 <none> 80:30003/TCP 4m32s
myserver-tomcat-app1-service-underlay ClusterIP 192.168.0.113 <none> 80/TCP 4m21s
发现 underlay 的service IP 为192.168.0.113,但是浏览器直接访问显示不通:那是因为集群外部没有到这个 service 的路由(在集群内部是可以访问的)
但是集群内部是能访问的
root@k8s-node1:~# curl 192.168.0.113/myapp/index.html
tomcat app1 v2
注意:测试 service 能不能访问,不要使用 ping 来检查。
(29条消息) 为什么k8s service IP不能ping呢?_Monkey_speaking的博客-优快云博客
为什么Kubernetes Service不能ping | Kuboard
给主机添加路由后再次访问就可以了
4、配置 k8s 默认网络行为
比如本例中的默认网络行为就是 overlay ,使用 underlay 要单独指定。
三、网络组件flannel总结
1、k8s集群中的通信需求
2、什么是 cni ?
https://v1-24.docs.kubernetes.io/zh-cn/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/
https://github.com/containernetworking/cni
在 Kubernetes 中,CNI(Container Networking Interface)是一种插件化的网络架构,它负责为 Kubernetes 集群中的容器提供网络连接。CNI 通过一个独立的二进制文件实现,并通过 API 与容器运行时进行交互,从而为容器提供网络接口。在 Kubernetes 中,CNI 是 Kubernetes 网络插件的基础。
CNI 的主要作用是为容器提供网络连接。当 Kubernetes 集群中创建一个 Pod 时,CNI 插件将会被调用,它将会负责创建一个网络接口并分配一个 IP 地址给该 Pod。同时,CNI 还可以负责进行网络隔离、路由、防火墙等方面的配置,以确保容器之间的网络通信安全可靠。
另外,CNI 的插件化架构使得 Kubernetes 网络插件可以灵活选择和集成第三方的网络方案,如 Calico、Flannel、Cilium 等,以满足不同应用场景的需求。通过使用 CNI 插件,Kubernetes 集群中的容器可以具备更强大的网络功能,从而更好地支持各种应用场景的需求。
3、Flannel 简介
Flannel 是一个基于 Linux 系统上的网络覆盖层,用于构建和管理大规模容器集群。它的主要作用是为容器提供 IP 地址和网络通信能力。
Flannel 的网络模型是基于 Overlay 网络的,使用了虚拟网络技术来构建一个全局的覆盖网络。Flannel 通过在宿主机之间建立虚拟网络隧道来实现容器之间的通信。Flannel 支持多种后端,包括 VXLAN、UDP、Host-GW 和 AWS VPC 等。
在 Flannel 的网络模型中,每个宿主机会分配一个唯一的子网地址段。当容器需要进行通信时,Flannel 会为其分配一个唯一的 IP 地址,并使用 Overlay 网络技术将容器连接到一个全局的虚拟网络中。这使得容器之间可以像在同一网络中一样进行通信,而不需要暴露在外部网络中。
总体来说,Flannel 的网络模型非常灵活,可以适应各种不同的容器环境和网络配置。它为容器提供了可靠的网络通信能力,可以帮助用户轻松地构建和管理大规模的容器集群。
1、Flannel 网络模式(后端模型)
Flannel 提供了三种不同的后端模型:VXLAN、UDP 和 Host-GW,它们各自具有以下特点:
- VXLAN
VXLAN(Virtual Extensible LAN)是一种基于 UDP 的封装技术,通过在原始数据包上添加 VXLAN 头来实现跨主机的容器网络通信。VXLAN 的特点是可以扩展到大规模网络,且支持跨 VLAN 网络的通信。VXLAN 的缺点是需要在每个节点上配置 VTEP(VXLAN Tunnel Endpoint),增加了网络部署和维护的复杂度,同时也会增加网络负载和延迟。
- UDP(目前不使用)
UDP 模式是 Flannel 的默认模式,使用了 UDP 协议进行封装和解封。与 VXLAN 相比,UDP 模式的配置和维护相对简单,但不支持跨 VLAN 网络的通信,安全性及性能不足。
- Host-GW
Host-GW(Host Gateway)模式是将宿主机作为网络网关,通过宿主机的路由表实现容器之间的通信。与 VXLAN 和 UDP 相比,Host-GW 的优点是实现简单,不需要配置额外的网络组件,同时也没有额外的网络负载和延迟,性能较高。但 Host-GW 模式需要为每个节点配置不同的 IP 地址,不支持跨 VLAN 网络的通信。
综上所述,VXLAN 模式适合大规模网络和跨 VLAN 网络的部署,但配置和维护复杂;UDP 模式简单易用,但不支持跨 VLAN 网络的通信;Host-GW 模式简单,没有额外的网络负载和延迟,性能较高,但需要为每个节点配置不同的 IP 地址。选择适合自己的后端模型需要考虑自身的业务需求和网络规模,权衡不同模型的优缺点后再做决策。
2、cni0 和 flannel
在 Flannel 中,cni0 和 flannel.1 是两个虚拟网络接口,它们的作用如下:
- cni0
cni0 是 Flannel 中的一个虚拟网络接口。它是由 Flannel 在宿主机上创建的一个虚拟网络接口,用于连接宿主机和 Flannel 网络。cni0 接口的 IP 地址是 Flannel 分配的子网地址段中的一个地址,用于宿主机和 Flannel 网络之间的通信。
在 Flannel 的网络模型中,每个宿主机都有一个 cni0 接口,这个接口是唯一的,且所有的容器都会通过它来连接到 Flannel 网络。通过 cni0 接口,Flannel 可以将容器之间的通信路由到正确的宿主机和正确的容器上,实现容器之间的网络通信。
- flannel.1
flannel.1 是 Flannel 中的一个虚拟网络接口,用于连接不同宿主机之间的 Flannel 网络。在 Flannel 的网络模型中,每个宿主机都会创建一个 flannel.1 接口,这个接口会通过 VXLAN 等虚拟网络技术与其他宿主机上的 flannel.1 接口连接起来,形成一个全局的覆盖网络。
flannel.1 接口的 IP 地址是在 Flannel 启动时自动分配的,用于标识 Flannel 网络中的宿主机。通过 flannel.1 接口,Flannel 可以将不同宿主机上的容器之间的通信路由到正确的宿主机和正确的容器上,实现容器之间的跨主机网络通信。
总之,cni0 和 flannel.1 都是 Flannel 中重要的组件,它们分别负责着连接宿主机和 Flannel 网络、连接不同宿主机之间的 Flannel 网络这两个功能。通过这两个组件的协作,Flannel 可以为容器提供可靠的网络通信能力,并实现容器之间的跨主机通信。
3、部署 flannel
把前面实验的 hybridnet 卸载,使用 flannel 网络插件
root@k8s-master:/yaml# helm list -n kube-system
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
hybridnet kube-system 1 2023-02-20 14:46:51.050482279 +0800 CST deployed hybridnet-0.5.12 0.7.7
root@k8s-master:/yaml# helm -n kube-system uninstall hybridnet
release "hybridnet" uninstalled
flannel下载地址:https://github.com/flannel-io/flannel/releases
root@k8s-master:/yaml# wget https://github.com/flannel-io/flannel/releases/download/v0.21.2/kube-flannel.yml
将模板文件里的 Network 改为 kubernetes 集群初始化时设置的 Pod cidr。其他不变
net-conf.json: |
{
"Network": "10.200.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
如果要修改 Pod cidr 或者更改后端模型,可以修改 ConfigMap
4、Flannel 基本信息
# 运行环境
root@k8s-master1:~# find / -name flannel
/opt/cni/bin/flannel
/run/flannel
/usr/local/bin/flannel
# 子网信息
root@k8s-master1:~# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.200.0.0/16
FLANNEL_SUBNET=10.200.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
5、Flannel vxlan 架构图
不通node节点通信
同一node节点通信
6、Flannel 抓包
在10.200.1.5上分别ping同节点的10.200.1.6和不同节点的10.200.2.6,抓取 veth9ccc1330、cni0、flannel1.1 的流量
如何知道 Pod 使用的网卡就是宿主机上的 veth9ccc1330 ?
在容器内部查看 eth0 对应的网络设备id
在宿主机根据对应的 id 找到对应的网络设备
通信流程
1、源pod发起请求,此时报文中源IP为pod的eth0 的ip,源mac 为pod的eth0的mac,目的Pod为目的Pod的IP,目的mac为网关(cni0)的MAC
2、数据报文通过veth peer发送给网关cni0,检查目的mac就是发给自己的,cni0进行目标IP检查,如果是同一个网桥的报文就直接转发,不是的话就发送给flannel.1,此时报文被修改如下:
此时抓包宿主机的 cni0:
源IP:Pod IP,10.100.1.5
目的IP:Pod IP,10.100.2.6
源MAC: 源POD的MAC
目的MAC:cni0 的MAC
3、到达flannel.1,检查目的mac就是发给自己的,开始匹配路由表,先实现overlay报文的内层封装(主要是修改目的Pod的对端flannel.1的 MAC、源MAC为当前宿主机flannel.1的MAC)
此时抓取宿主机的 flannel.1:
源IP:Pod IP,10.100.1.5
目的IP:Pod IP,10.100.2.6
源MAC:源Pod所在宿主机flannel.1的MAC
目的MAC:目的Pod所在主机flannel.1的MAC
4、报文到达目的宿主机物理网卡,接开始解封装报文:
外层目的IP为本机物理网卡,解开后发现里面还有一层目的IP和目的MAC,发现目的IP为10.100.2.6,目的MAC为本机的flannel.1的MAC,然后将报文发送给flannel.1
5、报文到达目的宿主机flannel.1:
flannel.1检查报文的目的IP,发现是去往本机cni0的子网,将请求报文转发至cni0 :
目的IP:10.100.2.6 #目的Pod
源IP:10.100.1.5 #源Pod
目的 MAC:目的pod所在宿主机的flannel.1
源MAC:源pod所在宿主机flannel.1的MAC
6、报文到达目的宿主机cni0
cni0基于目的IP检查mac地址表,修改目的MAC为目的MAC后将来请求转给pod:
源IP:10.100.1.5 #源Pod
目的IP:10.100.2.6 #目的Pod
源MAC:目的Pod所在宿主机cni0的MAC
目的MAC:目的Pod的MAC
7、报文到达目的宿主机pod
cni0收到报文后去往10.100.1.6,检查MAC地址表发现是本地接口,然后通过网桥接口发给pod:
目的IP:目的pod IP 10.100.2.6
源IP:源Pod IP 10.200.1.5
目的MAC:目的pod MAC
源MAC:目的Pod所在宿主机cni0的MAC
四、NetworkPolicy Ingress及Egress简介及案例
1、NetworkPolicy | Kubernetes
在 Kubernetes 中,NetworkPolicy 是一种网络访问控制机制,用于限制 pod 之间和 pod 与集群外部通信的网络流量。
它允许 Kubernetes 用户通过使用标签选择器和规则定义来控制网络流量。通过 NetworkPolicy,您可以限制哪些 pod 可以与其他 pod 通信,哪些 pod 可以从集群外部访问应用程序,以及哪些端口可以使用。
一些常见的 NetworkPolicy 规则包括:
- 允许或禁止从特定 pod 到另一个 pod 的流量
- 允许或禁止来自特定 IP 地址或 IP 范围的流量
- 允许或禁止来自特定端口或端口范围的流量
- 允许或禁止入站或出站流量
使用 NetworkPolicy 可以提高集群的安全性和网络可靠性,并帮助用户避免在集群中发生网络故障和安全问题。
必需字段:与所有其他的 Kubernetes 配置一样,NetworkPolicy 需要 apiVersion
、 kind
和 metadata
字段。关于配置文件操作的一般信息, 请参考配置 Pod 以使用 ConfigMap 和对象管理。
spec:NetworkPolicy 规约 中包含了在一个名字空间中定义特定网络策略所需的所有信息。
podSelector:每个 NetworkPolicy 都包括一个 podSelector
, 它对该策略所适用的一组 Pod 进行选择。示例中的策略选择带有 “role=db” 标签的 Pod。 空的 podSelector
选择名字空间下的所有 Pod。
policyTypes:每个 NetworkPolicy 都包含一个 policyTypes
列表,其中包含 Ingress
或 Egress
或两者兼具。policyTypes
字段表示给定的策略是应用于进入所选 Pod 的入站流量还是来自所选 Pod 的出站流量,或两者兼有。 如果 NetworkPolicy 未指定 policyTypes
则默认情况下始终设置 Ingress
; 如果 NetworkPolicy 有任何出口规则的话则设置 Egress
。
ingress:每个 NetworkPolicy 可包含一个 ingress
规则的白名单列表。 每个规则都允许同时匹配 from
和 ports
部分的流量。示例策略中包含一条简单的规则: 它匹配某个特定端口,来自三个来源中的一个,第一个通过 ipBlock
指定,第二个通过 namespaceSelector
指定,第三个通过 podSelector
指定。
egress:每个 NetworkPolicy 可包含一个 egress
规则的白名单列表。 每个规则都允许匹配 to
和 port
部分的流量。该示例策略包含一条规则, 该规则将指定端口上的流量匹配到 10.0.0.0/24
中的任何目的地。
选择器 to
和 from
的行为
可以在 ingress
的 from
部分或 egress
的 to
部分中指定四种选择器:
podSelector:此选择器将在与 NetworkPolicy 相同的名字空间中选择特定的 Pod,应将其允许作为入站流量来源或出站流量目的地。
namespaceSelector:此选择器将选择特定的名字空间,应将所有 Pod 用作其入站流量来源或出站流量目的地。
namespaceSelector 和 podSelector:一个指定 namespaceSelector
和 podSelector
的 to
/from
条目选择特定名字空间中的特定 Pod。
2、本例环境
- kubernetes v1.24.2 版本,使用 calico 网络插件,两个 node 节点或以上
- 两个 namespace ,linux 和 python ,分别代表不同的项目
- 每个 namespace 运行多个 Pod ,Pod 可以运行在不同的 node 节点上
- 测试环境为每个 namespace 都运行一个 nginx 和 tomcat Pod,用于测试不同节点的 Pod 运行在同一个 namespace、以及跨 namespace 的访问及通信限制
1、创建 namespace
root@deploy:~# kubectl create ns linux
namespace/linux created
root@deploy:~# kubectl create ns python
namespace/python created
root@deploy:~#
root@deploy:~# kubectl label ns linux nsname=linux
namespace/linux labeled
root@deploy:~# kubectl label ns python nsname=python
namespace/python labeled
2、部署 web 服务
linux 命名空间部署 nginx 和 tomcat ,并让 nginx 可以将访问 /app 的请求转发给当前 namespace 的 tomcat Pod ;python 命名空间也是同样操作。
运行在 linux 命名空间的 nginx 能否将请求转发给 python 命名空间的 tomcat ?
创建多个业务 Pod 用于后期从不同节点进行测试;再创建一个测试 Pod ,用于访问目的 nginx 、tomcat 等业务 Pod。
1、创建测试 pod
root@deploy:~# kubectl run test-pod1 --image=centos:7.9.2009 sleep 100000000 -n linux
pod/test-pod1 created
root@deploy:~# kubectl run test-pod1 --image=centos:7.9.2009 sleep 100000000 -n python
pod/test-pod1 created
root@deploy:/yaml/NetWorkPolicy-case/python-ns2# vim testpod-busybox.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: testpod-busybox-deployment-label
name: testpod-busybox-deployment
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: python-nginx-selector
project: python
template:
metadata:
labels:
app: python-nginx-selector
project: python
spec:
containers:
- name: testpod-busybox-container
image: busybox:latest
command:
- sleep
- "50000000"
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
2、linux命名空间的nginx
该pod有一个pod:app: linux-nginx-selector
root@deploy:/yaml/NetWorkPolicy-case# cat linux-ns1/nginx.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: linux-nginx-deployment-label
name: linux-nginx-deployment
namespace: linux
spec:
replicas: 1
selector:
matchLabels:
app: linux-nginx-selector
template:
metadata:
labels:
app: linux-nginx-selector
spec:
containers:
- name: linux-nginx-container
image: nginx:1.20.2-alpine
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
name: http
- containerPort: 443
protocol: TCP
name: https
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
# resources:
# limits:
# cpu: 2
# memory: 2Gi
# requests:
# cpu: 500m
# memory: 1Gi
---
kind: Service
apiVersion: v1
metadata:
labels:
app: linux-nginx-service-label
name: linux-nginx-service
namespace: linux
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30008
- name: https
port: 443
protocol: TCP
targetPort: 443
nodePort: 30443
selector:
app: linux-nginx-selector
3、linux命名空间的tomcat
该pod有一个标签:app: linux-tomcat-app1-selector
root@deploy:/yaml/NetWorkPolicy-case# cat linux-ns1/tomcat.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: linux-tomcat-app1-deployment-label
name: linux-tomcat-app1-deployment
namespace: linux
spec:
replicas: 1
selector:
matchLabels:
app: linux-tomcat-app1-selector
template:
metadata:
labels:
app: linux-tomcat-app1-selector
spec:
containers:
- name: linux-tomcat-app1-container
image: tomcat:7.0.109-jdk8-openjdk
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
# resources:
# limits:
# cpu: 2
# memory: 2Gi
# requests:
# cpu: 500m
# memory: 1Gi
---
kind: Service
apiVersion: v1
metadata:
labels:
app: linux-tomcat-app1-service-label
name: linux-tomcat-app1-service
namespace: linux
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 30006
selector:
app: linux-tomcat-app1-selector
4、python命名空间的nginx
该pod有两个标签:app: python-nginx-selector、project: python
root@deploy:/yaml/NetWorkPolicy-case# cat python-ns2/nginx.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: python-nginx-deployment-label
name: python-nginx-deployment
namespace: python
spec:
replicas: 1
selector:
matchLabels:
app: python-nginx-selector
template:
metadata:
labels:
app: python-nginx-selector
project: python
spec:
containers:
- name: python-nginx-container
image: nginx:1.20.2-alpine
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
name: http
- containerPort: 443
protocol: TCP
name: https
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
# resources:
# limits:
# cpu: 2
# memory: 2Gi
# requests:
# cpu: 500m
# memory: 1Gi
---
kind: Service
apiVersion: v1
metadata:
labels:
app: python-nginx-service-label
name: python-nginx-service
namespace: python
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30016
- name: https
port: 443
protocol: TCP
targetPort: 443
nodePort: 30456
selector:
app: python-nginx-selector
project: python #一个或多个selector,至少能匹配目标pod的一个标签
5、python命名空间的tomcat
该pod有一个标签:app: python-tomcat-app1-selector
root@deploy:/yaml/NetWorkPolicy-case# cat python-ns2/tomcat.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: python-tomcat-app1-deployment-label
name: python-tomcat-app1-deployment
namespace: python
spec:
replicas: 1
selector:
matchLabels:
app: python-tomcat-app1-selector
template:
metadata:
labels:
app: python-tomcat-app1-selector
spec:
#nodeName: 172.31.7.113
containers:
- name: python-tomcat-app1-container
image: tomcat:7.0.109-jdk8-openjdk
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
# resources:
# limits:
# cpu: 2
# memory: 2Gi
# requests:
# cpu: 500m
# memory: 1Gi
---
kind: Service
apiVersion: v1
metadata:
labels:
app: python-tomcat-app1-service-label
name: python-tomcat-app1-service
namespace: python
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 30015
selector:
app: python-tomcat-app1-selector
6、在tomcat里创建测试页面
在两个命名空间的tomcat里创建测试页面,并从测试pod访问,目前没加 networkpolicy 所以能正常访问。
oot@deploy:~# kubectl -n python exec -it python-tomcat-app1-deployment-d445f65f9-mf9cs bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@python-tomcat-app1-deployment-d445f65f9-mf9cs:/usr/local/tomcat# cd webapps
root@python-tomcat-app1-deployment-d445f65f9-mf9cs:/usr/local/tomcat/webapps# mkdir app
root@python-tomcat-app1-deployment-d445f65f9-mf9cs:/usr/local/tomcat/webapps# cd app/
root@python-tomcat-app1-deployment-d445f65f9-mf9cs:/usr/local/tomcat/webapps/app# echo "python-tomcat" > index.jsp
3、ingress 示例一
以Pod为限制单位,只允许同namespace含有特定标签的源pod访问目标pod的所有端口。
这个 YAML 文件定义了一个 Kubernetes 的网络策略(NetworkPolicy),用于限制
python
命名空间中标签为app: python-tomcat-app1-selector
的 Pod 的入站网络流量,以防止来自其他 Pod 的流量。具体地,这个 NetworkPolicy 的规则为:
policyTypes
属性指定这个 NetworkPolicy 的策略类型为 Ingress,即入站流量限制。podSelector
属性指定了要受到这个 NetworkPolicy 限制的目标 Pod 的标签选择器,即匹配标签为app: python-tomcat-app1-selector
的 Pod。ingress
属性定义了这个 NetworkPolicy 的入站规则,即允许哪些来源的流量进入目标 Pod。在这个例子中,只允许来自标签选择器为project: "python"
的 Pod 进入目标 Pod。因此,这个 YAML 文件实现的功能是限制
python
命名空间中标签为app: python-tomcat-app1-selector
的 Pod 的入站网络流量,只允许来自同一命名空间并且标签为project: "python"
的 Pod 进入。这个策略只是限制了具有标记 “app: python-tomcat-app1-selector” 的Pod,只有具有标记 “project: python” 的同一命名空间中的Pod才能访问这些Pod。因此,这个策略不会影响节点直接访问这些Pod。
root@deploy:/yaml/NetWorkPolicy-case/python-ns2# cat case1-ingress-podSelector.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector:
matchLabels:
app: python-tomcat-app1-selector #对匹配到的目的Pod应用以下规则
ingress: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- from:
- podSelector:
matchLabels:
#app: python-nginx-selector #如果存在多个matchLabel条件,如果存在多个matchLabel条件,是and的关系,即要同时满足条件A、条件B、条件X
project: "python"
podSelector 和 ipBlock 的区别
2、ingress 示例二
以Pod加端口为限制单位,只允许同namespace含有特定标签的源pod访问目标pod的指定端口,没被允许的端口将被禁止访问。
root@deploy:/yaml/NetWorkPolicy-case/python-ns2# vim case2-ingress-podSelector-ns-SinglePort.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector:
matchLabels:
app: python-tomcat-app1-selector
ingress:
- from:
- podSelector:
matchLabels:
#app: python-nginx-selector #指定访问源的匹配条件,如果存在多个matchLabel条件,是and的关系,即要同时满足条件A、条件B、条件X
project: "python"
ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- protocol: TCP
port: 8080 #允许通过TCP协议访问目标pod的8080端口,但是其它没有允许的端口将全部禁止访问
#port: 80
将8080端口改成80端口
3、ingress 示例三
允许同 namespace 的所有 Pod 访问当前namespace的目标 Pod 的多个指定端口
本例中在 python 命名空间具有 app: python-tomcat-app1-selector 标签的 Pod 只能被同为 python 命名空间的所有 Pod 访问,且只开放8080、3306、6379这些TCP端口。
root@deploy:/yaml/NetWorkPolicy-case/python-ns2# cat case3-ingress-podSelector-ns-MultiPort.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access-networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector: #目标pod
matchLabels:
app: python-tomcat-app1-selector
ingress:
- from:
- podSelector: #匹配源pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
matchLabels: {}
ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- protocol: TCP
port: 8080 #允许通过TCP协议访问目标pod的8080端口,但是其它没有允许的端口将全部禁止访问
#port: 80
- protocol: TCP
port: 3306
- protocol: TCP
port: 6379
4、ingress 示例四
允许同 namespace 的所有pod访问当前namespace的所有pod的所有端口,其他namespace的Pod无法访问目标Pod。
root@deploy:/yaml/NetWorkPolicy-case/python-ns2# cat case4-ingress-podSelector-ns.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector: #目标pod
matchLabels: {} #匹配所有目标pod
ingress:
- from:
- podSelector: #匹配源pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
matchLabels: {}
ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- protocol: TCP
port: {} #允许通过TCP协议访问目标pod的所有端口
5、ingress 示例五
只要在白名单范围内并且没有被except指定禁止的源Pod IP,都能够访问。
在只设置了 ipBlock 匹配的前提下,只要不在except范围内,其他namespace的Pod也能访问目标Pod。
需要注意的是只能写Pod的地址,不能写公网地址
这个是一个 Kubernetes 的 NetworkPolicy 定义,它定义了一个网络访问策略,作用于名为
python
的命名空间中的所有具有app: python-tomcat-app1-selector
标签的 Pod,其中:
policyTypes: - Ingress
表示这个 NetworkPolicy 是一个入栈策略,它将限制其他 Pod 访问目标 Pod(即具有app: python-tomcat-app1-selector
标签的 Pod)的网络连接。podSelector: matchLabels: app: python-tomcat-app1-selector
表示该策略适用于拥有标签app: python-tomcat-app1-selector
的 Pod。ingress: - from:
表示接下来定义的是允许从哪些源访问目标 Pod。- ipBlock: cidr: 10.200.0.0/16 except: - 10.200.219.0/24 - 10.200.229.0/24 - 10.200.140.72/32
表示允许来自 10.200.0.0/16 网段的所有 IP 访问目标 Pod,但排除了 10.200.219.0/24、10.200.229.0/24 和 10.200.140.72 这三个 IP。ports:
下列出了允许访问的端口,包括 TCP 协议的 8080、3306 和 6379 端口。这意味着只有来自 10.200.0.0/16 网段的 IP,且访问目标 Pod 的 TCP 8080、3306 或 6379 端口的连接将被允许通过,其他所有连接将被禁止。
root@deploy:/yaml/NetWorkPolicy-case/python-ns2# vim case5-ingress-ipBlock.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector: #目标pod
matchLabels:
app: python-tomcat-app1-selector
ingress:
- from:
- ipBlock:
cidr: 10.200.0.0/16 #白名单,允许访问的地址范围,没有允许的将禁止访问目标pod
except:
- 10.200.219.0/24 #在以上范围内禁止访问的源IP地址
- 10.200.229.0/24 #在以上范围内禁止访问的源IP地址
- 10.200.140.72/32 #在以上范围内禁止访问的源IP地址
ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- protocol: TCP
port: 8080 #允许通过TCP协议访问目标pod的8080端口,但是其它没有允许的端口将全部禁止访问
port: 80
- protocol: TCP
port: 3306
- protocol: TCP
port: 6379
使用的是 linux 命名空间的 nginx Pod,IP为10.200.140.72,在except范围内,所有该Pod将无法访问目标Pod。
而linux命名空间里的tomcat Pod ,IP为10.200.140.69,不在except范围内,所有该Pod不受限制
6、ingress 示例六
**namespaceSelector **命名空间选择器:
- 被明确允许的namespace里的Pod可以访问目标Pod
- 没被明确允许的namespace将禁止访问
- 没有明确允许,即使同一个namespace也禁止访问
- 本例只允许了linux命名空间,那么python命名空间里的Pod将无法访问目标Pod
root@deploy:/yaml/NetWorkPolicy-case/python-ns2# cat case6-ingress-namespaceSelector.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector: #目标pod
matchLabels: {} #允许访问python namespace 中的所有pod
# app: python-tomcat-app1-selector #可以只允许访问python namespace中指定的pod
ingress:
- from:
# - podSelector: #匹配源pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
# matchLabels: {}
# - ipBlock:
# cidr: 10.200.0.0/16 #指定禁止访问的源网段
# except:
# - 10.200.218.0/24 #在以上范围内禁止访问的源IP地址
- namespaceSelector:
# matchLabels: {} #允许所有namespace访问python namespace指定的目标端口或指定的pod加指定端口
matchLabels:
nsname: linux #只允许指定的namespace访问
- namespaceSelector:
matchLabels:
nsname: python #只允许指定的namespace访问
ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- protocol: TCP
port: 8080 #允许通过TCP协议访问目标pod的8080端口,但是其它没有允许的端口将全部禁止访问
#port: 80
- protocol: TCP
port: 3306
- protocol: TCP
port: 6379
使用python命名空间里的nginx访问tomcat,前后对比,加了限制后即使在同一个namespace,也无法访问
7、Egress 案例一
只允许访问指定的目的地址范围和端口
这段 YAML 是定义了一个 NetworkPolicy,它的作用是限制 python
命名空间中的 Pod 出口流量。具体来说,它的策略类型是 Egress(出口),它只匹配具有 app: python-tomcat-app1-selector
标签的 Pod。这个 Pod 会被限制只能访问指定的 IP 地址范围和端口,通过 egress
字段定义了它可以访问的目的 IP 地址范围和端口。其中,ports
数组指定了该 Pod 可以访问的端口和协议,包括 TCP 的 80 端口和 UDP 的 53 端口,这意味着该 Pod 可以访问 HTTP 和 DNS 服务。
root@deploy:/yaml/NetWorkPolicy-case/python-ns2# cat case7-Egress-ipBlock.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-access-networkpolicy
namespace: python
spec:
policyTypes:
- Egress
podSelector: #目标pod选择器
matchLabels: #基于label匹配目标pod
app: python-tomcat-app1-selector #匹配python namespace中app的值为python-tomcat-app1-selector的pod,然后基于egress中的指定网络策略进行出口方向的网络限制
egress:
- to:
- ipBlock:
cidr: 10.200.0.0/16 #允许匹配到的pod出口访问的目的CIDR地址范围
- ipBlock:
cidr: 172.31.7.106/32 #允许匹配到的pod出口访问的目的主机
- ipBlock:
cidr: 0.0.0.0/0 #允许匹配到的pod出口访问的目的主机
ports:
- protocol: TCP
port: 80 #允许匹配到的pod访问目的端口为80的访问
- protocol: TCP
port: 53 #允许匹配到的pod访问目的端口为53 即DNS的解析
- protocol: UDP
port: 53 #允许匹配到的pod访问目的端口为53 即DNS的解析
在python命名空间的tomcat里,分别访问不在egress里的IP,前后对比
8、Egress 示例二
本例对python命名空间里的具有标签app: python-nginx-selector的Pod进行限制,只允许它访问同一个命名空间内具有标签app: python-tomcat-app1-selector的Pod的指定端口。无法访问其他命名空间具有标签app: python-tomcat-app1-selector的Pod。
root@deploy:/yaml/NetWorkPolicy-case/python-ns2# cat case8-Egress-PodSelector.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-access-networkpolicy
namespace: python
spec:
policyTypes:
- Egress
podSelector: #目标pod选择器
matchLabels: #基于label匹配目标pod
app: python-nginx-selector #匹配python namespace中app的值为python-tomcat-app1-selector的pod,然后基于egress中的指定网络策略进行出口方向的网络限制
egress:
- to:
# - ipBlock:
# cidr: 10.200.0.0/16 #允许访问的目的CIDR地址范围
# - ipBlock:
# cidr: 172.31.7.106/32 #允许访问的目的主机地址
# - ipBlock:
# cidr: 10.200.218.4/32 #白名单,允许访问的目的主机地址
- podSelector: #匹配pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
matchLabels:
app: python-tomcat-app1-selector
ports:
- protocol: TCP
port: 8080 #允许80端口的访问
- protocol: TCP
port: 53 #允许DNS的解析
- protocol: UDP
port: 53
在linux命名空间创建一个带有标签app: python-tomcat-app1-selector的Pod,未加限制前源Pod可以访问它,加限制后就不能访问了。所以无法访问其他命名空间具有标签app: python-tomcat-app1-selector的Pod
9、Egress 示例三
本例对python命名空间里的具有标签app: python-nginx-selector的Pod进行出口限制,它只能访问具有标签nsname: python的namespace和具有标签nsname: linux的namespace,且只能访问这两个namespace里的Pod指定的端口。
root@deploy:/yaml/NetWorkPolicy-case/python-ns2# cat case9-Egress-namespaceSelector.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-access-networkpolicy
namespace: python
spec:
policyTypes:
- Egress
podSelector: #目标pod选择器
matchLabels: #基于label匹配目标pod
app: python-nginx-selector #匹配python namespace中app的值为python-tomcat-app1-selector的pod,然后基于egress中的指定网络策略进行出口方向的网络限制
egress:
- to:
# - ipBlock:
# cidr: 10.200.0.0/16 #允许访问的目的CIDR地址范围
# - ipBlock:
# cidr: 172.31.7.106/32 #允许访问的目的主机地址
# - ipBlock:
# cidr: 10.200.218.4/32 #允许访问的目的主机地址
# - podSelector: #匹配pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
# matchLabels:
# app: python-tomcat-app1-selector
- namespaceSelector:
matchLabels:
nsname: python #指定允许访问的目的namespace
- namespaceSelector:
matchLabels:
nsname: linux #指定允许访问的目的namespace
ports:
- protocol: TCP
port: 8080 #允许80端口的访问
- protocol: TCP
port: 53 #允许DNS的解析
- protocol: UDP
port: 53
在default命名空间创建一个tomcat,没加限制前,python-nginx-selector 能够访问三个命名空间的tomcat的8080端口;加限制后,就不能访问default命名空间里的tomcat。
如果将8080端口也禁掉,那么就都不能访问tomcat。
egress:
- to:
- namespaceSelector:
matchLabels:
nsname: python #指定允许访问的目的namespace
- namespaceSelector:
matchLabels:
nsname: linux #指定允许访问的目的namespace
ports:
# - protocol: TCP
# port: 8080 #允许8080端口的访问
- protocol: TCP
port: 53 #允许DNS的解析
- protocol: UDP
port: 53
五、ingress-nginx使用案例
1、kubernetes service 类型简介和案例
1、ClusterIP
ClusterIP 是默认类型,用于k8s内部服务之间的访问,即通过内部的 service IP 实现服务间的访问,service IP 只能在内部访问,外部无法访问。
2、NodePort
在 ClusterIP 的基础之上,通过在每个 node 节点监听一个可以指定宿主机端口(NodePort)来暴露服务,从而允许外部客户端访问k8s集群里的服务,NodePort 把外部客户端的请求转发到 service 进行处理。
3、LoadBalancer
主要在公有云上使用,LoadBalancer 构建在 NodePort 基础之上,通过公有云服务商提供的负载均衡器将k8s集群中的服务暴露给集群外部的客户端访问。
4、ExternalName
用于将k8s集群外部的服务映射到k8s集群内部访问,从而让k8s集群内部的Pod能够通过固定的 service name 访问集群外部的服务,有时候也用于将不同 namespace 之间的 Pod 通过 ExternalName 进行访问。
比如下面这个例子将 www.magedu.com 这个外部域名映射到集群内部,这样集群内的 Pod 就可以通过固定的 service 名称来访问这个域名。
root@deploy:/yaml/4.Ingress-cases# cat 0.2.externalName.yaml
apiVersion: v1
kind: Service
metadata:
name: my-external-test-name
namespace: default
spec:
type: ExternalName #service类型
externalName: www.magedu.com #外部域名
我们创建一个 service ,同时给它指定一个后端服务,就不需要 service 自己去匹配挑选。
比如k8s集群里 Pod 需要访问外部的 redis 服务,这个 YAML 配置文件创建了一个名为 redis-production-server-name
的 Service 和对应的 Endpoints,这个 Service 暴露了 Redis 服务的默认端口号 6379。其他应用程序可以通过这个 Service 的名称 redis-production-server-name
来访问 Redis 服务,Kubernetes 会将请求转发到对应的 IP 地址和端口号上。
root@deploy:/yaml/4.Ingress-cases# cat 0.3.Endpoints.yaml
apiVersion: v1
kind: Service
metadata:
name: redis-production-server-name
namespace: default
spec:
ports:
- port: 6379
---
kind: Endpoints
apiVersion: v1
metadata:
name: redis-production-server-name
namespace: default
subsets:
- addresses:
- ip: 172.23.0.30
ports:
- port: 6379
2、Ingress 简介和应用
我们知道,Kubernetes上的NodePort和LoadBalancer类型的Service资源能够把集群内部服务暴露给集群外部客户端访问,但两个负载均衡跃点必然产生更大的网络延迟,且无疑会大大增加组织在使用云服务方面的费用开销。因此,Kubernetes为这种需求提供了一种更为高级的流量管理约束方式,尤其是对HTTP/HTTPS协议的约束。Kubernetes使用Ingress控制器作为统一的流量入口,管理内部各种必要的服务,并通过Ingress这一API资源来描述如何区分流量以及内部的路由逻辑。有了Ingress和Ingress控制器,我们就可通过定义路由流量的规则来完成服务发布,而无须创建一堆NodePort或LoadBalancer类型的Service,而且流量也会由Ingress控制器直接到达Pod对象。
1、Ingress 是什么?
Ingress是kubernetes API中的标准资源类型之一,ingress 实现的功能是在应用层对客户端请求的host名称或请求的URL路径把请求转发到指定的service资源的规则,即用于将kubernetes集群外部的请求资源转发之集群内部的service,再被service转发之pod处理客户端的请求。
Ingress 可为 Service 提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及基于名称的虚拟托管。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。
2、Ingress 控制器
为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。Ingress资源需要指定监听地址、请求的host和URL等配置,然后根据这些规则的匹配机制将客户端的请求进行转发,这种能够为ingress配置资源监听并转发流量的组件称为ingress控制器(ingress controller),ingress controller是kubernetes的一个附件,类似于dashboard或者flannel 一样,需要单独部署。
ingress 选型:
部署 ingress controller:
Installation Guide - NGINX Ingress Controller (kubernetes.github.io)
3、部署 web 服务和 ingress controller
本例部署两个 tomcat 来模拟不同的项目
root@deploy:/yaml/4.Ingress-cases# cat tomcat-app1.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: magedu-tomcat-app1-deployment-label
name: magedu-tomcat-app1-deployment
namespace: magedu
spec:
replicas: 1
selector:
matchLabels:
app: magedu-tomcat-app1-selector
template:
metadata:
labels:
app: magedu-tomcat-app1-selector
spec:
containers:
- name: magedu-tomcat-app1-container
image: tomcat:7.0.94-alpine
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
resources:
limits:
cpu: 1
memory: "512Mi"
requests:
cpu: 500m
memory: "512Mi"
---
kind: Service
apiVersion: v1
metadata:
labels:
app: magedu-tomcat-app1-service-label
name: magedu-tomcat-app1-service
namespace: magedu
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 40003
selector:
app: magedu-tomcat-app1-selector
root@deploy:/yaml/4.Ingress-cases# cat tomcat-app2.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: magedu-tomcat-app2-deployment-label
name: magedu-tomcat-app2-deployment
namespace: magedu
spec:
replicas: 1
selector:
matchLabels:
app: magedu-tomcat-app2-selector
template:
metadata:
labels:
app: magedu-tomcat-app2-selector
spec:
containers:
- name: magedu-tomcat-app2-container
image: tomcat:7.0.94-alpine
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
resources:
limits:
cpu: 1
memory: "512Mi"
requests:
cpu: 500m
memory: "512Mi"
---
kind: Service
apiVersion: v1
metadata:
labels:
app: magedu-tomcat-app2-service-label
name: magedu-tomcat-app2-service
namespace: magedu
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 40004
selector:
app: magedu-tomcat-app2-selector
部署控制器Installation Guide - NGINX Ingress Controller (kubernetes.github.io)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.6.4/deploy/static/provider/cloud/deploy.yaml
4、实现单host及多host的ingress
1、实现单个虚拟主机
对域名www.jiege.com的访问请求将被转发给名为magedu-tomcat-app1-service的service的80端口上,再由service转发给pod处理。只有访问这个域名才会匹配这个规则进行跳转
root@deploy:/yaml/4.Ingress-cases# cat 2.1.ingress_single-host.yaml
#apiVersion: networking.k8s.io/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-web
namespace: magedu
annotations:
kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
nginx.ingress.kubernetes.io/use-regex: "true" ##指定后面rules定义的path可以使用正则表达式
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" ##连接超时时间,默认为5s
nginx.ingress.kubernetes.io/proxy-send-timeout: "600" ##后端服务器回转数据超时时间,默认为60s
nginx.ingress.kubernetes.io/proxy-read-timeout: "600" ##后端服务器响应超时时间,默认为60s
nginx.ingress.kubernetes.io/proxy-body-size: "50m" ##客户端上传文件,最大大小,默认为20m
#nginx.ingress.kubernetes.io/rewrite-target: / ##URL重写
nginx.ingress.kubernetes.io/app-root: /index.html
#spec:
# rules: #路由规则
# - host: www.jiege.com ##客户端访问的host域名
# http:
# paths:
# - path:
# backend:
# serviceName: magedu-nginx-service #转发至哪个service
# servicePort: 80 ##转发至service的端口号
spec:
rules:
- host: www.jiege.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: magedu-tomcat-app1-service
port:
number: 80
这是我们不是通过访问Pod所在的宿主机来访问服务,而是通过NodePort的方式访问 ingress ,也就是访问宿主机的47238端口。
接着配置负载均衡和域名解析(因为只有访问域名才会匹配这个规则进行跳转)
root@haproxy:~# vim /etc/haproxy/haproxy.cfg
listen ingress-nginx-80
bind 172.23.90.170:80
mode tcp
balance source
server 172.23.0.20 172.23.0.20:47238 check inter 3s fall 3 rise 5
server 172.23.0.21 172.23.0.21:47238 check inter 3s fall 3 rise 5
echo "172.23.90.170 www.jiege.com" >> /etc/hosts
2、实现多个虚拟主机
访问 www.jiege.com 时将请求转发给app1 service, 访问 mobile.jiege.com 时将请求转发给app2 service。
root@deploy:/yaml/4.Ingress-cases# cat 2.2.ingress_multi-host.yaml
#apiVersion: networking.k8s.io/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-web
namespace: magedu
annotations:
kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
nginx.ingress.kubernetes.io/use-regex: "true" ##指定后面rules定义的path可以使用正则表达式
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" ##连接超时时间,默认为5s
nginx.ingress.kubernetes.io/proxy-send-timeout: "600" ##后端服务器回转数据超时时间,默认为60s
nginx.ingress.kubernetes.io/proxy-read-timeout: "600" ##后端服务器响应超时时间,默认为60s
nginx.ingress.kubernetes.io/proxy-body-size: "10m" ##客户端上传文件,最大大小,默认为20m
#nginx.ingress.kubernetes.io/rewrite-target: / ##URL重写
nginx.ingress.kubernetes.io/app-root: /index.html
spec:
rules:
- host: www.jiege.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: magedu-tomcat-app1-service
port:
number: 80
- host: mobile.jiege.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: magedu-tomcat-app2-service
port:
number: 80
配置域名解析后进行访问测试
5、实现基于URL的ingress
访问 www.jiege.com/app1 时将请求转发给app1 service,访问 www.jiege.com/app2 时将请求转发给app2 service。
root@deploy:/yaml/4.Ingress-cases# cat 3.1.ingress-url.yaml
#apiVersion: networking.k8s.io/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-web
namespace: magedu
annotations:
kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
nginx.ingress.kubernetes.io/use-regex: "true" ##指定后面rules定义的path可以使用正则表达式
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" ##连接超时时间,默认为5s
nginx.ingress.kubernetes.io/proxy-send-timeout: "600" ##后端服务器回转数据超时时间,默认为60s
nginx.ingress.kubernetes.io/proxy-read-timeout: "600" ##后端服务器响应超时时间,默认为60s
nginx.ingress.kubernetes.io/proxy-body-size: "10m" ##客户端上传文件,最大大小,默认为20m
#nginx.ingress.kubernetes.io/rewrite-target: / ##URL重写
nginx.ingress.kubernetes.io/app-root: /index.html
spec:
rules:
- host: www.jiege.com
http:
paths:
- pathType: Prefix
path: "/app1" # 所有以 /app1 开头的请求都会匹配这个规则
backend:
service:
name: magedu-tomcat-app1-service
port:
number: 80
- pathType: Prefix
path: "/app2" # 所有以 /app2 开头的请求都会匹配这个规则
backend:
service:
name: magedu-tomcat-app2-service
port:
number: 80
6、ingress实现单域名及多域名https
证书放在 ingress ,将证书以secret形式提前上传到k8s。从 ingress 到客户端走的是 https 加密,从 ingress 到后面的 service 走的是明文 http。
1、单个域名
将证书以secret形式提前上传到k8s
# 生成ca
root@deploy:/yaml/4.Ingress-cases/cert-20230225# openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 3560 -nodes -subj '/CN=www.jiegeca.com'
# 再生成csr
root@deploy:/yaml/4.Ingress-cases/cert-20230225# openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=www.jiege.com'
# 最后对其签发
root@deploy:/yaml/4.Ingress-cases/cert-20230225# openssl x509 -req -sha256 -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
root@deploy:/yaml/4.Ingress-cases/cert-20230225# ll
total 24
drwxr-xr-x 2 root root 88 Feb 25 22:19 ./
drwxr-xr-x 5 root root 4096 Feb 25 22:17 ../
-rw-r--r-- 1 root root 1822 Feb 25 22:18 ca.crt
-rw------- 1 root root 3272 Feb 25 22:18 ca.key
-rw-r--r-- 1 root root 1671 Feb 25 22:19 server.crt
-rw-r--r-- 1 root root 1590 Feb 25 22:18 server.csr
-rw------- 1 root root 3272 Feb 25 22:18 server.key
# 将证书上传到k8s
root@deploy:/yaml/4.Ingress-cases/cert-20230225# kubectl create secret tls tls-secret-www --cert=server.crt --key=server.key -n magedu
root@deploy:/yaml/4.Ingress-cases/cert-20230225# kubectl get secrets -n magedu
NAME TYPE DATA AGE
tls-secret-www kubernetes.io/tls 2 21s
查看证书信息
kubectl get secrets tls-secret-www -n magedu -o yaml
创建 ingress 规则
root@deploy:/yaml/4.Ingress-cases# cat 4.1.ingress-https-magedu_single-host.yaml
#apiVersion: networking.k8s.io/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-web
namespace: magedu
annotations:
kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
nginx.ingress.kubernetes.io/ssl-redirect: 'true' #SSL重定向,即将http请求强制重定向至https,等于nginx中的全站https
spec:
tls:
- hosts:
- www.jiege.com
secretName: tls-secret-www # 调用的证书
rules:
- host: www.jiege.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: magedu-tomcat-app1-service
port:
number: 80
配置好haproxy,这里的端口根据查看 ingress 控制器的 service 信息得来
root@deploy:/yaml/4.Ingress-cases# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.100.33.59 <none> 80:47238/TCP,443:56006/TCP 23h
listen ingress-nginx-80
bind 172.23.90.170:80
mode tcp
balance source
server 172.23.0.20 172.23.0.20:47238 check inter 3s fall 3 rise 5
server 172.23.0.21 172.23.0.21:47238 check inter 3s fall 3 rise 5
listen ingress-nginx-443
bind 172.23.90.170:443
mode tcp
balance source
server 172.23.0.20 172.23.0.20:56006 check inter 3s fall 3 rise 5
server 172.23.0.21 172.23.0.21:56006 check inter 3s fall 3 rise 5
2、多个域名
# 创建证书
root@deploy:/yaml/4.Ingress-cases/cert-20230225# openssl req -new -newkey rsa:4096 -keyout mobile.key -out mobile.csr -nodes -subj '/CN=mobile.jiege.com'
# 对其签发
root@deploy:/yaml/4.Ingress-cases/cert-20230225# openssl x509 -req -sha256 -days 3650 -in mobile.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out mobile.crt
# 以 secret 形式上传到 k8s
root@deploy:/yaml/4.Ingress-cases/cert-20230225# kubectl create secret tls tls-secret-mobile --cert=mobile.crt --key=mobile.key -n magedu
root@deploy:/yaml/4.Ingress-cases/cert-20230225# kubectl get secrets -n magedu
NAME TYPE DATA AGE
tls-secret-mobile kubernetes.io/tls 2 71s
tls-secret-www kubernetes.io/tls 2 28m
创建 ingress 规则
这是一个 Kubernetes Ingress 资源的 YAML 文件,它描述了如何将 HTTP(S) 流量路由到 Kubernetes 集群内的服务。具体来说,它使用了 networking.k8s.io/v1
API 版本的 Ingress 类型,指定了名称为 nginx-web-mobile
、命名空间为 magedu
的 Ingress 资源。
此外,还指定了一些注释(annotations),用于配置 Ingress Controller。其中,kubernetes.io/ingress.class: "nginx"
指定了使用的 Ingress Controller 类型为 Nginx。nginx.ingress.kubernetes.io/ssl-redirect: 'true'
表示启用 SSL 重定向功能。
在规格(spec)部分,指定了使用 TLS 加密协议的主机名和证书密钥。具体来说,tls
字段指定了两个主机名 mobile.jiege.com
和 www.jiege.com
,分别使用名为 tls-secret-mobile
和 tls-secret-www
的 TLS 证书密钥。然后,使用 rules
字段来指定如何将请求路由到服务。在这个例子中,对于 www.jiege.com
和 mobile.jiege.com
两个主机,它们的根路径("/"
)都会被路由到不同的服务(magedu-tomcat-app1-service
和 magedu-tomcat-app2-service
),使用 HTTP 端口 80。路由规则使用了 pathType: Prefix
,表示匹配路径的前缀。
root@deploy:/yaml/4.Ingress-cases# cat 4.2.ingress-https-magedu_multi-host.yaml
#apiVersion: networking.k8s.io/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-web-mobile
namespace: magedu
annotations:
kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
nginx.ingress.kubernetes.io/ssl-redirect: 'true'
spec:
tls:
- hosts:
- mobile.jiege.com
secretName: tls-secret-mobile
- hosts:
- www.jiege.com
secretName: tls-secret-www
rules:
- host: www.jiege.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: magedu-tomcat-app1-service
port:
number: 80
- host: mobile.jiege.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: magedu-tomcat-app2-service
port:
number: 80
7、ingress 证书更新
当证书即将过期时,为了不影响业务,对证书进行更新
1、准备好新的证书
root@deploy:/yaml/4.Ingress-cases/cert-2023-02-25-23-12-56# tree
.
├── ca.crt
├── ca.key
├── mobile.crt
├── mobile.csr
├── mobile.key
├── server.crt
├── server.csr
└── server.key
2、查看公钥和私钥信息并加密
查看公钥和私钥的信息,并在网上使用base64加密工具进行加密
root@deploy:/yaml/4.Ingress-cases/cert-2023-02-25-23-12-56# cat server.crt
-----BEGIN CERTIFICATE-----
MIIEpjCCAo4CAQEwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAwwPd3d3LmppZWdl
Y2EuY29tMB4XDTIzMDIyNTE1MTQxNFoXDTMzMDIyMjE1MTQxNFowGDEWMBQGA1UE
AwwNd3d3LmppZWdlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
AM6SKVVfE02nWwohrBKAzx6EjSsazRaU6xFkKxqNFXfg2/fYkSRy9Sj2UuNdotEh
0OEmrSNRRbHyHXCPKyXTmWCzwR54I1TVzWmFW9SASFZzI8zwwCk9M3wJHJH+ZzL+
FaEcExdt1RlQ/UDiaQevz8W0zG62EvTRbUqRGzFnlGfcqzFt4k77q81WqdHHadHT
Y68iR3+WWb4OqsYY5QC17pmXK2YNnAzLacoO34COuz4GAylSNlpNsVrxizeTzfAF
n8y9fNtCyDZbaf1tH3yJ2jzeYQQg12FZZrqmn9+pVeAG4onGwjafpBEOqyRaLWde
7wHWiwjB6Mod4A62EjD3i9eiC9iY8VPDgnRP7ADlZpLDaCn3ruq+KxO7DD9X9PWC
VEBzaylkY9QzbEOlA8auCkvuzxkGotTbFQZEk4MpXUwphKrzaD17+ZqA+4XnCLtR
rFEruy+EWk1HcD3xUcG6qQCpMOzPUrVx35m2n8XZq+lnSLg9HJitvHyg+2ASUUdR
DcGxvBd/UyH7bFP78D1udqvPB4vTGpg8hbo1NgQdqxSljNE2LbUnPWceBgp6weiY
EIllztamHjxA0OqouLH3C0kqoeZ1Y5kuUizNG5wzejjVJAaSp8W34lnNGi3W9olS
kJtqOa0dB7el6+7w5QfADmjnX7kyf4A0Kd3f7wAxoD49AgMBAAEwDQYJKoZIhvcN
AQELBQADggIBAHpHxHFm7DaBRoGC+XfYwYV/HqgbjVI7pSHPiHqjk4NSvYI7Yz2X
rUwH7+k9cWEm2Knpv+qDv07muFRJjiZMjqnXeJSFh3A20SmIBSUAKCpAsq/0GTcc
rk2Yz26scqNRuuXtijz+5tRTEtiExXkN0qeMpAtnbJIte+NFOfRUd1jpNuqDRLrb
aXmYpZI1DYy5lOrIm9UQWVJoilV2qf3GcnXTPFqblzsWzizsCxMB2ZZ7ZgnzyZNj
C3azpvhfjt2n7Zn96Frwi6sFxeD5i5qTjl87FH80EdcPKEilZcd0DLQtbF0OJpnU
Xi7EBtijglZ4fElgSORF3mug5OJJLAk1gJc7vauyais0ksKkJfCHvBpWmqXMG6WG
uf7EoTSLyU/XbsBY//lWqHKXke/kspasRSQ+oom64Q58c6GWBJ1AmxK1/xRn27v2
S3F5OTCmBZ8SE6UANI1htzDaUPC03AZvL/eZDRosqjAjdWjFI2+kccmQdCWUNBtk
cJ8rqVmNOO17oB7ARFK8iuRg3TpkTOWQgySLYjDLnBhMOZJYgUE4u6+upIOeN+S6
aSRsAKFpkYS4ZaQDrN/60neIj2n+iqfgo6gTsfNSoSMQ3abhcC9Vov2t5sZuen5+
P/Nicmwo8PROtGyDSMW1LzPBiQw9IxuFYs+ILUcQxwoHc863thHG/OZJ
-----END CERTIFICATE-----
在这个base64在线加密网站进行加密https://base64.us/ ,下面是加密后的公钥。私钥也是一样操作
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVwakNDQW80Q0FRRXdEUVlKS29aSWh2Y05BUUVMQlFBd0dqRVlNQllHQTFVRUF3d1BkM2QzTG1wcFpXZGwKWTJFdVkyOXRNQjRYRFRJek1ESXlOVEUxTVRReE5Gb1hEVE16TURJeU1qRTFNVFF4TkZvd0dERVdNQlFHQTFVRQpBd3dOZDNkM0xtcHBaV2RsTG1OdmJUQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCCkFNNlNLVlZmRTAybld3b2hyQktBeng2RWpTc2F6UmFVNnhGa0t4cU5GWGZnMi9mWWtTUnk5U2oyVXVOZG90RWgKME9FbXJTTlJSYkh5SFhDUEt5WFRtV0N6d1I1NEkxVFZ6V21GVzlTQVNGWnpJOHp3d0NrOU0zd0pISkgrWnpMKwpGYUVjRXhkdDFSbFEvVURpYVFldno4VzB6RzYyRXZUUmJVcVJHekZubEdmY3F6RnQ0azc3cTgxV3FkSEhhZEhUClk2OGlSMytXV2I0T3FzWVk1UUMxN3BtWEsyWU5uQXpMYWNvTzM0Q091ejRHQXlsU05scE5zVnJ4aXplVHpmQUYKbjh5OWZOdEN5RFpiYWYxdEgzeUoyanplWVFRZzEyRlpacnFtbjkrcFZlQUc0b25Hd2phZnBCRU9xeVJhTFdkZQo3d0hXaXdqQjZNb2Q0QTYyRWpEM2k5ZWlDOWlZOFZQRGduUlA3QURsWnBMRGFDbjNydXErS3hPN0REOVg5UFdDClZFQnpheWxrWTlRemJFT2xBOGF1Q2t2dXp4a0dvdFRiRlFaRWs0TXBYVXdwaEtyemFEMTcrWnFBKzRYbkNMdFIKckZFcnV5K0VXazFIY0QzeFVjRzZxUUNwTU96UFVyVngzNW0ybjhYWnErbG5TTGc5SEppdHZIeWcrMkFTVVVkUgpEY0d4dkJkL1V5SDdiRlA3OEQxdWRxdlBCNHZUR3BnOGhibzFOZ1FkcXhTbGpORTJMYlVuUFdjZUJncDZ3ZWlZCkVJbGx6dGFtSGp4QTBPcW91TEgzQzBrcW9lWjFZNWt1VWl6Tkc1d3plampWSkFhU3A4VzM0bG5OR2kzVzlvbFMKa0p0cU9hMGRCN2VsNis3dzVRZkFEbWpuWDdreWY0QTBLZDNmN3dBeG9ENDlBZ01CQUFFd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnSUJBSHBIeEhGbTdEYUJSb0dDK1hmWXdZVi9IcWdialZJN3BTSFBpSHFqazROU3ZZSTdZejJYCnJVd0g3K2s5Y1dFbTJLbnB2K3FEdjA3bXVGUkpqaVpNanFuWGVKU0ZoM0EyMFNtSUJTVUFLQ3BBc3EvMEdUY2MKcmsyWXoyNnNjcU5SdXVYdGlqeis1dFJURXRpRXhYa04wcWVNcEF0bmJKSXRlK05GT2ZSVWQxanBOdXFEUkxyYgphWG1ZcFpJMURZeTVsT3JJbTlVUVdWSm9pbFYycWYzR2NuWFRQRnFibHpzV3ppenNDeE1CMlpaN1pnbnp5Wk5qCkMzYXpwdmhmanQybjdabjk2RnJ3aTZzRnhlRDVpNXFUamw4N0ZIODBFZGNQS0VpbFpjZDBETFF0YkYwT0pwblUKWGk3RUJ0aWpnbFo0ZkVsZ1NPUkYzbXVnNU9KSkxBazFnSmM3dmF1eWFpczBrc0trSmZDSHZCcFdtcVhNRzZXRwp1ZjdFb1RTTHlVL1hic0JZLy9sV3FIS1hrZS9rc3Bhc1JTUStvb202NFE1OGM2R1dCSjFBbXhLMS94Um4yN3YyClMzRjVPVENtQlo4U0U2VUFOSTFodHpEYVVQQzAzQVp2TC9lWkRSb3NxakFqZFdqRkkyK2tjY21RZENXVU5CdGsKY0o4cnFWbU5PTzE3b0I3QVJGSzhpdVJnM1Rwa1RPV1FneVNMWWpETG5CaE1PWkpZZ1VFNHU2K3VwSU9lTitTNgphU1JzQUtGcGtZUzRaYVFEck4vNjBuZUlqMm4raXFmZ282Z1RzZk5Tb1NNUTNhYmhjQzlWb3YydDVzWnVlbjUrClAvTmljbXdvOFBST3RHeURTTVcxTHpQQmlRdzlJeHVGWXMrSUxVY1F4d29IYzg2M3RoSEcvT1pKCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
3、编辑 secret 文件
因为证书是以 secret 的形式上传到k8s的,所以我们进行编辑和替换 secret 文件。编辑保存好直接生效。
root@deploy:/yaml/4.Ingress-cases/cert-2023-02-25-23-12-56# kubectl get secrets -n magedu
NAME TYPE DATA AGE
tls-secret-mobile kubernetes.io/tls 2 32m
tls-secret-www kubernetes.io/tls 2 60m
root@deploy:/yaml/4.Ingress-cases/cert-2023-02-25-23-12-56# kubectl -n magedu edit secrets tls-secret-www
4、浏览器验证
之前的证书是22:49:14颁发的,现在的变成23:14:14颁发的,证书更新成功。