当前位置: 首页 > news >正文

超11万字整理完k8s的核心组件pod全部功能详解,理论代码超详细,建议跟着做一遍实验【含 label 标签使用】【1】

文章目录

  • 说明【必看】
    • 第二篇文章标题和链接
    • 第二篇文章标题和链接
    • 第三篇文章标题和链接
  • 创建及删除pod
    • 创建一个pod-1的文件夹和命名空间
    • 镜像准备【node节点执行】
    • 创建pod【虚拟机】
      • 方式1:命令行的方式【不建议】
        • 默认创建
        • 加imagePullPolicy参数创建
        • 说明
      • 方式2:yaml文件的方式创建【建议】
        • 获取yaml文件
        • 获取的配置文件说明
          • yaml文件格式说明
          • 一级参数获取
          • 二级菜单获取
          • 三级菜单获取
        • 配置文件中“-”的作用以及啥时候需要加“-”
          • 说明
          • demo说明
        • restartPolicy 参数说明
        • 编辑配置文件
        • 通过文件创建pod
        • 通过文件创建多个pod
        • 创建pod报错...expected "map"处理
    • 删除pod
      • pod名称方式删除【建议】
        • 配置文件方式删除
  • pod的几种状态说明
  • 一个pod运行多个容器
    • 说明
    • 容器的CMD说明
    • 指定容器CMD并创建
  • 在pod里执行一些命令
    • 查看pod详细信息
    • 不进入bash直接执行pod容器命令
      • 只有一个容器的情况下
      • 指定pod容器查看
    • 创建bash并进入pod容器
      • 只有一个容器的情况下
      • 指定pod容器查看
    • 拷贝本地文件到pod容器内【含反过来拷贝】
      • 指定pod容器
    • 查看pod容器日志输出【用于排错】
      • 指定pod容器
  • pod的生命周期【优雅的关闭】
  • pod钩子【pod hook】
    • 说明
    • demo
  • 初始化pod
    • 说明
    • 规则
    • demo
    • 扩展demo【修改内核参数】
    • 扩展demo【容器数据同步到本地,在获取本地数据】

说明【必看】

在这里插入图片描述

  • 因为总数超过了11万,我放在一篇中增修改的时候,我的天呐,打一个字要好几秒才能加载出来,而且页面加载也超级缓慢,最后一个原因是因为,标题实在太多,所以我分成了3篇来发布,初次看的时候,建议3篇都打开,按顺序学习和使实验,有助于理解哈。 后面复习的时候看标题,点进相应的文章哈
  • 这篇是第一篇

第二篇文章标题和链接

第二篇文章标题和链接

文章链接:

标题如下:
在这里插入图片描述
在这里插入图片描述

第三篇文章标题和链接

文章链接:

标题如下:
在这里插入图片描述
在这里插入图片描述

创建及删除pod

创建一个pod-1的文件夹和命名空间

  • 创建这个文件夹和命名空间是为了方便展示,这所有的测试文件放pod-1文件夹中,新增pod都放在这个pod-1命名空间内
[root@master wal]# mkdir pod-1
[root@master wal]# cd pod-1
[root@master pod-1]# 
[root@master pod-1]# kubectl create ns pod-1
namespace/pod-1 created
[root@master pod-1]# # 下面命令是切换到pod-1这个命名空间,kubens命令是需要单独安装的。
[root@master pod-1]# kubens pod-1
Context "context" modified.
Active namespace is "pod-1".
[root@master pod-1]# 
[root@master pod-1]# kubectl config get-contexts 
CURRENT   NAME           CLUSTER   AUTHINFO   NAMESPACE
*         context        master    ccx        pod-1context1-new   master1   ccx1       default
[root@master pod-1]# 
  • 安装kubens命令的博客如下:

k8s安装metric server和了解namespace【命名空间】,含k8s pod状态为ImagePullBackOff处理方法

镜像准备【node节点执行】

  • master上执行下面命令可以查看node节点的
[root@master pod-1]# kubectl get nodes
NAME     STATUS   ROLES    AGE    VERSION
master   Ready    <none>   3d6h   v1.21.0
node1    Ready    <none>   3d6h   v1.21.0
node2    Ready    <none>   3d6h   v1.21.0
[root@master pod-1]# 
  • 在noede节点上下载一个nginx镜像,方便做测试
    命令:docker pull nginx 【如果这些流程不清楚的,去我博客docker分类中补一下相关知识】
    下载完毕以后就会有这个镜像【注意主机名】
[root@node1 ~]# docker images | grep nginx
nginx                                                             latest     d1a364dc548d   7 weeks ago     133MB
[root@node1 ~]# [root@node2 ~]# docker images | grep nginx
nginx                                                             latest     d1a364dc548d   7 weeks ago     133MB
[root@node2 ~]#

创建pod【虚拟机】

  • 创建pod的方式有2种:
    • 1、命令行的方式
    • 2、使用yaml配置文件的方式【建议用这种】

方式1:命令行的方式【不建议】

默认创建

在这里插入图片描述

  • 命令:kubectl run pod名称【自定义】 --images=镜像名称
    如果不指定下载策略参数,那么默认使用的是Always,每次都需要下载新的镜像,如果node节点没有通外网的话,那么创建出来的镜像状态为:ImagePullBackOff【如下,我的就是没有外网的,创建出来就不是running,这种情况需要用下面指定参数下载】
  • 如:我使用nginx镜像创建一个名称是pod1的容器出来
    状态就是ImagePullBackOff
[root@master pod-1]# kubectl run pod1 --image=nginx
pod/pod1 created
[root@master pod-1]# 
[root@master pod-1]# kubectl get pods 
NAME   READY   STATUS             RESTARTS   AGE
pod1   0/1     ImagePullBackOff   0          7s
[root@master pod-1]# kubectl describe pod pod1 #这是日志查看报错信息
  • 综上,这种默认创建方式适合通外网的环境。

加imagePullPolicy参数创建

  • imagePullPolicy参数是一种镜像的下载策略,3种模式如下图【默认是第一种】
    一般都是建议加上这个参数选择本地创建的,因为默认是通过国外网站拉取的镜像,难免会很慢。
    在这里插入图片描述
    注:上图中,2和3的区别是,2如果本地没有的话,会自动从网站拉取,3如果本地没有,就直接失败了。

  • 如,我这使用第2种方式来创建pod,状态就会为Running了【当前虚机无外网的,使用的是本地的镜像】
    命令:kubectl run pod1 --image=nginx --image-pull-policy=IfNotPresent

[root@master ~]# docker images | grep nginx
#当前是master节点,这上面没有nginx镜像, 但是我node节点上有nginx镜像!!!!
[root@master ~]#
[root@master ~]# kubectl get pods
No resources found in pod-1 namespace.
[root@master ~]# kubectl run pod1 --image=nginx --image-pull-policy=IfNotPresent
pod/pod1 created
[root@master ~]# 
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          17s
[root@master ~]# 
[root@master ~]# ping -w 2 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 1999ms[root@master ~]# 

说明

  • 上面命令的方式创建,是可以加参数的
    如:我在创建的时候指定变量创建【各种变量和docker创建时候一致,就不在这多做说明】
[root@master ~]# kubectl run pod1 --image=nginx --image-pull-policy=IfNotPresent --env "aa=bb" --env "cc=dd" --labels="aa=bb,cc=dd"
pod/pod1 created
[root@master ~]# 
[root@master ~]# kubectl exec -it pod1 -- bash
root@pod1:/# echo $aa
bb
root@pod1:/# echo $bbroot@pod1:/# echo $cc
dd
root@pod1:/# 
root@pod1:/# exit
exit
[root@master ~]# 
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          43s
[root@master ~]# kubectl get pods --show-labels 
NAME   READY   STATUS    RESTARTS   AGE   LABELS
pod1   1/1     Running   0          55s   aa=bb,cc=dd
[root@master ~]# 
[root@master ~]# 

方式2:yaml文件的方式创建【建议】

这种方式还有一个最大的好处就是,可以用同一个配置文件创建多个pod【下面会说明的】

获取yaml文件

  • 语法:
kubectl run 自定义pod名称 --image=镜像名称 --image-pull-policy=下载策略 --dry-run=client/server -o yaml > 自定义名称.yaml#--image-pull-policy=有3种策略,加上面命令行中加参数创建# --dry-run=这是模拟运行的意思
#--dry-run=client:简洁输出【一般用这个比较多】
#--dry-run=server:详细输出,内容很多# -o yaml :以yaml文件的形式输出# > 自定义名称.yaml :如果不加这个,就直接打印到屏幕上
  • 如,我使用该方法创建一个名称为pod1的nginx镜像pod
    命令:kubectl run pod1 --image=nginx --image-pull-policy=IfNotPresent --dry-run=client -o yaml > pod1.yaml
    注:yaml文件默认存放在当前路径。 且执行该命令后是不会生成pod的。
[root@master ~]# kubectl delete pod pod1
pod "pod1" deleted
[root@master ~]# 
[root@master ~]# kubectl run pod1 --image=nginx --image-pull-policy=IfNotPresent --dry-run=client -o yaml > pod1.yaml
[root@master ~]# 
[root@master ~]# kubectl get pods
No resources found in pod-1 namespace.
[root@master ~]# 

获取的配置文件说明

  • 我通过上面方法获取到了pod1.yaml文件,文件内容如下
    【下面是最基础信息,没有进行任何修改】
[root@master ~]# vim pod1.yaml 
apiVersion: v1 
kind: Pod 
metadata: creationTimestamp: null labels: run: pod1 name: pod1 
spec:containers:- image: nginximagePullPolicy: IfNotPresentname: pod1resources: {}dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}
yaml文件格式说明
  • yaml文件里的格式,遵照的驼峰写法

    • 1.冒号前面
      第一个单词首字母为小写,后续每个单词首字母大写
    • 2.冒号右边:
      关键字,每个单词的首字母都要大写
  • yaml是有严格的文件缩进制度的,每一级用2个空格隔开,必须是2个空格,不能使用tab缩进,并且每一个参数的:后面有一个空格,这个空格不能省略,否则创建报错。

  • 如下图:

    • 一级是没有空格缩进的
    • 二级前面有2个空格
    • 三级前面有4个空格
      在这里插入图片描述
  • 主要是后面添加新参数的时候,添加的几级参数,前面的空格数量一定不能错!!!!【一二三级参数查看方式见下面】

一级参数获取
  • 如下图中的一级菜单,这只是一部分,并不是全部
    在这里插入图片描述

  • 查看全部一级菜单方法:
    命令:kubectl explain pods

[root@master ~]# kubectl explain pods
KIND:     Pod
VERSION:  v1DESCRIPTION:Pod is a collection of containers that can run on a host. This resource iscreated by clients and scheduled onto hosts.FIELDS:apiVersion   <string>APIVersion defines the versioned schema of this representation of anobject. Servers should convert recognized schemas to the latest internalvalue, and may reject unrecognized values. More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resourceskind <string>Kind is a string value representing the REST resource this objectrepresents. Servers may infer this from the endpoint the client submitsrequests to. Cannot be updated. In CamelCase. More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kindsmetadata     <Object>Standard object's metadata. More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadataspec <Object>Specification of the desired behavior of the pod. More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-statusstatus       <Object>Most recently observed status of the pod. This data may not be up to date.Populated by the system. Read-only. More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status[root@master ~]# 
二级菜单获取
  • 如下图中的二级菜单,这只是一部分,并不是全部
    注:二级菜单是一级的子菜单,所以要获取全部二级菜单的时候,是查询某一级菜单。
    在这里插入图片描述
  • 如:我获取上图中apiVersionmetadata的所有二级参数
    命令:kubectl explain pods.一级菜单名称
[root@master ~]# kubectl explain pods.metadata
KIND:     Pod
VERSION:  v1RESOURCE: metadata <Object>DESCRIPTION:Standard object's metadata. More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadataObjectMeta is metadata that all persisted resources must have, whichincludes all objects users must create.FIELDS:annotations  <map[string]string>Annotations is an unstructured key value map stored with a resource thatmay be set by external tools to store and retrieve arbitrary metadata. Theyare not queryable and should be preserved when modifying objects. Moreinfo: http://kubernetes.io/docs/user-guide/annotationsclusterName  <string>The name of the cluster which the object belongs to. This is used todistinguish resources with same name and namespace in different clusters.This field is not set anywhere right now and apiserver is going to ignoreit if set in create or update request.creationTimestamp    <string>CreationTimestamp is a timestamp representing the server time when thisobject was created. It is not guaranteed to be set in happens-before orderacross separate operations. Clients may not set this value. It isrepresented in RFC3339 form and is in UTC.Populated by the system. Read-only. Null for lists. More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadatadeletionGracePeriodSeconds   <integer>Number of seconds allowed for this object to gracefully terminate before itwill be removed from the system. Only set when deletionTimestamp is alsoset. May only be shortened. Read-only.deletionTimestamp    <string>DeletionTimestamp is RFC 3339 date and time at which this resource will bedeleted. This field is set by the server when a graceful deletion isrequested by the user, and is not directly settable by a client. Theresource is expected to be deleted (no longer visible from resource lists,and not reachable by name) after the time in this field, once thefinalizers list is empty. As long as the finalizers list contains items,deletion is blocked. Once the deletionTimestamp is set, this value may notbe unset or be set further into the future, although it may be shortened orthe resource may be deleted prior to this time. For example, a user mayrequest that a pod is deleted in 30 seconds. The Kubelet will react bysending a graceful termination signal to the containers in the pod. Afterthat 30 seconds, the Kubelet will send a hard termination signal (SIGKILL)to the container and after cleanup, remove the pod from the API. In thepresence of network partitions, this object may still exist after thistimestamp, until an administrator or automated process can determine theresource is fully terminated. If not set, graceful deletion of the objecthas not been requested.Populated by the system when a graceful deletion is requested. Read-only.More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadatafinalizers   <[]string>Must be empty before the object is deleted from the registry. Each entry isan identifier for the responsible component that will remove the entry fromthe list. If the deletionTimestamp of the object is non-nil, entries inthis list can only be removed. Finalizers may be processed and removed inany order. Order is NOT enforced because it introduces significant risk ofstuck finalizers. finalizers is a shared field, any actor with permissioncan reorder it. If the finalizer list is processed in order, then this canlead to a situation in which the component responsible for the firstfinalizer in the list is waiting for a signal (field value, externalsystem, or other) produced by a component responsible for a finalizer laterin the list, resulting in a deadlock. Without enforced ordering finalizersare free to order amongst themselves and are not vulnerable to orderingchanges in the list.generateName <string>GenerateName is an optional prefix, used by the server, to generate aunique name ONLY IF the Name field has not been provided. If this field isused, the name returned to the client will be different than the namepassed. This value will also be combined with a unique suffix. The providedvalue has the same validation rules as the Name field, and may be truncatedby the length of the suffix required to make the value unique on theserver.If this field is specified and the generated name exists, the server willNOT return a 409 - instead, it will either return 201 Created or 500 withReason ServerTimeout indicating a unique name could not be found in thetime allotted, and the client should retry (optionally after the timeindicated in the Retry-After header).Applied only if Name is not specified. More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotencygeneration   <integer>A sequence number representing a specific generation of the desired state.Populated by the system. Read-only.labels       <map[string]string>Map of string keys and values that can be used to organize and categorize(scope and select) objects. May match selectors of replication controllersand services. More info: http://kubernetes.io/docs/user-guide/labelsmanagedFields        <[]Object>ManagedFields maps workflow-id and version to the set of fields that aremanaged by that workflow. This is mostly for internal housekeeping, andusers typically shouldn't need to set or understand this field. A workflowcan be the user's name, a controller's name, or the name of a specificapply path like "ci-cd". The set of fields is always in the version thatthe workflow used when modifying the object.name <string>Name must be unique within a namespace. Is required when creatingresources, although some resources may allow a client to request thegeneration of an appropriate name automatically. Name is primarily intendedfor creation idempotence and configuration definition. Cannot be updated.More info: http://kubernetes.io/docs/user-guide/identifiers#namesnamespace    <string>Namespace defines the space within which each name must be unique. An emptynamespace is equivalent to the "default" namespace, but "default" is thecanonical representation. Not all objects are required to be scoped to anamespace - the value of this field for those objects will be empty.Must be a DNS_LABEL. Cannot be updated. More info:http://kubernetes.io/docs/user-guide/namespacesownerReferences      <[]Object>List of objects depended by this object. If ALL objects in the list havebeen deleted, this object will be garbage collected. If this object ismanaged by a controller, then an entry in this list will point to thiscontroller, with the controller field set to true. There cannot be morethan one managing controller.resourceVersion      <string>An opaque value that represents the internal version of this object thatcan be used by clients to determine when objects have changed. May be usedfor optimistic concurrency, change detection, and the watch operation on aresource or set of resources. Clients must treat these values as opaque andpassed unmodified back to the server. They may only be valid for aparticular resource or set of resources.Populated by the system. Read-only. Value must be treated as opaque byclients and . More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistencyselfLink     <string>SelfLink is a URL representing this object. Populated by the system.Read-only.DEPRECATED Kubernetes will stop propagating this field in 1.20 release andthe field is planned to be removed in 1.21 release.uid  <string>UID is the unique in time and space value for this object. It is typicallygenerated by the server on successful creation of a resource and is notallowed to change on PUT operations.Populated by the system. Read-only. More info:http://kubernetes.io/docs/user-guide/identifiers#uids[root@master ~]# 
三级菜单获取
  • 如下图中的三级菜单,这只是一部分,并不是全部
    注:三级菜单是二级的子菜单,所以要获取全部三级菜单的时候,是查询某二级菜单。
    在这里插入图片描述
  • 如:我查询上图中的creationTimestamp和labels菜单
    命令:kubectl explain pods.一级菜单名称.二级菜单名称
[root@master ~]# kubectl explain pods.metadata.creationTimestamp
KIND:     Pod
VERSION:  v1FIELD:    creationTimestamp <string>DESCRIPTION:CreationTimestamp is a timestamp representing the server time when thisobject was created. It is not guaranteed to be set in happens-before orderacross separate operations. Clients may not set this value. It isrepresented in RFC3339 form and is in UTC.Populated by the system. Read-only. Null for lists. More info:https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadataTime is a wrapper around time.Time which supports correct marshaling toYAML and JSON. Wrappers are provided for many of the factory methods thatthe time package offers.
[root@master ~]# 
[root@master ~]# 
[root@master ~]# 
[root@master ~]# kubectl explain pods.metadata.labels
KIND:     Pod
VERSION:  v1FIELD:    labels <map[string]string>DESCRIPTION:Map of string keys and values that can be used to organize and categorize(scope and select) objects. May match selectors of replication controllersand services. More info: http://kubernetes.io/docs/user-guide/labels
[root@master ~]# 

配置文件中“-”的作用以及啥时候需要加“-”

说明
  • 我们获取的yaml文件中,有一个 “-” 应该注意到了吧,如下图
    在这里插入图片描述
  • 这个-的意思我用下面方式展示吧,应该更容易理解一点

在这里插入图片描述
如果还不能理解,没关系,我下面用一个demo再说明

demo说明
  • 我上面说过,用字典表示没有-,用列表表示有-,所以下面配置文件中我标出来就是如下
spec: #字典containers:#字典- image: nginx #列表imagePullPolicy: IfNotPresent#列表内容name: pod1#列表内容resources: {}#列表内容dnsPolicy: ClusterFirst#字典
  • 又说过列表是可以重复的,那么我们新增几个列表就是
spec: #字典containers:#字典- image: nginx #列表imagePullPolicy: IfNotPresent#列表内容name: pod1#列表内容resources: {}#列表内容...#可以新增自定义列表内容的- image: nginx #列表imagePullPolicy: IfNotPresent#列表内容name: pod1#列表内容resources: {}#列表内容...#可以新增自定义列表内容的- image: nginx #列表imagePullPolicy: IfNotPresent#列表内容name: pod1#列表内容resources: {}#列表内容    ...#可以新增自定义列表内容的  dnsPolicy: ClusterFirst#字典

restartPolicy 参数说明

  • 默认参数为Always
  restartPolicy: Always
  • 我们可以查看菜单获取帮助的
[root@master ~]# kubectl explain pods.spec.restartPolicy
KIND:     Pod
VERSION:  v1FIELD:    restartPolicy <string>DESCRIPTION:Restart policy for all containers within the pod. One of Always, OnFailure,Never. Default to Always. More info:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
[root@master ~]# 
  • 一共有3个参数:
    • Always:总是是重启
    • OnFailure:非正常退出才重启【就是容器正常运行完成以后,就不会重启,比如定义个command为 sleep 100,那么100秒后容器就停了且不会重启】
    • Never:从不重启

编辑配置文件

  • 默认生成的文件呢,其实可以啥都不用修改,直接生成pod
    注:需要特意留意imagePullPolicy: IfNotPresent这个参数,没有的话务必要改成这个【前提是在node上准备好镜像】
  • 我下面添加了一个env变量参数 ,用来展示列表的使用。
    注:env变量如果是纯数字,必须要加"",否则创建会报错
[root@master ~]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod1name: pod1
spec:containers:- image: nginximagePullPolicy: IfNotPresentname: pod1resources: {}env:- name: aavalue: xxx- name: bbvalue: "888"dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}
[root@master ~]#

通过文件创建pod

  • 命令:kubectl apply -f yaml文件
  • 如,我生成上面修改完毕的pod文件
[root@master ~]# kubectl apply -f pod1.yaml
pod/pod1 created
[root@master ~]# 
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          32s
[root@master ~]# 

通过文件创建多个pod

  • 先丢一个配置文件在这吧
[root@master ~]# cat pod1.yaml 
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod1name: pod1
spec:containers:- image: nginximagePullPolicy: IfNotPresentname: pod1resources: {}env:- name: aavalue: xxx- name: bbvalue: "888"dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}
[root@master ~]# 
  • 常规通过配置文件创建多个呢,是直接cp上面的配置文件,但我这不这么做,使用一个配置文件创建多个pod,看下面。

  • 语法

sed 's/pod1/pod2/' pod1.yaml | kubectl apply -f -#pod1:是配置文件中的name
#pod2:是新名【自定义】 【如果要创建更多,仅修改这个值】
# pod1.yaml是配置文件名称
  • 如:我通过这个文件创建3个pod,分别为pod1,pod2,pod3
[root@master ~]# kubectl get pods
No resources found in pod-1 namespace.
[root@master ~]# 
[root@master ~]# kubectl apply -f pod1.yaml 
pod/pod1 created
[root@master ~]# sed 's/pod1/pod2/' pod1.yaml  | kubectl apply -f -
pod/pod2 created
[root@master ~]# 
[root@master ~]# sed 's/pod1/pod3/' pod1.yaml  | kubectl apply -f -
pod/pod3 created
[root@master ~]# 
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          35s
pod2   1/1     Running   0          15s
pod3   1/1     Running   0          5s
[root@master ~]# 

创建pod报错…expected "map"处理

  • 通过文件创建pod出错的话,一般都是因为你新增的参数格式不对
  • 报错内容
    比如下面2种报错,就是因为新增参数的格式错误
[root@master ~]# kubectl apply -f pod1.yaml
error: error validating "pod1.yaml": error validating data: [ValidationError(Pod.spec.containers[0].env[0]): invalid type for io.k8s.api.core.v1.EnvVar: got "string", expected "map", ValidationError(Pod.spec.containers[0].env[1]): invalid type for io.k8s.api.core.v1.EnvVar: got "string", expected "map"]; if you choose to ignore these errors, turn validation off with --validate=false[root@master ~]# kubectl apply -f pod1.yaml
error: error parsing pod1.yaml: error converting YAML to JSON: yaml: line 17: could not find expected ':'
  • 处理方法就是在参数:后面新增空格即可。
    在这里插入图片描述

删除pod

pod名称方式删除【建议】

  • 命令:kubectl delete pod pod名称 --force【–force是不等待强制删除,平常删除可不加】
    如:我删除上面创建的pod1
[root@master pod-1]# kubectl delete pod pod1
pod "pod1" deleted
[root@master pod-1]# 
[root@master pod-1]# kubectl get pods
No resources found in pod-1 namespace.
[root@master pod-1]# 

配置文件方式删除

  • 这种方式主要适用于通过yaml文件的方式创建的pod
    命令:kubectl delete -f yaml文件
  • 如,我删除上面通过文件的方式创建的pod
[root@master ~]# 
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          10m
[root@master ~]# 
[root@master ~]# kubectl delete -f pod1.yaml 
pod "pod1" deleted
[root@master ~]# 
[root@master ~]# kubectl get pods
No resources found in pod-1 namespace.
[root@master ~]# 

pod的几种状态说明

  • 执行命令:kubectl get pods的时候有一栏是STATUS,这就是pod的状态
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          3d6h
pod2   2/2     Running   27         3d5h
[root@master ~]#
  • 下面我说一下几种状态的原因
    • Running:已经被调度到节点上,且容器工作正常
    • Pending :pod因为其他的原因导致pod准备开始创建,但还没有创建【卡主了】
    • Completed :pod里所有容器正常退出【比如restartPolicy模式为OnFailure且定义了sleep 100,100秒以后状态就成这个了】
    • Terminating:pod正在删除中【就是优雅的关闭,默认30秒才删除】
    • CrashLoopBackOff:创建的时候就出错,属于内部原因【比如定义变量错误了,或者无法访问存储了等等】
    • imagePullBackoff:创建pod的时候,镜像下载失败【这种一般就需要定义imagePullPolicy参数修改镜像获取模式了】

一个pod运行多个容器

  • 上面我们详细说明了pod的创建和删除,但这种仅仅是常规创建,也就是一个pod一个容器,pod和容器对应关系如下图
    在这里插入图片描述

  • cp一份pod1的配置文件为pod2,下面我们用pod2来做说明

[root@master ~]# cp pod1.yaml pod2.yaml

并在里面执行一下全局替换,将pod1替换为pod2
在这里插入图片描述

  • 最候将env变量删了,得到一个初始版的容器文件
[root@master ~]# cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod2name: pod2
spec:containers:- image: nginximagePullPolicy: IfNotPresentname: pod2resources: {}dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}
[root@master ~]#

说明

  • 何为一个pod运行多个容器呢,简单来说就是给一个pod定义多个 镜像,结合上图看,应该能明白我的意思吧。

  • 用豆荚表示呢,就是外壳是pod,壳子里面的豆呢,就是容器,一个pod可以有很多容器,外壳【pod】和里面的豆子【容器】名称是可以自定义的,如下图
    在这里插入图片描述

  • 注意,一个pod里面是不能运行2中容器的,比如同一个pod,不不能运行nginx和mysql这2种容器的,他们是不同的容器,还是需要运行在不同的pod上

  • 使用场景:一般使用在一个pod中同一个镜像的不同cmd而已
    比如:一个pod的nginx镜像中,我们挂载了一个外挂硬盘,这时候使用多个CMD,来做日志分析这样子。

  • 所以呢,下面的测试中,更多是明白这种用法或这种东西的存在即可,一般情况下不要在一个pod下创建多个容器,容易出错。

容器的CMD说明

  • 我们先创建2个容器的pod吧,将配置文件中的image内容全部复制,将name修改为c1和c2
[root@master ~]# cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod2name: pod2
spec:containers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}- image: nginximagePullPolicy: IfNotPresentname: c2resources: {}dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}
[root@master ~]# 
[root@master ~]# kubectl apply -f pod2.yaml
pod/pod2 created
[root@master ~]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          31m
pod2   1/2     Error     1          11s
[root@master ~]# 
  • 可以看到上面创建出来的pod2呢,状态为Error,这是因为:
    容器默认使用的是 镜像中的 CMD
    但镜像中的cmd只有一个,如果有多个容器使用镜像中的这个CMD,肯定是不得行的,所以如果一个pod中创建多个容器,从第二容器开始,就需要指定cmd了,至于cmd内容是啥,你可以自定义,也可以使用和镜像中的一样。

指定容器CMD并创建

  • 我给第二个cmd指定为:sleep 10
    文件整体内容就直接看文件内容吧,应该能看懂的,操作步骤也看下面代码内容
[root@master ~]# vim pod2.yaml 
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod2name: pod2
spec:containers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}- image: nginximagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 10"]name: c2resources: {}dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}
~
~
~
~
~
"pod2.yaml" 21L, 379C written                                    
[root@master ~]# 
[root@master ~]# kubectl delete pod pod2 --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "pod2" force deleted
[root@master ~]# 
[root@master ~]# kubectl apply -f pod2.yaml 
pod/pod2 created
[root@master ~]# 
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          35m
pod2   2/2     Running   0          7s
[root@master ~]# 

可以看到增加cmd内容以后,创建的pod 状态就为Running了

  • 我们再次查看pod的时候,可以看到 RESTART数量在增加
    是因为配置文件中c2的cmd的sleep 10,又定义了Always,会一直重启的,所以每隔10秒钟会重启一次该容器
[root@master ~]# kubectl get pods
NAME   READY   STATUS             RESTARTS   AGE
pod1   1/1     Running            0          37m
pod2   1/2     CrashLoopBackOff   3          104s
[root@master ~]# kubectl get pods
NAME   READY   STATUS             RESTARTS   AGE
pod1   1/1     Running            0          37m
pod2   1/2     CrashLoopBackOff   3          107s
[root@master ~]# kubectl get pods
NAME   READY   STATUS     RESTARTS   AGE
pod1   1/1     Running    0          37m
pod2   1/2     NotReady   4          2m26s
[root@master ~]# 
[root@master ~]# kubectl get pods
NAME   READY   STATUS     RESTARTS   AGE
pod1   1/1     Running    0          37m
pod2   1/2     NotReady   4          2m31s

在pod里执行一些命令

查看pod详细信息

  • 命令:kubectl describe pod pod名称
  • 如:我查看pod2,里面会有容器c1和c2的详细信息
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          77m
pod2   2/2     Running   0          5s
[root@master ~]# kubectl describe pod pod2
Name:         pod2
Namespace:    pod-1
Priority:     0
Node:         node1/192.168.59.143
Start Time:   Fri, 23 Jul 2021 12:17:01 +0800
Labels:       run=pod2
Annotations:  cni.projectcalico.org/podIP: 10.244.166.135/32cni.projectcalico.org/podIPs: 10.244.166.135/32
Status:       Running
IP:           10.244.166.135
IPs:IP:  10.244.166.135
Containers:c1:Container ID:   docker://32da51b11a075f077c392a8bab1a0aaa34423de21ee6a357d5ea15dadc8fee35Image:          nginxImage ID:       docker://sha256:d1a364dc548d5357f0da3268c888e1971bbdb957ee3f028fe7194f1d61c6fdeePort:           <none>Host Port:      <none>State:          RunningStarted:      Fri, 23 Jul 2021 12:17:03 +0800Ready:          TrueRestart Count:  0Environment:    <none>Mounts:/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-x8cql (ro)c2:Container ID:  docker://fe480106b8205a38e22997f2611382e964f6ab9161cb23df2046ffc5d61cf216Image:         nginxImage ID:      docker://sha256:d1a364dc548d5357f0da3268c888e1971bbdb957ee3f028fe7194f1d61c6fdeePort:          <none>Host Port:     <none>Command:sh-csleep 10000State:          RunningStarted:      Fri, 23 Jul 2021 12:17:03 +0800Ready:          TrueRestart Count:  0Environment:    <none>Mounts:/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-x8cql (ro)
Conditions:Type              StatusInitialized       True Ready             True ContainersReady   True PodScheduled      True 
Volumes:kube-api-access-x8cql:Type:                    Projected (a volume that contains injected data from multiple sources)TokenExpirationSeconds:  3607ConfigMapName:           kube-root-ca.crtConfigMapOptional:       <nil>DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:Type    Reason     Age   From               Message----    ------     ----  ----               -------Normal  Scheduled  12s   default-scheduler  Successfully assigned pod-1/pod2 to node1Normal  Pulled     11s   kubelet            Container image "nginx" already present on machineNormal  Created    10s   kubelet            Created container c1Normal  Started    10s   kubelet            Started container c1Normal  Pulled     10s   kubelet            Container image "nginx" already present on machineNormal  Created    10s   kubelet            Created container c2Normal  Started    10s   kubelet            Started container c2
[root@master ~]# 

不进入bash直接执行pod容器命令

只有一个容器的情况下

  • 语法:kubectl exec pod名 -- 命令
  • 如:我执行pod1的一些命令
[root@master ~]# kubectl exec pod1 -- ls /tmp
[root@master ~]# 
[root@master ~]# kubectl exec pod1 -- ls /root
[root@master ~]# kubectl exec pod1 -- ls /var/log
apt
btmp
dpkg.log
faillog
lastlog
nginx
wtmp#比如容器中命令不存在,那么就会报如下错误[root@master ~]# kubectl exec pod1 -- ifconfig
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ifconfig": executable file not found in $PATH: unknown
command terminated with exit code 126
[root@master ~]# 

指定pod容器查看

  • 命令:kubectl exec pod名称 -c 容器名称 -- 命令
    如果pod中有多个容器,不指定的话,会提示让你选择的
  • 如,我查看pod2中c1和c2的容器
[root@master ~]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          79m
pod2   2/2     Running   0          2m
[root@master ~]# 
[root@master ~]# kubectl exec pod2 -- ls /tmp
Defaulted container "c1" out of: c1, c2
[root@master ~]# 
[root@master ~]# kubectl exec pod2 -c c1 -- ls /tmp
[root@master ~]# 
[root@master ~]# kubectl exec pod2 -c c2 -- ls /tmp
[root@master ~]# 

创建bash并进入pod容器

只有一个容器的情况下

  • 命令:kubectl exec -it pod名 -- bash
  • 如:我进入pod1的bash
[root@master ~]# kubectl exec -it pod1 -- bash
root@pod1:/# 
root@pod1:/# ls
bin   docker-entrypoint.d   home   media  proc  sbin  tmp
boot  docker-entrypoint.sh  lib    mnt    root  srv   usr
dev   etc                   lib64  opt    run   sys   var
root@pod1:/# pwd
/
root@pod1:/# # 这种比较直观,命令不存在的话正常提示,而不是报错
root@pod1:/# ifconfig
bash: ifconfig: command not found
root@pod1:/# 
root@pod1:/# exit
exit
command terminated with exit code 127
[root@master ~]# 

指定pod容器查看

    • 命令:kubectl exec -it pod名称 -c 容器名称 -- bash
      如果pod中有多个容器,不指定的话,会提示让你选择的的同时,默认进入第一个容器了
  • 如,我进入pod2中c1和c2的容器
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          81m
pod2   2/2     Running   0          4m34s
[root@master ~]# 
[root@master ~]# kubectl exec -it pod2 -- bash
Defaulted container "c1" out of: c1, c2
root@pod2:/# 
root@pod2:/# exit
exit
[root@master ~]#
[root@master ~]# kubectl exec -it pod2 -c c1 -- bash
root@pod2:/# ls
bin   docker-entrypoint.d   home   media  proc  sbin  tmp
boot  docker-entrypoint.sh  lib    mnt    root  srv   usr
dev   etc                   lib64  opt    run   sys   var
root@pod2:/# exit
exit
[root@master ~]# 
[root@master ~]# kubectl exec -it pod2 -c c2 -- bash
root@pod2:/# ls
bin   docker-entrypoint.d   home   media  proc  sbin  tmp
boot  docker-entrypoint.sh  lib    mnt    root  srv   usr
dev   etc                   lib64  opt    run   sys   var
root@pod2:/# exit
exit
[root@master ~]#

拷贝本地文件到pod容器内【含反过来拷贝】

  • 命令:kubectl exec 主机文件 容器名:拷贝路径
  • 如:我拷贝主机的 /etc/hosts到容器的/tmp路径
[root@master ~]# kubectl cp /etc/hosts pod1:/tmp
[root@master ~]# 
[root@master ~]# kubectl exec -it pod1 -- bash
root@pod1:/# ls /tmp/
hosts
root@pod1:/# cat hosts
cat: hosts: No such file or directory
root@pod1:/# cat /tmp/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6192.168.59.142 master
192.168.59.143 node1
192.168.59.144 node2root@pod1:/# 
  • 容器内容拷贝到主机的话,语法和上面一样的
    命令:kubectl cp 容器名:路径 主机路径和文件文件名【不加路径默认当前路径,文件名必须存在】
[root@master ~]# kubectl cp  pod1:/etc/hosts hosts
tar: Removing leading `/' from member names
[root@master ~]#
[root@master ~]# cat hosts 
# Kubernetes-managed hosts file.
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.244.104.5    pod1
[root@master ~]# 
[root@master ~]# rm -rf hosts 
[root@master ~]# 

指定pod容器

方法见上面bash的用法吧,方法都一样,就加个参数-c 容器名 罢了

查看pod容器日志输出【用于排错】

  • 命令:kubectl logs pod名称
  • 如,我查看pod1的日志输出
[root@master ~]# kubectl logs pod1
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/07/23 02:59:49 [notice] 1#1: using the "epoll" event method
2021/07/23 02:59:49 [notice] 1#1: nginx/1.21.0
2021/07/23 02:59:49 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6) 
2021/07/23 02:59:49 [notice] 1#1: OS: Linux 3.10.0-957.el7.x86_64
2021/07/23 02:59:49 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/07/23 02:59:49 [notice] 1#1: start worker processes
2021/07/23 02:59:49 [notice] 1#1: start worker process 31
2021/07/23 02:59:49 [notice] 1#1: start worker process 32
2021/07/23 02:59:49 [notice] 1#1: start worker process 33
2021/07/23 02:59:49 [notice] 1#1: start worker process 34
[root@master ~]#

指定pod容器

方法见上面bash的用法吧,方法都一样,就加个参数-c 容器名 罢了

pod的生命周期【优雅的关闭】

  • 默认情况下,我们使用命令删除一个pod的时候,会发现删除的时候会等待一段时间,这个一般是等待30秒,叫做宽限期,如下图。
    在这里插入图片描述
  • 其实这种有2种方法可以直接删除pod不用等待30秒
    • 方式1: 在删除后面 加上参数:--force
    • 方式2:使用文件创建的时候,指定参数,将默认的30秒改为0
  • 这个参数是terminationGracePeriodSeconds,也叫做优雅的关闭pod,详细信息如下
[root@master ~]# kubectl explain pods.spec | egrep -A 9 terminationGracePeriodSecondsterminationGracePeriodSeconds        <integer>Optional duration in seconds the pod needs to terminate gracefully. May bedecreased in delete request. Value must be non-negative integer. The valuezero indicates stop immediately via the kill signal (no opportunity to shutdown). If this value is nil, the default grace period will be used instead.The grace period is the duration in seconds after the processes running inthe pod are sent a termination signal and the time when the processes areforcibly halted with a kill signal. Set this value longer than the expectedcleanup time for your process. Defaults to 30 seconds.[root@master ~]#
  • 我下面就说方式2吧,通过文件创建pod的时候,就加一个参数,将30秒改为0【默认30秒】
    这样创建出来的pod,即使不加force参数删除也是秒删了。
[root@master ~]# cp pod2.yaml  pod3.yaml
[root@master ~]# vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod3name: pod3
spec:terminationGracePeriodSeconds: 0containers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}- image: nginximagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 10000"]name: c2resources: {}dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}
~
~
~
~
"pod3.yaml" 22L, 417C written                                    
[root@master ~]# kubectl apply -f pod3.yaml 
pod/pod3 created
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          102m
pod2   2/2     Running   0          25m
pod3   2/2     Running   0          5s
[root@master ~]# 
[root@master ~]# kubectl delete pod pod3
pod "pod3" deleted
[root@master ~]# 

pod钩子【pod hook】

说明

  • 我们知道,创建容器的时候,默认使用的是镜像的CMD进程,如果定义了command,那也是修改了镜像的默认进程罢了
  • 但如果我们需要新增一个command进程,而不是替换默认的command进程,这时候就需要使用到pod hook 【pod钩子】了。
  • pod hook有两种模式
    • postStart
      容器启动之后执行xxxx
      注:是和主进程是同时运行起来的,并没有先后顺序
    • preStop
      在容器关闭之前执行xxxx
  • 详细语法
spec:- image:**...#下面的为钩子的全部语法了lifecycle:postStart:exec:command: ["/bin/sh","-c","执行命令"]preStop:exec:command: ["/bin/sh","-c","执行命令"]

demo

  • 先编辑如下内容
[root@master ~]# cat pod4.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod4name: pod4
spec:terminationGracePeriodSeconds: 600containers:- image: nginxcommand: ["sh","-c","data > /tmp/aa.txt ; sleep 10000"]imagePullPolicy: IfNotPresentname: c1resources: {}lifecycle:postStart:exec:command: ["/bin/sh","-c","data > /tmp/bb.txt"]preStop:exec:command: ["/bin/sh","-c","data >> /tmp/bb.txt ; sleep 100"]dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}
[root@master ~]# #  terminationGracePeriodSeconds: 600 ——宽恕期设置为600
#  command: ["sh","-c","date > /tmp/aa.txt ; sleep 10000"] —— 主进程改为这个。
#  command: ["/bin/sh","-c","date > /tmp/bb.txt"]——容器创建时执行这个【和上面主进程同时运行】
#  command: ["/bin/sh","-c","date >> /tmp/bb.txt ; sleep 100"]——容器关闭【删除】时执行这个
  • 上面注意看上面的代码介绍,下面我们创建这个容器并进入容器验证一下主进程和容器运行时的进程,上面说了这2进程是同时运行的,所以我们可以创建好容器以后,进入容器查看这2个容器的时候是不是一致即可,如果是一致的,那么证明逻辑没问题。
[root@master ~]# kubectl apply -f pod4.yaml 
pod/pod4 created
[root@master ~]# 
[root@master ~]# kubectl exec -it pod4 -- bash
root@pod4:/# 
root@pod4:/# cat /tmp/aa.txt 
Mon Jul 26 09:10:48 UTC 2021
root@pod4:/# 
root@pod4:/# cat /tmp/bb.txt 
Mon Jul 26 09:10:48 UTC 2021
root@pod4:/# 
root@pod4:/# 
root@pod4:/# exit
exit
[root@master ~]#
  • 最后我们写了容器删除时候执行的这个代码,写入一个时间并睡眠100秒,这个时候的逻辑是这样子的
    当我们删除容器以后,会立刻追加时间到bb.txt中,然后开始sleep 100,这个执行完毕以后开始执行住进程的sleep 10000,所以即使上面的sleep 100结束了,该容器也不会被删除,需要等待主进程的10000执行完毕才会被删除;
    但是我们又定义了宽恕时间是 600,所以到600以后,该容器会被强制删除了。
    现在开始测试这个
[root@master ~]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          3d6h
pod2   2/2     Running   27         3d4h
pod4   1/1     Running   0          3m52s
[root@master ~]# kubectl delete pod pod4
pod "pod4" deleted
#卡在这里的,这时候我们重新打开一个终端,并进入这个bash里面[root@master ~]# kubectl exec -it pod4 -- bash
root@pod4:/# cat /tmp/bb.txt 
Mon Jul 26 09:10:48 UTC 2021
Mon Jul 26 09:14:45 UTC 2021
root@pod4:/# 
root@pod4:/# exit
exit
[root@master ~]# 
[root@master ~]# kubectl get pod
NAME   READY   STATUS        RESTARTS   AGE
pod1   1/1     Running       0          3d6h
pod2   2/2     Running       27         3d4h
pod4   1/1     Terminating   0          5m43s
[root@master ~]# # 许久之后
[root@master ~]# kubectl get pod | tail -n 1
pod4   1/1     Terminating   0          8m52s
[root@master ~]# #我们上面是3分钟开始删除的,现在8分了,过去了5分钟,600秒马上到了,这个容器也该被删除了,再等一分钟
# 回到刚删除的界面,可以看到删除结束了,同时pod4也没了[root@master ~]# kubectl delete pod pod4
pod "pod4" deleted
[root@master ~]# 
[root@master ~]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          3d6h
pod2   2/2     Running   27         3d5h
[root@master ~]# 
  • 注:以我们上面的nginx为例,如果没有修改bash进程,默认使用nginx的话,删除不需要等待30秒就结束了,可能十四五秒就结束了,如果想要默认nginx也优雅关闭【默认30秒,或定义多少为多少】,需要定义结束时的 command并加上-s quit参数,如下:
    加了这个参数以后,容器就不会提前被删除了,需要等宽恕时间完毕以后才关闭呢。
...preStop:exec:command: ["/bin/sh","-c","/usr/sbin/nginx -s quit"]
...

初始化pod

说明

  • 初始化容器的概念

    • 比如一个容器A依赖其他容器,可以为A设置多个 依赖容易A1,A2,A3 A1,A2,A3要按照顺序启动,A1没有启动启动起来的 话,A2,A3是不会启动的,直到所有的静态容器全 部启动完毕,主容器A才会启动。
    • 一般用于A容器运行之前,先做一些准备工作。
    • 注:如果初始化容器失败,则会一直重启,pod不会创建
  • 我们上面说到了pod钩子,pod钩子呢是和容器同时运行或在容器被删除时运行,而这个初始化呢,和pod钩子 类似,只是这个是在容器运行执行执行某些功能罢了,流程如下图:
    在这里插入图片描述

  • 完整语法是:

spec:
...initContainers:- name: initc1 #自定义名称image: nginx #镜像名称imagePullPolicy: IfNotPresent #镜像策略command: ["sh","-c","sleep 20"] #command
...
  • 注:每一个pod,即使不定义初始化内容,也会有一个隐藏的初始化容器,叫做pause容器,这个的存在是为了能让该pod容器能正常运行,比如调度网络这些。
    如下,我随便创建一个pod,查看其运行的node节点,然后去这个node节点上查看运行的docker容器,肯定有个相应的pause容器生成
[root@master ~]# kubectl apply -f pod5.yaml 
pod/pod5 created
[root@master ~]# 
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS     RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
pod5   0/1     Init:0/1   0          8s    10.244.166.138   node1   <none>           <none>
[root@master ~]# 
[root@master ~]# ssh node1
root@node1's password: 
Last login: Tue Jul 27 10:43:30 2021 from master
[root@node1 ~]# 
[root@node1 ~]# docker ps | grep pause
f172aa85d2f1   registry.aliyuncs.com/google_containers/pause:3.4.1   "/pause"                 2 minutes ago        Up 2 minutes                  k8s_POD_pod5_pod-1_5d3283f7-0fb2-41d2-9a3f-d586ad92ddb7_0
9eb01589f988   registry.aliyuncs.com/google_containers/pause:3.4.1   "/pause"                 8 days ago           Up 8 days                     k8s_POD_calico-node-zl42z_kube-system_7d504cb1-790f-407f-b5f7-f292cef949a5_1
be2b39468acd   registry.aliyuncs.com/google_containers/pause:3.4.1   "/pause"                 8 days ago           Up 8 days                     k8s_POD_kube-proxy-7nqfv_kube-system_cb31c4f7-7dcc-4632-b281-907cef422133_1
[root@node1 ~]# #一个pod对应一个pause容器
# 也就是说,运行的容器出了pod本身,还会有一个pause存在
[root@node1 ~]# docker ps | grep pod5
69e1009f9b59   d1a364dc548d                                          "/docker-entrypoint.…"   3 minutes ago   Up 3 minutes             k8s_c1_pod5_pod-1_5d3283f7-0fb2-41d2-9a3f-d586ad92ddb7_0
f172aa85d2f1   registry.aliyuncs.com/google_containers/pause:3.4.1   "/pause"                 3 minutes ago   Up 3 minutes             k8s_POD_pod5_pod-1_5d3283f7-0fb2-41d2-9a3f-d586ad92ddb7_0
[root@node1 ~]#

规则

  • 1、它们总是运行到完成。
  • 2、每个都必须在下一个启动之前成功完成。
  • 3、如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy 为 Never,它不会重新启动。
  • 4、Init 容器支持应用容器的全部字段和特性,但不支持 Readiness Probe,因为它们必须在 Pod 就绪之前运行完 成。
  • 5、如果为一个 Pod 指定了多个 Init 容器,那些容器会按顺序一次运行一个。 每个 Init 容器必须运行成功,下一个 才能够运行。
  • 6、因为 Init 容器可能会被重启、重试或者重新执行,所以 Init 容器的代码应该是幂等的。 特别地,被写到 EmptyDirs 中文件的代码,应该对输出文件可能已经存在做好准备。
  • 7、在 Pod 上使用 activeDeadlineSeconds,在容器上使用 livenessProbe,这样能够避免 Init 容器一直失败。 这就 为 Init 容器活跃设置了一个期限。
  • 8、在 Pod 中的每个 app 和 Init 容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误。
  • 9、对 Init 容器 spec 的修改,被限制在容器 image 字段中。 更改 Init 容器的 image 字段,等价于重启该 Pod。

demo

  • 我这呢,就添加一个初始化容器为例
    完整代码如下,可以直接拷贝:
[root@master ~]# cat pod5.yaml 
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod5name: pod5
spec:terminationGracePeriodSeconds: 0containers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}initContainers:- name: initc1image: nginximagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 20"]dnsPolicy: ClusterFirstrestartPolicy: Never
status: {}
[root@master ~]# 
  • 我们生成这个容器,并观察状态
    因为我们定义了一个初始化内容的command为sleep 20,所以可以发现,20秒前都是在初始化,20秒以后容器才会变成Running
[root@master ~]# kubectl apply -f pod5.yaml 
pod/pod5 created
[root@master ~]# kubectl get pods
NAME   READY   STATUS     RESTARTS   AGE
pod1   1/1     Running    0          3d7h
pod2   2/2     Running    28         3d6h
pod5   0/1     Init:0/1   0          3s
[root@master ~]# 
[root@master ~]# kubectl get pods | tail -n 1 
pod5   0/1     Init:0/1   0          15s
[root@master ~]# 
[root@master ~]# kubectl get pods | tail -n 1 
pod5   0/1     Init:0/1   0          17s
[root@master ~]# kubectl get pods | tail -n 1 
pod5   0/1     Init:0/1   0          20s
[root@master ~]# kubectl get pods | tail -n 1 
pod5   0/1     Init:0/1   0          22s
[root@master ~]# kubectl get pods | tail -n 1 
pod5   1/1     Running   0          24s
[root@master ~]# 
  • 如果我们需要定义多个初始化内容,那么就多增几个 initContainers即可,如:
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod5name: pod5
spec:terminationGracePeriodSeconds: 0containers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}initContainers:- name: initc1image: nginximagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 20"]initContainers:- name: initc1image: nginximagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 20"]initContainers:- name: initc1image: nginximagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 20"]dnsPolicy: ClusterFirstrestartPolicy: Never
status: {}

扩展demo【修改内核参数】

  • 我们创建一个pod,若要这个pod正常运行,那么pod所属的主机/proc/sys/vm/swappiness值需必须要为0才行。
  • 正常情况我们可以去这个pod上修改这个值为0 ,但如果节点很多,这么修改就不现实了,所以,我们可以利用初始化的方式,在pod运行前修改这个值为0
  • 需要知道一个事,我们在容器内修改参数的时候,其实修改的是主机的内核参数,因为这个操作是修改内核参数,pod因为安全性,不允许容器里修改内核参数,但aseccom控制了容器能做哪些操作
  • 镜像准备,下载alpine镜像【所有node上节点下载】
    必须所有node节点都下载这个镜像,否则,在master上创建这个pod,如果在node2节点运行,但node2节点没这个镜像,就会报错。
[root@node1 ~]# docker pull alpine# 下载完以后有如下镜像
[root@node1 ~]# docker images | grep alpine
alpine                                                            latest     d4ff818577bc   5 weeks ago     5.6MB
[root@node1 ~]#
  • 配置文件内容如下
[root@master ~]# cat pod6.yaml 
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod6name: pod6
spec:terminationGracePeriodSeconds: 0containers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}initContainers:- name: initc1image: alpineimagePullPolicy: IfNotPresentcommand: ["sh","-c","/sbin/sysctl -w vm.swappiness=0"]securityContext:privileged: truednsPolicy: ClusterFirstrestartPolicy: Never
status: {}
[root@master ~]# #下面为解释哈initContainers: #定义初始化内容- name: initc1 #自定义名称image: alpine #镜像imagePullPolicy: IfNotPresent #容器模式command: ["sh","-c","/sbin/sysctl -w vm.swappiness=0"]securityContext: #这个就是允许容器修改主机内核参数的选项privileged: true #true为允许修改
  • 创建pod
[root@master ~]# kubectl apply -f pod6.yaml 
pod/pod6 created
# 下面这个命令是查看这个pod运行在哪个节点上的
[root@master ~]# kubectl get pods -o wide | grep pod6
pod6   1/1     Running   0          80s     10.244.166.137   node1   <none>           <none>
[root@master ~]#
  • 验证
    我们说了,现在允许pod修改主机的这个值,所以我们通过上面看到的pod运行在node1上,那么我们就去node1查看值是否被修改了
    结果为0是正常的!
[root@master ~]# ssh node1
root@node1's password: 
Last login: Tue Jul 27 10:13:10 2021 from master
[root@node1 ~]# 
[root@node1 ~]# cat /proc/sys/vm/swappiness 
0
[root@node1 ~]#
  • 顺便补充一下,为什么你去查看其它pod运行的主机上这个值依然为30,是因为默认不允许pod修改这个值,所以这个值查看是没有变化的,这变0了是因为我们定义了参数允许pod修改值
    如下:pod5是运行在node2上的,但我们pod5中没有配置允许容器修改内核参数,所以去node2上看这个值,为默认值30才对
[root@master ~]# kubectl get pod -o wide | grep pod5
pod5   1/1     Running   0          16h     10.244.104.14    node2   <none>           <none>
[root@master ~]# 
[root@master ~]# ssh node2
root@node2's password: 
Last login: Tue Jul 27 10:15:23 2021 from master
[root@node2 ~]# cat /proc/sys/vm/swappiness
30
[root@node2 ~]# 

扩展demo【容器数据同步到本地,在获取本地数据】

  • 注意:下面的仅仅是展示一种方法,一种思路,不要考虑持久化的问题,下面容器创建的方式,当容器被删除后数据也会跟着被删除,关于持久化,后面有单独做 卷 笔记的,想了解的可以去我博客k8s分栏找找。
  • 镜像准备,下载alpine镜像【所有node上节点下载】
    必须所有node节点都下载这个镜像,否则,在master上创建这个pod,如果在node2节点运行,但node2节点没这个镜像,就会报错。
[root@node2 ~]# docker pull busybox
[root@node2 ~]# docker images | grep bus
busybox                                                           latest     69593048aa3a   7 weeks ago     1.24MB
[root@node2 ~]# 
  • 配置文件如下
[root@node2 ~]# exit
logout
Connection to node2 closed.
[root@master ~]# cat pod7.yaml 
apiVersion: v1
kind: Pod
metadata:name: myapp-podlabels:app: myapp
spec:terminationGracePeriodSeconds: 0volumes:- name: nodediremptyDir: {}containers:- name: myapp-containerimage: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: nodedirmountPath: "/xx"initContainers:- name: initc1image: busyboximagePullPolicy: IfNotPresentcommand: ["sh","-c","touch /node-dir/aa.txt"]volumeMounts:- name: nodedirmountPath: "/node-dir"
[root@master ~]# 
  • 流程说明:下图中顺序,红色为1,黄色为2【截图软件突然卡死了,我拍的照,不想弄第二次了,怕过程太长这截图软件又卡死,将就看一下吧】
    我在简单叙述一下:
    1、先定义一个主机的数据存储路径
    2、初始化时创建一个随机路径,并创建一个任意文件,最后将随机路径挂载到主机定义的路径上【这时候主机路径就会有初始化时创建的文件了】【注:这个镜像和要创建容器的镜像不是同一个,因为这是初始化的镜像,touch创建完成任务后该进程就会被删了(因为初始化完成以后才会进行创建容器),所以我们进不去这个镜像内部】【我们用busybox镜像是因为这个镜像占用空间小,且集成了linux常用命令,比较方便,如果用一些其他镜像,没有touch命令,这个容器创建就会报错】
    3、最后将有数据的主机存储路径,挂载到镜像的任意路径,创建容器以后,我们进入到该路径,是可以看到初始化时候创建的文件才对的
    在这里插入图片描述
  • 创建容器并测试
[root@master ~]# kubectl apply -f pod7.yaml
pod/myapp-pod created
[root@master ~]# kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
myapp-pod   1/1     Running   0          64s
[root@master ~]# kubectl exec -it myapp-pod -- bash
Defaulted container "myapp-container" out of: myapp-container, initc1 (init)
root@myapp-pod:/# 
root@myapp-pod:/# ls /xx
aa.txt
root@myapp-pod:/# 
root@myapp-pod:/# exit
exit
command terminated with exit code 1
[root@master ~]#

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-35151.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

品牌应该如何把握抖音电商的红利:深度拆解花西子如何通过抖音电商一年销售1亿+

最近抖音电商正在逐渐起势&#xff0c;前一阵子老赵去参加了抖音的电商大会和千川大会&#xff0c;从这两个会的火爆程度我们就可以看出&#xff0c;越来越多的品牌正在涌向抖音电商平台&#xff0c;并且越来越重视这个平台。抖音电商将是品牌们的新战场&#xff0c;这个平台让…...

你不知道的JS思考题

思考题 1、对比空值和对象的类型 思路&#xff1a; typeof null "object" typeof {} "object"答案 var a null ; (!a && tpeof a object); 补充&#xff1a; 内置类型typeof null "object" 祖传bug undefined "undefined&…...

Layui快速入门(2021.06.15)

第一步&#xff1a;下载layui文件 第二步&#xff1a;新建项目&#xff0c;导入下载的文件夹 第三步&#xff1a;参考文档开发 1.layui入门html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>la…...

Mysql异常之Communications link failure

前天线上出现数据数据抖动&#xff0c;收到大量异常告警&#xff0c;都要疯了&#xff0c;数据库出现大量异常&#xff0c;肯定第一件事就是看下数据库监控数据&#xff0c;发现有一个从分片执行时间有一个50多秒的操作&#xff0c;这里肯定有问题了&#xff0c;第一时间找了db…...

储备未完待续

储备 如何精准熬一人份的粥 如何快速晾凉一碗粥 3M手套和钢铁侠 洗手盆三件套 三种门锁、两个门锁 制作书签的一种方法 摩托车和汽车的排气筒 变形金刚和巴巴爸爸 横向冲击和纵向冲击 我和图书馆 影响我的三本书 曲黎敏、亨利我们会追上你的、穷理查历书...

git知识点查阅

若自己在自己的电脑上修改了某一代码&#xff0c;而此时远程分支上对应的代码别人也做了修改&#xff0c;现在需要把远程分支的代码和自己本地的代码合并到本地电脑&#xff0c;操作&#xff1a; git stash git pull git stash pop...

如何成为一个成功的 Java 开发人员?

【此文章转自乐字节】 如果你是一名成功的Java程序员&#xff0c;那么在任何公司中的Java开发人员中&#xff0c;你都有机会获取一席之地。 前言 在当今时代&#xff0c;有很多编程语言可能会塑造我们的未来。然而&#xff0c;当我们开始学习编程时&#xff0c;我们总是从C语…...

代理和负载均衡的详细说明是什么

对客户端提供的代理服务&#xff0c;在客户端无法直接访问服务端的情况下&#xff0c;星池StarPool通过配置代理服务器的方式访问服务端。在整个过程中&#xff0c;客户端请求首先发送到代理服务器&#xff0c;代理服务器再将请求发送到服务端后将结果返回给客户端。从服务端角…...

使用DNSObserver检测DNS安全漏洞

关于DNSObserver DNSObserver是个功能强大的DNS服务&#xff0c;该工具使用Go语言开发&#xff0c;可以帮助广大研究人员轻松检测各种类型的盲注漏洞。它可以监控渗透测试人员所搭建服务器的带外DNS交互信息&#xff0c;并通过Slack发送查询通知。DNSObserver可以帮助我们寻找的…...

Zookeeper源码查看: 七. 客户端启动源码

客户端启动源码 查看启动脚本 查看 zkCli.sh, 在 zkCli.sh 启动 Zookeeper 时, 会调用 ZooKeeperMain.java 创建 ZookeeperAdmin 查看启动类 ZookeeperMain 查看 ZookeeperMain 构造方法 查看 connectToZK() 方法 初始化监听器 查看 ZookeeperAdmin 类 解析连接地址…...

整理了 34 个 Python 自动化办公库

本次内容涵盖了Excel、Word、PPT、ODF、PDF、邮件、微信、文件处理等所有能在办公场景实现自动化的库,希望能够对大家有所帮助。 Python Excel自动化库 // 1.xlwings 库 官网: https://www.xlwings.org/ 特点:xlwings 是开源且免费的,预装了 Anaconda 和 WinPython,可…...

【Jenkins插件】之Multiple SCMs

在Jenkins配置中&#xff0c;有的时候我们需要依次拉取多个代码仓库&#xff0c;有时候还会需要既拉取svn代码库&#xff0c;又拉取git代码库&#xff0c;但Jenkins默认的配置是不支持这样操作的。因此&#xff0c;我们需要使用到Jenkins的Multiple SCMs插件。 Multiple SCMs这…...

为什么自己干了这么多活,最后功劳都是别人的?

【本文只针对IT行业技术岗】 一、粉丝留言 自己每天加班到10点&#xff0c;有时候都到凌晨&#xff0c;周6基本全勤&#xff0c;公司项目忙的时候周日还去加班&#xff0c; 做过的项目无数&#xff0c;很多项目都给公司带来了丰厚的利润。 年底年终奖比别人少了一个月&…...

pytest(10)-参数化详解

先看如下情况&#xff0c;即为了测试一个函数&#xff0c;列举了三个测试用例&#xff0c;每个用例其实就是参数不同而已 在test_example.py 文件中编写如下代码&#xff1a; def add(a,b):return (ab)def test_1():assert add(3,5)8def test_2():assert add(2,4)7def test_3(…...

防(反)浏览器指纹技术之指纹浏览器揭秘

什么是指纹浏览器? 首先&#xff0c;这个指纹并不是上班打卡的指纹&#xff0c;也不是你家指纹锁的指纹&#xff01; 这里指的浏览器指纹是指通过浏览器的各种信息&#xff0c;如系统字体、屏幕分辨率、浏览器语言、时区等等&#xff0c;无需 cookie 等技术&#xff0c;就能…...

2021全球暑期量子学习日程汇总,谷歌量子夏季研讨会正在报名中

今日小暑&#xff0c;虽酷热&#xff0c;但学习热忱不减&#xff0c;尤其是在各个科技巨头和高等院校接连发布了量子暑期班的招募通告后&#xff0c;大家可以妥善安排&#xff0c;“错峰出行”。 近日&#xff0c;谷歌也发布了暑期会议相关通告&#xff0c;其量子夏季研讨会 (…...

STM32使用STM32CubeMX配置引脚中断

前言 嵌入式系统中&#xff0c;外部中断&#xff0c;是一个比较常见的功能。中断的灵活使用&#xff0c;大大增强了系统的实时性。使用STM32 最新的HAL库&#xff0c;如何配置一个引脚中断呢&#xff1f; 配置中断 可以借助STM32提供的可视化软件&#xff1a;STM32CubeMX&#…...

最新出炉,头条三面技术四面HR,看我如何一步一步攻克面试官?

最开始面的头条游戏中台&#xff0c;当时是第一次面试&#xff0c;没有经验&#xff0c;导致算法题虽然有思路&#xff0c;但是没有写出最优解&#xff0c;直接挂了。后来又被捞起来&#xff0c;因为此时已有阿里的offer&#xff0c;所以胆子也大起来了&#xff0c;收拾心情开始…...

Linux基本命令

文章目录第一章Linux基础一、基本命令1.ls命令2.cd命令3.文件操作二、用户解读1.用户权限三、linux的基本操作1.软件介绍2.用户操作3.组3.1权限控制4.文件权限控制4.1权限设置5.vim的使用——一开始是命令模式6.寄存器7.find命令格式8.管道符—— |xargs9.grep命令第一章Linux基…...

docker+k8s 报错

dockerk8s报错 问题点&#xff1a;docker容器中或者k8s的pod中执行systemctl相关后台服务 报错信息&#xff1a;Failed to get D-Bus connection: Operation not permitted解决办法 docker&#xff1a;运行容器添加参数–privilegedtrue /sbin/init docker run -tid --name…...

国基北盛—云计算私有云iaas(2.4)平台搭建

1.基本环境配置详情&#xff1a; 2.虚拟机配置&#xff1a; Controller&#xff1a; 内存 6G 处理器4个 硬盘&#xff08;sda&#xff09;100G 网卡1&#xff08;仅主机192.168.100.10&#xff09; 网卡2&#xff08;NAT 192.168.200.10&#xff09; Compute&#xff1a; 内…...

zynq操作系统 : Linux下LHB155304测试用例

前言 第一种情况的改进和第三种情况&#xff0c;都可以在应用层来做   比如我们可以设置快速读写模式fastmode&#xff0c;在应用层调用这个函数open时&#xff0c;配置寄存器屏蔽掉其他子地址的中断&#xff0c;直接源头上减少信号量&#xff0c;提升操作系统处理效率&#…...

flink 小技巧记录

一、背景 flink做etl、大宽表、统计过程中有些小细节可以尝试优化&#xff0c;这里简单记录下&#xff1a; 二、场景 2.1 允许延迟的数据同步。比如线上订单库binlog同步到查询库&#xff0c;或者简单处理进入分析库&#xff0c;让分析师直接查询明细. 如果吞吐要求大一点&…...

Zookeeper源码查看: 七. 客户端启动源码

客户端启动源码 查看启动脚本 查看 zkCli.sh, 在 zkCli.sh 启动 Zookeeper 时, 会调用 ZooKeeperMain.java 创建 ZookeeperAdmin 查看启动类 ZookeeperMain 查看 ZookeeperMain 构造方法 查看 connectToZK() 方法 初始化监听器 查看 ZookeeperAdmin 类 解析连接地址…...

关于环境变量定义prompt实现$替换成用户+当前路径提示

set prompt "// ${HOST}:$cwd % " alias cd cd \!* ;set prompt "// ${HOST}:$cwd % "...

jspdf本地运行环境正常,打包后下载的pdf不全

最近开发过程中遇到个问题&#xff0c;用jspdf配合html2canvas把页面元素下载为pdf文件&#xff0c;在本地运行环境好好的&#xff0c;但是打包之后下载的pdf就是不全的&#xff0c;搜了好久也没找出什么对症的解决方案。 现象就是这样&#xff1a; 正常的文件&#xff1a; 有…...

LCD驱动芯片工厂,稳定提供高抗干扰超低功耗芯片2C23适用于水电气表以及工控仪表类驱动IC

容&#xff1a; VK2C23是一个点阵式存储映射的LCD驱动器&#xff0c;可支持最大224点&#xff08;56SEGx4COM&#xff09;或者最大416点&#xff08;52SEGx8COM&#xff09;的LCD屏。单片机可通过I2C接口配置显示参数和读写显示数据&#xff0c;也可通过指令进入省电模式。其高…...

5个实用提速深度学习模型的方法

您是否通过深度学习模型获得了良好的准确性&#xff0c;却发现推理时间不足以部署到生产环境中&#xff1f;您是否对如何优化模型的推理速度迷失了方向&#xff1f;那么这篇文章是给你的。众所周知&#xff0c;数据科学项目有一个奇特的特性&#xff0c;即项目者需要不断转换关…...

易-----

易 本人00后&#xff0c;近期在学子平、八字命理、易经玄学方面&#xff0c;如也是玄学爱好者&#xff0c;可以加联系方式一起讨论、学习&#xff0c;年龄相仿更好。 微信&#xff1a;1783176946 事实上还有两种《易经》&#xff0c;一种叫《连山易》&#xff0c;一种叫《归藏…...

ssh爆破获取用户密码

通过nmap扫描目标主机发现ssh版本为OpenSSH 5.3&#xff0c;有漏洞 漏洞影响版本&#xff08;OpenSSH < 8.3p1&#xff09; 使用msfconsole 工具 search ssh #查找有关ssh的漏洞 找到并使用漏洞use auxiliary/scanner/ssh/ssh_login show options #查看此漏…...

dbc2000 注册机|dbc2000 注册码注册机下载

点击下载来源&#xff1a;dbc2000 注册机 dbc2000 注册机是同名源程序软件的注册机软件&#xff0c;该源程序软件是一款应用于数据库搭建以及数据写入的数据库架设工具&#xff0c;它拥有强大的数据写入功能&#xff0c;在作为应用程序使用时&#xff0c;它不仅可以充当数据属性…...

秋招面经第八弹:网易二面-数据开发工程师

秋招第八弹&#xff1a;网易二面-数据开发工程师 写在最前&#xff1a;秋招以来一直在冲&#xff0c;因为事情比较多&#xff0c;对于笔试面试一直没有复盘&#xff0c;现在靠仅存的记忆把面试的一些问题记录下来&#xff0c;尽可能记录出能回忆到的问题&#xff0c;但可能记的…...

安卓课程格子APP

https://download.csdn.net/download/weixin_57836618/73810452 功能演示&#xff1a; 查看所有课程 点击主页面空白处即可添加课程 添加课程之后查看课程 查看双周课程 查看单周课程 6.查看课程详情...

强化学习——格子世界

强化学习——格子世界 项目源码地址&#xff1a;https://gitee.com/infiniteStars/machine-learning-experiment 1. 实验内容 2. 实验代码 import numpy as np import matplotlib.pyplot as plt from matplotlib.table import Table from xml.dom.minidom import Document #手…...

华为机试 - 跳格子游戏

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 地上共有N个格子&#xff0c;你需要跳完地上所有的格子&#xff0c;但是格子间是有强依赖关系的&#xff0c;跳完前一个格子后&#xff0c;后续的格子才会被开启&#xff0c;格子间的依赖关系由多组st…...

php 爬课程表信息,Ruby爬取教务系统生成课程表

我为什么要虐自己最近觉得课程格子广告越来越多&#xff0c;乱七八糟的东西越来越多&#xff0c;完全失去了一开始的存在价值&#xff0c;并且没有电脑端app&#xff0c;想查看课程必须拿出手机&#xff0c;而我使用电脑频率要比手机高&#xff0c;所以才有了折腾的动力。于是我…...

android 课程表 ui,UICollectionViewLayout实现课程表布局

因为项目中有课程表的相关模块&#xff0c;第一时间想到用UICollectionView。然而后期的需求越来越复杂&#xff0c;每个格子需要展示的内容越来越多&#xff0c;所以不得不寻找合适的解决方案。最后发现自定义UICollectionViewLayout可以实现我的需求。先放效果图&#xff1a;…...

Android自定义View课程表,Android 自定义View课程表表格

自己闲下来时间写的一个课表控件使用的自定义LinearLayout 里面View都是用代码实现的 最终效果如下图 写的可能有问题希望多多指点创建一个自定义LinearLayout 控件用来装载课程的信息和课程的周数 和节数大概的布局三这样的根据上面的看来觉得总体布局我分了两个 上面的星期是…...

java课程设计设计_java课程设计

1. 团队课程设计博客链接https://www.cnblogs.com/choco1ate/p/12172223.html2.本组课题及本人任务本组课题&#xff1a;泡泡堂(炸弹人)游戏本人任务&#xff1a;Box类(游戏地图中的每个方格)Bomb类(游戏过程中的)游戏玩家输赢信息的文件储存3.需求分析Box类&#xff1a;该类为…...

《课程格子》的一个笔试题目

题目如下&#xff0c;感觉很适合喜欢琢磨的程序员&#xff0c;也是考验你编码风格的时候。 Lets make a tower defense game&#xff08;塔防游戏):1. You have 1 tower, with H health and D dps(damage per second).2. There are n attackers, each with h_i health and d_i …...

Android仿照超级课程表 or 课程格子 一键提取课表功能(方正系统)

参考文章http://blog.csdn.net/sbsujjbcy ,本文仿照‘ 安卓弟 提供的android 项目实战——打造超级课程表一键提取课表功能文章&#xff0c;对他的代码进行了修改和补充&#xff0c;为什么要修改呢&#xff1f;原因是安卓弟的那个源码版本过于老旧&#xff0c;很多方法已经过…...

联想服务器系统初始化失败怎么回事,win10重置初始化失败怎么解决

对于我们正在使用win10操作系统的小伙伴们来说&#xff0c;如果想要重置自己的操作系统&#xff0c;但是发现win10重置初始化失败&#xff0c;小编觉得可能是因为系统内部配置错误。解决方法请看下文~win10重置初始化失败怎么解决方法一&#xff1a;1点选左下角“开始”按钮。2…...

如何解决未能初始化战场服务器,初始化失败,教您如何解决cf初始化失败

不少用户更新了微软推送的补丁之后&#xff0c;系统就无法正常运行游戏了&#xff0c;对于游戏中的BUG大家可能一笑而过&#xff0c;但是对于游戏的初始化失败大家就很头疼了&#xff0c;尤其是CF、LOL等大型游戏都不能愉快的玩耍了&#xff0c;该如何解决?下面&#xff0c;小…...

服务器显示初始化失败怎么回事,服务器初始化失败

服务器初始化失败 内容精选换一换专属分布式存储的基本操作流程如入门流程所示。使用专属分布式存储服务前&#xff0c;需要先申请存储池&#xff0c;请参见申请存储池。专属分布式存储服务的存储能力由磁盘实现&#xff0c;存储池申请成功后&#xff0c;需要在存储池中创建磁盘…...

解决Redis Object Cache Pro插件无法使用高性能配置的解决方案

说明 辉哥演示站和本地使用的对象缓存都是redis&#xff0c;刚好手上有Redis Object Cache Pro插件&#xff0c;目前大多数用户都是用的是官方推荐的基础配置&#xff0c;并没有使用高性能配置&#xff08;官方的说法是在毫秒内优化高流量站点&#xff09;&#xff0c;刚好辉哥…...

A智慧城市,新型信息化城市形态

A智慧城市&#xff0c;新型信息化城市形态 智慧城市就是物联网应用最直接、最集中的体现。智慧城市的建设可以把物联网带入城市&#xff0c;使物联网走进生活&#xff0c;让每个人都能感受并体验得到。 “智慧的城市”愿景在2010年被IBM正式提出&#xff0c;希望为世界和中国的…...

城市名接龙爬取全国城市各医院基本信息(名字、地址、联系电话、医院等级、重点科室、经营方式等)

整个程序分两部分&#xff1a;实现城市名接龙(兼容谐音)和爬取城市医院信息。 城市接龙部分&#xff1a; 城市接龙需要兼容谐音&#xff0c;那么就必须用到xpinyin模块中的Pinyin类方法&#xff0c;负责将中文转换为拼音&#xff1b;而城市接龙的实现便是通过将初次输入的城市…...

通过ip地址获取用户的所在城市信息

通过ip地址获取用户的所在城市信息 最近公司市场部在对推广页面进行地区优化时&#xff0c;提及的一个小的需求&#xff0c;目前公司的推广页面都有自己固定的推广地址&#xff0c;但是怕些许用户损失所以需要根据用户的提交数据时所在的网络进行用户地址的定位&#xff0c;自…...

城市轨道交通信息化架构

...

Python案例:获取全国城市列表(区号与名称)

文章目录 一、获取城市信息JSON数据(一)访问网页,查看数据(二)利用JsonViewer查看城市数据二、解析城市数据获取城市列表(一)编写程序,实现功能(二)运行程序,查看结果一、获取城市信息JSON数据 (一)访问网页,查看数据 网址:https://j.i8tq.com/weather2020/sea…...