busybox-date.c调试

注释代码

/* vi: set sw=4 ts=4: */
/*
 * Mini date implementation for busybox
 *
 * by Matthew Grant <grantma@anathoth.gen.nz>
 *
 * iso-format handling added by Robert Griebl <griebl@gmx.de>
 * bugfixes and cleanup by Bernhard Reutner-Fischer
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/

/* This 'date' command supports only 2 time setting formats,
   all the GNU strftime stuff (its in libc, lets use it),
   setting time using UTC and displaying it, as well as
   an RFC 2822 compliant date output for shell scripting
   mail commands */

/* Input parsing code is always bulky - used heavy duty libc stuff as
   much as possible, missed out a lot of bounds checking */

//applet:IF_DATE(APPLET(date, BB_DIR_BIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_DATE) += date.o

//config:config DATE
//config:	bool "date"
//config:	default y
//config:	help
//config:	  date is used to set the system date or display the
//config:	  current time in the given format.
//config:
//config:config FEATURE_DATE_ISOFMT
//config:	bool "Enable ISO date format output (-I)"
//config:	default y
//config:	depends on DATE
//config:	help
//config:	  Enable option (-I) to output an ISO-8601 compliant
//config:	  date/time string.
//config:
//config:# defaults to "no": stat's nanosecond field is a bit non-portable
//config:config FEATURE_DATE_NANO
//config:	bool "Support %[num]N nanosecond format specifier"
//config:	default n
//config:	depends on DATE  # syscall(__NR_clock_gettime)
//config:	select PLATFORM_LINUX
//config:	help
//config:	  Support %[num]N format specifier. Adds ~250 bytes of code.
//config:
//config:config FEATURE_DATE_COMPAT
//config:	bool "Support weird 'date MMDDhhmm[[YY]YY][.ss]' format"
//config:	default y
//config:	depends on DATE
//config:	help
//config:	  System time can be set by 'date -s DATE' and simply 'date DATE',
//config:	  but formats of DATE string are different. 'date DATE' accepts
//config:	  a rather weird MMDDhhmm[[YY]YY][.ss] format with completely
//config:	  unnatural placement of year between minutes and seconds.
//config:	  date -s (and other commands like touch -d) use more sensible
//config:	  formats (for one, ISO format YYYY-MM-DD hh:mm:ss.ssssss).
//config:
//config:	  With this option off, 'date DATE' is 'date -s DATE' support
//config:	  the same format. With it on, 'date DATE' additionally supports
//config:	  MMDDhhmm[[YY]YY][.ss] format.

/* GNU coreutils 6.9 man page:
 * date [OPTION]... [+FORMAT]
 * date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
 * -d, --date=STRING
 *      display time described by STRING, not `now'
 * -f, --file=DATEFILE
 *      like --date once for each line of DATEFILE
 * -r, --reference=FILE
 *      display the last modification time of FILE
 * -R, --rfc-2822
 *      output date and time in RFC 2822 format.
 *      Example: Mon, 07 Aug 2006 12:34:56 -0600
 * --rfc-3339=TIMESPEC
 *      output date and time in RFC 3339 format.
 *      TIMESPEC='date', 'seconds', or 'ns'
 *      Date and time components are separated by a single space:
 *      2006-08-07 12:34:56-06:00
 * -s, --set=STRING
 *      set time described by STRING
 * -u, --utc, --universal
 *      print or set Coordinated Universal Time
 *
 * Busybox:
 * long options are not supported
 * -f is not supported
 * -I seems to roughly match --rfc-3339, but -I has _optional_ param
 *    (thus "-I seconds" doesn't work, only "-Iseconds"),
 *    and does not support -Ins
 * -D FMT is a bbox extension for _input_ conversion of -d DATE
 */

//usage:#define date_trivial_usage
//usage:       "[OPTIONS] [+FMT] [TIME]"
//usage:#define date_full_usage "\n\n"
//usage:       "Display time (using +FMT), or set time\n"
//usage:	IF_NOT_LONG_OPTS(
//usage:     "\n	[-s] TIME	Set time to TIME"
//usage:     "\n	-u		Work in UTC (don't convert to local time)"
//usage:     "\n	-R		Output RFC-2822 compliant date string"
//usage:	) IF_LONG_OPTS(
//usage:     "\n	[-s,--set] TIME	Set time to TIME"
//usage:     "\n	-u,--utc	Work in UTC (don't convert to local time)"
//usage:     "\n	-R,--rfc-2822	Output RFC-2822 compliant date string"
//usage:	)
//usage:	IF_FEATURE_DATE_ISOFMT(
//usage:     "\n	-I[SPEC]	Output ISO-8601 compliant date string"
//usage:     "\n			SPEC='date' (default) for date only,"
//usage:     "\n			'hours', 'minutes', or 'seconds' for date and"
//usage:     "\n			time to the indicated precision"
//usage:	)
//usage:	IF_NOT_LONG_OPTS(
//usage:     "\n	-r FILE		Display last modification time of FILE"
//usage:     "\n	-d TIME		Display TIME, not 'now'"
//usage:	) IF_LONG_OPTS(
//usage:     "\n	-r,--reference FILE	Display last modification time of FILE"
//usage:     "\n	-d,--date TIME	Display TIME, not 'now'"
//usage:	)
//usage:	IF_FEATURE_DATE_ISOFMT(
//usage:     "\n	-D FMT		Use FMT for -d TIME conversion"
//usage:	)
//usage:     "\n"
//usage:     "\nRecognized TIME formats:"
//usage:     "\n	hh:mm[:ss]"
//usage:     "\n	[YYYY.]MM.DD-hh:mm[:ss]"
//usage:     "\n	YYYY-MM-DD hh:mm[:ss]"
//usage:     "\n	[[[[[YY]YY]MM]DD]hh]mm[.ss]"
//usage:	IF_FEATURE_DATE_COMPAT(
//usage:     "\n	'date TIME' form accepts MMDDhhmm[[YY]YY][.ss] instead"
//usage:	)
//usage:
//usage:#define date_example_usage
//usage:       "$ date\n"
//usage:       "Wed Apr 12 18:52:41 MDT 2000\n"

#include "libbb.h"
#if ENABLE_FEATURE_DATE_NANO
# include <sys/syscall.h>
#endif

#include "hi_rtc_lib.h"

enum {
	OPT_RFC2822   = (1 << 0), /* R */
	OPT_SET       = (1 << 1), /* s */
	OPT_UTC       = (1 << 2), /* u */
	OPT_DATE      = (1 << 3), /* d */
	OPT_REFERENCE = (1 << 4), /* r */
	OPT_TIMESPEC  = (1 << 5) * ENABLE_FEATURE_DATE_ISOFMT, /* I */
	OPT_HINT      = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* D */
};

static void maybe_set_utc(int opt)
{
	if (opt & OPT_UTC)
		putenv((char*)"TZ=UTC0");
}

#if ENABLE_LONG_OPTS
static const char date_longopts[] ALIGN1 =
		"rfc-822\0"   No_argument       "R"
		"rfc-2822\0"  No_argument       "R"
		"set\0"       Required_argument "s"
		"utc\0"       No_argument       "u"
	/*	"universal\0" No_argument       "u" */
		"date\0"      Required_argument "d"
		"reference\0" Required_argument "r"
		;
#endif

int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int date_main(int argc UNUSED_PARAM, char **argv)
{
	struct timespec ts;
	struct tm tm_time;
	char buf_fmt_dt2str[64];
	unsigned opt;
	int ifmt = -1;
	char *date_str;
	char *fmt_dt2str;
	char *fmt_str2dt;
	char *filename;
	char *isofmt_arg = NULL;

	opt_complementary = "d--s:s--d"
		IF_FEATURE_DATE_ISOFMT(":R--I:I--R");
	IF_LONG_OPTS(applet_long_options = date_longopts;)
	opt = getopt32(argv, "Rs:ud:r:"
			IF_FEATURE_DATE_ISOFMT("I::D:"),
			&date_str, &date_str, &filename
			IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt));
	argv += optind;
	maybe_set_utc(opt);

	if (ENABLE_FEATURE_DATE_ISOFMT && (opt & OPT_TIMESPEC)) {
		ifmt = 0; /* default is date */
		if (isofmt_arg) {
			static const char isoformats[] ALIGN1 =
				"date\0""hours\0""minutes\0""seconds\0"; /* ns? */
			ifmt = index_in_substrings(isoformats, isofmt_arg);
			if (ifmt < 0)
				bb_show_usage();
		}
	}

	fmt_dt2str = NULL;
	if (argv[0] && argv[0][0] == '+') {
		fmt_dt2str = &argv[0][1]; /* skip over the '+' */
		argv++;
	}
	if (!(opt & (OPT_SET | OPT_DATE))) {
		opt |= OPT_SET;
		date_str = argv[0]; /* can be NULL */
		if (date_str) {
#if ENABLE_FEATURE_DATE_COMPAT
			int len = strspn(date_str, "0123456789");
			if (date_str[len] == '\0'
			 || (date_str[len] == '.'
			    && isdigit(date_str[len+1])
			    && isdigit(date_str[len+2])
			    && date_str[len+3] == '\0'
			    )
			) {
				/* Dreaded MMDDhhmm[[CC]YY][.ss] format!
				 * It does not match -d or -s format.
				 * Some users actually do use it.
				 */
				len -= 8;
				if (len < 0 || len > 4 || (len & 1))
					bb_error_msg_and_die(bb_msg_invalid_date, date_str);
				if (len != 0) { /* move YY or CCYY to front */
					char buf[4];
					memcpy(buf, date_str + 8, len);
					memmove(date_str + len, date_str, 8);
					memcpy(date_str, buf, len);
				}
			}
#endif
			argv++;
		}
	}
	if (*argv)
		bb_show_usage();

	/* Now we have parsed all the information except the date format
	 * which depends on whether the clock is being set or read */

	if (opt & OPT_REFERENCE) {
		struct stat statbuf;
		xstat(filename, &statbuf);
		ts.tv_sec = statbuf.st_mtime;
#if ENABLE_FEATURE_DATE_NANO
		ts.tv_nsec = statbuf.st_mtim.tv_nsec;
		/* Some toolchains use .st_mtimensec instead of st_mtim.tv_nsec.
		 * If you need #define _SVID_SOURCE 1 to enable st_mtim.tv_nsec,
		 * drop a mail to project mailing list please
		 */
#endif
	printf("##01\n");
	} else {
#if ENABLE_FEATURE_DATE_NANO
		/* libc has incredibly messy way of doing this,
		 * typically requiring -lrt. We just skip all this mess */
		syscall(__NR_clock_gettime, CLOCK_REALTIME, &ts);
#else
		time(&ts.tv_sec);
printf("##02\n");

#endif
	}

	/* 01 02这个地方会获取 当前秒数,定义如下time_t tv_sec; // seconds */

	printf("## 0x%x %d\n",ts.tv_sec,ts.tv_sec);

	localtime_r(&ts.tv_sec, &tm_time); // 应该是根据秒数获取时间结构体

	printf("## getNowYear: %d\n",tm_time.tm_year + 1900);
	

	// 如果date后面没有给时间字符串,或者说不用设置,那么就不更新tm_time。
	/* 如果给出了时间字符串,就更新tm_time结构体,需要设置时间就设置时间 */
	/* If date string is given, update tm_time, and maybe set date */
	if (date_str != NULL) {
		/* Zero out fields - take her back to midnight! */
		tm_time.tm_sec = 0;
		tm_time.tm_min = 0;
		tm_time.tm_hour = 0;
		printf("##03\n");

		/* Process any date input to UNIX time since 1 Jan 1970 */
		if (ENABLE_FEATURE_DATE_ISOFMT && (opt & OPT_HINT)) {
			if (strptime(date_str, fmt_str2dt, &tm_time) == NULL)
				bb_error_msg_and_die(bb_msg_invalid_date, date_str);
				printf("## 04\n");
		} else {
			parse_datestr(date_str, &tm_time);
			printf("##05\n");
			
		}

		printf("##getParseYear %d\n",tm_time.tm_year + 1900);

		/* Correct any day of week and day of year etc. fields */
		/* Be sure to recheck dst (but not if date is time_t format) */
		if (date_str[0] != '@')
			tm_time.tm_isdst = -1;

		printf("date_str:%s\n",date_str);


		// 这里设置时发现错误,并让程序退出。直接没有 返回值了。
		// 否则返回秒数,stime之后ts没有什么用了。后面是显示字符串部分了。
		// date_str只是作为错误提示参数传递进去了。
		ts.tv_sec = validate_tm_time(date_str, &tm_time);

		// 这里设置时间如果非法就返回了。 
		// validate_tm_time =》bb_error_msg_and_die
		printf("##051\n");

		maybe_set_utc(opt);
		printf("##052\n");

		/* if setting time, set it */
		if ((opt & OPT_SET) && stime(&ts.tv_sec) < 0) {
			bb_perror_msg("can't set date");
		}

		//
	}

	
	printf("##06\n");

	/* */
	/* Display output */

	/* Deal with format string */
	if (fmt_dt2str == NULL) {
		int i;
		printf("##07\n");
		fmt_dt2str = buf_fmt_dt2str;
		if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) {
			/* -I[SPEC]: 0:date 1:hours 2:minutes 3:seconds */
			strcpy(fmt_dt2str, "%Y-%m-%dT%H:%M:%S");
			i = 8 + 3 * ifmt;
			if (ifmt != 0) {
				/* TODO: if (ifmt==4) i += sprintf(&fmt_dt2str[i], ",%09u", nanoseconds); */
 format_utc:
				fmt_dt2str[i++] = '%';
				fmt_dt2str[i++] = (opt & OPT_UTC) ? 'Z' : 'z';
			}
			fmt_dt2str[i] = '\0';
		} else if (opt & OPT_RFC2822) {
			/* -R. undo busybox.c setlocale */
			if (ENABLE_LOCALE_SUPPORT)
				setlocale(LC_TIME, "C");
			strcpy(fmt_dt2str, "%a, %d %b %Y %H:%M:%S ");
			i = sizeof("%a, %d %b %Y %H:%M:%S ")-1;
			goto format_utc;
		} else { /* default case */
			fmt_dt2str = (char*)"%a %b %e %H:%M:%S %Z %Y";
		}
	}
#if ENABLE_FEATURE_DATE_NANO
	else {
		printf("##08\n");
		/* User-specified fmt_dt2str */
		/* Search for and process "%N" */
		char *p = fmt_dt2str;
		while ((p = strchr(p, '%')) != NULL) {
			int n, m;
			unsigned pres, scale;

			p++;
			if (*p == '%') {
				p++;
				continue;
			}
			n = strspn(p, "0123456789");
			if (p[n] != 'N') {
				p += n;
				continue;
			}
			/* We have "%[nnn]N" */
			p[-1] = '\0';
			p[n] = '\0';
			scale = 1;
			pres = 9;
			if (n) {
				pres = xatoi_positive(p);
				if (pres == 0)
					pres = 9;
				m = 9 - pres;
				while (--m >= 0)
					scale *= 10;
			}

			m = p - fmt_dt2str;
			p += n + 1;
			fmt_dt2str = xasprintf("%s%0*u%s", fmt_dt2str, pres, (unsigned)ts.tv_nsec / scale, p);
			p = fmt_dt2str + m;
		}
	}
#endif

#define date_buf bb_common_bufsiz1
	if (*fmt_dt2str == '\0') {
		/* With no format string, just print a blank line */
		date_buf[0] = '\0';
		printf("##09\n");
	} else {
		/* Handle special conversions */
		if (strncmp(fmt_dt2str, "%f", 2) == 0) {
			fmt_dt2str = (char*)"%Y.%m.%d-%H:%M:%S";
		}
		/* Generate output string */
		strftime(date_buf, sizeof(date_buf), fmt_dt2str, &tm_time);
		printf("##010\n");
	}
	puts(date_buf);

	return EXIT_SUCCESS;
}

代码追踪

##02
## 0x21e0a 138762
## getYear: 1970
##03
##05
date_str:2007-08-03 14:15:00
##051
##052
##06
##07
##010
Fri Aug  3 14:15:00 CST 2007

/mnt/bin # ./date -s "2047-08-03 14:15:00"  
##02
## 0x46b2cbd1 1186122705
## getNowYear: 2007
##03
##05
##getParseYear 2047
date_str:2047-08-03 14:15:00
date: invalid date '2047-08-03 14:15:00'

/mnt/bin # ./date 
##02
## 0x46b2d295 1186124437
## getNowYear: 2007
##06
##07
##010
Fri Aug  3 15:00:37 CST 2007

Pod 的 hostname 和 subdomain 字段 当前,创建 Pod 时其主机名(从 Pod 内部观察)取自 Pod 的 metadata.name 值。 Pod 规约中包含一个可选的 hostname 字段,可以用来指定一个不同的主机名。 当这个字段被设置时,它将优先于 Pod 的名字成为该 Pod 的主机名(同样是从 Pod 内部观察)。 举个例子,给定一个 spec.hostname 设置为 “my-host” 的 Pod, 该 Pod 的主机名将被设置为 “my-host”。 Pod 规约还有一个可选的 subdomain 字段,可以用来表明该 Pod 属于命名空间的一个子组。 例如,某 Pod 的 spec.hostname 设置为 “foo”,spec.subdomain 设置为 “bar”, 在命名空间 “my-namespace” 中,主机名称被设置成 “foo” 并且对应的完全限定域名(FQDN)为 “foo.bar.my-namespace.svc.cluster-domain.example”(还是从 Pod 内部观察)。 如果 Pod 所在的命名空间中存在一个无头 Service,其名称与子域相同, 则集群的 DNS 服务器还会为 Pod 的完全限定主机名返回 A 和/或 AAAA 记录。 示例: apiVersion: v1 kind: Service metadata: name: busybox-subdomain spec: selector: name: busybox clusterIP: None ports: - name: foo # 单个端口的 service 可以不指定 name port: 1234 --- apiVersion: v1 kind: Pod metadata: name: busybox1 labels: name: busybox spec: hostname: busybox-1 subdomain: busybox-subdomain containers: - image: busybox:1.28 command: - sleep - "3600" name: busybox --- apiVersion: v1 kind: Pod metadata: name: busybox2 labels: name: busybox spec: hostname: busybox-2 subdomain: busybox-subdomain containers: - image: busybox:1.28 command: - sleep - "3600" name: busybox 鉴于上述服务 “busybox-subdomain” 和将 spec.subdomain 设置为 “busybox-subdomain” 的 Pod, 第一个 Pod 将看到自己的 FQDN 为 “busybox-1.busybox-subdomain.my-namespace.svc.cluster-domain.example”。 DNS 会为此名字提供一个 A 记录和/或 AAAA 记录,指向该 Pod 的 IP。 Pod “busybox1” 和 “busybox2” 都将有自己的地址记录。 解释一下
最新发布
03-11
<think>好的,我现在需要帮助用户理解Kubernetes中Pod的hostname和subdomain字段。用户已经提供了一些官方文档中的解释和示例,但可能希望得到更清晰的解释,尤其是结合示例的情况。 首先,我需要确认用户的主要疑问是什么。他们可能想知道这两个字段的作用,如何配置,以及在实际应用中的效果。用户给出的示例中,创建了一个无头Service和两个Pod,这两个Pod设置了hostname和subdomain,用户可能想知道这样配置后DNS记录如何生成,以及Pod之间如何通过域名通信。 接下来,我需要回顾Kubernetes的相关知识。hostname字段允许覆盖Pod内部的主机名,而subdomain用于指定子域名,结合无头Service,可以为Pod生成特定的FQDN。当subdomain与无头Service同名时,Kubernetes的DNS会为每个Pod创建A记录,使得其他Pod可以通过这个FQDN访问它。 用户提供的示例中,Service是headless(clusterIP: None),这样每个Pod会有独立的DNS记录。需要解释为什么需要这样的配置,以及它带来的好处,比如直接访问每个Pod而不是通过负载均衡。 另外,用户可能对FQDN的结构有疑问,比如命名空间、集群域名等部分是如何组合的。需要分解FQDN的各个部分,确保用户理解每个部分的作用。 还需要注意用户可能的误区,比如subdomain必须与Service名称相同才能生效,或者hostname和subdomain的设置对Pod间通信的必要性。此外,要强调无头Service在此配置中的关键作用,以及标签选择器如何关联Service和Pod。 最后,应该总结使用场景,比如有状态应用需要每个Pod有唯一的主机名和固定的DNS记录,或者微服务中需要直接访问特定实例的情况。同时,可能提到最佳实践,比如如何合理设置hostname和subdomain,以及常见错误的避免方法,比如忘记创建对应的无头Service导致DNS记录不生成。</think>以下是对 Kubernetes Pod 的 `hostname` 和 `subdomain` 字段的完整解析: --- ### 一、核心概念对比 | 字段 | 作用范围 | 默认值 | 优先级 | DNS 记录生成条件 | |--------------------|---------------|--------------------|--------|------------------------------------| | `metadata.name` | Pod 名称 | 必填字段 | 最低 | 无(需通过 Service 暴露) | | `spec.hostname` | Pod 内部主机名 | 未设置时取 Pod 名称 | 最高 | 必须配合 `subdomain` 和无头 Service | | `spec.subdomain` | DNS 子域 | 空 | - | 必须存在同名无头 Service | --- ### 二、字段作用机制详解 #### 1. `hostname` 字段 - **覆盖逻辑**:当设置 `spec.hostname` 时,Pod 内部: ```bash # Pod 内执行 hostname # 输出将是 spec.hostname 的值(而非 metadata.name) ``` - **典型场景**:需要自定义 Pod 主机名(如模拟物理设备命名) #### 2. `subdomain` 字段 - **域名构建规则**: $$FQDN = \text{hostname}.\text{subdomain}.\text{namespace}.svc.\text{cluster-domain}$$ 例如:`busybox-1.busybox-subdomain.default.svc.cluster.local` - **必要条件**: - 必须存在同名无头 Service(`clusterIP: None`) - Service 的 `selector` 要能匹配 Pod 标签 --- ### 三、示例场景全解析 #### 给定配置: ```yaml # 无头 Service(关键点:clusterIP: None) apiVersion: v1 kind: Service metadata: name: busybox-subdomain # 名称必须与 Pod 的 subdomain 相同 spec: clusterIP: None selector: name: busybox # 匹配 Pod 的标签 ports: - port: 1234 ``` ```yaml # Pod 1 配置 apiVersion: v1 kind: Pod metadata: name: busybox1 # 实际 Pod 名称 labels: name: busybox # 匹配 Service 的 selector spec: hostname: busybox-1 # 覆盖内部主机名 subdomain: busybox-subdomain # 必须与 Service 同名 # ... ``` #### 产生的 DNS 记录: 1. **Pod 自身视角** - 主机名:`busybox-1`(由 `spec.hostname` 决定) - FQDN:`busybox-1.busybox-subdomain.default.svc.cluster.local` - 解析结果:指向该 Pod 的 IP 2. **集群内其他 Pod 访问方式** ```bash # 直接访问单个 Pod ping busybox-1.busybox-subdomain # 短格式(同命名空间) # 通过 Service 发现所有 Pod nslookup busybox-subdomain.default.svc.cluster.local # 返回所有匹配 Pod 的 IP(包括 busybox-1 和 busybox-2) ``` --- ### 四、关键验证步骤 1. **进入 Pod 验证主机名** ```bash kubectl exec -it busybox1 -- sh hostname # 应输出 "busybox-1" ``` 2. **检查 DNS 解析** ```bash kubectl exec -it busybox1 -- nslookup busybox-1.busybox-subdomain # 应返回该 Pod 的 IP kubectl exec -it busybox2 -- nslookup busybox-subdomain # 应返回两个 Pod 的 IP 列表 ``` 3. **查看 Service 关联** ```bash kubectl get endpoints busybox-subdomain -o yaml # 应包含两个 Pod 的 IP 和端口 ``` --- ### 五、设计意义与典型应用场景 1. **有状态应用** - 为每个 StatefulSet Pod 生成唯一 FQDN(如 MySQL 主从节点) - 示例:`mysql-0.db-cluster.ns.svc.cluster.local` 2. **直接 Pod 通信** - 绕过 Service 负载均衡,直连特定 Pod - 适用于需要定点通信的分布式系统(如 Consul、Etcd) 3. **遗留系统迁移** - 通过自定义 `hostname` 保持与原有系统主机名兼容 --- ### 六、常见问题排查 1. **DNS 解析失败** - 检查无头 Service 是否存在且名称与 `subdomain` 匹配 - 确认 Service 的 `selector` 能匹配 Pod 标签 - 验证 CoreDNS 是否正常运行 2. **hostname 未生效** - 确保 `spec.hostname` 符合 DNS 标签规范(小写字母、数字、减号) - 长度不超过 63 字符 3. **跨命名空间访问** - 必须使用全限定域名:`hostname.subdomain.namespace.svc.cluster.local` --- 通过合理使用 `hostname` 和 `subdomain`,可以实现精细化的 Pod 网络身份管理,为复杂应用场景提供灵活的命名解析支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值