06--kubernetes.pod管理与投射数据卷

前言:上一章记录了部署k8s常用的两个方式,这一章就简单一些,整理一下k8s资源对象的配置和管理命令。

1、集群状态检查

前天搭建的环境,然后关机了两天今天开启后第一时间需要检查集群环境是否正常

[root@k8s-master1 ~]# kubectl get node
NAME          STATUS   ROLES    AGE     VERSION
k8s-master1   Ready    master   2d17h   v1.19.1
k8s-node1     Ready    <none>   2d17h   v1.19.1
k8s-node2     Ready    <none>   2d17h   v1.19.1[root@k8s-master1 ~]# kubectl get pod -n kube-system
NAME                                  READY   STATUS    RESTARTS   AGE
coredns-f9fd979d6-f8rxv               1/1     Running   1          2d17h
coredns-f9fd979d6-frrvc               1/1     Running   1          2d17h
etcd-k8s-master1                      1/1     Running   1          2d17h
kube-apiserver-k8s-master1            1/1     Running   1          2d17h
kube-controller-manager-k8s-master1   1/1     Running   1          2d17h
kube-flannel-ds-c576q                 1/1     Running   1          2d17h
kube-flannel-ds-hxkww                 1/1     Running   2          2d17h
kube-flannel-ds-nm9b2                 1/1     Running   2          2d17h
kube-proxy-96cnh                      1/1     Running   1          2d17h
kube-proxy-j5gbf                      1/1     Running   1          2d17h
kube-proxy-pz2l2                      1/1     Running   1          2d17h
kube-scheduler-k8s-master1            1/1     Running   1          2d17h

集群状态正常继续今天的操作

常用检查命令

查看service的信息:
[root@k8s-master1 ~]# kubectl get service在不同的namespace里面查看service:
[root@k8s-master1 ~]# kubectl get service -n kube-system
-n:namespace名称空间查看所有名称空间内的pod:
[root@k8s-master1 ~]# kubectl get pods --all-namespaces同时查看多种资源对象的信息:
[root@k8s-master1 ~]# kubectl get pod,service -n kube-system查看主节点:
[root@k8s-master1 ~]# kubectl cluster-infoapi查询:(写yaml要用)
[root@k8s-master1 ~]# kubectl api-versions也可以查看pod的信息
[root@k8s-master1 ~]# kubectl describe node k8s-node1

2、命名空间管理

在 Kubernetes(K8s)中,Namespace(命名空间)就像是一个虚拟的隔间,用于将集群中的资源进行逻辑上的分区。通过创建不同的 Namespace,可以有效地管理和隔离资源,实现更高效的资源管理和权限控制。

Namespace 的作用可以形象地比喻为以下几种场景:

  1. 资源隔离:想象一下一个大型办公楼,每个部门都有自己的独立办公室。不同的部门(Namespace)在自己的办公室(Namespace)里工作,互不干扰。这样,不同部门的资源(如服务、Pod)就不会相互碰撞或冲突,保持清晰和有序。

  2. 资源管理:在办公楼中,所有财务部门的文件、设备和人员都集中在一个区域。类似地,将相关的资源(如应用程序、数据库)放在同一个 Namespace 中,使管理和监控变得更加简单和高效。

  3. 权限控制:在办公楼中,门禁系统可以限制哪些人可以进入哪些区域。通过 Kubernetes 的 RBAC(基于角色的访问控制),你可以设置不同的权限,让只有特定角色的人能够访问或管理特定的 Namespace,就像门禁系统控制访问一样。

  4. 环境隔离:办公楼的不同楼层可能被设计成不同的用途:一层用于开发,二层用于测试,三层用于生产。类似地,Kubernetes 中可以创建不同的 Namespace 来分别部署开发、测试和生产环境,确保各个环境之间相互隔离,提升安全性和稳定性。

查看命名空间

[root@k8s-master1 ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   2d17h
kube-flannel      Active   2d17h
kube-node-lease   Active   2d17h
kube-public       Active   2d17h
kube-system       Active   2d17h[root@k8s-master1 ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   2d17h
kube-flannel      Active   2d17h
kube-node-lease   Active   2d17h
kube-public       Active   2d17h
kube-system       Active   2d17h

创建命名空间

使用yaml文件创建ns
[root@k8s-master1 ~]# mkdir namespace.yaml.d
[root@k8s-master1 ~]# cd namespace.yaml.d/
[root@k8s-master1 namespace.yaml.d]# vim namespace1.yaml
[root@k8s-master1 namespace.yaml.d]# cat namespace1.yaml
---
apiVersion: v1
kind: Namespace #设定创建资源对象类型
metadata: #元数据name: ns-example #ns名字labels:this_ns_name: name_is_ns-example #标签创建ns
[root@k8s-master1 namespace.yaml.d]# kubectl apply -f namespace1.yaml 
namespace/ns-example created查看ns
[root@k8s-master1 namespace.yaml.d]# kubectl get ns
NAME              STATUS   AGE
default           Active   2d18h
kube-flannel      Active   2d17h
kube-node-lease   Active   2d18h
kube-public       Active   2d18h
kube-system       Active   2d18h
ns-example        Active   15s
[root@k8s-master1 namespace.yaml.d]# kubectl get ns ns-example
NAME         STATUS   AGE
ns-example   Active   46s
[root@k8s-master1 namespace.yaml.d]# kubectl describe namespace ns-example
Name:         ns-example
Labels:       this_ns_name=name_is_ns-example
Annotations:  <none>
Status:       ActiveNo resource quota.No LimitRange resource.删除ns[root@k8s-master1 namespace.yaml.d]# kubectl delete -f namespace1.yaml[root@k8s-master prome]# kubectl delete namespace ns-example

一个yaml/yml内可以写两个资源对象

[root@k8s-master1 namespace.yaml.d]# vim namespace2.yml
[root@k8s-master1 namespace.yaml.d]# cat namespace2.yml
---
apiVersion: v1
kind: Namespace
metadata: name: ns-examplelabels:this_ns_name: name_is_ns-example
---
apiVersion: v1
kind: Namespace
metadata: name: ns-example2labels:this_ns_name2: name_is_ns-example
[root@k8s-master1 namespace.yaml.d]# kubectl apply -f namespace2.yml 
namespace/ns-example created
namespace/ns-example2 created
[root@k8s-master1 namespace.yaml.d]# kubectl get ns
NAME              STATUS   AGE
default           Active   2d18h
kube-flannel      Active   2d18h
kube-node-lease   Active   2d18h
kube-public       Active   2d18h
kube-system       Active   2d18h
ns-example        Active   6s
ns-example2       Active   6s

3、pod管理

3.1、创建pod

任务:发布第一个容器化应用

  1. 制作镜像:作为应用开发者,你首先需要制作容器镜像。
  2. 组织镜像:将镜像按 Kubernetes 的规范整理,并提交上去。

Kubernetes 项目能"认识"的方式

Kubernetes 不推荐直接使用命令行运行容器,而是使用 YAML 或 JSON 配置文件来定义和管理容器。你需要将容器的定义、参数和配置记录在 YAML 文件中,然后使用以下指令运行:

# kubectl create -f 配置文件

好处

  • 文件记录了 Kubernetes 运行了什么,便于后续查看。

使用 YAML 创建 Pod

YAML 文件在 Kubernetes 中对应 API 对象。填写字段并提交,Kubernetes 会根据定义创建容器或其他 API 资源。

编写yaml
[root@k8s-master1 pod.yaml.d]# vim pod1.yml 
[root@k8s-master1 pod.yaml.d]# cat pod1.yml 
---
apiVersion: v1
kind: Pod
metadata:name: websitlabels:this-pod-name: this-is-websit
spec:containers:- name: name-of-websit-nginximage: linuxserver/nginxports:- containerPort: 80#############注意事项#########
自定义字段命名规则( DNS-1123 标签):必须只包含小写字母(a-z)、数字(0-9)和连字符(-)。必须以字母或数字开头和结尾。不能包含大写字母或其他字符。

创建pod

[root@k8s-master1 pod.yaml.d]# kubectl apply -f pod1.yml
pod/websit created
[root@k8s-master1 pod.yaml.d]# kubectl get pod
NAME     READY   STATUS    RESTARTS   AGE
websit   1/1     Running   0          9s

这里有一个需要了解的点:

pod的准备状况指的是Pod是否准备就绪以接收请求,Pod的准备状况取决于容器,即所有容器都准备就绪了,Pod才准备就绪。这时候kubernetes的代理服务才会添加Pod作为后端,而一旦Pod的准备状况变为false(至少一个容器的准备状况为false),kubernetes会将Pod从代理服务的分发后端移除,即不会分发请求给该Pod。

一个pod刚被创建的时候是不会被调度的,因为没有任何节点被选择用来运行这个pod。调度的过程发生在创建完成之后,但是这个过程一般很快,所以通常看不到pod是处于unscheduler状态的除非创建的过程遇到了问题。

pod被调度之后,分配到指定的节点上运行,这时候,如果该节点没有所需要的image,那么将会自动从默认的Docker Hub上pull指定的image,一切就绪之后,看到pod是处于running状态了

3.2、pod管理

查看pod

[root@k8s-master1 pod.yaml.d]# kubectl get pod -o wide
NAME     READY   STATUS    RESTARTS   AGE    IP           NODE        NOMINATED NODE   READINESS GATES
websit   1/1     Running   0          4m5s   10.244.1.2   k8s-node1   <none>           <none>#在k8s看来创建了一个pod,在node1上使用docker ps可以看到新建的容器#这里能看到pod的ip,可以尝试访问

查看pod的详细信息

[root@k8s-master1 pod.yaml.d]# kubectl describe pod websit -n 命名空间

也可以使用yaml导出 

[root@k8s-master1 pod.yaml.d]# kubectl get pod websit -o yaml -n default

进入pod

[root@k8s-master1 pod.yaml.d]# kubectl exec -it websit /bin/sh

 删除pod

[root@k8s-master1 pod.yaml.d]# kubectl delete pod website
[root@k8s-master1 pod.yaml.d]# kubectl delete -f pod1.yml 批量删除用法
[root@k8s-master1 pod.yaml.d]# kubectl delete pod --all
[root@k8s-master1 pod.yaml.d]# kubectl delete pod pod名1 pod名2

补充:

kubectl create 和 kubectl apply 是两个用于管理 Kubernetes 资源的命令,但它们在处理资源的方式上有一些关键区别。
kubectl create功能:用于创建新的资源对象。用法:kubectl create -f <file.yaml>行为:只适用于创建资源。它不会对已经存在的资源进行更新。如果你需要更新资源,你必须首先删除现有资源,然后重新创建。例如,如果你修改了 YAML 文件中的配置,你需要先使用 kubectl delete -f <file.yaml> 删除现有的资源,然后使用 kubectl create -f <file.yaml> 重新创建。kubectl apply功能:用于创建或更新资源对象。用法:kubectl apply -f <file.yaml>行为:创建:如果资源不存在,apply 会创建它。更新:如果资源已经存在,apply 会自动检测到 YAML 文件中的更改,并更新现有资源。这意味着你可以修改 YAML 文件,然后再次运行 kubectl apply -f <file.yaml>,Kubernetes 会处理更新,无需删除资源。

pod的hosts解析

临时创建,删除容器后重新创建失效

操作方式:进入pod内部编辑hosts文件

永久创建:修改yaml/yml文件

操作方式如下

[root@k8s-master1 pod.yaml.d]# kubectl delete -f pod1.yml 
pod "websit" deleted
[root@k8s-master1 pod.yaml.d]# vim pod1.yml 
[root@k8s-master1 pod.yaml.d]# cat pod1.yml 
---
apiVersion: v1
kind: Pod
metadata:name: websitlabels:this-pod-name: this-is-websit
spec:containers:- name: name-of-websit-nginximage: linuxserver/nginxports:- containerPort: 80hostAliases:- ip: "192.168.188.101"hostnames:- "k8s-master"- "su-zhu-ji"- "www.master.com"- ip: "192.168.188.102"hostnames:- "k8s-node1"- "node-node-1"- "www.node1.com"

 根据此文件创建pod,完成后进入容器,效果如下

[root@k8s-master1 pod.yaml.d]# kubectl apply -f pod1.yml 
pod/websit created
[root@k8s-master1 pod.yaml.d]# kubectl exec -it websit /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@websit:/# cat /etc/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.1.5	websit# Entries added by HostAliases.
192.168.188.101	k8s-master	su-zhu-ji	www.master.com
192.168.188.102	k8s-node1	node-node-1	www.node1.com
root@websit:/# ping www.master.com
PING www.master.com (192.168.188.101): 56 data bytes
64 bytes from 192.168.188.101: seq=0 ttl=63 time=0.304 ms
64 bytes from 192.168.188.101: seq=1 ttl=63 time=0.387 ms
64 bytes from 192.168.188.101: seq=2 ttl=63 time=0.269 ms
^C
--- www.master.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.269/0.320/0.387 ms
root@websit:/# 

3.3、pod生命周期

常见状态:

  • Pending:此状态表示Pod 的 YAML 文件已经提交给了 Kubernetes,API 对象已经被创建并保存在 Etcd 当中(准备状态)。但这个 Pod 里有些容器因为某种原因而不能被顺利创建。比如,调度不成功。
  • Running:此状态表示Pod 已经调度成功,跟一个具体的节点绑定。它包含的容器都已经创建成功,并且至少有一个正在运行中。(只有这个状态是正常的)
  • Succeeded:此状态表示 Pod 里的所有容器都正常运行完毕,并且已经退出了。这种情况在运行一次性任务时最为常见。
  • Failed:此状态表示 Pod 里至少有一个容器以不正常的状态(非 0 的返回码)退出。这个状态的出现,意味着你得想办法 Debug 这个容器的应用,比如查看 Pod 的 Events 和日志。
  • Unknown:这是一个异常状态(未知状态),表示 Pod 的状态不能持续地被 kubelet 汇报给 kube-apiserver这很有可能是主从节点(Master 和 Kubelet)间的通信出现了问题

其他状态:

CrashLoopBackOff: 容器退出,kubelet正在将它重启
InvalidImageName: 无法解析镜像名称
ImageInspectError: 无法校验镜像
ErrImageNeverPull: 策略禁止拉取镜像
ImagePullBackOff: 正在重试拉取
RegistryUnavailable: 连接不到镜像中心
ErrImagePull: 通用的拉取镜像出错
CreateContainerConfigError: 不能创建kubelet使用的容器配置
CreateContainerError: 创建容器失败
m.internalLifecycle.PreStartContainer  执行hook报错
RunContainerError: 启动容器失败
PostStartHookError: 执行hook报错 
ContainersNotInitialized: 容器没有初始化完毕
ContainersNotReady: 容器没有准备完毕 
ContainerCreating:容器创建中
PodInitializing:pod 初始化中 
DockerDaemonNotReady:docker还没有完全启动
NetworkPluginNotReady: 网络插件还没有完全启动

4、投射数据卷 Projected Volume

Projected Volume 是 Kubernetes v1.11 之后引入的新特性,类似于 Docker 中的映射卷(docker run -v)。

在 Kubernetes 中,有几种特殊的 Volume 不是为了存放容器数据,也不是用来进行容器和宿主机之间的数据交换,而是为了为容器提供预先定义好的数据。从容器的角度来看,这些 Volume 里的信息仿佛是被 Kubernetes "投射"(Project)进入容器当中的。

Kubernetes 支持的 Projected Volume 包括四种类型(这些在k8s中都被看做资源对象):

  • Secret
  • ConfigMap
  • Downward API
  • ServiceAccount

4.1、secret

secret介绍:

  • secret用来保存小片敏感数据的k8s资源对象,例如密码,token,或者秘钥。这类数据当然也可以存放在Pod或者镜像中,但是放在Secret中是为了更方便的控制如何使用数据,并减少暴露的风险。
  • 用户可以创建自己的secret,系统也会有自己的secret。
  • Pod需要先引用才能使用某个secret

pod使用secre的方式:

  • 內建的Secrets::由ServiceAccount创建的API证书附加的秘钥k8s自动生成的用来访问apiserver的Secret,所有Pod会默认使用这个Secret与apiserver通信

  • 创建自己的Secret:使用kubectl create secret命令或yaml文件创建Secret

4.1.1、创建secret

命令创建secret:

[root@k8s-master1 ~]# echo -n 'admin' > username.txt
[root@k8s-master1 ~]# echo -n 'Liumuquan@123' > password.txt
[root@k8s-master1 ~]# kubectl create secret generic db-user-pass --from-file=username.txt --from-file=password.txt
secret/db-user-pass created
[root@k8s-master1 ~]#  kubectl get secret
NAME                  TYPE                                  DATA   AGE
db-user-pass          Opaque                                2      3s
default-token-l87r2   kubernetes.io/service-account-token   3      5d17h查看详细信息[root@k8s-master1 ~]# kubectl describe secret db-user-pass
Name:         db-user-pass
Namespace:    default
Labels:       <none>
Annotations:  <none>Type:  OpaqueData
====
password.txt:  13 bytes
username.txt:  5 bytes[root@k8s-master1 ~]# kubectl get secret db-user-pass -o yaml
apiVersion: v1
data:password.txt: TGl1bXVxdWFuQDEyMw==username.txt: YWRtaW4=
kind: Secret
metadata:creationTimestamp: "2024-08-20T10:15:04Z"managedFields:- apiVersion: v1fieldsType: FieldsV1fieldsV1:f:data:.: {}f:password.txt: {}f:username.txt: {}f:type: {}manager: kubectl-createoperation: Updatetime: "2024-08-20T10:15:04Z"name: db-user-passnamespace: defaultresourceVersion: "70826"selfLink: /api/v1/namespaces/default/secrets/db-user-passuid: fddaf0fd-96ac-461c-88df-f301a8dcbd08
type: Opaque

对data选项进行解码

[root@k8s-master1 ~]# echo TGl1bXVxdWFuQDEyMw== | base64 --decode
Liumuquan@123

yaml创建secret:

明文显示容易暴露,先转码,再写入文件

[root@k8s-master1 ~]# echo -n "admin" | base64
YWRtaW4=
[root@k8s-master1 ~]# echo -n "123456" | base64
MTIzNDU2
[root@k8s-master1 ~]# mkdir secret.yaml.d
[root@k8s-master1 ~]# cd secret.yaml.d/
[root@k8s-master1 secret.yaml.d]# vim secret1.yaml
[root@k8s-master1 secret.yaml.d]# cat secret1.yaml
---
apiVersion: v1
kind: Secret
metadata:name: mysecret
type: Opaque
data:username: YWRtaW4=password: MTIzNDU2
[root@k8s-master1 secret.yaml.d]# kubectl apply -f secret1.yaml
secret/mysecret created

查看secret

[root@k8s-master1 secret.yaml.d]# kubectl get secrets
NAME                  TYPE                                  DATA   AGE
db-user-pass          Opaque                                2      22m
default-token-l87r2   kubernetes.io/service-account-token   3      5d17h
mysecret              Opaque                                2      10s
[root@k8s-master1 secret.yaml.d]# kubectl get secret mysecret -o yaml -n default
apiVersion: v1
data:password: MTIzNDU2username: YWRtaW4=
kind: Secret
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"v1","data":{"password":"MTIzNDU2","username":"YWRtaW4="},"kind":"Secret","metadata":{"annotations":{},"name":"mysecret","namespace":"default"},"type":"Opaque"}creationTimestamp: "2024-08-20T10:37:34Z"managedFields:- apiVersion: v1fieldsType: FieldsV1fieldsV1:f:data:.: {}f:password: {}f:username: {}f:metadata:f:annotations:.: {}f:kubectl.kubernetes.io/last-applied-configuration: {}f:type: {}manager: kubectl-client-side-applyoperation: Updatetime: "2024-08-20T10:37:34Z"name: mysecretnamespace: defaultresourceVersion: "74069"selfLink: /api/v1/namespaces/default/secrets/mysecretuid: a66ffa02-f40f-4b1b-ab47-efb35c9bc829
type: Opaque

4.1.2、引用secret

1)卷挂载方式引用

创建pod文件,并以卷挂载格式引用secret

[root@k8s-master1 pod.yaml.d]# vim pod_use_secret.yaml
[root@k8s-master1 pod.yaml.d]# cat pod_use_secret.yaml
---
apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: testredisimage: daocloud.io/library/redisvolumeMounts:    #挂载一个卷- name: foo     #这个名字需要与定义的卷的名字一致mountPath: "/etc/foo"  #挂载到容器里哪个目录下,随便写readOnly: truevolumes:     #数据卷的定义- name: foo   #卷的名字这个名字自定义secret:    #卷是直接使用的secret。secretName: mysecret   #调用刚才定义的secret

创建pod并进入pod查看挂载的目录

[root@k8s-master1 pod.yaml.d]# kubectl apply -f pod_use_secret.yaml 
pod/mypod created
[root@k8s-master1 pod.yaml.d]# kubectl get pod
NAME     READY   STATUS    RESTARTS   AGE
mypod    1/1     Running   0          10s
websit   1/1     Running   0          105m[root@k8s-master1 pod.yaml.d]# kubectl exec -it mypod /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@mypod:/# ls /etc/foo
password  username
root@mypod:/# cat /etc/foo/username 
admin

这种方式会将secret中所有key全部引用

映射secret key

删除刚创建的pod,创建pod文件如下

[root@k8s-master1 pod.yaml.d]# cat pod_use_secret.yaml 
---
apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: testnginximage: linuxserver/nginxvolumeMounts:- name: foomountPath: "/etc/foo"readOnly: truevolumes:- name: foosecret:secretName: mysecretitems:   #定义一个items- key: username   #将那个key重新定义到那个目录下path: my-group/my-username  #相对路径,相对于/etc/foo的路径

创建pod并进入pod查看挂载的目录

[root@k8s-master1 pod.yaml.d]# kubectl apply -f pod_use_secret.yaml 
pod/mypod created
[root@k8s-master1 pod.yaml.d]# kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
mypod   1/1     Running   0          10s
[root@k8s-master1 pod.yaml.d]# kubectl exec -it mypod /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@mypod:/# ls /etc/foo
my-group
root@mypod:/# ls /etc/foo/my-group/
my-username
root@mypod:/# cat /etc/foo/my-group/my-username 
admin

修改secret的值,然后重新配置secret

[root@k8s-master1 pod.yaml.d]# echo -n "Administrator" | base64
QWRtaW5pc3RyYXRvcg==
[root@k8s-master1 pod.yaml.d]# vim /root/secret.yaml.d/secret1.yaml 
[root@k8s-master1 pod.yaml.d]# cat /root/secret.yaml.d/secret1.yaml 
---
apiVersion: v1
kind: Secret
metadata:name: mysecret
type: Opaque
data:username: QWRtaW5pc3RyYXRvcg==password: MTIzNDU2
[root@k8s-master1 pod.yaml.d]# kubectl apply -f /root/secret.yaml.d/secret1.yaml
secret/mysecret configured

secret自动更新

等待一段时间进入pod内部

[root@k8s-master1 pod.yaml.d]# kubectl exec -it mypod /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@mypod:/# cat /etc/foo/my-group/my-username 
Administrator

卷挂载方式是可以自动更新的,后面演示的环境变量方式是无法自动更新的

2)环境变量方式引用

以mysql的用户名和密码为例,先创建secert和pod文件

[root@k8s-master1 pod.yaml.d]# echo -n "root" | base64
cm9vdA==
[root@k8s-master1 pod.yaml.d]# echo -n "Liumuquan@123" | base64
TGl1bXVxdWFuQDEyMw==[root@k8s-master1 pod.yaml.d]# cat pod_mysql_secert.yaml
---
apiVersion: v1
kind: Secret
metadata:name: mysql-user-pass
type: Opaque
data:username: cm9vdA==password: TGl1bXVxdWFuQDEyMw==
---
apiVersion: v1
kind: Pod
metadata:name: mysql
spec:containers:- name: mysqlimage: docker pull registry.cn-chengdu.aliyuncs.com/liumuquan_app/mysql:5.7env:- name: MYSQL_ROOT_PASSWORD  #创建新的环境变量名称valueFrom:secretKeyRef:   #调用的key是什么name: mysql-user-pass  #变量的值来自于mysecretkey: password       #username里面的

根据yaml文件创建镜像

[root@k8s-master1 pod.yaml.d]# kubectl apply -f pod_mysql_secert.yaml

验证密码是否配置成功

[root@k8s-master1 pod.yaml.d]# kubectl exec -it mysql /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.2# mysql -uroot -p'Liumuquan@123'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44 MySQL Community Server (GPL)Copyright (c) 2000, 2023, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> 

修改yaml后应用文件,并不会更新密码。

4.1.3、私有仓库secret应用

以阿里云私有仓库为例

[root@k8s-master1 pod.yaml.d]# kubectl create secret docker-registry myregistrykey --docker-server=registry.cn-chengdu.aliyuncs.com --docker-username=liumuquan --docker-password=XXXX密码XXXX

secret引用

4.2、ConfigMap

ConfigMap 与 Secret 类似,用来存储配置文件的kubernetes资源对象,所有的配置内容都存储在etcd中。ConfigMap 保存的是不需要加密的、应用所需的配置信息

ConfigMap 的用法几乎与 Secret 完全相同:可以使用 kubectl create configmap 从文件或者目录创建 ConfigMap,也可以直接编写 ConfigMap 对象的 YAML 文件。

创建ConfigMap有四种方式(也可以说是两种)

  • 方式1:通过直接在命令行中指定configmap参数创建,即--from-literal
  • 方式2:通过指定文件创建,即将一个配置文件创建为一个ConfigMap,--from-file=<文件>
  • 方式3:通过指定目录创建,即将一个目录下的所有配置文件创建为一个ConfigMap,--from-file=<目录>
  • 方式4:事先写好标准的 configmap的yaml文件,然后kubectl create -f 创建

4.2.1、创建configmap

1)命令行--from-literal创建

[root@k8s-master1 ~]# kubectl create configmap test-configmap --from-literal=user=liumuquan --from-literal=pass=mypassword@123
configmap/test-configmap created
[root@k8s-master1 ~]# kubectl get configmap
NAME             DATA   AGE
test-configmap   2      14s
[root@k8s-master1 ~]# kubectl get cm
NAME             DATA   AGE
test-configmap   2      19s

2)指定文件创建

[root@k8s-master1 configmap.d]# vim mysql_configmapm_test
[root@k8s-master1 configmap.d]# cat mysql_configmapm_test
key.1 = value-1
key.2 = value-2
key.3 = value-3
key.4 = value-4
[mysqld]
!include /home/wing/mysql/etc/mysqld.cnf
port = 3306
socket = /home/wing/mysql/tmp/mysql.sock
pid-file = /wing/mysql/mysql/var/mysql.pid
basedir = /home/mysql/mysql
datadir = /wing/mysql/mysql/var
[root@k8s-master1 configmap.d]# kubectl create configmap test-configmap2 --from-file=mysql_configmapm_test 
configmap/test-configmap2 created可以指定多个文件

效果如下:

3)指定目录创建 

[root@k8s-master1 configmap.d]# mkdir configmap_test
[root@k8s-master1 configmap.d]# cd configmap_test/
[root@k8s-master1 configmap_test]# pwd
/root/configmap.d/configmap_test
[root@k8s-master1 configmap_test]# vim configmap_test1
[root@k8s-master1 configmap_test]# cat configmap_test1
aaa
bbb
ccc
ddd
a=d
[root@k8s-master1 configmap_test]# vim configmap_test2
[root@k8s-master1 configmap_test]# cat configmap_test2
eee
fff
h=p
[root@k8s-master1 configmap_test]# cd ..
[root@k8s-master1 configmap.d]# kubectl create configmap test-configmap3 --from-file=configmap_testconfigmap/test-configmap3 created

效果如下:

这里内容格式为key:value,对应为文件名:文件内容 

4)yaml文件创建

[root@k8s-master1 configmap.d]# vim configmap4.yaml
[root@k8s-master1 configmap.d]# cat configmap4.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:name: test-configmap4namespace: default
data:key1_cache_host: memcached-gcxtkey2_cache_port: "11211"key3_cache_prefix: gcxtmy.cnf: |[mysqld]log-bin = mysql-binhaha = hehe
[root@k8s-master1 configmap.d]# kubectl apply -f configmap4.yaml configmap/test-configmap4 created

效果如下:

4.2.2、引用configmap

使用ConfigMap有三种方式,一种是通过环境变量的方式,直接传递pod,另一种是通过在pod的命令行下运行的方式,第三种(最常用的)是使用volume的方式挂载入到pod内

 使用卷挂载这里有一个需要注意的地方,就是subPath的使用:

在 Linux 中,将目录 A 挂载到目录 B 时,目录 B 中原有的文件会被目录 A 下的文件覆盖。在 Kubernetes 中,可以使用 subPath 将 ConfigMap 挂载到容器中某个目录的文件中,从而避免覆盖该目录下的其他文件

使用 subPath 可以将 ConfigMap 或 Secret 挂载为容器中某个目录的文件,而不会覆盖挂载目录下的现有文件。然而,使用 subPath 参数后,配置文件不支持热更新

卷挂载使用方式如下:

先做一份nginx的配置文件出来

[root@k8s-master1 configmap.d]# cat /etc/nginx/nginx.conf > configmap_nginx

创建configmap

[root@k8s-master1 configmap.d]# kubectl create cm cm-nginx --from-file=configmap_nginx

创建pod文件并引用configmap

[root@k8s-master1 configmap.d]# cd /root/pod.yaml.d/
[root@k8s-master1 pod.yaml.d]# vim nginx-cm-pod.yaml
[root@k8s-master1 pod.yaml.d]# cat nginx-cm-pod.yaml
---
apiVersion: v1
kind: Pod
metadata:name: nginx-cm-test
spec:containers:- name: nginximage: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:1.20.1volumeMounts:- name: nginxmountPath: /etc/nginx/nginx.confsubPath: nginx.conf #只覆盖这一个文件,不影响该路径其他文件volumes:- name: nginxconfigMap:name: cm-nginxitems:- key: configmap_nginx #这个值来自于-o yaml查看path: nginx.conf #挂载到pod内产生的文件名

创建pod

[root@k8s-master1 pod.yaml.d]# kubectl apply -f nginx-cm-pod.yaml 
pod/nginx-cm-test created
[root@k8s-master1 pod.yaml.d]# kubectl get pod
NAME            READY   STATUS    RESTARTS   AGE
mypod           1/1     Running   1          25h
mysql           1/1     Running   0          5h52m
nginx-cm-test   1/1     Running   0          3s

这个cm是使用命令行方式创建的,修改方式有所不同

[root@k8s-master1 pod.yaml.d]# kubectl edit configmap cm-nginx

即使经过上面方式修改文件,已经创建的pod内并不会随之更新

4.2.3、ConfigMap 的热更新

  1. 使用 ConfigMap 挂载的环境变量 (Env) 不会同步更新。
  2. 使用 ConfigMap 挂载的卷 (Volume) 中的数据需要一些时间(大约 10 秒)才能同步更新。请注意:
    • 只有通过 YAML 文件创建的 ConfigMap 才支持热更新。
    • 不能使用 subPath 参数。

附注:当 ConfigMap 作为数据卷挂载到 Pod 中时,更新或重新创建 ConfigMap 后,Pod 内部的配置会热更新。但如果 ConfigMap 用作环境变量,环境变量不会自动更新,因为它们在容器启动时被注入,启动后 Kubernetes 不会改变环境变量的值。此外,同一 namespace 中的 Pod 的环境变量是累加的

以下为操作方式以nginx搭建反向代理为例:

yaml文件如下

[root@k8s-master1 pod.yaml.d]# vim nginx-pod.yaml
[root@k8s-master1 pod.yaml.d]# cat nginx-pod.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:name: configmap-yaml
data:server1.conf: |-upstream tomcatserver1 {server 192.168.15.55:8081;}server {listen 80;server_name 8081.max.com;location / {proxy_pass http://tomcatserver1;index index.html index.htm;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}}
---
apiVersion: v1
kind: Pod
metadata:name: configmap-pod
spec:containers:- name: nginximage: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:1.20.1ports:- containerPort: 80volumeMounts:- mountPath: /etc/nginx/conf.dname: conf-namevolumes:- name: conf-nameconfigMap:name: configmap-yamlitems:- key: server1.confpath: server1.conf

创建cm和pod

[root@k8s-master1 pod.yaml.d]# kubectl apply -f nginx-pod.yaml 
configmap/configmap-yaml created
pod/configmap-pod created
[root@k8s-master1 pod.yaml.d]# kubectl get cm
NAME             DATA   AGE
cm-nginx         1      46m
configmap-yaml   1      17s
[root@k8s-master1 pod.yaml.d]# kubectl get pod
NAME            READY   STATUS    RESTARTS   AGE
configmap-pod   1/1     Running   0          21s
mypod           1/1     Running   1          25h
mysql           1/1     Running   0          6h13m
nginx-cm-test   1/1     Running   0          21m

进入刚创建的pod内部查看配置

[root@k8s-master1 pod.yaml.d]# kubectl exec -it configmap-pod /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# ls /etc/nginx/conf.d/   
server1.conf
# cat /etc/nginx/conf.d/server1.conf
upstream tomcatserver1 {server 192.168.15.55:8081;
}
server {listen 80;server_name 8081.max.com;location / {proxy_pass http://tomcatserver1;index index.html index.htm;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}
}# 

出去修改cm内容,检查热更新

[root@k8s-master1 pod.yaml.d]# vim nginx-pod.yaml 
[root@k8s-master1 pod.yaml.d]# kubectl apply nginx-pod.yaml 
error: must specify one of -f and -k
[root@k8s-master1 pod.yaml.d]# kubectl apply -f nginx-pod.yaml 
configmap/configmap-yaml configured
pod/configmap-pod configured#    此处需要等待一段时间,热更新速度较慢[root@k8s-master1 pod.yaml.d]# kubectl exec -it configmap-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@configmap-pod:/# cat /etc/nginx/conf.d/server1.conf
upstream tomcatserver1 {server 111.111.111.111:1111;
}
server {listen 2222;server_name 3333.max.com;location / {proxy_pass http://tomcatserver1;index index.html index.htm;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}
}root@configmap-pod:/# 内部ip和端口已经被修改,此时无需重启nginx,配置自动载入

4.3、Downward API

Downward API 用于在容器中获取 POD 的基本信息,kubernetes支持 Downward API提供了两种方式用于将 POD 的信息注入到容器内部,无需提前创建:

  1. 环境变量:用于单个变量,可以将 POD 信息和容器信息直接注入容器内部。
  2. Volume挂载:将 POD 信息生成为文件,直接挂载到容器内部中去。

环境变量的方式:

通过Downward API来将 POD 的 IP、名称以及所对应的 namespace 注入到容器的环境变量中去,然后在容器中打印全部的环境变量来进行验证

使用fieldRef获取 POD 的基本信息,示例如下:

[root@k8s-master1 pod.yaml.d]# vim test-env-pod.yml
[root@k8s-master1 pod.yaml.d]# cat test-env-pod.yml
---
apiVersion: v1
kind: Pod
metadata:name: test-env-podnamespace: kube-system
spec:containers:- name: test-env-podimage: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:1.20.1env:- name: POD_NAME   #第一个环境变量的名字valueFrom:      #使用valueFrom方式设置fieldRef:    #关联一个字段metadata.name(元数据的字段)fieldPath: metadata.name  #这个字段从当前运行的pod详细信息查看- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: POD_IPvalueFrom:fieldRef:fieldPath: status.podIP这个podIP可以通过-o yaml查看

创建pod,进入pod查看配置的环境变量

[root@k8s-master1 pod.yaml.d]# kubectl apply -f test-env-pod.yml
[root@k8s-master1 pod.yaml.d]# kubectl get pod -n kube-system | grep test
test-env-pod                          1/1     Running   0          4m45s
[root@k8s-master1 pod.yaml.d]# kubectl exec -it test-env-pod -n kube-system /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@test-env-pod:/# echo $POD_NAME
test-env-pod
root@test-env-pod:/# echo $POD_NAMESPACE
kube-system
root@test-env-pod:/# echo $POD_IP       
10.244.1.9

Volume挂载

通过Downward API将 POD 的 Label、Annotation 等信息通过 Volume 挂载到容器的某个文件中去,然后在容器中打印出该文件的值来验证

操作如下:

[root@k8s-master1 pod.yaml.d]# vim test-volume-pod.yaml
[root@k8s-master1 pod.yaml.d]# cat test-volume-pod.yaml
---
apiVersion: v1
kind: Pod
metadata:name: test-volume-podnamespace: kube-systemlabels:k8s-app: test-volumenode-env: test
spec:containers:- name: test-volume-pod-containerimage: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:1.20.1volumeMounts:- name: podinfomountPath: /etc/podinfovolumes:- name: podinfodownwardAPI:items:- path: "labels"fieldRef:fieldPath: metadata.labels

创建pod,进入pod查看配置的环境变量

[root@k8s-master1 pod.yaml.d]# kubectl apply -f test-volume-pod.yaml 
pod/test-volume-pod created
[root@k8s-master1 pod.yaml.d]# kubectl get pod -n kube-system | grep test-volume-pod
test-volume-pod                       1/1     Running   0          32s
[root@k8s-master1 pod.yaml.d]# kubectl exec -it test-volume-pod -n kube-system /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@test-volume-pod:/# cat /etc/podinfo/labels 
k8s-app="test-volume"
node-env="test"root

在实际应用中,如果你的应用有获取 POD 的基本信息的需求,就可以利用Downward API来获取基本信息,然后编写一个启动脚本或者利用initContainer将 POD 的信息注入到容器中去,然后在自己的应用中就可以正常的处理相关逻辑了。

目前 Downward API 支持的字段(常用部分):

1. 使用 fieldRef 可以声明使用:
spec.nodeName - 宿主机名字
status.hostIP - 宿主机 IP
metadata.name - Pod 的名字
metadata.namespace - Pod 的 Namespace
status.podIP - Pod 的 IP
spec.serviceAccountName - Pod 的 Service Account 的名字
metadata.uid - Pod 的 UID
metadata.labels['<KEY>'] - 指定 <KEY> 的 Label 值
metadata.annotations['<KEY>'] - 指定 <KEY> 的 Annotation 值
metadata.labels - Pod 的所有 Label
metadata.annotations - Pod 的所有 Annotation

Secret、ConfigMap,以及 Downward API 这三种 Projected Volume 定义的信息,大多还可以通过环境变量的方式出现在容器里。但是,通过环境变量获取这些信息的方式,不具备自动更新的能力。一般情况下,建议使用 Volume 文件的方式获取这些信息(根据资源对象用途判断)。

4.4、ServiceAccount

ServiceAccount是一种 Kubernetes 资源,用于提供身份给 Pod。ServiceAccount 允许 Pod 访问 Kubernetes API 服务器,通常是为了进行 API 操作或与 Kubernetes 集群交互。ServiceAccount 通常与角色(Role)和角色绑定(RoleBinding)结合使用,以控制 Pod 访问 Kubernetes API 的权限。

使用场景

  • 为 Pod 提供访问 Kubernetes API 的权限。
  • 定义 Pod 访问集群资源的权限和方式。

这一部分先暂时做一个了解,后面会在用到的地方进行详细解释

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探索《黑神话·悟空》背后的AI技术支持:英伟达全景光线追踪技术、DLSS 3.5 与帧生成

引言 2023 年&#xff0c;游戏《黑神话悟空》以其震撼的视觉效果和深度沉浸的游戏体验&#xff0c;成为全球玩家热议的焦点。这款游戏在发布初期就取得了惊人的销量&#xff1a;预售阶段便突破 120 万套&#xff0c;而发售首日更是达到 450 万份的惊人成绩。这个现象级作品背后…

大模型微调课程及大模型应用开发课程介绍

大模型实验室是在学校现有的实验室建设基础上&#xff0c;依托行业标杆企业&#xff0c;聚焦行业大模型产业发展方向&#xff0c;建设一个产学研一体化的合作教学平台&#xff0c;形成“教与学紧密结合、理论与实践紧密结合&#xff0c;学校与企业紧密结合”的创新教育模式。大…

初识C++以及安装C++学习工具

C的发展史 C是由Bjarne Stroustrup在20世纪80年代初期于贝尔实验室开发的一种编程语言。它的设计初衷是作为C语言的一个超集&#xff0c;通过添加面向对象编程的特性来增强C语言。C支持多种编程范式&#xff0c;包括过程化编程、面向对象编程和泛型编程。 C的历史可以追溯到1…

[数据集][目标检测]道路积水检测数据集VOC+YOLO格式2699张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2699 标注数量(xml文件个数)&#xff1a;2699 标注数量(txt文件个数)&#xff1a;2699 标注…

python-逆序数(赛氪OJ)

[题目描述] 在一个排列中&#xff0c;如果一对数的前后位置与大小顺序相反&#xff0c;即前面的数大于后面的数&#xff0c;那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。比如一个元素个数为 4 的数列&#xff0c;其元素为 2,4,3,1&#xff0c;则 (2,…

深度优先搜索-放苹果

放苹果 http://noi.openjudge.cn/ch0205/666/ #include<bits/stdc.h> using namespace std;int dfs(int,int); //第一个赋值为1 其余为0 int a[11]{1},ans,n,m;int main(){ int k; cin>>k; for(int i1;i<k;i){ ans0; cin>>m>>n; dfs(m,1);//m个…

Windows C++控制台菜单库开发与源码展示

Windows C控制台菜单库 声明&#xff1a;演示视频&#xff1a;一、前言二、具体框架三、源码展示console_screen_set.hframeconsole_screen_frame_base.hconsole_screen_frame_char.hconsole_screen_frame_wchar_t.hconsole_screen_frame.h menuconsole_screen_menu_base.hcons…

入门 - Vue中使用axios原理分析及解决前端跨域问题

1. 什么是Axios&#xff1f; Axios&#xff08;ajax i/o system&#xff09;&#xff0c;是Vue创建者主推的请求发送方式&#xff0c;因其简单的配置与良好的性能被前端爱好者所喜爱。众所周知&#xff0c;在进行网页设计时经常需要从后端拿数据&#xff0c;在Web应用初期会将…

计算机网络之TCP序号,确认序号和报文传输时间

开篇提示 本篇适合于了解基础知识&#xff0c;进行扩展提高的使用&#xff0c;附带考研习题以及解析。 TCP序号和确认序号的区别 TCP首部中有序号和确认序号&#xff0c;他们都是4个字节&#xff08;4B&#xff09;&#xff0c;且在数据传输中有很重要的意义&#xff0c;那么两…

0x01 GlassFish 任意文件读取漏洞复现

参考文章&#xff1a; 应用服务器glassfish任意文件读取漏洞 - SecPulse.COM | 安全脉搏 fofa 搜索使用该服务器的网站 网络空间测绘&#xff0c;网络空间安全搜索引擎&#xff0c;网络空间搜索引擎&#xff0c;安全态势感知 - FOFA网络空间测绘系统 "glassfish"&…

用TensorFlow实现线性回归

说明 本文采用TensorFlow框架进行讲解&#xff0c;虽然之前的文章都采用mxnet&#xff0c;但是我发现tensorflow提供了免费的gpu可供使用&#xff0c;所以果断开始改为tensorflow&#xff0c;若要实现文章代码&#xff0c;可以使用colaboratory进行运行&#xff0c;当然&#…

外挂程序:增强点及辅助

1.关于前几篇介绍的外挂程序,SAP中的业务单据还是要区分具体的操作人员。如建立财务凭证,工号A,B,C使用相同的SAP账号,那就没办法知道是谁操作的了啊,所以sap的业务单据需要细分到具体人员的都要增强实现以下: 如生产工单: 具体的增强点: 2.辅助程序:SAP账号自动锁定功…

从新手到专家必读书籍:官方推荐.NET技术体系架构指南

前言 Microsoft 官方推荐了一系列有关 .NET 体系结构的指南&#xff0c;旨在帮助开发人员掌握最新的技术和最佳实践。这些资源覆盖了从微服务架构到云原生应用开发等多个主题&#xff0c;是开发高质量 .NET 应用程序不可或缺的参考资料。 通过这些指南&#xff0c;可以深入了…

瑞幸x《黑神话》周边秒空,联名营销真的是流量密码吗?

​8月19日&#xff0c;瑞幸上线了与国产3A游戏《黑神话&#xff1a;悟空》合作的联名活动&#xff0c;其中包括黑神话腾云美式咖啡及周边产品。很多人为了抢到联名的周边&#xff0c;一大早就在瑞幸卡点下单&#xff0c;更有一些网友早上6点多就在瑞幸门口“蹲点”&#xff0c;…

会话跟踪方案:Cookie Session Token

什么是会话技术&#xff1f; Cookie 以登录为例&#xff0c;用户在浏览器中将账号密码输入并勾选自动登录&#xff0c;浏览器发送请求&#xff0c;请求头中设置Cookie&#xff1a;userName:张三 ,password:1234aa &#xff0c;若登录成功&#xff0c;服务器将这个cookie保存…

河南萌新联赛2024第(六)场:郑州大学(补题ABCDFGIL)

文章目录 河南萌新联赛2024第&#xff08;六&#xff09;场&#xff1a;郑州大学A 装备二选一&#xff08;一&#xff09;简单介绍&#xff1a;思路&#xff1a;代码&#xff1a; B 百变吗喽简单介绍&#xff1a;思路&#xff1a;代码&#xff1a; C 16进制世界简单介绍&#x…

【时时三省】(C语言基础)指针进阶2

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 数组指针 是一种指针&#xff0d;是指向数组的指针 整型指针&#xff0d;是指向整形的指针 字符指针&#xff0d;是指向字符的指针 什么叫做数组指针 上面的整形指针跟字符指针只需要&am…

【鸿蒙学习】HarmonyOS应用开发者高级认证 - 一次开发,多端部署

一、学习目的 掌握鸿蒙的核心概念和端云一体化开发、数据、网络、媒体、并发、分布式、多设备协同等关键技术能力&#xff0c;具备独立设计和开发鸿蒙应用能力。 二、总体介绍 HarmonyOS 系统面向多终端提供了“一次开发&#xff0c;多端部署”&#xff08;后文中简称为“一…

日志审计-graylog ssh登录超过6次告警

Apt 设备通过UDP收集日志&#xff0c;在gray创建接收端口192.168.0.187:1514 1、ssh登录失败次数大于5次 ssh日志级别默认为INFO级别&#xff0c;通过系统rsyslog模块处理&#xff0c;日志默认存储在/var/log/auth.log。 将日志转发到graylog vim /etc/rsyslog.conf 文件末…

深入探讨SD NAND的SD模式与SPI模式初始化

在嵌入式系统和存储解决方案中&#xff0c;SD NAND的广泛应用是显而易见的。CS创世推出的SD NAND支持SD模式和SPI模式&#xff0c;这两种模式在功能和实现上各有优劣。在本文中&#xff0c;我们将深入探讨这两种模式的初始化过程&#xff0c;并比较它们在不同应用场景下的优劣&…