Skip to content

Commit 7840b4d

Browse files
Merge pull request #20578 from deads2k/server-13-split-kubeapiserver
add kube-apiserver wiring
2 parents 9a8a2fb + 5e13f18 commit 7840b4d

File tree

25 files changed

+598
-123
lines changed

25 files changed

+598
-123
lines changed

hack/import-restrictions.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050
"github.com/openshift/origin/pkg/quota/admission/clusterresourceoverride",
5151
"github.com/openshift/origin/pkg/oc/cli/admin/createbootstrapprojecttemplate",
5252
"github.com/openshift/origin/pkg/cmd/server",
53-
"github.com/openshift/origin/pkg/cmd/openshift-apiserver"
53+
"github.com/openshift/origin/pkg/cmd/openshift-apiserver",
54+
"github.com/openshift/origin/pkg/cmd/openshift-kube-apiserver/openshiftkubeapiserver"
5455
],
5556
"forbiddenImportPackageRoots": [
5657
"github.com/openshift/origin/pkg/apps/apiserver",

install/kube-dns/install.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ objects:
4242
spec:
4343
serviceAccountName: kube-dns
4444
containers:
45-
- name: kube-proxy
45+
- name: kube-dns
4646
image: ${IMAGE}
4747
imagePullPolicy: ${OPENSHIFT_PULL_POLICY}
4848
command: ["openshift", "start", "network"]

install/kube-proxy/install.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ objects:
3030
- kind: ServiceAccount
3131
name: kube-proxy
3232
namespace: ${NAMESPACE}
33+
- kind: Group
34+
name: system:nodes
3335
roleRef:
3436
kind: ClusterRole
3537
name: system:node-proxier

pkg/cmd/openshift-apiserver/openshiftapiserver/openshift_apiserver.go

+25-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
kapi "k8s.io/kubernetes/pkg/apis/core"
2727
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
2828
kinternalinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
29+
rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
2930
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
3031
rbacauthorizer "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
3132

@@ -578,6 +579,16 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
578579
AddOpenshiftVersionRoute(s.GenericAPIServer.Handler.GoRestfulContainer, "/version/openshift")
579580

580581
// register our poststarthooks
582+
s.GenericAPIServer.AddPostStartHookOrDie("authorization.openshift.io-bootstrapclusterroles",
583+
func(context genericapiserver.PostStartHookContext) error {
584+
newContext := genericapiserver.PostStartHookContext{
585+
LoopbackClientConfig: c.ExtraConfig.KubeAPIServerClientConfig,
586+
StopCh: context.StopCh,
587+
}
588+
return bootstrapData(bootstrappolicy.Policy()).EnsureRBACPolicy()(newContext)
589+
590+
})
591+
s.GenericAPIServer.AddPostStartHookOrDie("authorization.openshift.io-ensureopenshift-infra", c.EnsureOpenShiftInfraNamespace)
581592
s.GenericAPIServer.AddPostStartHookOrDie("project.openshift.io-projectcache", c.startProjectCache)
582593
s.GenericAPIServer.AddPostStartHookOrDie("project.openshift.io-projectauthorizationcache", c.startProjectAuthorizationCache)
583594
s.GenericAPIServer.AddPostStartHookOrDie("security.openshift.io-bootstrapscc", c.bootstrapSCC)
@@ -712,13 +723,13 @@ func (c *completedConfig) bootstrapSCC(context genericapiserver.PostStartHookCon
712723
}
713724

714725
// EnsureOpenShiftInfraNamespace is called as part of global policy initialization to ensure infra namespace exists
715-
func EnsureOpenShiftInfraNamespace(context genericapiserver.PostStartHookContext) error {
726+
func (c *completedConfig) EnsureOpenShiftInfraNamespace(context genericapiserver.PostStartHookContext) error {
716727
namespaceName := bootstrappolicy.DefaultOpenShiftInfraNamespace
717728

718729
var coreClient coreclient.CoreInterface
719730
err := wait.Poll(1*time.Second, 30*time.Second, func() (bool, error) {
720731
var err error
721-
coreClient, err = coreclient.NewForConfig(context.LoopbackClientConfig)
732+
coreClient, err = coreclient.NewForConfig(c.ExtraConfig.KubeAPIServerClientConfig)
722733
if err != nil {
723734
utilruntime.HandleError(fmt.Errorf("unable to initialize client: %v", err))
724735
return false, nil
@@ -744,3 +755,15 @@ func EnsureOpenShiftInfraNamespace(context genericapiserver.PostStartHookContext
744755

745756
return nil
746757
}
758+
759+
// bootstrapData casts our policy data to the rbacrest helper that can
760+
// materialize the policy.
761+
func bootstrapData(data *bootstrappolicy.PolicyData) *rbacrest.PolicyData {
762+
return &rbacrest.PolicyData{
763+
ClusterRoles: data.ClusterRoles,
764+
ClusterRoleBindings: data.ClusterRoleBindings,
765+
Roles: data.Roles,
766+
RoleBindings: data.RoleBindings,
767+
ClusterRolesToAggregate: data.ClusterRolesToAggregate,
768+
}
769+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
package openshiftkubeapiserver
2+
3+
import (
4+
"fmt"
5+
"net"
6+
"sort"
7+
8+
"io/ioutil"
9+
10+
"bytes"
11+
12+
configapi "github.com/openshift/origin/pkg/cmd/server/apis/config"
13+
configapilatest "github.com/openshift/origin/pkg/cmd/server/apis/config/latest"
14+
originadmission "github.com/openshift/origin/pkg/cmd/server/origin/admission"
15+
"k8s.io/apimachinery/pkg/runtime"
16+
)
17+
18+
func ConfigToFlags(kubeAPIServerConfig *configapi.MasterConfig) ([]string, error) {
19+
args := map[string][]string{}
20+
for key, slice := range kubeAPIServerConfig.KubernetesMasterConfig.APIServerArguments {
21+
for _, val := range slice {
22+
args[key] = append(args[key], val)
23+
}
24+
}
25+
26+
host, portString, err := net.SplitHostPort(kubeAPIServerConfig.ServingInfo.BindAddress)
27+
if err != nil {
28+
return nil, err
29+
}
30+
31+
// TODO this list (and the content below) will be used to drive a config struct and a reflective test matching config to flags
32+
// these flags are overridden by a patch
33+
// admission-control
34+
// authentication-token-webhook-cache-ttl
35+
// authentication-token-webhook-config-file
36+
// authorization-mode
37+
// authorization-policy-file
38+
// authorization-webhook-cache-authorized-ttl
39+
// authorization-webhook-cache-unauthorized-ttl
40+
// authorization-webhook-config-file
41+
// basic-auth-file
42+
// enable-aggregator-routing
43+
// enable-bootstrap-token-auth
44+
// oidc-client-id
45+
// oidc-groups-claim
46+
// oidc-groups-prefix
47+
// oidc-issuer-url
48+
// oidc-required-claim
49+
// oidc-signing-algs
50+
// oidc-username-claim
51+
// oidc-username-prefix
52+
// service-account-lookup
53+
// token-auth-file
54+
55+
// alsologtostderr - don't know whether to change it
56+
// apiserver-count - ignored, hopefully we don't have to fix via patch
57+
// cert-dir - ignored because we set certs
58+
59+
// these flags were never supported via config
60+
// cloud-config
61+
// cloud-provider
62+
// cloud-provider-gce-lb-src-cidrs
63+
// contention-profiling
64+
// default-not-ready-toleration-seconds
65+
// default-unreachable-toleration-seconds
66+
// default-watch-cache-size
67+
// delete-collection-workers
68+
// deserialization-cache-size
69+
// enable-garbage-collector
70+
// etcd-compaction-interval
71+
// etcd-count-metric-poll-period
72+
// etcd-servers-overrides
73+
// experimental-encryption-provider-config
74+
// feature-gates
75+
// http2-max-streams-per-connection
76+
// insecure-bind-address
77+
// kubelet-timeout
78+
// log-backtrace-at
79+
// log-dir
80+
// log-flush-frequency
81+
// logtostderr
82+
// master-service-namespace
83+
// max-connection-bytes-per-sec
84+
// profiling
85+
// request-timeout
86+
// runtime-config
87+
// service-account-api-audiences
88+
// service-account-issuer
89+
// service-account-key-file
90+
// service-account-max-token-expiration
91+
// service-account-signing-key-file
92+
// stderrthreshold
93+
// storage-versions
94+
// target-ram-mb
95+
// v
96+
// version
97+
// vmodule
98+
// watch-cache
99+
// watch-cache-sizes
100+
101+
// TODO, we need to set these in order to enable the right admission plugins in each of the servers
102+
// TODO this is needed for a viable cluster up
103+
admissionFlags, err := admissionFlags(kubeAPIServerConfig)
104+
if err != nil {
105+
return nil, err
106+
}
107+
for flag, value := range admissionFlags {
108+
setIfUnset(args, flag, value...)
109+
}
110+
setIfUnset(args, "allow-privileged", "true")
111+
setIfUnset(args, "anonymous-auth", "false")
112+
setIfUnset(args, "authorization-mode", "RBAC", "Node") // overridden later, but this runs the poststarthook for bootstrapping RBAC
113+
for flag, value := range auditFlags(kubeAPIServerConfig) {
114+
setIfUnset(args, flag, value...)
115+
}
116+
setIfUnset(args, "bind-address", host)
117+
setIfUnset(args, "client-ca-file", kubeAPIServerConfig.ServingInfo.ClientCA)
118+
setIfUnset(args, "cors-allowed-origins", kubeAPIServerConfig.CORSAllowedOrigins...)
119+
setIfUnset(args, "enable-logs-handler", "false")
120+
setIfUnset(args, "enable-swagger-ui", "true")
121+
setIfUnset(args, "endpoint-reconciler-type", "lease")
122+
setIfUnset(args, "etcd-cafile", kubeAPIServerConfig.EtcdClientInfo.CA)
123+
setIfUnset(args, "etcd-certfile", kubeAPIServerConfig.EtcdClientInfo.ClientCert.CertFile)
124+
setIfUnset(args, "etcd-keyfile", kubeAPIServerConfig.EtcdClientInfo.ClientCert.KeyFile)
125+
setIfUnset(args, "etcd-prefix", kubeAPIServerConfig.EtcdStorageConfig.KubernetesStoragePrefix)
126+
setIfUnset(args, "etcd-servers", kubeAPIServerConfig.EtcdClientInfo.URLs...)
127+
setIfUnset(args, "insecure-port", "0")
128+
setIfUnset(args, "kubelet-certificate-authority", kubeAPIServerConfig.KubeletClientInfo.CA)
129+
setIfUnset(args, "kubelet-client-certificate", kubeAPIServerConfig.KubeletClientInfo.ClientCert.CertFile)
130+
setIfUnset(args, "kubelet-client-key", kubeAPIServerConfig.KubeletClientInfo.ClientCert.KeyFile)
131+
setIfUnset(args, "kubelet-https", "true")
132+
setIfUnset(args, "kubelet-preferred-address-types", "Hostname", "InternalIP", "ExternalIP")
133+
setIfUnset(args, "kubelet-read-only-port", "0")
134+
setIfUnset(args, "kubernetes-service-node-port", "0")
135+
setIfUnset(args, "max-mutating-requests-inflight", fmt.Sprintf("%d", kubeAPIServerConfig.ServingInfo.MaxRequestsInFlight/2))
136+
setIfUnset(args, "max-requests-inflight", fmt.Sprintf("%d", kubeAPIServerConfig.ServingInfo.MaxRequestsInFlight))
137+
setIfUnset(args, "min-request-timeout", fmt.Sprintf("%d", kubeAPIServerConfig.ServingInfo.RequestTimeoutSeconds))
138+
setIfUnset(args, "proxy-client-cert-file", kubeAPIServerConfig.AggregatorConfig.ProxyClientInfo.CertFile)
139+
setIfUnset(args, "proxy-client-key-file", kubeAPIServerConfig.AggregatorConfig.ProxyClientInfo.KeyFile)
140+
setIfUnset(args, "requestheader-allowed-names", kubeAPIServerConfig.AuthConfig.RequestHeader.ClientCommonNames...)
141+
setIfUnset(args, "requestheader-client-ca-file", kubeAPIServerConfig.AuthConfig.RequestHeader.ClientCA)
142+
setIfUnset(args, "requestheader-extra-headers-prefix", kubeAPIServerConfig.AuthConfig.RequestHeader.ExtraHeaderPrefixes...)
143+
setIfUnset(args, "requestheader-group-headers", kubeAPIServerConfig.AuthConfig.RequestHeader.GroupHeaders...)
144+
setIfUnset(args, "requestheader-username-headers", kubeAPIServerConfig.AuthConfig.RequestHeader.UsernameHeaders...)
145+
setIfUnset(args, "secure-port", portString)
146+
setIfUnset(args, "service-cluster-ip-range", kubeAPIServerConfig.KubernetesMasterConfig.ServicesSubnet)
147+
setIfUnset(args, "service-node-port-range", kubeAPIServerConfig.KubernetesMasterConfig.ServicesNodePortRange)
148+
setIfUnset(args, "storage-backend", "etcd3")
149+
setIfUnset(args, "storage-media-type", "application/vnd.kubernetes.protobuf")
150+
setIfUnset(args, "tls-cert-file", kubeAPIServerConfig.ServingInfo.ServerCert.CertFile)
151+
setIfUnset(args, "tls-cipher-suites", kubeAPIServerConfig.ServingInfo.CipherSuites...)
152+
setIfUnset(args, "tls-min-version", kubeAPIServerConfig.ServingInfo.MinTLSVersion)
153+
setIfUnset(args, "tls-private-key-file", kubeAPIServerConfig.ServingInfo.ServerCert.KeyFile)
154+
// TODO re-enable SNI for cluster up
155+
// tls-sni-cert-key
156+
setIfUnset(args, "secure-port", portString)
157+
158+
var keys []string
159+
for key := range args {
160+
keys = append(keys, key)
161+
}
162+
sort.Strings(keys)
163+
164+
var arguments []string
165+
for _, key := range keys {
166+
for _, token := range args[key] {
167+
arguments = append(arguments, fmt.Sprintf("--%s=%v", key, token))
168+
}
169+
}
170+
return arguments, nil
171+
}
172+
173+
// currently for cluster up, audit is just broken.
174+
// TODO fix this
175+
func auditFlags(kubeAPIServerConfig *configapi.MasterConfig) map[string][]string {
176+
args := map[string][]string{}
177+
for key, slice := range kubeAPIServerConfig.KubernetesMasterConfig.APIServerArguments {
178+
for _, val := range slice {
179+
args[key] = append(args[key], val)
180+
}
181+
}
182+
183+
return args
184+
}
185+
186+
func setIfUnset(cmdLineArgs map[string][]string, key string, value ...string) {
187+
if _, ok := cmdLineArgs[key]; !ok {
188+
cmdLineArgs[key] = value
189+
}
190+
}
191+
192+
func admissionFlags(kubeAPIServerConfig *configapi.MasterConfig) (map[string][]string, error) {
193+
args := map[string][]string{}
194+
195+
forceOn := []string{}
196+
forceOff := []string{}
197+
pluginConfig := map[string]configapi.AdmissionPluginConfig{}
198+
for pluginName, config := range kubeAPIServerConfig.AdmissionConfig.DeepCopy().PluginConfig {
199+
if len(config.Location) > 0 {
200+
content, err := ioutil.ReadFile(config.Location)
201+
if err != nil {
202+
return nil, err
203+
}
204+
// if the config isn't a DefaultAdmissionConfig, then assume we're enabled (we were called out after all)
205+
// if the config *is* a DefaultAdmissionConfig and it explicitly said to disable us, we are disabled
206+
obj, err := configapilatest.ReadYAML(bytes.NewBuffer(content))
207+
// if we can't read it, let the plugin deal with it
208+
// if nothing was there, let the plugin deal with it
209+
if err != nil || obj == nil {
210+
forceOn = append(forceOn, pluginName)
211+
config.Location = ""
212+
config.Configuration = &runtime.Unknown{Raw: content}
213+
pluginConfig[pluginName] = *config
214+
continue
215+
}
216+
217+
if defaultConfig, ok := obj.(*configapi.DefaultAdmissionConfig); !ok {
218+
forceOn = append(forceOn, pluginName)
219+
config.Location = ""
220+
config.Configuration = &runtime.Unknown{Raw: content}
221+
pluginConfig[pluginName] = *config
222+
223+
} else if defaultConfig.Disable {
224+
forceOff = append(forceOff, pluginName)
225+
226+
} else {
227+
forceOn = append(forceOn, pluginName)
228+
}
229+
230+
continue
231+
}
232+
// if it wasn't a DefaultAdmissionConfig object, let the plugin deal with it
233+
if defaultConfig, ok := config.Configuration.(*configapi.DefaultAdmissionConfig); !ok {
234+
forceOn = append(forceOn, pluginName)
235+
pluginConfig[pluginName] = *config
236+
237+
} else if defaultConfig.Disable {
238+
forceOff = append(forceOff, pluginName)
239+
240+
} else {
241+
forceOn = append(forceOn, pluginName)
242+
}
243+
244+
}
245+
upstreamAdmissionConfig, err := originadmission.ConvertOpenshiftAdmissionConfigToKubeAdmissionConfig(pluginConfig)
246+
if err != nil {
247+
return nil, err
248+
}
249+
configBytes, err := configapilatest.WriteYAML(upstreamAdmissionConfig)
250+
if err != nil {
251+
return nil, err
252+
}
253+
254+
tempFile, err := ioutil.TempFile("", "kubeapiserver-admission-config.yaml")
255+
if err != nil {
256+
return nil, err
257+
}
258+
if _, err := tempFile.Write(configBytes); err != nil {
259+
return nil, err
260+
}
261+
tempFile.Close()
262+
263+
setIfUnset(args, "admission-control-config-file", tempFile.Name())
264+
setIfUnset(args, "disable-admission-plugins", forceOff...)
265+
setIfUnset(args, "enable-admission-plugins", forceOn...)
266+
267+
return args, nil
268+
}

0 commit comments

Comments
 (0)