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

WIP: Allow kops cluster behind a proxy #2749

Closed

Conversation

johnzeringue
Copy link
Contributor

@johnzeringue johnzeringue commented Jun 14, 2017

Allow a kops cluster to operate behind a proxy by passing proxy
configuration to addons and nodes. The API will change to be consistent
with the rest of the project, but currently uses the environment
variables CLUSTER_HTTP_PROXY, CLUSTER_HTTPS_PROXY, and
CLUSTER_NO_PROXY available when and where kops is invoked.

Relates to #2481


This change is Reviewable

@k8s-ci-robot
Copy link
Contributor

Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please follow instructions at https://github.com/kubernetes/kubernetes/wiki/CLA-FAQ to sign the CLA.

It may take a couple minutes for the CLA signature to be fully registered; after that, please reply here with a new comment and we'll verify. Thanks.


Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. label Jun 14, 2017
@k8s-ci-robot
Copy link
Contributor

Hi @johnzeringue. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with @k8s-bot ok to test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Jun 14, 2017
Copy link
Member

@justinsb justinsb left a comment

Choose a reason for hiding this comment

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

Love the approach. I think few helper function could reduce some of the boilerplate code, but more importantly I think we should avoid adding too much new functionality to the bootstrap script, and we should consider storing the proxies in fields rather than env vars that must be passed every time.

buffer.WriteString(os.Getenv("NO_PROXY"))
buffer.WriteString("\" ")

manifest.Set("Service", "Environment", buffer.String())
Copy link
Member

Choose a reason for hiding this comment

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

So this would override the S3_ENDPOINT env. I would if we can refactor to build up a var env map[string]string, and then we manifest.Set("Service", "Environment"... with that only if the map is non-empty.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -188,6 +189,14 @@ func (b *KubeControllerManagerBuilder) buildPod() (*v1.Pod, error) {
},
}

if os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" {
Copy link
Member

Choose a reason for hiding this comment

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

We could probably put this into a helper function, in case the logic gets more complicated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a project convention for helper functions that span nodeup, kops, and protokube?

Copy link
Contributor

Choose a reason for hiding this comment

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

@johnzeringue putting the helper functions into upup is probably the best place for the code to live. There is not an official convention. If you want to recommend a convention let us know.


systemctl daemon-reload
systemctl restart docker
fi
Copy link
Member

Choose a reason for hiding this comment

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

If (if) we can put this logic into nodeup, it's a much safer place for it. The strategy in this file is to get nodeup running, but because doing retries etc is so hard in bash, we try not to put any additional logic into it.

Could we just export the 3 PROXY env vars, and then curl will pick them up?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could we just export the 3 PROXY env vars, and then curl will pick them up?

That's definitely the way to go

"ProxyEnv": func() string {
if os.Getenv("CLUSTER_HTTP_PROXY") != "" || os.Getenv("CLUSTER_HTTPS_PROXY") != "" {
return fmt.Sprintf("export HTTP_PROXY=%s\nexport HTTPS_PROXY=%s\nexport NO_PROXY=%s\n",
os.Getenv("CLUSTER_HTTP_PROXY"),
Copy link
Member

Choose a reason for hiding this comment

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

So my understanding is that we would have to set these env vars every time we called kops update.

I think this could instead be a couple of fields; it could either be a new top-level object (like authorization) or we could put it into the networking object. I think my preference would be a new top level object, because the networking object is currently an enum-style, where we only expect a single value to be set.

If you agree I'm happy to assist / write a doc & WIP PR on how to do this - let me know.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, the environment variables are terrible. I just haven't yet taken the time to familiarize myself with apimachinery.

Looking at it now, I think it should be a new top level object. I don't know whether proxy or proxying is preferred as the object name, but the fields should just be httpProxy, httpsProxy, and noProxy.

I'm not sure what kind of docs are needed, but I'd be happy to work with you

Copy link
Contributor

Choose a reason for hiding this comment

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

@johnzeringue here is some documentation that will help you with adding the new values into the API. https://github.com/kubernetes/kops/blob/master/docs/development/api_updates.md

I aggree with @justinsb that having these values as a new struct in the ClusterSpec makes a lot of sense. Here is an example of a struct that lives in the ClusterSpec https://github.com/kubernetes/kops/blob/master/pkg/apis/kops/cluster.go#L225

Allow a kops cluster to operate behind a proxy by passing proxy
configuration to addons and nodes. The API will change to be consistent
with the rest of the project, but currently uses the environment
variables `CLUSTER_HTTP_PROXY`, `CLUSTER_HTTPS_PROXY`, and
`CLUSTER_NO_PROXY` available when and where kops is invoked.

Relates to kubernetes#2481
@chrislovecnm
Copy link
Contributor

@johnzeringue can you sign the CLA?

@johnzeringue
Copy link
Contributor Author

@chrislovecnm, I'm working on getting my employer to sign.

@DerekV
Copy link
Contributor

DerekV commented Jun 19, 2017

I've got my own version up now as well finally #2777
I'm sorry I didn't get it up earlier.
Hopefully between the two sets we can find the cleanest solution.

Copy link
Contributor

@chrislovecnm chrislovecnm left a comment

Choose a reason for hiding this comment

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

Looks great, if you have questions let us know. Mostly concerned about having variables that are unset. Does it still work with values that are not set?

@@ -160,6 +161,14 @@ func (b *KubeAPIServerBuilder) buildPod() (*v1.Pod, error) {
},
}

if os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" {
container.Env = []v1.EnvVar{
{Name: "HTTP_PROXY", Value: os.Getenv("HTTP_PROXY")},
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to set this if it does not exist? This will set both env variables regardless if one does not exist.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In my experience export HTTP_PROXY= functions the same as unset HTTP_PROXY. There's an argument to be made for easy debugging (although maybe it goes both ways). Maybe it's neater with only the ones that get set. If anyone has a strong opinion, it's a quick change for me.

@@ -188,6 +189,14 @@ func (b *KubeControllerManagerBuilder) buildPod() (*v1.Pod, error) {
},
}

if os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

@johnzeringue putting the helper functions into upup is probably the best place for the code to live. There is not an official convention. If you want to recommend a convention let us know.

"ProxyEnv": func() string {
if os.Getenv("CLUSTER_HTTP_PROXY") != "" || os.Getenv("CLUSTER_HTTPS_PROXY") != "" {
return fmt.Sprintf("export HTTP_PROXY=%s\nexport HTTPS_PROXY=%s\nexport NO_PROXY=%s\n",
os.Getenv("CLUSTER_HTTP_PROXY"),
Copy link
Contributor

Choose a reason for hiding this comment

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

@johnzeringue here is some documentation that will help you with adding the new values into the API. https://github.com/kubernetes/kops/blob/master/docs/development/api_updates.md

I aggree with @justinsb that having these values as a new struct in the ClusterSpec makes a lot of sense. Here is an example of a struct that lives in the ClusterSpec https://github.com/kubernetes/kops/blob/master/pkg/apis/kops/cluster.go#L225

@chrislovecnm
Copy link
Contributor

We need a rebase, I know it is a pain, but if you could sign the CLA please.

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels Jun 30, 2017
@johnzeringue
Copy link
Contributor Author

I'll rebase the next chance I get to work on the code (I'm OOO for a couple weeks). The CLA should be signed now. It looks like the robot figured that out after you commented.

@k8s-github-robot
Copy link

@johnzeringue PR needs rebase

@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 20, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: johnzeringue
We suggest the following additional approver: justinsb

Assign the PR to them by writing /assign @justinsb in a comment when ready.

Associated issue: 2481

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

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@johnzeringue
Copy link
Contributor Author

Closing in favor of #2777

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants