IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> kubernetes(2)service、ingress、网络通信及calico -> 正文阅读

[系统运维]kubernetes(2)service、ingress、网络通信及calico

一、service

Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。Service 是由 kube-proxy 组件,加上 iptables 来共同实现的。kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables 规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源。

1.开启kube-proxy的ipvs模式

在 ipvs 模式下,kube-proxy 监视 Kubernetes 服务和端点,调用 netlink 接口相应地创建 IPVS 规则, 并定期将 IPVS 规则与 Kubernetes 服务和端点同步。 该控制循环可确保IPVS 状态与所需状态匹配。访问服务时,IPVS 将流量定向到后端Pod之一。

IPVS代理模式基于类似于 iptables 模式的 netfilter 挂钩函数, 但是使用哈希表作为基础数据结构,并且在内核空间中工作。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。 与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。

所有节点中? yum install -y ipvsadm

[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl get pod -n kube-system 
[root@server2 ~]# kubectl get all
[root@server2 ~]# kubectl delete svc liveness-http 
[root@server2 ~]# kubectl get svc
[root@server2 ~]# yum install -y ipvsadm
[root@server2 ~]# ipvsadm -ln
[root@server2 ~]# kubectl -n kube-system get pod

将模式改为ipvs ,然后更新(就是删除之前的重新建立)


[root@server2 ~]# kubectl -n kube-system get svc
[root@server2 ~]# kubectl -n kube-system get cm
[root@server2 ~]# kubectl edit cm kube-proxy -n kube-system

 mode: "ipvs"

[root@server2 ~]# kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'

?查看策略

[root@server2 ~]# ipvsadm -ln

?查看其他节点策略:

IPVS 提供了更多选项来平衡后端 Pod 的流量。 这些是:

rr:轮替(Round-Robin)
lc:最少链接(Least Connection),即打开链接数量最少者优先
dh:目标地址哈希(Destination Hashing)
sh:源地址哈希(Source Hashing)
sed:最短预期延迟(Shortest Expected Delay)
nq:从不排队(Never Queue)

[root@server2 ~]# kubectl get pod -n kube-system

[root@server2 ~]# kubectl get pod -n kube-system -o wide

?[root@server2 ~]# kubectl? -n kube-system describe svc kube-dns

IPVS模式下,kube-proxy会在service创建后,在宿主机上添加一个虚拟网卡:kube-ipvs0,并分配service IP。
[root@server2 ~]# ip addr

kube-proxy通过linux的IPVS模块,以rr轮询方式调度service中的Pod。
[root@server2 ~]# ipvsadm -ln

2.创建service:(ClusterIP方式)

[root@server2 ~]# mkdir service
[root@server2 ~]# cd service/
[root@server2 service]# vim clusterip.yml
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector:
      app: myapp
  type: ClusterIP
[root@server2 service]# kubectl apply -f clusterip.yml 
service/web-service created
[root@server2 service]# kubectl get svc
[root@server2 service]# ip addr
[root@server2 service]# ipvsadm -ln

??创建副本:

[root@server2 ~]# cd pod/
[root@server2 pod]# ls
cronjob.yml  daemonset.yaml  deploy.yaml  job.yml  pod1.yml  pod.yml
[root@server2 pod]# cat deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1
[root@server2 pod]# kubectl apply -f deploy.yaml 
deployment.apps/myapp-deployment created
[root@server2 pod]# kubectl get pod

[root@server2 service]# kubectl get pod --show-labels
[root@server2 service]# kubectl describe svc web-service 

?curl IP

[root@server2 service]# kubectl get pod -n kube-system
[root@server2 service]# kubectl get svc -n kube-system

[root@server2 service]# kubectl run -it demo --image=busyboxplus

kube-proxy通过linux的IPVS模块,以rr轮询方式调度service中的Pod?

3.无头服务

Headless Service不需要分配一个VIP,而是直接以DNS记录的方式解析出被代理Pod的IP地址。

[root@server2 service]# ls
clusterip.yml
[root@server2 service]# kubectl delete -f clusterip.yml 
service "web-service" deleted
[root@server2 service]# vim clusterip.yml 
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector:
      app: myapp
  #type: ClusterIP
  clusterIP: None 
[root@server2 service]# kubectl apply -f clusterip.yml 
service/web-service created
[root@server2 service]# kubectl get svc
[root@server2 service]# kubectl describe svc web-service 

?dig查看解析

4.创建service:(NodePort方式)

[root@server2 service]# kubectl delete -f clusterip.yml 
service "web-service" deleted
[root@server2 service]# ls
clusterip.yml
[root@server2 service]# mv clusterip.yml svc.yml
[root@server2 service]# vim svc.yml 
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector:
      app: myapp
  type: NodePort
[root@server2 service]# kubectl apply -f svc.yml 
service/web-service created
[root@server2 service]# kubectl get pod
[root@server2 service]# kubectl get svc

?[root@server2 service]# ipvsadm -ln

[root@server2 service]# ip addr

[root@server2 service]# kubectl get svc

?在客户端使用curl命令访问:

[root@server3 ~]# yum install -y ipvsadm
[root@server3 ~]# ipvsadm -ln ? ? ##查看策略

5.公有云的k8s对外访问方式

从外部访问 Service 的第二种方式,适用于公有云上的 Kubernetes 服务。这时候,你可以指定一个 LoadBalancer 类型的 Service。

更改type

[root@server2 service]# kubectl edit svc web-service
service/web-service edited

  type: LoadBalancer

?修改kube-proxy的配置:

[root@server2 service]# kubectl edit configmap -n kube-system kube-proxy
configmap/kube-proxy edited

 strictARP: true

?修改完成后,删除副本,副本自动创建,重新生成副本使得修改生效

[root@server2 service]# kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
pod "kube-proxy-gs2tq" deleted
pod "kube-proxy-qlsn8" deleted
pod "kube-proxy-vtrf2" deleted
[root@server2 service]# 

?在官网get与私有云对接的文件

[root@server2 metallb]# wget https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/namespace.yaml
[root@server2 metallb]# wget https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/metallb-v0.11.0.yaml
[root@server2 metallb]# vim metallb-v0.11.0.yaml ##查看需要的镜像

?先下载需要的镜像到仓库

[root@server1 harbor]# docker pull quay.io/metallb/speaker:v0.11.0
[root@server1 harbor]# docker pull quay.io/metallb/controller:v0.11.0
[root@server1 harbor]# docker tag quay.io/metallb/speaker:v0.11.0 reg.westos.org/metallb/speaker:v0.11.0
[root@server1 harbor]# docker tag quay.io/metallb/controller:v0.11.0  reg.westos.org/metallb/controller:v0.11.0
[root@server1 harbor]# docker push reg.westos.org/metallb/speaker:v0.11.0
[root@server1 harbor]# docker push reg.westos.org/metallb/controller:v0.11.0

?修改文件中的镜像路径:

[root@server2 metallb]# vim metallb-v0.11.0.yaml 
     image: metallb/controller:v0.11.0
       image: metallb/speaker:v0.11.0

[root@server2 metallb]# vim namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: metallb-system
  labels:
    app: metallb
[root@server2 metallb]# kubectl apply -f namespace.yaml 
namespace/metallb-system created
[root@server2 metallb]#  kubectl get ns
NAME              STATUS   AGE
default           Active   47h
kube-node-lease   Active   47h
kube-public       Active   47h
kube-system       Active   47h
metallb-system    Active   46s
[root@server2 metallb]# 

?[root@server2 metallb]# kubectl apply -f metallb-v0.11.0.yaml
[root@server2 metallb]# kubectl -n metallb-system get pod

?编辑配置文件,给定IP:

?测试访问

?负载均衡通过configmap分配IP,供外部访问,真正的负载均衡由service提供

6.ExternalName

?从外部访问的第三种形式ExtenalName,通过给定域名访问解析

拉起容器后查看服务信息,可以看到externalname额外的域名??

?dig查看详细解析A记录

[root@server2 metallb]# vim ex-svc.yml
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type:  ExternalName
  externalName: www.baidu.com
[root@server2 metallb]# kubectl apply -f ex-svc.yml 
service/my-service configured
[root@server2 metallb]# kubectl get svc
[root@server2 metallb]# dig -t A my-service.default.svc.cluster.local. @10.96.0.10

7.分配一个公有IP

?service允许为其分配一个公有IP。

[root@server2 metallb]# vim ex-ip.yml
apiVersion: v1
kind: Service
metadata:
  name: ex-ip
spec:
  selector:
    app: myapp
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80
  externalIPs:
  - 172.25.52.111

[root@server2 metallb]# kubectl get pod --show-labels
[root@server2 metallb]# kubectl apply -f ex-ip.yml 
service/ex-ip created
[root@server2 metallb]# kubectl get svc

?[root@server2 metallb]# ip addr

[root@server2 metallb]# curl 172.25.52.111?? ##内部可以访问
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 metallb]# curl 172.25.52.111/hostname.html

在集群外部无法访问:

需要添加IP

?[root@server2 metallb]# ip addr add 172.25.52.111/24 dev eth0

外网可以访问了?

二、ingress服务

一种全局的、为了代理不同后端 Service 而设置的负载均衡服务,就是 Kubernetes 里的Ingress 服务。Ingress Controller 会根据你定义的 Ingress 对象,提供对应的代理能力。业界常用的各种反向代理项目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已经为Kubernetes 专门维护了对应的 Ingress Controller。 ?

参考文档:Installation Guide - NGINX Ingress Controller

从官网获取文档

[root@server2 metallb]# kubectl delete svc ex-ip 
service "ex-ip" deleted
[root@server2 metallb]# cd ..
[root@server2 service]# mkdir ingress
[root@server2 service]# cd ingress/
[root@server2 ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/baremetal/deploy-v1.1.0.yaml

?拉取所需要的镜像并上传至仓库

[root@server1 ~]# docker search ingress-nginx
[root@server1 ~]# docker pull wangshun1024/ingress-nginx-controller:v1.1.0  
[root@server1 ~]# docker pull wangshun1024/kube-webhook-certgen:v1.1.1
[root@server1 ~]# docker tag wangshun1024/kube-webhook-certgen:v1.1.1 reg.westos.org/ingress-nginx/kube-webhook-certgen:v1.1.1
[root@server1 ~]# docker push reg.westos.org/ingress-nginx/kube-webhook-certgen:v1.1.1
[root@server1 ~]# docker tag wangshun1024/ingress-nginx-controller:v1.1.0 reg.westos.org/ingress-nginx/controller:v1.1.0
[root@server1 ~]# docker push reg.westos.org/ingress-nginx/controller:v1.1.0

在仓库中查看镜像:

[root@server2 ingress]# vim deploy-v1.1.0.yaml  ##修改镜像地址

  image: ingress-nginx/controller:v1.1.0
  image: ingress-nginx/kube-webhook-certgen:v1.1.1
 
  image: ingress-nginx/kube-webhook-certgen:v1.1.1

[root@server2 ingress]# kubectl apply -f deploy-v1.1.0.yaml

[root@server2 ingress]# kubectl -n ingress-nginx get all

?[root@server2 ingress]# kubectl -n ingress-nginx describe svc ingress-nginx-controller

?

[root@server2 ingress]# kubectl -n ingress-nginx edit svc ingress-nginx-controller
service/ingress-nginx-controller edited

  type: LoadBalancer

[root@server2 ingress]# kubectl -n ingress-nginx get svc
[root@server2 ingress]# kubectl -n ingress-nginx get pod

?在客户端访问:

[root@server2 ingress]# kubectl -n ingress-nginx logs ingress-nginx-controller-77f65b6696-z8bqb?

?

开启ingress?

?

[root@server2 service]# ls
ingress  metallb  svc.yml
[root@server2 service]# cd ingress/
[root@server2 ingress]# vim ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-myservicea
spec:
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web1
            port:
              number: 80
  ingressClassName: nginx
[root@server2 ingress]# kubectl apply -f ingress.yml 
ingress.networking.k8s.io/ingress-myservicea created
[root@server2 ingress]# kubectl get ingress
NAME                 CLASS   HOSTS             ADDRESS   PORTS   AGE
ingress-myservicea   nginx   www1.westos.org             80      11s
[root@server2 ingress]# 

添加地址解析后可以ping通?

?

?测试:

?

?

[root@server2 service]# ls
ingress  metallb  svc.yml
[root@server2 service]# vim svc.yml 
apiVersion: v1
kind: Service
metadata:
  name: web1
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector:
      app: myapp
  type: ClusterIP
[root@server2 service]# cd ingress/
[root@server2 ingress]# ls
deployment.yml  deploy-v1.1.0.yaml  ingress.yml
[root@server2 ingress]# vim deployment.yml   
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: myapp:v2
---
apiVersion: v1
kind: Service
metadata:
  name: web1
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector:
    app: nginx
  type: ClusterIP
[root@server2 ingress]# kubectl apply -f deployment.yml 
deployment.apps/nginx-deployment unchanged
service/web2 created
[root@server2 ingress]# kubectl get pod
[root@server2 ingress]# kubectl get svc
[root@server2 ingress]# curl 10.99.230.235 
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@server2 ingress]#

?

[root@server2 ingress]# ls
deployment.yml  deploy-v1.1.0.yaml  ingress.yml
[root@server2 ingress]# vim ingress.yml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-myservicea
spec:
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web1
            port:
              number: 80
  - host: www2.westos.org
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web2
            port:
              number: 80
  ingressClassName: nginx
[root@server2 ingress]# kubectl apply -f ingress.yml 
ingress.networking.k8s.io/ingress-myservicea configured
[root@server2 ingress]# kubectl describe ingress ingress-myservicea 

?

外网也可访问

?Ingress TLS 配置?

[root@server2 ingress]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
[root@server2 ingress]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt 
secret/tls-secret created

?[root@server2 ingress]# vim ingress.yml

?

?访问http://www1.westos.org/

?

?访问http://www1.westos.org/hostname.html??? ——>查看负载均衡

?

?

?

?添加认证

[root@server2 ingress]# yum install -y httpd-tools
[root@server2 ingress]# htpasswd -c auth gyy
New password: 
Re-type new password: 
Adding password for user gyy
[root@server2 ingress]# cat auth 
gyy:$apr1$ubjVCDpD$I0rH03f29hsH21KdXMYLf.
[root@server2 ingress]# kubectl create secret generic basic-auth --from-file=auth
secret/basic-auth created
[root@server2 ingress]# kubectl get secrets 

[root@server2 ingress]# vim ingress.yml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-myservicea
  annotations:
    nginx.ingress.kubernetes.io/app-root: /hostname.html  ##重定向
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - gyy'
spec:
  tls:
    - hosts:
      - www1.westos.org
      secretName: tls-secret
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web1
            port:
              number: 80
  - host: www2.westos.org
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web2
            port:
              number: 80
  ingressClassName: nginx

? 此时访问需要输入用户和密码

?

?

?三、k8s网络通信

?????? k8s是通过CNI接口接入插件来实现网络通讯的。目前较为流行的插件有flannel、calico等。
插件存放位置在/etc/cni/net.d/,因此更改、重置网络插件都需要将这个目录下的文件清空。

插件主要工作解决方案如下:
1.多个容器共用一个虚拟网卡,使用虚拟网桥和虚拟网卡进行通信。
2.多个容器共用一个物理网卡进行通信,在二层使用Mac地址。
3.一个物理网卡可以虚拟机出多个接口,硬件交换的方式实现,此方法性能最优,但是成本也高。

主要通信包括:

  • 容器间通信:同一个pod内的容器通过回环接口实现。
  • pod之间的通信,分为同一节点之间的pod和不同节点之间的pod:同一节点之间的pod通过cni网桥转发数据包,实现pod-ip访问pod-ip。不同结点之间的pod通过网络插件支持。
  • pod与service间的通信:想要pod-ip去访问Cluster-ip,实质上Cluster-ip是通过iptables和ipvs虚拟出来的ip,不影响pod访问。同样,ipvs也无法代替iptables,因为ipvs只能做负载均衡为iptables减缓刷新压力,真正的nat转换是通过iptables实现的。
  • pod和外网通信:iptables的MASQUERADE。
  • Service与集群外部客户端的通信:(ingress、nodeport、loadbalancer)。

? [root@server2 ingress]# ip addr

[root@server3 ~]# yum install -y bridge-utils
[root@server3 ~]# brctl show
[root@server3 ~]# ip addr

?

Flannel vxlan模式

VXLAN,即Virtual Extensible LAN (虚拟可扩展局域网) ,是Linux本身支持的一网种网络虚拟化技术。VXLAN可以完全在内核态实现封装和解封装工作,从而通过“隧道” 机制,构建出覆盖网络(Overlay Network)。

  • VTEP: VXLAN Tunnel End Point (虚拟隧道端点),在Flannel中VNI的默认值是1,这也是为什么宿主机的VTEP设备都叫flannel.1的原因。
  • Cni0:网桥设备,每创建一个pod都会创建- 对veth pair。 其中一端是pod中的eth0, 另一端是Cni0网桥中的端口(网卡)。
  • Flannel.1: TUN设备(虚拟网卡),用来进行vxlan报文的处理(封包和解包)。不同node之间的pod数据流量都从overlay设备以隧道的形式发送到对端。
  • Flanneld: flannel在每 个主机中运行flanneld作为agent,它会为所在主机从集群的网络地址空间中,获取一个小的网段subnet,本主机内所有容器的IP地址都将从中分配。同时Flanneld监听K8s集群数据库,为flannel. 1设备提供封装数据时必要的mac、ip等网络数据信息

?DR模式实现

查看节点网关此时是flannel

[root@server2 ingress]# kubectl -n kube-system get cm

[root@server2 ingress]# kubectl -n kube-system edit cm kube-flannel-cfg ##修改
configmap/kube-flannel-cfg edited
        "Type": "host-gw"

?

?

?删除重建会自动更新

[root@server2 ingress]# kubectl get pod -n kube-system | grep kube-flannel | awk '{system("kubectl delete pod "$1" -n kube-system")}'

?查看各个节点网关都已变为docker_gwbridge

四、calico网络插件

1.calico简介:

flannel实现的是网络通信,calico的特性是在pod之间的隔离。
通过BGP路由,但大规模端点的拓扑计算和收敛往往需要一定的时间和计算资源。
纯三层的转发,中间没有任何的NAT和overlay,转发效率最好。
Calico 仅依赖三层路由可达。Calico 较少的依赖性使它能适配所有 VM、Container、白盒或者混合环境场景

从官方获取文档

[root@server2 service]# mkdir calico
[root@server2 service]# cd calico/
[root@server2 calico]# wget https://docs.projectcalico.org/manifests/calico.yaml --no-check-certificate

拉取所需镜像并上传至仓库

[root@server1 ~]# docker pull calico/cni:v3.21.2
[root@server1 ~]# docker pull calico/pod2daemon-flexvol:v3.21.2
[root@server1 ~]# docker pull calico/node:v3.21.2
[root@server1 ~]# docker pull calico/kube-controllers:v3.21.2
[root@server1 ~]# docker images | grep calico | awk '{system("docker tag "$1":"$2" reg.westos.org/"$1":"$2"")}'
[root@server1 ~]# docker images | grep reg.westos.org/calico | awk '{system("docker push "$1":"$2"")}'

?[root@server2 calico]# vim calico.yaml?? ##修改镜像下载地址,与仓库保持一致

?

?注意:在执行前需要删除flannel,否则有冲突

每个节点都要删除10-flannel.conflist?

?

?[root@server2 calico]# kubectl apply -f calico.yaml?

?查看节点

?切换完成之后,测试一下

? 在浏览器访问:

?

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-01-24 11:21:19  更:2022-01-24 11:23:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 7:50:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码