From 27e7aace35bf02968f9e6603488f61afca3ecb36 Mon Sep 17 00:00:00 2001 From: Kwang Hun Date: Sun, 2 May 2021 20:04:04 +0900 Subject: [PATCH 1/9] Update managing-tls-in-a-cluster.md fix typo --- content/ko/docs/tasks/tls/managing-tls-in-a-cluster.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ko/docs/tasks/tls/managing-tls-in-a-cluster.md b/content/ko/docs/tasks/tls/managing-tls-in-a-cluster.md index f814db9919..d6f29e780d 100644 --- a/content/ko/docs/tasks/tls/managing-tls-in-a-cluster.md +++ b/content/ko/docs/tasks/tls/managing-tls-in-a-cluster.md @@ -88,7 +88,7 @@ EOF 여기서 `192.0.2.24`는 서비스의 클러스터 IP, `my-svc.my-namespace.svc.cluster.local`은 서비스의 DNS 이름, -`10.0.34.2`는 파드의 IP,`my-pod.my- namespace.pod.cluster.local`은 +`10.0.34.2`는 파드의 IP,`my-pod.my-namespace.pod.cluster.local`은 파드의 DNS 이름이다. 다음 출력이 표시되어야 한다. ``` From f174e793e981bf2a829932c5cd29d3d8d7c15c38 Mon Sep 17 00:00:00 2001 From: Jihoon Seo Date: Mon, 3 May 2021 18:44:25 +0900 Subject: [PATCH 2/9] [ko] Fix wrong custom heading ID --- content/ko/docs/concepts/services-networking/dns-pod-service.md | 2 +- .../reference/command-line-tools-reference/feature-gates.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ko/docs/concepts/services-networking/dns-pod-service.md b/content/ko/docs/concepts/services-networking/dns-pod-service.md index 006ffba99c..e3254d3ba8 100644 --- a/content/ko/docs/concepts/services-networking/dns-pod-service.md +++ b/content/ko/docs/concepts/services-networking/dns-pod-service.md @@ -194,7 +194,7 @@ A 또는 AAAA 레코드만 생성할 수 있다. (`default-subdomain.my-namespac 또한 서비스에서 `publishNotReadyAddresses=True` 를 설정하지 않았다면, 파드가 준비 상태가 되어야 레코드를 가질 수 있다. {{< /note >}} -### 파드의 setHostnameAsFQDN 필드 {# pod-sethostnameasfqdn-field} +### 파드의 setHostnameAsFQDN 필드 {#pod-sethostnameasfqdn-field} {{< feature-state for_k8s_version="v1.20" state="beta" >}} diff --git a/content/ko/docs/reference/command-line-tools-reference/feature-gates.md b/content/ko/docs/reference/command-line-tools-reference/feature-gates.md index a0f970d7c4..e8e1699803 100644 --- a/content/ko/docs/reference/command-line-tools-reference/feature-gates.md +++ b/content/ko/docs/reference/command-line-tools-reference/feature-gates.md @@ -785,7 +785,7 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 참고한다. - `SetHostnameAsFQDN`: 전체 주소 도메인 이름(FQDN)을 파드의 호스트 이름으로 설정하는 기능을 활성화한다. - [파드의 `setHostnameAsFQDN` 필드](/ko/docs/concepts/services-networking/dns-pod-service/#파드의-sethostnameasfqdn-필드)를 참고한다. + [파드의 `setHostnameAsFQDN` 필드](/ko/docs/concepts/services-networking/dns-pod-service/#pod-sethostnameasfqdn-field)를 참고한다. - `StartupProbe`: kubelet에서 [스타트업](/ko/docs/concepts/workloads/pods/pod-lifecycle/#언제-스타트업-프로브를-사용해야-하는가) 프로브를 활성화한다. From a80c2fc05f6178da77ad61ad6cfa16e57597b63e Mon Sep 17 00:00:00 2001 From: Jerry Park Date: Tue, 4 May 2021 18:35:22 +0900 Subject: [PATCH 3/9] [ko] Update outdated files in dev-1.21-ko.2 (p2) --- .../feature-gates.md | 99 +++++----- .../kube-proxy.md | 8 +- .../reference/using-api/client-libraries.md | 17 +- .../production-environment/tools/kops.md | 8 +- .../production-environment/tools/kubespray.md | 2 +- .../windows/intro-windows-in-kubernetes.md | 15 +- content/ko/docs/setup/release/notes.md | 171 +++++------------- 7 files changed, 118 insertions(+), 202 deletions(-) diff --git a/content/ko/docs/reference/command-line-tools-reference/feature-gates.md b/content/ko/docs/reference/command-line-tools-reference/feature-gates.md index a0f970d7c4..5f640165a5 100644 --- a/content/ko/docs/reference/command-line-tools-reference/feature-gates.md +++ b/content/ko/docs/reference/command-line-tools-reference/feature-gates.md @@ -53,7 +53,7 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `APIPriorityAndFairness` | `false` | 알파 | 1.17 | 1.19 | | `APIPriorityAndFairness` | `true` | 베타 | 1.20 | | | `APIResponseCompression` | `false` | 알파 | 1.7 | 1.15 | -| `APIResponseCompression` | `false` | 베타 | 1.16 | | +| `APIResponseCompression` | `true` | 베타 | 1.16 | | | `APIServerIdentity` | `false` | 알파 | 1.20 | | | `AllowInsecureBackendProxy` | `true` | 베타 | 1.17 | | | `AnyVolumeDataSource` | `false` | 알파 | 1.18 | | @@ -90,6 +90,7 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `CSIStorageCapacity` | `true` | 베타 | 1.21 | | | `CSIVolumeFSGroupPolicy` | `false` | 알파 | 1.19 | 1.19 | | `CSIVolumeFSGroupPolicy` | `true` | 베타 | 1.20 | | +| `CSIVolumeHealth` | `false` | 알파 | 1.21 | | | `ConfigurableFSGroupPolicy` | `false` | 알파 | 1.18 | 1.19 | | `ConfigurableFSGroupPolicy` | `true` | 베타 | 1.20 | | | `CronJobControllerV2` | `false` | 알파 | 1.20 | 1.20 | @@ -125,14 +126,13 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `HPAScaleToZero` | `false` | 알파 | 1.16 | | | `HugePageStorageMediumSize` | `false` | 알파 | 1.18 | 1.18 | | `HugePageStorageMediumSize` | `true` | 베타 | 1.19 | | +| `IndexedJob` | `false` | 알파 | 1.21 | | | `IngressClassNamespacedParams` | `false` | 알파 | 1.21 | | | `IPv6DualStack` | `false` | 알파 | 1.15 | 1.20 | | `IPv6DualStack` | `true` | 베타 | 1.21 | | | `KubeletCredentialProviders` | `false` | 알파 | 1.20 | | -| `KubeletPodResources` | `true` | 알파 | 1.13 | 1.14 | -| `KubeletPodResources` | `true` | 베타 | 1.15 | | | `LegacyNodeRoleBehavior` | `false` | 알파 | 1.16 | 1.18 | -| `LegacyNodeRoleBehavior` | `true` | True | 1.19 | | +| `LegacyNodeRoleBehavior` | `true` | 베타 | 1.19 | | | `LocalStorageCapacityIsolation` | `false` | 알파 | 1.7 | 1.9 | | `LocalStorageCapacityIsolation` | `true` | 베타 | 1.10 | | | `LocalStorageCapacityIsolationFSQuotaMonitoring` | `false` | 알파 | 1.15 | | @@ -158,8 +158,6 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `RotateKubeletServerCertificate` | `false` | 알파 | 1.7 | 1.11 | | `RotateKubeletServerCertificate` | `true` | 베타 | 1.12 | | | `RunAsGroup` | `true` | 베타 | 1.14 | | -| `SCTPSupport` | `false` | 알파 | 1.12 | 1.18 | -| `SCTPSupport` | `true` | 베타 | 1.19 | | | `ServerSideApply` | `false` | 알파 | 1.14 | 1.15 | | `ServerSideApply` | `true` | 베타 | 1.16 | | | `ServiceInternalTrafficPolicy` | `false` | 알파 | 1.21 | | @@ -181,12 +179,13 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `TopologyManager` | `true` | 베타 | 1.18 | | | `ValidateProxyRedirects` | `false` | 알파 | 1.12 | 1.13 | | `ValidateProxyRedirects` | `true` | 베타 | 1.14 | | +| `VolumeCapacityPriority` | `false` | 알파 | 1.21 | - | | `WarningHeaders` | `true` | 베타 | 1.19 | | | `WinDSR` | `false` | 알파 | 1.14 | | | `WinOverlay` | `false` | 알파 | 1.14 | 1.19 | | `WinOverlay` | `true` | 베타 | 1.20 | | | `WindowsEndpointSliceProxying` | `false` | 알파 | 1.19 | 1.20 | -| `WindowsEndpointSliceProxying` | `true` | beta | 1.21 | | +| `WindowsEndpointSliceProxying` | `true` | 베타 | 1.21 | | {{< /table >}} ### GA 또는 사용 중단된 기능을 위한 기능 게이트 @@ -225,7 +224,6 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `CSIPersistentVolume` | `false` | 알파 | 1.9 | 1.9 | | `CSIPersistentVolume` | `true` | 베타 | 1.10 | 1.12 | | `CSIPersistentVolume` | `true` | GA | 1.13 | - | -| `CSIVolumeHealth` | `false` | 알파 | 1.21 | - | | `CustomPodDNS` | `false` | 알파 | 1.9 | 1.9 | | `CustomPodDNS` | `true` | 베타| 1.10 | 1.13 | | `CustomPodDNS` | `true` | GA | 1.14 | - | @@ -258,9 +256,9 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `EnableEquivalenceClassCache` | - | 사용중단 | 1.15 | - | | `EndpointSlice` | `false` | 알파 | 1.16 | 1.16 | | `EndpointSlice` | `false` | 베타 | 1.17 | 1.17 | -| `EndpointSlice` | `true` | 베타 | 1.18 | 1.21 | +| `EndpointSlice` | `true` | 베타 | 1.18 | 1.20 | | `EndpointSlice` | `true` | GA | 1.21 | - | -| `EndpointSliceNodeName` | `false` | 알파 | 1.20 | 1.21 | +| `EndpointSliceNodeName` | `false` | 알파 | 1.20 | 1.20 | | `EndpointSliceNodeName` | `true` | GA | 1.21 | - | | `ExperimentalCriticalPodAnnotation` | `false` | 알파 | 1.5 | 1.12 | | `ExperimentalCriticalPodAnnotation` | `false` | 사용중단 | 1.13 | - | @@ -278,7 +276,6 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `ImmutableEphemeralVolumes` | `false` | 알파 | 1.18 | 1.18 | | `ImmutableEphemeralVolumes` | `true` | 베타 | 1.19 | 1.20 | | `ImmutableEphemeralVolumes` | `true` | GA | 1.21 | | -| `IndexedJob` | `false` | 알파 | 1.21 | | | `Initializers` | `false` | 알파 | 1.7 | 1.13 | | `Initializers` | - | 사용중단 | 1.14 | - | | `KubeletConfigFile` | `false` | 알파 | 1.8 | 1.9 | @@ -315,6 +312,7 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `PodShareProcessNamespace` | `true` | 베타 | 1.12 | 1.16 | | `PodShareProcessNamespace` | `true` | GA | 1.17 | - | | `RequestManagement` | `false` | 알파 | 1.15 | 1.16 | +| `RequestManagement` | - | 사용중단 | 1.17 | - | | `ResourceLimitsPriorityFunction` | `false` | 알파 | 1.9 | 1.18 | | `ResourceLimitsPriorityFunction` | - | 사용중단 | 1.19 | - | | `ResourceQuotaScopeSelectors` | `false` | 알파 | 1.11 | 1.11 | @@ -338,7 +336,7 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `ServiceAccountIssuerDiscovery` | `true` | 베타 | 1.20 | 1.20 | | `ServiceAccountIssuerDiscovery` | `true` | GA | 1.21 | - | | `ServiceAppProtocol` | `false` | 알파 | 1.18 | 1.18 | -| `ServiceAppProtocol` | `true` | 베타 | 1.19 | | +| `ServiceAppProtocol` | `true` | 베타 | 1.19 | 1.19 | | `ServiceAppProtocol` | `true` | GA | 1.20 | - | | `ServiceLoadBalancerFinalizer` | `false` | 알파 | 1.15 | 1.15 | | `ServiceLoadBalancerFinalizer` | `true` | 베타 | 1.16 | 1.16 | @@ -350,7 +348,7 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `StorageObjectInUseProtection` | `true` | GA | 1.11 | - | | `StreamingProxyRedirects` | `false` | 베타 | 1.5 | 1.5 | | `StreamingProxyRedirects` | `true` | 베타 | 1.6 | 1.18 | -| `StreamingProxyRedirects` | - | 사용중단| 1.19 | - | +| `StreamingProxyRedirects` | - | GA | 1.19 | - | | `SupportIPVSProxyMode` | `false` | 알파 | 1.8 | 1.8 | | `SupportIPVSProxyMode` | `false` | 베타 | 1.9 | 1.9 | | `SupportIPVSProxyMode` | `true` | 베타 | 1.10 | 1.10 | @@ -376,15 +374,15 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 | `TokenRequestProjection` | `true` | 베타 | 1.12 | 1.19 | | `TokenRequestProjection` | `true` | GA | 1.20 | - | | `VolumeCapacityPriority` | `false` | 알파 | 1.21 | - | -| `VolumeSnapshotDataSource` | `false` | 알파 | 1.12 | 1.16 | -| `VolumeSnapshotDataSource` | `true` | 베타 | 1.17 | 1.19 | -| `VolumeSnapshotDataSource` | `true` | GA | 1.20 | - | | `VolumePVCDataSource` | `false` | 알파 | 1.15 | 1.15 | | `VolumePVCDataSource` | `true` | 베타 | 1.16 | 1.17 | | `VolumePVCDataSource` | `true` | GA | 1.18 | - | | `VolumeScheduling` | `false` | 알파 | 1.9 | 1.9 | | `VolumeScheduling` | `true` | 베타 | 1.10 | 1.12 | | `VolumeScheduling` | `true` | GA | 1.13 | - | +| `VolumeSnapshotDataSource` | `false` | 알파 | 1.12 | 1.16 | +| `VolumeSnapshotDataSource` | `true` | 베타 | 1.17 | 1.19 | +| `VolumeSnapshotDataSource` | `true` | GA | 1.20 | - | | `VolumeSubpath` | `true` | GA | 1.10 | - | | `VolumeSubpathEnvExpansion` | `false` | 알파 | 1.14 | 1.14 | | `VolumeSubpathEnvExpansion` | `true` | 베타 | 1.15 | 1.16 | @@ -451,7 +449,7 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 - `APIServerIdentity`: 클러스터의 각 API 서버에 ID를 할당한다. - `Accelerators`: 도커 사용 시 Nvidia GPU 지원 활성화한다. - `AdvancedAuditing`: [고급 감사](/docs/tasks/debug-application-cluster/audit/#advanced-audit) 기능을 활성화한다. -- `AffinityInAnnotations`(*사용 중단됨*): [파드 어피니티 또는 안티-어피니티](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity) +- `AffinityInAnnotations`: [파드 어피니티 또는 안티-어피니티](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity) 설정을 활성화한다. - `AllowExtTrafficLocalEndpoints`: 서비스가 외부 요청을 노드의 로컬 엔드포인트로 라우팅할 수 있도록 한다. - `AllowInsecureBackendProxy`: 사용자가 파드 로그 요청에서 kubelet의 @@ -477,8 +475,8 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 확인한다. - `CPUManager`: 컨테이너 수준의 CPU 어피니티 지원을 활성화한다. [CPU 관리 정책](/docs/tasks/administer-cluster/cpu-management-policies/)을 참고한다. -- `CRIContainerLogRotation`: cri 컨테이너 런타임에 컨테이너 로그 로테이션을 활성화한다. 로그 파일 사이즈 기본값은 10MB이며, -컨테이너 당 최대 로그 파일 수 기본값은 5이다. 이 값은 kubelet 환경설정으로 변경할 수 있다. +- `CRIContainerLogRotation`: cri 컨테이너 런타임에 컨테이너 로그 로테이션을 활성화한다. 로그 파일 사이즈 기본값은 10MB이며, +컨테이너 당 최대 로그 파일 수 기본값은 5이다. 이 값은 kubelet 환경설정으로 변경할 수 있다. 더 자세한 내용은 [노드 레벨에서의 로깅](/ko/docs/concepts/cluster-administration/logging/#노드-레벨에서의-로깅)을 참고한다. - `CSIBlockVolume`: 외부 CSI 볼륨 드라이버가 블록 스토리지를 지원할 수 있게 한다. 자세한 내용은 [`csi` 원시 블록 볼륨 지원](/ko/docs/concepts/storage/volumes/#csi-원시-raw-블록-볼륨-지원) @@ -592,18 +590,18 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 hugepages 사용을 활성화한다. - `DryRun`: 서버 측의 [dry run](/docs/reference/using-api/api-concepts/#dry-run) 요청을 요청을 활성화하여 커밋하지 않고 유효성 검사, 병합 및 변화를 테스트할 수 있다. -- `DynamicAuditing`(*사용 중단됨*): v1.19 이전의 버전에서 동적 감사를 활성화하는 데 사용된다. +- `DynamicAuditing`: v1.19 이전의 버전에서 동적 감사를 활성화하는 데 사용된다. - `DynamicKubeletConfig`: kubelet의 동적 구성을 활성화한다. [kubelet 재구성](/docs/tasks/administer-cluster/reconfigure-kubelet/)을 참고한다. - `DynamicProvisioningScheduling`: 볼륨 토폴로지를 인식하고 PV 프로비저닝을 처리하도록 기본 스케줄러를 확장한다. 이 기능은 v1.12의 `VolumeScheduling` 기능으로 대체되었다. -- `DynamicVolumeProvisioning`(*사용 중단됨*): 파드에 퍼시스턴트 볼륨의 +- `DynamicVolumeProvisioning`: 파드에 퍼시스턴트 볼륨의 [동적 프로비저닝](/ko/docs/concepts/storage/dynamic-provisioning/)을 활성화한다. - `EfficientWatchResumption`: 스토리지에서 생성된 북마크(진행 알림) 이벤트를 사용자에게 전달할 수 있다. 이것은 감시 작업에만 적용된다. -- `EnableAggregatedDiscoveryTimeout` (*사용 중단됨*): 수집된 검색 호출에서 5초 +- `EnableAggregatedDiscoveryTimeout`: 수집된 검색 호출에서 5초 시간 초과를 활성화한다. - `EnableEquivalenceClassCache`: 스케줄러가 파드를 스케줄링할 때 노드의 동등성을 캐시할 수 있게 한다. @@ -661,11 +659,13 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 기능을 활성화한다. - `ImmutableEphemeralVolumes`: 안정성과 성능 향상을 위해 개별 시크릿(Secret)과 컨피그맵(ConfigMap)을 변경할 수 없는(immutable) 것으로 표시할 수 있다. -- `IndexedJob`: [잡](/ko/docs/concepts/workloads/controllers/job/) 컨트롤러가 +- `IndexedJob`: [잡](/ko/docs/concepts/workloads/controllers/job/) 컨트롤러가 완료 횟수를 기반으로 파드 완료를 관리할 수 있도록 한다. -- `IngressClassNamespacedParams`: `IngressClass` 리소스가 네임스페이스 범위로 - 한정된 파라미터를 이용할 수 있도록 한다. 이 기능은 `IngressClass.spec.parameters` 에 +- `IngressClassNamespacedParams`: `IngressClass` 리소스가 네임스페이스 범위로 + 한정된 파라미터를 이용할 수 있도록 한다. 이 기능은 `IngressClass.spec.parameters` 에 `Scope` 와 `Namespace` 2개의 필드를 추가한다. +- `Initializers`: Initializers 어드미션 플러그인을 사용하여 오브젝트 생성의 + 비동기 조정을 허용한다. - `IPv6DualStack`: IPv6을 위한 [이중 스택](/ko/docs/concepts/services-networking/dual-stack/) 기능을 활성화한다. - `KubeletConfigFile`: 구성 파일을 사용하여 지정된 파일에서 @@ -679,12 +679,12 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 [장치 모니터링 지원](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/606-compute-device-assignment/README.md)을 참고한다. - `KubeletPodResourcesGetAllocatable`: kubelet의 파드 리소스 `GetAllocatableResources` 기능을 활성화한다. - 이 API는 클라이언트가 노드의 여유 컴퓨팅 자원을 잘 파악할 수 있도록, 할당 가능 자원에 대한 정보를 + 이 API는 클라이언트가 노드의 여유 컴퓨팅 자원을 잘 파악할 수 있도록, 할당 가능 자원에 대한 정보를 [자원 할당 보고](/ko/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/#장치-플러그인-리소스-모니터링)한다. - `LegacyNodeRoleBehavior`: 비활성화되면, 서비스 로드 밸런서 및 노드 중단의 레거시 동작은 `NodeDisruptionExclusion` 과 `ServiceNodeExclusion` 에 의해 제공된 기능별 레이블을 대신하여 `node-role.kubernetes.io/master` 레이블을 무시한다. -- `LocalStorageCapacityIsolation`: +- `LocalStorageCapacityIsolation`: [로컬 임시 스토리지](/ko/docs/concepts/configuration/manage-resources-containers/)와 [emptyDir 볼륨](/ko/docs/concepts/storage/volumes/#emptydir)의 `sizeLimit` 속성을 사용할 수 있게 한다. @@ -695,15 +695,14 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 프로젝트 쿼터를 사용하여 [emptyDir 볼륨](/ko/docs/concepts/storage/volumes/#emptydir) 스토리지 사용을 모니터링하여 성능과 정확성을 향상시킨다. -- `LogarithmicScaleDown`: 컨트롤러 스케일 다운 시에 파드 타임스탬프를 로그 스케일로 버켓화하여 +- `LogarithmicScaleDown`: 컨트롤러 스케일 다운 시에 파드 타임스탬프를 로그 스케일로 버켓화하여 축출할 파드를 반-랜덤하게 선택하는 기법을 활성화한다. - `MixedProtocolLBService`: 동일한 로드밸런서 유형 서비스 인스턴스에서 다른 프로토콜 사용을 활성화한다. -- `MountContainers` (*사용 중단됨*): 호스트의 유틸리티 컨테이너를 볼륨 마운터로 - 사용할 수 있다. +- `MountContainers`: 호스트의 유틸리티 컨테이너를 볼륨 마운터로 사용할 수 있다. - `MountPropagation`: 한 컨테이너에서 다른 컨테이너 또는 파드로 마운트된 볼륨을 공유할 수 있다. 자세한 내용은 [마운트 전파(propagation)](/ko/docs/concepts/storage/volumes/#마운트-전파-propagation)을 참고한다. -- `NamespaceDefaultLabelName`: API 서버로 하여금 모든 네임스페이스에 대해 변경할 수 없는 (immutable) +- `NamespaceDefaultLabelName`: API 서버로 하여금 모든 네임스페이스에 대해 변경할 수 없는 (immutable) {{< glossary_tooltip text="레이블" term_id="label" >}} `kubernetes.io/metadata.name`을 설정하도록 한다. (네임스페이스의 이름도 변경 불가) - `NetworkPolicyEndPort`: 네트워크폴리시(NetworkPolicy) 오브젝트에서 단일 포트를 지정하는 것 대신에 포트 범위를 지정할 수 있도록, `endPort` 필드의 사용을 활성화한다. - `NodeDisruptionExclusion`: 영역(zone) 장애 시 노드가 제외되지 않도록 노드 레이블 `node.kubernetes.io/exclude-disruption` @@ -712,12 +711,12 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 - `NonPreemptingPriority`: 프라이어리티클래스(PriorityClass)와 파드에 `preemptionPolicy` 필드를 활성화한다. - `PVCProtection`: 파드에서 사용 중일 때 퍼시스턴트볼륨클레임(PVC)이 삭제되지 않도록 한다. -- `PodDeletionCost`: 레플리카셋 다운스케일 시 삭제될 파드의 우선순위를 사용자가 조절할 수 있도록, +- `PodDeletionCost`: 레플리카셋 다운스케일 시 삭제될 파드의 우선순위를 사용자가 조절할 수 있도록, [파드 삭제 비용](/ko/docs/concepts/workloads/controllers/replicaset/#파드-삭제-비용) 기능을 활성화한다. - `PersistentLocalVolumes`: 파드에서 `local` 볼륨 유형의 사용을 활성화한다. `local` 볼륨을 요청하는 경우 파드 어피니티를 지정해야 한다. - `PodDisruptionBudget`: [PodDisruptionBudget](/docs/tasks/run-application/configure-pdb/) 기능을 활성화한다. -- `PodAffinityNamespaceSelector`: [파드 어피니티 네임스페이스 셀렉터](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#네임스페이스-셀렉터) 기능과 +- `PodAffinityNamespaceSelector`: [파드 어피니티 네임스페이스 셀렉터](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#네임스페이스-셀렉터) 기능과 [CrossNamespacePodAffinity](/ko/docs/concepts/policy/resource-quotas/#네임스페이스-간-파드-어피니티-쿼터) 쿼터 범위 기능을 활성화한다. - `PodOverhead`: 파드 오버헤드를 판단하기 위해 [파드오버헤드(PodOverhead)](/ko/docs/concepts/scheduling-eviction/pod-overhead/) 기능을 활성화한다. @@ -729,8 +728,8 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 - `PodShareProcessNamespace`: 파드에서 실행되는 컨테이너 간에 단일 프로세스 네임스페이스를 공유하기 위해 파드에서 `shareProcessNamespace` 설정을 활성화한다. 자세한 내용은 [파드의 컨테이너 간 프로세스 네임스페이스 공유](/docs/tasks/configure-pod-container/share-process-namespace/)에서 확인할 수 있다. -- `ProbeTerminationGracePeriod`: 파드의 [프로브-수준 - `terminationGracePeriodSeconds` 설정하기](/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#probe-level-terminationgraceperiodseconds) 기능을 활성화한다. +- `ProbeTerminationGracePeriod`: 파드의 [프로브-수준 + `terminationGracePeriodSeconds` 설정하기](/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#probe-level-terminationgraceperiodseconds) 기능을 활성화한다. 더 자세한 사항은 [기능개선 제안](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2238-liveness-probe-grace-period)을 참고한다. - `ProcMountType`: SecurityContext의 `procMount` 필드를 설정하여 컨테이너의 proc 타입의 마운트를 제어할 수 있다. @@ -742,7 +741,9 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 응답에서 남은 항목 수를 표시하도록 허용한다. - `RemoveSelfLink`: ObjectMeta 및 ListMeta에서 `selfLink` 를 사용하지 않고 제거한다. -- `ResourceLimitsPriorityFunction` (*사용 중단됨*): 입력 파드의 CPU 및 메모리 한도 중 +- `RequestManagement`: 각 API 서버에서 우선 순위 및 공정성으로 요청 동시성을 + 관리할 수 있다. 1.17 이후 `APIPriorityAndFairness` 에서 사용 중단되었다. +- `ResourceLimitsPriorityFunction`: 입력 파드의 CPU 및 메모리 한도 중 하나 이상을 만족하는 노드에 가능한 최저 점수 1을 할당하는 스케줄러 우선 순위 기능을 활성화한다. 의도는 동일한 점수를 가진 노드 사이의 관계를 끊는 것이다. @@ -770,11 +771,11 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 JWKS URL)를 활성화한다. 자세한 내용은 [파드의 서비스 어카운트 구성](/docs/tasks/configure-pod-container/configure-service-account/#service-account-issuer-discovery)을 참고한다. -- `ServiceAppProtocol`: 서비스와 엔드포인트에서 `AppProtocol` 필드를 활성화한다. -- `ServiceInternalTrafficPolicy`: 서비스에서 `InternalTrafficPolicy` 필드를 활성화한다. -- `ServiceLBNodePortControl`: 서비스에서`spec.allocateLoadBalancerNodePorts` 필드를 - 활성화한다. -- `ServiceLoadBalancerClass`: 서비스에서 `LoadBalancerClass` 필드를 활성화한다. 자세한 내용은 [로드밸런서 구현체의 종류 확인하기](/ko/docs/concepts/services-networking/service/#load-balancer-class)를 참고한다. +- `ServiceAppProtocol`: 서비스와 엔드포인트에서 `appProtocol` 필드를 활성화한다. +- `ServiceInternalTrafficPolicy`: 서비스에서 `internalTrafficPolicy` 필드를 활성화한다. +- `ServiceLBNodePortControl`: 서비스에서 `allocateLoadBalancerNodePorts` 필드를 활성화한다. +- `ServiceLoadBalancerClass`: 서비스에서 `loadBalancerClass` 필드를 활성화한다. 자세한 내용은 + [로드밸런서 구현체의 종류 확인하기](/ko/docs/concepts/services-networking/service/#load-balancer-class)를 참고한다. - `ServiceLoadBalancerFinalizer`: 서비스 로드 밸런서에 대한 Finalizer 보호를 활성화한다. - `ServiceNodeExclusion`: 클라우드 제공자가 생성한 로드 밸런서에서 노드를 제외할 수 있다. "`node.kubernetes.io/exclude-from-external-load-balancers`"로 @@ -800,14 +801,14 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 스트리밍 요청의 예로는 `exec`, `attach` 및 `port-forward` 요청이 있다. - `SupportIPVSProxyMode`: IPVS를 사용하여 클러스터 내 서비스 로드 밸런싱을 제공한다. 자세한 내용은 [서비스 프록시](/ko/docs/concepts/services-networking/service/#가상-ip와-서비스-프록시)를 참고한다. -- `SupportPodPidsLimit`: 파드의 PID 제한을 지원한다. - `SupportNodePidsLimit`: 노드에서 PID 제한 지원을 활성화한다. `--system-reserved` 및 `--kube-reserved` 옵션의 `pid=` 파라미터를 지정하여 지정된 수의 프로세스 ID가 시스템 전체와 각각 쿠버네티스 시스템 데몬에 대해 예약되도록 할 수 있다. -- `SuspendJob`: 잡 중지/재시작 기능을 활성화한다. - 자세한 내용은 [잡 문서](/ko/docs/concepts/workloads/controllers/job/)를 +- `SupportPodPidsLimit`: 파드의 PID 제한에 대한 지원을 활성화한다. +- `SuspendJob`: 잡 중지/재시작 기능을 활성화한다. + 자세한 내용은 [잡 문서](/ko/docs/concepts/workloads/controllers/job/)를 참고한다. - `Sysctls`: 각 파드에 설정할 수 있는 네임스페이스 커널 파라미터(sysctl)를 지원한다. 자세한 내용은 @@ -824,14 +825,17 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 - `TokenRequest`: 서비스 어카운트 리소스에서 `TokenRequest` 엔드포인트를 활성화한다. - `TokenRequestProjection`: [`projected` 볼륨](/ko/docs/concepts/storage/volumes/#projected)을 통해 서비스 어카운트 토큰을 파드에 주입할 수 있다. -- `TopologyAwareHints`: 엔드포인트슬라이스(EndpointSlices)에서 토폴로지 힌트 기반 - 토폴로지-어웨어 라우팅을 활성화한다. 자세한 내용은 +- `TopologyAwareHints`: 엔드포인트슬라이스(EndpointSlices)에서 토폴로지 힌트 기반 + 토폴로지-어웨어 라우팅을 활성화한다. 자세한 내용은 [토폴로지 어웨어 힌트](/docs/concepts/services-networking/topology-aware-hints/) 를 참고한다. - `TopologyManager`: 쿠버네티스의 다른 컴포넌트에 대한 세분화된 하드웨어 리소스 할당을 조정하는 메커니즘을 활성화한다. [노드의 토폴로지 관리 정책 제어](/docs/tasks/administer-cluster/topology-manager/)를 참고한다. -- `VolumeCapacityPriority`: 가용 PV 용량을 기반으로 +- `ValidateProxyRedirects`: 이 플래그는 API 서버가 동일한 호스트로만 리디렉션되는가를 + 확인해야 하는지 여부를 제어한다. `StreamingProxyRedirects` + 플래그가 활성화된 경우에만 사용된다. +- `VolumeCapacityPriority`: 가용 PV 용량을 기반으로 여러 토폴로지에 있는 노드들의 우선순위를 정하는 기능을 활성화한다. - `VolumePVCDataSource`: 기존 PVC를 데이터 소스로 지정하는 기능을 지원한다. - `VolumeScheduling`: 볼륨 토폴로지 인식 스케줄링을 활성화하고 @@ -839,6 +843,7 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면, 기능 `PersistentLocalVolumes` 기능 게이트와 함께 사용될 때 [`local`](/ko/docs/concepts/storage/volumes/#local) 볼륨 유형을 사용할 수 있다. - `VolumeSnapshotDataSource`: 볼륨 스냅샷 데이터 소스 지원을 활성화한다. +- `VolumeSubpath`: 컨테이너에 볼륨의 하위 경로(subpath)를 마운트할 수 있다. - `VolumeSubpathEnvExpansion`: 환경 변수를 `subPath`로 확장하기 위해 `subPathExpr` 필드를 활성화한다. - `WarningHeaders`: API 응답에서 경고 헤더를 보낼 수 있다. diff --git a/content/ko/docs/reference/command-line-tools-reference/kube-proxy.md b/content/ko/docs/reference/command-line-tools-reference/kube-proxy.md index e4c790c491..bd930180cd 100644 --- a/content/ko/docs/reference/command-line-tools-reference/kube-proxy.md +++ b/content/ko/docs/reference/command-line-tools-reference/kube-proxy.md @@ -5,6 +5,7 @@ weight: 30 auto_generated: true --- + +![익스텐션 포인트와 컨트롤 플레인](/ko/docs/concepts/extend-kubernetes/control-plane.png) ## 익스텐션 포인트 이 다이어그램은 쿠버네티스 시스템의 익스텐션 포인트를 보여준다. - - +![익스텐션 포인트](/docs/concepts/extend-kubernetes/extension-points.png) + 1. 사용자는 종종 `kubectl`을 사용하여 쿠버네티스 API와 상호 작용한다. [Kubectl 플러그인](/ko/docs/tasks/extend-kubectl/kubectl-plugins/)은 kubectl 바이너리를 확장한다. 개별 사용자의 로컬 환경에만 영향을 미치므로 사이트 전체 정책을 적용할 수는 없다. 2. apiserver는 모든 요청을 처리한다. apiserver의 여러 유형의 익스텐션 포인트는 요청을 인증하거나, 콘텐츠를 기반으로 요청을 차단하거나, 콘텐츠를 편집하고, 삭제 처리를 허용한다. 이 내용은 [API 접근 익스텐션](#api-접근-익스텐션) 섹션에 설명되어 있다. 3. apiserver는 다양한 종류의 *리소스* 를 제공한다. `pods`와 같은 *빌트인 리소스 종류* 는 쿠버네티스 프로젝트에 의해 정의되며 변경할 수 없다. 직접 정의한 리소스를 추가할 수도 있고, [커스텀 리소스](#사용자-정의-유형) 섹션에 설명된 대로 *커스텀 리소스* 라고 부르는 다른 프로젝트에서 정의한 리소스를 추가할 수도 있다. 커스텀 리소스는 종종 API 접근 익스텐션과 함께 사용된다. @@ -99,11 +102,10 @@ kubectl에서 어디서부터 시작해야 할지 모르겠다면, 이 플로우 차트가 도움이 될 수 있다. 일부 솔루션에는 여러 유형의 익스텐션이 포함될 수 있다. - - - +![익스텐션 플로우차트](/ko/docs/concepts/extend-kubernetes/flowchart.png) + ## API 익스텐션 ### 사용자 정의 유형 diff --git a/content/ko/docs/concepts/extend-kubernetes/control-plane.png b/content/ko/docs/concepts/extend-kubernetes/control-plane.png new file mode 100644 index 0000000000000000000000000000000000000000..df95778fdb15eeb44140b8b021158f215dcd41d0 GIT binary patch literal 42721 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 h|E149$ - -쿠버네티스는 매우 유연하게 구성할 수 있고 확장 가능하다. 결과적으로 -쿠버네티스 프로젝트를 포크하거나 코드에 패치를 제출할 필요가 -거의 없다. - -이 가이드는 쿠버네티스 클러스터를 사용자 정의하기 위한 옵션을 설명한다. -쿠버네티스 클러스터를 업무 환경의 요구에 맞게 -조정하는 방법을 이해하려는 {{< glossary_tooltip text="클러스터 운영자" term_id="cluster-operator" >}}를 -대상으로 한다. -잠재적인 {{< glossary_tooltip text="플랫폼 개발자" term_id="platform-developer" >}} 또는 -쿠버네티스 프로젝트 {{< glossary_tooltip text="컨트리뷰터" term_id="contributor" >}}인 개발자에게도 -어떤 익스텐션 포인트와 패턴이 있는지, -그리고 그것들의 트레이드오프와 제약에 대한 소개 자료로 유용할 것이다. - - - - -## 개요 - -사용자 정의 방식은 크게 플래그, 로컬 구성 파일 또는 API 리소스 변경만 포함하는 *구성* 과 추가 프로그램이나 서비스 실행과 관련된 *익스텐션* 으로 나눌 수 있다. 이 문서는 주로 익스텐션에 관한 것이다. - -## 구성 - -*구성 파일* 및 *플래그* 는 온라인 문서의 레퍼런스 섹션에 각 바이너리 별로 문서화되어 있다. - -* [kubelet](/docs/reference/command-line-tools-reference/kubelet/) -* [kube-apiserver](/docs/reference/command-line-tools-reference/kube-apiserver/) -* [kube-controller-manager](/docs/reference/command-line-tools-reference/kube-controller-manager/) -* [kube-scheduler](/docs/reference/command-line-tools-reference/kube-scheduler/). - -호스팅된 쿠버네티스 서비스 또는 매니지드 설치 환경의 배포판에서 플래그 및 구성 파일을 항상 변경할 수 있는 것은 아니다. 변경 가능한 경우 일반적으로 클러스터 관리자만 변경할 수 있다. 또한 향후 쿠버네티스 버전에서 변경될 수 있으며, 이를 설정하려면 프로세스를 다시 시작해야 할 수도 있다. 이러한 이유로 다른 옵션이 없는 경우에만 사용해야 한다. - -[리소스쿼터](/ko/docs/concepts/policy/resource-quotas/), [PodSecurityPolicy](/ko/docs/concepts/policy/pod-security-policy/), [네트워크폴리시](/ko/docs/concepts/services-networking/network-policies/) 및 역할 기반 접근 제어([RBAC](/docs/reference/access-authn-authz/rbac/))와 같은 *빌트인 정책 API(built-in Policy API)* 는 기본적으로 제공되는 쿠버네티스 API이다. API는 일반적으로 호스팅된 쿠버네티스 서비스 및 매니지드 쿠버네티스 설치 환경과 함께 사용된다. 그것들은 선언적이며 파드와 같은 다른 쿠버네티스 리소스와 동일한 규칙을 사용하므로, 새로운 클러스터 구성을 반복할 수 있고 애플리케이션과 동일한 방식으로 관리할 수 ​​있다. 또한, 이들 API가 안정적인 경우, 다른 쿠버네티스 API와 같이 [정의된 지원 정책](/docs/reference/using-api/deprecation-policy/)을 사용할 수 있다. 이러한 이유로 인해 구성 파일과 플래그보다 선호된다. - -## 익스텐션(Extension) {#익스텐션} - -익스텐션은 쿠버네티스를 확장하고 쿠버네티스와 긴밀하게 통합되는 소프트웨어 컴포넌트이다. -이들 컴포넌트는 쿠버네티스가 새로운 유형과 새로운 종류의 하드웨어를 지원할 수 있게 해준다. - -대부분의 클러스터 관리자는 쿠버네티스의 호스팅 또는 배포판 인스턴스를 사용한다. -결과적으로 대부분의 쿠버네티스 사용자는 익스텐션 기능을 설치할 필요가 없고 -새로운 익스텐션 기능을 작성할 필요가 있는 사람은 더 적다. - -## 익스텐션 패턴 - -쿠버네티스는 클라이언트 프로그램을 작성하여 자동화 되도록 설계되었다. -쿠버네티스 API를 읽고 쓰는 프로그램은 유용한 자동화를 제공할 수 있다. -*자동화* 는 클러스터 상에서 또는 클러스터 밖에서 실행할 수 있다. 이 문서의 지침에 따라 -고가용성과 강력한 자동화를 작성할 수 있다. -자동화는 일반적으로 호스트 클러스터 및 매니지드 설치 환경을 포함한 모든 -쿠버네티스 클러스터에서 작동한다. - -쿠버네티스와 잘 작동하는 클라이언트 프로그램을 작성하기 위한 특정 패턴은 *컨트롤러* 패턴이라고 한다. -컨트롤러는 일반적으로 오브젝트의 `.spec`을 읽고, 가능한 경우 수행한 다음 -오브젝트의 `.status`를 업데이트 한다. - -컨트롤러는 쿠버네티스의 클라이언트이다. 쿠버네티스가 클라이언트이고 -원격 서비스를 호출할 때 이를 *웹훅(Webhook)* 이라고 한다. 원격 서비스를 -*웹훅 백엔드* 라고 한다. 컨트롤러와 마찬가지로 웹훅은 장애 지점을 -추가한다. - -웹훅 모델에서 쿠버네티스는 원격 서비스에 네트워크 요청을 한다. -*바이너리 플러그인* 모델에서 쿠버네티스는 바이너리(프로그램)를 실행한다. -바이너리 플러그인은 kubelet(예: -[Flex 볼륨 플러그인](/ko/docs/concepts/storage/volumes/#flexvolume)과 -[네트워크 플러그인](/ko/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/))과 -kubectl에서 -사용한다. - -아래는 익스텐션 포인트가 쿠버네티스 컨트롤 플레인과 상호 작용하는 방법을 -보여주는 다이어그램이다. - - - - - - -## 익스텐션 포인트 - -이 다이어그램은 쿠버네티스 시스템의 익스텐션 포인트를 보여준다. - - - - - -1. 사용자는 종종 `kubectl`을 사용하여 쿠버네티스 API와 상호 작용한다. [Kubectl 플러그인](/ko/docs/tasks/extend-kubectl/kubectl-plugins/)은 kubectl 바이너리를 확장한다. 개별 사용자의 로컬 환경에만 영향을 미치므로 사이트 전체 정책을 적용할 수는 없다. -2. apiserver는 모든 요청을 처리한다. apiserver의 여러 유형의 익스텐션 포인트는 요청을 인증하거나, 콘텐츠를 기반으로 요청을 차단하거나, 콘텐츠를 편집하고, 삭제 처리를 허용한다. 이 내용은 [API 접근 익스텐션](/ko/docs/concepts/extend-kubernetes/extend-cluster/#api-접근-익스텐션) 섹션에 설명되어 있다. -3. apiserver는 다양한 종류의 *리소스* 를 제공한다. `pods`와 같은 *빌트인 리소스 종류* 는 쿠버네티스 프로젝트에 의해 정의되며 변경할 수 없다. 직접 정의한 리소스를 추가할 수도 있고, [커스텀 리소스](/ko/docs/concepts/extend-kubernetes/extend-cluster/#사용자-정의-유형) 섹션에 설명된 대로 *커스텀 리소스* 라고 부르는 다른 프로젝트에서 정의한 리소스를 추가할 수도 있다. 커스텀 리소스는 종종 API 접근 익스텐션과 함께 사용된다. -4. 쿠버네티스 스케줄러는 파드를 배치할 노드를 결정한다. 스케줄링을 확장하는 몇 가지 방법이 있다. 이들은 [스케줄러 익스텐션](/ko/docs/concepts/extend-kubernetes/#스케줄러-익스텐션) 섹션에 설명되어 있다. -5. 쿠버네티스의 많은 동작은 API-Server의 클라이언트인 컨트롤러(Controller)라는 프로그램으로 구현된다. 컨트롤러는 종종 커스텀 리소스와 함께 사용된다. -6. kubelet은 서버에서 실행되며 파드가 클러스터 네트워크에서 자체 IP를 가진 가상 서버처럼 보이도록 한다. [네트워크 플러그인](/ko/docs/concepts/extend-kubernetes/extend-cluster/#네트워크-플러그인)을 사용하면 다양한 파드 네트워킹 구현이 가능하다. -7. kubelet은 컨테이너의 볼륨을 마운트 및 마운트 해제한다. 새로운 유형의 스토리지는 [스토리지 플러그인](/ko/docs/concepts/extend-kubernetes/extend-cluster/#스토리지-플러그인)을 통해 지원될 수 있다. - -어디서부터 시작해야 할지 모르겠다면, 이 플로우 차트가 도움이 될 수 있다. 일부 솔루션에는 여러 유형의 익스텐션이 포함될 수 있다. - - - - - - -## API 익스텐션 -### 사용자 정의 유형 - -새 컨트롤러, 애플리케이션 구성 오브젝트 또는 기타 선언적 API를 정의하고 `kubectl`과 같은 쿠버네티스 도구를 사용하여 관리하려면 쿠버네티스에 커스텀 리소스를 추가하자. - -애플리케이션, 사용자 또는 모니터링 데이터의 데이터 저장소로 커스텀 리소스를 사용하지 않는다. - -커스텀 리소스에 대한 자세한 내용은 [커스텀 리소스 개념 가이드](/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources/)를 참고하길 바란다. - - -### 새로운 API와 자동화의 결합 - -사용자 정의 리소스 API와 컨트롤 루프의 조합을 [오퍼레이터(operator) 패턴](/ko/docs/concepts/extend-kubernetes/operator/)이라고 한다. 오퍼레이터 패턴은 특정 애플리케이션, 일반적으로 스테이트풀(stateful) 애플리케이션을 관리하는 데 사용된다. 이러한 사용자 정의 API 및 컨트롤 루프를 사용하여 스토리지나 정책과 같은 다른 리소스를 제어할 수도 있다. - -### 빌트인 리소스 변경 - -사용자 정의 리소스를 추가하여 쿠버네티스 API를 확장하면 추가된 리소스는 항상 새로운 API 그룹에 속한다. 기존 API 그룹을 바꾸거나 변경할 수 없다. -API를 추가해도 기존 API(예: 파드)의 동작에 직접 영향을 미치지는 않지만 API 접근 익스텐션은 영향을 준다. - - -### API 접근 익스텐션 - -요청이 쿠버네티스 API 서버에 도달하면 먼저 인증이 되고, 그런 다음 승인된 후 다양한 유형의 어드미션 컨트롤이 적용된다. 이 흐름에 대한 자세한 내용은 [쿠버네티스 API에 대한 접근 제어](/ko/docs/concepts/security/controlling-access/)를 참고하길 바란다. - -이러한 각 단계는 익스텐션 포인트를 제공한다. - -쿠버네티스에는 이를 지원하는 몇 가지 빌트인 인증 방법이 있다. 또한 인증 프록시 뒤에 있을 수 있으며 인증 헤더에서 원격 서비스로 토큰을 전송하여 확인할 수 있다(웹훅). 이러한 방법은 모두 [인증 설명서](/docs/reference/access-authn-authz/authentication/)에 설명되어 있다. - -### 인증 - -[인증](/docs/reference/access-authn-authz/authentication/)은 모든 요청의 헤더 또는 인증서를 요청하는 클라이언트의 사용자 이름에 매핑한다. - -쿠버네티스는 몇 가지 빌트인 인증 방법과 필요에 맞지 않는 경우 [인증 웹훅](/docs/reference/access-authn-authz/authentication/#webhook-token-authentication) 방법을 제공한다. - - -### 승인 - -[승인](/docs/reference/access-authn-authz/webhook/)은 특정 사용자가 API 리소스에서 읽고, 쓰고, 다른 작업을 수행할 수 있는지를 결정한다. 전체 리소스 레벨에서 작동하며 임의의 오브젝트 필드를 기준으로 구별하지 않는다. 빌트인 인증 옵션이 사용자의 요구를 충족시키지 못하면 [인증 웹훅](/docs/reference/access-authn-authz/webhook/)을 통해 사용자가 제공한 코드를 호출하여 인증 결정을 내릴 수 있다. - - -### 동적 어드미션 컨트롤 - -요청이 승인된 후, 쓰기 작업인 경우 [어드미션 컨트롤](/docs/reference/access-authn-authz/admission-controllers/) 단계도 수행된다. 빌트인 단계 외에도 몇 가지 익스텐션이 있다. - -* [이미지 정책 웹훅](/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook)은 컨테이너에서 실행할 수 있는 이미지를 제한한다. -* 임의의 어드미션 컨트롤 결정을 내리기 위해 일반적인 [어드미션 웹훅](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)을 사용할 수 있다. 어드미션 웹훅은 생성 또는 업데이트를 거부할 수 있다. - -## 인프라스트럭처 익스텐션 - - -### 스토리지 플러그인 - -[Flex 볼륨](/ko/docs/concepts/storage/volumes/#flexvolume)을 사용하면 -Kubelet이 바이너리 플러그인을 호출하여 볼륨을 마운트하도록 함으로써 -빌트인 지원 없이 볼륨 유형을 마운트 할 수 있다. - - -### 장치 플러그인 - -장치 플러그인은 노드가 [장치 플러그인](/ko/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)을 -통해 새로운 노드 리소스(CPU 및 메모리와 같은 빌트인 자원 외에)를 -발견할 수 있게 해준다. - -### 네트워크 플러그인 - -노드-레벨의 [네트워크 플러그인](/ko/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/)을 통해 -다양한 네트워킹 패브릭을 지원할 수 있다. - -### 스케줄러 익스텐션 - -스케줄러는 파드를 감시하고 파드를 노드에 할당하는 특수한 유형의 -컨트롤러이다. 다른 쿠버네티스 컴포넌트를 계속 사용하면서 -기본 스케줄러를 완전히 교체하거나, -[여러 스케줄러](/docs/tasks/extend-kubernetes/configure-multiple-schedulers/)를 -동시에 실행할 수 있다. - -이것은 중요한 부분이며, 거의 모든 쿠버네티스 사용자는 스케줄러를 수정할 -필요가 없다는 것을 알게 된다. - -스케줄러는 또한 웹훅 백엔드(스케줄러 익스텐션)가 -파드에 대해 선택된 노드를 필터링하고 우선 순위를 지정할 수 있도록 하는 -[웹훅](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/scheduler_extender.md)을 -지원한다. - - -## {{% heading "whatsnext" %}} - -* [커스텀 리소스](/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources/)에 대해 더 알아보기 -* [동적 어드미션 컨트롤](/docs/reference/access-authn-authz/extensible-admission-controllers/)에 대해 알아보기 -* 인프라스트럭처 익스텐션에 대해 더 알아보기 - * [네트워크 플러그인](/ko/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) - * [장치 플러그인](/ko/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/) -* [kubectl 플러그인](/ko/docs/tasks/extend-kubectl/kubectl-plugins/)에 대해 알아보기 -* [오퍼레이터 패턴](/ko/docs/concepts/extend-kubernetes/operator/)에 대해 알아보기 diff --git a/content/ko/docs/concepts/extend-kubernetes/flowchart.png b/content/ko/docs/concepts/extend-kubernetes/flowchart.png new file mode 100644 index 0000000000000000000000000000000000000000..1415903a8357dfca70b7538224f52ba7640e568d GIT binary patch literal 61775 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 z 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 literal 0 HcmV?d00001 diff --git a/content/ko/docs/concepts/overview/working-with-objects/labels.md b/content/ko/docs/concepts/overview/working-with-objects/labels.md index da3cff2a89..0583ae0fe3 100644 --- a/content/ko/docs/concepts/overview/working-with-objects/labels.md +++ b/content/ko/docs/concepts/overview/working-with-objects/labels.md @@ -53,9 +53,9 @@ _레이블_ 은 키와 값의 쌍이다. 유효한 레이블 키에는 슬래시 `kubernetes.io/`와 `k8s.io/` 접두사는 쿠버네티스의 핵심 컴포넌트로 예약되어있다. 유효한 레이블 값은 다음과 같다. -* 63 자 이하 여야 하고(공백이면 안 됨), -* 시작과 끝은 알파벳과 숫자(`[a-z0-9A-Z]`)이며, -* 알파벳과 숫자, 대시(`-`), 밑줄(`_`), 점(`.`)를 중간에 포함할 수 있다. +* 63 자 이하여야 하고 (공백일 수도 있음), +* (공백이 아니라면) 시작과 끝은 알파벳과 숫자(`[a-z0-9A-Z]`)이며, +* 알파벳과 숫자, 대시(`-`), 밑줄(`_`), 점(`.`)을 중간에 포함할 수 있다. 유효한 레이블 값은 63자 미만 또는 공백이며 시작과 끝은 알파벳과 숫자(`[a-z0-9A-Z]`)이며, 대시(`-`), 밑줄(`_`), 점(`.`)과 함께 사용할 수 있다. diff --git a/content/ko/docs/concepts/scheduling-eviction/assign-pod-node.md b/content/ko/docs/concepts/scheduling-eviction/assign-pod-node.md index 8c095e4a27..da30c01ab2 100644 --- a/content/ko/docs/concepts/scheduling-eviction/assign-pod-node.md +++ b/content/ko/docs/concepts/scheduling-eviction/assign-pod-node.md @@ -72,7 +72,7 @@ spec: ## 넘어가기 전에: 내장 노드 레이블들 {#built-in-node-labels} [붙인](#1-단계-노드에-레이블-붙이기) 레이블뿐만 아니라, 노드에는 -표준 레이블 셋이 미리 채워져 있다. 이들 목록은 [잘 알려진 레이블, 어노테이션 및 테인트](/docs/reference/kubernetes-api/labels-annotations-taints/)를 참고한다. +표준 레이블 셋이 미리 채워져 있다. 이들 목록은 [잘 알려진 레이블, 어노테이션 및 테인트](/docs/reference/labels-annotations-taints/)를 참고한다. {{< note >}} 이 레이블들의 값은 클라우드 공급자에 따라 다르고 신뢰성이 보장되지 않는다. diff --git a/content/ko/docs/concepts/scheduling-eviction/taint-and-toleration.md b/content/ko/docs/concepts/scheduling-eviction/taint-and-toleration.md index bab0803b99..588adee0f7 100644 --- a/content/ko/docs/concepts/scheduling-eviction/taint-and-toleration.md +++ b/content/ko/docs/concepts/scheduling-eviction/taint-and-toleration.md @@ -206,9 +206,9 @@ tolerations: `Ready` 가 "`False`"로 됨에 해당한다. * `node.kubernetes.io/unreachable`: 노드가 노드 컨트롤러에서 도달할 수 없다. 이는 NodeCondition `Ready` 가 "`Unknown`"로 됨에 해당한다. - * `node.kubernetes.io/out-of-disk`: 노드에 디스크가 부족하다. * `node.kubernetes.io/memory-pressure`: 노드에 메모리 할당 압박이 있다. * `node.kubernetes.io/disk-pressure`: 노드에 디스크 할당 압박이 있다. + * `node.kubernetes.io/pid-pressure`: 노드에 PID 할당 압박이 있다. * `node.kubernetes.io/network-unavailable`: 노드의 네트워크를 사용할 수 없다. * `node.kubernetes.io/unschedulable`: 노드를 스케줄할 수 없다. * `node.cloudprovider.kubernetes.io/uninitialized`: "외부" 클라우드 공급자로 @@ -271,7 +271,7 @@ tolerations: * `node.kubernetes.io/memory-pressure` * `node.kubernetes.io/disk-pressure` - * `node.kubernetes.io/out-of-disk` (*중요한 파드에만 해당*) + * `node.kubernetes.io/pid-pressure` (1.14 이상) * `node.kubernetes.io/unschedulable` (1.10 이상) * `node.kubernetes.io/network-unavailable` (*호스트 네트워크만 해당*) diff --git a/content/ko/docs/concepts/services-networking/service.md b/content/ko/docs/concepts/services-networking/service.md index e5aa794ae0..7bbb4f6f63 100644 --- a/content/ko/docs/concepts/services-networking/service.md +++ b/content/ko/docs/concepts/services-networking/service.md @@ -935,11 +935,18 @@ Classic ELB의 연결 드레이닝은 # 값 보다 작아야한다. 기본값은 5이며, 2와 60 사이여야 한다. service.beta.kubernetes.io/aws-load-balancer-security-groups: "sg-53fae93f" - # 생성된 ELB에 추가할 기존 보안 그룹 목록. - # service.beta.kubernetes.io/aws-load-balancer-extra-security-groups 어노테이션과 달리, 이는 이전에 ELB에 할당된 다른 모든 보안 그룹을 대체한다. + # 생성된 ELB에 설정할 기존 보안 그룹(security group) 목록. + # service.beta.kubernetes.io/aws-load-balancer-extra-security-groups 어노테이션과 달리, 이는 이전에 ELB에 할당된 다른 모든 보안 그룹을 대체하며, + # '해당 ELB를 위한 고유 보안 그룹 생성'을 오버라이드한다. + # 목록의 첫 번째 보안 그룹 ID는 인바운드 트래픽(서비스 트래픽과 헬스 체크)이 워커 노드로 향하도록 하는 규칙으로 사용된다. + # 여러 ELB가 하나의 보안 그룹 ID와 연결되면, 1줄의 허가 규칙만이 워커 노드 보안 그룹에 추가된다. + # 즉, 만약 여러 ELB 중 하나를 지우면, 1줄의 허가 규칙이 삭제되어, 같은 보안 그룹 ID와 연결된 모든 ELB에 대한 접속이 막힌다. + # 적절하게 사용되지 않으면 이는 다수의 서비스가 중단되는 상황을 유발할 수 있다. service.beta.kubernetes.io/aws-load-balancer-extra-security-groups: "sg-53fae93f,sg-42efd82e" - # ELB에 추가될 추가 보안 그룹(security group) 목록 + # 생성된 ELB에 추가할 추가 보안 그룹 목록 + # 이 방법을 사용하면 이전에 생성된 고유 보안 그룹이 그대로 유지되므로, 각 ELB가 고유 보안 그룹 ID와 그에 매칭되는 허가 규칙 라인을 소유하여 + # 트래픽(서비스 트래픽과 헬스 체크)이 워커 노드로 향할 수 있도록 한다. 여기에 기재되는 보안 그룹은 여러 서비스 간 공유될 수 있다. service.beta.kubernetes.io/aws-load-balancer-target-node-labels: "ingress-gw,gw-name=public-api" # 로드 밸런서의 대상 노드를 선택하는 데 @@ -988,7 +995,6 @@ NLB는 특정 인스턴스 클래스에서만 작동한다. 지원되는 인스 | 규칙 | 프로토콜 | 포트 | IP 범위 | IP 범위 설명 | |------|----------|---------|------------|---------------------| | 헬스 체크 | TCP | NodePort(s) (`.spec.healthCheckNodePort` for `.spec.externalTrafficPolicy = Local`) | Subnet CIDR | kubernetes.io/rule/nlb/health=\ | - | 클라이언트 트래픽 | TCP | NodePort(s) | `.spec.loadBalancerSourceRanges` (defaults to `0.0.0.0/0`) | kubernetes.io/rule/nlb/client=\ | | MTU 탐색 | ICMP | 3,4 | `.spec.loadBalancerSourceRanges` (defaults to `0.0.0.0/0`) | kubernetes.io/rule/nlb/mtu=\ | diff --git a/content/ko/docs/concepts/storage/volumes.md b/content/ko/docs/concepts/storage/volumes.md index 698ee14e72..6156a4704b 100644 --- a/content/ko/docs/concepts/storage/volumes.md +++ b/content/ko/docs/concepts/storage/volumes.md @@ -29,10 +29,9 @@ weight: 10 쿠버네티스는 다양한 유형의 볼륨을 지원한다. {{< glossary_tooltip term_id="pod" text="파드" >}}는 여러 볼륨 유형을 동시에 사용할 수 있다. 임시 볼륨 유형은 파드의 수명을 갖지만, 퍼시스턴트 볼륨은 -파드의 수명을 넘어 존재한다. 결과적으로, 볼륨은 파드 내에서 -실행되는 모든 컨테이너보다 오래 지속되며, 컨테이너를 다시 시작해도 데이터가 보존된다. 파드가 -더 이상 존재하지 않으면, 쿠버네티스는 임시(ephemeral) 볼륨을 삭제하지만, +파드의 수명을 넘어 존재한다. 파드가 더 이상 존재하지 않으면, 쿠버네티스는 임시(ephemeral) 볼륨을 삭제하지만, 퍼시스턴트(persistent) 볼륨은 삭제하지 않는다. +볼륨의 종류와 상관없이, 파드 내의 컨테이너가 재시작되어도 데이터는 보존된다. 기본적으로 볼륨은 디렉터리이며, 일부 데이터가 있을 수 있으며, 파드 내 컨테이너에서 접근할 수 있다. 디렉터리의 생성 방식, 이를 지원하는 diff --git a/content/ko/docs/concepts/workloads/pods/disruptions.md b/content/ko/docs/concepts/workloads/pods/disruptions.md index 9d2319ae6a..56244fae26 100644 --- a/content/ko/docs/concepts/workloads/pods/disruptions.md +++ b/content/ko/docs/concepts/workloads/pods/disruptions.md @@ -135,7 +135,7 @@ PDB는 [비자발적 중단](#자발적-중단과-비자발적-중단)이 발생 Eviction API를 사용하여 파드를 축출하면, [PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core)의 -`terminationGracePeriodSeconds` 설정을 준수하여 정상적으로 [종료됨](/ko/docs/concepts/workloads/pods/pod-lifecycle/#파드의-종료) 상태가 된다.) +`terminationGracePeriodSeconds` 설정을 준수하여 정상적으로 [종료됨](/ko/docs/concepts/workloads/pods/pod-lifecycle/#파드의-종료) 상태가 된다. ## PodDisruptionBudget 예시 {#pdb-example} diff --git a/content/ko/docs/concepts/workloads/pods/pod-topology-spread-constraints.md b/content/ko/docs/concepts/workloads/pods/pod-topology-spread-constraints.md index b927895575..9bb8cfba78 100644 --- a/content/ko/docs/concepts/workloads/pods/pod-topology-spread-constraints.md +++ b/content/ko/docs/concepts/workloads/pods/pod-topology-spread-constraints.md @@ -58,7 +58,7 @@ graph TB class zoneA,zoneB cluster; {{< /mermaid >}} -레이블을 수동으로 적용하는 대신에, 사용자는 대부분의 클러스터에서 자동으로 생성되고 채워지는 [잘-알려진 레이블](/docs/reference/kubernetes-api/labels-annotations-taints/)을 재사용할 수 있다. +레이블을 수동으로 적용하는 대신에, 사용자는 대부분의 클러스터에서 자동으로 생성되고 채워지는 [잘-알려진 레이블](/docs/reference/labels-annotations-taints/)을 재사용할 수 있다. ## 파드의 분배 제약 조건 diff --git a/content/ko/docs/contribute/new-content/open-a-pr.md b/content/ko/docs/contribute/new-content/open-a-pr.md index 8697159261..552a6e1a0c 100644 --- a/content/ko/docs/contribute/new-content/open-a-pr.md +++ b/content/ko/docs/contribute/new-content/open-a-pr.md @@ -123,8 +123,8 @@ git에 익숙하거나, 변경 사항이 몇 줄보다 클 경우, ```bash origin git@github.com:/website.git (fetch) origin git@github.com:/website.git (push) - upstream https://github.com/kubernetes/website (fetch) - upstream https://github.com/kubernetes/website (push) + upstream https://github.com/kubernetes/website.git (fetch) + upstream https://github.com/kubernetes/website.git (push) ``` 6. 포크의 `origin/master` 와 `kubernetes/website` 의 `upstream/master` 에서 커밋을 가져온다. diff --git a/content/ko/docs/reference/_index.md b/content/ko/docs/reference/_index.md index 4c0b0b8177..a441e80783 100644 --- a/content/ko/docs/reference/_index.md +++ b/content/ko/docs/reference/_index.md @@ -25,7 +25,7 @@ no_list: true * [쿠버네티스 {{< param "version" >}}용 원페이지(One-page) API 레퍼런스](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/) * [쿠버네티스 API 사용](/ko/docs/reference/using-api/) - 쿠버네티스 API에 대한 개요 * [API 접근 제어](/ko/docs/reference/access-authn-authz/) - 쿠버네티스가 API 접근을 제어하는 방법에 대한 세부사항 -* [잘 알려진 레이블, 어노테이션과 테인트](/docs/reference/kubernetes-api/labels-annotations-taints/) +* [잘 알려진 레이블, 어노테이션과 테인트](/docs/reference/labels-annotations-taints/) ## 공식적으로 지원되는 클라이언트 라이브러리 diff --git a/content/ko/docs/reference/access-authn-authz/service-accounts-admin.md b/content/ko/docs/reference/access-authn-authz/service-accounts-admin.md index a64633ed52..c5a13a5608 100644 --- a/content/ko/docs/reference/access-authn-authz/service-accounts-admin.md +++ b/content/ko/docs/reference/access-authn-authz/service-accounts-admin.md @@ -5,14 +5,15 @@ weight: 50 --- + 이것은 서비스 어카운트에 대한 클러스터 관리자 안내서다. 독자는 [쿠버네티스 서비스 어카운트 설정](/docs/tasks/configure-pod-container/configure-service-account/)에 익숙하다고 가정한다. 인증 및 사용자 어카운트에 대한 지원은 아직 준비 중이다. -가끔은 서비스 어카운트를 더 잘 설명하기 위해 준비 중인 기능을 참조한다. - +서비스 어카운트를 더 잘 설명하기 위해, 때때로 미완성 기능이 언급될 수 있다. + ## 사용자 어카운트와 서비스 어카운트 비교 쿠버네티스는 여러 가지 이유로 사용자 어카운트와 서비스 어카운트의 개념을 @@ -48,37 +49,51 @@ weight: 50 파드가 생성되거나 수정될 때 파드를 수정하기 위해 동기적으로 동작한다. 이 플러그인이 활성 상태(대부분의 배포에서 기본값)인 경우 파드 생성 또는 수정 시 다음 작업을 수행한다. - 1. 파드에 `ServiceAccount` 가 없다면, `ServiceAccount` 를 `default` 로 설정한다. - 1. 파드에 참조되는 `ServiceAccount` 가 있도록 하고, 그렇지 않으면 이를 거부한다. - 1. 파드에 `ImagePullSecrets` 이 없는 경우, `ServiceAccount` 의 `ImagePullSecrets` 이 파드에 추가된다. - 1. 파드에 API 접근을 위한 토큰이 포함된 `volume` 을 추가한다. - 1. `/var/run/secrets/kubernetes.io/serviceaccount` 에 마운트된 파드의 각 컨테이너에 `volumeSource` 를 추가한다. +1. 파드에 `ServiceAccount` 가 없다면, `ServiceAccount` 를 `default` 로 설정한다. +1. 이전 단계는 파드에 참조되는 `ServiceAccount` 가 있도록 하고, 그렇지 않으면 이를 거부한다. +1. 서비스어카운트 `automountServiceAccountToken` 와 파드의 `automountServiceAccountToken` 중 어느 것도 `false` 로 설정되어 있지 않다면, API 접근을 위한 토큰이 포함된 `volume` 을 파드에 추가한다. +1. 이전 단계에서 서비스어카운트 토큰을 위한 볼륨이 만들어졌다면, `/var/run/secrets/kubernetes.io/serviceaccount` 에 마운트된 파드의 각 컨테이너에 `volumeSource` 를 추가한다. +1. 파드에 `ImagePullSecrets` 이 없는 경우, `ServiceAccount` 의 `ImagePullSecrets` 이 파드에 추가된다. #### 바인딩된 서비스 어카운트 토큰 볼륨 + {{< feature-state for_k8s_version="v1.21" state="beta" >}} -`BoundServiceAccountTokenVolume` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)가 활성화되면, 서비스 어카운트 어드미션 컨트롤러가 -시크릿 볼륨 대신 프로젝티드 서비스 어카운트 토큰 볼륨을 추가한다. 서비스 어카운트 토큰은 기본적으로 1시간 후에 만료되거나 파드가 삭제된다. [프로젝티드 볼륨](/docs/tasks/configure-pod-container/configure-projected-volume-storage/)에 대한 자세한 내용을 참고한다. +`BoundServiceAccountTokenVolume` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)가 활성화되면, +토큰 컨트롤러에 의해 생성된 무기한 서비스 어카운트 토큰을 위해, 서비스 어카운트 어드미션 컨트롤러가 시크릿 기반 볼륨 대신 다음과 같은 프로젝티드 볼륨을 추가한다. -이 기능은 모든 네임스페이스에 "kube-root-ca.crt" 컨피그맵을 게시하는 활성화된 `RootCAConfigMap` 기능 게이트에 따라 다르다. 이 컨피그맵에는 kube-apiserver에 대한 연결을 확인하는 데 사용되는 CA 번들이 포함되어 있다. +```yaml +- name: kube-api-access- + projected: + defaultMode: 420 # 0644 + sources: + - serviceAccountToken: + expirationSeconds: 3600 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +``` -1. 파드에 `serviceAccountName`가 없다면, `serviceAccountName`를 - `default`로 설정한다. -1. 파드에 참조되는 `serviceAccountName`가 있도록 하고, 그렇지 않으면 - 이를 거부한다. -1. 파드에 `imagePullSecrets`이 없는 경우, 서비스어카운트의 - `imagePullSecrets`이 파드에 추가된다. -1. 서비스어카운트 `automountServiceAccountToken` 또는 파드의 - `automountServiceAccountToken` 이 `false` 로 설정되지 않은 경우 - 파드에 API 접근 토큰이 포함된 `volume`을 추가한다. -1. 이전 단계에서 서비스어카운트 토큰에 대한 볼륨을 생성한 경우, - `/var/run/secrets/kubernetes.io/serviceaccount`에 마운트된 - 파드의 각 컨테이너에 `volumeSource`를 추가한다. +프로젝티드 볼륨은 세 가지로 구성된다. -`BoundServiceAccountTokenVolume` 기능 게이트가 활성화되면 서비스 어카운트 볼륨을 프로젝티드 볼륨으로 마이그레이션할 수 있다. -서비스 어카운트 토큰은 1시간 후에 만료되거나 파드가 삭제된다. -[프로젝티드 볼륨](/docs/tasks/configure-pod-container/configure-projected-volume-storage/)에 대한 -자세한 내용을 참조한다. +1. kube-apiserver로부터 TokenRequest API를 통해 얻은 서비스어카운트토큰(ServiceAccountToken). 서비스어카운트토큰은 기본적으로 1시간 뒤에, 또는 파드가 삭제될 때 만료된다. 서비스어카운트토큰은 파드에 연결되며 kube-apiserver를 위해 존재한다. +1. kube-apiserver에 대한 연결을 확인하는 데 사용되는 CA 번들을 포함하는 컨피그맵(ConfigMap). 이 기능은 모든 네임스페이스에 "kube-root-ca.crt" 컨피그맵을 게시하는 기능 게이트인 `RootCAConfigMap`이 활성화되어 있어야 동작한다. `RootCAConfigMap`은 1.20에서 기본적으로 활성화되어 있으며, 1.21 이상에서는 항상 활성화된 상태이다. +1. 파드의 네임스페이스를 참조하는 DownwardAPI. + +상세 사항은 [프로젝티드 볼륨](/docs/tasks/configure-pod-container/configure-projected-volume-storage/)을 참고한다. + +`BoundServiceAccountTokenVolume` 기능 게이트가 활성화되어 있지 않은 경우, +위의 프로젝티드 볼륨을 파드 스펙에 추가하여 시크릿 기반 서비스 어카운트 볼륨을 프로젝티드 볼륨으로 수동으로 옮길 수 있다. +그러나, `RootCAConfigMap`은 활성화되어 있어야 한다. ### 토큰 컨트롤러 From 8819bdc0ac3158968f5c43fc45393138fea027d3 Mon Sep 17 00:00:00 2001 From: seokho-son Date: Wed, 5 May 2021 19:37:00 +0900 Subject: [PATCH 5/9] Update task tookls and network in dev-1.21-ko.2 --- .../docs/tasks/network/validate-dual-stack.md | 16 ++++++-- .../docs/tasks/tools/install-kubectl-linux.md | 21 +++-------- .../docs/tasks/tools/install-kubectl-macos.md | 33 ++++++++++++----- .../tasks/tools/install-kubectl-windows.md | 37 ++----------------- 4 files changed, 46 insertions(+), 61 deletions(-) diff --git a/content/ko/docs/tasks/network/validate-dual-stack.md b/content/ko/docs/tasks/network/validate-dual-stack.md index a9f15956a0..5a3fdc477e 100644 --- a/content/ko/docs/tasks/network/validate-dual-stack.md +++ b/content/ko/docs/tasks/network/validate-dual-stack.md @@ -1,4 +1,8 @@ --- + + + + min-kubernetes-server-version: v1.20 title: IPv4/IPv6 이중 스택 검증 content_type: task @@ -36,9 +40,10 @@ a00:100::/24 ``` 단일 IPv4 블록과 단일 IPv6 블록이 할당되어야 한다. -노드가 IPv4 및 IPv6 인터페이스를 가지고 있는지 검증한다. (노드 이름을 클러스터의 검증된 노드로 대체한다. 본 예제에서 노드 이름은 k8s-linuxpool1-34450317-0) 이다. +노드가 IPv4 및 IPv6 인터페이스를 가지고 있는지 검증한다. 노드 이름을 클러스터의 검증된 노드로 대체한다. 본 예제에서 노드 이름은 `k8s-linuxpool1-34450317-0` 이다. + ```shell -kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .status.addresses}}{{printf "%s: %s \n" .type .address}}{{end}}' +kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .status.addresses}}{{printf "%s: %s\n" .type .address}}{{end}}' ``` ``` Hostname: k8s-linuxpool1-34450317-0 @@ -48,9 +53,10 @@ InternalIP: 2001:1234:5678:9abc::5 ### 파드 어드레싱 검증 -파드가 IPv4 및 IPv6 주소를 할당받았는지 검증한다. (파드 이름을 클러스터에서 검증된 파드로 대체한다. 본 예제에서 파드 이름은 pod01 이다.) +파드가 IPv4 및 IPv6 주소를 할당받았는지 검증한다. 파드 이름을 클러스터에서 검증된 파드로 대체한다. 본 예제에서 파드 이름은 `pod01` 이다. + ```shell -kubectl get pods pod01 -o go-template --template='{{range .status.podIPs}}{{printf "%s \n" .ip}}{{end}}' +kubectl get pods pod01 -o go-template --template='{{range .status.podIPs}}{{printf "%s\n" .ip}}{{end}}' ``` ``` 10.244.1.4 @@ -68,6 +74,7 @@ a00:100::4 ``` 다음 커맨드는 컨테이너 내 `MY_POD_IPS` 환경 변수의 값을 출력한다. 해당 값은 파드의 IPv4 및 IPv6 주소를 나타내는 쉼표로 구분된 목록이다. + ```shell kubectl exec -it pod01 -- set | grep MY_POD_IPS ``` @@ -225,3 +232,4 @@ kubectl get svc -l app=MyApp ```shell NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-service LoadBalancer fd00::7ebc 2603:1030:805::5 80:30790/TCP 35s +``` diff --git a/content/ko/docs/tasks/tools/install-kubectl-linux.md b/content/ko/docs/tasks/tools/install-kubectl-linux.md index 96ab0a4024..39c442c939 100644 --- a/content/ko/docs/tasks/tools/install-kubectl-linux.md +++ b/content/ko/docs/tasks/tools/install-kubectl-linux.md @@ -12,24 +12,17 @@ card: ## {{% heading "prerequisites" %}} -클러스터의 마이너(minor) 버전 차이 내에 있는 kubectl 버전을 사용해야 한다. -예를 들어, v1.2 클라이언트는 v1.1, v1.2 및 v1.3의 마스터와 함께 작동해야 한다. +클러스터의 마이너(minor) 버전 차이 내에 있는 kubectl 버전을 사용해야 한다. 예를 들어, v{{< skew latestVersion >}} 클라이언트는 v{{< skew prevMinorVersion >}}, v{{< skew latestVersion >}}, v{{< skew nextMinorVersion >}}의 컨트롤 플레인과 연동될 수 있다. 최신 버전의 kubectl을 사용하면 예기치 않은 문제를 피할 수 있다. ## 리눅스에 kubectl 설치 다음과 같은 방법으로 리눅스에 kubectl을 설치할 수 있다. -- [{{% heading "prerequisites" %}}](#시작하기-전에) -- [리눅스에 kubectl 설치](#리눅스에-kubectl-설치) - - [리눅스에서 curl을 사용하여 kubectl 바이너리 설치]{#install-kubectl-binary-with-curl-on-linux} - - [기본 패키지 관리 도구를 사용하여 설치]{#install-using-native-package-management} - - [다른 패키지 관리 도구를 사용하여 설치]{#install-using-other-package-management} - - [Google Cloud SDK를 사용하여 설치]{#install-on-linux-as-part-of-the-google-cloud-sdk} -- [kubectl 구성 확인](#kubectl-구성-확인) -- [선택적 kubectl 구성](#선택적-kubectl-구성) - - [셸 자동 완성 활성화](#셸-자동-완성-활성화) -- [{{% heading "whatsnext" %}}](#다음-내용) +- [리눅스에 curl을 사용하여 kubectl 바이너리 설치](#install-kubectl-binary-with-curl-on-linux) +- [기본 패키지 관리 도구를 사용하여 설치](#install-using-native-package-management) +- [다른 패키지 관리 도구를 사용하여 설치](#install-using-other-package-management) +- [리눅스에 Google Cloud SDK를 사용하여 설치](#install-on-linux-as-part-of-the-google-cloud-sdk) ### 리눅스에서 curl을 사용하여 kubectl 바이너리 설치 {#install-kubectl-binary-with-curl-on-linux} @@ -158,7 +151,6 @@ yum install -y kubectl ```shell snap install kubectl --classic - kubectl version --client ``` @@ -169,7 +161,6 @@ kubectl version --client ```shell brew install kubectl - kubectl version --client ``` @@ -177,7 +168,7 @@ kubectl version --client {{< /tabs >}} -### Google Cloud SDK를 사용하여 설치 {#install-on-linux-as-part-of-the-google-cloud-sdk} +### 리눅스에 Google Cloud SDK를 사용하여 설치 {#install-on-linux-as-part-of-the-google-cloud-sdk} {{< include "included/install-kubectl-gcloud.md" >}} diff --git a/content/ko/docs/tasks/tools/install-kubectl-macos.md b/content/ko/docs/tasks/tools/install-kubectl-macos.md index 1fd37151a6..614134da8a 100644 --- a/content/ko/docs/tasks/tools/install-kubectl-macos.md +++ b/content/ko/docs/tasks/tools/install-kubectl-macos.md @@ -12,8 +12,7 @@ card: ## {{% heading "prerequisites" %}} -클러스터의 마이너(minor) 버전 차이 내에 있는 kubectl 버전을 사용해야 한다. -예를 들어, v1.2 클라이언트는 v1.1, v1.2 및 v1.3의 마스터와 함께 작동해야 한다. +클러스터의 마이너(minor) 버전 차이 내에 있는 kubectl 버전을 사용해야 한다. 예를 들어, v{{< skew latestVersion >}} 클라이언트는 v{{< skew prevMinorVersion >}}, v{{< skew latestVersion >}}, v{{< skew nextMinorVersion >}}의 컨트롤 플레인과 연동될 수 있다. 최신 버전의 kubectl을 사용하면 예기치 않은 문제를 피할 수 있다. ## macOS에 kubectl 설치 @@ -29,17 +28,28 @@ card: 1. 최신 릴리스를 다운로드한다. - ```bash + {{< tabs name="download_binary_macos" >}} + {{< tab name="Intel" codelang="bash" >}} curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl" - ``` + {{< /tab >}} + {{< tab name="Apple Silicon" codelang="bash" >}} + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl" + {{< /tab >}} + {{< /tabs >}} {{< note >}} 특정 버전을 다운로드하려면, `$(curl -L -s https://dl.k8s.io/release/stable.txt)` 명령 부분을 특정 버전으로 바꾼다. - 예를 들어, macOS에서 버전 {{< param "fullversion" >}}을 다운로드하려면, 다음을 입력한다. + 예를 들어, Intel macOS에 버전 {{< param "fullversion" >}}을 다운로드하려면, 다음을 입력한다. ```bash - curl -LO https://dl.k8s.io/release/{{< param "fullversion" >}}/bin/darwin/amd64/kubectl + curl -LO "https://dl.k8s.io/release/{{< param "fullversion" >}}/bin/darwin/amd64/kubectl" + ``` + + Apple Silicon의 macOS라면, 다음을 입력한다. + + ```bash + curl -LO "https://dl.k8s.io/release/{{< param "fullversion" >}}/bin/darwin/arm64/kubectl" ``` {{< /note >}} @@ -48,9 +58,14 @@ card: kubectl 체크섬 파일을 다운로드한다. - ```bash - curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl.sha256" - ``` + {{< tabs name="download_checksum_macos" >}} + {{< tab name="Intel" codelang="bash" >}} + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl.sha256" + {{< /tab >}} + {{< tab name="Apple Silicon" codelang="bash" >}} + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl.sha256" + {{< /tab >}} + {{< /tabs >}} kubectl 바이너리를 체크섬 파일을 통해 검증한다. diff --git a/content/ko/docs/tasks/tools/install-kubectl-windows.md b/content/ko/docs/tasks/tools/install-kubectl-windows.md index e1c67af9ce..23b16e3da6 100644 --- a/content/ko/docs/tasks/tools/install-kubectl-windows.md +++ b/content/ko/docs/tasks/tools/install-kubectl-windows.md @@ -12,8 +12,7 @@ card: ## {{% heading "prerequisites" %}} -클러스터의 마이너(minor) 버전 차이 내에 있는 kubectl 버전을 사용해야 한다. -예를 들어, v1.2 클라이언트는 v1.1, v1.2 및 v1.3의 마스터와 함께 작동해야 한다. +클러스터의 마이너(minor) 버전 차이 내에 있는 kubectl 버전을 사용해야 한다. 예를 들어, v{{< skew latestVersion >}} 클라이언트는 v{{< skew prevMinorVersion >}}, v{{< skew latestVersion >}}, v{{< skew nextMinorVersion >}}의 컨트롤 플레인과 연동될 수 있다. 최신 버전의 kubectl을 사용하면 예기치 않은 문제를 피할 수 있다. ## 윈도우에 kubectl 설치 @@ -21,9 +20,8 @@ card: 다음과 같은 방법으로 윈도우에 kubectl을 설치할 수 있다. - [윈도우에서 curl을 사용하여 kubectl 바이너리 설치](#install-kubectl-binary-with-curl-on-windows) -- [PSGallery에서 PowerShell로 설치](#install-with-powershell-from-psgallery) - [Chocolatey 또는 Scoop을 사용하여 윈도우에 설치](#install-on-windows-using-chocolatey-or-scoop) -- [Google Cloud SDK를 사용하여 설치](#install-on-windows-as-part-of-the-google-cloud-sdk) +- [윈도우에서 Google Cloud SDK를 사용하여 설치](#install-on-windows-as-part-of-the-google-cloud-sdk) ### 윈도우에서 curl을 사용하여 kubectl 바이너리 설치 {#install-kubectl-binary-with-curl-on-windows} @@ -76,33 +74,6 @@ card: 도커 데스크톱을 이전에 설치한 경우, 도커 데스크톱 설치 프로그램에서 추가한 `PATH` 항목 앞에 `PATH` 항목을 배치하거나 도커 데스크톱의 `kubectl` 을 제거해야 할 수도 있다. {{< /note >}} -### PSGallery에서 PowerShell로 설치 {#install-with-powershell-from-psgallery} - -윈도우에서 [Powershell Gallery](https://www.powershellgallery.com/) 패키지 관리자를 사용하는 경우, Powershell로 kubectl을 설치하고 업데이트할 수 있다. - -1. 설치 명령을 실행한다(`DownloadLocation` 을 지정해야 한다). - - ```powershell - Install-Script -Name install-kubectl -Scope CurrentUser -Force - install-kubectl.ps1 [-DownloadLocation ] - ``` - - {{< note >}} - `DownloadLocation` 을 지정하지 않으면, `kubectl` 은 사용자의 `temp` 디렉터리에 설치된다. - {{< /note >}} - - 설치 프로그램은 `$HOME/.kube` 를 생성하고 구성 파일을 작성하도록 지시한다. - -1. 설치한 버전이 최신 버전인지 확인한다. - - ```powershell - kubectl version --client - ``` - -{{< note >}} -설치 업데이트는 1 단계에서 나열한 두 명령을 다시 실행하여 수행한다. -{{< /note >}} - ### Chocolatey 또는 Scoop을 사용하여 윈도우에 설치 {#install-on-windows-using-chocolatey-or-scoop} 1. 윈도우에 kubectl을 설치하기 위해서 [Chocolatey](https://chocolatey.org) 패키지 관리자나 [Scoop](https://scoop.sh) 커맨드 라인 설치 프로그램을 사용할 수 있다. @@ -156,7 +127,7 @@ card: 메모장과 같은 텍스트 편집기를 선택하여 구성 파일을 편집한다. {{< /note >}} -### Google Cloud SDK를 사용하여 설치 {#install-on-windows-as-part-of-the-google-cloud-sdk} +### 윈도우에서 Google Cloud SDK를 사용하여 설치 {#install-on-windows-as-part-of-the-google-cloud-sdk} {{< include "included/install-kubectl-gcloud.md" >}} @@ -176,4 +147,4 @@ kubectl은 Bash 및 Zsh에 대한 자동 완성 지원을 제공하므로 입력 ## {{% heading "whatsnext" %}} -{{< include "included/kubectl-whats-next.md" >}} \ No newline at end of file +{{< include "included/kubectl-whats-next.md" >}} From d05cbcad6345c7d8130ea190ddd2d702dee15ae2 Mon Sep 17 00:00:00 2001 From: seokho-son Date: Wed, 5 May 2021 17:03:48 +0900 Subject: [PATCH 6/9] Update kustomization.md in dev-1.21-ko.2 --- .../kustomization.md | 183 +++++++++++++++--- 1 file changed, 161 insertions(+), 22 deletions(-) diff --git a/content/ko/docs/tasks/manage-kubernetes-objects/kustomization.md b/content/ko/docs/tasks/manage-kubernetes-objects/kustomization.md index e420acbed9..feff78ce25 100644 --- a/content/ko/docs/tasks/manage-kubernetes-objects/kustomization.md +++ b/content/ko/docs/tasks/manage-kubernetes-objects/kustomization.md @@ -47,12 +47,12 @@ Kustomize는 쿠버네티스 구성을 사용자 정의화하는 도구이다. ### 리소스 생성 -컨피그 맵과 시크릿은 파드와 같은 다른 쿠버네티스 오브젝트에서 사용되는 설정이나 민감한 데이터를 가지고 있다. 컨피그 맵이나 시크릿의 실질적인 소스는 일반적으로 `.properties` 파일이나 ssh key 파일과 같은 것들은 클러스터 외부에 있다. -Kustomize는 시크릿과 컨피그 맵을 파일이나 문자열에서 생성하는 `secretGenerator`와 `configMapGenerator`를 가지고 있다. +컨피그맵과 시크릿은 파드와 같은 다른 쿠버네티스 오브젝트에서 사용되는 설정이나 민감한 데이터를 가지고 있다. 컨피그맵이나 시크릿의 실질적인 소스는 일반적으로 `.properties` 파일이나 ssh key 파일과 같은 것들은 클러스터 외부에 있다. +Kustomize는 시크릿과 컨피그맵을 파일이나 문자열에서 생성하는 `secretGenerator`와 `configMapGenerator`를 가지고 있다. #### configMapGenerator -파일에서 컨피그 맵을 생성하려면 `configMapGenerator` 내의 `files` 리스트에 항목을 추가한다. 다음은 하나의 `.properties` 파일에서 데이터 항목으로 컨피그 맵을 생성하는 예제이다. +파일에서 컨피그맵을 생성하려면 `configMapGenerator` 내의 `files` 리스트에 항목을 추가한다. 다음은 하나의 `.properties` 파일에서 데이터 항목으로 컨피그맵을 생성하는 예제이다. ```shell # application.properties 파일을 생성 @@ -68,13 +68,13 @@ configMapGenerator: EOF ``` -생성된 컨피그 맵은 다음 명령어로 검사할 수 있다. +생성된 컨피그맵은 다음 명령어로 검사할 수 있다. ```shell kubectl kustomize ./ ``` -생성된 컨피그 맵은 다음과 같다. +생성된 컨피그맵은 다음과 같다. ```yaml apiVersion: v1 @@ -86,7 +86,7 @@ metadata: name: example-configmap-1-8mbdf7882g ``` -컨피그 맵은 문자로된 키-값 쌍들로도 생성할 수 있다. 문자로된 키-값 쌍에서 컨피그 맵을 생성하려면, configMapGenerator 내의 `literals` 리스트에 항목을 추가한다. 다음은 키-값 쌍을 데이터 항목으로 받는 컨피그 맵을 생성하는 예제이다. +컨피그맵은 문자로된 키-값 쌍들로도 생성할 수 있다. 문자로된 키-값 쌍에서 컨피그맵을 생성하려면, configMapGenerator 내의 `literals` 리스트에 항목을 추가한다. 다음은 키-값 쌍을 데이터 항목으로 받는 컨피그맵을 생성하는 예제이다. ```shell cat <./kustomization.yaml @@ -97,13 +97,13 @@ configMapGenerator: EOF ``` -생성된 컨피그 맵은 다음 명령어로 확인할 수 있다. +생성된 컨피그맵은 다음 명령어로 확인할 수 있다. ```shell kubectl kustomize ./ ``` -생성된 컨피그 맵은 다음과 같다. +생성된 컨피그맵은 다음과 같다. ```yaml apiVersion: v1 @@ -114,6 +114,98 @@ metadata: name: example-configmap-2-g2hdhfc6tk ``` +디플로이먼트에서 생성된 컨피그맵을 사용하기 위해서는, configMapGenerator의 이름을 참조한다. Kustomize는 자동으로 해당 이름을 생성된 이름으로 교체할 것이다. + +다음은 생성된 컨피그맵을 사용하는 디플로이먼트의 예시다. + +```yaml +# application.properties 파일을 생성한다. +cat <application.properties +FOO=Bar +EOF + +cat <deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-app + labels: + app: my-app +spec: + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + containers: + - name: app + image: my-app + volumeMount: + - name: config + mountPath: /config + volumes: + - name: config + configMap: + name: example-configmap-1 +EOF + +cat <./kustomization.yaml +resources: +- deployment.yaml +configMapGenerator: +- name: example-configmap-1 + files: + - application.properties +EOF +``` + +컨피그맵과 디플로이먼트를 생성한다. + +```shell +kubectl kustomize ./ +``` + +생성된 디플로이먼트는 이름을 통해서 생성된 컨피그맵을 참조한다. + +```yaml +apiVersion: v1 +data: + application.properties: | + FOO=Bar +kind: ConfigMap +metadata: + name: example-configmap-1-g4hk9g2ff8 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: my-app + name: my-app +spec: + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + containers: + - image: my-app + name: app + volumeMount: + - mountPath: /config + name: config + volumes: + - configMap: + name: example-configmap-1-g4hk9g2ff8 + name: config +``` + #### secretGenerator 파일 또는 문자로된 키-값 쌍들로 시크릿을 생성할 수 있다. 파일에서 시크릿을 생성하려면 `secretGenerator` 내의 `files` 리스트에 항목을 추가한다. 다음은 파일을 데이터 항목으로 받는 시크릿을 생성하는 예제이다. @@ -170,9 +262,56 @@ metadata: type: Opaque ``` +컨피그맵과 유사하게, 생성된 시크릿도 secretGenerator의 이름을 참조함으로써 디플로이먼트에서 사용될 수 있다. + +```shell +# password.txt 파일을 생성한다. +cat <./password.txt +username=admin +password=secret +EOF + +cat <deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-app + labels: + app: my-app +spec: + selector: + matchLabels: + app: my-app + template: + metadata: + labels: + app: my-app + spec: + containers: + - name: app + image: my-app + volumeMount: + - name: password + mountPath: /secrets + volumes: + - name: password + secret: + secretName: example-secret-1 +EOF + +cat <./kustomization.yaml +resources: +- deployment.yaml +secretGenerator: +- name: example-secret-1 + files: + - password.txt +EOF +``` + #### generatorOptions -생성된 컨피그 맵과 시크릿은 콘텐츠 해시 접미사가 추가된다. 이는 콘텐츠가 변경될 때 새로운 컨피그 맵 이나 시크릿이 생성되는 것을 보장한다. 접미사를 추가하는 동작을 비활성화하는 방법으로 `generatorOptions`를 사용할 수 있다. 그밖에, 생성된 컨피그 맵과 시크릿에 교차 편집 옵션들을 지정해주는 것도 가능하다. +생성된 컨피그맵과 시크릿은 콘텐츠 해시 접미사가 추가된다. 이는 콘텐츠가 변경될 때 새로운 컨피그맵 이나 시크릿이 생성되는 것을 보장한다. 접미사를 추가하는 동작을 비활성화하는 방법으로 `generatorOptions`를 사용할 수 있다. 그밖에, 생성된 컨피그맵과 시크릿에 교차 편집 옵션들을 지정해주는 것도 가능하다. ```shell cat <./kustomization.yaml @@ -189,7 +328,7 @@ generatorOptions: EOF ``` -생성된 컨피그 맵을 보려면 `kubectl kustomize ./`를 실행한다. +생성된 컨피그맵을 보려면 `kubectl kustomize ./`를 실행한다. ```yaml apiVersion: v1 @@ -814,17 +953,17 @@ deployment.apps "dev-my-nginx" deleted | nameSuffix | string | 모든 리소스 네임에 이 필드의 값이 접미사로 추가된다 | | commonLabels | map[string]string | 모든 리소스와 셀렉터에 추가될 레이블 | | commonAnnotations | map[string]string | 모든 리소스에 추가될 어노테이션 | -| resources | []string | 이 리스트 내 각각의 항목은 반드시 존재하는 리소스 구성 파일로 해석되어져야 한다 | -| configmapGenerator | [][ConfigMapArgs](https://github.com/kubernetes-sigs/kustomize/blob/release-kustomize-v4.0/api/types/kustomization.go#L99) | 이 리스트 내 각각의 항목은 컨피그 맵을 생성한다 | -| secretGenerator | [][SecretArgs](https://github.com/kubernetes-sigs/kustomize/blob/release-kustomize-v4.0/api/types/kustomization.go#L106) | 이 리스트 내 각각의 항목은 시크릿을 생성한다 | -| generatorOptions | [GeneratorOptions](https://github.com/kubernetes-sigs/kustomize/blob/release-kustomize-v4.0/api/types/kustomization.go#L109) | 모든 configMapGenerator와 secretGenerator의 동작을 변경 | -| bases | []string | 이 리스트 내 각각의 항목은 kustomization.yaml 파일을 가지는 디렉터리로 해석되어져야 한다 | -| patchesStrategicMerge | []string | 이 리스트 내 각각의 항목은 쿠버네티스 오브젝트의 전략적 병합 패치로 해석되어져야 한다 | -| patchesJson6902 | [][Json6902](https://github.com/kubernetes-sigs/kustomize/blob/release-kustomize-v4.0/api/types/patchjson6902.go#L8) | 이 리스트 내 각각의 항목은 쿠버네티스 오브젝트와 Json 패치로 해석되어져야 한다 | -| vars | [][Var](https://github.com/kubernetes-sigs/kustomize/blob/master/api/types/var.go#L31) | 각각의 항목은 한 리소스의 필드에서 텍스트를 캡쳐한다 | -| images | [][Image](https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/image.go#L23) | 각각의 항목은 패치를 생성하지 않고 한 이미지의 name, tags 그리고/또는 digest를 수정한다 | -| configurations | []string | 이 리스트 내 각각의 항목은 [Kustomize 변환 설정](https://github.com/kubernetes-sigs/kustomize/tree/master/examples/transformerconfigs)을 포함하는 파일로 해석되어져야 한다 | -| crds | []string | 이 리스트 내 각각의 항목은 쿠버네티스 타입에 대한 OpenAPI 정의 파일로 해석되어져야 한다 | +| resources | []string | 이 리스트 내 각각의 항목은 반드시 존재하는 리소스 구성 파일로 해석되어야 한다. | +| configMapGenerator | [][ConfigMapArgs](https://github.com/kubernetes-sigs/kustomize/blob/master/api/types/configmapargs.go#L7) | 이 리스트의 각 항목은 컨피그맵을 생성한다. | +| secretGenerator | [][SecretArgs](https://github.com/kubernetes-sigs/kustomize/blob/master/api/types/secretargs.go#L7) | 이 리스트의 각 항목은 시크릿을 생성한다. | +| generatorOptions | [GeneratorOptions](https://github.com/kubernetes-sigs/kustomize/blob/master/api/types/generatoroptions.go#L7) | 모든 컨피그맵 및 시크릿 생성자(generator)의 동작을 수정한다. | +| bases | []string | 이 리스트 내 각각의 항목은 kustomization.yaml 파일을 가지는 디렉터리로 해석되어야 한다. | +| patchesStrategicMerge | []string | 이 리스트 내 각각의 항목은 쿠버네티스 오브젝트의 전략적 병합 패치로 해석되어야 한다. | +| patchesJson6902 | [][Patch](https://github.com/kubernetes-sigs/kustomize/blob/master/api/types/patch.go#L10) | 이 리스트 내 각각의 항목은 쿠버네티스 오브젝트와 Json 패치로 해석되어야 한다. | +| vars | [][Var](https://github.com/kubernetes-sigs/kustomize/blob/master/api/types/var.go#L19) | 각각의 항목은 한 리소스의 필드에서 텍스트를 캡쳐한다. | +| images | [][Image](https://github.com/kubernetes-sigs/kustomize/blob/master/api/types/image.go#L8) | 각각의 항목은 패치를 생성하지 않고 하나의 이미지에 대한 name, tags 그리고/또는 digest를 수정한다. | +| configurations | []string | 이 리스트 내 각각의 항목은 [Kustomize 변환 설정](https://github.com/kubernetes-sigs/kustomize/tree/master/examples/transformerconfigs)을 포함하는 파일로 해석되어야 한다. | +| crds | []string | 이 리스트 내 각각의 항목은 쿠버네티스 타입에 대한 OpenAPI 정의 파일로 해석되어야 한다. | @@ -832,6 +971,6 @@ deployment.apps "dev-my-nginx" deleted * [Kustomize](https://github.com/kubernetes-sigs/kustomize) -* [Kubectl 북](https://kubectl.docs.kubernetes.io) +* [Kubectl 문서](https://kubectl.docs.kubernetes.io) * [Kubectl 커맨드 참조](/docs/reference/generated/kubectl/kubectl-commands/) * [쿠버네티스 API 참조](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/) From 0885df43c5ff918096bea861533921e57a30fdfb Mon Sep 17 00:00:00 2001 From: computerphilosopher Date: Sat, 15 May 2021 12:24:09 +0900 Subject: [PATCH 7/9] Fix typo of korean docs --- content/ko/docs/concepts/cluster-administration/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ko/docs/concepts/cluster-administration/_index.md b/content/ko/docs/concepts/cluster-administration/_index.md index 9870704596..f5363a45c2 100755 --- a/content/ko/docs/concepts/cluster-administration/_index.md +++ b/content/ko/docs/concepts/cluster-administration/_index.md @@ -45,7 +45,7 @@ no_list: true ## 클러스터 보안 -* [인증서 생성](/ko/docs/tasks/administer-cluster/certificates/)는 다른 툴 체인을 사용하여 인증서를 생성하는 단계를 설명한다. +* [인증서 생성](/ko/docs/tasks/administer-cluster/certificates/)은 다른 툴 체인을 사용하여 인증서를 생성하는 단계를 설명한다. * [쿠버네티스 컨테이너 환경](/ko/docs/concepts/containers/container-environment/)은 쿠버네티스 노드에서 Kubelet으로 관리하는 컨테이너에 대한 환경을 설명한다. From 9a7f807474d9302621b6b79ee34e6329d7383ed1 Mon Sep 17 00:00:00 2001 From: seokho-son Date: Wed, 5 May 2021 18:38:29 +0900 Subject: [PATCH 8/9] Update administer-cluster in dev-1.21-ko.2 --- .../declare-network-policy.md | 6 +- .../kubeadm/kubeadm-certs.md | 76 ++++++++++++++++++- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/content/ko/docs/tasks/administer-cluster/declare-network-policy.md b/content/ko/docs/tasks/administer-cluster/declare-network-policy.md index 7a7a97576d..2a476d520d 100644 --- a/content/ko/docs/tasks/administer-cluster/declare-network-policy.md +++ b/content/ko/docs/tasks/administer-cluster/declare-network-policy.md @@ -1,4 +1,7 @@ --- + + + title: 네트워크 폴리시(Network Policy) 선언하기 min-kubernetes-server-version: v1.8 content_type: task @@ -13,8 +16,9 @@ content_type: task {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} -네트워크 폴리시를 지원하는 네트워크 제공자를 구성하였는지 확인해야 한다. 다음과 같이 네트워크폴리시를 제공하는 많은 네트워크 제공자들이 있다. +네트워크 폴리시를 지원하는 네트워크 제공자를 구성하였는지 확인해야 한다. 다음과 같이 네트워크폴리시를 지원하는 많은 네트워크 제공자들이 있다. +* [Antrea](/docs/tasks/administer-cluster/network-policy-provider/antrea-network-policy/) * [캘리코(Calico)](/ko/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy/) * [실리움(Cilium)](/ko/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy/) * [Kube-router](/ko/docs/tasks/administer-cluster/network-policy-provider/kube-router-network-policy/) diff --git a/content/ko/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md b/content/ko/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md index 3474aee3c2..78e2fa767b 100644 --- a/content/ko/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md +++ b/content/ko/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md @@ -1,4 +1,6 @@ --- + + title: kubeadm을 사용한 인증서 관리 content_type: task weight: 10 @@ -190,11 +192,13 @@ CSR과 함께 제공되는 개인 키가 모두 출력된다. `kubeadm init` 과 마찬가지로 출력 디렉터리를 `--csr-dir` 플래그로 지정할 수 있다. CSR에는 인증서 이름, 도메인 및 IP가 포함되지만, 용도를 지정하지는 않는다. -인증서를 발행할 때 [올바른 인증서 용도](/ko/docs/setup/best-practices/certificates/#모든-인증서)를 지정하는 것은 CA의 책임이다. +인증서를 발행할 때 [올바른 인증서 용도](/ko/docs/setup/best-practices/certificates/#모든-인증서)를 +지정하는 것은 CA의 책임이다. * `openssl` 의 경우 [`openssl ca` 명령](https://superuser.com/questions/738612/openssl-ca-keyusage-extension)으로 수행한다. -* `cfssl` 의 경우 [설정 파일에 용도](https://github.com/cloudflare/cfssl/blob/master/doc/cmd/cfssl.txt#L170)를 지정한다. +* `cfssl` 의 경우 + [설정 파일에 용도](https://github.com/cloudflare/cfssl/blob/master/doc/cmd/cfssl.txt#L170)를 지정한다. 선호하는 방법으로 인증서에 서명한 후, 인증서와 개인 키를 PKI 디렉터리(기본적으로 `/etc/kubernetes/pki`)에 복사해야 한다. @@ -203,3 +207,71 @@ CSR에는 인증서 이름, 도메인 및 IP가 포함되지만, 용도를 지 Kubeadm은 CA 인증서의 순환이나 교체 기능을 기본적으로 지원하지 않는다. CA의 수동 순환이나 교체에 대한 보다 상세한 정보는 [CA 인증서 수동 순환](/docs/tasks/tls/manual-rotation-of-ca-certificates/) 문서를 참조한다. + +## 서명된 kubelet 인증서 활성화하기 {#kubelet-serving-certs} + +기본적으로 kubeadm에 의해서 배포된 kubelet 인증서는 자가 서명된(self-signed) 것이다. +이것은 [metrics-server](https://github.com/kubernetes-sigs/metrics-server)와 +같은 외부 서비스의 kubelet에 대한 연결은 +TLS로 보안되지 않음을 의미한다. + +제대로 서명된 인증서를 얻기 위해서 신규 kubeadm 클러스터의 kubelet을 구성하려면 +다음의 최소 구성을 `kubeadm init` 에 전달해야 한다. + +```yaml +apiVersion: kubeadm.k8s.io/v1beta2 +kind: ClusterConfiguration +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +serverTLSBootstrap: true +``` + +만약 이미 클러스터를 생성했다면 다음을 따라 이를 조정해야 한다. + - `kube-system` 네임스페이스에서 `kubelet-config-{{< skew latestVersion >}}` 컨피그맵을 찾아서 수정한다. +해당 컨피그맵에는 `config` 키가 +[KubeletConfiguration](/docs/reference/config-api/kubelet-config.v1beta1/#kubelet-config-k8s-io-v1beta1-KubeletConfiguration) +문서를 값으로 가진다. `serverTLSBootstrap: true` 가 되도록 KubeletConfiguration 문서를 수정한다. +- 각 노드에서, `serverTLSBootstrap: true` 필드를 `/var/lib/kubelet/config.yaml` 에 추가한다. +그리고 `systemctl restart kubelet` 로 kubelet을 재시작한다. + +`serverTLSBootstrap: true` 필드는 kubelet 인증서를 이용한 부트스트랩을 +`certificates.k8s.io` API에 요청함으로써 활성화할 것이다. 한 가지 알려진 제약은 +이 인증서들에 대한 CSR(인증서 서명 요청)들이 kube-controller-manager - +[`kubernetes.io/kubelet-serving`](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#kubernetes-signers)의 +기본 서명자(default signer)에 의해서 자동으로 승인될 수 없다는 점이다. +이것은 사용자나 제 3의 컨트롤러의 액션을 필요로 할 것이다. + +이 CSR들은 다음을 통해 볼 수 있다. + +```shell +kubectl get csr +NAME AGE SIGNERNAME REQUESTOR CONDITION +csr-9wvgt 112s kubernetes.io/kubelet-serving system:node:worker-1 Pending +csr-lz97v 1m58s kubernetes.io/kubelet-serving system:node:control-plane-1 Pending +``` + +이를 승인하기 위해서는 다음을 수행한다. +```shell +kubectl certificate approve +``` + +기본적으로, 이 인증서는 1년 후에 만기될 것이다. Kubeadm은 +`KubeletConfiguration` 필드의 `rotateCertificates` 를 `true` 로 설정한다. 이것은 만기가 +다가오면 인증서를 위한 신규 CSR 세트가 생성되는 것을 의미하며, +해당 순환(rotation)을 완료하기 위해서는 승인이 되어야 한다는 것을 의미한다. 더 상세한 이해를 위해서는 +[인증서 순환](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/#certificate-rotation)를 확인한다. + +만약 이 CSR들의 자동 승인을 위한 솔루션을 찾고 있다면 클라우드 제공자와 +연락하여 대역 외 메커니즘(out of band mechanism)을 통해 노드의 신분을 검증할 수 있는 +CSR 서명자를 가지고 있는지 문의하는 것을 추천한다. + +{{% thirdparty-content %}} + +제 3 자 커스텀 컨트롤러도 사용될 수 있다. +- [kubelet-rubber-stamp](https://github.com/kontena/kubelet-rubber-stamp) + +이러한 컨트롤러는 CSR의 CommonName과 요청된 IPs 및 도메인 네임을 +모두 검증하지 않는 한, 보안이 되는 메커니즘이 아니다. 이것을 통해 악의적 행위자가 +kubelet 인증서(클라이언트 인증)를 사용하여 아무 IP나 도메인 네임에 대해 인증서를 +요청하는 CSR의 생성을 방지할 수 있을 것이다. From b26563c314336d2398818d3da09f08d6a636f875 Mon Sep 17 00:00:00 2001 From: Seonggwon Yoon Date: Tue, 18 May 2021 12:23:42 +0900 Subject: [PATCH 9/9] Fix typo minikubue to minikube --- content/ko/docs/tutorials/hello-minikube.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ko/docs/tutorials/hello-minikube.md b/content/ko/docs/tutorials/hello-minikube.md index e5831046df..eaa81c3809 100644 --- a/content/ko/docs/tutorials/hello-minikube.md +++ b/content/ko/docs/tutorials/hello-minikube.md @@ -41,7 +41,7 @@ Katacode는 무료로 브라우저에서 쿠버네티스 환경을 제공한다. -## minikubue 클러스터 만들기 +## minikube 클러스터 만들기 1. **Launch Terminal** 을 클릭