K8S:常用资源对象操作

这篇具有很好参考价值的文章主要介绍了K8S:常用资源对象操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、使用Replication Controller(RC)、Replica Set(RS) 管理Pod

如果有一种工具能够来帮助我们管理Pod就好了,Pod不够了自动帮我新增一个,Pod挂了自动帮我在合适的节点上重新启动一个Pod,这样是不是遇到上面的问题我们都不需要手动去解决了。

幸运的是,Kubernetes就为我们提供了这样的资源对象:

  • Replication Controller:用来部署、升级Pod
  • Replica Set:下一代的Replication Controller
  • Deployment:可以更加方便的管理Pod和Replica Set

1 Replication Controller(RC)

Replication Controller简称RC,RC是Kubernetes系统中的核心概念之一,简单来说,RC可以保证在任意时间运行Pod的副本数量,能够保证Pod总是可用的。如果实际Pod数量比指定的多那就结束掉多余的,如果实际数量比指定的少就新启动一些Pod,当Pod失败、被删除或者挂掉后,RC都会去自动创建新的Pod来保证副本数量,所以即使只有一个Pod,我们也应该使用RC来管理我们的Pod。

运行Pod的节点挂了,RC检测到Pod失败了,就会去合适的节点重新启动一个Pod就行,不需要我们手动去新建一个Pod了。如果是第一种情况的话在活动开始之前我们给Pod指定10个副本,结束后将副本数量改成2,这样是不是也远比我们手动去启动、手动去关闭要好得多,而且我们后面还会给大家介绍另外一种资源对象HPA可以根据资源的使用情况来进行自动扩缩容。

现在我们来使用RC来管理我们前面使用的Nginx的Pod,YAML文件如下:

apiVersion: v1
kind: ReplicationController
metadata:
  name: rc-demo
  labels:
    name: rc
spec:
  replicas: 3
  selector:
    name: rc
  template:
    metadata:
     labels:
       name: rc
    spec:
     containers:
     - name: nginx-demo
       image: nginx
       ports:
       - containerPort: 80

上面的YAML文件相对于我们之前的Pod的格式:

  • kind:ReplicationController
  • spec.replicas: 指定Pod副本数量,默认为1
  • spec.selector: RC通过该属性来筛选要控制的Pod
  • spec.template: 这里就是我们之前的Pod的定义的模块,但是不需要apiVersion和kind了
  • spec.template.metadata.labels: 注意这里的Pod的labels要和spec.selector相同,这样RC就可以来控制当前这个Pod了。

这个YAML文件中的意思就是定义了一个RC资源对象,它的名字叫rc-demo,保证一直会有3个Pod运行,Pod的镜像是nginx镜像。

注意spec.selector和spec.template.metadata.labels这两个字段必须相同,否则会创建失败的,当然我们也可以不写spec.selector,这样就默认与Pod模板中的metadata.labels相同了。所以为了避免不必要的错误的话,不写为好。

然后我们来创建上面的RC对象(保存为 rc-demo.yaml):

$ kubectl create -f rc-demo.yaml

查看RC:

$ kubectl get rc

查看具体信息:

$ kubectl describe rc rc-demo

K8S:常用资源对象操作,Docker & OpenStack,kubernetes,java,容器

然后我们通过RC来修改下Pod的副本数量为2:

$ kubectl apply -f rc-demo.yaml

或者
$ kubectl edit rc rc-demo

而且我们还可以用RC来进行滚动升级,比如我们将镜像地址更改为nginx:1.7.9:

$ kubectl rolling-update rc-demo --image=nginx:1.7.9

但是如果我们的Pod中多个容器的话,就需要通过修改YAML文件来进行修改了:

$ kubectl rolling-update rc-demo -f rc-demo.yaml

RC无法进行回滚操作

  • 如果升级完成后出现了新的问题,想要一键回滚到上一个版本的话,使用RC只能用同样的方法把镜像地址替换成之前的,然后重新滚动升级。

2 Replication Set(RS)

Replication Set简称RS,随着Kubernetes的高速发展,官方已经推荐我们使用RS和Deployment来代替RC了,实际上RS和RC的功能基本一致,目前唯一的一个区别就是RC只支持基于等式的selector(env=dev或environment!=qa),但RS还支持基于集合的selector(version in (v1.0, v2.0)),这对复杂的运维管理就非常方便了。

eg:

apiVersion: v1
kind: ReplicationSet
metadata:
  name: rc-demo
  labels:
    name: rc
spec:
  replicas: 3
  selector:
    name: rc
  template:
    metadata:
     labels:
       name: rc
    spec:
     containers:
     - name: nginx-demo
       image: nginx
       ports:
       - containerPort: 80

kubectl命令行工具中关于RC的大部分命令同样适用于我们的RS资源对象。不过我们也很少会去单独使用RS,它主要被Deployment这个更加高层的资源对象使用,除非用户需要自定义升级功能或根本不需要升级Pod,在一般情况下,我们推荐使用Deployment而不直接使用Replica Set。

最后我们总结下关于RC/RS的一些特性和作用吧:

  • 大部分情况下,我们可以通过定义一个RC实现的Pod的创建和副本数量的控制
  • RC中包含一个完整的Pod定义模块(不包含apiversion和kind)
  • RC是通过label selector机制来实现对Pod副本的控制的
  • 通过改变RC里面的Pod副本数量,可以实现Pod的扩缩容功能
  • 通过改变RC里面的Pod模板中镜像版本,可以实现Pod的滚动升级功能(但是不支持一键回滚,需要用相同的方法去修改镜像地址)

二、Deployment的使用

首先RC是Kubernetes的一个核心概念,当我们把应用部署到集群之后,需要保证应用能够持续稳定的运行,RC就是这个保证的关键,主要功能如下:

  • 确保Pod数量:它会确保Kubernetes中有指定数量的Pod在运行,如果少于指定数量的Pod,RC就会创建新的,反之这会删除多余的,保证Pod的副本数量不变。
  • 确保Pod健康:当Pod不健康,比如运行出错了,总之无法提供正常服务时,RC也会杀死不健康的Pod,重新创建新的。
  • 弹性伸缩:在业务高峰或者低峰的时候,可以用过RC来动态的调整Pod数量来提供资源的利用率,当然我们也提到过如果使用HPA这种资源对象的话可以做到自动伸缩。
  • 滚动升级:滚动升级是一种平滑的升级方式,通过逐步替换的策略,保证整体系统的稳定性,

Deployment同样也是Kubernetes系统的一个核心概念,主要职责和RC一样的都是保证Pod的数量和健康,二者大部分功能都是完全一致的,我们可以看成是一个升级版的RC控制器,那Deployment又具备那些新特性呢?

  • RC的全部功能:Deployment具备上面描述的RC的全部功能
  • 事件和状态查看:可以查看Deployment的升级详细进度和状态
  • 回滚:当升级Pod的时候如果出现问题,可以使用回滚操作回滚到之前的任一版本
  • 版本记录:每一次对Deployment的操作,都能够保存下来,这也是保证可以回滚到任一版本的基础
  • 暂停和启动:对于每一次升级都能够随时暂停和启动

作为对比,我们知道Deployment作为新一代的RC,不仅在功能上更为丰富了,同时我们也说过现在官方也都是推荐使用Deployment来管理Pod的,比如一些官方组件kube-dns、kube-proxy也都是使用的Deployment来管理的,所以当大家在使用的使用也最好使用Deployment来管理Pod。

1 创建

K8S:常用资源对象操作,Docker & OpenStack,kubernetes,java,容器

可以看出一个Deployment拥有多个Replica Set,而一个Replica Set拥有一个或多个Pod。

一个Deployment控制多个rs主要是为了支持回滚机制,每当Deployment操作时,Kubernetes会重新生成一个Replica Set并保留,以后有需要的话就可以回滚至之前的状态。

下面创建一个Deployment,它创建了一个Replica Set来启动3个nginx pod,yaml文件如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  labels:
    k8s-app: nginx-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

将上面内容保存为: nginx-deployment.yaml,执行命令:

$ kubectl create -f nginx-deployment.yaml 
deployment "nginx-deploy" created

然后执行一下命令查看刚刚创建的Deployment:

$ kubectl get deployments
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3         0         0            0           1s

隔一会再次执行上面命令:
$ kubectl get deployments
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3         3         3            3           4m

我们可以看到Deployment已经创建了1个Replica Set了,执行下面的命令查看rs和pod:

$ kubectl get rs
NAME                     DESIRED   CURRENT   READY     AGE
nginx-deploy-431080787   3         3         3         6m

$ kubectl get pod --show-labels
NAME                           READY     STATUS    RESTARTS   AGE       LABELS
nginx-deploy-431080787-53z8q   1/1       Running   0          7m        app=nginx,pod-template-hash=431080787
nginx-deploy-431080787-bhhq0   1/1       Running   0          7m        app=nginx,pod-template-hash=431080787
nginx-deploy-431080787-sr44p   1/1       Running   0          7m        app=nginx,pod-template-hash=431080787

上面的Deployment的yaml文件中的replicas:3将会保证我们始终有3个POD在运行。

2 滚动升级

现在我们将刚刚保存的yaml文件中的nginx镜像修改为nginx:1.13.3,然后在spec下面添加滚动升级策略:

minReadySeconds: 5
strategy:
  # indicate which strategy we want for rolling update
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 1

minReadySeconds:
Kubernetes在等待设置的时间后才进行升级

  • 如果没有设置该值,Kubernetes会假设该容器启动起来后就提供服务了
  • 如果没有设置该值,在某些极端情况下可能会造成服务不正常运行

maxSurge:

  • 升级过程中最多可以比原先设置多出的POD数量
  • 例如:maxSurage=1,replicas=5,则表示Kubernetes会先启动1一个新的Pod后才删掉一个旧的POD,整个升级过程中最多会有5+1个POD。

maxUnavaible:

  • 升级过程中最多有多少个POD处于无法提供服务的状态
  • 当maxSurge不为0时,该值也不能为0
  • 例如:maxUnavaible=1,则表示Kubernetes整个升级过程中最多会有1个POD处于无法服务的状态。
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: test
  labels:
    app: nginx-demo
spec:
  replicas: 3
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.13.3
        ports:
        - containerPort: 80
          name: nginxweb

然后执行命令:

$ kubectl apply -f nginx-deployment.yaml --record=true
deployment "nginx-deploy" configured

然后我们可以使用rollout命令:

查看状态:kubectl rollout status deployment nginx-deploy
$ kubectl rollout status deployment/nginx-deploy
Waiting for rollout to finish: 1 out of 3 new replicas have been updated..
deployment "nginx-deploy" successfully rolled out

暂停升级
$ kubectl rollout pause deployment nginx-deploy

继续升级
$ kubectl rollout resume deployment nginx-deploy

升级结束后,继续查看rs的状态:

$ kubectl get rs
NAME                      DESIRED   CURRENT   READY     AGE
nginx-deploy-2078889897   0         0         0         47m
nginx-deploy-3297445372   3         3         3         42m
nginx-deploy-431080787    0         0         0         1h

根据AGE我们可以看到离我们最近的当前状态是:3,和我们的yaml文件是一致的,证明升级成功了。

用describe命令可以查看升级的全部信息:

kubectl describe deployment nginx-deploy
Name:     nginx-deploy
Namespace:    default
CreationTimestamp:  Wed, 18 Oct 2017 16:58:52 +0800
Labels:     k8s-app=nginx-demo
Annotations:    deployment.kubernetes.io/revision=3
      kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"k8s-app":"nginx-demo"},"name":"nginx-deploy","namespace":"defa...
Selector:   app=nginx
Replicas:   3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:   RollingUpdate
MinReadySeconds:  0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels: app=nginx
  Containers:
   nginx:
    Image:    nginx:1.13.3
    Port:   80/TCP
    Environment:  <none>
    Mounts:   <none>
  Volumes:    <none>
Conditions:
  Type    Status  Reason
  ----    ------  ------
  Progressing   True  NewReplicaSetAvailable
  Available   True  MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet:  nginx-deploy-3297445372 (3/3 replicas created)
Events:
  FirstSeen LastSeen  Count From      SubObjectPath Type    Reason      Message
  --------- --------  ----- ----      ------------- --------  ------      -------
  50m   50m   1 deployment-controller     Normal    ScalingReplicaSet Scaled up replica set nginx-deploy-2078889897 to 1
  45m   45m   1 deployment-controller     Normal    ScalingReplicaSet Scaled down replica set nginx-deploy-2078889897 to 0
  45m   45m   1 deployment-controller     Normal    ScalingReplicaSet Scaled up replica set nginx-deploy-3297445372 to 1
  39m   39m   1 deployment-controller     Normal    ScalingReplicaSet Scaled down replica set nginx-deploy-431080787 to 2
  39m   39m   1 deployment-controller     Normal    ScalingReplicaSet Scaled up replica set nginx-deploy-3297445372 to 2
  38m   38m   1 deployment-controller     Normal    ScalingReplicaSet Scaled down replica set nginx-deploy-431080787 to 1
  38m   38m   1 deployment-controller     Normal    ScalingReplicaSet Scaled up replica set nginx-deploy-3297445372 to 3
  38m   38m   1 deployment-controller     Normal    ScalingReplicaSet Scaled down replica set nginx-deploy-431080787 to 0

3 回滚Deployment

我们已经能够滚动平滑的升级我们的Deployment了,但是如果升级后的POD出了问题该怎么办?我们能够想到的最好最快的方式当然是回退到上一次能够提供正常工作的版本,Deployment就为我们提供了回滚机制。

首先,查看Deployment的升级历史:

$ kubectl rollout history deployment nginx-deploy
deployments "nginx-deploy"
REVISION  CHANGE-CAUSE
1   <none>
2   <none>
3   kubectl apply --filename=Desktop/nginx-deployment.yaml --record=true

从上面的结果可以看出在执行Deployment升级的时候最好带上record参数,便于我们查看历史版本信息。

默认情况下,所有通过kubectl xxxx --record都会被kubernetes记录到etcd进行持久化,这无疑会占用资源,最重要的是,时间久了,当你kubectl get rs时,会有成百上千的垃圾RS返回给你,那时你可能就眼花缭乱了。

上生产时,我们最好通过设置Deployment的.spec.revisionHistoryLimit来限制最大保留的revision number,比如15个版本,回滚的时候一般只会回滚到最近的几个版本就足够了。
其实rollout history中记录的revision都和ReplicaSets一一对应。如果手动delete某个ReplicaSet,对应的rollout history就会被删除,也就是还说你无法回滚到这个revison了。

---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: test
  labels:
    app: nginx-demo
spec:
  replicas: 3
  revisionHistoryLimit: 15
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: nginxweb

rollout history和ReplicaSet的对应关系,可以在kubectl describe rs $RSNAME返回的revision字段中得到,这里的revision就对应着rollout history返回的revison。

同样我们可以使用下面的命令查看单个revison的信息:

$ kubectl rollout history deployment nginx-deploy --revision=3
deployments "nginx-deploy" with revision #3
Pod Template:
  Labels: app=nginx
  pod-template-hash=3297445372
  Annotations:  kubernetes.io/change-cause=kubectl apply --filename=nginx-deployment.yaml --record=true
  Containers:
   nginx:
    Image:  nginx:1.13.3
    Port: 80/TCP
    Environment:  <none>
    Mounts: <none>
  Volumes:  <none>

假如现在要直接回退到当前版本的前一个版本:

$ kubectl rollout undo deployment nginx-deploy
deployment "nginx-deploy" rolled back

当然也可以用revision回退到指定的版本:

$ kubectl rollout undo deployment nginx-deploy --to-revision=2
deployment "nginx-deploy" rolled back

删除一个rs

$ kubectl delete rs nginx-deploy-431080787

K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

三、 Pod 自动扩缩容HPA

手工执行kubectl scale命令和在Dashboard上操作可以实现Pod的扩缩容,但是这样毕竟需要每次去手工操作一次,而且指不定什么时候业务请求量就很大了,所以如果不能做到自动化的去扩缩容的话,这也是一个很麻烦的事情。

Kubernetes为我们提供了这样一个资源对象:Horizontal Pod Autoscaling(Pod水平自动伸缩),简称HPA。HAP通过监控分析RC或者Deployment控制的所有Pod的负载变化情况来确定是否需要调整Pod的副本数量,这是HPA最基本的原理。
K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

HPA在kubernetes集群中被设计成一个controller

  • 我们可以简单的通过kubectl autoscale命令来创建一个HPA资源对象,
  • HPA Controller默认30s轮询一次(可通过kube-controller-manager的标志–horizontal-pod-autoscaler-sync-period进行设置),查询指定的资源(RC或者Deployment)中Pod的资源使用率,并且与创建时设定的值和指标做对比,从而实现自动伸缩的功能。

当你创建了HPA后,HPA会从Heapster或者用户自定义的RESTClient端获取每一个一个Pod利用率或原始值的平均值,然后和HPA中定义的指标进行对比,同时计算出需要伸缩的具体值并进行相应的操作。目前,HPA可以从两个地方获取数据:

  • Heapster:仅支持CPU使用率
  • 自定义监控:

实际上我们已经默认把Heapster(1.4.2 版本)相关的镜像都已经拉取到节点上了,所以接下来我们只需要部署即可:Heapster的github页面。
K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

heapster.yaml中的image: gcr.io/google_containers/heapster-amd64:v1.3.0可能需要依据本地的image tag进行修改。
grafana.yaml(类似dashboard)中的image: gcr.io/google_containers/heapster-grafana-amd64:v4.2.0可能需要依据本地的image tag进行修改。

我们将该目录下面的yaml文件保存到我们的集群上,然后使用kubectl命令行工具创建即可.
执行所有的yaml文件

kubectl create -f .

查看某个pod的运行日志:

kubectl logs -f heapster-676cc864c6 -n kube-system

通过yaml文件删除pod

kubectl delete -f heapster.yaml

问题:直接启动heapster会出现以下问题:heapster没有权限
K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器
需要将heapster绑定到cluster-admin

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: heapster
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: heapster-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: heapster
  namespace: kube-system
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: heapster
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        task: monitoring
        k8s-app: heapster
    spec:
      serviceAccountName: heapster
      containers:
      - name: heapster
        image: gcr.io/google_containers/heapster-amd64:v1.3.0
        imagePullPolicy: IfNotPresent
        command:
        - /heapster
        - --source=kubernetes:https://kubernetes.default
        - --sink=influxdb:http://monitoring-influxdb.kube-system.svc:8086
---
apiVersion: v1
kind: Service
metadata:
  labels:
    task: monitoring
    # For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
    # If you are NOT using this as an addon, you should comment out this line.
    kubernetes.io/cluster-service: 'true'
    kubernetes.io/name: Heapster
  name: heapster
  namespace: kube-system
spec:
  ports:
  - port: 80
    targetPort: 8082
  selector:
    k8s-app: heapster

重新kubectl delete yaml、kubectl reate即可

另外创建完成后,如果需要在Dashboard当中看到监控图表,我们还需要在Dashboard中配置上我们的heapster-host。

为了能够创建HPA,可能需要修改master上的kube-controller-manager.yaml
K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器
需要在command中增加下面的命令(修改完毕,则自动更新):
K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

1 使用kubectl autoscale

我们来创建一个Deployment管理的Nginx Pod,然后利用HPA来进行自动扩缩容。
定义Deployment的YAML文件如下:(hap-deploy-demo.yaml)

---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: hpa-demo
  labels:
    app: hpa
spec:
  revisionHistoryLimit: 15
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          requests:
            cpu: 100m
        ports:
        - containerPort: 80

然后创建Deployment

$ kubectl create -f hpa-deploy-demo.yaml

现在我们来创建一个HPA,可以使用kubectl autoscale命令来创建:

$ kubectl autoscale deployment hpa-nginx-deploy --cpu-percent=10 --min=1 --max=10
deployment "hpa-nginx-deploy" autoscaled
···
$ kubectl get hpa                                                         
NAME        REFERENCE              TARGET    CURRENT   MINPODS   MAXPODS   AGE
hpa-nginx-deploy   Deployment/hpa-nginx-deploy   10%       0%        1         10        13s

此命令创建了一个关联资源 hpa-nginx-deploy 的HPA,最小的 pod 副本数为1,最大为10。HPA会根据设定的 cpu使用率(10%)动态的增加或者减少pod数量。

现在我们来增大负载进行测试,我们来创建一个busybox,并且循环访问上面创建的服务。

$ kubectl run -i --tty load-generator --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # while true; do wget -q -O- http://172.16.255.60:4000; done

下图可以看到,HPA已经开始工作。

 kubectl get hpa
NAME        REFERENCE              TARGET    CURRENT   MINPODS   MAXPODS   AGE
hpa-nginx-deploy   Deployment/hpa-nginx-deploy   10%       29%        1         10        27m

同时我们查看相关资源hpa-nginx-deploy的副本数量,副本数量已经从原来的1变成了3。

$ kubectl get deployment hpa-nginx-deploy
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hpa-nginx-deploy   3         3         3            3           4d

同时再次查看HPA,由于副本数量的增加,使用率也保持在了10%左右。

$ kubectl get hpa
NAME        REFERENCE              TARGET    CURRENT   MINPODS   MAXPODS   AGE
hpa-nginx-deploy   Deployment/hpa-nginx-deploy   10%       9%        1         10        35m

同样的这个时候我们来关掉busybox来减少负载,然后等待一段时间观察下HPA和Deployment对象

$ kubectl get hpa     
NAME        REFERENCE              TARGET    CURRENT   MINPODS   MAXPODS   AGE
hpa-nginx-deploy   Deployment/hpa-nginx-deploy   10%       0%        1         10        48m
$ kubectl get deployment hpa-nginx-deploy
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hpa-nginx-deploy   1         1         1            1           4d

可以看到副本数量已经由3变为1。

2 不使用kubectl autoscale

使用已经创建成功的hpa

$ kubectl get hpa hpa-nginx-deploy -o yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  creationTimestamp: 2017-06-29T08:04:08Z
  name: nginxtest
  namespace: default
  resourceVersion: "951016361"
  selfLink: /apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers/nginxtest
  uid: 86febb63-5ca1-11e7-aaef-5254004e79a3
spec:
  maxReplicas: 5 //资源最大副本数
  minReplicas: 1 //资源最小副本数
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment //需要伸缩的资源类型
    name: nginxtest  //需要伸缩的资源名称
  targetCPUUtilizationPercentage: 50 //触发伸缩的cpu使用率
status:
  currentCPUUtilizationPercentage: 48 //当前资源下pod的cpu使用率
  currentReplicas: 1 //当前的副本数
  desiredReplicas: 2 //期望的副本数
  lastScaleTime: 2017-07-03T06:32:19Z

K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

使用生成的HPA重新创建一个HPA

删除hpa
kubectl delete hpa hpa-demo

删除deployments
kubectl delete -f hpa-demo.yaml

K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

将生成的yaml追加到hap-deploy-demo.yaml,得到的内容如下:

---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: hpa-demo
  labels:
    app: hpa
spec:
  revisionHistoryLimit: 15
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          requests:
            cpu: 100m
        ports:
        - containerPort: 80

---
5apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-demo
  namespace: default
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: hpa-demo
  targetCPUUtilizationPercentage: 5

重新创建

kubectl create -f hpa-demo.yaml

K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器
K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

三、Job 和 Cronjob 的使用

Job负责处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。而CronJob则就是在Job上加上了时间调度。

1 Job

我们用Job这个资源对象来创建一个任务,我们定一个Job来执行一个倒计时的任务,定义YAML文件:

apiVersion: batch/v1
kind: Job
metadata:
  name: job-demo
spec:
  template:
    metadata:
      name: job-demo
    spec:
      restartPolicy: Never
      containers:
      - name: counter
        image: busybox
        command:
        - "bin/sh"
        - "-c"
        - "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"

注意Job的RestartPolicy仅支持Never和OnFailure两种,不支持Always,我们知道Job就相当于来执行一个批处理任务,执行完就结束了,如果支持Always的话是不是就陷入了死循环了?

然后来创建该Job,保存为job-demo.yaml:

$ kubectl create -f ./job.yaml
job "job-demo" created

然后我们可以查看当前的Job资源对象:

$ kubectl get jobs
$ kubectl describe job job-demo

注意查看我们的Pod的状态,同样我们可以通过kubectl logs来查看当前任务的执行结果。

$ kubectl logs job-demo-p6zst

2 CronJob

期性地在给定时间点运行。这个实际上和我们Linux中的crontab就非常类似了。

一个CronJob对象其实就对应中crontab文件中的一行,它根据配置的时间格式周期性地运行一个Job,格式和crontab也是一样的。

crontab的格式如下:

分 时 日 月 星期 要运行的命令
第1列分钟0~59
第2列小时0~23)
第3列日1~31
第4列月1~12
第5列星期0~7(0和7表示星期天)
第6列要运行的命令

现在,我们用CronJob来管理我们上面的Job任务,

apiVersion: batch/v2alpha1
kind: CronJob
metadata:
  name: cronjob-demo
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: hello
            image: busybox
            args:
            - "bin/sh"
            - "-c"
            - "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"

我们这里的Kind是CronJob了,要注意的是.spec.schedule字段是必须填写的,用来指定任务运行的周期,格式就和crontab一样,另外一个字段是.spec.jobTemplate, 用来指定需要运行的任务,格式当然和Job是一致的。

还有一些值得我们关注的字段.spec.successfulJobsHistoryLimit和.spec.failedJobsHistoryLimit,表示历史限制,是可选的字段。它们指定了可以保留多少完成和失败的Job,默认没有限制,所有成功和失败的Job都会被保留。然而,当运行一个Cron Job时,Job可以很快就堆积很多,所以一般推荐设置这两个字段的值。如果设置限制的值为 0,那么相关类型的Job完成后将不会被保留。

接下来我们来创建这个cronjob

$ kubectl create -f cronjob-demo.yaml
cronjob "cronjob-demo" created

当然,也可以用kubectl run来创建一个CronJob:

kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
$ kubectl get cronjob
NAME      SCHEDULE      SUSPEND   ACTIVE    LAST-SCHEDULE
hello     */1 * * * *   False     0         <none>
$ kubectl get jobs
NAME               DESIRED   SUCCESSFUL   AGE
hello-1202039034   1         1            49s
$ pods=$(kubectl get pods --selector=job-name=hello-1202039034 --output=jsonpath={.items..metadata.name} -a)
$ kubectl logs $pods
Mon Aug 29 21:34:09 UTC 2016
Hello from the Kubernetes cluster

一旦不再需要 Cron Job,简单地可以使用 kubectl 命令删除它:

$ kubectl delete cronjob hello
cronjob "hello" deleted

这将会终止正在创建的 Job。
然而,运行中的 Job 将不会被终止,不会删除 Job 或 它们的 Pod。为了清理那些 Job 和 Pod,需要列出该 Cron Job 创建的全部 Job,然后删除它们:

$ kubectl get jobs
NAME               DESIRED   SUCCESSFUL   AGE
hello-1201907962   1         1            11m
hello-1202039034   1         1            8m
...

$ kubectl delete jobs hello-1201907962 hello-1202039034 ...
job "hello-1201907962" deleted
job "hello-1202039034" deleted
...

一旦 Job 被删除,由 Job 创建的 Pod 也会被删除。注意,所有由名称为 “hello” 的 Cron Job 创建的 Job 会以前缀字符串 “hello-” 进行命名。如果想要删除当前 Namespace 中的所有 Job,可以通过命令 kubectl delete jobs --all 立刻删除它们。

CronJob的某个job与pod之间的对应关系如下:

$ kubectl get cronjob
$ kubectl get jobs
$ kubectl get pods

K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

看下job的对应的pod的log,无法直接查看某个cronjob的log

$ kubectl logs cronjob-demo-12XXX

删除CronJob

$ kubectl delte cronjob cronjob-demo
或者
$ kubectl delete -f cronjob-demo.yaml

四、Service

在没有使用Kubernetes之前,我相信可能很多同学都遇到过这样的问题,不一定是IP变化的问题,比如我们在部署一个WEB服务的时候,前端一般部署一个Nginx作为服务的入口,然后Nginx后面肯定就是挂载的这个服务的大量后端,很早以前我们可能是去手动更改Nginx配置中的upstream选项,来动态改变提供服务的数量,到后面出现了一些服务发现的工具,比如Consul、ZooKeeper还有我们熟悉的etcd等工具,有了这些工具过后我们就可以只需要把我们的服务注册到这些服务发现中心去就可以,然后让这些工具动态的去更新Nginx的配置就可以了,我们完全不用去手工的操作了,是不是非常方便。

K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器
同样的,要解决我们上面遇到的问题是不是实现一个服务发现的工具也可以解决啊?没错的,当我们Pod被销毁或者新建过后,我们可以把这个Pod的地址注册到这个服务发现中心去就可以,但是这样的话我们的前端的Pod结合就不能直接去连接后台的Pod集合了是吧,应该连接到一个能够做服务发现的中间件上面,对吧?

没错,Kubernetes集群就为我们提供了这样的一个对象

  • Service,Service是一种抽象的对象,它定义了一组Pod的逻辑集合和一个用于访问它们的策略,其实这个概念和微服务非常类似。一个Serivce下面包含的Pod集合一般是由Label Selector来决定的。
  • 比如我们上面的例子,假如我们后端运行了3个副本,这些副本都是可以替代的,因为前端并不关心它们使用的是哪一个后端服务。尽管由于各种原因后端的Pod集合会发送变化,但是前端却不需要知道这些变化,也不需要自己用一个列表来记录这些后端的服务,Service的这种抽象就可以帮我们达到这种解耦的目的。

1.三种IP

  • Node IP:Node节点的IP地址
  • Pod IP: Pod的IP地址
  • Cluster IP: Service的IP地址

首先,Node IP是Kubernetes集群中节点的物理网卡IP地址(一般为内网),所有属于这个网络的服务器之间都可以直接通信,所以Kubernetes集群外要想访问Kubernetes集群内部的某个节点或者服务,肯定得通过Node IP进行通信(这个时候一般是通过外网IP了)

然后Pod IP是每个Pod的IP地址,它是Docker Engine根据docker0网桥的IP地址段进行分配的(我们这里使用的是flannel这种网络插件保证所有节点的Pod IP不会冲突)

最后Cluster IP是一个虚拟的IP,仅仅作用于Kubernetes Service这个对象,由Kubernetes自己来进行管理和分配地址,当然我们也无法ping这个地址,他没有一个真正的实体对象来响应,他只能结合Service Port来组成一个可以通信的服务。

2.定义Service

先创建pods

---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: test
  labels:
    app: nginx-demo
spec:
  replicas: 3
  revisionHistoryLimit: 15
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: nginxweb

创建Deployment

$ kubectl create -f deploy-demo.yaml

创建service

apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
  	# 该service的端口
    port: 80
    #匹配到app: nginx的容器的端口
    targetPort: nginxweb
$ kubectl create -f service-demo.yaml

查看

$ kubectl get svc 
$ kubectl describe svc myservice 

K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器
K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

测试Cluster IP

$ kubectl run -it testservice --image=busybox /bin/bash
$ wget -O- -q http://10.104.27.136:80

3.kube-proxy

在Kubernetes集群中,每个Node会运行一个kube-proxy进程, 负责为Service实现一种 VIP(虚拟 IP,就是我们上面说的clusterIP)的代理形式,现在的Kubernetes中默认是使用的iptables这种模式来代理。

这种模式,kube-proxy会监视Kubernetes master对 Service 对象和 Endpoints 对象的添加和移除。

对每个 Service,它会添加上 iptables 规则,从而捕获到达该 Service 的 clusterIP(虚拟 IP)和端口的请求,进而将请求重定向到 Service 的一组 backend 中的某一个个上面。

对于每个 Endpoints 对象,它也会安装 iptables 规则,这个规则会选择一个 backend Pod。

默认的策略是,随机选择一个 backend。 我们也可以实现基于客户端 IP 的会话亲和性,可以将 service.spec.sessionAffinity 的值设置为 “ClientIP” (默认值为 “None”)。

如果最开始选择的 Pod 没有响应,iptables 代理能够自动地重试另一个 Pod,所以它需要依赖 readiness probes。

K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

4.Service 类型

我们在定义Service的时候可以指定一个自己需要的类型的Service,如果不指定的话默认是ClusterIP类型。

我们可以使用的服务类型如下:

  • ClusterIP:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的ServiceType。
  • NodePort:通过每个 Node 节点上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由(会暴露一个node的端口)到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 node ip:node port,可以从集群的外部访问一个 NodePort 服务。
  • LoadBalancer:使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务,这个需要结合具体的云厂商进行操作。
  • ExternalName:通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。

5.NodePort 类型

如果设置 type 的值为 “NodePort”,Kubernetes master 将从给定的配置范围内(默认:30000-32767)分配端口,每个 Node 将从该端口(每个 Node 上的同一端口)代理到 Service。

  • 该端口将通过 Service 的 spec.ports[*].nodePort 字段被指定,如果不指定的话会自动生成一个端口。

需要注意的是,Service 将能够通过 :spec.ports[].nodePort 和 spec.clusterIp:spec.ports[].port 而对外可见。

接下来我们来给大家创建一个NodePort的服务来访问我们前面的Nginx服务:(保存为service-demo.yaml)

apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: myapp
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    name: myapp-http

创建该Service:

$ kubectl create -f service-demo.yaml

然后我们可以查看Service对象信息:

$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        27d
myservice    NodePort    10.104.57.198   <none>        80:32560/TCP   14h

我们可以看到myservice的 TYPE 类型已经变成了NodePort,后面的PORT(S)部分也多了一个 32560 的映射端口。

  • 直接通过node ip:32560即可访问

6.ExternalName

ExternalName 是 Service 的特例,它没有 selector,也没有定义任何的端口和 Endpoint。 对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

当查询主机 my-service.prod.svc.cluster.local (后面服务发现的时候我们会再深入讲解)时,集群的 DNS 服务将返回一个值为 my.database.example.com 的 CNAME 记录。 访问这个服务的工作方式与其它的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发。

如果后续决定要将数据库迁移到 Kubernetes 集群中,可以启动对应的 Pod,增加合适的 Selector 或 Endpoint,修改 Service 的 type,完全不需要修改调用的代码,这样就完全解耦了。

五、ConfigMap

资源对象:ConfigMap,我们知道许多应用经常会有从配置文件、命令行参数或者环境变量中读取一些配置信息,这些配置信息我们肯定不会直接写死到应用程序中去的,比如你一个应用连接一个redis服务,下一次想更换一个了的,还得重新去修改代码,重新制作一个镜像,这肯定是不可取的,而ConfigMap就给我们提供了向容器中注入配置信息的能力,不仅可以用来保存单个属性,也可以用来保存整个配置文件,比如我们可以用来配置一个redis服务的访问地址,也可以用来保存整个redis的配置文件。

1.通过yaml文件的方式创建

ConfigMap 资源对象使用key-value形式的键值对来配置数据,这些数据可以在Pod里面使用,ConfigMap和我们后面要讲到的Secrets比较类似,一个比较大的区别是ConfigMap可以比较方便的处理一些非敏感的数据,比如密码之类的还是需要使用Secrets来进行管理。

我们来举个例子说明下ConfigMap的使用方法:

kind: ConfigMap
apiVersion: v1
metadata:
  name: cm-demo
  namespace: default
data:
  data.1: hello
  data.2: world
  config: |
    property.1=value-1
    property.2=value-2
    property.3=value-3

其中配置数据在data属性下面进行配置,前两个被用来保存单个属性,后面一个被用来保存一个配置文件。

使用kubectl create -f xx.yaml来创建上面的ConfigMap对象

查询configmap

$ kubectl get configmap

描述configmap

$ kubectl describe configmap cm-demo1

2.通过目录和命令行创建

我们可以看到可以从一个给定的目录来创建一个ConfigMap对象,比如我们有一个testcm的目录,该目录下面包含一些配置文件,redis和mysql的连接信息,如下:

$ ls testcm
redis.conf
mysql.conf

$ cat testcm/redis.conf
host=127.0.0.1
port=6379

$ cat testcm/mysql.conf
host=127.0.0.1
port=3306

然后我们可以使用from-file关键字来创建包含这个目录下面所以配置文件的ConfigMap:

$ kubectl create configmap cm-demo1 --from-file=testcm
configmap "cm-demo1" created

其中from-file参数指定在该目录下面的所有文件都会被用在ConfigMap里面创建一个键值对,键的名字就是文件名,值就是文件的内容。

创建完成后,同样我们可以使用如下命令来查看ConfigMap列表:

$ kubectl get configmap
NAME       DATA      AGE
cm-demo1   2         17s

可以看到已经创建了一个cm-demo1的ConfigMap对象,然后可以使用describe命令查看详细信息:

kubectl describe configmap cm-demo1
Name:         cm-demo1
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
mysql.conf:
----
host=127.0.0.1
port=3306

redis.conf:
----
host=127.0.0.1
port=6379

Events:  <none>

我们可以看到两个key是testcm目录下面的文件名称,对应的value值的话就是文件内容,这里值得注意的是如果文件里面的配置信息很大的话,describe的时候可能不会显示对应的值,要查看键值的话,可以使用如下命令:

$ kubectl get configmap cm-demo1 -o yaml
apiVersion: v1
data:
  mysql.conf: |
    host=127.0.0.1
    port=3306
  redis.conf: |
    host=127.0.0.1
    port=6379
kind: ConfigMap
metadata:
  creationTimestamp: 2018-06-14T16:24:36Z
  name: cm-demo1
  namespace: default
  resourceVersion: "3109975"
  selfLink: /api/v1/namespaces/default/configmaps/cm-demo1
  uid: 6e0f4d82-6fef-11e8-a101-525400db4df7

3.通过配置文件和命令行创建

以上面的配置文件为例,我们创建一个redis的配置的一个单独ConfigMap对象:

$ kubectl create configmap cm-demo2 --from-file=testcm/redis.conf
configmap "cm-demo2" created
$ kubectl get configmap cm-demo2 -o yaml
apiVersion: v1
data:
  redis.conf: |
    host=127.0.0.1
    port=6379
kind: ConfigMap
metadata:
  creationTimestamp: 2018-06-14T16:34:29Z
  name: cm-demo2
  namespace: default
  resourceVersion: "3110758"
  selfLink: /api/v1/namespaces/default/configmaps/cm-demo2
  uid: cf59675d-6ff0-11e8-a101-525400db4df7

我们可以看到一个关联redis.conf文件配置信息的ConfigMap对象创建成功了,另外值得注意的是–from-file这个参数可以使用多次,比如我们这里使用两次分别指定redis.conf和mysql.conf文件,就和直接指定整个目录是一样的效果了。

4.通过命令行的–from-literal进行创建

可以直接使用字符串进行创建,通过–from-literal参数传递配置信息,同样的,这个参数可以使用多次,格式如下:

$ kubectl create configmap cm-demo3 --from-literal=db.host=localhost --from-literal=db.port=3306
configmap "cm-demo3" created
$ kubectl get configmap cm-demo3 -o yaml
apiVersion: v1
data:
  db.host: localhost
  db.port: "3306"
kind: ConfigMap
metadata:
  creationTimestamp: 2018-06-14T16:43:12Z
  name: cm-demo3
  namespace: default
  resourceVersion: "3111447"
  selfLink: /api/v1/namespaces/default/configmaps/cm-demo3
  uid: 06eeec7e-6ff2-11e8-a101-525400db4df7

5.如何在pod中使用?

ConfigMap这些配置数据可以通过很多种方式在Pod里使用,主要有以下几种方式:

  • 设置环境变量的值
  • 在容器里设置命令行参数
  • 在数据卷里面创建config文件

(1)设置环境变量的值

apiVersion: v1
kind: Pod
metadata:
  name: testcm1-pod
spec:
  containers:
    - name: testcm1
      image: busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: cm-demo3
              key: db.host
        - name: DB_PORT
          valueFrom:
            configMapKeyRef:
              name: cm-demo3
              key: db.port
      envFrom:
        - configMapRef:
            name: cm-demo1

这个Pod运行后会输出如下几行:

$ kubectl logs testcm1-pod
......
DB_HOST=localhost
DB_PORT=3306
mysql.conf=host=127.0.0.1
port=3306
redis.conf=host=127.0.0.1
port=6379
......

我们可以看到DB_HOST和DB_PORT都已经正常输出了,另外的环境变量是因为我们这里直接把cm-demo1给注入进来了,所以把他们的整个键值给输出出来了,这也是符合预期的。

(2)在容器里设置命令行参数
ConfigMap也可以被用来设置容器中的命令或者参数值,如下Pod:

apiVersion: v1
kind: Pod
metadata:
  name: testcm2-pod
spec:
  containers:
    - name: testcm2
      image: busybox
      command: [ "/bin/sh", "-c", "echo $(DB_HOST) $(DB_PORT)" ]
      env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: cm-demo3
              key: db.host
        - name: DB_PORT
          valueFrom:
            configMapKeyRef:
              name: cm-demo3
              key: db.port

运行这个Pod后会输出如下信息:

$ kubectl logs testcm2-pod
localhost 3306

(3)在数据卷里面创建config文件

外一种是非常常见的使用ConfigMap的方式:通过数据卷使用,在数据卷里面使用ConfigMap,就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容:

apiVersion: v1
kind: Pod
metadata:
  name: testcm4-pod
spec:
  containers:
  - name: testcm4
    image: busybox
    command: ["/bin/sh", "-c", "cat /etc/config/redis.conf"]
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
  # 与volumeMounts.name保持一致
  - name: config-volume
    configMap:
     name: cm-demo3

运行这个Pod的,查看日志:

$ kubectl logs testcm3-pod
host=127.0.0.1
port=6379

K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

K8S:常用资源对象操作,Docker &amp; OpenStack,kubernetes,java,容器

当然我们也可以在ConfigMap值被映射的数据卷里去控制路径,如下Pod定义:

apiVersion: v1
kind: Pod
metadata:
  name: testcm4-pod
spec:
  containers:
    - name: testcm4
      image: busybox
      command: [ "/bin/sh","-c","cat /etc/config/path/to/msyql.conf" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: cm-demo1
        items:
        - key: mysql.conf
          path: path/to/msyql.conf

运行这个Pod的,查看日志:

$ kubectl logs testcm4-pod
host=127.0.0.1
port=3306

另外需要注意的是,当ConfigMap以数据卷的形式挂载进Pod的时,这时更新ConfigMap(或删掉重建ConfigMap),Pod内挂载的配置信息会热更新。这时可以增加一些监测配置文件变更的脚本,然后reload对应服务。文章来源地址https://www.toymoban.com/news/detail-847479.html

到了这里,关于K8S:常用资源对象操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • k8s资源对象(1) namespace&&pod

    Namespace是kubernetes系统中的一种非常重要资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。 默认情况下,kubernetes集群中的所有的Pod都是可以相互访问的。但是在实际中,可能不想让两个Pod之间进行互相的访问,那此时就可以将两个Pod划分到不同的

    2024年01月18日
    浏览(35)
  • yum部署kubernetes(k8s)集群、k8s常用资源管理

    目录 一、环境搭建 1、准备环境 1)计算机说明,建议系统版本7.4或者7.6 2)修改所有主机的计算机名设置host文件  2、安装master节点 1)安装etcd配置etcd 2)安装k8s-master节点 3)配置apiserver 4)配置controller和scheduler 5)启动k8s服务 3、安装k8s-master上的node 1)安装node 2)配置kube

    2024年02月13日
    浏览(47)
  • (kubernetes)k8s常用资源管理

    目录 k8s常用资源管理 1、创建一个pod 1)创建yuml文件 2)创建容器 3)查看所有pod创建运行状态 4)查看指定pod资源 5)查看pod运行的详细信息 6)验证运行的pod 2、pod管理 1)删除pod 2)查看删除pod无法找到 3)创建pod 4)发现最先创建的pod运行在k8s-master节点上,下载镜像速度太

    2024年02月13日
    浏览(36)
  • Host/ KVM/ Docker/ K8s/ OpenStack/ Mesos简单介绍和区别

    Host 是指物理服务器或虚拟机主机,它们可以运行多个虚拟机或容器来提供计算和存储资源。Host 是云计算和容器化技术中的基本组成部分。 KVM 是一种开源虚拟化技术,它可以将一台物理服务器虚拟化为多个虚拟机,每个虚拟机可以运行不同的操作系统和应用程序。KVM 可以提

    2024年02月14日
    浏览(37)
  • 【K8S】Kubernetes 中有状态的资源对象——StatefulSet

    现在基本上很多服务中的应用都是有状态的,比如MySQL数据库、Redis等,因为其中的数据在不断地变化,所以这些应用每个时刻都处于一个不同的状态。或者一个系统中存在多个不同的应用,这些应用存在一定的依赖关系。例如一个博客服务,该服务中包含了Redis缓存和MySQL数

    2024年02月04日
    浏览(35)
  • K8S - 架构、常用K8S命令、yaml资源清单部署、Ingress、故障排查、存储卷

    K8S官网文档:https://kubernetes.io/zh/docs/home/ 学习东西还是要从官方文档入手; 用于管理、扩展、自动部署容器; 其实就是 对多个跨机器的Docker集群; 服务发现和负载均衡 Kubernetes 可以使用 DNS 名称或自己的 IP 地址来暴露容器。 如果进入容器的流量很大, Kubernetes 可以负载均

    2024年02月09日
    浏览(45)
  • Kubernetes(K8s)从入门到精通系列之三:K8s的基本概念和术语之资源对象概述

    K8s中的基本概念和术语大多是围绕资源对象(Resource Object)来说的,而资源对象在总体上可分为以下两类: 某种资源的对象,例如节点(Node)、Pod、服务(Service)、存储卷(Volume)。 与资源对象相关的事物与动作,例如标签(Label)、注解(Annotation)、命名空间(Namespace)、部署(Deployment)、

    2024年02月14日
    浏览(44)
  • k8s对象操作的了解

    Kubernetes对象指的是Kubernetes系统的持久化实体,所有这些对象合起来,代表了你集群的实际情况。常规的应用里,我们把应用程序的数据存储在数据库中,Kubernetes将其数据以Kubernetes对象的形式通过 api server存储在 etcd 中。具体来说,这些数据(Kubernetes对象)描述了: 集群中

    2024年02月12日
    浏览(49)
  • 云上攻防-云原生篇&;Kubernetes&;K8s安全&;API&;Kubelet未授权访问&;容器执行

    curl -XPOST -k “https://192.168.139.132:10250/run///” -d “cmd=id” 执行的命令是test03容器里的命令,需要进行容器逃逸。 1、攻击8080端口:API Server(Master)未授权访问 旧版本的k8s的API Server默认会开启两个端口:8080和6443。 6443是安全端口,安全端口使用TLS加密;但是8080端口无需认证,

    2024年04月22日
    浏览(45)
  • K8s: Ingress对象, 创建Ingress控制器, 创建Ingress资源并暴露服务

    Ingress对象 1 )概述 Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP Ingress-nginx 本质是网关,当你请求 abc.com/service/a, Ingress 就把对应的地址转发给你,底层运行了一个 nginx 但 K8s 为什么不直接使用 nginx 呢,是因为 K8s 也需要把转发的路由规则纳入

    2024年04月28日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包