mirror of https://github.com/kubernetes/kops.git
CentOS7 initial experimental support
This commit is contained in:
parent
a6fd824994
commit
d86390c172
8
Makefile
8
Makefile
|
@ -96,8 +96,9 @@ gcs-publish-ci: gcs-upload
|
|||
echo "${GCS_URL}/${VERSION}" > .build/upload/${LATEST_FILE}
|
||||
gsutil cp .build/upload/${LATEST_FILE} ${GCS_LOCATION}
|
||||
|
||||
push: nodeup-dist
|
||||
scp -C .build/dist/nodeup ${TARGET}:/tmp/
|
||||
# Assumes running on linux for speed (todo: crossbuild on OSX?)
|
||||
push: nodeup-gocode
|
||||
scp -C ${GOPATH_1ST}/bin/nodeup ${TARGET}:/tmp/
|
||||
|
||||
push-gce-dry: push
|
||||
ssh ${TARGET} sudo SKIP_PACKAGE_UPDATE=1 /tmp/nodeup --conf=metadata://gce/config --dryrun --v=8
|
||||
|
@ -108,8 +109,9 @@ push-aws-dry: push
|
|||
push-gce-run: push
|
||||
ssh ${TARGET} sudo SKIP_PACKAGE_UPDATE=1 /tmp/nodeup --conf=metadata://gce/config --v=8
|
||||
|
||||
# -t is for CentOS http://unix.stackexchange.com/questions/122616/why-do-i-need-a-tty-to-run-sudo-if-i-can-sudo-without-a-password
|
||||
push-aws-run: push
|
||||
ssh ${TARGET} sudo SKIP_PACKAGE_UPDATE=1 /tmp/nodeup --conf=/var/cache/kubernetes-install/kube_env.yaml --v=8
|
||||
ssh -t ${TARGET} sudo SKIP_PACKAGE_UPDATE=1 /tmp/nodeup --conf=/var/cache/kubernetes-install/kube_env.yaml --v=8
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -29,3 +29,14 @@ which should be easier than editing your instance groups.
|
|||
In addition, we support a few-well known aliases for the owner:
|
||||
|
||||
`kope.io` => `383156758163`
|
||||
|
||||
|
||||
|
||||
## Centos
|
||||
|
||||
CentOS7 support is still experimental.
|
||||
|
||||
The following steps are known:
|
||||
|
||||
* Accept the agreement at http://aws.amazon.com/marketplace/pp?sku=aw0evgkw8e5c1q413zgy5pjce
|
||||
* Specify the AMI by id (there are no tags): us-east-1: ami-6d1c2007
|
||||
|
|
|
@ -49,6 +49,9 @@
|
|||
"readOnly": true},
|
||||
{ "name": "etcpkitls",
|
||||
"mountPath": "/etc/pki/tls",
|
||||
"readOnly": true},
|
||||
{ "name": "etcpkicatrust",
|
||||
"mountPath": "/etc/pki/ca-trust",
|
||||
"readOnly": true}
|
||||
]
|
||||
}
|
||||
|
@ -79,6 +82,10 @@
|
|||
{ "name": "etcpkitls",
|
||||
"hostPath": {
|
||||
"path": "/etc/pki/tls"}
|
||||
},
|
||||
{ "name": "etcpkicatrust",
|
||||
"hostPath": {
|
||||
"path": "/etc/pki/ca-trust"}
|
||||
}
|
||||
]
|
||||
}}
|
|
@ -0,0 +1,22 @@
|
|||
[Unit]
|
||||
Description=Docker Application Container Engine
|
||||
Documentation=https://docs.docker.com
|
||||
After=network.target docker.socket
|
||||
Requires=docker.socket
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
EnvironmentFile=/etc/sysconfig/docker
|
||||
ExecStart=/usr/bin/docker daemon -H fd:// "$DOCKER_OPTS"
|
||||
MountFlags=slave
|
||||
LimitNOFILE=1048576
|
||||
LimitNPROC=1048576
|
||||
LimitCORE=infinity
|
||||
Restart=always
|
||||
RestartSec=2s
|
||||
StartLimitInterval=0
|
||||
# set delegate yes so that systemd does not reset the cgroups of docker containers
|
||||
Delegate=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,2 @@
|
|||
DOCKER_OPTS="{{ BuildFlags .Docker }}"
|
||||
DOCKER_NOFILE=1000000
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"version": "1.11.2",
|
||||
"source": "https://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-1.11.2-1.el7.centos.x86_64.rpm",
|
||||
"hash": "432e6d7948df9e05f4190fce2f423eedbfd673d5"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"version": "1.11.2",
|
||||
"source": "https://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-selinux-1.11.2-1.el7.centos.noarch.rpm",
|
||||
"hash": "f6da608fa8eeb2be8071489086ed9ff035f6daba"
|
||||
}
|
|
@ -14,6 +14,7 @@ import (
|
|||
type CloudInitTarget struct {
|
||||
Config *CloudConfig
|
||||
out io.Writer
|
||||
Tags map[string]struct{}
|
||||
}
|
||||
|
||||
type AddBehaviour int
|
||||
|
@ -23,10 +24,11 @@ const (
|
|||
Once
|
||||
)
|
||||
|
||||
func NewCloudInitTarget(out io.Writer) *CloudInitTarget {
|
||||
func NewCloudInitTarget(out io.Writer, tags map[string]struct{}) *CloudInitTarget {
|
||||
t := &CloudInitTarget{
|
||||
Config: &CloudConfig{},
|
||||
out: out,
|
||||
Tags: tags,
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
@ -49,6 +51,11 @@ type CloudConfigFile struct {
|
|||
Content string `json:"content,omitempty"`
|
||||
}
|
||||
|
||||
func (t *CloudInitTarget) HasTag(tag string) bool {
|
||||
_, found := t.Tags[tag]
|
||||
return found
|
||||
}
|
||||
|
||||
func (t *CloudInitTarget) AddMkdirpCommand(p string, dirMode os.FileMode) {
|
||||
t.AddCommand(Once, "mkdir", "-p", "-m", fi.FileModeToString(dirMode), p)
|
||||
|
||||
|
|
|
@ -198,12 +198,13 @@ func (c *NodeUpCommand) Run(out io.Writer) error {
|
|||
case "direct":
|
||||
target = &local.LocalTarget{
|
||||
CacheDir: c.CacheDir,
|
||||
Tags: tags,
|
||||
}
|
||||
case "dryrun":
|
||||
target = fi.NewDryRunTarget(out)
|
||||
case "cloudinit":
|
||||
checkExisting = false
|
||||
target = cloudinit.NewCloudInitTarget(out)
|
||||
target = cloudinit.NewCloudInitTarget(out, tags)
|
||||
default:
|
||||
return fmt.Errorf("unsupported target type %q", c.Target)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import "k8s.io/kops/upup/pkg/fi"
|
|||
|
||||
type LocalTarget struct {
|
||||
CacheDir string
|
||||
Tags map[string]struct{}
|
||||
}
|
||||
|
||||
var _ fi.Target = &LocalTarget{}
|
||||
|
@ -11,3 +12,8 @@ var _ fi.Target = &LocalTarget{}
|
|||
func (t *LocalTarget) Finish(taskMap map[string]fi.Task) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *LocalTarget) HasTag(tag string) bool {
|
||||
_, found := t.Tags[tag]
|
||||
return found
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/nodeup/cloudinit"
|
||||
"k8s.io/kops/upup/pkg/fi/nodeup/local"
|
||||
"k8s.io/kops/upup/pkg/fi/nodeup/tags"
|
||||
"k8s.io/kops/util/pkg/hashing"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
@ -87,6 +88,20 @@ func NewPackage(name string, contents string, meta string) (fi.Task, error) {
|
|||
}
|
||||
|
||||
func (e *Package) Find(c *fi.Context) (*Package, error) {
|
||||
target := c.Target.(*local.LocalTarget)
|
||||
|
||||
if target.HasTag(tags.TagOSFamilyDebian) {
|
||||
return e.findDpkg(c)
|
||||
}
|
||||
|
||||
if target.HasTag(tags.TagOSFamilyCentos) {
|
||||
return e.findYum(c)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported package system")
|
||||
}
|
||||
|
||||
func (e *Package) findDpkg(c *fi.Context) (*Package, error) {
|
||||
args := []string{"dpkg-query", "-f", "${db:Status-Abbrev}${Version}\\n", "-W", e.Name}
|
||||
human := strings.Join(args, " ")
|
||||
|
||||
|
@ -146,6 +161,54 @@ func (e *Package) Find(c *fi.Context) (*Package, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (e *Package) findYum(c *fi.Context) (*Package, error) {
|
||||
args := []string{"/usr/bin/rpm", "-q", e.Name, "--queryformat", "%{NAME} %{VERSION}"}
|
||||
human := strings.Join(args, " ")
|
||||
|
||||
glog.V(2).Infof("Listing installed packages: %s", human)
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
if strings.Contains(string(output), "is not installed") {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("error listing installed packages: %v: %s", err, string(output))
|
||||
}
|
||||
|
||||
installed := false
|
||||
var healthy *bool
|
||||
installedVersion := ""
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
tokens := strings.Split(line, " ")
|
||||
if len(tokens) != 2 {
|
||||
return nil, fmt.Errorf("error parsing rpm line %q", line)
|
||||
}
|
||||
|
||||
name := tokens[0]
|
||||
if name != e.Name {
|
||||
return nil, fmt.Errorf("error parsing rpm line %q", line)
|
||||
}
|
||||
installed = true
|
||||
installedVersion = tokens[1]
|
||||
// If we implement unhealthy; be sure to implement repair in Render
|
||||
healthy = fi.Bool(true)
|
||||
}
|
||||
|
||||
if !installed {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &Package{
|
||||
Name: e.Name,
|
||||
Version: fi.String(installedVersion),
|
||||
Healthy: healthy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (e *Package) Run(c *fi.Context) error {
|
||||
return fi.DefaultDeltaRunMethod(e, c)
|
||||
}
|
||||
|
@ -186,7 +249,14 @@ func (_ *Package) RenderLocal(t *local.LocalTarget, a, e, changes *Package) erro
|
|||
return err
|
||||
}
|
||||
|
||||
args := []string{"dpkg", "-i", local}
|
||||
var args []string
|
||||
if t.HasTag(tags.TagOSFamilyDebian) {
|
||||
args = []string{"dpkg", "-i", local}
|
||||
} else if t.HasTag(tags.TagOSFamilyCentos) {
|
||||
args = []string{"/usr/bin/rpm", "-i", local}
|
||||
} else {
|
||||
return fmt.Errorf("unsupported package system")
|
||||
}
|
||||
glog.Infof("running command %s", args)
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
@ -194,7 +264,16 @@ func (_ *Package) RenderLocal(t *local.LocalTarget, a, e, changes *Package) erro
|
|||
return fmt.Errorf("error installing package %q: %v: %s", e.Name, err, string(output))
|
||||
}
|
||||
} else {
|
||||
args := []string{"apt-get", "install", "--yes", e.Name}
|
||||
var args []string
|
||||
if t.HasTag(tags.TagOSFamilyDebian) {
|
||||
args = []string{"apt-get", "install", "--yes", e.Name}
|
||||
|
||||
} else if t.HasTag(tags.TagOSFamilyCentos) {
|
||||
args = []string{"/usr/bin/yum", "install", "-y", e.Name}
|
||||
} else {
|
||||
return fmt.Errorf("unsupported package system")
|
||||
}
|
||||
|
||||
glog.Infof("running command %s", args)
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
@ -204,15 +283,22 @@ func (_ *Package) RenderLocal(t *local.LocalTarget, a, e, changes *Package) erro
|
|||
}
|
||||
} else {
|
||||
if changes.Healthy != nil {
|
||||
args := []string{"dpkg", "--configure", "-a"}
|
||||
glog.Infof("package is not healthy; runnning command %s", args)
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error running `dpkg --configure -a`: %v: %s", err, string(output))
|
||||
}
|
||||
if t.HasTag(tags.TagOSFamilyDebian) {
|
||||
args := []string{"dpkg", "--configure", "-a"}
|
||||
glog.Infof("package is not healthy; runnning command %s", args)
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error running `dpkg --configure -a`: %v: %s", err, string(output))
|
||||
}
|
||||
|
||||
changes.Healthy = nil
|
||||
changes.Healthy = nil
|
||||
} else if t.HasTag(tags.TagOSFamilyCentos) {
|
||||
// We can't reach here anyway...
|
||||
return fmt.Errorf("package repair not supported on centos")
|
||||
} else {
|
||||
return fmt.Errorf("unsupported package system")
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(changes, &Package{}) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/nodeup/cloudinit"
|
||||
"k8s.io/kops/upup/pkg/fi/nodeup/local"
|
||||
"k8s.io/kops/upup/pkg/fi/nodeup/tags"
|
||||
"k8s.io/kops/upup/pkg/fi/utils"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
@ -18,7 +19,8 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
systemdSystemPath = "/lib/systemd/system" // TODO: Different on redhat
|
||||
debianSystemdSystemPath = "/lib/systemd/system"
|
||||
centosSystemdSystemPath = "/usr/lib/systemd/system"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
|
@ -109,7 +111,22 @@ func getSystemdStatus(name string) (map[string]string, error) {
|
|||
return properties, nil
|
||||
}
|
||||
|
||||
func (e *Service) systemdSystemPath(target tags.HasTags) (string, error) {
|
||||
if target.HasTag(tags.TagOSFamilyDebian) {
|
||||
return debianSystemdSystemPath, nil
|
||||
} else if target.HasTag(tags.TagOSFamilyCentos) {
|
||||
return centosSystemdSystemPath, nil
|
||||
} else {
|
||||
return "", fmt.Errorf("unsupported systemd system")
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Service) Find(c *fi.Context) (*Service, error) {
|
||||
systemdSystemPath, err := e.systemdSystemPath(c.Target.(tags.HasTags))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
servicePath := path.Join(systemdSystemPath, e.Name)
|
||||
|
||||
d, err := ioutil.ReadFile(servicePath)
|
||||
|
@ -203,6 +220,11 @@ func (s *Service) CheckChanges(a, e, changes *Service) error {
|
|||
}
|
||||
|
||||
func (_ *Service) RenderLocal(t *local.LocalTarget, a, e, changes *Service) error {
|
||||
systemdSystemPath, err := e.systemdSystemPath(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serviceName := e.Name
|
||||
|
||||
action := ""
|
||||
|
@ -311,10 +333,15 @@ func (_ *Service) RenderLocal(t *local.LocalTarget, a, e, changes *Service) erro
|
|||
}
|
||||
|
||||
func (_ *Service) RenderCloudInit(t *cloudinit.CloudInitTarget, a, e, changes *Service) error {
|
||||
systemdSystemPath, err := e.systemdSystemPath(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serviceName := e.Name
|
||||
|
||||
servicePath := path.Join(systemdSystemPath, serviceName)
|
||||
err := t.WriteFile(servicePath, fi.NewStringResource(*e.Definition), 0644, 0755)
|
||||
err = t.WriteFile(servicePath, fi.NewStringResource(*e.Definition), 0644, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/golang/glog"
|
||||
"io/ioutil"
|
||||
"k8s.io/kops/upup/pkg/fi/nodeup/tags"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
@ -18,7 +19,7 @@ func FindOSTags(rootfs string) ([]string, error) {
|
|||
for _, line := range strings.Split(string(lsbRelease), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "DISTRIB_CODENAME=xenial" {
|
||||
return []string{"_xenial", "_debian_family", "_systemd"}, nil
|
||||
return []string{"_xenial", tags.TagOSFamilyDebian, tags.TagSystemd}, nil
|
||||
}
|
||||
}
|
||||
glog.Warningf("unhandled lsb-release info %q", string(lsbRelease))
|
||||
|
@ -31,7 +32,7 @@ func FindOSTags(rootfs string) ([]string, error) {
|
|||
if err == nil {
|
||||
debianVersion := strings.TrimSpace(string(debianVersionBytes))
|
||||
if strings.HasPrefix(debianVersion, "8.") {
|
||||
return []string{"_jessie", "_debian_family", "_systemd"}, nil
|
||||
return []string{"_jessie", tags.TagOSFamilyDebian, tags.TagSystemd}, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("unhandled debian version %q", debianVersion)
|
||||
}
|
||||
|
@ -39,6 +40,20 @@ func FindOSTags(rootfs string) ([]string, error) {
|
|||
glog.Warningf("error reading /etc/debian_version: %v", err)
|
||||
}
|
||||
|
||||
// Centos has /etc/centos-release
|
||||
centosRelease, err := ioutil.ReadFile(path.Join(rootfs, "etc/centos-release"))
|
||||
if err == nil {
|
||||
for _, line := range strings.Split(string(centosRelease), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "CentOS Linux release 7.") {
|
||||
return []string{"_centos7", tags.TagOSFamilyCentos, tags.TagSystemd}, nil
|
||||
}
|
||||
}
|
||||
glog.Warningf("unhandled centos-release info %q", string(lsbRelease))
|
||||
} else if !os.IsNotExist(err) {
|
||||
glog.Warningf("error reading /etc/centos-release: %v", err)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("cannot identify distro")
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package tags
|
||||
|
||||
const (
|
||||
TagOSFamilyCentos = "_centos_family"
|
||||
TagOSFamilyDebian = "_debian_family"
|
||||
|
||||
TagSystemd = "_systemd"
|
||||
)
|
||||
|
||||
type HasTags interface {
|
||||
HasTag(tag string) bool
|
||||
}
|
Loading…
Reference in New Issue