kubernetes bible section3

生产环境得k8s负载

HA FT 高可用,容错

k8s主要有以下得组件

1. replicationController

        最初得定义pod replication能力,定义一个replicas值,不停得校准,后续已经逐步淘汰。

2. replicaSet

        1得继任者,支持基于set 得selectors 即选择器

3. deployment

        更高层级得replicaSet抽象。声明式得pod。用于管理无状态服务和负载

4. statefulSet

        statefulSet 有状态服务。难以设计

5. daemonSet

        每个nod上有一个daemonset

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx-replicationcontroller-example
spec:
  replicas: 3
  selector:
    app: nginx
    environment: test
  template:
    metadata:
      labels:
        app: nginx
        environment: test
    spec:
      containers:
        - name: nginx
          image: nginx:1.17
          ports:
            - containerPort: 80

replicaSet


#先用这个bare
vim nginx-bare.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod-bare-example
  labels:
    app: nginx
    environment: test
spec:
  containers:
    - name: nginx
      image: nginx:1.17
      ports:
        - containerPort: 80

kubectl apply -f nginx-bare.yaml

#再用这个replicasSet
vim nginx-replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset-example
spec:
  replicas: 3
# replicasController管理得pod得特征
  selector:
    matchLabels:
      app: nginx
      environment: test
# 创建得pod得模板
  template:
    metadata:
#创建得pod得labels
      labels:
        app: nginx
        environment: test
    spec:
      containers:
        - name: nginx
          image: nginx:1.17
          ports:
            - containerPort: 80

kubectl apply-f nginx-replicaset.yaml

#match 可以用operator
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
    matchExpressions:
      - key: environment
        operator: In
        values:
          - test
          - dev

replicas与livenessprobe结合

#带探针检测得
vim replicaset-livenessprobe.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset-livenessprobe-example
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
      environment: test
  template:
    metadata:
      labels:
        app: nginx
        environment: test
    spec:
      containers:
        - name: nginx
          image: nginx:1.17
          ports:
            - containerPort: 80
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 2
            periodSeconds: 2


kubectl apply -f replicaset-livenessprobe.yaml

#获取pod删除index.html
kubectl get pods

kubectl exec -it nginx-replicaset-livenessprobe-example-2qbhk -- rm /usr/share/nginx/html/index.html

#查看实际得历史
kubectl describe pod/nginx-replicaset-livenessprobe-example-2qbhk 

deployment

四类资源

  • stateless 不包括任何来自客户端得可变更得值
  • stateful 如mysql mongodb
  • batch 批处理得pod
  • node-local 如daemonset 每个node节点上有一个
vim deployment-nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-example
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
      environment: test
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: nginx
        environment: test
    spec:
      containers:
        - name: nginx
          image: nginx:1.17
          ports:
            - containerPort: 80

kubectl apply -f deployment-nginx.yaml

kubectl delete deploy nginx-deployment-example --cascade=orphan

selector pod-template-hash标签防止不同得replicaSet当滚动升级得时候

strategy 意味着怎么取更新 maxUnavailable 最大不可用 maxSurge 最多增长

service

 service由kube-proxy监听,service属于deployment、

vim nginx-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-service-example
spec:
  selector:
    app: nginx
    environment: test
  type: LoadBalancer
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80

kubectl apply -f nginx-service.yaml

readiness liveness startup probe

是否准备好了

是否还活着,防止比如死锁之类的。

开启得probe,必须startup之后,才能走另外两个

vim nginx-deployment-liveliness-readiness.yaml


apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset-livenessprobe-example
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
      environment: test
#更新策略
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: nginx
        environment: test
    spec:
      containers:
        - name: nginx
          image: nginx:1.17
          ports:
            - containerPort: 80
          command:
            - /bin/sh
# -c 是/bin/bash得参数, touch创建一个ready文件 echo 准备好了,替换原本得文件 
            - -c
            - |
              touch /usr/share/nginx/html/ready
              echo "You have been served by Pod with IP address: $(hostname -i)" > /usr/share/nginx/html/index.html
              nginx -g "daemon off;"
          readinessProbe:
            httpGet:
              path: /ready
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 2
            timeoutSeconds: 10
            successThreshold: 1
#失败得阈值
            failureThreshold: 2
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 2
            periodSeconds: 2

kubectl create -f nginx-deployment-liveliness-readiness.yaml

#删除
kubectl exec -it nginx-replicaset-livenessprobe-example-7bblt -- rm /usr/share/nginx/html/ready
#查看
kubectl describe svc nginx-service-example

扩缩容

kubectl scale deploy nginx-deployment-example --replicas=2

 滚动升级

RollingUpdate

内部又两个replicaSet,老得先scale down 然后new将呗scaled up。 又两个参数 .spec.strategy.rollilngUpdate.maxUnavailable 最多有几个不可用,以及.spec.strategy.rollilngUpdate.maxSurge最多多出来几个pods

Recreate

非滚动升级,直接替换

回滚

kubectl rollout history deploy nginx-replicaset-livenessprobe-example

#查看
kubectl rollout history deploy  nginx-replicaset-livenessprobe-example --revision=1
#回滚到上一次
kubectl rollout undo deploy  nginx-replicaset-livenessprobe-example
#回滚到指定revision
kubectl rollout undo deploy  nginx-replicaset-livenessprobe-example --to-revision=2

kubectl rollout status deploy  nginx-replicaset-livenessprobe-example


kubectl rollout pause deployment nginx-replicaset-livenessprobe-example
kubectl rollout resume deployment nginx-replicaset-livenessprobe-example

最佳实践

用声明式得东西去做

不要用recreate strategy

        因为存在一个问题就是不可用问题,用RollingUpdate

不要创建一些命中现有label selector得pod

探针得正确使用

        readiness

  •        如果可能需要额外准备,就需要使用
  •        cache预热 包括数据库迁移 ,但注意不要用耗时过久得东西放在这里面
  •        微服务来说,如果是http得终端,可以考虑用http得方式做探针
  •        可以用一个专门得入口,如/health
  •        如果依赖去检测一些诸如外部得database等服务,就需要小心。小心超时

         liveness

  •         如果非必须,不要用 deadlock这种可以用
  •         应该支取检查他自己得状态,快速得检查,而不要检查依赖。
  •         如果说你得容器自己崩溃了,那就完全不需要liveliness探针
  •         initialDelaySeconds设置保守点来避免一直重新启动。

image tags最好使用具备语义得

从老k8s中迁移。

statefulSet

state是说可以改变的状态。

一般来说,用statefulset一般必须满足如下的请求:

  • 被k8s的集群管理的 持久化存储
  • 对于单一的pod副本稳定的以及唯一的网络标识符(dnsName)
  • 管理的deployment以及scaling
  • 管理的滚动升级。

与deployments相比,可以看做一个更具备预测能力的object

  • statefulset 一般就是statefulsetName-ordinal ,deployments 复杂一些更随机一些 比如 deploymentName-podTemplateHash-randomHash
  • 对于有状态的对象,pod以一个特定的、可预测的 顺序启动
  • 依据存储,k8s 依据volumeClaimTemplates 创建pvc(再stateSet中)并且经常附到同样的pod名字中。
  • 你需要创建一个headless服务来负责管理这些 确定性的网络标识符,headless service,他允许我们依据这个获取所有的podIp 指定stateful的方式为增加 spec.serviceName

管理有状态服务

pv 挂载在 minikube下的 /tmp/hostpath-provisioner/default/my-hostpath-pvc 可以用minikube ssh进去

vim nginx-statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx-statefulset-example
spec:
  replicas: 3
  serviceName: nginx-headless
  selector:
    matchLabels:
      app: nginx-stateful
      environment: test
  template:
    metadata:
      labels:
        app: nginx-stateful
        environment: test
    spec:
      containers:
        - name: nginx
          image: nginx:1.17
          ports:
            - containerPort: 80
          volumeMounts:
            - name: nginx-data
              mountPath: /usr/share/nginx/html
          command:
            - /bin/sh
            - -c
            - |
              echo "You have been served by Pod with IP address: $(hostname -i)" > /usr/share/nginx/html/index.html
              nginx -g "daemon off;"
  volumeClaimTemplates:
    - metadata:
        name: nginx-data
      spec:
        accessModes: [ "ReadWriteOnce" ]
        resources:
          requests:
            storage: 1Gi

kubectl apply -f nginx-statefulset.yaml


vim nginx-headless-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-headless
spec:
  selector:
    app: nginx-stateful
    environment: test
  clusterIP: None
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80

kubectl apply -f nginx-headless-service.yaml


vim nginx-client-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-client
spec:
  selector:
    app: nginx-stateful
    environment: test
  type: LoadBalancer
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
kubectl apply -f nginx-client-service.yaml

#get pvId
kubectl get pvc nginx-data-nginx-statefulset-example-1
#get pvId
kubectl describe pv pvid
#结果
Name:            pvc-fb07149d-48f4-44c4-ad67-4c5ea26961d2
Labels:          <none>
Annotations:     hostPathProvisionerIdentity: fe86868a-72c3-43e2-98fd-4f86b38b7bf9
                 pv.kubernetes.io/provisioned-by: k8s.io/minikube-hostpath
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    standard
Status:          Bound
Claim:           default/nginx-data-nginx-statefulset-example-1
Reclaim Policy:  Delete
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        1Gi
Node Affinity:   <none>
Message:
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /tmp/hostpath-provisioner/default/nginx-data-nginx-statefulset-example-1
    HostPathType:
Events:            <none>
chens@chens-01:~$

已经创建了statefulSet,现在来验证是否按照预期

kubectl describe svc nginx-client

kubectl run -i --tty busybox --image=busybox:1.28 --rm --restart=Never -- sh
#查询
nslookup nginx-client

#结果
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name:      nginx-client
Address 1: 10.111.188.122 nginx-client.default.svc.cluster.local

#查询nginx-headless 就能得到一个结果
nslookup nginx-headless

#结果
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx-headless
Address 1: 10.244.120.88 nginx-statefulset-example-2.nginx-headless.default.svc.cluster.local
Address 2: 10.244.120.86 nginx-statefulset-example-0.nginx-headless.default.svc.cluster.local
Address 3: 10.244.120.87 nginx-statefulset-example-1.nginx-headless.default.svc.cluster.local



wget http://nginx-statefulset-example-0.nginx-headless && cat index.html
#结果
Connecting to nginx-statefulset-example-0.nginx-headless (10.244.120.86:80)
index.html           100% |************************************************************************************************************************************|    59   0:00:00 ETA
You have been served by Pod with IP address: 10.244.120.86


#如果删除后,还会再起来同样的dnsname
kubectl delete pod nginx-statefulset-example-0
#再执行一遍
nslookup nginx-headless
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name:      nginx-headless
Address 1: 10.244.120.87 nginx-statefulset-example-1.nginx-headless.default.svc.cluster.local
Address 2: 10.244.120.69 nginx-statefulset-example-0.nginx-headless.default.svc.cluster.local
Address 3: 10.244.120.88 nginx-statefulset-example-2.nginx-headless.default.svc.cluster.local

pv得持久化演示

kubectl exec -it nginx-statefulset-example-0 -- /bin/sh -c "echo State of Pod 0 > /usr/share/nginx/html/state.html"

kubectl exec -it nginx-statefulset-example-1 -- /bin/sh -c "echo State of Pod 1 > /usr/share/nginx/html/state.html"

kubectl exec -it nginx-statefulset-example-2 -- /bin/sh -c "echo State of Pod 2 > /usr/share/nginx/html/state.html"

# get list
minikube service list

#states
minikube ssh
wget ip:port/state.html
wget http://nginx-statefulset-example-0.nginx-headless/state.html && cat state.html



#查看ip
kubectl get pods -o wide

#删除
kubectl delete  pod nginx-statefulset-example-0 nginx-statefulset-example-1 nginx-statefulset-example-2

#wide
kubectl get pods -o wide -w

扩缩容

  • 按照顺序 从0- n-1得依次序创建
  • 缩容得时候反过来,从大到小。
  • 后续创建必须等前置创建完成。
  • 缩容时必须后续得terminated 和删除掉得。
  • 如果后续失败了,再后续得就动不了了。

 .spec.podManagementPolicy这个参数默认是OrderedReady,控制了扩缩容得行为。

删除

kubectl delete sts nginx-statefulset-example

kubectl delete sts nginx-statefulset-example --cascade=orphan

#删除后不会删除pvc,如果要删除,就需要
kubectl delete pvc nginx-data-nginx-statefulset-example-0 nginx-data-nginx-statefulset-example-1 nginx-data-nginx-statefulset-example-2

新版本释放。

.spec.updateStrategy.type

RollingUpdate:只不过相比来说按照次序创建得。

         .spec.updateStrategy.rollingUpdate.partition 小于他不会升级得副本数。即便删除了,也用原来得版本。

OnDelete 1.7之前就有得。必须手动删除一个来替换。

最佳实践

  • 使用声明式管理方式
  • 不要使用时常为0得优雅停机。有状态服务需要优雅停机。
  • 如果你后续还需要使用pvc,最好先缩容,再停机。
  • 回滚得时候要注意相互兼容性。
  • 不要创建与现有服务冲突得有状态服务得标签

daemonset

一个node一个做一些

  • node监控
  • logs 监控得聚合
  • 管理集群得存储。尤其是对pv 和pvc管理

如果需要与外部交流

  • 需要映射内部与外部得端口
  • 推送data到另外一个service
  • headless service来匹配daemonset pod标签选择器
  • 普通得service匹配daemonset 标签选择器 不是很常见

创建和管理daemonset

vim nginx-daemon.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-daemonset-example
spec:
  selector:
    matchLabels:
      app: nginx-daemon
      environment: test
  template:
    metadata:
      labels:
        app: nginx-daemon
        environment: test
    spec:
      containers:
        - name: nginx
          image: nginx:1.17
          ports:
            - containerPort: 80
          env:
            - name: NODE_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
          command:
            - /bin/sh
            - -c
            - |
              echo "You have been served by Pod running on Node with IP address: $(NODE_IP)" > /usr/share/nginx/html/index.html
              nginx -g "daemon off;"

kubectl apply -f nginx-daemon.yaml 


vim nginx-daemon-headless.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-daemon-headless
spec:
  selector:
    app: nginx-daemon
    environment: test
  clusterIP: None
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80

kubectl apply -f nginx-daemon-headless.yaml

kubectl get daemonset

kubectl desribe daemonset nginx-daemonset-example

#获取node
kubectl get node -o wide

#shell 去查看对应消息
kubectl run -i --tty busybox --image=busybox:1.28 --rm --restart=Never -- s
wget http://10-244-120-66.nginx-daemon-headless && cat index.html

.spec.template.spec.nodeSelector or .spec.template.spec.tolerations 控制哪些节点布置

.spec.updateStrategy.spec.revisionHistoryLimit, and .spec.minReadySeconds  回滚升级信息

后续包括升级方式、删除等,与上面deployments类似

一些可替代得设计思路

  • sidecar模式,虽然需要更多资源,但是更号
  • 如果仅仅是想跑周期任务,就走k8s得cronJobs
  • 有些系统共据能提供类似得功能,如ubuntu中得systemd,与k8s相比,又以来上得优势和劣势(不依赖k8s,有时候必须要k8s管理得时候没法处理)
  • 静态容器 (Create static Pods | Kubernetes) kubelet会监听对应得静态文件,但不能用kubectl监控,但似乎一般用于cluster 启动函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值