Skip to content

Commit

Permalink
Correct several problems with fluxy-in-k8s and document
Browse files Browse the repository at this point in the history
The image did not include ssh, which git wants to be present.

If you mount a secret to get the private key, it will have the wrong
permissions and ssh will ignore it. So, copy the key into the working
directory, and make sure it has the right permissions.

Elaborated instructions on making keys for trying it out with a
config.
  • Loading branch information
squaremo committed Aug 18, 2016
1 parent 3e7eadc commit a0561f7
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 25 deletions.
69 changes: 55 additions & 14 deletions deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,75 @@ make clean build
which will build the image in minikube's Docker daemon,
thus making it available to Kubernetes.

The file `fluxy-deployment.yaml` contains a Kubernetes deployment configuration
that runs the latest image of Fluxy.
## Creating a key for automation

The automation component mutates a Git repository containing your
Kubernetes config, which requires an SSH access key. That private key
is stored as a Kubernetes secret named `fluxy-repo-key`.

Here is an example of setting this up for the `helloworld` example in
the fluxy repository.

Fork the fluxy repository on github (you may also wish to rename it,
e.g., to `fluxy-testconf`). Now, we're going to add a deploy key so
fluxy can push to that repo. Generate a key in the console:

```
kubectl create -f fluxy-deployment.yaml
ssh-keygen -t rsa -b 4096 -f id-rsa-fluxy
```

To make the pod accessible to `fluxctl`, you can port forward:
This makes a private key file (`id-rsa-fluxy`) which we'll supply to
Fluxy in a minute, and a public key file (`id-rsa-fluxy.pub`) which
we'll now give to Github.

On the Github page for your forked repo, go to the settings and find
the "Deploy keys" page. Add one, and paste in the contents of the
`id-rsa-fluxy.pub` file -- the public key.

Kubernetes wants the private key in the form of a secret. To create that,

```
kubectl port-forward $(kubectl get pods | grep fluxy | awk '{print $1}') 3030:3030
kubectl delete secret fluxy-repo-key
kubectl create secret generic fluxy-repo-key --from-file=id-rsa=id-rsa-fluxy
```

This will work with the default settings of `fluxctl`,
and is especially handy with minikube.
## Customising the deployment config

The file `fluxy-deployment.yaml` contains a Kubernetes deployment
configuration that runs the latest image of Fluxy.

To force Kubernetes to run the latest image, kill the pod:
You will need to change at least the repository arguments, to use your
Github repo. Adapt these lines:

```
kubectl get pods | grep fluxy | awk '{ print $1 }' | xargs kubectl delete pod
- --repo-url=git@github.com:squaremo/fluxy-testdata
- --repo-key=/var/run/secrets/fluxy/key/id-rsa
- --repo-path=testdata
```

## Automation and secrets
The last, `--repo-path`, refers to the directory _within_ the
repository containing the configuration files (the seeting above is
correct if you have forked the fluxy repo as above).

The automation component mutates a Git repository, which requires an SSH access key.
That private key is stored as a Kubernetes secret named `fluxy-repo-key`.
You can create the deployment now:

```
kubectl delete secret fluxy-repo-key
kubectl create secret generic fluxy-repo-key --from-file=id-rsa=/path/to/id_rsa
kubectl create -f fluxy-deployment.yaml
```

To make the pod accessible to `fluxctl`, you can create a service for Fluxy and use the Kubernetes API proxy to access it:

```
kubectl create -f fluxy-service.yaml
kubectl proxy &
export FLUX_URL=http://localhost:8001/api/v1/proxy/namespaces/default/services/fluxy
```

This will work with the default settings of `fluxctl`,
and is especially handy with minikube.

To force Kubernetes to run the latest image after a rebuild, kill the pod:

```
kubectl get pods | grep fluxy | awk '{ print $1 }' | xargs kubectl delete pod
```
4 changes: 2 additions & 2 deletions deploy/fluxy-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ spec:
- --kubernetes-bearer-token-file=/var/run/secrets/kubernetes.io/serviceaccount/token
- --database-driver=ql
- --database-source=file://history.db
- --repo-url=git@github.com:peterbourgon/dumbconf
- --repo-url=git@github.com:squaremo/fluxy-testdata
- --repo-key=/var/run/secrets/fluxy/key/id-rsa
- --repo-path="/"
- --repo-path=testdata
9 changes: 9 additions & 0 deletions deploy/fluxy-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Service
metadata:
name: fluxy
spec:
ports:
- port: 3030
selector:
name: fluxy
2 changes: 1 addition & 1 deletion docker/Dockerfile.fluxy
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM alpine:3.3
WORKDIR /home/flux
RUN apk add --no-cache git
RUN apk add --no-cache git openssh
ADD ./kubectl /home/flux/
COPY ./ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY ./fluxd /home/flux/
40 changes: 32 additions & 8 deletions git/releasing.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,27 @@ func (r Repo) Release(
) error {
// Check out latest version of config repo.
logf("fetching config repo")
configPath, err := clone(r.Key, r.URL)

working, err := ioutil.TempDir(os.TempDir(), "fluxy-gitclone")
if err != nil {
return err
}
defer func(d string) {
os.RemoveAll(d)
}(working)

// If the private key is from a mounted k8s secret, it will have
// the wrong permissions; copy it to the working dir and give it
// the right permissions
keyPath, err := copyKey(working, r.Key)
if err != nil {
return err
}

configPath, err := clone(working, keyPath, r.URL)
if err != nil {
return fmt.Errorf("clone of config repo failed: %v", err)
}
defer os.RemoveAll(configPath)

// Find the relevant resource definition file.
file, err := findFileFor(configPath, r.Path, candidate.Repository())
Expand Down Expand Up @@ -65,7 +81,7 @@ func (r Repo) Release(
logf("release complete")

// Push the new commit.
if err := push(r.Key, configPath); err != nil {
if err := push(keyPath, configPath); err != nil {
return fmt.Errorf("push failed: %v", err)
}
logf("committed and pushed the resource definition file %s", file)
Expand Down Expand Up @@ -93,18 +109,17 @@ func env(repoKey string) []string {
return []string{fmt.Sprintf("%s -i %q", base, repoKey)}
}

func clone(repoKey, repoURL string) (path string, err error) {
dst, err := ioutil.TempDir(os.TempDir(), "fluxy-gitclone")
func clone(working, repoKey, repoURL string) (path string, err error) {
if err != nil {
return "", err
}
repoPath := filepath.Join(working, "repo")

if err := cmd("", repoKey, "clone", repoURL, dst).Run(); err != nil {
os.RemoveAll(dst)
if err := cmd("", repoKey, "clone", repoURL, repoPath).Run(); err != nil {
return "", fmt.Errorf("git clone: %v", err)
}

return dst, nil
return repoPath, nil
}

func findFileFor(basePath, repoPath, imageStr string) (res string, err error) {
Expand Down Expand Up @@ -179,3 +194,12 @@ func push(repoKey, workingDir string) error {
}
return nil
}

func copyKey(working, key string) (string, error) {
keyPath := filepath.Join(working, "id-rsa")
f, err := ioutil.ReadFile(key)
if err == nil {
err = ioutil.WriteFile(keyPath, f, 0400)
}
return keyPath, err
}

0 comments on commit a0561f7

Please sign in to comment.