Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable configure-helper.sh to support two scenarios for etcd level encryption: decryption and adding encryption to existing clusters. #68379

Merged
merged 1 commit into from
Oct 5, 2018

Conversation

immutableT
Copy link
Contributor

What this PR does / why we need it:

  1. Enables two additional scenarios for etcd level encryption:
    Adding encryption to an existing cluster
    Decryption
    Both of the above mentioned scenarios require that secrets be "touched" by the envelope transformer post cluster startup. This functionality is implemented in the apply-encryption-config function.
  2. Refactor all encryption related logic into a single function - setup-etcd-encryption
  3. Remove the responsibility of generating kms-plugin manifest from configure-helper.sh. Implementers of kms-plugins (cloud-providers) should rely on the up-stream components to generate kms-plugin manifest.

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #

Special notes for your reviewer:

Release note:

NONE

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Sep 6, 2018
@k8s-ci-robot k8s-ci-robot added sig/cluster-lifecycle Categorizes an issue or PR as relevant to SIG Cluster Lifecycle. and removed needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Sep 6, 2018
@immutableT
Copy link
Contributor Author

/assign @mikedanese

@immutableT immutableT force-pushed the kms-plugin-via-gke branch 2 times, most recently from 70bc500 to 6ee40cc Compare September 7, 2018 00:48
@BenTheElder
Copy link
Member

/ok-to-test

@k8s-ci-robot k8s-ci-robot removed the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Sep 8, 2018
@immutableT immutableT changed the title Enable configure_helper.sh to support two scenarios for etcd level encryption: decryption and adding encryption to existing clusters. Enable configure-helper.sh to support two scenarios for etcd level encryption: decryption and adding encryption to existing clusters. Sep 10, 2018
@immutableT
Copy link
Contributor Author

/assign @awly

@immutableT
Copy link
Contributor Author

/test pull-kubernetes-verify

Copy link
Contributor

@awly awly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a lot of bash and sed,. Just to make sure have you successfully started a cluster with these changes?

@@ -51,89 +55,138 @@ readonly DOCKER_REGISTRY="k8s.gcr.io"
readonly ENABLE_LEGACY_ABAC=false
readonly ETC_MANIFESTS=${KUBE_HOME}/etc/kubernetes/manifests
readonly KUBE_API_SERVER_DOCKER_TAG=v1.11.0-alpha.0.1808_3c7452dc11645d-dirty
readonly LOG_OWNER_USER=$(id -un)
readonly LOG_OWNER_USER=$(whoami)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this change for?

kmsPluginManifestFileName = "kms-plugin-container.manifest"
kubeAPIServerStartFuncName = "start-kube-apiserver"
/*
encryptionProviderConfigForKMS is base64 encoded yaml below
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you base64-encode it at runtime? Makes it easier to edit.
The YAML itself can still be a string

}

func newKubeAPIServerManifestTestCase(t *testing.T) *kubeAPIServerManifestTestCase {
return &kubeAPIServerManifestTestCase{
ManifestTestCase: newManifestTestCase(t, kubeAPIServerManifestFileName, kubeAPIServerStartFuncName, []string{kmsPluginManifestFileName}),
ManifestTestCase: newManifestTestCase(t, kubeAPIServerManifestFileName, kubeAPIServerStartFuncName, []string{}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nil instead of []string{}

flag := fmt.Sprintf("%s=%s", encryptionConfigFlag, e.EncryptionProviderConfigPath)

switch {
case tc.wantFlag && !flagIsInArg:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case tc.wantFlag != flagIsInArg:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would save one case block, but will prevent me from providing a more informative error message.

case !tc.wantFlag && flagIsInArg:
t.Fatalf("Got %q,\n do not want flags to contain %q", execArgs, encryptionConfigFlag)
case tc.wantFlag && flagIsInArg:
if !strings.Contains(execArgs, flag) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this check into the case condition above

# Assumes vars (supplied via kube-env):
# ENCRYPTION_PROVIDER_CONFIG
# CLOUD_KMS_INTEGRATION

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove newline

# kms_socket_mnt is used by both kms_plugin and kube-apiserver - this is how these containers talk.
local kms_socket_mnt="{ \"name\": \"kmssocket\", \"mountPath\": \"${kms_socket_dir}\", \"readOnly\": false}"
local -n kube_api_server_params=$2
local encryption_provider_config_path=${ENCRYPTION_PROVIDER_CONFIG_PATH:-/etc/srv/kubernetes/encryption-provider-config.yml}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mention ENCRYPTION_PROVIDER_CONFIG_PATH in the function comment above

# Assumes vars (supplied via kube-env):
# ENCRYPTION_PROVIDER_CONFIG_FORCE
function apply-encryption-config() {
if [[ -z "${ENCRYPTION_PROVIDER_CONFIG_FORCE:-}" ]] || [[ "${ENCRYPTION_PROVIDER_CONFIG_FORCE:-}" == "false" ]]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if [[ "${ENCRYPTION_PROVIDER_CONFIG_FORCE:-false}" == "false" ]];

} " "${src_file}"
fi
# need kube-apiserver to be ready
until kubectl get secret
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, what other startup steps are blocked by this? I wonder if this needs a timeout or maybe needs to run as the very last step of configure-helper

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this block of code fails then we can safely assume that the cluster did not come-up, so I don't see much value in time-out.
I put this function into background to allow other things to continue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, when the parent shell exits (when rest of configure-helper is done) will it continue running?
And will there be a way to tell if/when it fails?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that the parent will not exit until that function is done.
Today, this is a weak spot - cluster creation times-out and users need to login to the master to investigate. In other words, the caller would not know why kube-up or cluster create fails.

@BenTheElder
Copy link
Member

It's a lot of bash and sed,. Just to make sure have you successfully started a cluster with these changes?

I'd love if you took a look at these with shellcheck, working on a PR to make this a presubmit currently.

@immutableT
Copy link
Contributor Author

@awly PTAL.

@immutableT
Copy link
Contributor Author

@BenTheElder ran shellcheck and addressed issues it found in my changes.

@awly
Copy link
Contributor

awly commented Sep 10, 2018

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 10, 2018
@BenTheElder
Copy link
Member

Thanks!!

@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 10, 2018
@immutableT
Copy link
Contributor Author

squashed

params+=" --experimental-encryption-provider-config=${ENCRYPTION_PROVIDER_CONFIG_PATH}"
fi
# params is passed by reference, so no "$"
setup-etcd-encryption "${src_file}" params
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused. Isn't this params passed as a string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to allow setup-etcd-encryption function to modify params and the results of such modifications to be visible in start-kube-apiserver function. If I were to pass params as ${params} setup-etcd-encryption will get a copy of params.

EOM
)
fi
src_file="${src_dir}/kube-apiserver.manifest"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make local?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used in other places (ex. start-etcd-empty-dir-clean-up-pod).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

start-etcd-empty-dir-clean-up-pod declares src_file as local. Shouldn't we do the same here?

# kms_socket_mnt is used by both kms_plugin and kube-apiserver - this is how these containers talk.
local kms_socket_mnt="{ \"name\": \"kmssocket\", \"mountPath\": \"${kms_socket_dir}\", \"readOnly\": false}"
kube_api_server_params=$2
encryption_provider_config_path=${ENCRYPTION_PROVIDER_CONFIG_PATH:-/etc/srv/kubernetes/encryption-provider-config.yml}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quote bash variable

# CLOUD_KMS_INTEGRATION
# ENCRYPTION_PROVIDER_CONFIG_PATH (will default to /etc/srv/kubernetes/encryption-provider-config.yml)
function setup-etcd-encryption {
local kube_apiserver_template_path
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File uses two spaces for indent

cp "${src_file}" "${ETC_MANIFESTS:-/etc/kubernetes/manifests}"
# forces all secrets to be re-written to etcd, and in the process either encrypting or decrypting them
# https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it will lose data if secrets are being modified while it runs.

@immutableT immutableT force-pushed the kms-plugin-via-gke branch 2 times, most recently from 33628ec to cffa2b9 Compare September 27, 2018 22:08
@immutableT
Copy link
Contributor Author

@mikedanese PTAL.

@mikedanese
Copy link
Member

/retest

# need kube-apiserver to be ready
until kubectl get secret
do
sleep ${ENCRYPTION_PROVIDER_CONFIG_FORCE_DELAY:-5}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix indentation

# ENCRYPTION_PROVIDER_CONFIG_FORCE
function apply-encryption-config() {
if [[ "${ENCRYPTION_PROVIDER_CONFIG_FORCE:-false}" == "false" ]]; then
return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix indentation

cp "${src_file}" "${ETC_MANIFESTS:-/etc/kubernetes/manifests}"
# need kube-apiserver to be ready
until kubectl get secret
do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# else updated the secret in the middle of our update).
# TODO: Retry only on errors caused by a conflict.
until (( retries == 0 ))
do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mikedanese
Copy link
Member

/lgtm
/hold

@k8s-ci-robot k8s-ci-robot added lgtm "Looks good to me", indicates that a PR is ready to be merged. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed lgtm "Looks good to me", indicates that a PR is ready to be merged. labels Oct 4, 2018
@mikedanese
Copy link
Member

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 4, 2018
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: awly, immutableT, mikedanese

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@immutableT
Copy link
Contributor Author

/test pull-kubernetes-integration
/test pull-kubernetes-e2e-kops-aws

@immutableT
Copy link
Contributor Author

/test pull-kubernetes-e2e-kops-aws

@mikedanese
Copy link
Member

/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 4, 2018
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

1 similar comment
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@immutableT
Copy link
Contributor Author

/test pull-kubernetes-e2e-gke

@k8s-ci-robot k8s-ci-robot merged commit 5602ab7 into kubernetes:master Oct 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesn't merit a release note. sig/cluster-lifecycle Categorizes an issue or PR as relevant to SIG Cluster Lifecycle. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants