A cluster consists of a master API server and a set of worker VMs called nodes. <del> Create a cluster via the Console: *Compute > Container Engine > Container Clusters > New container cluster*. Leave all the options default, and you should get a Kubernetes cluster with three nodes, ready to receive your container image. </del> <ins> Create a cluster via the Console: *Compute > Container Engine > Container Clusters > New container cluster*. Set the name to 'hello-world', leaving all other options default.  You should get a Kubernetes cluster with three nodes, ready to receive your container image. </ins> ![image](/images/hellonode/image_11.png)


Here is the `Dockerfile` for the web server: ```shell <del> FROM node:0.10.40 </del> <ins> FROM node:4.4 </ins> RUN mkdir -p /usr/src/app WORKDIR /usr/src/app


A `Dockerfile` is pretty self explanatory, and this one is dead simple. <del> First, it uses the official Node.js image as the base image. </del> <ins> First, it uses the official Node.js LTS image as the base image. </ins> Then, it creates a folder to store the code, `cd`s into that directory, copies the code in, and installs the dependencies with npm.


Hopefully I can do some more posts about advanced Kubernetes topics such as changing the cluster size and number of Node.js web server replicas, using different environments (dev, staging, prod) on the same cluster, and doing rolling updates. Thanks to [Mark Mandel](https://medium.com/@markmandel), [Aja Hammerly](https://medium.com/@thagomizer), and [Jack Wilber](https://medium.com/@jack.g.wilber). [Some rights reserved](http://creativecommons.org/licenses/by/4.0/) by the author.


#### Dockerfile ```conf <del> FROM node:0.12 </del> <ins> FROM node:4.4 </ins> EXPOSE 8080 COPY server.js . CMD node server.js ``` <del> This "recipe" for the Docker image will start from the Node 0.12 image found on the Docker registry, expose port 8080, copy our `server.js` file to the image and start the Node server. </del> <ins> This "recipe" for the Docker image will start from the official Node.js LTS image found on the Docker registry, expose port 8080, copy our `server.js` file to the image and start the Node server. </ins> Now build an image of your container by running `docker build`, tagging the image with the Google  Container Registry repo for your `PROJECT_ID`:


{ type: 0, name: 'ASM Technologies Limited', <del> logo: 'asmtech', </del> <ins> logo: 'asm', </ins> link: 'http://www.asmtech.com/', <del> blurb: 'http://www.asmtech.com/audience-channels/software_publisher/' </del> <ins> blurb: 'Our technology supply chain portfolio enables your software products to be accessible, viable and available more effectively.' </ins> }, { type: 1,


- Subject-matching properties: - `user`, type string; the user-string from `--token-auth-file`. If you specify `user`, it must match the username of the authenticated user. - `group`, type string; if you specify `group`, it must match one of the groups of the authenticated user. `system:authenticated` matches all authenticated requests. `system:unauthenticated` matches all unauthenticated requests. <del> - `readonly`, type boolean, when true, means that the policy only applies to get, list, and watch operations. </del> - Resource-matching properties: <del> - `apiGroup`, type string; an API group, such as `extensions`. `*` matches all API groups. - `namespace`, type string; a namespace string. `*` matches all resource requests. - `resource`, type string; a resource, such as `pods`. `*` matches all resource requests. </del> <ins> - `apiGroup`, type string; an API group. - Ex: `extensions` - Wildard: `*` matches all API groups. - `namespace`, type string; a namespace. - Ex: `kube-system` - Wildard: `*` matches all resource requests. - `resource`, type string; a resource type - Ex: `pods` - Wildcard: `*` matches all resource requests. </ins> - Non-resource-matching properties: <del> - `nonResourcePath`, type string; matches the non-resource request paths (like `/version` and `/apis`). `*` matches all non-resource requests. `/foo/*` matches `/foo/` and all of its subpaths. </del> <ins> - `nonResourcePath`, type string; non-resource request paths. - Ex: `/version` or `/apis` - Wildcard: - `*` matches all non-resource requests. - `/foo/*` matches `/foo/` and all of its subpaths. - `readonly`, type boolean, when true, means that the policy only applies to get, list, and watch operations. </ins> <del> An unset property is the same as a property set to the zero value for its type </del> <ins> **NOTES:** An unset property is the same as a property set to the zero value for its type </ins> (e.g. empty string, 0, false). However, unset should be preferred for readability.


We also allow users to customize garbage collection policy through the following kubelet flags: 1. `minimum-container-ttl-duration`, minimum age for a finished container before it is <del> garbage collected. Default is 0 minute, which means any finished container will be garbaged collected. 2. `maximum-dead-containers-per-container`, maximum number of old instances to retain </del> <ins> garbage collected. Default is 0 minute, which means every finished container will be garbaged collected. 2. `maximum-dead-containers-per-container`, maximum number of old instances to be retained </ins> per container. Default is 1. 3. `maximum-dead-containers`, maximum number of old instances of containers to retain globally. Default is -1, which means there is no global limit.


Hit enter for command prompt <del> / # wget -s --timeout=1 nginx </del> <ins> / # wget --spider --timeout=1 nginx </ins> Connecting to nginx (10.100.0.16:80) wget: download timed out / #


Hit enter for command prompt <del> / # wget -s --timeout=1 nginx </del> <ins> / # wget --spider --timeout=1 nginx </ins> Connecting to nginx (10.100.0.16:80) / # ```


--- assignees: - bboreham <del> title: Weave Net Addon </del> <ins> title: Using Weave Net for NetworkPolicy </ins> --- The [Weave Net Addon](https://www.weave.works/docs/net/latest/kube-addon/) for Kubernetes comes with a Network Policy Controller.


The Master is responsible for managing the cluster. The master coordinates all activities in your cluster, such as scheduling applications, maintaining applications' desired state, scaling applications, and rolling out new updates.

A node is a VM or a physical computer that serves as a worker machine in a Kubernetes cluster. Each node has a Kubelet, which is an agent for managing the node and communicating with the Kubernetes master. The node should also have tools for handling container operations, such as Docker or rtk. A Kubernetes cluster that handles production traffic should have a minimum of three nodes.

A node is a VM or a physical computer that serves as a worker machine in a Kubernetes cluster. Each node has a Kubelet, which is an agent for managing the node and communicating with the Kubernetes master. The node should also have tools for handling container operations, such as Docker or rkt. A Kubernetes cluster that handles production traffic should have a minimum of three nodes.


Now, re-run the test: ```console <del> $ for node in $NODES; do curl --connect-timeout 1 -s $node:$NODEPORT | grep -i client_address; do </del> <ins> $ for node in $NODES; do curl --connect-timeout 1 -s $node:$NODEPORT | grep -i client_address; done </ins> client_address=104.132.1.79 ```


(backward-compatible) changes to the way the Kubernetes cluster DNS server processes DNS queries, to facilitate the lookup of federated services (which span multiple Kubernetes clusters). <del> See the [Cluster Federation Administrators' Guide](/docs/admin/federation/index.md) for more </del> <ins> See the [Cluster Federation Administrators' Guide](/docs/admin/federation) for more </ins> details on Cluster Federation and multi-site support. ## References


<ins> # *Stop.  This guide has been superseded by [Minikube](../minikube/). The link below is present only for historical purposes* The document has been moved to [here](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/local-cluster/docker.md) </ins>


### SEE ALSO <del> * [kubectl](kubectl.md)	 - kubectl controls the Kubernetes cluster manager </del> <ins> * [kubectl](../kubectl.md)	 - kubectl controls the Kubernetes cluster manager </ins> ###### Auto generated by spf13/cobra on 12-Aug-2016


are certain circumstances where two jobs might be created, or no job might be created. We attempt to make these rare, but do not completely prevent them. Therefore, jobs should be _idempotent_. <del> The job is responsible for retrying pods, parallelism among pods it creates, and determining the success or failure of the set of pods. A cron job does not examine pods at all. </del> <ins> If `startingDeadlineSeconds` is set to a large value or left unset (the default) and if `concurrentPolicy` is set to `AllowConcurrent`, the jobs will always run at least once. Jobs may fail to run if the CronJob controller is not running or broken for a span of time from before the start time of the CronJob to start time plus `startingDeadlineSeconds`, or if the span covers multiple start times and `concurrencyPolicy` does not allow concurrency. For example, suppose a cron job is set to start at exactly `08:30:00` and its `startingDeadlineSeconds` is set to 10, if the CronJob controller happens to be down from `08:29:00` to `08:42:00`, the job will not start. Set a longer `startingDeadlineSeconds` if starting later is better than not starting at all. The job is only responsible for creating Jobs that match its schedule, and the the Job in turn is responsible for the management of the Pods it represents. </ins> ## Writing a Cron Job Spec


38s        37s        2    {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}                Warning        FailedSync    Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1" 1m         22s         2     {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}    spec.containers{main}    Warning        FailedPostStartHook ``` <ins> ## What's Next - See an example of [using container lifecycle hooks](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/) </ins>


kubectl exec -ti cassandra-0 -- nodetool status # cleanup <del> grace=$(kubectl get po cassandra-0 --template '{{.spec.terminationGracePeriodSeconds}}')  </del> <ins> grace=$(kubectl get po cassandra-0 -o=jsonpath='{.spec.terminationGracePeriodSeconds}')  </ins> && kubectl delete statefulset,po -l app=cassandra  && echo "Sleeping $grace"  && sleep $grace


Use the following commands to delete the StatefulSet. ```console <del> $ grace=$(kubectl get po cassandra-0 --template '{{.spec.terminationGracePeriodSeconds}}')  </del> <ins> $ grace=$(kubectl get po cassandra-0 -o=jsonpath='{.spec.terminationGracePeriodSeconds}')  </ins> && kubectl delete statefulset -l app=cassandra  && echo "Sleeping $grace"  && sleep $grace


--- <del> redirect_from: - "/docs/tutorials/getting-started/create-cluster/" - "/docs/tutorials/getting-started/create-cluster.html" </del> title: 使用 Minikube 创建一个集群 ---


--- title: 使用命令式的方式管理 Kubernetes 对象 <del> redirect_from: - "/docs/concepts/tools/kubectl/object-management-using-imperative-commands/" - "/docs/concepts/tools/kubectl/object-management-using-imperative-commands.html" </del> --- {% capture overview %}


--- title: Kubernetes 对象管理 <del> redirect_from: - "/docs/concepts/tools/kubectl/object-management-overview/" - "/docs/concepts/tools/kubectl/object-management-overview.html" - "/docs/user-guide/working-with-resources/" - "/docs/user-guide/working-with-resources.html" </del> --- {% capture overview %}


/docs/admin/     /docs/concepts/cluster-administration/cluster-administration-overview/ 301 /docs/admin/add-ons/     /docs/concepts/cluster-administration/addons/ 301 <ins> /docs/admin/addons/     /docs/concepts/cluster-administration/addons/ 301 </ins> /docs/admin/apparmor/     /docs/tutorials/clusters/apparmor/ 301 /docs/admin/audit/     /docs/tasks/debug-application-cluster/audit/ 301 /docs/admin/authorization/rbac.md     /docs/admin/authorization/rbac/ 301


* One or more machines running Ubuntu 16.04+, Debian 9, CentOS 7, RHEL 7, Fedora 25/26 (best-effort) or HypriotOS v1.0.1+ * 1GB or more of RAM per machine (any less will leave little room for your apps) * Full network connectivity between all machines in the cluster (public or private network is fine) <del> * Unique MAC address and product_uuid for every node </del> <ins> * Unique hostname, MAC address, and product_uuid for every node </ins> * Certain ports are open on your machines. See the section below for more details * Swap disabled. You must disable swap in order for the kubelet to work properly. * Set `/proc/sys/net/bridge/bridge-nf-call-iptables` to `1` by running `sysctl net.bridge.bridge-nf-call-iptables=1`


* [Daemon Sets](http://kubernetes.io/docs/admin/daemons/) which ensure that all or some of the nodes in your cluster run a copy of a Pod. * [Deployments](http://kubernetes.io/docs/user-guide/deployments/) which provide declarative updates for Pods and Replica Sets (the next-generation [Replication Controller](http://kubernetes.io/docs/user-guide/replication-controller/)) The Details page for a Deployment lists resource details, as well as new and old Replica Sets. The resource details also include information on the [RollingUpdate](http://kubernetes.io/docs/user-guide/rolling-updates/) strategy, if any. <del> * [Pet Sets](http://kubernetes.io/docs/user-guide/load-balancer/) (nominal Services, also known as load-balanced Services) for legacy application support. </del> <ins> * [Pet Sets](http://kubernetes.io/docs/user-guide/petset/) (nominal Services, also known as load-balanced Services) for legacy application support. </ins> * [Replica Sets](http://kubernetes.io/docs/user-guide/replicasets/) for using label selectors. * [Jobs](http://kubernetes.io/docs/user-guide/jobs/) for creating one or more Pods, ensuring that a specified number of them successfully terminate, and tracking the completions. * [Replication Controllers](http://kubernetes.io/docs/user-guide/replication-controller/)


<del> --- reviewers: - davidopp - madhusudancs title: Configure Multiple Schedulers content_type: task --- <!-- overview --> Kubernetes ships with a default scheduler that is described [here](/docs/admin/kube-scheduler/). If the default scheduler does not suit your needs you can implement your own scheduler. Not just that, you can even run multiple schedulers simultaneously alongside the default scheduler and instruct Kubernetes what scheduler to use for each of your pods. Let's learn how to run multiple schedulers in Kubernetes with an example. A detailed description of how to implement a scheduler is outside the scope of this document. Please refer to the kube-scheduler implementation in [pkg/scheduler](https://github.com/kubernetes/kubernetes/tree/{{< param "githubbranch" >}}/pkg/scheduler) in the Kubernetes source directory for a canonical example. ## {{% heading "prerequisites" %}} {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} <!-- steps --> ## Package the scheduler Package your scheduler binary into a container image. For the purposes of this example, let's just use the default scheduler (kube-scheduler) as our second scheduler as well. Clone the [Kubernetes source code from GitHub](https://github.com/kubernetes/kubernetes) and build the source. ```shell git clone https://github.com/kubernetes/kubernetes.git cd kubernetes make ``` Create a container image containing the kube-scheduler binary. Here is the `Dockerfile` to build the image: ```docker FROM busybox ADD ./_output/local/bin/linux/amd64/kube-scheduler /usr/local/bin/kube-scheduler ``` Save the file as `Dockerfile`, build the image and push it to a registry. This example pushes the image to [Google Container Registry (GCR)](https://cloud.google.com/container-registry/). For more details, please read the GCR [documentation](https://cloud.google.com/container-registry/docs/). ```shell docker build -t gcr.io/my-gcp-project/my-kube-scheduler:1.0 . gcloud docker -- push gcr.io/my-gcp-project/my-kube-scheduler:1.0 ``` ## Define a Kubernetes Deployment for the scheduler Now that we have our scheduler in a container image, we can just create a pod config for it and run it in our Kubernetes cluster. But instead of creating a pod directly in the cluster, let's use a [Deployment](/docs/concepts/workloads/controllers/deployment/) for this example. A [Deployment](/docs/concepts/workloads/controllers/deployment/) manages a [Replica Set](/docs/concepts/workloads/controllers/replicaset/) which in turn manages the pods, thereby making the scheduler resilient to failures. Here is the deployment config. Save it as `my-scheduler.yaml`: {{< codenew file="admin/sched/my-scheduler.yaml" >}} An important thing to note here is that the name of the scheduler specified as an argument to the scheduler command in the container spec should be unique. This is the name that is matched against the value of the optional `spec.schedulerName` on pods, to determine whether this scheduler is responsible for scheduling a particular pod. Note also that we created a dedicated service account `my-scheduler` and bind the cluster role `system:kube-scheduler` to it so that it can acquire the same privileges as `kube-scheduler`. Please see the [kube-scheduler documentation](/docs/admin/kube-scheduler/) for detailed description of other command line arguments. ## Run the second scheduler in the cluster In order to run your scheduler in a Kubernetes cluster, just create the deployment specified in the config above in a Kubernetes cluster: ```shell kubectl create -f my-scheduler.yaml ``` Verify that the scheduler pod is running: ```shell kubectl get pods --namespace=kube-system ``` ``` NAME                                           READY     STATUS    RESTARTS   AGE .... my-scheduler-lnf4s-4744f                       1/1       Running   0          2m ... ``` You should see a "Running" my-scheduler pod, in addition to the default kube-scheduler pod in this list. ### Enable leader election To run multiple-scheduler with leader election enabled, you must do the following: First, update the following fields in your YAML file: * `--leader-elect=true` * `--lock-object-namespace=<lock-object-namespace>` * `--lock-object-name=<lock-object-name>` {{< note >}} The control plane creates the lock objects for you, but the namespace must already exist. You can use the `kube-system` namespace. {{< /note >}} If RBAC is enabled on your cluster, you must update the `system:kube-scheduler` cluster role. Add your scheduler name to the resourceNames of the rule applied for `endpoints` and `leases` resources, as in the following example: ``` kubectl edit clusterrole system:kube-scheduler ``` ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:kube-scheduler rules: - apiGroups: - coordination.k8s.io resources: - leases verbs: - create - apiGroups: - coordination.k8s.io resourceNames: - kube-scheduler - my-scheduler resources: - leases verbs: - get - update - apiGroups: - "" resourceNames: - kube-scheduler - my-scheduler resources: - endpoints verbs: - delete - get - patch - update ``` ## Specify schedulers for pods Now that our second scheduler is running, let's create some pods, and direct them to be scheduled by either the default scheduler or the one we just deployed. In order to schedule a given pod using a specific scheduler, we specify the name of the scheduler in that pod spec. Let's look at three examples. - Pod spec without any scheduler name {{< codenew file="admin/sched/pod1.yaml" >}} When no scheduler name is supplied, the pod is automatically scheduled using the default-scheduler. Save this file as `pod1.yaml` and submit it to the Kubernetes cluster. ```shell kubectl create -f pod1.yaml ``` - Pod spec with `default-scheduler` {{< codenew file="admin/sched/pod2.yaml" >}} A scheduler is specified by supplying the scheduler name as a value to `spec.schedulerName`. In this case, we supply the name of the default scheduler which is `default-scheduler`. Save this file as `pod2.yaml` and submit it to the Kubernetes cluster. ```shell kubectl create -f pod2.yaml ``` - Pod spec with `my-scheduler` {{< codenew file="admin/sched/pod3.yaml" >}} In this case, we specify that this pod should be scheduled using the scheduler that we deployed - `my-scheduler`. Note that the value of `spec.schedulerName` should match the name supplied to the scheduler command as an argument in the deployment config for the scheduler. Save this file as `pod3.yaml` and submit it to the Kubernetes cluster. ```shell kubectl create -f pod3.yaml ``` Verify that all three pods are running. ```shell kubectl get pods ``` <!-- discussion --> ### Verifying that the pods were scheduled using the desired schedulers In order to make it easier to work through these examples, we did not verify that the pods were actually scheduled using the desired schedulers. We can verify that by changing the order of pod and deployment config submissions above. If we submit all the pod configs to a Kubernetes cluster before submitting the scheduler deployment config, we see that the pod `annotation-second-scheduler` remains in "Pending" state forever while the other two pods get scheduled. Once we submit the scheduler deployment config and our new scheduler starts running, the `annotation-second-scheduler` pod gets scheduled as well. Alternatively, one could just look at the "Scheduled" entries in the event logs to verify that the pods were scheduled by the desired schedulers. ```shell kubectl get events ``` </del>


<ins> --- reviewers: - davidopp - madhusudancs title: Configure Multiple Schedulers content_type: task weight: 20 --- <!-- overview --> Kubernetes ships with a default scheduler that is described [here](/docs/admin/kube-scheduler/). If the default scheduler does not suit your needs you can implement your own scheduler. Not just that, you can even run multiple schedulers simultaneously alongside the default scheduler and instruct Kubernetes what scheduler to use for each of your pods. Let's learn how to run multiple schedulers in Kubernetes with an example. A detailed description of how to implement a scheduler is outside the scope of this document. Please refer to the kube-scheduler implementation in [pkg/scheduler](https://github.com/kubernetes/kubernetes/tree/{{< param "githubbranch" >}}/pkg/scheduler) in the Kubernetes source directory for a canonical example. ## {{% heading "prerequisites" %}} {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} <!-- steps --> ## Package the scheduler Package your scheduler binary into a container image. For the purposes of this example, let's just use the default scheduler (kube-scheduler) as our second scheduler as well. Clone the [Kubernetes source code from GitHub](https://github.com/kubernetes/kubernetes) and build the source. ```shell git clone https://github.com/kubernetes/kubernetes.git cd kubernetes make ``` Create a container image containing the kube-scheduler binary. Here is the `Dockerfile` to build the image: ```docker FROM busybox ADD ./_output/local/bin/linux/amd64/kube-scheduler /usr/local/bin/kube-scheduler ``` Save the file as `Dockerfile`, build the image and push it to a registry. This example pushes the image to [Google Container Registry (GCR)](https://cloud.google.com/container-registry/). For more details, please read the GCR [documentation](https://cloud.google.com/container-registry/docs/). ```shell docker build -t gcr.io/my-gcp-project/my-kube-scheduler:1.0 . gcloud docker -- push gcr.io/my-gcp-project/my-kube-scheduler:1.0 ``` ## Define a Kubernetes Deployment for the scheduler Now that we have our scheduler in a container image, we can just create a pod config for it and run it in our Kubernetes cluster. But instead of creating a pod directly in the cluster, let's use a [Deployment](/docs/concepts/workloads/controllers/deployment/) for this example. A [Deployment](/docs/concepts/workloads/controllers/deployment/) manages a [Replica Set](/docs/concepts/workloads/controllers/replicaset/) which in turn manages the pods, thereby making the scheduler resilient to failures. Here is the deployment config. Save it as `my-scheduler.yaml`: {{< codenew file="admin/sched/my-scheduler.yaml" >}} An important thing to note here is that the name of the scheduler specified as an argument to the scheduler command in the container spec should be unique. This is the name that is matched against the value of the optional `spec.schedulerName` on pods, to determine whether this scheduler is responsible for scheduling a particular pod. Note also that we created a dedicated service account `my-scheduler` and bind the cluster role `system:kube-scheduler` to it so that it can acquire the same privileges as `kube-scheduler`. Please see the [kube-scheduler documentation](/docs/admin/kube-scheduler/) for detailed description of other command line arguments. ## Run the second scheduler in the cluster In order to run your scheduler in a Kubernetes cluster, just create the deployment specified in the config above in a Kubernetes cluster: ```shell kubectl create -f my-scheduler.yaml ``` Verify that the scheduler pod is running: ```shell kubectl get pods --namespace=kube-system ``` ``` NAME                                           READY     STATUS    RESTARTS   AGE .... my-scheduler-lnf4s-4744f                       1/1       Running   0          2m ... ``` You should see a "Running" my-scheduler pod, in addition to the default kube-scheduler pod in this list. ### Enable leader election To run multiple-scheduler with leader election enabled, you must do the following: First, update the following fields in your YAML file: * `--leader-elect=true` * `--lock-object-namespace=<lock-object-namespace>` * `--lock-object-name=<lock-object-name>` {{< note >}} The control plane creates the lock objects for you, but the namespace must already exist. You can use the `kube-system` namespace. {{< /note >}} If RBAC is enabled on your cluster, you must update the `system:kube-scheduler` cluster role. Add your scheduler name to the resourceNames of the rule applied for `endpoints` and `leases` resources, as in the following example: ``` kubectl edit clusterrole system:kube-scheduler ``` ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:kube-scheduler rules: - apiGroups: - coordination.k8s.io resources: - leases verbs: - create - apiGroups: - coordination.k8s.io resourceNames: - kube-scheduler - my-scheduler resources: - leases verbs: - get - update - apiGroups: - "" resourceNames: - kube-scheduler - my-scheduler resources: - endpoints verbs: - delete - get - patch - update ``` ## Specify schedulers for pods Now that our second scheduler is running, let's create some pods, and direct them to be scheduled by either the default scheduler or the one we just deployed. In order to schedule a given pod using a specific scheduler, we specify the name of the scheduler in that pod spec. Let's look at three examples. - Pod spec without any scheduler name {{< codenew file="admin/sched/pod1.yaml" >}} When no scheduler name is supplied, the pod is automatically scheduled using the default-scheduler. Save this file as `pod1.yaml` and submit it to the Kubernetes cluster. ```shell kubectl create -f pod1.yaml ``` - Pod spec with `default-scheduler` {{< codenew file="admin/sched/pod2.yaml" >}} A scheduler is specified by supplying the scheduler name as a value to `spec.schedulerName`. In this case, we supply the name of the default scheduler which is `default-scheduler`. Save this file as `pod2.yaml` and submit it to the Kubernetes cluster. ```shell kubectl create -f pod2.yaml ``` - Pod spec with `my-scheduler` {{< codenew file="admin/sched/pod3.yaml" >}} In this case, we specify that this pod should be scheduled using the scheduler that we deployed - `my-scheduler`. Note that the value of `spec.schedulerName` should match the name supplied to the scheduler command as an argument in the deployment config for the scheduler. Save this file as `pod3.yaml` and submit it to the Kubernetes cluster. ```shell kubectl create -f pod3.yaml ``` Verify that all three pods are running. ```shell kubectl get pods ``` <!-- discussion --> ### Verifying that the pods were scheduled using the desired schedulers In order to make it easier to work through these examples, we did not verify that the pods were actually scheduled using the desired schedulers. We can verify that by changing the order of pod and deployment config submissions above. If we submit all the pod configs to a Kubernetes cluster before submitting the scheduler deployment config, we see that the pod `annotation-second-scheduler` remains in "Pending" state forever while the other two pods get scheduled. Once we submit the scheduler deployment config and our new scheduler starts running, the `annotation-second-scheduler` pod gets scheduled as well. Alternatively, one could just look at the "Scheduled" entries in the event logs to verify that the pods were scheduled by the desired schedulers. ```shell kubectl get events ``` </ins>


/docs/tasks/administer-cluster/certificate-rotation/     /docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/ 301 /docs/tasks/administer-cluster/cilium-network-policy/     /docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy/ 301 /docs/tasks/administer-cluster/configure-namespace-isolation/     /docs/concepts/services-networking/network-policies/ 301 <ins> /docs/tasks/administer-cluster/configure-multiple-schedulers/     /docs/tasks/extend-kubernetes/configure-multiple-schedulers/ 301 </ins> /docs/tasks/administer-cluster/configure-pod-disruption-budget/     /docs/tasks/run-application/configure-pdb/ 301 /docs/tasks/administer-cluster/cpu-constraint-namespace/     /docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/ 301 /docs/tasks/administer-cluster/cpu-default-namespace/     /docs/tasks/administer-cluster/manage-resources/cpu-default-namespace 301


flag in the `docker run` command. - The `spec.containers[].resources.limits.cpu` is converted to its millicore value and <del> multiplied by 100. The resulting value is the total amount of CPU time that a container can use every 100ms. A container cannot use more than its share of CPU time during this interval. </del> <ins> multiplied by 100. The resulting value is the total amount of CPU time in microseconds that a container can use every 100ms. A container cannot use more than its share of CPU time during this interval. </ins> {{< note >}} The default quota period is 100ms. The minimum resolution of CPU quota is 1ms.


These controllers include: <del> * Node Controller * Responsible for noticing & responding when nodes go down. * Replication Controller * Responsible for maintaining the correct number of pods for every replication controller object in the system. * Endpoints Controller * Populates the Endpoints object (i.e., join Services & Pods). * Service Account & Token Controllers * Create default accounts and API access tokens for new namespaces. </del> <ins> * Node Controller: Responsible for noticing & responding when nodes go down. * Replication Controller: Responsible for maintaining the correct number of pods for every replication controller object in the system. * Endpoints Controller: Populates the Endpoints object (i.e., join Services & Pods). * Service Account & Token Controllers: Create default accounts and API access tokens for new namespaces. </ins> * ... and others. ### kube-scheduler


Scalable tracking of network endpoints in a Kubernetes cluster. content_template: templates/concept <del> weight: 10 </del> <ins> weight: 15 </ins> ---


kubectl get svc my-nginx ``` ``` <del> NAME       TYPE        CLUSTER-IP     EXTERNAL-IP        PORT(S)               AGE my-nginx   ClusterIP   10.0.162.149   162.222.184.144    80/TCP,81/TCP,82/TCP  21s </del> <ins> NAME       TYPE           CLUSTER-IP     EXTERNAL-IP        PORT(S)               AGE my-nginx   LoadBalancer   10.0.162.149     xx.xxx.xxx.xxx     8080:30163/TCP        21s </ins> ``` ``` curl https://<EXTERNAL-IP> -k


[blackfriday] hrefTargetBlank = true fractions = false <ins> smartDashes = false </ins> [frontmatter] date = ["date", ":filename", "publishDate", "lastmod"]


<ins> --- title: Kindを使用してKubernetesをインストールする weight: 40 content_type: concept --- <!-- overview --> Kindは、Dockerコンテナをノードとして使用して、ローカルのKubernetesクラスターを実行するためのツールです。 <!-- body --> ## インストール [Kindをインストールする](https://kind.sigs.k8s.io/docs/user/quick-start/)を参照してください。 </ins>


* [Introduction to Kubernetes (edX)](https://www.edx.org/course/introduction-kubernetes-linuxfoundationx-lfs158x#) <del> * [Hello Minikube](/docs/tutorials/hello-minikube/) </del> <ins> * [Hello Minikube](/es/docs/tutorials/hello-minikube/) </ins> ## Configuración


<ins> --- title: Hello Minikube content_template: templates/tutorial weight: 5 menu: main: title: "Get Started" weight: 10 post: > <p>¿Listo para poner manos a la obra? Construye un clúster sencillo de Kubernetes que ejecuta un Hola Mundo para Node.js</p> card: name: tutorials weight: 10 --- {{% capture overview %}} Este tutorial muestra como ejecutar una aplicación Node.js Hola Mundo en Kubernetes utilizando [Minikube](/docs/setup/learning-environment/minikube) y Katacoda. Katacoda provee un ambiente de Kubernetes desde el navegador. {{< note >}} También se puede  seguir este tutorial si se ha instalado [Minikube localmente](/docs/tasks/tools/install-minikube/). {{< /note >}} {{% /capture %}} {{% capture objectives %}} * Desplegar una aplicación Hola Mundo en Minikube. * Ejecutar la aplicación. * Ver los logs de la aplicación. {{% /capture %}} {{% capture prerequisites %}} Este tutorial provee una imagen de contenedor construida desde los siguientes archivos: {{< codenew language="js" file="minikube/server.js" >}} {{< codenew language="conf" file="minikube/Dockerfile" >}} Para más información sobre el comando `docker build`, lea la [documentación de Docker ](https://docs.docker.com/engine/reference/commandline/build/). {{% /capture %}} {{% capture lessoncontent %}} ## Crear un clúster Minikube 1. Haz clic en **Launch Terminal** {{< kat-button >}} {{< note >}}Si se tiene instalado Minikube local, ejecutar `minikube start`.{{< /note >}} 2. Abrir el tablero de Kubernetes dashboard en un navegador: ```shell minikube dashboard ``` 3. Solo en el ambiente de Katacoda: En la parte superior de la terminal, haz clic en el símbolo + y luego clic en **Select port to view on Host 1**. 4. Solo en el ambiente de Katacoda: Escribir `30000`, y hacer clic en **Display Port**. ## Crear un Deployment Un [*Pod*](/docs/concepts/workloads/pods/pod/) en Kubernetes es un grupo de uno o más contenedores, asociados con propósitos de administración y redes. El Pod en este tutorial tiene solo un contenedor. Un [*Deployment*](/docs/concepts/workloads/controllers/deployment/) en Kubernetes verifica la salud del Pod y reinicia su contenedor si este es eliminado. Los Deployments son la manera recomendada de manejar la creación y escalación. 1. Ejecutar el comando `kubectl create` para crear un Deployment que maneje un Pod. El Pod ejecuta un contenedor basado en la imagen proveida por Docker. ```shell kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4 ``` 2. Ver el Deployment: ```shell kubectl get deployments ``` El resultado es similar a: ``` NAME         READY   UP-TO-DATE   AVAILABLE   AGE hello-node   1/1     1            1           1m ``` 3. Ver el Pod: ```shell kubectl get pods ``` El resultado es similar a: ``` NAME                          READY     STATUS    RESTARTS   AGE hello-node-5f76cf6ccf-br9b5   1/1       Running   0          1m ``` 4. Ver los eventos del clúster: ```shell kubectl get events ``` 5. Ver la configuración `kubectl`: ```shell kubectl config view ``` {{< note >}} Para más información sobre el comando `kubectl`, ver [kubectl overview](/docs/user-guide/kubectl-overview/).{{< /note >}} ## Crear un Service Por defecto, el Pod es accedido por su dirección IP interna dentro del clúster de Kubernetes, para hacer que el contenedor `hello-node` sea accesible desde afuera de la red virtual Kubernetes, se debe exponer el Pod como un [*Service*](/docs/concepts/services-networking/service/) de Kubernetes. 1. Exponer el Pod a la red pública de internet utilizando el comando `kubectl expose`: ```shell kubectl expose deployment hello-node --type=LoadBalancer --port=8080 ``` El flag `--type=LoadBalancer` indica que se quiere exponer el Service fuera del clúster. 2. Ver el Service creado: ```shell kubectl get services ``` El resultado es similar a: ``` NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE hello-node   LoadBalancer   10.108.144.78   <pending>     8080:30369/TCP   21s kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP          23m ``` Para los proveedores Cloud que soportan balanceadores de carga, una dirección IP externa será provisionada para acceder al servicio, en Minikube, el tipo `LoadBalancer` permite que el servicio sea accesible a través del comando `minikube service`. 3. Ejecutar el siguiente comando: ```shell minikube service hello-node ``` 4. Solo en el ambiente de Katacoda: Hacer clic sobre el símbolo +, y luego en **Select port to view on Host 1**. 5. Solo en el ambiente de Katacoda: Anotar el puerto de 5 dígitos ubicado al lado del valor de `8080` en el resultado de servicios. Este número de puerto es generado aleatoriamente y puede ser diferente al indicado en el ejemplo. Escribir el número de puerto en el cuadro de texto y hacer clic en Display Port. Usando el ejemplo anterior, usted escribiría `30369`. Esto abre una ventana de navegador que contiene la aplicación y muestra el mensaje "Hello World". ## Habilitar Extensiones Minikube tiene un conjunto  de {{< glossary_tooltip text="Extensiones" term_id="addons" >}} que pueden ser habilitados y desahabilitados en el ambiente local de Kubernetes. 1. Listar las extensiones soportadas actualmente: ```shell minikube addons list ``` El resultado es similar a: ``` addon-manager: enabled dashboard: enabled default-storageclass: enabled efk: disabled freshpod: disabled gvisor: disabled helm-tiller: disabled ingress: disabled ingress-dns: disabled logviewer: disabled metrics-server: disabled nvidia-driver-installer: disabled nvidia-gpu-device-plugin: disabled registry: disabled registry-creds: disabled storage-provisioner: enabled storage-provisioner-gluster: disabled ``` 2. Habilitar una extensión, por ejemplo, `metrics-server`: ```shell minikube addons enable metrics-server ``` El resultado es similar a: ``` metrics-server was successfully enabled ``` 3. Ver el Pod y Service creados: ```shell kubectl get pod,svc -n kube-system ``` El resultado es similar a: ``` NAME                                        READY     STATUS    RESTARTS   AGE pod/coredns-5644d7b6d9-mh9ll                1/1       Running   0          34m pod/coredns-5644d7b6d9-pqd2t                1/1       Running   0          34m pod/metrics-server-67fb648c5                1/1       Running   0          26s pod/etcd-minikube                           1/1       Running   0          34m pod/influxdb-grafana-b29w8                  2/2       Running   0          26s pod/kube-addon-manager-minikube             1/1       Running   0          34m pod/kube-apiserver-minikube                 1/1       Running   0          34m pod/kube-controller-manager-minikube        1/1       Running   0          34m pod/kube-proxy-rnlps                        1/1       Running   0          34m pod/kube-scheduler-minikube                 1/1       Running   0          34m pod/storage-provisioner                     1/1       Running   0          34m NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE service/metrics-server         ClusterIP   10.96.241.45    <none>        80/TCP              26s service/kube-dns               ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP       34m service/monitoring-grafana     NodePort    10.99.24.54     <none>        80:30002/TCP        26s service/monitoring-influxdb    ClusterIP   10.111.169.94   <none>        8083/TCP,8086/TCP   26s ``` 4. Deshabilitar `metrics-server`: ```shell minikube addons disable metrics-server ``` El resultado es similar a: ``` metrics-server was successfully disabled ``` ## Limpieza Ahora se puede eliminar los recursos creados en el clúster: ```shell kubectl delete service hello-node kubectl delete deployment hello-node ``` Opcional, detener la máquina virtual de Minikube: ```shell minikube stop ``` Opcional, eliminar la máquina virtual de Minikube: ```shell minikube delete ``` {{% /capture %}} {{% capture whatsnext %}} * Leer más sobre [Deployments](/docs/concepts/workloads/controllers/deployment/). * Leer más sobre [Desplegando aplicaciones](/docs/tasks/run-application/run-stateless-application-deployment/). * Leer más sobre [Services](/docs/concepts/services-networking/service/). {{% /capture %}} </ins>


<ins> FROM node:6.14.2 EXPOSE 8080 COPY server.js . CMD [ "node", "server.js" ] </ins>


<ins> var http = require('http'); var handleRequest = function(request, response) { console.log('Received request for URL: ' + request.url); response.writeHead(200); response.end('Hello World!'); }; var www = http.createServer(handleRequest); www.listen(8080); </ins>


• [VirtualBox](https://www.virtualbox.org/wiki/Downloads) <del> {{< note >}} minikubeは、VMではなくホストでKubernetesコンポーネントを実行する`--vm-driver=none`オプションもサポートしています。 </del> <ins> Minikubeは、VMではなくホストでKubernetesコンポーネントを実行する`--vm-driver=none`オプションもサポートしています。 </ins> このドライバーを使用するには、[Docker](https://www.docker.com/products/docker-desktop)とLinux環境が必要ですが、ハイパーバイザーは不要です。 <del> noneドライバーを使用する場合は、[Docker](https://www.docker.com/products/docker-desktop)からdockerのaptインストールを使用することをおすすめします。 dockerのsnapインストールは、minikubeでは機能しません。 {{< /note >}} </del> <ins> Debian系のLinuxで`none`ドライバーを使用する場合は、snapパッケージではなく`.deb`パッケージを使用してDockerをインストールしてください。snapパッケージはMinikubeでは機能しません。 [Docker](https://www.docker.com/products/docker-desktop)から`.deb`パッケージをダウンロードできます。 {{< caution >}} `none` VMドライバーは、セキュリティとデータ損失の問題を引き起こす可能性があります。 `--vm-driver=none`を使用する前に、詳細について[このドキュメント](https://minikube.sigs.k8s.io/docs/reference/drivers/none/) を参照してください。 {{< /caution >}} MinikubeはDockerドライバーと似たような`vm-driver=podman`もサポートしています。Podmanを特権ユーザー権限(root user)で実行することは、コンテナがシステム上の利用可能な機能へ完全にアクセスするための最もよい方法です。 {{< caution >}} `podman` ドライバーは、rootでコンテナを実行する必要があります。これは、通常のユーザーアカウントが、コンテナの実行に必要とされるすべてのOS機能への完全なアクセスを持っていないためです。 {{< /caution >}} </ins> ### パッケージを利用したMinikubeのインストール


sudo install minikube /usr/local/bin/ ``` <ins> ### Homebrewを利用したMinikubeのインストール 別の選択肢として、Linux [Homebrew](https://docs.brew.sh/Homebrew-on-Linux)を利用してインストールできます。 ```shell brew install minikube ``` </ins> {{% /tab %}} {{% tab name="macOS" %}} ### kubectlのインストール


{{% /capture %}} <ins> ## インストールの確認 ハイパーバイザーとMinikube両方のインストール成功を確認するため、以下のコマンドをローカルKubernetesクラスターを起動するために実行してください: {{< note >}} `minikube start`で`--vm-driver`の設定をするため、次の`<driver_name>`の部分では、インストールしたハイパーバイザーの名前を小文字で入力してください。`--vm-driver`値のすべてのリストは、[specifying the VM driver documentation](https://kubernetes.io/docs/setup/learning-environment/minikube/#specifying-the-vm-driver)で確認できます。 {{< /note >}} ```shell minikube start --vm-driver=<driver_name> ``` `minikube start`が完了した場合、次のコマンドを実行してクラスターの状態を確認します。 ```shell minikube status ``` クラスターが起動していると、`minikube status`の出力はこのようになります。 ``` host: Running kubelet: Running apiserver: Running kubeconfig: Configured ``` 選択したハイパーバイザーでMinikubeが動作しているか確認した後は、そのままMinikubeを使い続けることもできます。また、クラスターを停止することもできます。クラスターを停止するためには、次を実行してください。 ```shell minikube stop ``` </ins> ## ローカル状態のクリーンアップ {#cleanup-local-state} もし以前に　Minikubeをインストールしていたら、以下のコマンドを実行します。


- A user who can create a Pod that uses a secret can also see the value of that secret. Even if the API server policy does not allow that user to read the Secret, the user could run a Pod which exposes the secret. <del> - Currently, anyone with root permission on any node can read _any_ secret from the API server, by impersonating the kubelet. It is a planned feature to only send secrets to nodes that actually require them, to restrict the impact of a root exploit on a single node. </del> ## {{% heading "whatsnext" %}}


<ins> --- title: Secret id: secret date: 2018-04-12 full_link: /ja/docs/concepts/configuration/secret/ short_description: > パスワードやOAuthトークン、SSHキーのような機密の情報を保持します。 aka: tags: - core-object - security --- パスワードやOAuthトークン、SSHキーのような機密の情報を保持します。 <!--more--> 機密情報の取り扱い方法を細かく制御することができ、保存時には[暗号化](/ja/docs/tasks/administer-cluster/encrypt-data/#ensure-all-secrets-are-encrypted)するなど、誤って公開してしまうリスクを減らすことができます。{{< glossary_tooltip text="Pod" term_id="pod" >}}は、ボリュームマウントされたファイルとして、またはPodのイメージをPullするkubeletによって、Secretを参照します。Secretは機密情報を扱うのに最適で、機密でない情報には[ConfigMap](/ja/docs/tasks/configure-pod-container/configure-pod-configmap/)が適しています。 </ins>


Example: <del> If `kube-proxy` version is **{{< skew latestVersion >}}**: </del> <ins> If `kube-proxy` version is **{{< skew oldestMinorVersion >}}**: </ins> <del> * `kubelet` version must be at the same minor version as **{{< skew latestVersion >}}**. </del> <ins> * `kubelet` version must be at the same minor version as **{{< skew oldestMinorVersion >}}**. </ins> * `kube-apiserver` version must be between **{{< skew oldestMinorVersion >}}** and **{{< skew latestVersion >}}**, inclusive.


英語 | 日本語 --------- | --------- <del> cluster|クラスター orchestrate(動詞)|オーケストレーションする Persistent Volume|KubernetesリソースとしてのPersistentVolumeはママ表記、一般的な用語としての場合は、永続ボリューム Deployment/Deploy|KubernetesリソースとしてのDeploymentはママ表記、一般的な用語としてのdeployの場合は、デプロイ </del> Addon/Add-on|アドオン <del> Quota|クォータ For more information|さらなる情報(一時的) prefix | プレフィックス container | コンテナ directory | ディレクトリ </del> <ins> Aggregation Layer | アグリゲーションレイヤー architecture | アーキテクチャ </ins> binary | バイナリ <ins> cluster|クラスター community | コミュニティ container | コンテナ </ins> controller | コントローラー <del> operator | オペレーター Aggregation Layer | アグリゲーションレイヤー </del> <ins> Deployment/Deploy|KubernetesリソースとしてのDeploymentはママ表記、一般的な用語としてのdeployの場合は、デプロイ directory | ディレクトリ For more information|さらなる情報(一時的) GitHub | GitHub (ママ表記) </ins> Issue | Issue (ママ表記) <ins> operator | オペレーター orchestrate(動詞)|オーケストレーションする Persistent Volume|KubernetesリソースとしてのPersistentVolumeはママ表記、一般的な用語としての場合は、永続ボリューム prefix | プレフィックス </ins> Pull Request | Pull Request (ママ表記) <del> GitHub | GitHub (ママ表記) </del> <ins> Quota|クォータ </ins> registry | レジストリ <del> architecture | アーキテクチャ </del> secure | セキュア <del> stacked | 積層(例: stacked etcd clusterは積層etcdクラスター) </del> a set of ~ | ～の集合 <del> community | コミュニティ </del> <ins> stacked | 積層(例: stacked etcd clusterは積層etcdクラスター) </ins> ### 備考


<ins> --- title: 역할과 책임 content_type: concept weight: 10 --- <!-- overview --> 누구나 쿠버네티스에 기여할 수 있다. SIG Docs에 대한 기여가 커짐에 따라, 커뮤니티의 다양한 멤버십을 신청할 수 있다. 이러한 역할을 통해 커뮤니티 내에서 더 많은 책임을 질 수 있다. 각 역할마다 많은 시간과 노력이 필요하다. 역할은 다음과 같다. - 모든 사람: 쿠버네티스 문서에 정기적으로 기여하는 기여자 - 멤버: 이슈를 할당, 심사하고 풀 리퀘스트에 대한 구속력 없는 리뷰를 제공할 수 있다. - 리뷰어: 문서의 풀 리퀘스트에 대한 리뷰를 리딩할 수 있으며 변경 사항에 대한 품질을 보증할 수 있다. - 승인자: 문서에 대한 리뷰를 리딩하고 변경 사항을 병합할 수 있다 <!-- body --> ## 모든 사람 GitHub 계정을 가진 누구나 쿠버네티스에 기여할 수 있다. SIG Docs는 모든 새로운 기여자를 환영한다! 모든 사람은 다음의 작업을 할 수 있다. - [`kubernetes/website`](https://github.com/kubernetes/website)를 포함한 모든 [쿠버네티스](https://github.com/kubernetes/) 리포지터리에서 이슈를 올린다. - 풀 리퀘스트에 대해 구속력 없는 피드백을 제공한다. - 현지화에 기여한다. - [슬랙](http://slack.k8s.io/) 또는 [SIG docs 메일링 리스트](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)에 개선을 제안한다. [CLA에 서명](/ko/docs/contribute/new-content/overview/#sign-the-cla) 후에 누구나 다음을 할 수 있다. - 기존 콘텐츠를 개선하거나, 새 콘텐츠를 추가하거나, 블로그 게시물 또는 사례연구 작성을 위해 풀 리퀘스트를 연다. - 다이어그램, 그래픽 자산 그리고 포함할 수 있는 스크린캐스트와 비디오를 제작한다. 자세한 내용은 [새로운 콘텐츠 기여하기](/ko/docs/contribute/new-content/)를 참고한다. ## 멤버 멤버는 `kubernetes/website` 에 여러 개의 풀 리퀘스트를 제출한 사람이다. 멤버는 [쿠버네티스 GitHub 조직](https://github.com/kubernetes)의 회원이다. 멤버는 다음의 작업을 할 수 있다. - [모든 사람](#모든-사람)에 나열된 모든 것을 한다. - 풀 리퀘스트에 `/lgtm` 코멘트를 사용하여 LGTM(looks good to me) 레이블을 추가한다. {{< note >}} `/lgtm` 사용은 자동화를 트리거한다. 만약 구속력 없는 승인을 제공하려면, 단순히 "LGTM" 코멘트를 남기는 것도 좋다! {{< /note >}} - `/hold` 코멘트를 사용하여 풀 리퀘스트에 대한 병합을 차단한다. - `/assign` 코멘트를 사용하여 풀 리퀘스트에 리뷰어를 지정한다. - 풀 리퀘스트에 구속력 없는 리뷰를 제공한다. - 자동화를 사용하여 이슈를 심사하고 분류한다. - 새로운 기능에 대한 문서를 작성한다. ### 멤버 되기 최소 5개의 실질적인 풀 리퀘스트를 제출하고 다른 [요구 사항](https://github.com/kubernetes/community/blob/master/community-membership.md#member)을 충족시킨 후, 다음의 단계를 따른다. 1. 멤버십을 [후원](/docs/contribute/advanced#sponsor-a-new-contributor)해줄 두 명의 [리뷰어](#리뷰어) 또는 [승인자](#승인자)를 찾는다. [슬랙의 #sig-docs 채널](https://kubernetes.slack.com) 또는 [SIG Docs 메일링 리스트](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)에서 후원을 요청한다. {{< note >}} SIG Docs 멤버 개인에게 직접 email을 보내거나 슬랙 다이렉트 메시지를 보내지 않는다. 반드시 지원서를 제출하기 전에 후원을 요청해야 한다. {{< /note >}} 1. [`kubernetes/org`](https://github.com/kubernetes/org/) 리포지터리에 GitHub 이슈를 등록한다. **Organization Membership Request** 이슈 템플릿을 사용한다. 1. 후원자에게 GitHub 이슈를 알린다. 다음 중 하나를 수행할 수 있다. - 이슈에서 후원자의 GitHub 사용자 이름을 코멘트로 추가한다. (`@<GitHub-username>`) - 슬랙 또는 이메일을 사용해 이슈 링크를 후원자에게 보낸다. 후원자는 `+1` 투표로 여러분의 요청을 승인할 것이다. 후원자가 요청을 승인하면, 쿠버네티스 GitHub 관리자가 여러분을 멤버로 추가한다. 축하한다! 만약 멤버십이 수락되지 않으면 피드백을 받게 될 것이다. 피드백의 내용을 해결한 후, 다시 지원하자. 1. 여러분의 이메일 계정으로 수신된 쿠버네티스 GitHub 조직으로의 초대를 수락한다. {{< note >}} GitHub은 초대를 여러분 계정의 기본 이메일 주소로 보낸다. {{< /note >}} ## 리뷰어 리뷰어는 열린 풀 리퀘스트를 리뷰할 책임이 있다. 멤버 피드백과는 달리, 여러분은 리뷰어의 피드백을 반드시 해결해야 한다. 리뷰어는 [@kubernetes/sig-docs-{language}-reviews](https://github.com/orgs/kubernetes/teams?query=sig-docs) GitHub 팀의 멤버이다. 리뷰어는 다음의 작업을 수행할 수 있다. - [모든 사람](#모든-사람)과 [멤버](#멤버)에 나열된 모든 것을 수행한다. - 풀 리퀘스트 리뷰와 구속력 있는 피드백을 제공한다. {{< note >}} 구속력 없는 피드백을 제공하려면, 코멘트에 "선택 사항: "과 같은 문구를 접두어로 남긴다. {{< /note >}} - 코드에서 사용자 화면 문자열 편집 - 코드 코멘트 개선 여러분은 SIG DOcs 리뷰어이거나, 특정 주제 영역의 문서에 대한 리뷰어일 수 있다. ### 풀 리퀘스트에 대한 리뷰어 할당 자동화 시스템은 모든 풀 리퀘스트에 대해 리뷰어를 할당한다. `/assign [@_github_handle]` 코멘트를 남겨 특정 사람에게 리뷰를 요청할 수 있다. 지정된 리뷰어가 PR에 코멘트를 남기지 않는다면, 다른 리뷰어가 개입할 수 있다. 필요에 따라 기술 리뷰어를 지정할 수도 있다. ### `/lgtm` 사용하기 LGTM은 "Looks good to me"의 약자이며 풀 리퀘스트가 기술적으로 정확하고 병합할 준비가 되었음을 나타낸다. 모든 PR은 리뷰어의 `/lgtm` 코멘트가 필요하고 병합을 위해 승인자의 `/approve` 코멘트가 필요하다. 리뷰어의 `/lgtm` 코멘트는 구속력 있고 자동화 시스템이 `lgtm` 레이블을 추가하도록 트리거한다. ### 리뷰어 되기 [요건](https://github.com/kubernetes/community/blob/master/community-membership.md#reviewer)을 충족하면, SIG Docs 리뷰어가 될 수 있다. 다른 SIG의 리뷰어는 SIG Docs의 리뷰어 자격에 반드시 별도로 지원해야 한다. 지원하려면, 다음을 수행한다. 1. `kubernetes/website` 리포지터리 내 [OWNERS_ALIASES](https://github.com/kubernetes/website/blob/master/OWNERS) 파일의 섹션에 여러분의 GitHub 사용자 이름을 추가하는 풀 리퀘스트를 연다. {{< note >}} 자신을 추가할 위치가 확실하지 않으면, `sig-docs-ko-reviews` 에 추가한다. {{< /note >}} 1. PR을 하나 이상의 SIG-Docs 승인자(`sig-docs-{language}-owners` 에 나열된 사용자 이름)에게 지정한다. 승인되면, SIG Docs 리더가 적당한 GitHub 팀에 여러분을 추가한다. 일단 추가되면, [K8s-ci-robot](https://github.com/kubernetes/test-infra/tree/master/prow#bots-home)이 새로운 풀 리퀘스트에서 리뷰어로 여러분을 할당하고 제안한다. ## 승인자 승인자는 병합하기 위해 풀 리퀘스트를 리뷰하고 승인한다. 승인자는 [@kubernetes/sig-docs-{language}-owners](https://github.com/orgs/kubernetes/teams/?query=sig-docs) GitHub 팀의 멤버이다. 승인자는 다음의 작업을 할 수 있다. - [모든 사람](#모든-사람), [멤버](#멤버) 그리고 [리뷰어](#리뷰어) 하위의 모든 목록을 할 수 있다. - 코멘트에 `/approve` 를 사용해서 풀 리퀘스트를 승인하고, 병합해서 기여자의 컨텐츠를 게시한다. - 스타일 가이드 개선을 제안한다. - 문서 테스트 개선을 제안한다. - 쿠버네티스 웹사이트 또는 다른 도구 개선을 제안한다. PR에 이미 `/lgtm` 이 있거나, 승인자도 `/lgtm` 코멘트를 남긴다면, PR은 자동으로 병합된다. SIG Docs 승인자는 추가적인 기술 리뷰가 필요치 않는 변경에 대해서만 `/lgtm` 을 남겨야 한다. ### 풀 리퀘스트 승인 승인자와 SIG Docs 리더는 website 리포지터리로 풀 리퀘스트를 병합할 수 있는 유일한 사람들이다. 이것은 특정한 책임이 따른다. - 승인자는 PR들을 리포지터리에 병합하는 `/approve` 명령을 사용할 수 있다. {{< warning >}} 부주의한 머지로 인해 사이트를 파괴할 수 있으므로, 머지할 때에 그 의미를 확인해야 한다. {{< /warning >}} - 제안된 변경이 [컨트리뷰션 가이드 라인](/docs/contribute/style/content-guide/#contributing-content)에 적합한지 확인한다. 질문이 생기거나 확실하지 않다면 자유롭게 추가 리뷰를 요청한다. - PR을 `/approve` 하기 전에 Netlify 테스트 결과를 검토한다. <img src="/images/docs/contribute/netlify-pass.png" width="75%" alt="승인 전에 반드시 Netlify 테스트를 통과해야 한다" /> - 승인 전에 PR에 대한 Netlify 프리뷰 페이지를 방문하여, 제대로 보이는지 확인한다. - 주간 로테이션을 위해 [PR Wrangler 로테이션 스케줄](https://github.com/kubernetes/website/wiki/PR-Wranglers)에 참여한다. SIG Docs는 모든 승인자들이 이 로테이션에 참여할 것으로 기대한다. 자세한 내용은 [PR 랭글러(PR wrangler)](/ko/docs/contribute/participating/pr-wranglers/)를 참고한다. ## 승인자 되기 [요구 사항](https://github.com/kubernetes/community/blob/master/community-membership.md#approver)을 충족하면 SIG Docs 승인자가 될 수 있다. 다른 SIG의 승인자는 SIG Docs의 승인자 자격에 대해 별도로 신청해야 한다. 지원하려면 다음을 수행한다. 1. `kubernetes/website` 리포지터리 내 [OWNERS_ALIASES](https://github.com/kubernetes/website/blob/master/OWNERS) 파일의 섹션에 자신을 추가하는 풀 리퀘스트를 연다. {{< note >}} 자신을 추가할 위치가 확실하지 않으면, `sig-docs-ko-owners` 에 추가한다. {{< /note >}} 2. PR에 한 명 이상의 현재 SIG Docs 승인자를 지정한다. 승인되면, SIG Docs 리더가 적당한 GitHub 팀에 여러분을 추가한다. 일단 추가되면, [@k8s-ci-robot](https://github.com/kubernetes/test-infra/tree/master/prow#bots-home)이 새로운 풀 리퀘스트에서 승인자로 여러분을 할당하고 제안한다. ## {{% heading "whatsnext" %}} - 모든 승인자가 교대로 수행하는 역할인 [PR 랭글러](/ko/docs/contribute/participating/pr-wranglers)에 대해 읽어보기 </ins>


<del> --- title: 역할과 책임 content_type: concept weight: 10 --- <!-- overview --> 누구나 쿠버네티스에 기여할 수 있다. SIG Docs에 대한 기여가 커짐에 따라, 커뮤니티의 다양한 멤버십을 신청할 수 있다. 이러한 역할을 통해 커뮤니티 내에서 더 많은 책임을 질 수 있다. 각 역할마다 많은 시간과 노력이 필요하다. 역할은 다음과 같다. - 모든 사람: 쿠버네티스 문서에 정기적으로 기여하는 기여자 - 멤버: 이슈를 할당, 심사하고 풀 리퀘스트에 대한 구속력 없는 리뷰를 제공할 수 있다. - 리뷰어: 문서의 풀 리퀘스트에 대한 리뷰를 리딩할 수 있으며 변경 사항에 대한 품질을 보증할 수 있다. - 승인자: 문서에 대한 리뷰를 리딩하고 변경 사항을 병합할 수 있다 <!-- body --> ## 모든 사람 GitHub 계정을 가진 누구나 쿠버네티스에 기여할 수 있다. SIG Docs는 모든 새로운 기여자를 환영한다! 모든 사람은 다음의 작업을 할 수 있다. - [`kubernetes/website`](https://github.com/kubernetes/website)를 포함한 모든 [쿠버네티스](https://github.com/kubernetes/) 리포지터리에서 이슈를 올린다. - 풀 리퀘스트에 대해 구속력 없는 피드백을 제공한다. - 현지화에 기여한다. - [슬랙](http://slack.k8s.io/) 또는 [SIG docs 메일링 리스트](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)에 개선을 제안한다. [CLA에 서명](/ko/docs/contribute/new-content/overview/#sign-the-cla) 후에 누구나 다음을 할 수 있다. - 기존 콘텐츠를 개선하거나, 새 콘텐츠를 추가하거나, 블로그 게시물 또는 사례연구 작성을 위해 풀 리퀘스트를 연다. - 다이어그램, 그래픽 자산 그리고 포함할 수 있는 스크린캐스트와 비디오를 제작한다. 자세한 내용은 [새로운 콘텐츠 기여하기](/ko/docs/contribute/new-content/)를 참고한다. ## 멤버 멤버는 `kubernetes/website` 에 여러 개의 풀 리퀘스트를 제출한 사람이다. 멤버는 [쿠버네티스 GitHub 조직](https://github.com/kubernetes)의 회원이다. 멤버는 다음의 작업을 할 수 있다. - [모든 사람](#모든-사람)에 나열된 모든 것을 한다. - 풀 리퀘스트에 `/lgtm` 코멘트를 사용하여 LGTM(looks good to me) 레이블을 추가한다. {{< note >}} `/lgtm` 사용은 자동화를 트리거한다. 만약 구속력 없는 승인을 제공하려면, 단순히 "LGTM" 코멘트를 남기는 것도 좋다! {{< /note >}} - `/hold` 코멘트를 사용하여 풀 리퀘스트에 대한 병합을 차단한다. - `/assign` 코멘트를 사용하여 풀 리퀘스트에 리뷰어를 지정한다. - 풀 리퀘스트에 구속력 없는 리뷰를 제공한다. - 자동화를 사용하여 이슈를 심사하고 분류한다. - 새로운 기능에 대한 문서를 작성한다. ### 멤버 되기 최소 5개의 실질적인 풀 리퀘스트를 제출하고 다른 [요구 사항](https://github.com/kubernetes/community/blob/master/community-membership.md#member)을 충족시킨 후, 다음의 단계를 따른다. 1. 멤버십을 [후원](/docs/contribute/advanced#sponsor-a-new-contributor)해줄 두 명의 [리뷰어](#리뷰어) 또는 [승인자](#승인자)를 찾는다. [슬랙의 #sig-docs 채널](https://kubernetes.slack.com) 또는 [SIG Docs 메일링 리스트](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)에서 후원을 요청한다. {{< note >}} SIG Docs 멤버 개인에게 직접 email을 보내거나 슬랙 다이렉트 메시지를 보내지 않는다. 반드시 지원서를 제출하기 전에 후원을 요청해야 한다. {{< /note >}} 1. [`kubernetes/org`](https://github.com/kubernetes/org/) 리포지터리에 GitHub 이슈를 등록한다. **Organization Membership Request** 이슈 템플릿을 사용한다. 1. 후원자에게 GitHub 이슈를 알린다. 다음 중 하나를 수행할 수 있다. - 이슈에서 후원자의 GitHub 사용자 이름을 코멘트로 추가한다. (`@<GitHub-username>`) - 슬랙 또는 이메일을 사용해 이슈 링크를 후원자에게 보낸다. 후원자는 `+1` 투표로 여러분의 요청을 승인할 것이다. 후원자가 요청을 승인하면, 쿠버네티스 GitHub 관리자가 여러분을 멤버로 추가한다. 축하한다! 만약 멤버십이 수락되지 않으면 피드백을 받게 될 것이다. 피드백의 내용을 해결한 후, 다시 지원하자. 1. 여러분의 이메일 계정으로 수신된 쿠버네티스 GitHub 조직으로의 초대를 수락한다. {{< note >}} GitHub은 초대를 여러분 계정의 기본 이메일 주소로 보낸다. {{< /note >}} ## 리뷰어 리뷰어는 열린 풀 리퀘스트를 리뷰할 책임이 있다. 멤버 피드백과는 달리, 여러분은 리뷰어의 피드백을 반드시 해결해야 한다. 리뷰어는 [@kubernetes/sig-docs-{language}-reviews](https://github.com/orgs/kubernetes/teams?query=sig-docs) GitHub 팀의 멤버이다. 리뷰어는 다음의 작업을 수행할 수 있다. - [모든 사람](#모든-사람)과 [멤버](#멤버)에 나열된 모든 것을 수행한다. - 풀 리퀘스트 리뷰와 구속력 있는 피드백을 제공한다. {{< note >}} 구속력 없는 피드백을 제공하려면, 코멘트에 "선택 사항: "과 같은 문구를 접두어로 남긴다. {{< /note >}} - 코드에서 사용자 화면 문자열 편집 - 코드 코멘트 개선 여러분은 SIG DOcs 리뷰어이거나, 특정 주제 영역의 문서에 대한 리뷰어일 수 있다. ### 풀 리퀘스트에 대한 리뷰어 할당 자동화 시스템은 모든 풀 리퀘스트에 대해 리뷰어를 할당한다. `/assign [@_github_handle]` 코멘트를 남겨 특정 사람에게 리뷰를 요청할 수 있다. 지정된 리뷰어가 PR에 코멘트를 남기지 않는다면, 다른 리뷰어가 개입할 수 있다. 필요에 따라 기술 리뷰어를 지정할 수도 있다. ### `/lgtm` 사용하기 LGTM은 "Looks good to me"의 약자이며 풀 리퀘스트가 기술적으로 정확하고 병합할 준비가 되었음을 나타낸다. 모든 PR은 리뷰어의 `/lgtm` 코멘트가 필요하고 병합을 위해 승인자의 `/approve` 코멘트가 필요하다. 리뷰어의 `/lgtm` 코멘트는 구속력 있고 자동화 시스템이 `lgtm` 레이블을 추가하도록 트리거한다. ### 리뷰어 되기 [요건](https://github.com/kubernetes/community/blob/master/community-membership.md#reviewer)을 충족하면, SIG Docs 리뷰어가 될 수 있다. 다른 SIG의 리뷰어는 SIG Docs의 리뷰어 자격에 반드시 별도로 지원해야 한다. 지원하려면, 다음을 수행한다. 1. `kubernetes/website` 리포지터리 내 [OWNERS_ALIASES](https://github.com/kubernetes/website/blob/master/OWNERS) 파일의 섹션에 여러분의 GitHub 사용자 이름을 추가하는 풀 리퀘스트를 연다. {{< note >}} 자신을 추가할 위치가 확실하지 않으면, `sig-docs-ko-reviews` 에 추가한다. {{< /note >}} 1. PR을 하나 이상의 SIG-Docs 승인자(`sig-docs-{language}-owners` 에 나열된 사용자 이름)에게 지정한다. 승인되면, SIG Docs 리더가 적당한 GitHub 팀에 여러분을 추가한다. 일단 추가되면, [K8s-ci-robot](https://github.com/kubernetes/test-infra/tree/master/prow#bots-home)이 새로운 풀 리퀘스트에서 리뷰어로 여러분을 할당하고 제안한다. ## 승인자 승인자는 병합하기 위해 풀 리퀘스트를 리뷰하고 승인한다. 승인자는 [@kubernetes/sig-docs-{language}-owners](https://github.com/orgs/kubernetes/teams/?query=sig-docs) GitHub 팀의 멤버이다. 승인자는 다음의 작업을 할 수 있다. - [모든 사람](#모든-사람), [멤버](#멤버) 그리고 [리뷰어](#리뷰어) 하위의 모든 목록을 할 수 있다. - 코멘트에 `/approve` 를 사용해서 풀 리퀘스트를 승인하고, 병합해서 기여자의 컨텐츠를 게시한다. - 스타일 가이드 개선을 제안한다. - 문서 테스트 개선을 제안한다. - 쿠버네티스 웹사이트 또는 다른 도구 개선을 제안한다. PR에 이미 `/lgtm` 이 있거나, 승인자도 `/lgtm` 코멘트를 남긴다면, PR은 자동으로 병합된다. SIG Docs 승인자는 추가적인 기술 리뷰가 필요치 않는 변경에 대해서만 `/lgtm` 을 남겨야 한다. ### 풀 리퀘스트 승인 승인자와 SIG Docs 리더는 website 리포지터리로 풀 리퀘스트를 병합할 수 있는 유일한 사람들이다. 이것은 특정한 책임이 따른다. - 승인자는 PR들을 리포지터리에 병합하는 `/approve` 명령을 사용할 수 있다. {{< warning >}} 부주의한 머지로 인해 사이트를 파괴할 수 있으므로, 머지할 때에 그 의미를 확인해야 한다. {{< /warning >}} - 제안된 변경이 [컨트리뷰션 가이드 라인](/docs/contribute/style/content-guide/#contributing-content)에 적합한지 확인한다. 질문이 생기거나 확실하지 않다면 자유롭게 추가 리뷰를 요청한다. - PR을 `/approve` 하기 전에 Netlify 테스트 결과를 검토한다. <img src="/images/docs/contribute/netlify-pass.png" width="75%" alt="승인 전에 반드시 Netlify 테스트를 통과해야 한다" /> - 승인 전에 PR에 대한 Netlify 프리뷰 페이지를 방문하여, 제대로 보이는지 확인한다. - 주간 로테이션을 위해 [PR Wrangler 로테이션 스케줄](https://github.com/kubernetes/website/wiki/PR-Wranglers)에 참여한다. SIG Docs는 모든 승인자들이 이 로테이션에 참여할 것으로 기대한다. 자세한 내용은 [PR 랭글러(PR wrangler)](/ko/docs/contribute/participating/pr-wranglers/)를 참고한다. ## 승인자 되기 [요구 사항](https://github.com/kubernetes/community/blob/master/community-membership.md#approver)을 충족하면 SIG Docs 승인자가 될 수 있다. 다른 SIG의 승인자는 SIG Docs의 승인자 자격에 대해 별도로 신청해야 한다. 지원하려면 다음을 수행한다. 1. `kubernetes/website` 리포지터리 내 [OWNERS_ALIASES](https://github.com/kubernetes/website/blob/master/OWNERS) 파일의 섹션에 자신을 추가하는 풀 리퀘스트를 연다. {{< note >}} 자신을 추가할 위치가 확실하지 않으면, `sig-docs-ko-owners` 에 추가한다. {{< /note >}} 2. PR에 한 명 이상의 현재 SIG Docs 승인자를 지정한다. 승인되면, SIG Docs 리더가 적당한 GitHub 팀에 여러분을 추가한다. 일단 추가되면, [@k8s-ci-robot](https://github.com/kubernetes/test-infra/tree/master/prow#bots-home)이 새로운 풀 리퀘스트에서 승인자로 여러분을 할당하고 제안한다. ## {{% heading "whatsnext" %}} - 모든 승인자가 교대로 수행하는 역할인 [PR 랭글러](/ko/docs/contribute/participating/pr-wranglers)에 대해 읽어보기 </del>


* 클라이언트는 `node2:nodePort`로 패킷을 보낸다. * `node2`는 소스 IP 주소(SNAT)를 패킷 상에서 자신의 IP 주소로 교체한다. <del> * `noee2`는 대상 IP를 패킷 상에서 파드의 IP로 교체한다. </del> <ins> * `node2`는 대상 IP를 패킷 상에서 파드의 IP로 교체한다. </ins> * 패킷은 node 1로 라우팅 된 다음 엔드포인트로 라우팅 된다. * 파드의 응답은 node2로 다시 라우팅된다. * 파드의 응답은 클라이언트로 다시 전송된다.


Kubernetes has a "hub-and-spoke" API pattern. All API usage from nodes (or the pods they run) terminate at the apiserver (none of the other control plane components are designed to expose remote services). The apiserver is configured to listen for remote connections on a secure HTTPS port (typically 443) with one or more forms of client [authentication](/docs/reference/access-authn-authz/authentication/) enabled. One or more forms of [authorization](/docs/reference/access-authn-authz/authorization/) should be enabled, especially if [anonymous requests](/docs/reference/access-authn-authz/authentication/#anonymous-requests) or [service account tokens](/docs/reference/access-authn-authz/authentication/#service-account-tokens) are allowed. <del> Nodes should be provisioned with the public root certificate for the cluster such that they can connect securely to the apiserver along with valid client credentials. For example, on a default GKE deployment, the client credentials provided to the kubelet are in the form of a client certificate. See [kubelet TLS bootstrapping](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) for automated provisioning of kubelet client certificates. </del> <ins> Nodes should be provisioned with the public root certificate for the cluster such that they can connect securely to the apiserver along with valid client credentials. A good approach is that the client credentials provided to the kubelet are in the form of a client certificate. See [kubelet TLS bootstrapping](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) for automated provisioning of kubelet client certificates. </ins> Pods that wish to connect to the apiserver can do so securely by leveraging a service account so that Kubernetes will automatically inject the public root certificate and a valid bearer token into the pod when it is instantiated. The `kubernetes` service (in all namespaces) is configured with a virtual IP address that is redirected (via kube-proxy) to the HTTPS endpoint on the apiserver.


 --- ---   Click tags or use the drop downs to filter. Click table headers to sort or reverse sort.
 Filter by Concept:
 Filter by Object:
 Filter by Command:


## {{% heading "whatsnext" %}} <del> - [RuntimeClass Design](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/runtime-class.md) - [RuntimeClass Scheduling Design](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/runtime-class-scheduling.md) </del> <ins> - [RuntimeClass Design](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/585-runtime-class/README.md) - [RuntimeClass Scheduling Design](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/585-runtime-class/README.md#runtimeclass-scheduling) </ins> - Read about the [Pod Overhead](/docs/concepts/configuration/pod-overhead/) concept - [PodOverhead Feature Design](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/20190226-pod-overhead.md)


_Pods_ are the smallest deployable units of computing that you can create and manage in Kubernetes. A _Pod_ (as in a pod of whales or pea pod) is a group of one or more <del> {{< glossary_tooltip text="containers" term_id="container" >}}, with shared storage/network resources, and a specification </del> <ins> [containers](/docs/concepts/containers/), with shared storage/network resources, and a specification </ins> for how to run the containers. A Pod's contents are always co-located and co-scheduled, and run in a shared context. A Pod models an application-specific "logical host": it contains one or more application


title: 容器运行环境（Container Runtime） id: container-runtime date: 2019-06-05 <del> full_link: /docs/reference/generated/container-runtime </del> <ins> full_link: /docs/setup/production-environment/container-runtimes </ins> short_description: > 容器运行环境是负责运行容器的软件。


title: Container Runtime id: container-runtime date: 2019-06-05 <del> full_link: /docs/reference/generated/container-runtime </del> <ins> full_link: /docs/setup/production-environment/container-runtimes </ins> short_description: > The container runtime is the software that is responsible for running containers.


<!--more--> <!-- <del> Kubernetes supports several container runtimes: [Docker](http://www.docker.com), [containerd](https://containerd.io), [cri-o](https://cri-o.io/), [rktlet](https://github.com/kubernetes-incubator/rktlet) and any implementation of the [Kubernetes CRI (Container Runtime Interface)](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/container-runtime-interface.md). </del> <ins> Kubernetes supports several container runtimes: {{< glossary_tooltip term_id="docker">}}, {{< glossary_tooltip term_id="containerd" >}}, {{< glossary_tooltip term_id="cri-o" >}}, and any implementation of the [Kubernetes CRI (Container Runtime Interface)](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/container-runtime-interface.md). </ins> --> <del> Kubernetes 支持多个容器运行环境: [Docker](http://www.docker.com)、 [containerd](https://containerd.io)、[cri-o](https://cri-o.io/)、 [rktlet](https://github.com/kubernetes-incubator/rktlet) 以及任何实现 [Kubernetes CRI (容器运行环境接口)](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/container-runtime-interface.md)。 </del> <ins> Kubernetes 支持多个容器运行环境: {{< glossary_tooltip term_id="docker">}}、 {{< glossary_tooltip term_id="containerd" >}}、{{< glossary_tooltip term_id="cri-o" >}} 以及任何实现 [Kubernetes CRI (容器运行环境接口)](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/container-runtime-interface.md)。 </ins>


max_line_length = 80 trim_trailing_whitespace = true <ins> [*.md] trim_trailing_whitespace = false </ins> [*.{css,html,js,json,sass,md,mmark,toml,yaml}] indent_style = space indent_size = 2


<ins> --- title: 服务器端应用（Server-Side Apply） content_type: concept weight: 25 min-kubernetes-server-version: 1.16 --- <!-- --- title: Server-Side Apply reviewers: - smarterclayton - apelisse - lavalamp - liggitt content_type: concept weight: 25 min-kubernetes-server-version: 1.16 --- --> <!-- overview --> {{< feature-state for_k8s_version="v1.16" state="beta" >}} <!-- ## Introduction Server Side Apply helps users and controllers manage their resources via declarative configurations. It allows them to create and/or modify their [objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/) declaratively, simply by sending their fully specified intent. --> ## 简介 {#introduction} 服务器端应用协助用户、控制器通过声明式配置的方式管理他们的资源。 它发送完整描述的目标（A fully specified intent）， 声明式地创建和/或修改 [对象](/zh/docs/concepts/overview/working-with-objects/kubernetes-objects/)。 <!-- A fully specified intent is a partial object that only includes the fields and values for which the user has an opinion. That intent either creates a new object or is [combined](#merge-strategy), by the server, with the existing object. The system supports multiple appliers collaborating on a single object. --> 一个完整描述的目标并不是一个完整的对象，仅包括能体现用户意图的字段和值。 该目标（intent）可以用来创建一个新对象， 也可以通过服务器来实现与现有对象的[合并](#merge-strategy)。 系统支持多个应用者（appliers）在同一个对象上开展协作。 <!-- Changes to an object's fields are tracked through a "[field management](#field-management)" mechanism. When a field's value changes, ownership moves from its current manager to the manager making the change. When trying to apply an object, fields that have a different value and are owned by another manager will result in a [conflict](#conflicts). This is done in order to signal that the operation might undo another collaborator's changes. Conflicts can be forced, in which case the value will be overridden, and the ownership will be transferred. --> “[字段管理（field management）](#field-management)”机制追踪对象字段的变化。 当一个字段值改变时，其所有权从当前管理器（manager）转移到施加变更的管理器。 当尝试将新配置应用到一个对象时，如果字段有不同的值，且由其他管理器管理， 将会引发[冲突](#conflicts)。 冲突引发警告信号：此操作可能抹掉其他协作者的修改。 冲突可以被刻意忽略，这种情况下，值将会被改写，所有权也会发生转移。 <!-- If you remove a field from a configuration and apply the configuration, server side apply checks if there are any other field managers that also own the field.  If the field is not owned by any other field managers, it is either deleted from the live object or reset to its default value, if it has one. The same rule applies to associative list or map items. --> 当你从配置文件中删除一个字段，然后应用这个配置文件， 这将触发服务端应用检查此字段是否还被其他字段管理器拥有。 如果没有，那就从活动对象中删除该字段；如果有，那就重置为默认值。 该规则同样适用于 list 或 map 项目。 <!-- Server side apply is meant both as a replacement for the original `kubectl apply` and as a simpler mechanism for controllers to enact their changes. If you have Server Side Apply enabled, the control plane tracks managed fields for all newlly created objects. --> 服务器端应用既是原有 `kubectl apply` 的替代品， 也是控制器发布自身变化的一个简化机制。 如果你启用了服务器端应用，控制平面就会跟踪被所有新创建对象管理的字段。 <!-- ## Field Management Compared to the `last-applied` annotation managed by `kubectl`, Server Side Apply uses a more declarative approach, which tracks a user's field management, rather than a user's last applied state. This means that as a side effect of using Server Side Apply, information about which field manager manages each field in an object also becomes available. --> ## 字段管理 {#field-management} 相对于通过 `kubectl` 管理的注解 `last-applied`， 服务器端应用使用了一种更具声明式特点的方法： 它持续的跟踪用户的字段管理，而不仅仅是最后一次的执行状态。 这就意味着，作为服务器端应用的一个副作用， 关于用哪一个字段管理器负责管理对象中的哪个字段的这类信息，都要对外界开放了。 <!-- For a user to manage a field, in the Server Side Apply sense, means that the user relies on and expects the value of the field not to change. The user who last made an assertion about the value of a field will be recorded as the current field manager. This can be done either by changing the value with `POST`, `PUT`, or non-apply `PATCH`, or by including the field in a config sent to the Server Side Apply endpoint. When using Server-Side Apply, trying to change a field which is managed by someone else will result in a rejected request (if not forced, see [Conflicts](#conflicts)). --> 用户管理字段这件事，在服务器端应用的场景中，意味着用户依赖并期望字段的值不要改变。 最后一次对字段值做出断言的用户将被记录到当前字段管理器。 这可以通过发送 `POST`、 `PUT`、 或非应用（non-apply）方式的 `PATCH` 等命令来修改字段值的方式实现， 或通过把字段放在配置文件中，然后发送到服务器端应用的服务端点的方式实现。 当使用服务器端应用，尝试着去改变一个被其他人管理的字段， 会导致请求被拒绝（在没有设置强制执行时，参见[冲突](#conflicts)）。 <!-- When two or more appliers set a field to the same value, they share ownership of that field. Any subsequent attempt to change the value of the shared field, by any of the appliers, results in a conflict. Shared field owners may give up ownership of a field by removing it from their configuration. Field management is stored in a`managedFields` field that is part of an object's [`metadata`](/docs/reference/generated/kubernetes-api/{{< latest-version >}}/#objectmeta-v1-meta). A simple example of an object created by Server Side Apply could look like this: --> 如果两个或以上的应用者均把同一个字段设置为相同值，他们将共享此字段的所有权。 后续任何改变共享字段值的尝试，不管由那个应用者发起，都会导致冲突。 共享字段的所有者可以放弃字段的所有权，这只需从配置文件中删除该字段即可。 字段管理的信息存储在 `managedFields` 字段中，该字段是对象的 [`metadata`](/docs/reference/generated/kubernetes-api/{{< latest-version >}}/#objectmeta-v1-meta)中的一部分。 服务器端应用创建对象的简单示例如下： ```yaml apiVersion: v1 kind: ConfigMap metadata: name: test-cm namespace: default labels: test-label: test managedFields: - manager: kubectl operation: Apply apiVersion: v1 time: "2010-10-10T0:00:00Z" fieldsType: FieldsV1 fieldsV1: f:metadata: f:labels: f:test-label: {} f:data: f:key: {} data: key: some value ``` <!-- The above object contains a single manager in `metadata.managedFields`. The manager consists of basic information about the managing entity itself, like operation type, API version, and the fields managed by it. This field is managed by the  API server and should not be changed by the user. --> 上述对象在 `metadata.managedFields` 中包含了唯一的管理器。 管理器由管理实体自身的基本信息组成，比如操作类型、API 版本、以及它管理的字段。 {{< note >}} 该字段由 API 服务器管理，用户不应该改动它。 {{< /note >}} <!-- Nevertheless it is possible to change `metadata.managedFields` through an `Update` operation. Doing so is highly discouraged, but might be a reasonable option to try if, for example, the `managedFields` get into an inconsistent state (which clearly should not happen). The format of the `managedFields` is described in the [API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#fieldsv1-v1-meta). --> 不过，执行 `Update` 操作修改 `metadata.managedFields` 也是可实现的。 强烈不鼓励这么做，但当发生如下情况时， 比如 `managedFields` 进入不一致的状态（显然不应该发生这种情况）， 这么做也是一个合理的尝试。 `managedFields` 的格式在 [API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#fieldsv1-v1-meta) 文档中描述。 <!-- ## Conflicts A conflict is a special status error that occurs when an `Apply` operation tries to change a field, which another user also claims to manage. This prevents an applier from unintentionally overwriting the value set by another user. When this occurs, the applier has 3 options to resolve the conflicts: --> ## 冲突 {#conflicts} 冲突是一种特定的错误状态， 发生在执行 `Apply` 改变一个字段，而恰巧该字段被其他用户声明过主权时。 这可以防止一个应用者不小心覆盖掉其他用户设置的值。 冲突发生时，应用者有三种办法来解决它： <!-- * **Overwrite value, become sole manager:** If overwriting the value was intentional (or if the applier is an automated process like a controller) the applier should set the `force` query parameter to true and make the request again. This forces the operation to succeed, changes the value of the field, and removes the field from all other managers' entries in managedFields. * **Don't overwrite value, give up management claim:** If the applier doesn't care about the value of the field anymore, they can remove it from their config and make the request again. This leaves the value unchanged, and causes the field to be removed from the applier's entry in managedFields. * **Don't overwrite value, become shared manager:** If the applier still cares about the value of the field, but doesn't want to overwrite it, they can change the value of the field in their config to match the value of the object on the server, and make the request again. This leaves the value unchanged, and causes the field's management to be shared by the applier and all other field managers that already claimed to manage it. --> * **覆盖前值，成为唯一的管理器：** 如果打算覆盖该值（或应用者是一个自动化部件，比如控制器）， 应用者应该设置查询参数 `force` 为 true，然后再发送一次请求。 这将强制操作成功，改变字段的值，从所有其他管理器的 managedFields 条目中删除指定字段。 * **不覆盖前值，放弃管理权：** 如果应用者不再关注该字段的值， 可以从配置文件中删掉它，再重新发送请求。 这就保持了原值不变，并从 managedFields 的应用者条目中删除该字段。 * **不覆盖前值，成为共享的管理器：** 如果应用者仍然关注字段值，并不想覆盖它， 他们可以在配置文件中把字段的值改为和服务器对象一样，再重新发送请求。 这样在不改变字段值的前提下， 就实现了字段管理被应用者和所有声明了管理权的其他的字段管理器共享。 <!-- ## Managers Managers identify distinct workflows that are modifying the object (especially useful on conflicts!), and can be specified through the `fieldManager` query parameter as part of a modifying request. It is required for the apply endpoint, though kubectl will default it to `kubectl`. For other updates, its default is computed from the user-agent. --> ## 管理器 {#managers} 管理器识别出正在修改对象的工作流程（在冲突时尤其有用）, 管理器可以通过修改请求的参数 `fieldManager` 指定。 虽然 kubectl 默认发往 `kubectl` 服务端点，但它则请求到应用的服务端点（apply endpoint）。 对于其他的更新，它默认的是从用户代理计算得来。 <!-- ## Apply and Update The two operation types considered by this feature are `Apply` (`PATCH` with content type `application/apply-patch+yaml`) and `Update` (all other operations which modify the object). Both operations update the `managedFields`, but behave a little differently. Whether you are submitting JSON data or YAML data, use `application/apply-patch+yaml` as the `Content-Type` header value. All JSON documents are valid YAML. --> ## 应用和更新 {#apply-and-update} 此特性涉及两类操作，分别是 `Apply` （内容类型为 `application/apply-patch+yaml` 的 `PATCH` 请求） 和 `Update` （所有修改对象的其他操作）。 这两类操作都会更新字段 `managedFields`，但行为表现有一点不同。 {{< note >}} 不管你提交的是 JSON 数据还是 YAML 数据， 都要使用 `application/apply-patch+yaml` 作为 `Content-Type` 的值。 所有的 JSON 文档 都是合法的 YAML。 {{< /note >}} <!-- For instance, only the apply operation fails on conflicts while update does not. Also, apply operations are required to identify themselves by providing a `fieldManager` query parameter, while the query parameter is optional for update operations. Finally, when using the apply operation you cannot have `managedFields` in the object that is being applied. An example object with multiple managers could look like this: --> 例如，在冲突发生的时候，只有 `apply` 操作失败，而 `update` 则不会。 此外，`apply` 操作必须通过提供一个 `fieldManager` 查询参数来标识自身， 而此查询参数对于 `update` 操作则是可选的。 最后，当使用 `apply` 命令时，你不能在应用中的对象中持有 `managedFields`。 一个包含多个管理器的对象，示例如下： ```yaml apiVersion: v1 kind: ConfigMap metadata: name: test-cm namespace: default labels: test-label: test managedFields: - manager: kubectl operation: Apply apiVersion: v1 fields: f:metadata: f:labels: f:test-label: {} - manager: kube-controller-manager operation: Update apiVersion: v1 time: '2019-03-30T16:00:00.000Z' fields: f:data: f:key: {} data: key: new value ``` <!-- In this example, a second operation was run as an `Update` by the manager called `kube-controller-manager`. The update changed a value in the data field which caused the field's management to change to the `kube-controller-manager`. If this update would have been an `Apply` operation, the operation would have failed due to conflicting ownership. --> 在这个例子中， 第二个操作被管理器 `kube-controller-manager` 以 `Update` 的方式运行。 此 `update` 更改 data 字段的值， 并使得字段管理器被改为 `kube-controller-manager`。 如果把 `update` 操作改为 `Apply`，那就会因为所有权冲突的原因，导致操作失败。 <!-- ## Merge strategy The merging strategy, implemented with Server Side Apply, provides a generally more stable object lifecycle. Server Side Apply tries to merge fields based on the fact who manages them instead of overruling just based on values. This way it is intended to make it easier and more stable for multiple actors updating the same object by causing less unexpected interference. --> ## 合并策略 {#merge-strategy} 由服务器端应用实现的合并策略，提供了一个总体更稳定的对象生命周期。 服务器端应用试图依据谁管理它们来合并字段，而不只是根据值来否决。 这么做是为了多个参与者可以更简单、更稳定的更新同一个对象，且避免引起意外干扰。 <!-- When a user sends a "fully-specified intent" object to the Server Side Apply endpoint, the server merges it with the live object favoring the value in the applied config if it is specified in both places. If the set of items present in the applied config is not a superset of the items applied by the same user last time, each missing item not managed by any other appliers is removed. For more information about how an object's schema is used to make decisions when merging, see [sigs.k8s.io/structured-merge-diff](https://sigs.k8s.io/structured-merge-diff). --> 当用户发送一个“完整描述的目标”对象到服务器端应用的服务端点， 服务器会将它和活动对象做一次合并，如果两者中有重复定义的值，那就以配置文件的为准。 如果配置文件中的项目集合不是此用户上一次操作项目的超集， 所有缺少的、没有其他应用者管理的项目会被删除。 关于合并时用来做决策的对象规格的更多信息，参见 [sigs.k8s.io/structured-merge-diff](https://sigs.k8s.io/structured-merge-diff). <!-- A number of markers were added in Kubernetes 1.16 and 1.17, to allow API developers to describe the merge strategy supported by lists, maps, and structs. These markers can be applied to objects of the respective type, in Go files or in the OpenAPI schema definition of the [CRD](/docs/reference/generated/kubernetes-api/{{< param "version" >}}#jsonschemaprops-v1-apiextensions-k8s-io): --> Kubernetes 1.16 和 1.17 中添加了一些标记， 允许 API 开发人员描述由 list、map、和 structs 支持的合并策略。 这些标记可应用到相应类型的对象，在 Go 文件或在 [CRD](/docs/reference/generated/kubernetes-api/{{< param "version" >}}#jsonschemaprops-v1-apiextensions-k8s-io) 的 OpenAPI 的模式中定义： <!-- | Golang marker | OpenAPI extension | Accepted values | Description | Introduced in | |---|---|---|---|---| | `//+listType` | `x-kubernetes-list-type` | `atomic`/`set`/`map` | Applicable to lists. `atomic` and `set` apply to lists with scalar elements only. `map` applies to lists of nested types only. If configured as `atomic`, the entire list is replaced during merge; a single manager manages the list as a whole at any one time. If `granular`, different managers can manage entries separately. | 1.16          | | `//+listMapKey` | `x-kubernetes-list-map-keys` | Slice of map keys that uniquely identify entries for example `["port", "protocol"]` | Only applicable when `+listType=map`. A slice of strings whose values in combination must uniquely identify list entries. While there can be multiple keys, `listMapKey` is singular because keys need to be specified individually in the Go type. | 1.16 | | `//+mapType` | `x-kubernetes-map-type` | `atomic`/`granular` | Applicable to maps. `atomic` means that the map can only be entirely replaced by a single manager. `granular` means that the map supports separate managers updating individual fields. | 1.17 | | `//+structType` | `x-kubernetes-map-type` | `atomic`/`granular` | Applicable to structs; otherwise same usage and OpenAPI annotation as `//+mapType`.| 1.17 | --> | Golang 标记 | OpenAPI extension | 可接受的值 | 描述 | 引入版本 | |---|---|---|---|---| | `//+listType` | `x-kubernetes-list-type` | `atomic`/`set`/`map` | 适用于 list。 `atomic` 和 `set` 适用于只包含标量元素的 list。 `map` 适用于只包含嵌套类型的 list。 如果配置为 `atomic`, 合并时整个列表会被替换掉; 任何时候，唯一的管理器都把列表作为一个整体来管理。如果是细粒度管理，不同的管理器也可以分开管理条目。 | 1.16          | | `//+listMapKey` | `x-kubernetes-list-map-keys` | 用来唯一标识条目的 map keys 切片，例如 `["port", "protocol"]` | 仅当 `+listType=map` 时适用。组合值的字符串切片必须唯一标识列表中的条目。尽管有多个 key，`listMapKey` 是单数的，这是因为 key 需要在 Go 类型中单独的指定。 | 1.16 | | `//+mapType` | `x-kubernetes-map-type` | `atomic`/`granular` | 适用于 map。 `atomic` 指 map 只能被单个的管理器整个的替换。 `granular` 指 map 支持多个管理器各自更新自己的字段。 | 1.17 | | `//+structType` | `x-kubernetes-map-type` | `atomic`/`granular` | 适用于 structs；否则就像 `//+mapType` 有相同的用法和 openapi 注释.| 1.17 | <!-- ### Custom Resources By default, Server Side Apply treats custom resources as unstructured data. All keys are treated the same as struct fields, and all lists are considered atomic. If the Custom Resource Definition defines a [schema](/docs/reference/generated/kubernetes-api/{{< param "version" >}}#jsonschemaprops-v1-apiextensions-k8s-io) that contains annotations as defined in the previous "Merge Strategy" section, these annotations will be used when merging objects of this type. --> ### 自定义资源 {#custom-resources} 默认情况下，服务器端应用把自定义资源看做非结构化数据。 所有的键值（keys）就像 struct 的字段一样被处理， 所有的 list 被认为是原子性的。 如果自定义资源定义（Custom Resource Definition，CRD）定义了一个 [模式](/docs/reference/generated/kubernetes-api/{{< param "version" >}}#jsonschemaprops-v1-apiextensions-k8s-io)， 它包含类似以前“合并策略”章节中定义过的注解， 这些注解将在合并此类型的对象时使用。 <!-- ### Using Server-Side Apply in a controller As a developer of a controller, you can use server-side apply as a way to simplify the update logic of your controller. The main differences with a read-modify-write and/or patch are the following: * the applied object must contain all the fields that the controller cares about. * there are no way to remove fields that haven't been applied by the controller before (controller can still send a PATCH/UPDATE for these use-cases). * the object doesn't have to be read beforehand, `resourceVersion` doesn't have to be specified. It is strongly recommended for controllers to always "force" conflicts, since they might not be able to resolve or act on these conflicts. --> ### 在控制器中使用服务器端应用 {#using-server-side-apply-in-controller} 控制器的开发人员可以把服务器端应用作为简化控制器的更新逻辑的方式。 读-改-写 和/或 patch 的主要区别如下所示： * 应用的对象必须包含控制器关注的所有字段。 * 对于在控制器没有执行过应用操作之前就已经存在的字段，不能删除。 （控制器在这种用例环境下，依然可以发送一个 PATCH/UPDATE） * 对象不必事先读取，`resourceVersion` 不必指定。 强烈推荐：设置控制器在冲突时强制执行，这是因为冲突发生时，它们没有其他解决方案或措施。 <!-- ### Transferring Ownership In addition to the concurrency controls provided by [conflict resolution](#conflicts), Server Side Apply provides ways to perform coordinated field ownership transfers from users to controllers. This is best explained by example. Let's look at how to safely transfer ownership of the `replicas` field from a user to a controller while enabling automatic horizontal scaling for a Deployment, using the HorizontalPodAutoscaler resource and its accompanying controller. Say a user has defined deployment with `replicas` set to the desired value: --> ### 转移所有权 {#transferring-ownership} 除了通过[冲突解决方案](#conflicts)提供的并发控制， 服务器端应用提供了一些协作方式来将字段所有权从用户转移到控制器。 最好通过例子来说明这一点。 让我们来看看，在使用 HorizontalPodAutoscaler 资源和与之配套的控制器， 且开启了 Deployment 的自动水平扩展功能之后， 怎么安全的将 `replicas` 字段的所有权从用户转移到控制器。 假设用户定义了 Deployment，且 `replicas` 字段已经设置为期望的值： {{< codenew file="application/ssa/nginx-deployment.yaml" >}} <!-- And the user has created the deployment using server side apply like so: --> 并且，用户使用服务器端应用，像这样创建 Deployment： ```shell kubectl apply -f https://k8s.io/examples/application/ssa/nginx-deployment.yaml --server-side ``` <!-- Then later, HPA is enabled for the deployment, e.g.: --> 然后，为 Deployment 启用 HPA，例如： ```shell kubectl autoscale deployment nginx-deployment --cpu-percent=50 --min=1 --max=10 ``` <!-- Now, the user would like to remove `replicas` from their configuration, so they don't accidentally fight with the HPA controller. However, there is a race: it might take some time before HPA feels the need to adjust `replicas`, and if the user removes `replicas` before the HPA writes to the field and becomes its owner, then apiserver will set `replicas` to 1, its default value. This is not what the user wants to happen, even temporarily. --> 现在，用户希望从他们的配置中删除 `replicas`，所以他们总是和 HPA 控制器冲突。 然而，这里存在一个竟态： 在 HPA 需要调整 `replicas` 之前会有一个时间窗口， 如果在 HPA 写入字段成为所有者之前，用户删除了`replicas`， 那 API 服务器就会把 `replicas` 的值设为1， 也就是默认值。 这不是用户希望发生的事情，即使是暂时的。 <!-- There are two solutions: - (easy) Leave `replicas` in the configuration; when HPA eventually writes to that field, the system gives the user a conflict over it. At that point, it is safe to remove from the configuration. - (more advanced) If, however, the user doesn't want to wait, for example because they want to keep the cluster legible to coworkers, then they can take the following steps to make it safe to remove `replicas` from their configuration: First, the user defines a new configuration containing only the `replicas` field: --> 这里有两个解决方案： - （容易） 把 `replicas` 留在配置文件中；当 HPA 最终写入那个字段， 系统基于此事件告诉用户：冲突发生了。在这个时间点，可以安全的删除配置文件。 - （高级）然而，如果用户不想等待，比如他们想为合作伙伴保持集群清晰， 那他们就可以执行以下步骤，安全的从配置文件中删除 `replicas`。 首先，用户新定义一个只包含 `replicas` 字段的配置文件： {{< codenew file="application/ssa/nginx-deployment-replicas-only.yaml" >}} <!-- The user applies that configuration using the field manager name `handover-to-hpa`: --> 用户使用名为 `handover-to-hpa` 的字段管理器，应用此配置文件。 ```shell kubectl apply -f https://k8s.io/examples/application/ssa/nginx-deployment-replicas-only.yaml  --server-side --field-manager=handover-to-hpa  --validate=false ``` <!-- If the apply results in a conflict with the HPA controller, then do nothing. The conflict just indicates the controller has claimed the field earlier in the process than it sometimes does. At this point the user may remove the `replicas` field from their configuration. --> 如果应用操作和 HPA 控制器产生冲突，那什么都不做。 冲突只是表明控制器在更早的流程中已经对字段声明过所有权。 在此时间点，用户可以从配置文件中删除 `replicas` 。 {{< codenew file="application/ssa/nginx-deployment-no-replicas.yaml" >}} <!-- Note that whenever the HPA controller sets the `replicas` field to a new value, the temporary field manager will no longer own any fields and will be automatically deleted. No clean up is required. --> 注意，只要 HPA 控制器为 `replicas` 设置了一个新值， 该临时字段管理器将不再拥有任何字段，会被自动删除。 这里不需要执行清理工作。 <!-- ## Transferring Ownership Between Users Users can transfer ownership of a field between each other by setting the field to the same value in both of their applied configs, causing them to share ownership of the field. Once the users share ownership of the field, one of them can remove the field from their applied configuration to give up ownership and complete the transfer to the other user. --> ## 在用户之间转移所有权 {#transferring-ownership-between-users} 通过在配置文件中把一个字段设置为相同的值，用户可以在他们之间转移字段的所有权， 从而共享了字段的所有权。 当用户共享了字段的所有权，任何一个用户可以从他的配置文件中删除该字段， 并应用该变更，从而放弃所有权，并实现了所有权向其他用户的转移。 <!-- ## Comparison with Client Side Apply A consequence of the conflict detection and resolution implemented by Server Side Apply is that an applier always has up to date field values in their local state. If they don't, they get a conflict the next time they apply. Any of the three options to resolve conflicts results in the applied configuration being an up to date subset of the object on the server's fields. This is different from Client Side Apply, where outdated values which have been overwritten by other users are left in an applier's local config. These values only become accurate when the user updates that specific field, if ever, and an applier has no way of knowing whether their next apply will overwrite other users' changes. Another difference is that an applier using Client Side Apply is unable to change the API version they are using, but Server Side Apply supports this use case. --> ## 与客户端应用的对比 {#comparison-with-client-side-apply} 由服务器端应用实现的冲突检测和解决方案的一个结果就是， 应用者总是可以在本地状态中得到最新的字段值。 如果得不到最新值，下次执行应用操作时就会发生冲突。 解决冲突三个选项的任意一个都会保证：此应用过的配置文件是服务器上对象字段的最新子集。 这和客户端应用（Client Side Apply） 不同，如果有其他用户覆盖了此值， 过期的值被留在了应用者本地的配置文件中。 除非用户更新了特定字段，此字段才会准确， 应用者没有途径去了解下一次应用操作是否会覆盖其他用户的修改。 另一个区别是使用客户端应用的应用者不能改变他们正在使用的 API 版本，但服务器端应用支持这个场景。 <!-- ## Upgrading from client-side apply to server-side apply Client-side apply users who manage a resource with `kubectl apply` can start using server-side apply with the following flag. --> ## 从客户端应用升级到服务器端应用 {#upgrading-from-client-side-apply-to-server-side-apply} 客户端应用方式时，用户使用 `kubectl apply` 管理资源， 可以通过使用下面标记切换为使用服务器端应用。 ```shell kubectl apply --server-side [--dry-run=server] ``` <!-- By default, field management of the object transfers from client-side apply to kubectl server-side apply without encountering conflicts. Keep the `last-applied-configuration` annotation up to date. The annotation infers client-side apply's managed fields. Any fields not managed by client-side apply raise conflicts. For example, if you used `kubectl scale` to update the replicas field after client-side apply, then this field is not owned by client-side apply and creates conflicts on `kubectl apply --server-side`. This behavior applies to server-side apply with the `kubectl` field manager. As an exception, you can opt-out of this behavior by specifying a different, non-default field manager, as seen in the following example. The default field manager for kubectl server-side apply is `kubectl`. --> 默认情况下，对象的字段管理从客户端应用方式迁移到 kubectl 触发的服务器端应用时，不会发生冲突。 {{< caution >}} 保持注解 `last-applied-configuration` 是最新的。 从注解能推断出字段是由客户端应用管理的。 任何没有被客户端应用管理的字段将引发冲突。 举例说明，比如你在客户端应用之后， 使用 `kubectl scale` 去更新 `replicas` 字段， 可是该字段并没有被客户端应用所拥有， 在执行 `kubectl apply --server-side` 时就会产生冲突。 {{< /caution >}} 此操作以 `kubectl` 作为字段管理器来应用到服务器端应用。 作为例外，可以指定一个不同的、非默认字段管理器停止的这种行为，如下面的例子所示。 对于 kubectl 触发的服务器端应用，默认的字段管理器是 `kubectl`。 ```shell kubectl apply --server-side --field-manager=my-manager [--dry-run=server] ``` <!-- ## Downgrading from server-side apply to client-side apply If you manage a resource with `kubectl apply --server-side`, you can downgrade to client-side apply directly with `kubectl apply`. Downgrading works because kubectl server-side apply keeps the `last-applied-configuration` annotation up-to-date if you use `kubectl apply`. This behavior applies to server-side apply with the `kubectl` field manager. As an exception, you can opt-out of this behavior by specifying a different, non-default field manager, as seen in the following example. The default field manager for kubectl server-side apply is `kubectl`. --> ## 从服务器端应用降级到客户端应用 {#downgrading-from-server-side-apply-to-client-side-apply} 如果你用 `kubectl apply --server-side` 管理一个资源， 可以直接用 `kubectl apply` 命令将其降级为客户端应用。 降级之所以可行，这是因为 `kubectl server-side apply` 会保存最新的 `last-applied-configuration` 注解。 此操作以 `kubectl` 作为字段管理器应用到服务器端应用。 作为例外，可以指定一个不同的、非默认字段管理器停止这种行为，如下面的例子所示。 对于 kubectl 触发的服务器端应用，默认的字段管理器是 `kubectl`。 ```shell kubectl apply --server-side --field-manager=my-manager [--dry-run=server] ``` <!-- ## API Endpoint With the Server Side Apply feature enabled, the `PATCH` endpoint accepts the additional `application/apply-patch+yaml` content type. Users of Server Side Apply can send partially specified objects as YAML to this endpoint.  When applying a configuration, one should always include all the fields that they have an opinion about. --> ## API 端点 {#api-endpoint} 启用了服务器端应用特性之后， `PATCH` 服务端点接受额外的内容类型 `application/apply-patch+yaml`。 服务器端应用的用户就可以把 YAMl 格式的 部分定义对象（partially specified objects）发送到此端点。 当一个配置文件被应用时，它应该包含所有体现你意图的字段。 <!-- ## Clearing ManagedFields It is possible to strip all managedFields from an object by overwriting them using `MergePatch`, `StrategicMergePatch`, `JSONPatch` or `Update`, so every non-apply operation. This can be done by overwriting the managedFields field with an empty entry. Two examples are: --> ## 清除 ManagedFields {#clearing-managedfields} 可以从对象中剥离所有 managedField， 实现方法是通过使用 `MergePatch`、 `StrategicMergePatch`、 `JSONPatch`、 `Update`、以及所有的非应用方式的操作来覆盖它。 这可以通过用空条目覆盖 managedFields 字段的方式实现。 ```console PATCH /api/v1/namespaces/default/configmaps/example-cm Content-Type: application/merge-patch+json Accept: application/json Data: {"metadata":{"managedFields": [{}]}} ``` ```console PATCH /api/v1/namespaces/default/configmaps/example-cm Content-Type: application/json-patch+json Accept: application/json Data: [{"op": "replace", "path": "/metadata/managedFields", "value": [{}]}] ``` <!-- This will overwrite the managedFields with a list containing a single empty entry that then results in the managedFields being stripped entirely from the object. Note that just setting the managedFields to an empty list will not reset the field. This is on purpose, so managedFields never get stripped by clients not aware of the field. In cases where the reset operation is combined with changes to other fields than the managedFields, this will result in the managedFields being reset first and the other changes being processed afterwards. As a result the applier takes ownership of any fields updated in the same request. --> 这一操作将用只包含一个空条目的 list 覆写 managedFields， 来实现从对象中整个的去除 managedFields。 注意，只把 managedFields 设置为空 list 并不会重置字段。 这么做是有目的的，所以 managedFields 将永远不会被与该字段无关的客户删除。 在重置操作结合 managedFields 以外其他字段更改的场景中， 将导致 managedFields 首先被重置，其他改变被押后处理。 其结果是，应用者取得了同一个请求中所有字段的所有权。 <!-- Server Side Apply does not correctly track ownership on sub-resources that don't receive the resource object type. If you are using Server Side Apply with such a sub-resource, the changed fields won't be tracked. --> {{< caution >}} 对于不接受资源对象类型的子资源（sub-resources）， 服务器端应用不能正确地跟踪其所有权。 如果你对这样的子资源使用服务器端应用，变更的字段将不会被跟踪。 {{< /caution >}} <!-- ## Disabling the feature Server Side Apply is a beta feature, so it is enabled by default. To turn this [feature gate](/docs/reference/command-line-tools-reference/feature-gates) off, you need to include the `--feature-gates ServerSideApply=false` flag when starting `kube-apiserver`. If you have multiple `kube-apiserver` replicas, all should have the same flag setting. --> ## 禁用此功能 {#disabling-the-feature} 服务器端应用是一个 beta 版特性，默认启用。 要关闭此[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates)， 你需要在启动 `kube-apiserver` 时包含参数 `--feature-gates ServerSideApply=false`。 如果你有多个 `kube-apiserver` 副本，他们都应该有相同的标记设置。 </ins>  No newline at end of file


<ins> --- title: "示例：配置 java 微服务" weight: 10 --- <!-- --- title: "Example: Configuring a Java Microservice" weight: 10 --- --> </ins>  No newline at end of file


 --- title: "互动教程 - 配置 java 微服务" weight: 20 ---  <!DOCTYPE html>   <link href="/docs/tutorials/kubernetes-basics/public/css/styles.css" rel="stylesheet"> <link href="/docs/tutorials/kubernetes-basics/public/css/overrides.css" rel="stylesheet">

  如需要与终端交互，请使用台式机/平板电脑版