ServiceClusterIPRangeutil.IPNet// TODO: make this a list
ServiceNodePortsutil.PortRange
ServiceNodePortRangeutil.PortRange
EnableLogsSupportbool
EnableLogsSupportbool
MasterServiceNamespacestring
MasterServiceNamespacestring
RuntimeConfigutil.ConfigurationMap
RuntimeConfigutil.ConfigurationMap
...
@@ -183,8 +183,12 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) {
...
@@ -183,8 +183,12 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.OldEtcdPathPrefix,"old-etcd-prefix",s.OldEtcdPathPrefix,"The previous prefix for all resource paths in etcd, if any.")
fs.StringVar(&s.OldEtcdPathPrefix,"old-etcd-prefix",s.OldEtcdPathPrefix,"The previous prefix for all resource paths in etcd, if any.")
fs.Var(&s.CorsAllowedOriginList,"cors-allowed-origins","List of allowed origins for CORS, comma separated. An allowed origin can be a regular expression to support subdomain matching. If this list is empty CORS will not be enabled.")
fs.Var(&s.CorsAllowedOriginList,"cors-allowed-origins","List of allowed origins for CORS, comma separated. An allowed origin can be a regular expression to support subdomain matching. If this list is empty CORS will not be enabled.")
fs.Var(&s.PortalNet,"portal-net","A CIDR notation IP range from which to assign portal IPs. This must not overlap with any IP ranges assigned to nodes for pods.")
fs.Var(&s.ServiceClusterIPRange,"service-cluster-ip-range","A CIDR notation IP range from which to assign service cluster IPs. This must not overlap with any IP ranges assigned to nodes for pods.")
fs.Var(&s.ServiceNodePorts,"service-node-ports","A port range to reserve for services with NodePort visibility. Example: '30000-32767'. Inclusive at both ends of the range.")
fs.Var(&s.ServiceClusterIPRange,"portal-net","Deprecated: see --service-cluster-ip-range instead.")
fs.Var(&s.ServiceNodePortRange,"service-node-port-range","A port range to reserve for services with NodePort visibility. Example: '30000-32767'. Inclusive at both ends of the range.")
fs.Var(&s.ServiceNodePortRange,"service-node-ports","Deprecated: see --service-node-port-range instead.")
fs.StringVar(&s.MasterServiceNamespace,"master-service-namespace",s.MasterServiceNamespace,"The namespace from which the kubernetes master services should be injected into pods")
fs.StringVar(&s.MasterServiceNamespace,"master-service-namespace",s.MasterServiceNamespace,"The namespace from which the kubernetes master services should be injected into pods")
fs.Var(&s.RuntimeConfig,"runtime-config","A set of key=value pairs that describe runtime configuration that may be passed to the apiserver. api/<version> key can be used to turn on/off specific api versions. api/all and api/legacy are special keys to control all and legacy api versions respectively.")
fs.Var(&s.RuntimeConfig,"runtime-config","A set of key=value pairs that describe runtime configuration that may be passed to the apiserver. api/<version> key can be used to turn on/off specific api versions. api/all and api/legacy are special keys to control all and legacy api versions respectively.")
@@ -83,7 +83,7 @@ We want to be able to assign IP addresses externally from Docker ([Docker issue
...
@@ -83,7 +83,7 @@ We want to be able to assign IP addresses externally from Docker ([Docker issue
In addition to enabling self-registration with 3rd-party discovery mechanisms, we'd like to setup DDNS automatically ([Issue #146](https://github.com/GoogleCloudPlatform/kubernetes/issues/146)). hostname, $HOSTNAME, etc. should return a name for the pod ([Issue #298](https://github.com/GoogleCloudPlatform/kubernetes/issues/298)), and gethostbyname should be able to resolve names of other pods. Probably we need to set up a DNS resolver to do the latter ([Docker issue #2267](https://github.com/dotcloud/docker/issues/2267)), so that we don't need to keep /etc/hosts files up to date dynamically.
In addition to enabling self-registration with 3rd-party discovery mechanisms, we'd like to setup DDNS automatically ([Issue #146](https://github.com/GoogleCloudPlatform/kubernetes/issues/146)). hostname, $HOSTNAME, etc. should return a name for the pod ([Issue #298](https://github.com/GoogleCloudPlatform/kubernetes/issues/298)), and gethostbyname should be able to resolve names of other pods. Probably we need to set up a DNS resolver to do the latter ([Docker issue #2267](https://github.com/dotcloud/docker/issues/2267)), so that we don't need to keep /etc/hosts files up to date dynamically.
[Service](http://docs.k8s.io/services.md) endpoints are currently found through environment variables. Both [Docker-links-compatible](https://docs.docker.com/userguide/dockerlinks/) variables and kubernetes-specific variables ({NAME}_SERVICE_HOST and {NAME}_SERVICE_BAR) are supported, and resolve to ports opened by the service proxy. We don't actually use [the Docker ambassador pattern](https://docs.docker.com/articles/ambassador_pattern_linking/) to link containers because we don't require applications to identify all clients at configuration time, yet. While services today are managed by the service proxy, this is an implementation detail that applications should not rely on. Clients should instead use the [service portal IP](http://docs.k8s.io/services.md)(which the above environment variables will resolve to). However, a flat service namespace doesn't scale and environment variables don't permit dynamic updates, which complicates service deployment by imposing implicit ordering constraints. We intend to register each service portal IP in DNS, and for that to become the preferred resolution protocol.
[Service](http://docs.k8s.io/services.md) endpoints are currently found through environment variables. Both [Docker-links-compatible](https://docs.docker.com/userguide/dockerlinks/) variables and kubernetes-specific variables ({NAME}_SERVICE_HOST and {NAME}_SERVICE_BAR) are supported, and resolve to ports opened by the service proxy. We don't actually use [the Docker ambassador pattern](https://docs.docker.com/articles/ambassador_pattern_linking/) to link containers because we don't require applications to identify all clients at configuration time, yet. While services today are managed by the service proxy, this is an implementation detail that applications should not rely on. Clients should instead use the [service IP](http://docs.k8s.io/services.md)(which the above environment variables will resolve to). However, a flat service namespace doesn't scale and environment variables don't permit dynamic updates, which complicates service deployment by imposing implicit ordering constraints. We intend to register each service's IP in DNS, and for that to become the preferred resolution protocol.
We'd also like to accommodate other load-balancing solutions (e.g., HAProxy), non-load-balanced services ([Issue #260](https://github.com/GoogleCloudPlatform/kubernetes/issues/260)), and other types of groups (worker pools, etc.). Providing the ability to Watch a label selector applied to pod addresses would enable efficient monitoring of group membership, which could be directly consumed or synced with a discovery mechanism. Event hooks ([Issue #140](https://github.com/GoogleCloudPlatform/kubernetes/issues/140)) for join/leave events would probably make this even easier.
We'd also like to accommodate other load-balancing solutions (e.g., HAProxy), non-load-balanced services ([Issue #260](https://github.com/GoogleCloudPlatform/kubernetes/issues/260)), and other types of groups (worker pools, etc.). Providing the ability to Watch a label selector applied to pod addresses would enable efficient monitoring of group membership, which could be directly consumed or synced with a discovery mechanism. Event hooks ([Issue #140](https://github.com/GoogleCloudPlatform/kubernetes/issues/140)) for join/leave events would probably make this even easier.
**Configure the kubernetes services on the master.**
**Configure the kubernetes services on the master.**
* Edit /etc/kubernetes/apiserver to appear as such. The portal_net IP addresses must be an unused block of addresses, not used anywhere else. They do not need to be routed or assigned to anything.
* Edit /etc/kubernetes/apiserver to appear as such. The service_cluster_ip_range IP addresses must be an unused block of addresses, not used anywhere else. They do not need to be routed or assigned to anything.
The number of Kubernetes pods listed earlier (from `bin/kubectl get pods`) should equal to the number active Mesos tasks listed the previous listing (`mesos ps`).
The number of Kubernetes pods listed earlier (from `bin/kubectl get pods`) should equal to the number active Mesos tasks listed the previous listing (`mesos ps`).
Next, determine the internal IP address of the front end [service portal][8]:
Next, determine the internal IP address of the front end [service][8]:
```bash
```bash
$ bin/kubectl get services
$ bin/kubectl get services
...
@@ -268,14 +268,14 @@ Or interact with the frontend application via your browser, in 2 steps:
...
@@ -268,14 +268,14 @@ Or interact with the frontend application via your browser, in 2 steps:
First, open the firewall on the master machine.
First, open the firewall on the master machine.
```bash
```bash
# determine the internal port for the frontend service portal
# determine the internal port for the frontend service
$ sudo iptables-save|grep -e frontend # -- port 36336 in this case
$ sudo iptables-save|grep -e frontend # -- port 36336 in this case
@@ -61,7 +61,7 @@ Then the `roles ` variable defines the role of above machine in the same order,
...
@@ -61,7 +61,7 @@ Then the `roles ` variable defines the role of above machine in the same order,
The `NUM_MINIONS` variable defines the total number of minions.
The `NUM_MINIONS` variable defines the total number of minions.
The `PORTAL_NET` variable defines the kubernetes service portal ip range. Please make sure that you do have a valid private ip range defined here, because some IaaS provider may reserve private ips. You can use below three private network range accordin to rfc1918. Besides you'd better not choose the one that conflicts with your own private network range.
The `SERVICE_CLUSTER_IP_RANGE` variable defines the kubernetes service IP range. Please make sure that you do have a valid private ip range defined here, because some IaaS provider may reserve private ips. You can use below three private network range accordin to rfc1918. Besides you'd better not choose the one that conflicts with your own private network range.
10.0.0.0 - 10.255.255.255 (10/8 prefix)
10.0.0.0 - 10.255.255.255 (10/8 prefix)
...
@@ -69,7 +69,7 @@ The `PORTAL_NET` variable defines the kubernetes service portal ip range. Please
...
@@ -69,7 +69,7 @@ The `PORTAL_NET` variable defines the kubernetes service portal ip range. Please
192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
The `FLANNEL_NET` variable defines the IP range used for flannel overlay network, should not conflict with above PORTAL_NET range
The `FLANNEL_NET` variable defines the IP range used for flannel overlay network, should not conflict with above `SERVICE_CLUSTER_IP_RANGE`.
After all the above variable being set correctly. We can use below command in cluster/ directory to bring up the whole cluster.
After all the above variable being set correctly. We can use below command in cluster/ directory to bring up the whole cluster.
...
@@ -127,7 +127,7 @@ DNS_DOMAIN="kubernetes.local"
...
@@ -127,7 +127,7 @@ DNS_DOMAIN="kubernetes.local"
DNS_REPLICAS=1
DNS_REPLICAS=1
```
```
The `DNS_SERVER_IP` is defining the ip of dns server which must be in the portal_net range.
The `DNS_SERVER_IP` is defining the ip of dns server which must be in the service_cluster_ip_range.
The `DNS_REPLICAS` describes how many dns pod running in the cluster.
The `DNS_REPLICAS` describes how many dns pod running in the cluster.
@@ -20,6 +20,58 @@ clustered database or key-value store. We will target such workloads for our
...
@@ -20,6 +20,58 @@ clustered database or key-value store. We will target such workloads for our
## v1 APIs
## v1 APIs
For existing and future workloads, we want to provide a consistent, stable set of APIs, over which developers can build and extend Kubernetes. This includes input validation, a consistent API structure, clean semantics, and improved diagnosability of the system.
For existing and future workloads, we want to provide a consistent, stable set of APIs, over which developers can build and extend Kubernetes. This includes input validation, a consistent API structure, clean semantics, and improved diagnosability of the system.
||||||| merged common ancestors
## APIs and core features
1. Consistent v1 API
- Status: DONE. [v1beta3](http://kubernetesio.blogspot.com/2015/04/introducing-kubernetes-v1beta3.html) was developed as the release candidate for the v1 API.
2. Multi-port services for apps which need more than one port on the same portal IP ([#1802](https://github.com/GoogleCloudPlatform/kubernetes/issues/1802))
- Status: DONE. Released in 0.15.0
3. Nominal services for applications which need one stable IP per pod instance ([#260](https://github.com/GoogleCloudPlatform/kubernetes/issues/260))
- Status: #2585 covers some design options.
4. API input is scrubbed of status fields in favor of a new API to set status ([#4248](https://github.com/GoogleCloudPlatform/kubernetes/issues/4248))
- Status: DONE
5. Input validation reporting versioned field names ([#3084](https://github.com/GoogleCloudPlatform/kubernetes/issues/3084))
- Status: in progress
6. Error reporting: Report common problems in ways that users can discover
- Status:
7. Event management: Make events usable and useful
- Status:
8. Persistent storage support ([#5105](https://github.com/GoogleCloudPlatform/kubernetes/issues/5105))
- Status: in progress
9. Allow nodes to join/leave a cluster ([#6087](https://github.com/GoogleCloudPlatform/kubernetes/issues/6087),[#3168](https://github.com/GoogleCloudPlatform/kubernetes/issues/3168))
- Status: in progress ([#6949](https://github.com/GoogleCloudPlatform/kubernetes/pull/6949))
10. Handle node death
- Status: mostly covered by nodes joining/leaving a cluster
11. Allow live cluster upgrades ([#6075](https://github.com/GoogleCloudPlatform/kubernetes/issues/6075),[#6079](https://github.com/GoogleCloudPlatform/kubernetes/issues/6079))
- Status: design in progress
12. Allow kernel upgrades
- Status: mostly covered by nodes joining/leaving a cluster, need demonstration
13. Allow rolling-updates to fail gracefully ([#1353](https://github.com/GoogleCloudPlatform/kubernetes/issues/1353))
- Status:
14. Easy .dockercfg
- Status:
15. Demonstrate cluster stability over time
- Status
16. Kubelet use the kubernetes API to fetch jobs to run (instead of etcd) on supported platforms
- Status: DONE
## Reliability and performance
1. Restart system components in case of crash (#2884)
- Status: in progress
2. Scale to 100 nodes (#3876)
- Status: in progress
3. Scale to 30-50 pods (1-2 containers each) per node (#4188)
- Status:
4. Scheduling throughput: 99% of scheduling decisions made in less than 1s on 100 node, 3000 pod cluster; linear time to number of nodes and pods (#3954)
5. Startup time: 99% of end-to-end pod startup time with prepulled images is less than 5s on 100 node, 3000 pod cluster; linear time to number of nodes and pods (#3952, #3954)
- Status:
6. API performance: 99% of API calls return in less than 1s; constant time to number of nodes and pods (#4521)
- Status:
7. Manage and report disk space on nodes (#4135)
- Status: in progress
8. API test coverage more than 85% in e2e tests
- Status:
In addition, we will provide versioning and deprecation policies for the APIs.
In addition, we will provide versioning and deprecation policies for the APIs.
// ServiceTypeClusterIP means a service will only be accessible inside the
// ServiceTypeClusterIP means a service will only be accessible inside the
// cluster, via the portal IP.
// cluster, via the cluster IP.
ServiceTypeClusterIPServiceType="ClusterIP"
ServiceTypeClusterIPServiceType="ClusterIP"
// ServiceTypeNodePort means a service will be exposed on one port of
// ServiceTypeNodePort means a service will be exposed on one port of
...
@@ -1062,12 +1062,12 @@ type ServiceSpec struct {
...
@@ -1062,12 +1062,12 @@ type ServiceSpec struct {
// This service will route traffic to pods having labels matching this selector. If null, no endpoints will be automatically created. If empty, all pods will be selected.
// This service will route traffic to pods having labels matching this selector. If null, no endpoints will be automatically created. If empty, all pods will be selected.
Selectormap[string]string`json:"selector,omitempty" description:"label keys and values that must match in order to receive traffic for this service; if empty, all pods are selected, if not specified, endpoints must be manually specified"`
Selectormap[string]string`json:"selector,omitempty" description:"label keys and values that must match in order to receive traffic for this service; if empty, all pods are selected, if not specified, endpoints must be manually specified"`
// PortalIP is usually assigned by the master. If specified by the user
// ClusterIP is usually assigned by the master. If specified by the user
// we will try to respect it or else fail the request. This field can
// we will try to respect it or else fail the request. This field can
// not be changed by updates.
// not be changed by updates.
// Valid values are None, empty string (""), or a valid IP address
// Valid values are None, empty string (""), or a valid IP address
// None can be specified for headless services when proxying is not required
// None can be specified for headless services when proxying is not required
PortalIPstring`json:"portalIP,omitempty description: IP address of the service; usually assigned by the system; if specified, it will be allocated to the service if unused, and creation of the service will fail otherwise; cannot be updated; 'None' can be specified for a headless service when proxying is not required"`
ClusterIPstring`json:"clusterIP,omitempty description: IP address of the service; usually assigned by the system; if specified, it will be allocated to the service if unused, and creation of the service will fail otherwise; cannot be updated; 'None' can be specified for a headless service when proxying is not required"`
// Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer
// Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer
TypeServiceType`json:"type,omitempty" description:"type of this service; must be ClusterIP, NodePort, or LoadBalancer; defaults to ClusterIP"`
TypeServiceType`json:"type,omitempty" description:"type of this service; must be ClusterIP, NodePort, or LoadBalancer; defaults to ClusterIP"`
...
@@ -1120,9 +1120,9 @@ type Service struct {
...
@@ -1120,9 +1120,9 @@ type Service struct {
}
}
const(
const(
// PortalIPNone - do not assign a portal IP
// ClusterIPNone - do not assign a cluster IP
// no proxying required and no environment variables should be created for pods
// no proxying required and no environment variables should be created for pods
util.HandleError(fmt.Errorf("the portal IP %s for service %s/%s is not a valid IP; please recreate",svc.Spec.PortalIP,svc.Name,svc.Namespace))
util.HandleError(fmt.Errorf("the cluster IP %s for service %s/%s is not a valid IP; please recreate",svc.Spec.ClusterIP,svc.Name,svc.Namespace))
continue
continue
}
}
switcherr:=r.Allocate(ip);err{
switcherr:=r.Allocate(ip);err{
casenil:
casenil:
caseipallocator.ErrAllocated:
caseipallocator.ErrAllocated:
// TODO: send event
// TODO: send event
// portal IP is broken, reallocate
// cluster IP is broken, reallocate
util.HandleError(fmt.Errorf("the portal IP %s for service %s/%s was assigned to multiple services; please recreate",ip,svc.Name,svc.Namespace))
util.HandleError(fmt.Errorf("the cluster IP %s for service %s/%s was assigned to multiple services; please recreate",ip,svc.Name,svc.Namespace))
caseipallocator.ErrNotInRange:
caseipallocator.ErrNotInRange:
// TODO: send event
// TODO: send event
// portal IP is broken, reallocate
// cluster IP is broken, reallocate
util.HandleError(fmt.Errorf("the portal IP %s for service %s/%s is not within the service CIDR %s; please recreate",ip,svc.Name,svc.Namespace,c.network))
util.HandleError(fmt.Errorf("the cluster IP %s for service %s/%s is not within the service CIDR %s; please recreate",ip,svc.Name,svc.Namespace,c.network))
caseipallocator.ErrFull:
caseipallocator.ErrFull:
// TODO: send event
// TODO: send event
returnfmt.Errorf("the service CIDR %s is full; you must widen the CIDR in order to create new services")
returnfmt.Errorf("the service CIDR %s is full; you must widen the CIDR in order to create new services")
default:
default:
returnfmt.Errorf("unable to allocate portal IP %s for service %s/%s due to an unknown error, exiting: %v",ip,svc.Name,svc.Namespace,err)
returnfmt.Errorf("unable to allocate cluster IP %s for service %s/%s due to an unknown error, exiting: %v",ip,svc.Name,svc.Namespace,err)