在 k8s 中,Service 和 Pod 对象会创建 DNS 记录,用于 k8s 集群内部的域名解析。
Pod 域名注册
规则一:
每个 k8s pod 都会创建 DNS 记录: <pod_ip>.<namespace>.pod.<cluster-domain>。其中 为 pod ip 地址,但需要将 ip 地址中的 . 转换为 -。
比如 pod nginx-deployment-57d84f57dc-cpgkc 会创建 A 记录 10-244-3-8.default.pod.cluster.local
1 2 3
$ kubectl get pod -o wide nginx-deployment-57d84f57dc-cpgkc -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-57d84f57dc-cpgkc 1/1 Running 0 2m59s 10.244.3.8 vc-worker2 <none> <none>
规则二:
pod 如何同时指定了 spec.hostname 和 spec.subdomain,则会创建 A 记录:<hostname>.<subdomain>.<namespace>.svc.cluster.local,而不是 <pod_ip>.<namespace>.pod.<cluster-domain>。对于 Statefulset 类型的 pod 会自动设置 spec.hostname 为 pod 的名字,spec.subdomain 为 StatefulSet 的 spec.serviceName。
比如 pod nginx-statefulset-0 会创建 A 记录 nginx-statefulset-0.nginx.default.svc.cluster.local。
1 2 3
$ kubectl get pod nginx-statefulset-0 -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-statefulset-0 1/1 Running 0 62m 10.244.3.7 vc-worker2 <none> <none>
Deployment/DaemonSet 管理的 pod
使用 Deployment/DaemonSet 拉起的 pod,k8s 会创建额外的 DNS 记录:<pod_ip>.<deployment-name/daemonset-name>.<namespace>.svc.<cluster-domain>。
Service 域名注册
普通 Service
除了 headless service 之外的其他 service 会在 DNS 中生成 my-svc.my-namespace.svc.cluster-domain.example 的 A 或者 AAAA 记录,A 记录指向 ClusterIP。
headless service 会在 DNS 中生成 my-svc.my-namespace.svc.cluster-domain.example 的 A 或者 AAAA 记录,但指向的为 pod ip 地址集合。
可以针对所有类型的 Service 生效,用来配置多个外部的 ip 地址(该 ip 地址不是 k8s 分配),kube-proxy 会设置该 ip 地址的规则,确保在 k8s 集群内部访问该 ip 地址时,可以路由到后端的 pod。效果就跟访问普通的 ClusterIP 类型 Service 没有区别。
# The directive includes the prefix $deleteFromPrimitiveList and # followed by a '/' and the name of the list. # The values in this list will be deleted after applying the patch. $deleteFromPrimitiveList/finalizers: -b -c
最终得到结果:
1 2
finalizers: -a
setElementOrder
用于数组中的元素排序
简单数组排序例子
原始内容如下:
1 2 3 4
finalizers: -a -b -c
设置排序顺序:
1 2 3 4 5 6
# The directive includes the prefix $setElementOrder and # followed by a '/' and the name of the list. $setElementOrder/finalizers: -b -c -a
最终得到排序顺序:
1 2 3 4
finalizers: -b -c -a
map 类型数组排序例子
其中 patchMergeKey 为 name 字段
1 2 3 4 5 6 7
containers: -name:a ... -name:b ... -name:c ...
patch 指令的格式:
1 2 3 4 5
# each map in the list should only include the mergeKey $setElementOrder/containers: -name:b -name:c -name:a
最终获得结果:
1 2 3 4 5 6 7
containers: -name:b ... -name:c ... -name:a ...
retainKeys
用来清理 map 结构中的 key,并指定保留的 key 原始内容:
1 2 3
union: foo:a other:b
patch 内容:
1 2 3 4 5 6
union: retainKeys: -another -bar another:d bar:c
最终结果,可以看到 foo 和 other 因为不在保留列表中已经被清楚了。同时新增加了字段 another 和 bar,新增加的是字段是直接 patch 的结果,同时这两个字段也在保留的列表内。
1 2 3 4
union: # Field foo and other have been cleared w/o explicitly set them to null. another:d bar:c
strategic merge patch 在 k8s 中应用
kubectl patch 命令通过–type 参数提供了几种 patch 方法。
1
--type='strategic': The type of patch being provided; one of [json merge strategic]
// Runtime service defines the public APIs for remote container runtimes service RuntimeService { // Version returns the runtime name, runtime version, and runtime API version. rpc Version(VersionRequest) returns (VersionResponse) {}
// RunPodSandbox creates and starts a pod-level sandbox. Runtimes must ensure // the sandbox is in the ready state on success. rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}
// StopPodSandbox stops any running process that is part of the sandbox and // reclaims network resources (e.g., IP addresses) allocated to the sandbox. // If there are any running containers in the sandbox, they must be forcibly // terminated. // This call is idempotent, and must not return an error if all relevant // resources have already been reclaimed. kubelet will call StopPodSandbox // at least once before calling RemovePodSandbox. It will also attempt to // reclaim resources eagerly, as soon as a sandbox is not needed. Hence, // multiple StopPodSandbox calls are expected.
rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {} // RemovePodSandbox removes the sandbox. If there are any running containers // in the sandbox, they must be forcibly terminated and removed. // This call is idempotent, and must not return an error if the sandbox has // already been removed.
rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {} // PodSandboxStatus returns the status of the PodSandbox. If the PodSandbox is not // present, returns an error.
// ListPodSandbox returns a list of PodSandboxes. rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {}
// CreateContainer creates a new container in specified PodSandbox rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
// StartContainer starts the container. rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {}
// StopContainer stops a running container with a grace period (i.e., timeout). // This call is idempotent, and must not return an error if the container has // already been stopped. // The runtime must forcibly kill the container after the grace period is // reached. rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {}
// RemoveContainer removes the container. If the container is running, the // container must be forcibly removed. // This call is idempotent, and must not return an error if the container has // already been removed.
// ListContainers lists all containers by filters. rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}
// ContainerStatus returns status of the container. If the container is not // present, returns an error. rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}
// UpdateContainerResources updates ContainerConfig of the container. rpc UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {}
// ReopenContainerLog asks runtime to reopen the stdout/stderr log file // for the container. This is often called after the log file has been // rotated. If the container is not running, container runtime can choose // to either create a new log file and return nil, or return an error. // Once it returns error, new container log file MUST NOT be created. rpc ReopenContainerLog(ReopenContainerLogRequest) returns (ReopenContainerLogResponse) {}
// ExecSync runs a command in a container synchronously. rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {}
// Exec prepares a streaming endpoint to execute a command in the container. rpc Exec(ExecRequest) returns (ExecResponse) {}
// Attach prepares a streaming endpoint to attach to a running container. rpc Attach(AttachRequest) returns (AttachResponse) {}
// PortForward prepares a streaming endpoint to forward ports from a PodSandbox. rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}
// ContainerStats returns stats of the container. If the container does not // exist, the call returns an error. rpc ContainerStats(ContainerStatsRequest) returns (ContainerStatsResponse) {}
// ListContainerStats returns stats of all running containers. rpc ListContainerStats(ListContainerStatsRequest) returns (ListContainerStatsResponse) {}
// PodSandboxStats returns stats of the pod sandbox. If the pod sandbox does not // exist, the call returns an error. rpc PodSandboxStats(PodSandboxStatsRequest) returns (PodSandboxStatsResponse) {}
// ListPodSandboxStats returns stats of the pod sandboxes matching a filter. rpc ListPodSandboxStats(ListPodSandboxStatsRequest) returns (ListPodSandboxStatsResponse) {}
// UpdateRuntimeConfig updates the runtime configuration based on the given request. rpc UpdateRuntimeConfig(UpdateRuntimeConfigRequest) returns (UpdateRuntimeConfigResponse) {}
// Status returns the status of the runtime. rpc Status(StatusRequest) returns (StatusResponse) {} }
// ImageService defines the public APIs for managing images. service ImageService { // ListImages lists existing images. rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {}
// ImageStatus returns the status of the image. If the image is not // present, returns a response with ImageStatusResponse.Image set to // nil. rpc ImageStatus(ImageStatusRequest) returns (ImageStatusResponse) {}
// PullImage pulls an image with authentication config. rpc PullImage(PullImageRequest) returns (PullImageResponse) {}
// RemoveImage removes the image. // This call is idempotent, and must not return an error if the image has // already been removed. rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {}
// ImageFSInfo returns information of the filesystem that is used to store images. rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {} }
CRI CLI
CRI 自带了命令行工具 crictl。
Linux 下安装脚本:
1 2 3 4
VERSION="v1.26.0" # check latest version in /releases page wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin rm -f crictl-$VERSION-linux-amd64.tar.gz