使用nginx管理docker容器

一直YY着想有一個基於web的docker管理器,市面上的都比較重,我只想要輕量一點的,因而想着本身作一個,直接部署在nginx裏面,不佔內存

先說說原理,其實很簡單,docker提供了一套socket接口,基於unix套接字,只要實現nginx能經過socket訪問docker基本就上就OK了。html

因而想到了nginx + lua,因爲服務器上有openresty,直接就拿來用了,經過lua-resty-http 模塊,使用unix套接字訪問docker的接口,沒想到還真能夠nginx

代碼很簡單angularjs

docker.luaweb

local http = require "resty.http"

local _M = {}

-- 運行docker remote api,
function do_docker_cmd(uri, is_post)
    local httpc = http.new()
    local method = "GET"
    if is_post == true then
        method = "POST"
    end
    httpc:connect('unix:/var/run/docker.sock')
    local res, err = httpc:request({
        path = 'http://localhost' .. uri,
        method = method,
        headers = {
            ["Host"] = "localhost",
            ["Accept"] = "application/json",
            ["Accept-Encoding"] = "utf-8"
        }
    })
    if err then
       return nil, err
    end
    httpc:set_keepalive(60)
    if res.status == 500 then
        ngx.log(ngx.ALERT, res.body)
    end
    return res, nil
end

-- 獲取全部容器
function _M.index()
    local resp, err = do_docker_cmd('/containers/json');
    if err then
        ngx.say(err);
        return
    end
    ngx.say(resp:read_body());
end

-- 中止容器
function _M.stop()
    local id = ngx.var.arg_id
    local resp, err = do_docker_cmd('/containers/' .. id .. '/stop', true);
    if err then
        ngx.say(err);
        return
    end
    ngx.say(resp:read_body());
end

-- 重啓容器
function _M.restart()
    local id = ngx.var.arg_id
    local resp, err = do_docker_cmd('/containers/' .. id .. '/restart', true);
    if err then
        ngx.say(err);
        return
    end
    ngx.say(resp:read_body());
end

若是連不上,那多是docker.sock文件沒有權限,chmod 給一下權限就好了,或者把nginx 的用戶改一下也行docker

剩下的就是寫一個簡單的頁面 html + angular1,把容器都讀出來,顯示容器信息了,效果圖以下:json

這裏寫圖片描述

我這裏,只有兩個操做,一個是中止 一個是重啓,看日誌功能沒時間作api

angularjs服務器

function loadContainer() {
    $http.get('/app/docker').then(function (res) {
        $scope.containers = res.data
    })
}
$scope.stopContainer = function(item) {
    $http.get('/app/docker/stop', {params: {id: item.Id}}).then(function(res) {
        loadContainer();
    })
}
$scope.restartContainer = function(item) {
    $http.get('/app/docker/restart', {params: {id: item.Id}}).then(function(res) {
        loadContainer();
    })
}
$scope.showContainers = function() {
    var views = document.getElementsByClassName('ui-view');
    for (var i = 0; i < views.length; i++) {
        views[i].setAttribute('class', 'ng-hide ui-view');
    }
    document.getElementById('containers').setAttribute('class', 'ui-view')

    loadContainer();
}

htmlapp

<div id="containers" class="ng-hide ui-view">
            <div ui-view="list-c" class="console-container ng-scope" ng-animate="{enter:'fade-enter'}">
                <div class="console-title ng-scope">
                    <div class="pull-left">
                        <h5>容器列表</h5>
                        <ul class="nav nav-pills">
                            <!-- ngRepeat: item in vm.region -->
                            <li ng-repeat="item in vm.region" ng-class="{'active':vm.selectedRegion==item.region}"
                                class="ng-scope active">
                            </li><!-- end ngRepeat: item in vm.region -->
                        </ul>
                    </div>
                </div>

                <!-- ngIf: !vm.initial -->
                <div class="ng-isolate-scope">
                    <div>
                        <div class="searchSection inline-block"></div>
                        <div class="tagSearchSection inline-block margin-left"></div>
                    </div>
                    <div class="gridSection">
                        <table class="table table-hover">
                            <thead>
                            <tr>
                                <th>鏡像名</th>
                                <th>容器名</th>
                                <th>建立時間</th>
                                <th>運行時間</th>
                                <th>狀態</th>
                                <th>IP</th>
                                <th>暴露端口</th>
                                <th class="text-right">操做</th>
                            </tr>
                            </thead>
                            <tbody>
                            <!-- ngRepeat: item in store --><!-- ngIf: !loadingState -->
                            <tr text-editor-trigger-target="" data-ng-if="!loadingState" bindonce=""
                                data-ng-repeat="item in containers" class="ng-scope">
                                <td><span ng-bind="item.Image"></span></td>
                                <td><a ng-href="{{'http://' + item.Names[0] + '.test.com/'}}" target="_blank" ng-bind="item.Names"></a></td>
                                
                                <td><span>{{(item.Created * 1000) | date: 'yyyy-MM-dd HH:mm:ss'}}</span></td>
                                <td><span ng-bind="item.Status"></span></td>
                                <td><span ng-bind="item.State"></span></td>
                                <td><span ng-bind="item.NetworkSettings.Networks.bridge.IPAddress"></span></td>
                                <td><span ng-bind="item.Ports[0].PrivatePort"></span></td>
                                <td class="text-right">
                                    <div image-list-actions="" config="item" table-handler="item.tableHandler"
                                    class="ng-isolate-scope">
                                    <a ng-show="item.State == 'running'" ng-click="stopContainer(item)">中止</a>
                                        <span class="text-explode">|</span>
                                    <a ng-click="restartContainer(item)">重啓</a>
                                        
                                    </div>
                                </td>
                            </tr>
                            <!-- end ngRepeat: item in store -->
                            </tbody>
                        </table>
                    </div>

                </div>
            </div><!-- end ngIf: !vm.initial -->
        </div>

基本就是這個樣子啦,不用登陸服務器,就能管理docker容器了,而後簡單的在nginx成配置一個 basic auth ,使用用戶名密碼登錄,成本很低,幾乎沒有什麼內存消耗。是否是很輕量。socket

相關文章
相關標籤/搜索