зеркало из https://github.com/Azure/draft-classic.git
Merge pull request #72 from bacongobbler/off-cluster-registry
implement off-cluster registry story
This commit is contained in:
Коммит
1f71489e32
2
Makefile
2
Makefile
|
@ -87,7 +87,7 @@ compress-binary:
|
|||
.PHONY: serve
|
||||
serve: check-helm
|
||||
helm install chart/ --name ${APP} --namespace ${APP} \
|
||||
--set image.name=${IMAGE_PREFIX}/${SHORT_NAME},image.registry=${DOCKER_REGISTRY},image.tag=${IMAGE_TAG}
|
||||
--set image.name=${SHORT_NAME},image.org=${IMAGE_PREFIX},image.registry=${DOCKER_REGISTRY},image.tag=${IMAGE_TAG}
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
|
|
@ -34,7 +34,8 @@ import (
|
|||
|
||||
const ChartTemplate = `image:
|
||||
name: %s
|
||||
registry: "%s:%s"
|
||||
org: %s
|
||||
registry: %s
|
||||
tag: %s
|
||||
`
|
||||
|
||||
|
@ -47,6 +48,15 @@ type APIServer struct {
|
|||
HTTPServer *http.Server
|
||||
Listener net.Listener
|
||||
DockerClient *docker.Client
|
||||
// RegistryAuth is the authorization token used to push images up to the registry.
|
||||
//
|
||||
// This field follows the format of the X-Registry-Auth header.
|
||||
RegistryAuth string
|
||||
// RegistryOrg is the organization (e.g. your DockerHub account) used to push images
|
||||
// up to the registry.
|
||||
RegistryOrg string
|
||||
// RegistryURL is the URL of the registry (e.g. quay.io, docker.io, gcr.io)
|
||||
RegistryURL string
|
||||
}
|
||||
|
||||
// Serve starts the HTTP server, accepting all new connections.
|
||||
|
@ -179,11 +189,11 @@ func getVersion(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|||
}
|
||||
|
||||
func buildApp(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
var imagePrefix string
|
||||
appName := p.ByName("id")
|
||||
server := r.Context().Value("server").(*APIServer)
|
||||
namespace := r.Header.Get("Kubernetes-Namespace")
|
||||
logLevel := r.Header.Get("Log-Level")
|
||||
registryServicePort := os.Getenv("REGISTRY_SERVICE_PORT")
|
||||
|
||||
// NOTE(bacongobbler): If no header was set, we default back to the default namespace.
|
||||
if namespace == "" {
|
||||
|
@ -194,10 +204,6 @@ func buildApp(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|||
logLevel = log.GetLevel().String()
|
||||
}
|
||||
|
||||
if registryServicePort == "" {
|
||||
registryServicePort = "5000"
|
||||
}
|
||||
|
||||
if r.Method != "POST" {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
|
@ -245,8 +251,12 @@ func buildApp(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|||
// truncate checksum to the first 40 characters (20 bytes)
|
||||
// this is the equivalent of `shasum build.tar.gz | awk '{print $1}'`
|
||||
tag := fmt.Sprintf("%.20x", buildContextChecksum.Sum(nil))
|
||||
imageName := fmt.Sprintf("127.0.0.1:%s/%s:%s",
|
||||
registryServicePort,
|
||||
if server.RegistryOrg != "" {
|
||||
imagePrefix = server.RegistryOrg + "/"
|
||||
}
|
||||
imageName := fmt.Sprintf("%s/%s%s:%s",
|
||||
server.RegistryURL,
|
||||
imagePrefix,
|
||||
appName,
|
||||
tag,
|
||||
)
|
||||
|
@ -307,9 +317,7 @@ func buildApp(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|||
pushResp, err := server.DockerClient.ImagePush(
|
||||
context.Background(),
|
||||
imageName,
|
||||
// assume no creds required for now
|
||||
// TODO(bacongobbler): implement custom auth handling for a registry
|
||||
types.ImagePushOptions{RegistryAuth: "hi"})
|
||||
types.ImagePushOptions{RegistryAuth: server.RegistryAuth})
|
||||
if err != nil {
|
||||
conn.WriteMessage(
|
||||
websocket.CloseMessage,
|
||||
|
@ -367,8 +375,8 @@ func buildApp(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|||
// and the version
|
||||
vals := fmt.Sprintf(ChartTemplate,
|
||||
appName,
|
||||
os.Getenv("PROWD_SERVICE_HOST"),
|
||||
os.Getenv("PROWD_SERVICE_PORT_REGISTRY"),
|
||||
server.RegistryOrg,
|
||||
server.RegistryURL,
|
||||
tag,
|
||||
)
|
||||
// If a release does not exist, install it. If another error occurs during
|
||||
|
|
|
@ -14,10 +14,13 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: prowd
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.org }}/{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
args:
|
||||
- start
|
||||
- --registry-url={{ .Values.registry.url }}
|
||||
- --registry-org={{ .Values.registry.org }}
|
||||
- --registry-auth={{ .Values.registry.authtoken }}
|
||||
{{- if .Values.debug }}
|
||||
- --debug
|
||||
{{- end }}
|
||||
|
@ -34,16 +37,6 @@ spec:
|
|||
volumeMounts:
|
||||
- mountPath: /var/run/docker.sock
|
||||
name: docker-socket
|
||||
env:
|
||||
- name: "REGISTRY_SERVICE_PORT"
|
||||
value: "{{ .Values.service.registry.externalPort }}"
|
||||
- name: registry
|
||||
image: registry:2
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: {{ .Values.service.registry.internalPort }}
|
||||
hostPort: {{ .Values.service.registry.externalPort }}
|
||||
name: registry
|
||||
volumes:
|
||||
- name: docker-socket
|
||||
hostPath:
|
||||
|
|
|
@ -7,8 +7,5 @@ spec:
|
|||
- name: http
|
||||
port: {{ .Values.service.http.externalPort }}
|
||||
targetPort: {{ .Values.service.http.internalPort }}
|
||||
- name: registry
|
||||
port: {{ .Values.service.registry.externalPort }}
|
||||
targetPort: {{ .Values.service.registry.internalPort }}
|
||||
selector:
|
||||
app: {{ .Chart.Name }}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
replicaCount: 1
|
||||
image:
|
||||
registry: quay.io
|
||||
name: deis/prowd
|
||||
org: deis
|
||||
name: prowd
|
||||
tag: canary
|
||||
pullPolicy: Always
|
||||
debug: false
|
||||
|
@ -12,6 +13,18 @@ service:
|
|||
http:
|
||||
externalPort: 80
|
||||
internalPort: 44135
|
||||
registry:
|
||||
externalPort: 5000
|
||||
internalPort: 5000
|
||||
registry:
|
||||
url: quay.io
|
||||
org: deis
|
||||
# This field follows the format of Docker's X-Registry-Auth header.
|
||||
#
|
||||
# See https://github.com/docker/docker/blob/master/docs/api/v1.22.md#push-an-image-on-the-registry
|
||||
#
|
||||
# For credential-based logins, use
|
||||
#
|
||||
# $ echo '{"username":"jdoe","password":"secret","email":"jdoe@acme.com"}' | base64 -w 0
|
||||
#
|
||||
# For token-based logins, use
|
||||
#
|
||||
# $ echo '{"registrytoken":"9cbaf023786cd7"}' | base64 -w 0
|
||||
authtoken: changeme
|
||||
|
|
|
@ -28,6 +28,12 @@ type startCmd struct {
|
|||
dockerVersion string
|
||||
// retrieve docker engine information from environment
|
||||
dockerFromEnv bool
|
||||
// registryAuth is the authorization token used to push images up to the registry.
|
||||
registryAuth string
|
||||
// registryOrg is the organization (e.g. your DockerHub account) used to push images up to the registry.
|
||||
registryOrg string
|
||||
// registryURL is the URL of the registry (e.g. quay.io, docker.io, gcr.io)
|
||||
registryURL string
|
||||
}
|
||||
|
||||
func newStartCmd(out io.Writer) *cobra.Command {
|
||||
|
@ -49,6 +55,9 @@ func newStartCmd(out io.Writer) *cobra.Command {
|
|||
f.StringVarP(&sc.dockerAddr, "docker-addr", "", "unix:///var/run/docker.sock", "the address the docker engine listens on")
|
||||
f.StringVarP(&sc.dockerVersion, "docker-version", "", "", "the API version of the docker engine")
|
||||
f.BoolVarP(&sc.dockerFromEnv, "docker-from-env", "", false, "retrieve docker engine information from environment")
|
||||
f.StringVar(&sc.registryAuth, "registry-auth", "", "the authorization token used to push images up to the registry")
|
||||
f.StringVar(&sc.registryOrg, "registry-org", "", "the organization (e.g. your DockerHub account) used to push images up to the registry")
|
||||
f.StringVar(&sc.registryURL, "registry-url", "127.0.0.1:5000", "the URL of the registry (e.g. quay.io, docker.io, gcr.io)")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -75,6 +84,9 @@ func (c *startCmd) run() error {
|
|||
return fmt.Errorf("failed to create server at %s: %v", c.listenAddr, err)
|
||||
}
|
||||
server.DockerClient = dockerClient
|
||||
server.RegistryAuth = c.registryAuth
|
||||
server.RegistryOrg = c.registryOrg
|
||||
server.RegistryURL = c.registryURL
|
||||
log.Printf("server is now listening at %s", c.listenAddr)
|
||||
if err = server.Serve(); err != nil {
|
||||
return err
|
||||
|
|
|
@ -65,7 +65,7 @@ When you run `prow up`, Prow deploys your code to your Kubernetes cluster for yo
|
|||
following:
|
||||
|
||||
- Packages your code using a `docker build`.
|
||||
- Sends your code to the in-cluster Docker Registry.
|
||||
- Sends your code to a Docker Registry.
|
||||
- Installs (or upgrades) your chart using Helm
|
||||
|
||||
And when you're done with development, Prow's "first class" objects are all supported by the
|
||||
|
@ -101,7 +101,7 @@ This is a look behind the curtain. Here's how Prow works:
|
|||
- Prow uses several existing components:
|
||||
- A Kubernetes cluster
|
||||
- The Helm Tiller server
|
||||
- An in-cluster Docker Registry
|
||||
- A Docker Registry
|
||||
- A directory full of "packs" for specific templates
|
||||
- `prow create` reads a scaffold out of the appropriate pack, creates the necessary file system
|
||||
objects, and writes some basic configuration into your chart.
|
||||
|
@ -142,6 +142,7 @@ Inside of the `values.yaml` file, Prow configures images for your chart:
|
|||
```
|
||||
image:
|
||||
registry: gcr.io
|
||||
org: bacongobbler
|
||||
name: myapp
|
||||
tag: 0.1.0
|
||||
```
|
||||
|
@ -168,15 +169,16 @@ want to use:
|
|||
|
||||
```
|
||||
image:
|
||||
registry: 10.0.0.131:5000 # the address of the in-cluster registry
|
||||
name: myapp # the name of the image
|
||||
registry: quay.io # the address of the registry
|
||||
org: bacongobbler # the organization of the image
|
||||
name: myapp # the name of the image
|
||||
tag: 08db751 # the release of the image in the registry
|
||||
```
|
||||
|
||||
_How do I add an existing chart to Prow?_
|
||||
|
||||
Just copy (`helm fetch`) it into the `chart/` directory. You need to tweak the values file to
|
||||
read from `image.regsitry`, `image.name` and `image.tag` if you want Prow to regenerate Docker
|
||||
read from `image.registry`, `image.org`, `image.name` and `image.tag` if you want Prow to regenerate Docker
|
||||
images for you. See above.
|
||||
|
||||
_How do I deploy applications to production?_
|
||||
|
|
|
@ -8,6 +8,7 @@ development environment for working on the Prow source code.
|
|||
To compile and test Prow binaries and to build Docker images, you will need:
|
||||
|
||||
- [docker][]
|
||||
- a [Docker Hub][] or [quay.io][quay] account
|
||||
- [git][]
|
||||
- [Go][] 1.7 or later, with support for compiling to `linux/amd64`
|
||||
- [glide][]
|
||||
|
@ -115,13 +116,20 @@ Client: &version.Version{SemVer:"v2.2.0", GitCommit:"fc315ab59850ddd1b9b4959c89e
|
|||
Server: &version.Version{SemVer:"v2.2.0", GitCommit:"fc315ab59850ddd1b9b4959c89ef008fef5cdf89", GitTreeState:"clean"}
|
||||
```
|
||||
|
||||
Then, install the Prow chart:
|
||||
To install Prowd, edit `chart/values.yaml` and change the fields under `registry` to your
|
||||
[Docker Hub][] or [quay.io][quay] account:
|
||||
|
||||
```
|
||||
$ $EDITOR charts/values.yaml
|
||||
```
|
||||
|
||||
Then, install the chart:
|
||||
|
||||
```shell
|
||||
$ make serve
|
||||
$ helm list # check that prowd has a helm release
|
||||
NAME REVISION UPDATED STATUS CHART NAMESPACE
|
||||
prowd 1 Thu Feb 16 10:18:21 2017 DEPLOYED prowd-0.1.0 prow
|
||||
prow 1 Thu Feb 16 10:18:21 2017 DEPLOYED prowd-0.1.0 prow
|
||||
```
|
||||
|
||||
## Re-deploying Your Changes
|
||||
|
|
|
@ -53,6 +53,7 @@ const defaultValues = `# Default values for %s.
|
|||
replicaCount: 1
|
||||
image:
|
||||
registry: docker.io
|
||||
org: library
|
||||
name: nginx
|
||||
tag: stable
|
||||
pullPolicy: IfNotPresent
|
||||
|
@ -109,7 +110,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.org }}/{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.service.internalPort }}
|
||||
|
|
|
@ -13,7 +13,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
||||
image: "{{ .Values.image.registry }}/{{ .Values.image.org }}/{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.service.internalPort }}
|
||||
|
|
|
@ -15,7 +15,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: {{ .Values.image.registry }}/{{ .Values.image.name }}:{{ .Values.image.tag }}
|
||||
image: {{ .Values.image.registry }}/{{ .Values.image.org }}/{{ .Values.image.name }}:{{ .Values.image.tag }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
|
Загрузка…
Ссылка в новой задаче