Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
9036d07c
Commit
9036d07c
authored
Nov 07, 2017
by
George Kraft
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add extra-args configs to kubernetes-worker charm
parent
45bdf707
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
152 additions
and
448 deletions
+152
-448
flagmanager.py
...rs/kubernetes-master/lib/charms/kubernetes/flagmanager.py
+0
-149
kubernetes_master.py
...ju/layers/kubernetes-master/reactive/kubernetes_master.py
+48
-91
config.yaml
cluster/juju/layers/kubernetes-worker/config.yaml
+18
-0
flagmanager.py
...rs/kubernetes-worker/lib/charms/kubernetes/flagmanager.py
+0
-149
kubernetes_worker.py
...ju/layers/kubernetes-worker/reactive/kubernetes_worker.py
+86
-59
No files found.
cluster/juju/layers/kubernetes-master/lib/charms/kubernetes/flagmanager.py
deleted
100644 → 0
View file @
45bdf707
#!/usr/bin/env python
# Copyright 2015 The Kubernetes Authors.
#
# 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.
from
charmhelpers.core
import
unitdata
class
FlagManager
:
'''
FlagManager - A Python class for managing the flags to pass to an
application without remembering what's been set previously.
This is a blind class assuming the operator knows what they are doing.
Each instance of this class should be initialized with the intended
application to manage flags. Flags are then appended to a data-structure
and cached in unitdata for later recall.
THe underlying data-provider is backed by a SQLITE database on each unit,
tracking the dictionary, provided from the 'charmhelpers' python package.
Summary:
opts = FlagManager('docker')
opts.add('bip', '192.168.22.2')
opts.to_s()
'''
def
__init__
(
self
,
daemon
,
opts_path
=
None
):
self
.
db
=
unitdata
.
kv
()
self
.
daemon
=
daemon
if
not
self
.
db
.
get
(
daemon
):
self
.
data
=
{}
else
:
self
.
data
=
self
.
db
.
get
(
daemon
)
def
__save
(
self
):
self
.
db
.
set
(
self
.
daemon
,
self
.
data
)
def
add
(
self
,
key
,
value
,
strict
=
False
):
'''
Adds data to the map of values for the DockerOpts file.
Supports single values, or "multiopt variables". If you
have a flag only option, like --tlsverify, set the value
to None. To preserve the exact value, pass strict
eg:
opts.add('label', 'foo')
opts.add('label', 'foo, bar, baz')
opts.add('flagonly', None)
opts.add('cluster-store', 'consul://a:4001,b:4001,c:4001/swarm',
strict=True)
'''
if
strict
:
self
.
data
[
'{}-strict'
.
format
(
key
)]
=
value
self
.
__save
()
return
if
value
:
values
=
[
x
.
strip
()
for
x
in
value
.
split
(
','
)]
# handle updates
if
key
in
self
.
data
and
self
.
data
[
key
]
is
not
None
:
item_data
=
self
.
data
[
key
]
for
c
in
values
:
c
=
c
.
strip
()
if
c
not
in
item_data
:
item_data
.
append
(
c
)
self
.
data
[
key
]
=
item_data
else
:
# handle new
self
.
data
[
key
]
=
values
else
:
# handle flagonly
self
.
data
[
key
]
=
None
self
.
__save
()
def
remove
(
self
,
key
,
value
):
'''
Remove a flag value from the DockerOpts manager
Assuming the data is currently {'foo': ['bar', 'baz']}
d.remove('foo', 'bar')
> {'foo': ['baz']}
:params key:
:params value:
'''
self
.
data
[
key
]
.
remove
(
value
)
self
.
__save
()
def
destroy
(
self
,
key
,
strict
=
False
):
'''
Destructively remove all values and key from the FlagManager
Assuming the data is currently {'foo': ['bar', 'baz']}
d.wipe('foo')
>{}
:params key:
:params strict:
'''
try
:
if
strict
:
self
.
data
.
pop
(
'{}-strict'
.
format
(
key
))
else
:
self
.
data
.
pop
(
key
)
self
.
__save
()
except
KeyError
:
pass
def
get
(
self
,
key
,
default
=
None
):
"""Return the value for ``key``, or the default if ``key`` doesn't exist.
"""
return
self
.
data
.
get
(
key
,
default
)
def
destroy_all
(
self
):
'''
Destructively removes all data from the FlagManager.
'''
self
.
data
.
clear
()
self
.
__save
()
def
to_s
(
self
):
'''
Render the flags to a single string, prepared for the Docker
Defaults file. Typically in /etc/default/docker
d.to_s()
> "--foo=bar --foo=baz"
'''
flags
=
[]
for
key
in
self
.
data
:
if
self
.
data
[
key
]
is
None
:
# handle flagonly
flags
.
append
(
"{}"
.
format
(
key
))
elif
'-strict'
in
key
:
# handle strict values, and do it in 2 steps.
# If we rstrip -strict it strips a tailing s
proper_key
=
key
.
rstrip
(
'strict'
)
.
rstrip
(
'-'
)
flags
.
append
(
"{}={}"
.
format
(
proper_key
,
self
.
data
[
key
]))
else
:
# handle multiopt and typical flags
for
item
in
self
.
data
[
key
]:
flags
.
append
(
"{}={}"
.
format
(
key
,
item
))
return
' '
.
join
(
flags
)
cluster/juju/layers/kubernetes-master/reactive/kubernetes_master.py
View file @
9036d07c
...
@@ -43,7 +43,6 @@ from charms.reactive import when, when_any, when_not, when_all
...
@@ -43,7 +43,6 @@ from charms.reactive import when, when_any, when_not, when_all
from
charms.reactive.helpers
import
data_changed
,
any_file_changed
from
charms.reactive.helpers
import
data_changed
,
any_file_changed
from
charms.kubernetes.common
import
get_version
from
charms.kubernetes.common
import
get_version
from
charms.kubernetes.common
import
retry
from
charms.kubernetes.common
import
retry
from
charms.kubernetes.flagmanager
import
FlagManager
from
charms.layer
import
tls_client
from
charms.layer
import
tls_client
...
@@ -172,11 +171,6 @@ def migrate_from_pre_snaps():
...
@@ -172,11 +171,6 @@ def migrate_from_pre_snaps():
hookenv
.
log
(
"Removing file: "
+
file
)
hookenv
.
log
(
"Removing file: "
+
file
)
os
.
remove
(
file
)
os
.
remove
(
file
)
# clear the flag managers
FlagManager
(
'kube-apiserver'
)
.
destroy_all
()
FlagManager
(
'kube-controller-manager'
)
.
destroy_all
()
FlagManager
(
'kube-scheduler'
)
.
destroy_all
()
def
install_snaps
():
def
install_snaps
():
channel
=
hookenv
.
config
(
'channel'
)
channel
=
hookenv
.
config
(
'channel'
)
...
@@ -228,15 +222,10 @@ def configure_cni(cni):
...
@@ -228,15 +222,10 @@ def configure_cni(cni):
@when_not
(
'authentication.setup'
)
@when_not
(
'authentication.setup'
)
def
setup_leader_authentication
():
def
setup_leader_authentication
():
'''Setup basic authentication and token access for the cluster.'''
'''Setup basic authentication and token access for the cluster.'''
api_opts
=
FlagManager
(
'kube-apiserver'
)
controller_opts
=
FlagManager
(
'kube-controller-manager'
)
service_key
=
'/root/cdk/serviceaccount.key'
service_key
=
'/root/cdk/serviceaccount.key'
basic_auth
=
'/root/cdk/basic_auth.csv'
basic_auth
=
'/root/cdk/basic_auth.csv'
known_tokens
=
'/root/cdk/known_tokens.csv'
known_tokens
=
'/root/cdk/known_tokens.csv'
api_opts
.
add
(
'basic-auth-file'
,
basic_auth
)
api_opts
.
add
(
'token-auth-file'
,
known_tokens
)
hookenv
.
status_set
(
'maintenance'
,
'Rendering authentication templates.'
)
hookenv
.
status_set
(
'maintenance'
,
'Rendering authentication templates.'
)
keys
=
[
service_key
,
basic_auth
,
known_tokens
]
keys
=
[
service_key
,
basic_auth
,
known_tokens
]
...
@@ -257,9 +246,6 @@ def setup_leader_authentication():
...
@@ -257,9 +246,6 @@ def setup_leader_authentication():
check_call
(
cmd
)
check_call
(
cmd
)
remove_state
(
'reconfigure.authentication.setup'
)
remove_state
(
'reconfigure.authentication.setup'
)
api_opts
.
add
(
'service-account-key-file'
,
service_key
)
controller_opts
.
add
(
'service-account-private-key-file'
,
service_key
)
# read service account key for syndication
# read service account key for syndication
leader_data
=
{}
leader_data
=
{}
for
f
in
[
known_tokens
,
basic_auth
,
service_key
]:
for
f
in
[
known_tokens
,
basic_auth
,
service_key
]:
...
@@ -294,13 +280,6 @@ def setup_non_leader_authentication():
...
@@ -294,13 +280,6 @@ def setup_non_leader_authentication():
return
return
hookenv
.
status_set
(
'maintenance'
,
'Rendering authentication templates.'
)
hookenv
.
status_set
(
'maintenance'
,
'Rendering authentication templates.'
)
api_opts
=
FlagManager
(
'kube-apiserver'
)
api_opts
.
add
(
'basic-auth-file'
,
basic_auth
)
api_opts
.
add
(
'token-auth-file'
,
known_tokens
)
api_opts
.
add
(
'service-account-key-file'
,
service_key
)
controller_opts
=
FlagManager
(
'kube-controller-manager'
)
controller_opts
.
add
(
'service-account-private-key-file'
,
service_key
)
remove_state
(
'kubernetes-master.components.started'
)
remove_state
(
'kubernetes-master.components.started'
)
set_state
(
'authentication.setup'
)
set_state
(
'authentication.setup'
)
...
@@ -400,7 +379,7 @@ def start_master(etcd):
...
@@ -400,7 +379,7 @@ def start_master(etcd):
handle_etcd_relation
(
etcd
)
handle_etcd_relation
(
etcd
)
# Add CLI options to all components
# Add CLI options to all components
configure_apiserver
()
configure_apiserver
(
etcd
)
configure_controller_manager
()
configure_controller_manager
()
configure_scheduler
()
configure_scheduler
()
...
@@ -768,8 +747,9 @@ def on_config_allow_privileged_change():
...
@@ -768,8 +747,9 @@ def on_config_allow_privileged_change():
@when
(
'config.changed.api-extra-args'
)
@when
(
'config.changed.api-extra-args'
)
@when
(
'kubernetes-master.components.started'
)
@when
(
'kubernetes-master.components.started'
)
def
on_config_api_extra_args_change
():
@when
(
'etcd.available'
)
configure_apiserver
()
def
on_config_api_extra_args_change
(
etcd
):
configure_apiserver
(
etcd
)
@when
(
'config.changed.controller-manager-extra-args'
)
@when
(
'config.changed.controller-manager-extra-args'
)
...
@@ -957,9 +937,9 @@ def get_kubernetes_service_ip():
...
@@ -957,9 +937,9 @@ def get_kubernetes_service_ip():
def
handle_etcd_relation
(
reldata
):
def
handle_etcd_relation
(
reldata
):
''' Save the client credentials and set appropriate daemon flags when
''' Save the client credentials and set appropriate daemon flags when
etcd declares itself as available'''
etcd declares itself as available'''
connection_string
=
reldata
.
get_connection_string
()
# Define where the etcd tls files will be kept.
# Define where the etcd tls files will be kept.
etcd_dir
=
'/root/cdk/etcd'
etcd_dir
=
'/root/cdk/etcd'
# Create paths to the etcd client ca, key, and cert file locations.
# Create paths to the etcd client ca, key, and cert file locations.
ca
=
os
.
path
.
join
(
etcd_dir
,
'client-ca.pem'
)
ca
=
os
.
path
.
join
(
etcd_dir
,
'client-ca.pem'
)
key
=
os
.
path
.
join
(
etcd_dir
,
'client-key.pem'
)
key
=
os
.
path
.
join
(
etcd_dir
,
'client-key.pem'
)
...
@@ -968,85 +948,45 @@ def handle_etcd_relation(reldata):
...
@@ -968,85 +948,45 @@ def handle_etcd_relation(reldata):
# Save the client credentials (in relation data) to the paths provided.
# Save the client credentials (in relation data) to the paths provided.
reldata
.
save_client_credentials
(
key
,
cert
,
ca
)
reldata
.
save_client_credentials
(
key
,
cert
,
ca
)
api_opts
=
FlagManager
(
'kube-apiserver'
)
# Never use stale data, always prefer whats coming in during context
def
parse_extra_args
(
config_key
):
# building. if its stale, its because whats in unitdata is stale
elements
=
hookenv
.
config
()
.
get
(
config_key
,
''
)
.
split
()
data
=
api_opts
.
data
args
=
{}
if
data
.
get
(
'etcd-servers-strict'
)
or
data
.
get
(
'etcd-servers'
):
api_opts
.
destroy
(
'etcd-cafile'
)
for
element
in
elements
:
api_opts
.
destroy
(
'etcd-keyfile'
)
if
'='
in
element
:
api_opts
.
destroy
(
'etcd-certfile'
)
key
,
_
,
value
=
element
.
partition
(
'='
)
api_opts
.
destroy
(
'etcd-servers'
,
strict
=
True
)
args
[
key
]
=
value
api_opts
.
destroy
(
'etcd-servers'
)
else
:
args
[
element
]
=
'true'
# Set the apiserver flags in the options manager
return
args
api_opts
.
add
(
'etcd-cafile'
,
ca
)
api_opts
.
add
(
'etcd-keyfile'
,
key
)
api_opts
.
add
(
'etcd-certfile'
,
cert
)
api_opts
.
add
(
'etcd-servers'
,
connection_string
,
strict
=
True
)
def
get_config_args
(
key
):
def
configure_kubernetes_service
(
service
,
base_args
,
extra_args_
key
):
db
=
unitdata
.
kv
()
db
=
unitdata
.
kv
()
old_config_args
=
db
.
get
(
key
,
[])
# We have to convert them to tuples becuase we use sets
old_config_args
=
[
tuple
(
i
)
for
i
in
old_config_args
]
new_config_args
=
[]
new_config_arg_names
=
[]
for
arg
in
hookenv
.
config
()
.
get
(
key
,
''
)
.
split
():
new_config_arg_names
.
append
(
arg
.
split
(
'='
,
1
)[
0
])
if
len
(
arg
.
split
(
'='
,
1
))
==
1
:
# handle flags ie. --profiling
new_config_args
.
append
(
tuple
([
arg
,
'true'
]))
else
:
new_config_args
.
append
(
tuple
(
arg
.
split
(
'='
,
1
)))
hookenv
.
log
(
'Handling "
%
s" option.'
%
key
)
hookenv
.
log
(
'Old arguments: {}'
.
format
(
old_config_args
))
hookenv
.
log
(
'New arguments: {}'
.
format
(
new_config_args
))
if
set
(
new_config_args
)
==
set
(
old_config_args
):
return
(
new_config_args
,
[])
# Store new args
db
.
set
(
key
,
new_config_args
)
to_add
=
set
(
new_config_args
)
to_remove
=
set
(
old_config_args
)
-
set
(
new_config_args
)
# Extract option names only
to_remove
=
[
i
[
0
]
for
i
in
to_remove
if
i
[
0
]
not
in
new_config_arg_names
]
return
(
to_add
,
to_remove
)
prev_args_key
=
'kubernetes-master.prev_args.'
+
service
prev_args
=
db
.
get
(
prev_args_key
)
or
{}
def
configure_kubernetes_service
(
service
,
base_args
,
extra_args_key
):
extra_args
=
parse_extra_args
(
extra_args_key
)
# Handle api-extra-args config option
to_add
,
to_remove
=
get_config_args
(
extra_args_key
)
flag_manager
=
FlagManager
(
service
)
# Remove arguments that are no longer provided as config option
# this allows them to be reverted to charm defaults
for
arg
in
to_remove
:
hookenv
.
log
(
'Removing option: {}'
.
format
(
arg
))
flag_manager
.
destroy
(
arg
)
# We need to "unset" options by setting their value to "null" string
cmd
=
[
'snap'
,
'set'
,
service
,
'{}=null'
.
format
(
arg
)]
check_call
(
cmd
)
# Add base arguments
args
=
{}
for
arg
in
prev_args
:
# remove previous args by setting to null
args
[
arg
]
=
'null'
for
k
,
v
in
base_args
.
items
():
for
k
,
v
in
base_args
.
items
():
flag_manager
.
add
(
k
,
v
,
strict
=
True
)
args
[
k
]
=
v
for
k
,
v
in
extra_args
.
items
():
# Add operator-provided arguments, this allows operators
args
[
k
]
=
v
# to override defaults
for
arg
in
to_add
:
hookenv
.
log
(
'Adding option: {} {}'
.
format
(
arg
[
0
],
arg
[
1
]))
# Make sure old value is gone
flag_manager
.
destroy
(
arg
[
0
])
flag_manager
.
add
(
arg
[
0
],
arg
[
1
],
strict
=
True
)
cmd
=
[
'snap'
,
'set'
,
service
]
+
flag_manager
.
to_s
()
.
split
(
' '
)
cmd
=
[
'snap'
,
'set'
,
service
]
+
[
'
%
s=
%
s'
%
item
for
item
in
args
.
items
()]
check_call
(
cmd
)
check_call
(
cmd
)
db
.
set
(
prev_args_key
,
args
)
def
configure_apiserver
():
def
configure_apiserver
(
etcd
):
api_opts
=
{}
api_opts
=
{}
# Get the tls paths from the layer data.
# Get the tls paths from the layer data.
...
@@ -1078,6 +1018,20 @@ def configure_apiserver():
...
@@ -1078,6 +1018,20 @@ def configure_apiserver():
api_opts
[
'insecure-port'
]
=
'8080'
api_opts
[
'insecure-port'
]
=
'8080'
api_opts
[
'storage-backend'
]
=
'etcd2'
# FIXME: add etcd3 support
api_opts
[
'storage-backend'
]
=
'etcd2'
# FIXME: add etcd3 support
api_opts
[
'basic-auth-file'
]
=
'/root/cdk/basic_auth.csv'
api_opts
[
'token-auth-file'
]
=
'/root/cdk/known_tokens.csv'
api_opts
[
'service-account-key-file'
]
=
'/root/cdk/serviceaccount.key'
etcd_dir
=
'/root/cdk/etcd'
etcd_ca
=
os
.
path
.
join
(
etcd_dir
,
'client-ca.pem'
)
etcd_key
=
os
.
path
.
join
(
etcd_dir
,
'client-key.pem'
)
etcd_cert
=
os
.
path
.
join
(
etcd_dir
,
'client-cert.pem'
)
api_opts
[
'etcd-cafile'
]
=
etcd_ca
api_opts
[
'etcd-keyfile'
]
=
etcd_key
api_opts
[
'etcd-certfile'
]
=
etcd_cert
api_opts
[
'etcd-servers'
]
=
etcd
.
get_connection_string
()
admission_control
=
[
admission_control
=
[
'Initializers'
,
'Initializers'
,
'NamespaceLifecycle'
,
'NamespaceLifecycle'
,
...
@@ -1120,6 +1074,9 @@ def configure_controller_manager():
...
@@ -1120,6 +1074,9 @@ def configure_controller_manager():
controller_opts
[
'logtostderr'
]
=
'true'
controller_opts
[
'logtostderr'
]
=
'true'
controller_opts
[
'master'
]
=
'http://127.0.0.1:8080'
controller_opts
[
'master'
]
=
'http://127.0.0.1:8080'
controller_opts
[
'service-account-private-key-file'
]
=
\
'/root/cdk/serviceaccount.key'
configure_kubernetes_service
(
'kube-controller-manager'
,
controller_opts
,
configure_kubernetes_service
(
'kube-controller-manager'
,
controller_opts
,
'controller-manager-extra-args'
)
'controller-manager-extra-args'
)
...
...
cluster/juju/layers/kubernetes-worker/config.yaml
View file @
9036d07c
...
@@ -31,3 +31,21 @@ options:
...
@@ -31,3 +31,21 @@ options:
description
:
|
description
:
|
When true, worker services will not be upgraded until the user triggers
When true, worker services will not be upgraded until the user triggers
it manually by running the upgrade action.
it manually by running the upgrade action.
kubelet-extra-args
:
type
:
string
default
:
"
"
description
:
|
Space separated list of flags and key=value pairs that will be passed as arguments to
kubelet. For example a value like this:
runtime-config=batch/v2alpha1=true profiling=true
will result in kube-apiserver being run with the following options:
--runtime-config=batch/v2alpha1=true --profiling=true
proxy-extra-args
:
type
:
string
default
:
"
"
description
:
|
Space separated list of flags and key=value pairs that will be passed as arguments to
kube-proxy. For example a value like this:
runtime-config=batch/v2alpha1=true profiling=true
will result in kube-apiserver being run with the following options:
--runtime-config=batch/v2alpha1=true --profiling=true
cluster/juju/layers/kubernetes-worker/lib/charms/kubernetes/flagmanager.py
deleted
100644 → 0
View file @
45bdf707
#!/usr/bin/env python
# Copyright 2015 The Kubernetes Authors.
#
# 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.
from
charmhelpers.core
import
unitdata
class
FlagManager
:
'''
FlagManager - A Python class for managing the flags to pass to an
application without remembering what's been set previously.
This is a blind class assuming the operator knows what they are doing.
Each instance of this class should be initialized with the intended
application to manage flags. Flags are then appended to a data-structure
and cached in unitdata for later recall.
THe underlying data-provider is backed by a SQLITE database on each unit,
tracking the dictionary, provided from the 'charmhelpers' python package.
Summary:
opts = FlagManager('docker')
opts.add('bip', '192.168.22.2')
opts.to_s()
'''
def
__init__
(
self
,
daemon
,
opts_path
=
None
):
self
.
db
=
unitdata
.
kv
()
self
.
daemon
=
daemon
if
not
self
.
db
.
get
(
daemon
):
self
.
data
=
{}
else
:
self
.
data
=
self
.
db
.
get
(
daemon
)
def
__save
(
self
):
self
.
db
.
set
(
self
.
daemon
,
self
.
data
)
def
add
(
self
,
key
,
value
,
strict
=
False
):
'''
Adds data to the map of values for the DockerOpts file.
Supports single values, or "multiopt variables". If you
have a flag only option, like --tlsverify, set the value
to None. To preserve the exact value, pass strict
eg:
opts.add('label', 'foo')
opts.add('label', 'foo, bar, baz')
opts.add('flagonly', None)
opts.add('cluster-store', 'consul://a:4001,b:4001,c:4001/swarm',
strict=True)
'''
if
strict
:
self
.
data
[
'{}-strict'
.
format
(
key
)]
=
value
self
.
__save
()
return
if
value
:
values
=
[
x
.
strip
()
for
x
in
value
.
split
(
','
)]
# handle updates
if
key
in
self
.
data
and
self
.
data
[
key
]
is
not
None
:
item_data
=
self
.
data
[
key
]
for
c
in
values
:
c
=
c
.
strip
()
if
c
not
in
item_data
:
item_data
.
append
(
c
)
self
.
data
[
key
]
=
item_data
else
:
# handle new
self
.
data
[
key
]
=
values
else
:
# handle flagonly
self
.
data
[
key
]
=
None
self
.
__save
()
def
remove
(
self
,
key
,
value
):
'''
Remove a flag value from the DockerOpts manager
Assuming the data is currently {'foo': ['bar', 'baz']}
d.remove('foo', 'bar')
> {'foo': ['baz']}
:params key:
:params value:
'''
self
.
data
[
key
]
.
remove
(
value
)
self
.
__save
()
def
destroy
(
self
,
key
,
strict
=
False
):
'''
Destructively remove all values and key from the FlagManager
Assuming the data is currently {'foo': ['bar', 'baz']}
d.wipe('foo')
>{}
:params key:
:params strict:
'''
try
:
if
strict
:
self
.
data
.
pop
(
'{}-strict'
.
format
(
key
))
else
:
self
.
data
.
pop
(
key
)
self
.
__save
()
except
KeyError
:
pass
def
get
(
self
,
key
,
default
=
None
):
"""Return the value for ``key``, or the default if ``key`` doesn't exist.
"""
return
self
.
data
.
get
(
key
,
default
)
def
destroy_all
(
self
):
'''
Destructively removes all data from the FlagManager.
'''
self
.
data
.
clear
()
self
.
__save
()
def
to_s
(
self
):
'''
Render the flags to a single string, prepared for the Docker
Defaults file. Typically in /etc/default/docker
d.to_s()
> "--foo=bar --foo=baz"
'''
flags
=
[]
for
key
in
self
.
data
:
if
self
.
data
[
key
]
is
None
:
# handle flagonly
flags
.
append
(
"{}"
.
format
(
key
))
elif
'-strict'
in
key
:
# handle strict values, and do it in 2 steps.
# If we rstrip -strict it strips a tailing s
proper_key
=
key
.
rstrip
(
'strict'
)
.
rstrip
(
'-'
)
flags
.
append
(
"{}={}"
.
format
(
proper_key
,
self
.
data
[
key
]))
else
:
# handle multiopt and typical flags
for
item
in
self
.
data
[
key
]:
flags
.
append
(
"{}={}"
.
format
(
key
,
item
))
return
' '
.
join
(
flags
)
cluster/juju/layers/kubernetes-worker/reactive/kubernetes_worker.py
View file @
9036d07c
...
@@ -32,7 +32,6 @@ from charms.reactive import set_state, remove_state, is_state
...
@@ -32,7 +32,6 @@ from charms.reactive import set_state, remove_state, is_state
from
charms.reactive
import
when
,
when_any
,
when_not
from
charms.reactive
import
when
,
when_any
,
when_not
from
charms.kubernetes.common
import
get_version
from
charms.kubernetes.common
import
get_version
from
charms.kubernetes.flagmanager
import
FlagManager
from
charms.reactive.helpers
import
data_changed
,
any_file_changed
from
charms.reactive.helpers
import
data_changed
,
any_file_changed
from
charms.templating.jinja2
import
render
from
charms.templating.jinja2
import
render
...
@@ -66,9 +65,6 @@ def upgrade_charm():
...
@@ -66,9 +65,6 @@ def upgrade_charm():
# Remove gpu.enabled state so we can reconfigure gpu-related kubelet flags,
# Remove gpu.enabled state so we can reconfigure gpu-related kubelet flags,
# since they can differ between k8s versions
# since they can differ between k8s versions
remove_state
(
'kubernetes-worker.gpu.enabled'
)
remove_state
(
'kubernetes-worker.gpu.enabled'
)
kubelet_opts
=
FlagManager
(
'kubelet'
)
kubelet_opts
.
destroy
(
'feature-gates'
)
kubelet_opts
.
destroy
(
'experimental-nvidia-gpus'
)
remove_state
(
'kubernetes-worker.cni-plugins.installed'
)
remove_state
(
'kubernetes-worker.cni-plugins.installed'
)
remove_state
(
'kubernetes-worker.config.created'
)
remove_state
(
'kubernetes-worker.config.created'
)
...
@@ -124,10 +120,6 @@ def cleanup_pre_snap_services():
...
@@ -124,10 +120,6 @@ def cleanup_pre_snap_services():
hookenv
.
log
(
"Removing file: "
+
file
)
hookenv
.
log
(
"Removing file: "
+
file
)
os
.
remove
(
file
)
os
.
remove
(
file
)
# cleanup old flagmanagers
FlagManager
(
'kubelet'
)
.
destroy_all
()
FlagManager
(
'kube-proxy'
)
.
destroy_all
()
@when
(
'config.changed.channel'
)
@when
(
'config.changed.channel'
)
def
channel_changed
():
def
channel_changed
():
...
@@ -344,7 +336,8 @@ def start_worker(kube_api, kube_control, auth_control, cni):
...
@@ -344,7 +336,8 @@ def start_worker(kube_api, kube_control, auth_control, cni):
set_privileged
()
set_privileged
()
create_config
(
random
.
choice
(
servers
),
creds
)
create_config
(
random
.
choice
(
servers
),
creds
)
configure_worker_services
(
servers
,
dns
,
cluster_cidr
)
configure_kubelet
(
dns
)
configure_kube_proxy
(
servers
,
cluster_cidr
)
set_state
(
'kubernetes-worker.config.created'
)
set_state
(
'kubernetes-worker.config.created'
)
restart_unit_services
()
restart_unit_services
()
update_kubelet_status
()
update_kubelet_status
()
...
@@ -436,6 +429,12 @@ def apply_node_labels():
...
@@ -436,6 +429,12 @@ def apply_node_labels():
_apply_node_label
(
label
,
overwrite
=
True
)
_apply_node_label
(
label
,
overwrite
=
True
)
@when_any
(
'config.changed.kubelet-extra-args'
,
'config.changed.proxy-extra-args'
)
def
extra_args_changed
():
set_state
(
'kubernetes-worker.restart-needed'
)
def
arch
():
def
arch
():
'''Return the package architecture as a string. Raise an exception if the
'''Return the package architecture as a string. Raise an exception if the
architecture is not supported by kubernetes.'''
architecture is not supported by kubernetes.'''
...
@@ -469,44 +468,92 @@ def create_config(server, creds):
...
@@ -469,44 +468,92 @@ def create_config(server, creds):
token
=
creds
[
'proxy_token'
],
user
=
'kube-proxy'
)
token
=
creds
[
'proxy_token'
],
user
=
'kube-proxy'
)
def
configure_worker_services
(
api_servers
,
dns
,
cluster_cidr
):
def
parse_extra_args
(
config_key
):
''' Add remaining flags for the worker services and configure snaps to use
elements
=
hookenv
.
config
()
.
get
(
config_key
,
''
)
.
split
()
them '''
args
=
{}
for
element
in
elements
:
if
'='
in
element
:
key
,
_
,
value
=
element
.
partition
(
'='
)
args
[
key
]
=
value
else
:
args
[
element
]
=
'true'
return
args
def
configure_kubernetes_service
(
service
,
base_args
,
extra_args_key
):
db
=
unitdata
.
kv
()
prev_args_key
=
'kubernetes-worker.prev_args.'
+
service
prev_args
=
db
.
get
(
prev_args_key
)
or
{}
extra_args
=
parse_extra_args
(
extra_args_key
)
args
=
{}
for
arg
in
prev_args
:
# remove previous args by setting to null
args
[
arg
]
=
'null'
for
k
,
v
in
base_args
.
items
():
args
[
k
]
=
v
for
k
,
v
in
extra_args
.
items
():
args
[
k
]
=
v
cmd
=
[
'snap'
,
'set'
,
service
]
+
[
'
%
s=
%
s'
%
item
for
item
in
args
.
items
()]
check_call
(
cmd
)
db
.
set
(
prev_args_key
,
args
)
def
configure_kubelet
(
dns
):
layer_options
=
layer
.
options
(
'tls-client'
)
layer_options
=
layer
.
options
(
'tls-client'
)
ca_cert_path
=
layer_options
.
get
(
'ca_certificate_path'
)
ca_cert_path
=
layer_options
.
get
(
'ca_certificate_path'
)
server_cert_path
=
layer_options
.
get
(
'server_certificate_path'
)
server_cert_path
=
layer_options
.
get
(
'server_certificate_path'
)
server_key_path
=
layer_options
.
get
(
'server_key_path'
)
server_key_path
=
layer_options
.
get
(
'server_key_path'
)
kubelet_opts
=
FlagManager
(
'kubelet'
)
kubelet_opts
=
{}
kubelet_opts
.
add
(
'require-kubeconfig'
,
'true'
)
kubelet_opts
[
'require-kubeconfig'
]
=
'true'
kubelet_opts
.
add
(
'kubeconfig'
,
kubeconfig_path
)
kubelet_opts
[
'kubeconfig'
]
=
kubeconfig_path
kubelet_opts
.
add
(
'network-plugin'
,
'cni'
)
kubelet_opts
[
'network-plugin'
]
=
'cni'
kubelet_opts
.
add
(
'v'
,
'0'
)
kubelet_opts
[
'v'
]
=
'0'
kubelet_opts
.
add
(
'address'
,
'0.0.0.0'
)
kubelet_opts
[
'address'
]
=
'0.0.0.0'
kubelet_opts
.
add
(
'port'
,
'10250'
)
kubelet_opts
[
'port'
]
=
'10250'
kubelet_opts
.
add
(
'cluster-dns'
,
dns
[
'sdn-ip'
])
kubelet_opts
[
'cluster-dns'
]
=
dns
[
'sdn-ip'
]
kubelet_opts
.
add
(
'cluster-domain'
,
dns
[
'domain'
])
kubelet_opts
[
'cluster-domain'
]
=
dns
[
'domain'
]
kubelet_opts
.
add
(
'anonymous-auth'
,
'false'
)
kubelet_opts
[
'anonymous-auth'
]
=
'false'
kubelet_opts
.
add
(
'client-ca-file'
,
ca_cert_path
)
kubelet_opts
[
'client-ca-file'
]
=
ca_cert_path
kubelet_opts
.
add
(
'tls-cert-file'
,
server_cert_path
)
kubelet_opts
[
'tls-cert-file'
]
=
server_cert_path
kubelet_opts
.
add
(
'tls-private-key-file'
,
server_key_path
)
kubelet_opts
[
'tls-private-key-file'
]
=
server_key_path
kubelet_opts
.
add
(
'logtostderr'
,
'true'
)
kubelet_opts
[
'logtostderr'
]
=
'true'
kubelet_opts
.
add
(
'fail-swap-on'
,
'false'
)
kubelet_opts
[
'fail-swap-on'
]
=
'false'
kube_proxy_opts
=
FlagManager
(
'kube-proxy'
)
privileged
=
is_state
(
'kubernetes-worker.privileged'
)
kube_proxy_opts
.
add
(
'cluster-cidr'
,
cluster_cidr
)
kubelet_opts
[
'allow-privileged'
]
=
'true'
if
privileged
else
'false'
kube_proxy_opts
.
add
(
'kubeconfig'
,
kubeproxyconfig_path
)
kube_proxy_opts
.
add
(
'logtostderr'
,
'true'
)
if
is_state
(
'kubernetes-worker.gpu.enabled'
):
kube_proxy_opts
.
add
(
'v'
,
'0'
)
if
get_version
(
'kubelet'
)
<
(
1
,
6
):
kube_proxy_opts
.
add
(
'master'
,
random
.
choice
(
api_servers
),
strict
=
True
)
hookenv
.
log
(
'Adding --experimental-nvidia-gpus=1 to kubelet'
)
kubelet_opts
[
'experimental-nvidia-gpus'
]
=
'1'
else
:
hookenv
.
log
(
'Adding --feature-gates=Accelerators=true to kubelet'
)
kubelet_opts
[
'feature-gates'
]
=
'Accelerators=true'
configure_kubernetes_service
(
'kubelet'
,
kubelet_opts
,
'kubelet-extra-args'
)
def
configure_kube_proxy
(
api_servers
,
cluster_cidr
):
kube_proxy_opts
=
{}
kube_proxy_opts
[
'cluster-cidr'
]
=
cluster_cidr
kube_proxy_opts
[
'kubeconfig'
]
=
kubeproxyconfig_path
kube_proxy_opts
[
'logtostderr'
]
=
'true'
kube_proxy_opts
[
'v'
]
=
'0'
kube_proxy_opts
[
'master'
]
=
random
.
choice
(
api_servers
)
if
b
'lxc'
in
check_output
(
'virt-what'
,
shell
=
True
):
if
b
'lxc'
in
check_output
(
'virt-what'
,
shell
=
True
):
kube_proxy_opts
.
add
(
'conntrack-max-per-core'
,
'0'
)
kube_proxy_opts
[
'conntrack-max-per-core'
]
=
'0'
cmd
=
[
'snap'
,
'set'
,
'kubelet'
]
+
kubelet_opts
.
to_s
()
.
split
(
' '
)
configure_kubernetes_service
(
'kube-proxy'
,
kube_proxy_opts
,
check_call
(
cmd
)
'proxy-extra-args'
)
cmd
=
[
'snap'
,
'set'
,
'kube-proxy'
]
+
kube_proxy_opts
.
to_s
()
.
split
(
' '
)
check_call
(
cmd
)
def
create_kubeconfig
(
kubeconfig
,
server
,
ca
,
key
=
None
,
certificate
=
None
,
def
create_kubeconfig
(
kubeconfig
,
server
,
ca
,
key
=
None
,
certificate
=
None
,
...
@@ -700,12 +747,6 @@ def set_privileged():
...
@@ -700,12 +747,6 @@ def set_privileged():
gpu_enabled
=
is_state
(
'kubernetes-worker.gpu.enabled'
)
gpu_enabled
=
is_state
(
'kubernetes-worker.gpu.enabled'
)
privileged
=
'true'
if
gpu_enabled
else
'false'
privileged
=
'true'
if
gpu_enabled
else
'false'
flag
=
'allow-privileged'
hookenv
.
log
(
'Setting {}={}'
.
format
(
flag
,
privileged
))
kubelet_opts
=
FlagManager
(
'kubelet'
)
kubelet_opts
.
add
(
flag
,
privileged
)
if
privileged
==
'true'
:
if
privileged
==
'true'
:
set_state
(
'kubernetes-worker.privileged'
)
set_state
(
'kubernetes-worker.privileged'
)
else
:
else
:
...
@@ -748,14 +789,6 @@ def enable_gpu():
...
@@ -748,14 +789,6 @@ def enable_gpu():
hookenv
.
log
(
cpe
)
hookenv
.
log
(
cpe
)
return
return
kubelet_opts
=
FlagManager
(
'kubelet'
)
if
get_version
(
'kubelet'
)
<
(
1
,
6
):
hookenv
.
log
(
'Adding --experimental-nvidia-gpus=1 to kubelet'
)
kubelet_opts
.
add
(
'experimental-nvidia-gpus'
,
'1'
)
else
:
hookenv
.
log
(
'Adding --feature-gates=Accelerators=true to kubelet'
)
kubelet_opts
.
add
(
'feature-gates'
,
'Accelerators=true'
)
# Apply node labels
# Apply node labels
_apply_node_label
(
'gpu=true'
,
overwrite
=
True
)
_apply_node_label
(
'gpu=true'
,
overwrite
=
True
)
_apply_node_label
(
'cuda=true'
,
overwrite
=
True
)
_apply_node_label
(
'cuda=true'
,
overwrite
=
True
)
...
@@ -777,12 +810,6 @@ def disable_gpu():
...
@@ -777,12 +810,6 @@ def disable_gpu():
"""
"""
hookenv
.
log
(
'Disabling gpu mode'
)
hookenv
.
log
(
'Disabling gpu mode'
)
kubelet_opts
=
FlagManager
(
'kubelet'
)
if
get_version
(
'kubelet'
)
<
(
1
,
6
):
kubelet_opts
.
destroy
(
'experimental-nvidia-gpus'
)
else
:
kubelet_opts
.
remove
(
'feature-gates'
,
'Accelerators=true'
)
# Remove node labels
# Remove node labels
_apply_node_label
(
'gpu'
,
delete
=
True
)
_apply_node_label
(
'gpu'
,
delete
=
True
)
_apply_node_label
(
'cuda'
,
delete
=
True
)
_apply_node_label
(
'cuda'
,
delete
=
True
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment