Skip to content

Commit

Permalink
Merge pull request istio#7818 from costinm/11-merge-10
Browse files Browse the repository at this point in the history
Merge recent changes from release-1.0
  • Loading branch information
rshriram authored Aug 14, 2018
2 parents f9ad4f0 + dfe9f6b commit 8aa9840
Show file tree
Hide file tree
Showing 19 changed files with 195 additions and 30 deletions.
37 changes: 37 additions & 0 deletions galley/pkg/crd/validation/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,50 @@ import (
"istio.io/istio/pkg/log"
)

// Check if the galley validation endpoint is ready to receive requests.
func (wh *Webhook) endpointReady() error {
endpoints, err := wh.clientset.CoreV1().Endpoints(wh.deploymentNamespace).Get(wh.deploymentName, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("%s/%v endpoint ready check failed: %v", wh.deploymentNamespace, wh.deploymentName, err)
}

if len(endpoints.Subsets) == 0 {
return fmt.Errorf("%s/%v endpoint not ready: no subsets", wh.deploymentNamespace, wh.deploymentName)
}

for _, subset := range endpoints.Subsets {
if len(subset.Addresses) > 0 {
return nil
}
}
return fmt.Errorf("%s/%v endpoint not ready: no ready addresses", wh.deploymentNamespace, wh.deploymentName)
}

func (wh *Webhook) createOrUpdateWebhookConfig() {
if wh.webhookConfiguration == nil {
log.Error("validatingwebhookconfiguration update failed: no configuration loaded")
reportValidationConfigUpdateError(errors.New("no configuration loaded"))
return
}

// During initial Istio installation its possible for custom
// resources to be created concurrently with galley startup. This
// can lead to validation failures with "no endpoints available"
// if the webhook is registered before the endpoint is visible to
// the rest of the system. Minimize this problem by waiting the
// galley endpoint is available at least once before
// self-registering. Subsequent Istio upgrades rely on deployment
// rolling updates to set maxUnavailable to zero.
if !wh.endpointReadyOnce {
if err := wh.endpointReady(); err != nil {
log.Warnf("%v validatingwebhookconfiguration update deferred: %v",
wh.webhookConfiguration.Name, err)
reportValidationConfigUpdateError(errors.New("endpoint not ready"))
return
}
wh.endpointReadyOnce = true
}

client := wh.clientset.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations()
updated, err := createOrUpdateWebhookConfigHelper(client, wh.webhookConfiguration)
if err != nil {
Expand Down
22 changes: 12 additions & 10 deletions galley/pkg/crd/validation/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ type Webhook struct {
deploymentName string
ownerRefs []v1.OwnerReference
webhookConfiguration *v1beta1.ValidatingWebhookConfiguration
endpointReadyOnce bool
}

// NewWebhook creates a new instance of the admission webhook controller.
Expand Down Expand Up @@ -200,15 +201,6 @@ func NewWebhook(p WebhookParameters) (*Webhook, error) {
}
}

if wh.webhookConfigFile != "" {
log.Info("server-side configuration validation enabled")
if err = wh.rebuildWebhookConfig(); err == nil {
wh.createOrUpdateWebhookConfig()
}
} else {
log.Info("server-side configuration validation disabled. Enable with --webhook-config-file")
}

// mtls disabled because apiserver webhook cert usage is still TBD.
wh.server.TLSConfig = &tls.Config{GetCertificate: wh.getCert}
h := http.NewServeMux()
Expand Down Expand Up @@ -245,6 +237,12 @@ func (wh *Webhook) Run(stop <-chan struct{}) {
var keyCertTimerC <-chan time.Time
var configTimerC <-chan time.Time

if wh.webhookConfigFile != "" {
log.Info("server-side configuration validation enabled")
} else {
log.Info("server-side configuration validation disabled. Enable with --webhook-config-file")
}

var reconcileTickerC <-chan time.Time
if wh.webhookConfigFile != "" {
reconcileTickerC = time.NewTicker(time.Second).C
Expand All @@ -261,7 +259,11 @@ func (wh *Webhook) Run(stop <-chan struct{}) {
wh.createOrUpdateWebhookConfig()
}
case <-reconcileTickerC:
if wh.webhookConfiguration != nil {
if wh.webhookConfiguration == nil {
if err := wh.rebuildWebhookConfig(); err == nil {
wh.createOrUpdateWebhookConfig()
}
} else {
wh.createOrUpdateWebhookConfig()
}
case event, more := <-wh.keyCertWatcher.Event:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{- if not .Values.global.omitSidecarInjectorConfigMap }}
apiVersion: v1
kind: ConfigMap
metadata:
Expand Down Expand Up @@ -168,4 +169,4 @@ data:
{{ "[[ else -]]" }}
secretName: {{ "[[ printf \"istio.%s\" .Spec.ServiceAccountName ]]" }}
{{ "[[ end -]]" }}

{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ rules:
resources: ["deployments"]
resourceNames: ["istio-galley"]
verbs: ["get"]
- apiGroups: ["*"]
resources: ["endpoints"]
resourceNames: ["istio-galley"]
verbs: ["get"]
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ spec:
- --grpc-port=8060
- --grpc-hostname=citadel
- --citadel-storage-namespace={{ .Release.Namespace }}
- --custom-dns-names=istio-pilot-service-account.{{ .Release.Namespace }}:istio-pilot.{{ .Release.Namespace }}
{{- if .Values.selfSigned }}
- --self-signed-ca=true
{{- else }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if .Values.sidecarInjectorWebhook.enabled }}
{{- if not .Values.global.omitSidecarInjectorConfigMap }}
apiVersion: v1
kind: ConfigMap
metadata:
Expand Down
6 changes: 6 additions & 0 deletions install/kubernetes/helm/istio/values-istio-gateways.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ global:
# and this options must be set off.
crds: false

# Omit the istio-sidecar-injector configmap when generate a
# standalone gateway. Gateways may be created in namespaces other
# than `istio-system` and we don't want to re-create the injector
# configmap in those.
omitSidecarInjectorConfigMap: true

# istio control plane namespace
istioNamespace: istio-system

Expand Down
5 changes: 3 additions & 2 deletions install/kubernetes/helm/istio/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,9 @@ gateways:
- port: 8060
targetPort: 8060
name: tcp-citadel-grpc-tls
# Telemetry-related ports are enabled in gateway - but will only redirect if
# the gateway configration for the various components are enabled.
- port: 853
targetPort: 853
name: tcp-dns-tls
- port: 15030
targetPort: 15030
name: http2-prometheus
Expand Down
2 changes: 1 addition & 1 deletion security/pkg/pki/ca/controller/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ func (sc *SecretController) generateKeyAndCert(saName string, saNamespace string
}
}
// Custom overrides using CLI
if e, ok := sc.dnsNames[saName+"."+saName]; ok {
if e, ok := sc.dnsNames[saName+"."+saNamespace]; ok {
for _, d := range e.CustomDomains {
id += "," + d
}
Expand Down
2 changes: 1 addition & 1 deletion security/pkg/platform/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func NewAwsClientImpl(rootCert string) *AwsClientImpl {

// GetDialOptions returns the GRPC dial options to connect to the CA.
func (ci *AwsClientImpl) GetDialOptions() ([]grpc.DialOption, error) {
creds, err := credentials.NewClientTLSFromFile(ci.rootCertFile, "")
creds, err := credentials.NewClientTLSFromFile(ci.rootCertFile, CitadelDNSSan)
if err != nil {
return nil, err
}
Expand Down
5 changes: 3 additions & 2 deletions security/pkg/platform/gcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ func NewGcpClientImpl(rootCert, ca string) *GcpClientImpl {
return &GcpClientImpl{
rootCertFile: rootCert,
caAddr: ca,
fetcher: &cred.GcpTokenFetcher{Aud: fmt.Sprintf("grpc://%s", ca)},
// The expected token is independent of the URL of the server.
fetcher: &cred.GcpTokenFetcher{Aud: "grpc://istio-citadel:8060"},
}
}

Expand All @@ -77,7 +78,7 @@ func (ci *GcpClientImpl) GetDialOptions() ([]grpc.DialOption, error) {
return nil, err
}

creds, err := credentials.NewClientTLSFromFile(ci.rootCertFile, "")
creds, err := credentials.NewClientTLSFromFile(ci.rootCertFile, CitadelDNSSan)
if err != nil {
return nil, err
}
Expand Down
14 changes: 13 additions & 1 deletion security/pkg/platform/onprem.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"

"strings"

"istio.io/istio/security/pkg/pki/util"
)

Expand All @@ -37,6 +39,10 @@ type OnPremClientImpl struct {
certChainFile string
}

// CitadelDNSSan is the hardcoded DNS SAN used to identify citadel server.
// The user may use an IP address to connect to the mesh.
const CitadelDNSSan = "istio-citadel"

// NewOnPremClientImpl creates a new OnPremClientImpl.
func NewOnPremClientImpl(rootCert, key, certChain string) (*OnPremClientImpl, error) {
if _, err := os.Stat(rootCert); err != nil {
Expand Down Expand Up @@ -84,7 +90,12 @@ func (ci *OnPremClientImpl) GetServiceIdentity() (string, error) {
return "", err
}
if len(serviceIDs) != 1 {
return "", fmt.Errorf("cert has %v SAN fields, should be 1", len(serviceIDs))
for _, s := range serviceIDs {
if strings.HasPrefix(s, "spiffe://") {
return s, nil
}
}
return "", fmt.Errorf("cert does not have siffe:// SAN fields")
}
return serviceIDs[0], nil
}
Expand Down Expand Up @@ -129,6 +140,7 @@ func getTLSCredentials(rootCertFile, keyFile, certChainFile string) (credentials
Certificates: []tls.Certificate{certificate},
}
config.RootCAs = certPool
config.ServerName = CitadelDNSSan

return credentials.NewTLS(&config), nil
}
20 changes: 19 additions & 1 deletion tests/e2e/framework/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const (
defaultSidecarInjectorFile = "istio-sidecar-injector.yaml"
ingressCertsName = "istio-ingress-certs"
maxDeploymentRolloutTime = 480 * time.Second
maxValidationReadyCheckTime = 30 * time.Second
helmServiceAccountFile = "helm-service-account.yaml"
istioHelmInstallDir = istioInstallDir + "/helm/istio"
caCertFileName = "samples/certs/ca-cert.pem"
Expand Down Expand Up @@ -693,7 +694,24 @@ func (k *KubeInfo) deployIstio() error {
}
}

return util.CheckDeployments(k.Namespace, maxDeploymentRolloutTime, k.KubeConfig)
if err := util.CheckDeployments(k.Namespace, maxDeploymentRolloutTime, k.KubeConfig); err != nil {
return err
}

if *useGalleyConfigValidator {
timeout := time.Now().Add(maxValidationReadyCheckTime)
var validationReady bool
for time.Now().Before(timeout) {
if _, err := util.ShellSilent("kubectl get validatingwebhookconfiguration istio-galley --kubeconfig=%s", k.KubeConfig); err == nil {
validationReady = true
break
}
}
if !validationReady {
return errors.New("timeout waiting for validatingwebhookconfiguration istio-galley to be created")
}
}
return nil
}

// DeployTiller deploys tiller in Istio mesh or returns error
Expand Down
4 changes: 2 additions & 2 deletions tests/istio.mk
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ e2e_galley_run: out_dir
go test -v -timeout 25m ./tests/e2e/tests/galley -args ${E2E_ARGS} ${EXTRA_E2E_ARGS} -use_galley_config_validator -cluster_wide

e2e_dashboard_run: out_dir
go test -v -timeout 25m ./tests/e2e/tests/dashboard -args ${E2E_ARGS} ${EXTRA_E2E_ARGS}
go test -v -timeout 25m ./tests/e2e/tests/dashboard -args ${E2E_ARGS} ${EXTRA_E2E_ARGS} -use_galley_config_validator -cluster_wide

e2e_bookinfo_run: out_dir
go test -v -timeout 60m ./tests/e2e/tests/bookinfo -args ${E2E_ARGS} ${EXTRA_E2E_ARGS}
Expand Down Expand Up @@ -249,4 +249,4 @@ helm/upgrade:
# Note that for Helm 2.10, the CRDs are not cleared
helm/delete:
${HELM} delete --purge istio-system
kubectl delete -f install/kubernetes/helm/istio/templates/crds.yaml
kubectl delete -f install/kubernetes/helm/istio/templates/crds.yaml
2 changes: 1 addition & 1 deletion tools/deb/istio-auth-node-agent.service
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Description=istio-auth-node-agent: The Istio auth node agent
Documentation=https://istio.io/

[Service]
ExecStart=/usr/local/bin/node_agent
ExecStart=/usr/local/bin/istio-node-agent-start.sh
Restart=always
StartLimitInterval=0
RestartSec=10
Expand Down
62 changes: 62 additions & 0 deletions tools/deb/istio-node-agent-start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/bash
#
# Copyright 2017 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#
# Script to configure and start the Istio node agent.
# Will run the node_agent as istio-proxy instead of root - to allow interception
# of apps running as root (node_agent requires root to not be intercepted) and
# to reduce risks.

set -e

# Load optional config variables
ISTIO_SIDECAR_CONFIG=${ISTIO_SIDECAR_CONFIG:-/var/lib/istio/envoy/sidecar.env}
if [[ -r ${ISTIO_SIDECAR_CONFIG} ]]; then
. $ISTIO_SIDECAR_CONFIG
fi

# Load config variables ISTIO_SYSTEM_NAMESPACE, CONTROL_PLANE_AUTH_POLICY
ISTIO_CLUSTER_CONFIG=${ISTIO_CLUSTER_CONFIG:-/var/lib/istio/envoy/cluster.env}
if [[ -r ${ISTIO_CLUSTER_CONFIG} ]]; then
. $ISTIO_CLUSTER_CONFIG
fi

# Set defaults
ISTIO_BIN_BASE=${ISTIO_BIN_BASE:-/usr/local/bin}
ISTIO_LOG_DIR=${ISTIO_LOG_DIR:-/var/log/istio}
NS=${ISTIO_NAMESPACE:-default}
SVC=${ISTIO_SERVICE:-rawvm}
ISTIO_SYSTEM_NAMESPACE=${ISTIO_SYSTEM_NAMESPACE:-istio-system}

EXEC_USER=${EXEC_USER:-istio-proxy}

if [ -z "${CITADEL_ADDRESS:-}" ]; then
CITADEL_ADDRESS=istio-citadel:8060
fi

CERTS_DIR=${CERTS_DIR:-/etc/certs}

CITADEL_ARGS="--ca-address ${CITADEL_ADDRESS}"
CITADEL_ARGS="${CITADEL_ARGS} --cert-chain ${CERTS_DIR}/cert-chain.pem"
CITADEL_ARGS="${CITADEL_ARGS} --key ${CERTS_DIR}/key.pem"
CITADEL_ARGS="${CITADEL_ARGS} --root-cert ${CERTS_DIR}/root-cert.pem"

if [ ${EXEC_USER} == ${USER:-} ] ; then
${ISTIO_BIN_BASE}/node_agent ${CITADEL_ARGS}
else
su -s /bin/sh -c "exec ${ISTIO_BIN_BASE}/node_agent ${CITADEL_ARGS}" ${EXEC_USER}
fi
Loading

0 comments on commit 8aa9840

Please sign in to comment.