云服务器内容精选

  • 删除Pod 删除pod时,Kubernetes终止Pod中所有容器。 Kubernetes向进程发送SIGTERM信号并等待一定的秒数(默认为30)让容器正常关闭。 如果它没有在这个时间内关闭,Kubernetes会发送一个SIGKILL信号杀死该进程。 Pod的停止与删除有多种方法,比如按名称删除,如下所示。 $ kubectl delete po nginx -n $namespace_name pod "nginx" deleted 同时删除多个Pod。 $ kubectl delete po pod1 pod2 -n $namespace_name 删除所有Pod。 $ kubectl delete po --all -n $namespace_name pod "nginx" deleted 根据Label删除Pod,Label详细内容将会在下一个章节介绍。 $ kubectl delete po -l app=nginx -n $namespace_name pod "nginx" deleted
  • 什么是Pod Pod是Kubernetes创建或部署的最小单位。一个Pod封装一个或多个容器(container)、存储资源(volume)、一个独立的网络IP以及管理控制容器运行方式的策略选项。 Pod使用主要分为两种方式: Pod中运行一个容器。这是Kubernetes最常见的用法,您可以将Pod视为单个封装的容器,但是Kubernetes是直接管理Pod而不是容器。 Pod中运行多个需要耦合在一起工作、需要共享资源的容器。通常这种场景下是应用包含一个主容器和几个辅助容器(SideCar Container),如图1所示,例如主容器为一个web服务器,从一个固定目录下对外提供文件服务,而辅助的容器周期性的从外部下载文件存到这个固定目录下。 图1 Pod 实际使用中很少直接创建Pod,而是使用Kubernetes中称为Controller的抽象层来管理Pod实例,例如Deployment和Job。Controller可以创建和管理多个Pod,提供副本管理、滚动升级和自愈能力。通常,Controller会使用Pod Template来创建相应的Pod。
  • 查询Pod详情 Pod创建完成后,可以使用kubectl get pods命令查询Pod的状态,如下所示。 $ kubectl get pods -n $namespace_name NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 40s 可以看到此处nginx这个Pod的状态为Running,表示正在运行;READY为1/1,表示这个Pod中有1个容器,其中1个容器的状态为Ready。 可以使用kubectl get命令查询具体Pod的配置信息,如下所示,-o yaml表示以YAML格式返回,还可以使用 -o json,以JSON格式返回。 $ kubectl get pod nginx -o yaml -n $namespace_name 您还可以使用kubectl describe命令查看Pod的详情。 $ kubectl describe pod nginx -n $namespace_name
  • 使用GPU 云容器实例支持使用GPU(必须在GPU类型命名空间下),申请GPU资源的方法非常简单,只需要在容器定制中申请GPU字段即可。 具体的规格信息请参考约束与限制中的“Pod规格”。 您需要设置Pod的metadata.annotations中添加cri.cci.io/gpu-driver字段,指定使用哪个版本显卡驱动,取值如下: gpu-460.106 gpu-418.126 如下示例创建一个容器规格为NVIDIA V100 16G x 1,CPU 4核,内存32GiB的Pod。 apiVersion: v1 kind: Pod metadata: name: gpu-test annotations: cri.cci.io/gpu-driver: gpu-418.126 # 指定GPU显卡的驱动版本 spec: containers: - image: tensorflow:latest name: container-0 resources: limits: cpu: 4000m # 4核 memory: 32Gi nvidia.com/gpu-tesla-v100-16GB: 1 # 申请GPU资源,支持 1、2、4、8,代表几块显卡 requests: cpu: 4000m # 4核 memory: 32Gi nvidia.com/gpu-tesla-v100-16GB: 1 imagePullSecrets: - name: imagepull-secret
  • 创建Pod kubernetes资源可以使用YAML描述(如果您对YAML格式不了解,可以参考YAML语法),也可以使用JSON,如下示例描述了一个名为nginx的Pod,这个Pod中包含一个名为container-0的容器,使用nginx:alpine镜像,使用的资源为0.5核CPU、1024M内存。 apiVersion: v1 # Kubernetes的API Version kind: Pod # Kubernetes的资源类型 metadata: name: nginx # Pod的名称 spec: # Pod的具体规格(specification) containers: - image: nginx:alpine # 使用的镜像为 nginx:alpine name: container-0 # 容器的名称 resources: # 申请容器所需的资源,云容器实例中limits与requests的值必须相同 limits: cpu: 500m # 0.5核 memory: 1024Mi requests: cpu: 500m # 0.5核 memory: 1024Mi imagePullSecrets: # 拉取镜像使用的证书,必须为imagepull-secret - name: imagepull-secret 如上面YAML的注释,YAML描述文件主要为如下部分: metadata:一些名称/标签/namespace等信息 spec:Pod实际的配置信息,包括使用什么镜像,volume等 如果去查询Kubernetes的资源,您会看到还有一个status字段,status描述kubernetes资源的实际状态,创建时不需要配置。这个示例是一个最小集,其他参数定义后面会逐步介绍。 kubernetes资源的参数定义的解释,您可以通过具体资源的API参考查询对应的解释。 Pod定义好后就可以使用kubectl创建,如果上面YAML文件名称为nginx.yaml,则创建命令如下所示,-f 表示使用文件方式创建。 $ kubectl create -f nginx.yaml -n $namespace_name pod/nginx created
  • 启动命令 启动容器就是启动主进程,但有些时候,启动主进程前,需要一些准备工作。比如MySQL类的数据库,可能需要一些数据库配置、初始化的工作,这些工作要在最终的MySQL服务器运行之前解决。这些操作,可以在制作镜像时通过在Dockerfile文件中设置ENTRYPOINT或CMD来完成,如下所示的Dockerfile中设置了ENTRYPOINT ["top", "-b"]命令,其将会在容器启动时执行。 FROM ubuntu ENTRYPOINT ["top", "-b"] 调用接口时,只需配置pod的containers.command参数,该参数是list类型,第一个参数为执行命令,后面均为命令的参数。 apiVersion: v1 kind: Pod metadata: name: Ubuntu spec: containers: - image: Ubuntu name: container-0 resources: limits: cpu: 500m memory: 1024Mi requests: cpu: 500m memory: 1024Mi command: # 启动命令 - top - "-b" imagePullSecrets: - name: imagepull-secret 父主题: Pod
  • 状态码 状态码 描述 200 OK 400 BadRequest 401 Unauthorized 403 Forbidden 404 NotFound 405 MethodNotAllowed 406 NotAcceptable 409 AlreadyExists 415 UnsupportedMediaType 422 Invalid 429 TooManyRequests 500 InternalError 503 ServiceUnavailable 504 ServerTimeout
  • URI POST /api/v1/namespaces/{namespace}/pods/{name}/exec 表1 路径参数 参数 是否必选 参数类型 描述 name 是 String name of the PodExecOptions namespace 是 String object name and auth scope, such as for teams and projects 表2 Query参数 参数 是否必选 参数类型 描述 command 否 String Command is the remote command to execute. argv array. Not executed within a shell. container 否 String Container in which to execute the command. Defaults to only container if there is only one container in the pod. stderr 否 Boolean Redirect the standard error stream of the pod for this call. Defaults to true. stdin 否 Boolean Redirect the standard input stream of the pod for this call. Defaults to false. stdout 否 Boolean Redirect the standard output stream of the pod for this call. Defaults to true. tty 否 Boolean TTY if true indicates that a tty will be allocated for the exec call. Defaults to false.
  • 响应示例 状态码: 200 OK { "apiVersion" : "v1", "kind" : "Pod", "metadata" : { "annotations" : { "cri.cci.io/container-type" : "secure-container", "kubernetes.io/availablezone" : "dc1", "network.alpha.kubernetes.io/network" : "[{\"name\":\"namespace-test-dc1-default-network\",\"interface\":\"eth0\",\"network_plane\":\"default\"}]" }, "creationTimestamp" : "2018-09-03T12:26:12Z", "labels" : { "name" : "pod-test" }, "name" : "pod-test", "namespace" : "namespace-test", "resourceVersion" : "5030610", "selfLink" : "/api/v1/namespaces/namespace-test/pods/pod-test", "uid" : "8b985a27-af74-11e8-9d5d-c88d83be759f" }, "spec" : { "containers" : [ { "image" : "redis", "imagePullPolicy" : "Always", "name" : "test", "resources" : { "limits" : { "cpu" : "500m", "memory" : "1Gi" }, "requests" : { "cpu" : "500m", "memory" : "1Gi" } }, "terminationMessagePath" : "/dev/termination-log", "terminationMessagePolicy" : "File" } ], "dnsPolicy" : "ClusterFirst", "imagePullSecrets" : [ { "name" : "imagepull-secret" } ], "nodeName" : "c0dd6256-195a-e811-90a2-10c17294fcbc", "restartPolicy" : "Always", "schedulerName" : "default-scheduler", "securityContext" : { }, "tolerations" : [ { "effect" : "NoExecute", "key" : "node.kubernetes.io/not-ready", "operator" : "Exists", "tolerationSeconds" : 300 }, { "effect" : "NoExecute", "key" : "node.kubernetes.io/unreachable", "operator" : "Exists", "tolerationSeconds" : 300 } ] }, "status" : { "conditions" : [ { "lastProbeTime" : null, "lastTransitionTime" : "2018-09-03T12:26:12Z", "status" : "True", "type" : "Initialized" }, { "lastProbeTime" : null, "lastTransitionTime" : "2018-09-03T12:26:16Z", "status" : "True", "type" : "Ready" }, { "lastProbeTime" : null, "lastTransitionTime" : "2018-09-03T12:26:12Z", "status" : "True", "type" : "PodScheduled" } ], "containerStatuses" : [ { "containerID" : "docker://aee55d8dedb8371f96aa5d5116f69a53bf1cb23afe1802567c24081514d3b048", "image" : "redis", "imageID" : "docker-pullable://redis@sha256:3ab7046bd035a47aa06963d8240651d00b57e82dab07ba374ad01f84dfa1230c", "lastState" : { }, "name" : "test", "ready" : true, "restartCount" : 0, "state" : { "running" : { "startedAt" : "2018-09-03T12:26:16Z" } } } ], "phase" : "Running", "podIP" : "192.168.245.185", "qosClass" : "Guaranteed", "startTime" : "2018-09-03T12:26:12Z" } }
  • 状态码 状态码 描述 200 OK 400 BadRequest 401 Unauthorized 403 Forbidden 404 NotFound 405 MethodNotAllowed 406 NotAcceptable 409 Conflict 415 UnsupportedMediaType 422 Invalid 429 TooManyRequests 500 InternalError 503 ServiceUnavailable 504 ServerTimeout
  • URI GET /api/v1/namespaces/{namespace}/pods/{name}/status 表1 路径参数 参数 是否必选 参数类型 描述 name 是 String name of the Pod namespace 是 String object name and auth scope, such as for teams and projects 表2 Query参数 参数 是否必选 参数类型 描述 pretty 否 String If 'true', then the output is pretty printed.
  • 有状态负载(StatefulSet) Deployment控制器下的Pod都有个共同特点,那就是每个Pod除了名称和IP地址不同,其余完全相同。需要的时候,Deployment可以通过Pod模板创建新的Pod;不需要的时候,Deployment就可以删除任意一个Pod。 但是在某些场景下,这并不满足需求,比如有些分布式的场景,要求每个Pod都有自己单独的状态时,比如 分布式数据库 ,每个Pod要求有单独的存储,这时Deployment无法满足业务需求。 分布式有状态应用的特点主要是应用中每个部分的角色不同(即分工不同),比如数据库有主备、Pod之间有依赖,在Kubernetes中部署有状态应用对Pod有如下要求: Pod能够被别的Pod找到,要求Pod有固定的标识。 每个Pod有单独存储,Pod被删除恢复后,必须读取原来的数据,否则状态就会不一致。 Kubernetes提供了StatefulSet来解决这个问题,其具体如下: StatefulSet给每个Pod提供固定名称,Pod名称增加从0-N的固定后缀,Pod重新调度后Pod名称和HostName不变。 StatefulSet通过Headless Service给每个Pod提供固定的访问域名。 StatefulSet通过创建固定标识的PVC保证Pod重新调度后还是能访问到相同的持久化数据。
  • 创建Statefulset Statefulset的YAML定义与其他对象基本相同,主要有两个差异点: serviceName指定了Statefulset使用哪个Headless Service,需要填写Headless Service的名称。 volumeClaimTemplates是用来申请持久化声明PVC ,这里定义了一个名为data的模板,它会为每个Pod创建一个PVC,storageClassName指定了持久化存储的类型,在PV、PVC和StorageClass会详细介绍;volumeMounts是为Pod挂载存储。当然如果不需要存储的话可以删除volumeClaimTemplates和volumeMounts字段。 apiVersion: apps/v1 kind: StatefulSet metadata: name: nginx spec: serviceName: nginx # headless service的名称 replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: container-0 image: nginx:alpine resources: limits: cpu: 100m memory: 200Mi requests: cpu: 100m memory: 200Mi volumeMounts: # Pod挂载的存储 - name: data mountPath: /usr/share/nginx/html # 存储挂载到/usr/share/nginx/html imagePullSecrets: - name: default-secret volumeClaimTemplates: - metadata: name: data spec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi storageClassName: csi-nas # 持久化存储的类型 执行如下命令创建。 # kubectl create -f statefulset.yaml statefulset.apps/nginx created 命令执行后,查询一下StatefulSet和Pod,可以看到Pod的名称后缀从0开始到2,逐个递增。 # kubectl get statefulset NAME READY AGE nginx 3/3 107s # kubectl get pods NAME READY STATUS RESTARTS AGE nginx-0 1/1 Running 0 112s nginx-1 1/1 Running 0 69s nginx-2 1/1 Running 0 39s 此时如果手动删除nginx-1这个Pod,然后再次查询Pod,可以看到StatefulSet重新创建了一个名称相同的Pod,通过创建时间5s可以看出nginx-1是刚刚创建的。 # kubectl delete pod nginx-1 pod "nginx-1" deleted # kubectl get pods NAME READY STATUS RESTARTS AGE nginx-0 1/1 Running 0 3m4s nginx-1 1/1 Running 0 5s nginx-2 1/1 Running 0 1m10s 进入容器查看容器的hostname,可以看到同样是nginx-0、nginx-1和nginx-2。 # kubectl exec nginx-0 -- sh -c 'hostname' nginx-0 # kubectl exec nginx-1 -- sh -c 'hostname' nginx-1 # kubectl exec nginx-2 -- sh -c 'hostname' nginx-2 同时可以看一下StatefulSet创建的PVC,可以看到这些PVC,都以“PVC名称-StatefulSet名称-编号”的方式命名,并且处于Bound状态。 # kubectl get pvc NAME STATUS VOLUME CAPACITY AC CES S MODES STORAGECLASS AGE data-nginx-0 Bound pvc-f58bc1a9-6a52-4664-a587-a9a1c904ba29 1Gi RWX csi-nas 2m24s data-nginx-1 Bound pvc-066e3a3a-fd65-4e65-87cd-6c3fd0ae6485 1Gi RWX csi-nas 101s data-nginx-2 Bound pvc-a18cf1ce-708b-4e94-af83-766007250b0c 1Gi RWX csi-nas 71s
  • Pod Security Admission标签 Kubernetes为Pod Security Admission定义了三种标签,如表2,您可以在某个命名空间中设置这些标签来定义需要使用的Pod安全性标准级别,但请勿在kube-system等系统命名空间修改Pod安全性标准级别,否则可能导致系统命名空间下Pod故障。 表2 Pod Security Admission标签 隔离模式(mode) 生效对象 描述 enforce Pod 违反指定策略会导致Pod无法创建。 audit 工作负载(例如Deployment、Job等) 违反指定策略会在审计日志(audit log)中添加新的审计事件,Pod可以被创建。 warn 工作负载(例如Deployment、Job等) 违反指定策略会返回用户可见的告警信息,Pod可以被创建。 Pod通常是通过创建Deployment或Job这类工作负载对象来间接创建的。在使用Pod Security Admission时,audit或warn模式的隔离都将在工作负载级别生效,而enforce模式并不会应用到工作负载,仅在Pod上生效。
  • 从PodSecurityPolicy迁移到Pod Security Admission 如您在1.25之前版本的集群中使用了PodSecurityPolicy,且需要在1.25及以后版本集群中继续使用Pod Security Admission来替代PodSecurityPolicy的用户,请参见从PodSecurityPolicy迁移到内置的Pod Security Admission。 由于Pod Security Admission仅支持三种隔离模式,因此灵活性相比于PodSecurityPolicy较差,部分场景下需要用户自行定义验证准入Webhook来实施更精准的策略。 由于PodSecurityPolicy具有变更能力,而Pod Security Admission并不具备该能力,因此之前依赖该能力的用户需要自行定义变更准入Webhook或修改Pod中的securityContext字段。 PodSecurityPolicy允许为不同的服务账号(Service Account)绑定不同策略(Kubernetes社区不建议使用该能力)。如果您有使用该能力的诉求,在迁移至Pod Security Admission后,需要自行定义第三方Webhook。 请勿将Pod Security Admission能力应用于kube-system、kube-public和kube-node-lease等一些CCE组件部署的Namespace中,否则会导致CCE组件、插件功能异常。