diff --git a/.gitignore b/.gitignore index 44a19a870..8e89bbf3a 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,3 @@ prime/ stage/ .sia_temp/ config.json -dockerscripts/healthcheck \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 1e908d8ab..13152332a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,8 +9,7 @@ ENV GO111MODULE on RUN \ apk add --no-cache git && \ git clone https://github.com/minio/minio && cd minio && \ - go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \ - cd dockerscripts; go build -tags kqueue -ldflags "-s -w" -o /usr/bin/healthcheck healthcheck.go + go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" FROM alpine:3.9 @@ -22,7 +21,6 @@ ENV MINIO_ACCESS_KEY_FILE=access_key \ EXPOSE 9000 COPY --from=0 /go/bin/minio /usr/bin/minio -COPY --from=0 /usr/bin/healthcheck /usr/bin/healthcheck COPY dockerscripts/docker-entrypoint.sh /usr/bin/ RUN \ @@ -33,6 +31,4 @@ ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] VOLUME ["/data"] -HEALTHCHECK --interval=1m CMD healthcheck - CMD ["minio"] diff --git a/Dockerfile.dev b/Dockerfile.dev index 212212685..950b27e75 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -2,7 +2,7 @@ FROM alpine:3.9 LABEL maintainer="MinIO Inc " -COPY dockerscripts/docker-entrypoint.sh dockerscripts/healthcheck /usr/bin/ +COPY dockerscripts/docker-entrypoint.sh /usr/bin/ COPY minio /usr/bin/ ENV MINIO_UPDATE off @@ -14,8 +14,7 @@ RUN \ apk add --no-cache ca-certificates 'curl>7.61.0' 'su-exec>=0.2' && \ echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \ chmod +x /usr/bin/minio && \ - chmod +x /usr/bin/docker-entrypoint.sh && \ - chmod +x /usr/bin/healthcheck + chmod +x /usr/bin/docker-entrypoint.sh EXPOSE 9000 @@ -23,6 +22,4 @@ ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] VOLUME ["/data"] -HEALTHCHECK --interval=1m CMD healthcheck - CMD ["minio"] diff --git a/Dockerfile.release b/Dockerfile.release index 8580f09df..2c86b1e3b 100644 --- a/Dockerfile.release +++ b/Dockerfile.release @@ -6,14 +6,12 @@ ENV GO111MODULE on RUN \ apk add --no-cache git && \ - git clone https://github.com/minio/minio && cd minio/dockerscripts && \ - go build -tags kqueue -ldflags "-s -w" -o /usr/bin/healthcheck healthcheck.go + git clone https://github.com/minio/minio FROM alpine:3.9 LABEL maintainer="MinIO Inc " -COPY --from=0 /usr/bin/healthcheck /usr/bin/healthcheck COPY dockerscripts/docker-entrypoint.sh /usr/bin/ ENV MINIO_UPDATE off @@ -26,8 +24,7 @@ RUN \ echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \ curl https://dl.min.io/server/minio/release/linux-amd64/minio > /usr/bin/minio && \ chmod +x /usr/bin/minio && \ - chmod +x /usr/bin/docker-entrypoint.sh && \ - chmod +x /usr/bin/healthcheck + chmod +x /usr/bin/docker-entrypoint.sh EXPOSE 9000 @@ -35,6 +32,4 @@ ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"] VOLUME ["/data"] -HEALTHCHECK --interval=1m CMD healthcheck - CMD ["minio"] diff --git a/Makefile b/Makefile index 76f755f01..a24462db4 100644 --- a/Makefile +++ b/Makefile @@ -72,7 +72,6 @@ coverage: build build: checks @echo "Building minio binary to './minio'" @GOPROXY=https://proxy.golang.org GO111MODULE=on GOFLAGS="" CGO_ENABLED=0 go build -tags kqueue --ldflags $(BUILD_LDFLAGS) -o $(PWD)/minio 1>/dev/null - @GOPROXY=https://proxy.golang.org GO111MODULE=on GOFLAGS="" CGO_ENABLED=0 go build -tags kqueue --ldflags $(BUILD_LDFLAGS) -o $(PWD)/dockerscripts/healthcheck $(PWD)/dockerscripts/healthcheck.go 1>/dev/null docker: build @docker build -t $(TAG) . -f Dockerfile.dev diff --git a/dockerscripts/healthcheck.go b/dockerscripts/healthcheck.go deleted file mode 100755 index 15a41f37d..000000000 --- a/dockerscripts/healthcheck.go +++ /dev/null @@ -1,181 +0,0 @@ -// +build ignore - -/* - * MinIO Cloud Storage, (C) 2019 MinIO, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package main - -import ( - "bufio" - "crypto/tls" - "errors" - "fmt" - "log" - "net/http" - "net/url" - "os" - "os/exec" - "strings" - "time" - - xhttp "github.com/minio/minio/cmd/http" -) - -const ( - initGraceTime = 300 - healthPath = "/minio/health/live" - timeout = time.Duration(30 * time.Second) - tcp = "tcp" - anyIPv6 = ":::" - anyIPv4 = "0.0.0.0" -) - -// returns container boot time by finding -// modtime of /proc/1 directory -func getStartTime() time.Time { - di, err := os.Stat("/proc/1") - if err != nil { - // Cant stat proc dir successfully, exit with error - log.Fatalln(err) - } - return di.ModTime() -} - -// Returns the ip:port of the MinIO process -// running in the container -func findEndpoint() (string, error) { - cmd := exec.Command("netstat", "-ntlp") - stdout, err := cmd.StdoutPipe() - if err != nil { - // error getting stdout pipe - return "", err - } - if err = cmd.Start(); err != nil { - // error executing the command. - return "", err - } - // split netstat output in rows - scanner := bufio.NewScanner(stdout) - scanner.Split(bufio.ScanLines) - // MinIO works on TCP and it is supposed to be - // the only process listening on a port on any IP address - // (on ::: or 0.0.0.0) inside container. - // Since MinIO may run as non-root user, we can - // not depend on the PID/Program name column - // of netstat output - for scanner.Scan() { - line := scanner.Text() - if strings.Contains(line, tcp) && (strings.Contains(line, anyIPv6) || strings.Contains(line, anyIPv4)) { - newLine := strings.Replace(line, anyIPv4, "127.0.0.1:", 1) - if strings.Contains(line, anyIPv6) { - newLine = strings.Replace(line, anyIPv6, "::1:", 1) - } - fields := strings.Fields(newLine) - // index 3 in the row has the Local address - // find the last index of ":" - address will - // have port number after this index - i := strings.LastIndex(fields[3], ":") - // split address and port - addr := fields[3][:i] - port := fields[3][i+1:] - // add surrounding [] for ip6 address - if strings.Count(addr, ":") > 0 { - addr = strings.Join([]string{"[", addr, "]"}, "") - } - // wait for cmd to complete before return - if err = cmd.Wait(); err != nil { - return "", err - } - // return joint address and port - return strings.Join([]string{addr, port}, ":"), nil - } - } - if err = scanner.Err(); err != nil { - return "", err - } - if err = cmd.Wait(); err != nil { - // command failed to run - return "", err - } - // minio process not found, exit with error - return "", errors.New("no minio process found") -} - -func main() { - startTime := getStartTime() - - // In distributed environment like Swarm, traffic is routed - // to a container only when it reports a `healthy` status. So, we exit - // with 0 to ensure healthy status till distributed MinIO starts (120s). - - // Refer: https://github.com/moby/moby/pull/28938#issuecomment-301753272 - - if (time.Now().Sub(startTime) / time.Second) > initGraceTime { - endPoint, err := findEndpoint() - if err != nil { - log.Fatalln(err) - } - u, err := url.Parse(fmt.Sprintf("http://%s%s", endPoint, healthPath)) - if err != nil { - // Could not parse URL successfully - log.Fatalln(err) - } - // MinIO server may be using self-signed or CA certificates. To avoid - // making Docker setup complicated, we skip verifying certificates here. - // This is because, following request tests for health status within - // containerized environment, i.e. requests are always made to the MinIO - // server running on the same host. - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } - client := &http.Client{Transport: tr, Timeout: timeout} - resp, err := client.Get(u.String()) - if err != nil { - // GET failed exit - log.Fatalln(err) - } - if resp.StatusCode == http.StatusOK { - // Drain any response. - xhttp.DrainBody(resp.Body) - // exit with success - os.Exit(0) - } - // Drain any response. - xhttp.DrainBody(resp.Body) - // 400 response may mean sever is configured with https - if resp.StatusCode == http.StatusBadRequest { - // Try with https - u.Scheme = "https" - resp, err = client.Get(u.String()) - if err != nil { - // GET failed exit - log.Fatalln(err) - } - if resp.StatusCode == http.StatusOK { - // Drain any response. - xhttp.DrainBody(resp.Body) - // exit with success - os.Exit(0) - } - // Drain any response. - xhttp.DrainBody(resp.Body) - } - // Execution reaching here means none of - // the success cases were satisfied - os.Exit(1) - } - os.Exit(0) -} diff --git a/docs/orchestration/docker-compose/docker-compose.yaml b/docs/orchestration/docker-compose/docker-compose.yaml index 0d6262315..48626aea9 100644 --- a/docs/orchestration/docker-compose/docker-compose.yaml +++ b/docs/orchestration/docker-compose/docker-compose.yaml @@ -1,49 +1,76 @@ -version: '2' +version: '3.7' # starts 4 docker containers running minio server instances. Each # minio server's web interface will be accessible on the host at port # 9001 through 9004. services: - minio1: - image: minio/minio:RELEASE.2019-08-14T20-37-41Z - volumes: - - data1:/data - ports: - - "9001:9000" - environment: - MINIO_ACCESS_KEY: minio - MINIO_SECRET_KEY: minio123 - command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data - minio2: - image: minio/minio:RELEASE.2019-08-14T20-37-41Z - volumes: - - data2:/data - ports: - - "9002:9000" - environment: - MINIO_ACCESS_KEY: minio - MINIO_SECRET_KEY: minio123 - command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data - minio3: - image: minio/minio:RELEASE.2019-08-14T20-37-41Z - volumes: - - data3:/data - ports: - - "9003:9000" - environment: - MINIO_ACCESS_KEY: minio - MINIO_SECRET_KEY: minio123 - command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data - minio4: - image: minio/minio:RELEASE.2019-08-14T20-37-41Z - volumes: - - data4:/data - ports: - - "9004:9000" - environment: - MINIO_ACCESS_KEY: minio - MINIO_SECRET_KEY: minio123 - command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data + minio1: + image: minio/minio:RELEASE.2019-08-14T20-37-41Z + volumes: + - data1:/data + ports: + - "9001:9000" + environment: + MINIO_ACCESS_KEY: minio + MINIO_SECRET_KEY: minio123 + command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data + healthcheck: + test: ["CMD", "curl", "-f", "http://minio1:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m + + minio2: + image: minio/minio:RELEASE.2019-08-14T20-37-41Z + volumes: + - data2:/data + ports: + - "9002:9000" + environment: + MINIO_ACCESS_KEY: minio + MINIO_SECRET_KEY: minio123 + command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data + healthcheck: + test: ["CMD", "curl", "-f", "http://minio2:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m + + minio3: + image: minio/minio:RELEASE.2019-08-14T20-37-41Z + volumes: + - data3:/data + ports: + - "9003:9000" + environment: + MINIO_ACCESS_KEY: minio + MINIO_SECRET_KEY: minio123 + command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data + healthcheck: + test: ["CMD", "curl", "-f", "http://minio3:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m + + minio4: + image: minio/minio:RELEASE.2019-08-14T20-37-41Z + volumes: + - data4:/data + ports: + - "9004:9000" + environment: + MINIO_ACCESS_KEY: minio + MINIO_SECRET_KEY: minio123 + command: server http://minio1/data http://minio2/data http://minio3/data http://minio4/data + healthcheck: + test: ["CMD", "curl", "-f", "http://minio4:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m ## By default this config uses default local driver, ## For custom volumes replace with volume driver configuration. diff --git a/docs/orchestration/docker-swarm/docker-compose-secrets.yaml b/docs/orchestration/docker-swarm/docker-compose-secrets.yaml index 1c411c0da..ffc3d6f68 100644 --- a/docs/orchestration/docker-swarm/docker-compose-secrets.yaml +++ b/docs/orchestration/docker-swarm/docker-compose-secrets.yaml @@ -1,4 +1,4 @@ -version: '3.1' +version: '3.7' services: minio1: @@ -22,6 +22,12 @@ services: secrets: - secret_key - access_key + healthcheck: + test: ["CMD", "curl", "-f", "http://minio1:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m minio2: image: minio/minio:RELEASE.2019-08-14T20-37-41Z @@ -44,6 +50,12 @@ services: secrets: - secret_key - access_key + healthcheck: + test: ["CMD", "curl", "-f", "http://minio2:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m minio3: image: minio/minio:RELEASE.2019-08-14T20-37-41Z @@ -66,6 +78,12 @@ services: secrets: - secret_key - access_key + healthcheck: + test: ["CMD", "curl", "-f", "http://minio3:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m minio4: image: minio/minio:RELEASE.2019-08-14T20-37-41Z @@ -88,6 +106,12 @@ services: secrets: - secret_key - access_key + healthcheck: + test: ["CMD", "curl", "-f", "http://minio4:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m volumes: minio1-data: diff --git a/docs/orchestration/docker-swarm/docker-compose.yaml b/docs/orchestration/docker-swarm/docker-compose.yaml index 0016560ce..025ee7bad 100644 --- a/docs/orchestration/docker-swarm/docker-compose.yaml +++ b/docs/orchestration/docker-swarm/docker-compose.yaml @@ -26,6 +26,12 @@ services: constraints: - node.labels.minio1==true command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export + healthcheck: + test: ["CMD", "curl", "-f", "http://minio1:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m minio2: image: minio/minio:RELEASE.2019-08-14T20-37-41Z @@ -52,6 +58,12 @@ services: constraints: - node.labels.minio2==true command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export + healthcheck: + test: ["CMD", "curl", "-f", "http://minio2:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m minio3: image: minio/minio:RELEASE.2019-08-14T20-37-41Z @@ -78,6 +90,12 @@ services: constraints: - node.labels.minio3==true command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export + healthcheck: + test: ["CMD", "curl", "-f", "http://minio3:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m minio4: image: minio/minio:RELEASE.2019-08-14T20-37-41Z @@ -104,6 +122,12 @@ services: constraints: - node.labels.minio4==true command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export + healthcheck: + test: ["CMD", "curl", "-f", "http://minio4:9000/minio/health/live"] + interval: 1m30s + timeout: 20s + retries: 3 + start_period: 3m volumes: minio1-data: