mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-20 17:49:10 +00:00
commit
508f12350a
@ -1,6 +1,10 @@
|
|||||||
# A dockerfile to build an etcd container image from the upstream one
|
# A dockerfile to build an etcd container image from the upstream one
|
||||||
# with a script as entry point
|
# with a script as entry point
|
||||||
FROM quay.io/coreos/etcd:v3.1.5
|
FROM quay.io/coreos/etcd:v3.1.5
|
||||||
|
|
||||||
|
# sfdisk and jq re required to mount the disk
|
||||||
|
RUN apk add --no-cache sfdisk jq
|
||||||
|
|
||||||
COPY ./etcd.sh /
|
COPY ./etcd.sh /
|
||||||
|
|
||||||
ENTRYPOINT ["/etcd.sh"]
|
ENTRYPOINT ["/etcd.sh"]
|
||||||
|
@ -4,6 +4,9 @@ An `etcd` cluster can be bootstrapped in different ways (see the [Documentation]
|
|||||||
|
|
||||||
The moby `etcd` package is build with [build-pkg.sh](./build-pkg.sh). It takes the official `etcd` container and adds a [script](./etcd.sh) to start `etcd`. [etcd.sh](./etcd.sh) first attempts to join a new cluster. If that fails it attempts to join an existing cluster. Note, the number and members of the cluster are somewhat hard coded in the script.
|
The moby `etcd` package is build with [build-pkg.sh](./build-pkg.sh). It takes the official `etcd` container and adds a [script](./etcd.sh) to start `etcd`. [etcd.sh](./etcd.sh) first attempts to join a new cluster. If that fails it attempts to join an existing cluster. Note, the number and members of the cluster are somewhat hard coded in the script.
|
||||||
|
|
||||||
|
Each node is also configured with a disk, which is mounted inside the
|
||||||
|
`etcd` container. `etcd` uses it to keep some state to help with
|
||||||
|
restarts.
|
||||||
|
|
||||||
## Preparation
|
## Preparation
|
||||||
|
|
||||||
@ -38,6 +41,9 @@ the nodes and then:
|
|||||||
docker run --rm -t quay.io/coreos/etcd:v3.1.5 etcdctl --endpoints http://192.168.65.200:2379 member list
|
docker run --rm -t quay.io/coreos/etcd:v3.1.5 etcdctl --endpoints http://192.168.65.200:2379 member list
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can perform rolling updates, by for example, switching the kernel version in `etcd.yml`, build a new moby, e.g., `moby build -name etcd-4.10 etcd`, update `infrakit.json`, and then commit the new configuration to InfraKit: `infrakit group commit infrakit.json`.
|
||||||
|
|
||||||
|
|
||||||
## Infrakit GCP setup
|
## Infrakit GCP setup
|
||||||
|
|
||||||
Note: This setup is somewhat specific to our GCP setup (IP addresses
|
Note: This setup is somewhat specific to our GCP setup (IP addresses
|
||||||
|
@ -4,6 +4,39 @@
|
|||||||
set -x
|
set -x
|
||||||
set -v
|
set -v
|
||||||
|
|
||||||
|
MOUNTPOINT=/var/etcd
|
||||||
|
|
||||||
|
mount_drive()
|
||||||
|
{
|
||||||
|
mkdir -p "$MOUNTPOINT"
|
||||||
|
|
||||||
|
# TODO fix for multiple disks, cdroms etc
|
||||||
|
DEVS="$(find /dev -maxdepth 1 -type b ! -name 'loop*' ! -name 'nbd*' | grep -v '[0-9]$' | sed 's@.*/dev/@@' | sort)"
|
||||||
|
|
||||||
|
for DEV in $DEVS
|
||||||
|
do
|
||||||
|
DRIVE="/dev/${DEV}"
|
||||||
|
|
||||||
|
# see if it has a partition table
|
||||||
|
if sfdisk -d "${DRIVE}" >/dev/null 2>/dev/null
|
||||||
|
then
|
||||||
|
# 83 is Linux partition identifier
|
||||||
|
DATA=$(sfdisk -J "$DRIVE" | jq -e -r '.partitiontable.partitions | map(select(.type=="83")) | .[0].node')
|
||||||
|
if [ $? -eq 0 ]
|
||||||
|
then
|
||||||
|
mount "$DATA" "$MOUNTPOINT" && return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "WARNING: Failed to mount a persistent volume (is there one?)"
|
||||||
|
|
||||||
|
# not sure if we want to fatally bail here, in some debug situations it is ok
|
||||||
|
# exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
mount_drive
|
||||||
|
|
||||||
# Wait till we have an IP address
|
# Wait till we have an IP address
|
||||||
IP=""
|
IP=""
|
||||||
while [ -z "$IP" ]; do
|
while [ -z "$IP" ]; do
|
||||||
@ -17,13 +50,20 @@ PREFIX=$(echo ${IP} | cut -d . -f 1,2,3)
|
|||||||
NAME=infra${NUM}
|
NAME=infra${NUM}
|
||||||
|
|
||||||
# This should come from Metadata
|
# This should come from Metadata
|
||||||
INIT_CLUSTER=infra200=http://${PREFIX}.200:2380,infra201=http://${PREFIX}.201:2380,infra202=http://${PREFIX}.202:2380,infra203=http://${PREFIX}.203:2380,infra204=http://${PREFIX}.204:2380
|
INIT_CLUSTER="infra200=http://${PREFIX}.200:2380,infra201=http://${PREFIX}.201:2380,infra202=http://${PREFIX}.202:2380,infra203=http://${PREFIX}.203:2380,infra204=http://${PREFIX}.204:2380"
|
||||||
|
|
||||||
# Try to start in *new* cluster mode
|
# We currently have no easy way to determine if we join a cluster for
|
||||||
|
# the first time or if we got restarted and need to join an existing
|
||||||
|
# cluster. So we first try joining a *new* cluster. This fails if we
|
||||||
|
# had already joined it previously. As a fallback we then try to join
|
||||||
|
# an existing cluster.
|
||||||
|
|
||||||
|
# Try to join an new cluster
|
||||||
/usr/local/bin/etcd \
|
/usr/local/bin/etcd \
|
||||||
--name ${NAME} \
|
--name ${NAME} \
|
||||||
--debug \
|
--debug \
|
||||||
--log-package-levels etcdmain=DEBUG,etcdserver=DEBUG \
|
--log-package-levels etcdmain=DEBUG,etcdserver=DEBUG \
|
||||||
|
--data-dir $MOUNTPOINT \
|
||||||
--initial-advertise-peer-urls http://${IP}:2380 \
|
--initial-advertise-peer-urls http://${IP}:2380 \
|
||||||
--listen-peer-urls http://${IP}:2380 \
|
--listen-peer-urls http://${IP}:2380 \
|
||||||
--listen-client-urls http://${IP}:2379,http://127.0.0.1:2379 \
|
--listen-client-urls http://${IP}:2379,http://127.0.0.1:2379 \
|
||||||
@ -34,11 +74,12 @@ INIT_CLUSTER=infra200=http://${PREFIX}.200:2380,infra201=http://${PREFIX}.201:23
|
|||||||
|
|
||||||
[ $? -eq 0 ] && exit 0
|
[ $? -eq 0 ] && exit 0
|
||||||
|
|
||||||
# Joining the new cluster failed. Let's try joining an *existing* cluster
|
# Try to join an existing cluster
|
||||||
/usr/local/bin/etcd \
|
/usr/local/bin/etcd \
|
||||||
--name ${NAME} \
|
--name ${NAME} \
|
||||||
--debug \
|
--debug \
|
||||||
--log-package-levels etcdmain=DEBUG,etcdserver=DEBUG \
|
--log-package-levels etcdmain=DEBUG,etcdserver=DEBUG \
|
||||||
|
--data-dir $MOUNTPOINT \
|
||||||
--initial-advertise-peer-urls http://${IP}:2380 \
|
--initial-advertise-peer-urls http://${IP}:2380 \
|
||||||
--listen-peer-urls http://${IP}:2380 \
|
--listen-peer-urls http://${IP}:2380 \
|
||||||
--listen-client-urls http://${IP}:2379,http://127.0.0.1:2379 \
|
--listen-client-urls http://${IP}:2379,http://127.0.0.1:2379 \
|
||||||
|
@ -2,7 +2,9 @@ kernel:
|
|||||||
image: "mobylinux/kernel:4.9.x"
|
image: "mobylinux/kernel:4.9.x"
|
||||||
cmdline: "console=ttyS0 console=tty0 page_poison=1"
|
cmdline: "console=ttyS0 console=tty0 page_poison=1"
|
||||||
init:
|
init:
|
||||||
- "mobylinux/init:a27e32a8d6c8865d691fbfb4d0bbb93846cf7802"
|
- mobylinux/init:925c88f42d92d57cd36b656db1f8757b152163a7
|
||||||
|
- mobylinux/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9
|
||||||
|
- mobylinux/containerd:68bb523deea09da293d675cbf88474eced540b8c
|
||||||
onboot:
|
onboot:
|
||||||
- name: sysctl
|
- name: sysctl
|
||||||
image: "mobylinux/sysctl:2cf2f9d5b4d314ba1bfc22b2fe931924af666d8c"
|
image: "mobylinux/sysctl:2cf2f9d5b4d314ba1bfc22b2fe931924af666d8c"
|
||||||
@ -12,6 +14,13 @@ onboot:
|
|||||||
capabilities:
|
capabilities:
|
||||||
- CAP_SYS_ADMIN
|
- CAP_SYS_ADMIN
|
||||||
readonly: true
|
readonly: true
|
||||||
|
- name: format
|
||||||
|
image: "mobylinux/format:53748000acf515549d398e6ae68545c26c0f3a2e"
|
||||||
|
binds:
|
||||||
|
- /dev:/dev
|
||||||
|
capabilities:
|
||||||
|
- CAP_SYS_ADMIN
|
||||||
|
- CAP_MKNOD
|
||||||
services:
|
services:
|
||||||
- name: rngd
|
- name: rngd
|
||||||
image: "mobylinux/rngd:3dad6dd43270fa632ac031e99d1947f20b22eec9@sha256:1c93c1db7196f6f71f8e300bc1d15f0376dd18e8891c8789d77c8ff19f3a9a92"
|
image: "mobylinux/rngd:3dad6dd43270fa632ac031e99d1947f20b22eec9@sha256:1c93c1db7196f6f71f8e300bc1d15f0376dd18e8891c8789d77c8ff19f3a9a92"
|
||||||
@ -33,12 +42,15 @@ services:
|
|||||||
- name: etcd
|
- name: etcd
|
||||||
image: "mobylinux/etcd"
|
image: "mobylinux/etcd"
|
||||||
capabilities:
|
capabilities:
|
||||||
- CAP_NET_BIND_SERVICE
|
|
||||||
- CAP_CHOWN
|
- CAP_CHOWN
|
||||||
- CAP_SETUID
|
- CAP_SETUID
|
||||||
- CAP_SETGID
|
- CAP_SETGID
|
||||||
- CAP_DAC_OVERRIDE
|
- CAP_DAC_OVERRIDE
|
||||||
|
- CAP_SYS_ADMIN
|
||||||
|
- CAP_MKNOD
|
||||||
net: host
|
net: host
|
||||||
|
binds:
|
||||||
|
- /dev:/dev
|
||||||
outputs:
|
outputs:
|
||||||
- format: kernel+initrd
|
- format: kernel+initrd
|
||||||
# - format: gcp
|
# - format: gcp
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
"Plugin": "instance-hyperkit",
|
"Plugin": "instance-hyperkit",
|
||||||
"Properties": {
|
"Properties": {
|
||||||
"Moby": "etcd",
|
"Moby": "etcd",
|
||||||
"Disk" : 0,
|
"Disk" : 1024,
|
||||||
"CPUs" : 1,
|
"CPUs" : 1,
|
||||||
"Memory" : 1024
|
"Memory" : 1024
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ INFRAKIT_HOME=~/.infrakit
|
|||||||
IK_PLUGINS=$INFRAKIT_HOME/plugins
|
IK_PLUGINS=$INFRAKIT_HOME/plugins
|
||||||
|
|
||||||
rm -rf $INFRAKIT_HOME
|
rm -rf $INFRAKIT_HOME
|
||||||
|
mkdir -p $INFRAKIT_HOME/cli
|
||||||
|
|
||||||
infrakit-flavor-vanilla &
|
infrakit-flavor-vanilla &
|
||||||
infrakit-instance-hyperkit &
|
infrakit-instance-hyperkit &
|
||||||
|
@ -2,7 +2,9 @@ kernel:
|
|||||||
image: "mobylinux/kernel:4.9.x"
|
image: "mobylinux/kernel:4.9.x"
|
||||||
cmdline: "console=ttyS0 console=tty0 page_poison=1"
|
cmdline: "console=ttyS0 console=tty0 page_poison=1"
|
||||||
init:
|
init:
|
||||||
- "mobylinux/init:a27e32a8d6c8865d691fbfb4d0bbb93846cf7802"
|
- mobylinux/init:925c88f42d92d57cd36b656db1f8757b152163a7
|
||||||
|
- mobylinux/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9
|
||||||
|
- mobylinux/containerd:68bb523deea09da293d675cbf88474eced540b8c
|
||||||
onboot:
|
onboot:
|
||||||
- name: sysctl
|
- name: sysctl
|
||||||
image: "mobylinux/sysctl:2cf2f9d5b4d314ba1bfc22b2fe931924af666d8c"
|
image: "mobylinux/sysctl:2cf2f9d5b4d314ba1bfc22b2fe931924af666d8c"
|
||||||
|
@ -21,6 +21,7 @@ func NewHyperKitPlugin(vmDir, hyperkit, vpnkitSock string) instance.Plugin {
|
|||||||
return &hyperkitPlugin{VMDir: vmDir,
|
return &hyperkitPlugin{VMDir: vmDir,
|
||||||
HyperKit: hyperkit,
|
HyperKit: hyperkit,
|
||||||
VPNKitSock: vpnkitSock,
|
VPNKitSock: vpnkitSock,
|
||||||
|
DiskDir: path.Join(vmDir, "disks"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +34,9 @@ type hyperkitPlugin struct {
|
|||||||
|
|
||||||
// VPNKitSock is the path to the VPNKit Unix domain socket.
|
// VPNKitSock is the path to the VPNKit Unix domain socket.
|
||||||
VPNKitSock string
|
VPNKitSock string
|
||||||
|
|
||||||
|
// DiskDir is the path to persistent (across reboots) disk images
|
||||||
|
DiskDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate performs local validation on a provision request.
|
// Validate performs local validation on a provision request.
|
||||||
@ -60,8 +64,9 @@ func (p hyperkitPlugin) Provision(spec instance.Spec) (*instance.ID, error) {
|
|||||||
if properties["Memory"] == nil {
|
if properties["Memory"] == nil {
|
||||||
properties["Memory"] = 512
|
properties["Memory"] = 512
|
||||||
}
|
}
|
||||||
if properties["Disk"] == nil {
|
diskSize := 0
|
||||||
properties["Disk"] = 256
|
if properties["Disk"] != nil {
|
||||||
|
diskSize = int(properties["Disk"].(float64))
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceDir, err := ioutil.TempDir(p.VMDir, "infrakit-")
|
instanceDir, err := ioutil.TempDir(p.VMDir, "infrakit-")
|
||||||
@ -71,12 +76,15 @@ func (p hyperkitPlugin) Provision(spec instance.Spec) (*instance.ID, error) {
|
|||||||
id := instance.ID(path.Base(instanceDir))
|
id := instance.ID(path.Base(instanceDir))
|
||||||
log.Infof("[%s] New instance", id)
|
log.Infof("[%s] New instance", id)
|
||||||
|
|
||||||
// The LogicalID may be a IP address. If so, translate it into a
|
|
||||||
// magic UUID which cause VPNKit to assign a fixed IP address
|
|
||||||
logicalID := string(id)
|
logicalID := string(id)
|
||||||
uuidStr := ""
|
uuidStr := ""
|
||||||
|
|
||||||
|
diskImage := ""
|
||||||
if spec.LogicalID != nil {
|
if spec.LogicalID != nil {
|
||||||
logicalID = string(*spec.LogicalID)
|
logicalID = string(*spec.LogicalID)
|
||||||
|
// The LogicalID may be a IP address. If so, translate
|
||||||
|
// it into a magic UUID which cause VPNKit to assign a
|
||||||
|
// fixed IP address
|
||||||
if ip := net.ParseIP(logicalID); len(ip) > 0 {
|
if ip := net.ParseIP(logicalID); len(ip) > 0 {
|
||||||
uuid := make([]byte, 16)
|
uuid := make([]byte, 16)
|
||||||
uuid[12] = ip.To4()[0]
|
uuid[12] = ip.To4()[0]
|
||||||
@ -85,12 +93,23 @@ func (p hyperkitPlugin) Provision(spec instance.Spec) (*instance.ID, error) {
|
|||||||
uuid[15] = ip.To4()[3]
|
uuid[15] = ip.To4()[3]
|
||||||
uuidStr = fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:])
|
uuidStr = fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:])
|
||||||
}
|
}
|
||||||
|
// If a LogicalID is supplied and the Disk size is
|
||||||
|
// non-zero, we place the disk in a special directory
|
||||||
|
// so it persists across reboots.
|
||||||
|
if diskSize != 0 {
|
||||||
|
diskImage = path.Join(p.DiskDir, logicalID+".img")
|
||||||
|
// Make sure the directory exists
|
||||||
|
err = os.MkdirAll(p.DiskDir, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
log.Infof("[%s] LogicalID: %s", id, logicalID)
|
log.Infof("[%s] LogicalID: %s", id, logicalID)
|
||||||
log.Debugf("[%s] UUID: %s", id, uuidStr)
|
log.Debugf("[%s] UUID: %s", id, uuidStr)
|
||||||
|
|
||||||
// Start a HyperKit instance
|
// Start a HyperKit instance
|
||||||
h, err := hyperkit.New(p.HyperKit, instanceDir, p.VPNKitSock, "")
|
h, err := hyperkit.New(p.HyperKit, instanceDir, p.VPNKitSock, diskImage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -98,12 +117,12 @@ func (p hyperkitPlugin) Provision(spec instance.Spec) (*instance.ID, error) {
|
|||||||
h.Initrd = properties["Moby"].(string) + "-initrd.img"
|
h.Initrd = properties["Moby"].(string) + "-initrd.img"
|
||||||
h.CPUs = int(properties["CPUs"].(float64))
|
h.CPUs = int(properties["CPUs"].(float64))
|
||||||
h.Memory = int(properties["Memory"].(float64))
|
h.Memory = int(properties["Memory"].(float64))
|
||||||
h.DiskSize = int(properties["Disk"].(float64))
|
h.DiskSize = diskSize
|
||||||
h.UUID = uuidStr
|
h.UUID = uuidStr
|
||||||
h.UserData = spec.Init
|
h.UserData = spec.Init
|
||||||
h.Console = hyperkit.ConsoleFile
|
h.Console = hyperkit.ConsoleFile
|
||||||
log.Infof("[%s] Booting: %s/%s", id, h.Kernel, h.Initrd)
|
log.Infof("[%s] Booting: %s/%s", id, h.Kernel, h.Initrd)
|
||||||
log.Infof("[%s] %d CPUs, %dMB Memory, %dMB Disk", id, h.CPUs, h.Memory, h.DiskSize)
|
log.Infof("[%s] %d CPUs, %dMB Memory, %dMB Disk (%s)", id, h.CPUs, h.Memory, h.DiskSize, h.DiskImage)
|
||||||
|
|
||||||
err = h.Start("console=ttyS0")
|
err = h.Start("console=ttyS0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user