Skip to content

007编写K8sYaml

部署应用所需资源

  • namespace
    • 资源隔离:不同的Namespace中的资源相互隔离,避免资源之间的冲突和影响
    • 管理资源:可以将相同类型的资源组织在同一个Namespace中,便于管理和监控
    • 权限控制:可以通过RBAC(基于角色的访问控制)来对不同的Namespace进行权限控制,实现对资源的访问控制。
    • 环境隔离:可以在不同的Namespace中部署不同的环境,如开发、测试、生产等,提高资源的安全性和稳定性。
  • statefulset
    • 管理有状态应用的Pod部署和伸缩
    • 更适用于需要持久化存储、唯一标识和有序部署的场景
    • 有序部署:StatefulSet能够按照定义的顺序,逐个部署Pod实例,确保它们按照固定的命名规则有序启动。
    • 稳定的网络标识:每个Pod都有一个稳定的网络标识(如DNS名称),使得它们可以方便地被其他应用或服务引用。
    • 持久化存储:StatefulSet支持使用持久化卷,确保Pod实例的数据可以持久保存,并在Pod重新调度时保留。
  • service
    • 定义访问Pod的规则:Service通过Label Selector来选择一组Pod,使得这些Pod共同对外提供服务。
    • 负载均衡:Service会为选择到的Pod分配一个Cluster IP,用于内部负载均衡,可以让用户无需关心具体Pod的IP地址就能访问服务。
    • 服务发现:Service可以通过Service Name来发现和访问特定服务,而不需要了解具体Pod的IP地址。
  • ingress
    • 把集群内 Service 配置成外网能够访问的 URL
    • 流量负载均衡
    • 提供基于域名访问的虚拟主机

部署模版

在K8s中,可以使用--dry-run=client--dry-run=server来启用dryrun模式。当使用client时,只会模拟请求,不会发送到服务器。当使用 server时,请求会被发送到服务器,但是不会实际执行。

Namespace

创建一个命名空间来组织相关的资源

yaml
 apiVersion: v1
 kind: Namespace
 metadata:
   name: namespace-cutejava-tiny-service

StatefulSet

管理有状态的应用,如数据库或消息队列

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset-cutejava-tiny-service
  namespace: namespace-cutejava-tiny-service
spec:
  serviceName: statefulset-cutejava-tiny-service
  replicas: 2
  selector:
    matchLabels:
      app: statefulset-cutejava-tiny-service
  template:
    metadata:
      labels:
        app: statefulset-cutejava-tiny-service
    spec:
      containers:
        - name: pod-cutejava-tiny-service
          image: easzlab.io.local:5000/cutejava-starter:version_20240521195715
          ports:
            - containerPort: 12800

Service

暴露应用内部的Pods

yaml
apiVersion: v1
kind: Service
metadata:
  name: service-cutejava-tiny-service
  namespace: namespace-cutejava-tiny-service
spec:
  selector:
    app: statefulset-cutejava-tiny-service
  ports:
    - protocol: TCP
      port: 80
      targetPort: 12800
  type: ClusterIP

ingress

配置外部访问规则,假设我们希望通过HTTP和HTTPS访问应用。注意:在生产环境中,你需要一个有效的TLS证书,并将其存储在一个名为my-tls-secret的Secret中

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-cutejava-tiny-service
  namespace: namespace-cutejava-tiny-service
spec:
  rules:
    - host: cutejava.odboy.cn
      http:
        paths:
          - path: /
            #            pathType: Prefix
            pathType: ImplementationSpecific
            backend:
              service:
                name: service-cutejava-tiny-service
                port:
                  number: 12800

执行脚本

shell
kubectl apply -f namespace.yaml
kubectl apply -f statefulset.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

验证

shell
kubectl get namespace|grep namespace-cutejava-tiny-service
kubectl get statefulset -n namespace-cutejava-tiny-service
kubectl get service -n namespace-cutejava-tiny-service
kubectl get ingress -n namespace-cutejava-tiny-service
kubectl get pod -A|grep namespace-cutejava-tiny-service

kubectl describe pod statefulset-cutejava-tiny-service-0 -n namespace-cutejava-tiny-service
kubectl exec -it statefulset-cutejava-tiny-service-0 -n namespace-cutejava-tiny-service bash
kubectl logs -f statefulset-cutejava-tiny-service-0 -n namespace-cutejava-tiny-service

podrunlogs.png

验证域名解析(SingeK8s上执行)

shell
yum install bind-utils -y
nslookup cutejava.odboy.cn

域名无法解析,看看endpoints

shell
kubectl get endpoints -A

allendpoints.png

问了下大佬,说是内网需要写host或者有直接代理到ingress的service

shell
kubectl get service -A

nginx-into.png

shell
echo '10.68.5.77 cutejava.odboy.cn' >> /etc/hosts

接着昨天ingress域名解析失败的问题

shell
# 写hosts
echo '10.68.5.77 cutejava.odboy.cna' >> /etc/hosts

# 更换ingress.yaml配置, 正确的配置如下
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-cutejava-tiny-service
  namespace: namespace-cutejava-tiny-service
spec:
  ingressClassName: nginx
  rules:
    - host: cutejava.odboy.cn
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service-cutejava-tiny-service
                port:
                  number: 12800
                  
# 昨天的ingress配置,错误的配置如下
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-cutejava-tiny-service
  namespace: namespace-cutejava-tiny-service
spec:
  rules:
    - host: cutejava.odboy.cn
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service-cutejava-tiny-service
                port:
                  number: 12800
                  
# 不难发现,就是少了 ingressClassName: nginx 这一行

删除原ingress

shell
kubectl delete -f ingress.yaml

替换ingress.yaml为正确的,然后应用变更

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-cutejava-tiny-service
  namespace: namespace-cutejava-tiny-service
spec:
  ingressClassName: nginx
  rules:
    - host: cutejava.odboy.cn
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service-cutejava-tiny-service
                port:
                  number: 12800

访问测试

shell
curl http://cutejava.odboy.cn

finally.png