pod

什么是Pod

Pod是Kubernetes中最小的单元,它由一组、一个或多个容器组成,每个Pod还包含了一个Pause容器,Pause容器是Pod的父容器,主要负责僵尸进程的回收管理,通过Pause容器可以使同一个Pod里面的多个容器共享存储、网络、PID、IPC

欢迎关注个人公众号【好好学技术】交流学习

创建一个Pod

vi pod.yaml

apiVersion: v1 # 必选,API的版本号
kind: Pod       # 必选,类型Pod
metadata:       # 必选,元数据
  name: nginx   # 必选,符合RFC 1035规范的Pod名称
  # namespace: default # 可选,Pod所在的命名空间,不指定默认为default,一般启动时使用-n 指定namespace 
  labels:       # 可选,标签选择器,一般用于过滤和区分Pod
    app: nginx
    role: frontend # 可以写多个
  annotations:  # 可选,注释列表,可以写多个 app名称、版本,备注等
    app: nginx
spec:   # 必选,用于定义容器的详细信息
#  initContainers: # 初始化容器,在容器启动之前执行的一些初始化操作 ,可配置多个
#  - command:
#    - sh
#    - -c
#    - echo "I am InitContainer for init some configuration"
#    image: busybox
#    imagePullPolicy: IfNotPresent
#    name: init-container
  # terminationGracePeriodSeconds: 40  # 一定大于sleep的时间
  containers:   # 必选,容器列表 可配置多个
  - name: nginx # 必选,符合RFC 1035规范的容器名称
    image: nginx:1.15.2    # 必选,容器所用的镜像的地址
    imagePullPolicy: IfNotPresent     # 可选,镜像拉取策略, IfNotPresent: 如果宿主机有这个镜像,那就不需要拉取了. Always: 总是拉取, Never: 不管是否存储都不拉取
    command: # 可选,容器启动执行的命令 command 相当于 ENTRYPOINT,   arg 相当于 cmd
    - nginx 
    - -g
    - "daemon off;"
    workingDir: /usr/share/nginx/html       # 可选,容器的工作目录
    volumeMounts:   # 可选,存储卷配置,可以配置多个
#    - name: webroot # 存储卷名称
#      mountPath: /usr/share/nginx/html # 挂载目录
#      readOnly: true        # 只读
    ports:  # 可选,容器需要暴露的端口号列表
    - name: http    # 端口名称
      containerPort: 80     # 端口号
      protocol: TCP # 端口协议,默认TCP
    env:    # 可选,环境变量配置列表
    - name: TZ      # 变量名 修改时区和编码
      value: Asia/Shanghai # 变量的值
    - name: LANG
      value: en_US.utf8
#    resources:      # 可选,资源限制和资源请求限制
#      limits:       # 最大限制设置
#        cpu: 1000m
#        memory: 1024Mi
#      requests:     # 启动所需的资源
#        cpu: 100m
#        memory: 512Mi
    startupProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式同时只能使用一种。
     # httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
     #       path: /api/successStart # 检查路径
     #       port: 80
      tcpSocket:
        port: 80
#    readinessProbe: # 可选,健康检查。
#      httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
#            path: / # 检查路径
#            port: 80        # 监控端口
#    livenessProbe:  # 可选,健康检查
      #exec:        # 执行容器命令检测方式
            #command: 
            #- cat
            #- /health
    #httpGet:       # httpGet检测方式
    #   path: /_health # 检查路径
    #   port: 8080
    #   httpHeaders: # 检查的请求头
    #   - name: end-user
    #     value: Jason 
#      tcpSocket:    # 端口检测方式
#            port: 80
#      initialDelaySeconds: 60       # 初始化时间
#      timeoutSeconds: 2     # 超时时间
#      periodSeconds: 5      # 检测间隔
#      successThreshold: 1 # 检查成功为1次表示就绪
#      failureThreshold: 2 # 检测失败2次表示未就绪
#    lifecycle:
#      postStart: # 容器创建完成后执行的指令, 可以是exec httpGet TCPSocket
#        exec:
#          command:
#          - sh
#          - -c
#          - 'mkdir /data/ '
#      preStop:
#        httpGet:      
#              path: /
#              port: 80

      #  exec:
      #    command:
      #    - sh
      #    - -c
      #    - sleep 9  #需配合terminationGracePeriodSeconds使用
  restartPolicy: Always   # 可选,默认为Always,容器故障或者没有启动成功,那就自动重启该容器,Onfailure: 容器以不为0的状态终止,自动重启该容器(异常退出重启), Never:无论何种状态,都不会重启
  #nodeSelector: # 可选,指定Node节点
  #      region: subnet7
#  imagePullSecrets:     # 可选,拉取镜像使用的secret,可以配置多个
#  - name: default-dockercfg-86258
  # hostNetwork: false    # 可选,是否为主机模式,如是,会占用主机端口
#  volumes:      # 共享存储卷列表
#  - name: webroot # 名称,与上述对应
#    emptyDir: {}    # 挂载目录
#        #hostPath:              # 挂载本机目录
#        #  path: /etc/hosts
#
-- create 创建资源 -f 资源文件
$ kubectl create -f pod.yaml 
$ kubectl get po   
NAME    READY   STATUS              RESTARTS   AGE
nginx   0/1     ContainerCreating   0          5s

-- 正在启动

$ kubectl get po --show-labels
NAME    READY   STATUS    RESTARTS   AGE   LABELS
nginx   1/1     Running   0          23m   app=nginx,role=frontend

-- 查看启动过程
$ kubectl describe po nginx

-- 启动成功
$ kubectl get po -owide

NAME    READY   STATUS    RESTARTS   AGE   IP          NODE             NOMINATED NODE   READINESS GATES
nginx   0/1     Running   0          2s    10.1.0.23   docker-desktop   <none>           <none>

如果修改文件,可以使用 kubectl apply -f pod.yaml

-- 删除pod
$ kubectl delete po nginx
pod "nginx" deleted

$ kubectl get po --show-labels
No resources found in default namespace.

Pod探针

  • StartupProbe:k8s1.16版本后新加的探测方式,用于判断容器内应用程序是否已经启动。如果配置了startupProbe,就会先禁止其他的探测,直到它成功为止,成功后将不在进行探测。

  • LivenessProbe:用于探测容器是否运行,如果探测失败,kubelet会根据配置的重启策略进行相应的处理。若没有配置该探针,默认就是success。(可能导致启动慢,程序异常后需要很久(超时时间 * 检测间隔 * 检测失败次数)才会重启)

  • ReadinessProbe:一般用于探测容器内的程序是否健康,它的返回值如果为success,那么就代表这个容器已经完成启动,并且程序已经是可以接受流量的状态。

Pod探针的检测方式

  • ExecAction:在容器内执行一个命令,如果返回值为0,则认为容器健康。

  • TCPSocketAction:通过TCP连接检查容器内的端口是否是通的,如果是通的就认为容器健康。

  • HTTPGetAction:通过应用程序暴露的API地址来检查程序是否是正常的,如果状态码为200~400之间,则认为容器健康。

探针检查参数配置

  initialDelaySeconds: 60       # 初始化时间
  timeoutSeconds: 2     # 超时时间
  periodSeconds: 5      # 检测间隔
  successThreshold: 1 # 检查成功为1次表示就绪
  failureThreshold: 2 # 检测失败2次表示未就绪

Deployment

用于部署无状态的服务,这个是最常用的控制器。一般用于管理维护企业内部无状态的微服务,比如configServer,springboot。可以管理多个副本的Pod实现无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等。

手动创建

$ kubectl create deployment nginx --image=nginx:1.15.2
deployment.apps/nginx created

$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-76446799f9-6ck7t   1/1     Running   0          26s

$ kubectl get deploy
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nginx                    1/1     1            1           32s

查看配置文件

# kubectl get deployment nginx -o yaml > nginx-deploy.yaml 
# cat nginx-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
 annotations:
   deployment.kubernetes.io/revision: "1"
 creationTimestamp: "2023-04-22T08:14:31Z"
 generation: 1
 labels:
   app: nginx
 name: nginx
 namespace: default
spec:
 progressDeadlineSeconds: 600
 replicas: 2 #副本数
 revisionHistoryLimit: 10 # 设置保留RS旧的revision的个数
 selector:
   matchLabels:
     app: nginx
 strategy: #滚动更新策略  默认是RollingUpdate(先创建一个新的,在删除一个旧的,交替更新)   Recreate:重建,先删除旧的Pod,在创建新的Pod
   rollingUpdate:
     maxSurge: 25% # 可以超过期望值的最大Pod数   可以设置成数字或百分比
     maxUnavailable: 25% #指定在回滚或更新时最大不可用的Pod的数量 可以设置成数字或百分比
   type: RollingUpdate
 template:
   metadata:
     creationTimestamp: null
     labels:
       app: nginx
   spec:
     containers:
     - image: nginx:1.15.2
       imagePullPolicy: IfNotPresent
       name: nginx
       resources: {}
       terminationMessagePath: /dev/termination-log
       terminationMessagePolicy: File
     dnsPolicy: ClusterFirst
     restartPolicy: Always
     schedulerName: default-scheduler
     securityContext: {}
     terminationGracePeriodSeconds: 30


Deployment更新

-- 更改deployment的镜像并记录
$ kubectl edit deploy nginx

-- 将nginx版本改为1.15.3 副本数改为2
- image: nginx:1.15.3
replicas: 2

-- 查看更新过程
kubectl rollout status deploy nginx

deployment "nginx" successfully rolled out

# kubectl rollout status deploy nginx

Waiting for deployment "nginx" rollout to finish: 1 out of 2 new replicas have been updated...

Waiting for deployment "nginx" rollout to finish: 1 out of 2 new replicas have been updated...

Waiting for deployment "nginx" rollout to finish: 1 out of 2 new replicas have been updated...

Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...

Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...

deployment "nginx" successfully rolled out


$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-76446799f9-6ck7t   1/1     Running   0          5m26s
nginx-66bbc9fdc5-svxwh   1/1     Running   0          45s

$ kubectl get deploy
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nginx                    2/2     2            2           5m32s

Deployment回滚


-- 再次更新
$ kubectl set image deploy nginx nginx=1.15.4
-- 查看历史版本
$ kubectl rollout history deploy nginx
deployment.apps/nginx
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         kubectl set image deploy nginx nginx=1.15.4 --record=true

1924 Desktop/k8s  »

-- 查看指定版本信息
$ kubectl rollout history deploy nginx --revision=1
-- 回滚指定版本
$ kubectl rollout undo deploy nginx --to-revision=1
deployment.apps/nginx rolled back

扩容和缩容

» kubectl scale --replicas=3 deploy nginx
deployment.apps/nginx scaled
» kubectl get deploy
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   3/3     3            3           17m
» kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
nginx-76446799f9-j2v2s   1/1     Running   0          4m42s
nginx-76446799f9-pxg8g   1/1     Running   0          4m43s
nginx-76446799f9-vvfvk   1/1     Running   0          35s

更新暂停和恢复

» kubectl rollout pause deployment nginx
deployment.apps/nginx paused
» kubectl set image deploy nginx nginx=nginx:1.15.3
deployment.apps/nginx image updated
» kubectl set resources deploy nginx -c nginx --limits=cpu=200m,memory=128Mi --requests=cpu=10m,memory=16Mi
deployment.apps/nginx resource requirements updated
-- 查看配置文件 版本号和资源调整已修改(见下图)
» kubectl get deploy nginx -oyaml
-- 通过AGE可以看出来,并没有更新
» kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
nginx-76446799f9-j2v2s   1/1     Running   0          15m
nginx-76446799f9-pxg8g   1/1     Running   0          15m
nginx-76446799f9-vvfvk   1/1     Running   0          11m

-- 更新
» kubectl rollout resume deploy nginx
deployment.apps/nginx resumed

» kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
nginx-7b7c775868-26brv   1/1     Running   0          3s
nginx-7b7c775868-594f6   1/1     Running   0          2s
nginx-7b7c775868-g2qdp   1/1     Running   0          5s

» kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
nginx-5cfd47cfc5   0         0         0       22m
nginx-76446799f9   0         0         0       30m
nginx-7b7c775868   3         3         3       8s
nginx-d45498588    0         0         0       29m

image.png

StatefulSet

用于部署有状态且需要有序启动的应用程序。主要用于管路有状态应用程序的工作负载API对象。比如生产环境中部署ElasticSearch集群、MongoDB集群或者需要持久化的RabbitMQ集群、Redis集群、kafka集群和zookeeper集群等。

创建

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:nginx:1.15.2
        ports:
        - containerPort: 80
          name: web
» kubectl create -f statefulset-nginx.yaml
service/nginx created
statefulset.apps/web created

» kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          10s
web-1   1/1     Running   0          8s

扩容缩容

» kubectl scale --replicas=3 sts web
statefulset.apps/web scaled

» kubectl get sts
NAME   READY   AGE
web    3/3     2m33s

» kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          2m38s
web-1   1/1     Running   0          2m36s
web-2   1/1     Running   0          14s

创建过程

顺序创建 先创建web-0成功继续创建web-1,失败则停止创建。
从后往前删除 先删web-2,再web-1,最后web-0。

  • 删除或创建时若发生异常(某个节点挂掉) 则停止创建或删除

查看创建过程

$ kubectl get pods -w
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          9m38s
web-1   1/1     Running   0          9m36s
web-2   1/1     Running   0          7m14s

-- 新开窗口执行命令
» kubectl scale --replicas=5 sts web     
statefulset.apps/web scaled


-- 查看变化过程
» kubectl get pods -w
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          9m38s
web-1   1/1     Running   0          9m36s
web-2   1/1     Running   0          7m14s
web-3   0/1     Pending   0          0s
web-3   0/1     Pending   0          0s
web-3   0/1     ContainerCreating   0          0s
web-3   1/1     Running             0          2s
web-4   0/1     Pending             0          0s
web-4   0/1     Pending             0          0s
web-4   0/1     ContainerCreating   0          0s
web-4   1/1     Running             0          1s

更新策略

» kubectl get sts web -o yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  creationTimestamp: "2023-04-22T09:14:31Z"
  generation: 3
  name: web
  namespace: default
  resourceVersion: "56239"
  uid: 2fdc1f52-3858-49c0-9ecc-4250a63e69ce
spec:
  podManagementPolicy: OrderedReady
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  serviceName: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.15.2
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          name: web
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
  updateStrategy: #更新策略
    rollingUpdate:
      partition: 0 # 更新大于等于partition的容器 (详解见下面)
    type: RollingUpdate #滚动更新,从后往前更新    OnDelete:只有手动删除才会更新镜像
status:
  availableReplicas: 5
  collisionCount: 0
  currentReplicas: 5
  currentRevision: web-6949d64dc8
  observedGeneration: 3
  readyReplicas: 5
  replicas: 5
  updateRevision: web-6949d64dc8
  updatedReplicas: 5

灰度发布

利用StatefulSet 更新策略我们可以实现灰度发布

假设有5个副本 web-0,web-1,web-2,web-3,web-4
设置 partition: 2,则滚动更新只会更新web-2,web-3,web-4

-- 修改滚动更新策略
» kubectl edit sts web
  updateStrategy:
    rollingUpdate:
      partition: 2
    type: RollingUpdate
    
-- 修改镜像版本
» kubectl edit sts web 
        image: nginx:1.15.3

-- 由创建时间可以看到web-2,web-3,web-4更新了,并且从web-4开始往上更新
» kubectl get po
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          32m
web-1   1/1     Running   0          32m
web-2   1/1     Running   0          4s
web-3   1/1     Running   0          6s
web-4   1/1     Running   0          45s


-- 查看pods镜像
» kubectl get po -oyaml | grep image
    - image: nginx:1.15.2
      imagePullPolicy: IfNotPresent
      image: nginx:1.15.2
      imageID: docker-pullable://nginx@sha256:d85914d547a6c92faa39ce7058bd7529baacab7e0cd4255442b04577c4d1f424
    - image: nginx:1.15.2
      imagePullPolicy: IfNotPresent
      image: nginx:1.15.2
      imageID: docker-pullable://nginx@sha256:d85914d547a6c92faa39ce7058bd7529baacab7e0cd4255442b04577c4d1f424
    - image: nginx:1.15.3
      imagePullPolicy: IfNotPresent
      image: nginx:1.15.3
      imageID: docker-pullable://nginx@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
    - image: nginx:1.15.3
      imagePullPolicy: IfNotPresent
      image: nginx:1.15.3
      imageID: docker-pullable://nginx@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
    - image: nginx:1.15.3
      imagePullPolicy: IfNotPresent
      image: nginx:1.15.3
      imageID: docker-pullable://nginx@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3

级联删除和非级联删除

  • 级联删除:删除sts时,同时删除Pod (默认)
  • 非级联删除:删除sts时,不删除Pod
-- 非级联删除 --cascade=false
» kubectl delete sts web --cascade=false
warning: --cascade=false is deprecated (boolean value) and can be replaced with --cascade=orphan.
statefulset.apps "web" deleted

» kubectl get sts
No resources found in default namespace.

» kubectl get po
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          62s
web-1   1/1     Running   0          60s

-- 此时删除pod不会新建,因为sts已经不存在了
» kubectl delete po web-0 web-1
pod "web-0" deleted
pod "web-1" deleted
» kubectl get po
No resources found in default namespace.

Service

可以简单理解为逻辑上的一组Pod。一种可以访问Pod的策略,而且其他Pod可以通过这个Service访问到这个Service代理的Pod。相对于Pod而言,它会有一个固定的名称,一旦创建就固定不变。

创建一个Service

 apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
  - name: http
    port: 80  #Service自己的端口
    targetPort: 80  #后端应用的端口 
    protocol: TCP  #UDP TCP SCTP  default:TCP
  - name: https
    port: 443  #Service自己的端口
    targetPort: 443  #后端应用的端口 
    protocol: TCP  #UDP TCP SCTP  default:TCP
  selector:
    app: nginx    
  sessionAffinity: None
  type: ClusterIP
» kubectl create -f service.yaml

» kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          28h
my-web-0     NodePort    10.105.106.72    <none>        80:32445/TCP     24m
nginx        ClusterIP   None             <none>        80/TCP           3h
nginx-svc    ClusterIP   10.100.224.240   <none>        80/TCP,443/TCP   160m

使用Service代理k8s外部应用

例如:
希望在生产环境中使用某个固定的名称而非IP地址进行访问外部的中间件服务(mysql、rabbitmq等。 可以在测试环境、开发环境、生产环境配置同一个名称,代理的ip指向不同环境的地址).
某个项目正在迁移至K8s集群,但是一部分服务仍然在集群外部,此时可以使用service代理至k8s集群外部的服务。

# vi svc-nginx-external.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-svc-external
  name: nginx-svc-external
spec:
  ports:
  - name: http
    port: 80  #Service自己的端口
    targetPort: 80  #后端应用的端口 
    protocol: TCP  #UDP TCP SCTP  default:TCP
  sessionAffinity: None
  type: ClusterIP
» kubectl create -f svc-nginx-external.yaml
service/nginx-svc-external created

» kubectl get svc
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes           ClusterIP   10.96.0.1        <none>        443/TCP          28h
my-web-0             NodePort    10.105.106.72    <none>        80:32445/TCP     35m
nginx                ClusterIP   None             <none>        80/TCP           3h11m
nginx-svc            ClusterIP   10.100.224.240   <none>        80/TCP,443/TCP   171m
nginx-svc-external   ClusterIP   10.97.68.85      <none>        80/TCP           9s

-- 并没有创建同名的ENDPOINTS
» kubectl get ep
NAME         ENDPOINTS                                              AGE
kubernetes   192.168.65.4:6443                                      28h
my-web-0     10.1.0.60:80                                           36m
nginx        10.1.0.60:80,10.1.0.61:80                              3h13m
nginx-svc    10.1.0.60:443,10.1.0.61:443,10.1.0.60:80 + 1 more...   173m

--复制一个
» kubectl get ep nginx-svc -oyaml > nginx-ep-external.yaml
--修改
» vi nginx-ep-external.yaml
» cat nginx-ep-external.yaml
apiVersion: v1
kind: Endpoints
metadata:
  labels:
    app: nginx-svc-external
  name: nginx-svc-external
  namespace: default
subsets:
- addresses:
  - ip: 220.181.38.148 #外部服务ip地址 ,这里是百度
  ports:
  - name: http
    port: 80 # 外部服务端口号
    protocol: TCP
    
» kubectl create -f nginx-ep-external.yaml
-- 以后需要变更地址,只需要kubectl edit ep nginx-svc-external 就行了

使用Service代理k8s外部域名

cp svc-nginx-external.yaml svc-nginx-externalname.yaml
➜ vi svc-nginx-externalname.yaml

➜ cat svc-nginx-externalname.yaml
apiVersion: v1
kind: Service
metadata:
 labels:
   app: nginx-externalname
 name: nginx-externalname
spec:
 type: ExternalName
 externalName: www.baidu.com

➜ kubectl apply -f svc-nginx-externalname.yaml
service/nginx-externalname created

➜ kubectl get svc
NAME                 TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)          AGE
kubernetes           ClusterIP      10.96.0.1        <none>          443/TCP          40h
my-web-0             NodePort       10.105.106.72    <none>          80:32445/TCP     12h
nginx                ClusterIP      None             <none>          80/TCP           15h
nginx-externalname   ExternalName   <none>           www.baidu.com   <none>           66s
nginx-svc            ClusterIP      10.100.224.240   <none>          80/TCP,443/TCP   14h
nginx-svc-external   ClusterIP      10.97.68.85      <none>          80/TCP           12h

➜ kubectl get po
NAME    READY   STATUS    RESTARTS      AGE
web-0   1/1     Running   1 (13m ago)   15h
web-1   1/1     Running   1 (13m ago)   15h

➜ kubectl exec -it web-0 bash
root@web-0:/# apt-get update && apt-get install wget

-- 跨域导致 403了,但是请求通了,110.242.68.4也是百度的ip
root@web-0:/# wget nginx-externalname
--2023-04-22 22:30:19--  http://nginx-externalname/
Resolving nginx-externalname (nginx-externalname)... 110.242.68.4, 110.242.68.3
Connecting to nginx-externalname (nginx-externalname)|110.242.68.4|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2023-04-22 22:30:19 ERROR 403: Forbidden.

-- 直接请求ip地址
root@web-0:/# wget 110.242.68.4
--2023-04-22 22:30:46--  http://110.242.68.4/
Connecting to 110.242.68.4:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2381 (2.3K) [text/html]
Saving to: 'index.html'

index.html                              100%[===============================================================================>]   2.33K  --.-KB/s    in 0s

2023-04-22 22:30:46 (14.7 MB/s) - 'index.html' saved [2381/2381]

root@web-0:/# cat index.html
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

Service常用类型

spec.type

  • ClusterIP:在集群内部使用的,默认类型
  • ExternalName:反代到指定的域名上。
  • LoadBalancer:使用云服务商提供的IP地址。成本太高。
  • NodePort:在每个宿主机上暴露一个随机端口,30000-32767,–service-node-port-range,集群外部可访问。

Ingress概念

用于实现用域名的方式访问K8s内部。它是Kubernetes集群中服务的入口,可以提供负载均衡、SSL终止和基于域名的虚拟主机。

  • 官方文档:https://kubernetes.io/docs/concepts/services-networking/ingress/
  • Ingress-Nginx安装文档:https://kubernetes.github.io/ingress-nginx/deploy/

安装ingress

➜ brew install helm

➜ helm version
version.BuildInfo{Version:"v3.9.0", GitCommit:"7ceeda6c585217a19a1131663d8cd1f7d641b2a7", GitTreeState:"clean", GoVersion:"go1.18.2"}

--试了很久v1.2.1版本镜像拉取错误,改为1.2.0启动成功
--只需在一台机器上启动,因此可以利用标签来选择在哪台机器上启动
➜ helm install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace \
  --set controller.dnsPolicy=ClusterFirstWithHostNet \
  --set controller.hostNetwork=true \
  --set controller.kind=DaemonSet \
  --set controller.service.type=NodePort \
  --set controller.image.tag="v1.2.0" \
  --set controller.image.digest= \
  --set controller.image.digestChroot= 


% kubectl get po -n ingress-nginx
NAME                             READY   STATUS    RESTARTS   AGE
ingress-nginx-controller-mmzpv   1/1     Running   0          42s

% kubectl get svc -n ingress-nginx
NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.105.16.145   <none>        80:32169/TCP,443:31839/TCP   15m
ingress-nginx-controller-admission   ClusterIP   10.105.37.15    <none>        443/TCP                      15m

创建ingress

先创建服务

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.2
        ports:
        - containerPort: 80
          name: web
% kubectl create -f statefulset-nginx.yaml -n ingress-nginx

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  # annotations:
  #   nginx.ingress.kubernetes.io/rewrite-target: /
  name: example
  namespace: ingress-nginx
spec:
  ingressClassName: nginx
  rules:
  - host: foo.bar.com
    http:
      paths:  #相当于nginx的location  ,可以配置多个
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: nginx-svc #自己的svc名称及端口
            port: 
              number: 80
% kubectl get ingress
NAME      CLASS   HOSTS         ADDRESS          PORTS   AGE
example   nginx   foo.bar.com   10.101.114.133   80      81s

% kubectl get svc -n ingress-nginx
NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.105.16.145   <none>        80:32169/TCP,443:31839/TCP   21m
ingress-nginx-controller-admission   ClusterIP   10.105.37.15    <none>        443/TCP                      21m
nginx                                ClusterIP   None            <none>        80/TCP                       69m


% kubectl get po -n ingress-nginx
NAME                             READY   STATUS    RESTARTS   AGE
ingress-nginx-controller-mdst4   1/1     Running   0          22m
web-0                            1/1     Running   0          69m
web-1                            1/1     Running   0          69m

vi ingress-example.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
  #   nginx.ingress.kubernetes.io/rewrite-target: /
    # nginx.ingress.kubernetes.io/enable-cors: "true"
    # nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
    # nginx.ingress.kubernetes.io/cors-allow-origin: "*"
     # nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
  name: example
  namespace: ingress-nginx
spec:
  # ingressClassName: nginx
  rules:
  - host: "foo.bar.com"
    http:
      paths:  #相当于nginx的location  ,可以配置多个
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: nginx
            port: 
              number: 80

% kubectl create -f ingress-example.yaml

% kubectl get ingress -n ingress-nginx
NAME      CLASS    HOSTS         ADDRESS         PORTS   AGE
example   <none>   foo.bar.com   10.105.16.145   80      12m

% vi /etc/hosts
加入 127.0.0.1 foo.bar.com

访问foo.bar.com:32169 (ingress-nginx-controller暴露出来的接口)
在这里插入图片描述

ConfigMap

ConfigMap概念

一般用ConfigMap去管理一些配置文件,或者一些大量的环境变量信息。
ConfigMap将配置和Pod分开,更易于配置文件的更改和管理。
ConfigMap 将你的环境配置信息和 容器镜像 解耦,便于应用配置的修改。\

官方文档:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-pod-configmap/

安装metrics-server

官网地址:https://github.com/kubernetes-sigs/metrics-server

```
# 创建本地目录
mkdir -p configure-pod-container/configmap/

# 将示例文件下载到 `configure-pod-container/configmap/` 目录
wget https://kubernetes.io/examples/configmap/game.properties -O configure-pod-container/configmap/game.properties
wget https://kubernetes.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties

# 创建 configmap
kubectl create configmap game-config --from-file=configure-pod-container/configmap/

kubectl get configmaps game-config -o yaml

apiVersion: v1
data:
  game.properties: |-
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
  creationTimestamp: "2023-04-22T11:07:31Z"
  name: game-config
  namespace: default
  resourceVersion: "170759"
  uid: f511b525-3057-4670-b59f-0a35405a0e80

官方文档很详细,建议直接看官方文档。

Secret

Secret概念

和ConfigMap一样管理配置文件,但是Secret更倾向于存储和共享敏感、加密的配置信息。比如redis、mysql密码登。

官方文档:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/

kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B*123'

kubectl get secret dev-db-secret -oyaml
apiVersion: v1
data:
  password: UyFCKjEyMw==
  username: ZGV2dXNlcg==
kind: Secret
metadata:
  creationTimestamp: "2023-04-22T11:16:31Z"
  name: dev-db-secret
  namespace: default
  resourceVersion: "206931"
  uid: f8dd6804-73b8-4eb3-8777-a4a9b4b3ff27
type: Opaque


❯ echo "UyFCKjEyMw==" | base64 --decode
S!B*123

配置文件管理
https://kubernetes.io/zh-cn/docs/tasks/configmap-secret/managing-secret-using-config-file/

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐