Skip to content
This repository has been archived by the owner on Aug 10, 2021. It is now read-only.

Commit

Permalink
Changes to the imagelayer ui application for use as a frontend in kub…
Browse files Browse the repository at this point in the history
…ernetes

Presents the UI code as static resources as before
Links are changed for paths
   /registry -> proxied to an cluster service named imagelayers
   /badge    -> proxied to a cluster service named badger

manifests/imagelayers-all.yaml is a complete kubernetes specification
for all three replication controllers and services
  • Loading branch information
ntfrnzn committed Mar 30, 2016
1 parent b96951e commit 8544de6
Show file tree
Hide file tree
Showing 8 changed files with 365 additions and 73 deletions.
5 changes: 3 additions & 2 deletions Dockerfile
@@ -1,7 +1,8 @@
FROM centurylink/nginx:1.6.2
FROM nginx:1.8.1

MAINTAINER CenturyLink Labs <ctl-labs-futuretech@centurylink.com>
MAINTAINER Nathan Franzen <nathan.franzen@ctl.io>
EXPOSE 9000
EXPOSE 8080

ADD nginx.conf /etc/nginx/nginx.conf
ADD /dist /data/dist
26 changes: 25 additions & 1 deletion README.md
Expand Up @@ -13,8 +13,32 @@ ImageLayers uses Grunt. To install Grunt, you must first have [npm installed on
The last step is to install Compass. ImageLayers recommends using the latest version of Ruby.
`gem install compass`

Next, make sure the [imagelayers API](https://github.com/CenturyLinkLabs/imagelayers/) is running.
Next, make sure the [imagelayers API](https://github.com/CenturyLinkLabs/imagelayers/) is running.
Run `grunt` for building the UI and `grunt serve` for preview. The ImageLayers UI will automatically open in a browser window.

### Deploying in Kubernetes

The [ImageLayers API](https://github.com/CenturyLinkLabs/imagelayers/) is
deployed in a Kubernetes cluster as a separate replication controller with
associated service. The api service is not available from oputside the cluster,
and is reached by proxying all requests through the same nginx server that hosts
this application.

To build the version of imagelayers ui that proxies these requests:
```
$ IMAGE_LAYERS_API="" grunt build --force
$ docker build -t [repositoryname]/imagelayers-ui:[version] .
```

A prototype of the kubernetes manifest is found in the manifest subdirectory and
can be deployed with kubectl. The api can be scaled independently of the frontend.
```
$ kubectl create -f manifest/imagelayers-all.yaml
$ kubectl scale rc imagelayers --replicas=3
```

The imagelayer-ui is defined as type Loadbalancer, and a new external endpoint
will be allocated upon deployment

## Testing
Running `grunt test` will run the unit tests with karma.
22 changes: 12 additions & 10 deletions app/scripts/controllers/badgedialog.js
Expand Up @@ -16,21 +16,24 @@
function BadgeDialogCtrl($scope, $sce) {
var nameChanged = function(current, previous) {
var newName = current.name,
oldName = previous.name;
oldName = previous.name;

return (newName !== undefined &&
newName !== oldName);
newName !== oldName);
};

var newImage = function() {
return { name: '', tag: 'latest' };
return {
name: '',
tag: 'latest'
};
};

$scope.selectedImage = newImage();

$scope.imageList = function() {
var data = $scope.graph,
list = [];
list = [];

angular.forEach(data, function(image) {
image.repo.label = image.repo.name + ':' + image.repo.tag;
Expand Down Expand Up @@ -66,23 +69,22 @@
$scope.asciiDocCopied = false;
}, true);

$scope.badgeAsHtml = function () {
$scope.badgeAsHtml = function() {
if ($scope.selectedImage.selected !== true) {
return "";
}

return $sce.trustAsHtml("<a href='https://imagelayers.io/?images=" + $scope.selectedImage.name + ":" + $scope.selectedImage.tag + "' title='Get your own badge on imagelayers.io'>" +
"<img src='https://badge.imagelayers.io/" + $scope.selectedImage.name + ":" + $scope.selectedImage.tag + ".svg'></a>");
"<img src='https://imagelayers.io/badge/" + $scope.selectedImage.name + ":" + $scope.selectedImage.tag + ".svg'></a>");
};

$scope.badgeAsMarkdown = function () {
$scope.badgeAsMarkdown = function() {
if ($scope.selectedImage.selected !== true) {
return "";
}

return "[![](https://badge.imagelayers.io/" + $scope.selectedImage.name + ":" + $scope.selectedImage.tag + ".svg)]" +
"(https://imagelayers.io/?images=" + $scope.selectedImage.name + ":" + $scope.selectedImage.tag + " 'Get your own badge on imagelayers.io')";
};
return "[![](https://imagelayers.io/badge/" + $scope.selectedImage.name + ":" + $scope.selectedImage.tag + ".svg)]" +
"(https://imagelayers.io/?images=" + $scope.selectedImage.name + ":" + $scope.selectedImage.tag + " 'Get your own badge on imagelayers.io')"; };

$scope.badgeAsAsciiDoc = function() {
if ($scope.selectedImage.selected !== true) {
Expand Down
2 changes: 1 addition & 1 deletion app/views/badgeDialog.html
Expand Up @@ -29,7 +29,7 @@
<section ng-if="selectedImage.selected">
<div class="preview">
<label>Badge Preview</label>
<img loading-src="https://badge.imagelayers.io/{{ selectedImage.name }}:{{ selectedImage.tag }}.svg">
<img loading-src="/badge/{{ selectedImage.name }}:{{ selectedImage.tag }}.svg">
</div>
<ul>
<li>
Expand Down
147 changes: 147 additions & 0 deletions manifest/imagelayers-all.yaml
@@ -0,0 +1,147 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: imagelayers
name: imagelayers
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8888
selector:
app: imagelayers
sessionAffinity: None
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
labels:
app: badger
name: badger
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 3000
selector:
app: badger
sessionAffinity: None
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
labels:
app: imagelayers-web
name: imagelayers-web
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 9000
nodePort: 30900
selector:
app: imagelayers-web
sessionAffinity: None
type: NodePort
---
apiVersion: v1
kind: ReplicationController
metadata:
labels:
app: imagelayers
name: imagelayers
namespace: default
spec:
replicas: 1
selector:
app: imagelayers
template:
metadata:
creationTimestamp: null
labels:
app: imagelayers
name: imagelayers
spec:
containers:
- image: centurylink/imagelayers-api
imagePullPolicy: IfNotPresent
name: imagelayers
resources: {}
securityContext:
privileged: false
terminationMessagePath: /dev/termination-log
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: ReplicationController
metadata:
labels:
app: imagelayers-web
version: kubernetes-v1.0
name: imagelayers-web
namespace: default
spec:
replicas: 1
selector:
app: imagelayers-web
version: kubernetes-v1.0
template:
metadata:
creationTimestamp: null
labels:
app: imagelayers-web
version: kubernetes-v1.0
name: imagelayers-web
spec:
containers:
- image: ntfrnzn/imagelayers-ui:kubernetes-v1.0
imagePullPolicy: IfNotPresent
name: imagelayers-web
resources: {}
securityContext:
privileged: false
terminationMessagePath: /dev/termination-log
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: ReplicationController
metadata:
labels:
app: badger
name: badger
namespace: default
spec:
replicas: 1
selector:
app: badger
template:
metadata:
creationTimestamp: null
labels:
app: badger
name: badger
spec:
containers:
- image: centurylink/badger
imagePullPolicy: IfNotPresent
name: badger
resources: {}
env:
- name: MODE
value: production
securityContext:
privileged: false
terminationMessagePath: /dev/termination-log
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
104 changes: 93 additions & 11 deletions nginx.conf
@@ -1,7 +1,7 @@
user nobody nogroup;
worker_processes 1;
daemon off;
error_log /dev/stderr info;

error_log /dev/stderr warn;

events {
worker_connections 1024;
Expand All @@ -10,11 +10,31 @@ events {
http {
include mime.types;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format main '{'
'"body_bytes_sent":"$body_bytes_sent",'
'"host":"$host",'
'"hostname":"$hostname",'
'"http_forwarded":"$http_forwarded",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"query_string":"$query_string",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request_method":"$request_method",'
'"request_time":"$request_time",'
'"request":"$request",'
'"scheme":"$scheme",'
'"server_port":"$server_port",'
'"status":"$status",'
'"time_iso8601":"$time_iso8601",'
'"upstream_addr":"$upstream_addr",'
'"upstream_response_time":"$upstream_response_time",'
'"upstream_status":"$upstream_status"'
'}';

access_log /dev/stdout main;
# error_log /dev/stdout debug;

sendfile on;
tcp_nopush on;
Expand All @@ -23,9 +43,50 @@ http {

gzip on;

upstream imagelayers-api {
server imagelayers;
}

upstream badger {
server badger;
}

## health and status check
server {
listen 8080;

location /nginx_status {
stub_status on;
access_log off;
}
}

# used only by clients directly addressing this service
server {
listen 9000;
server_name localhost;
server_name badge.imagelayers.io;

location / {
access_log /dev/stdout main;

proxy_redirect off;

proxy_set_header Host 'badge.imagelayers.io';
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection 'Keep-Alive';

proxy_pass http://badger/;
}

error_page 404 500 502 503 504 /error.html;
location = /error.html {
root html;
}
}

server {
listen 9000 default_server;
server_name imagelayers.io;

location / {
root /data/dist;
Expand All @@ -35,11 +96,32 @@ http {
try_files $uri $uri/ /index.html;
}

location /nginx_status {
stub_status on;
access_log off;
allow 172.17.0.0/16;
deny all;
# forward all requests for /registry to the internal imagelayers-api service
location /registry {
access_log /dev/stdout main;

rewrite /registry/(.*) /registry/$1 break;
proxy_redirect off;

proxy_set_header Host 'imagelayers.io';
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection 'Keep-Alive';

proxy_pass http://imagelayers-api/;
}

# forward all requests for /badge to the internal badge service
location /badge {
access_log /dev/stdout main;

rewrite /badge/(.*) /$1 break;
proxy_redirect off;

proxy_set_header Host 'badge.imagelayers.io';
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection 'Keep-Alive';

proxy_pass http://badger/;
}

error_page 404 500 502 503 504 /error.html;
Expand Down

0 comments on commit 8544de6

Please sign in to comment.