I am trying to deploy apache docker image using Terraform on Kubernetes Cluster
I tried the following command and able to hit the URL localhost:8082 from browser successfully
docker run -it --rm -d -p 8082:80 webservice
I then created a kubernetes_deployment using Terraform but pod keeps crashing and there's nothing in logs
resource "kubernetes_deployment" "api" {
metadata {
name = "ex-api"
labels = {
app = "EX"
component = "api"
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "EX"
}
}
template {
metadata {
name = "ex-api"
labels = {
app = "EX"
component = "api"
}
}
spec {
container {
image = "${var.web_service_image}:${var.web_service_image_tag}"
image_pull_policy = "IfNotPresent"
name = "api-image"
# All the other configuration options should be here too.
port {
container_port = 80
name = "web"
}
} # end of container block
} # end of spec block
} # end of template block
} # end of spec out-block
}
Pod's output
kubectl get pod
NAME READY STATUS RESTARTS AGE
ex-api-5458586bd8-ex6sp 0/1 CrashLoopBackOff 19 72m
I assume I should either add some command or daemonize (eg -itd when using docker) it so that it keeps running. I may be wrong here
Kindly let me know what should I do to overcome this
No logs or no events shown when you run the describe command generally suggests that that there is an issue with invoking your entrypoint in your Dockerfile. So, you may have to overwrite the command in your deployment.yaml
In your case - your deployment may need to use the command that you have or tried to use in your Dockerfile. Apparently, kubernetes pod is unable to use what you have defined in the Dockerfile.
I'm designing a GitLab CI pipeline to build a Docker image for a given service.
This is how (the relevant excerpt from) the Gitlab CI manifest looks like so far:
...
publish-docker-image:
stage: publish
dependencies:
- assemble
image:
name: docker.tld.com/namespace/kaniko:latest # At work they offer a custom kaniko image
entrypoint: [""]
script:
- mkdir --parents /kaniko/.docker/
- mv $kaniko_config /kaniko/.docker/config.json # $kaniko_config is a file variable from GitLab CI
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination artifactory.tld.com/artifactory/docker-snapshot/organization/project/kaniko-test:0.1.0
The $kaniko_config file translates into this JSON:
{
"auths": {
"https://artifactory.tld.com/": {
"username": "the_real_username",
"password": "the_real_password"
}
}
}
Now every time I run the pipeline I get this output:
$ mkdir --parents /kaniko/.docker/
$ mv $kaniko_config /kaniko/.docker/config.json
$ cat /kaniko/.docker/config.json
{
"auths": {
"https://artifactory.tld.com/": {
"username": "the_real_username",
"password": "the_real_password"
}
}
}
$ /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination artifactory.tld.com/artifactory/docker-snapshot/organization/project/kaniko-test:0.1.0
error checking push permissions -- make sure you entered the correct tag name, and that you are authenticated correctly, and try again: checking push permission for "artifactory.tld.com/artifactory/docker-snapshot/organization/project/kaniko-test:0.1.0": creating push check transport for artifactory.tld.com failed: GET https://artifactory.tld.com/v2/: : Not Found
Cleaning up file based variables
What am I doing wrong here? Moreover, I don't know why the error message have https://artifactory.tld.com/v2/ (the /v2) on it since I'm not using anything like that.
To anyone who encounters this issue in the future -
the kaniko-config.json file should have the following structure:
{
"auths": {
"<artifactory-docker-registry>": {
...
}
}
}
The "artifactory-docker-registry" can be retrieved using the Set Me Up button in the JFrog platform UI.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'am currently developing a small app with Golang on macOS and it works perfectly locally.
I have made a docker image from a Dockerfile made from scratch.
My issue is that when container is being launched it hangs indefinitely, docker does not bind ports but I can still go inside the container.
Here are the running processes inside the container:
/go/src/app # ps
PID USER TIME COMMAND
1 root 0:00 ./main
13 root 0:00 sh
23 root 0:00 ps
Here is my docker-compose:
version: "3.3"
services:
dns:
build:
context: .
ports:
- "53:53"
Here is my Dokerfile
FROM golang:alpine
RUN apk add git
WORKDIR /go/src/app
COPY . .
RUN go get -d -v
RUN go build main.go
RUN chmod +x main
EXPOSE 53/udp
EXPOSE 53/tcp
CMD ["./main"]
Logs from docker trying to launch the container:
Building dns
Step 1/10 : FROM golang:alpine
---> 813e7bfc1890
Step 2/10 : RUN apk add git
---> Using cache
---> b796ecde3d09
Step 3/10 : WORKDIR /go/src/app
---> Using cache
---> cf5226146d6c
Step 4/10 : COPY . .
---> e5fd26e9ade8
Step 5/10 : RUN go get -d -v
---> Running in ac4c1fe7dd41
github.com/gojektech/heimdall (download)
github.com/gojektech/valkyrie (download)
github.com/pkg/errors (download)
github.com/stretchr/testify (download)
github.com/davecgh/go-spew (download)
github.com/pmezard/go-difflib (download)
github.com/stretchr/objx (download)
get "gopkg.in/yaml.v3": found meta tag get.metaImport{Prefix:"gopkg.in/yaml.v3", VCS:"git", RepoRoot:"https://gopkg.in/yaml.v3"} at //gopkg.in/yaml.v3?go-get=1
gopkg.in/yaml.v3 (download)
github.com/miekg/dns (download)
get "golang.org/x/crypto/ed25519": found meta tag get.metaImport{Prefix:"golang.org/x/crypto", VCS:"git", RepoRoot:"https://go.googlesource.com/crypto"} at //golang.org/x/crypto/ed25519?go-get=1
get "golang.org/x/crypto/ed25519": verifying non-authoritative meta tag
golang.org/x/crypto (download)
get "golang.org/x/net/ipv4": found meta tag get.metaImport{Prefix:"golang.org/x/net", VCS:"git", RepoRoot:"https://go.googlesource.com/net"} at //golang.org/x/net/ipv4?go-get=1
get "golang.org/x/net/ipv4": verifying non-authoritative meta tag
golang.org/x/net (download)
get "golang.org/x/sys/unix": found meta tag get.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at //golang.org/x/sys/unix?go-get=1
get "golang.org/x/sys/unix": verifying non-authoritative meta tag
golang.org/x/sys (download)
get "golang.org/x/net/ipv6": found meta tag get.metaImport{Prefix:"golang.org/x/net", VCS:"git", RepoRoot:"https://go.googlesource.com/net"} at //golang.org/x/net/ipv6?go-get=1
get "golang.org/x/net/ipv6": verifying non-authoritative meta tag
Removing intermediate container ac4c1fe7dd41
---> b9d7f7dfbd1a
Step 6/10 : RUN CGO_ENABLED=0 go build main.go
---> Running in f1e34c2b4ff5
Removing intermediate container f1e34c2b4ff5
---> 948947d5834f
Step 7/10 : RUN chmod +x main
---> Running in f747d80c1784
Removing intermediate container f747d80c1784
---> 48d77cb64ede
Step 8/10 : EXPOSE 53/udp
---> Running in 154f55021335
Removing intermediate container 154f55021335
---> 43fec258b5b7
Step 9/10 : EXPOSE 53/tcp
---> Running in 793767d87201
Removing intermediate container 793767d87201
---> 5304e6d90c07
Step 10/10 : CMD ["./main"]
---> Running in 0d6644f390d2
Removing intermediate container 0d6644f390d2
---> 7fc32c2c2e27
Successfully built 7fc32c2c2e27
Successfully tagged lighthouse_dns:latest
Recreating lighthouse_dns_1 ... done
Attaching to lighthouse_dns_1
It hangs at "Attaching to lighthouse_dns_1" for an eternity.
and if I manually launch the executable from the container by doing this:
docker exec -it <container id> /bin/sh
/go/src/app# ./main
Here is the project structure:
.
└── project
├── main.go
└── vendor
└── services
├── dns.go
└── request.go
Here is the code:
main.go (root folder)
package main
import (
"flag"
"fmt"
"services"
)
func main() {
dnsPort := flag.Int("Port", 53, "Exposed running port")
flag.Parse()
fmt.Print("Starting server")
dnsService := services.Service{
Port: *dnsPort,
AccessKey: "hot-dog",
}
dnsService.Launch()
}
dns.go (vendor/services folder)
package services
import (
"log"
"net"
"strconv"
"github.com/miekg/dns"
)
type u struct {
AccessKey string
}
// ServeDNS ...
func (service *u) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
sdk := InternalSDK{}
msg := dns.Msg{}
msg.SetReply(r)
switch r.Question[0].Qtype {
case dns.TypeA:
msg.Authoritative = true
domain := msg.Question[0].Name
records, getDomainsError := sdk.GetDomainRecordsByType(domain, dns.TypeA)
if getDomainsError == nil {
for _, record := range records {
msg.Answer = append(msg.Answer, &dns.A{
Hdr: dns.RR_Header{Name: domain, Rrtype: record.Type, Class: record.Class, Ttl: record.TTL},
A: net.ParseIP(record.Data),
})
}
} else {
// todo: log error
}
}
w.WriteMsg(&msg)
}
type Service struct {
Port int
AccessKey string
}
// LaunchDNSService ...
func (service *Service) Launch() {
// make a new response chan
srv := &dns.Server{Addr: ":" + strconv.Itoa(service.Port), Net: "udp"}
srv.Handler = &u{}
if err := srv.ListenAndServe(); err != nil {
log.Fatalf("Failed to set udp listener %s\n", err.Error())
}
}
request.go (vendor/services folder)
package services
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
"time"
"github.com/gojektech/heimdall/httpclient"
)
type InternalSDK struct {
Timeout uint
Host string
Port uint32
AccessKey string
}
type DomainRecord struct {
Domain string `json:"domain"`
Type uint16 `json:"type"`
Class uint16 `json:"class"`
TTL uint32 `json:"ttl"`
Data string `json:"data"`
}
// New ...
// GetDomainInformations ...
func (call *InternalSDK) GetDomainRecordsByType(domain string, entryType uint16) ([]DomainRecord, error) {
// Use the clients GET method to create and execute the request
url := fmt.Sprintf("http://localhost:3000/dns/domain/%s/type/%d", strings.TrimSuffix(domain, "."), entryType)
timeout := 1000 * time.Millisecond
client := httpclient.NewClient(httpclient.WithHTTPTimeout(timeout))
// Use the clients GET method to create and execute the request
headers := http.Header{}
headers.Add("hug", "hh")
res, err := client.Get(url, headers)
if err != nil {
return nil, err
}
// Heimdall returns the standard *http.Response object
body, err := ioutil.ReadAll(res.Body)
var domainRecord []DomainRecord
json.Unmarshal([]byte(string(body)), &domainRecord)
return domainRecord, nil
}
It works and as soon as I quit the container it kills the executable execution (normal behaviour)
Do you guys have any idea why ?
I deployed this in my own environment and the server is up and listening on port 53:
Removing intermediate container 9ca44a8e9e1c
---> 50ac6085b9d6
Step 10/10 : CMD ["./main"]
---> Running in f031cb3bb632
Removing intermediate container f031cb3bb632
---> 61f8a889d84d
Successfully built 61f8a889d84d
Successfully tagged test-64451146:latest
Recreating 64451146_dns_1 ... done
$ docker run -it --rm --net container:64451146_dns_1 nicolaka/netshoot bash
bash-5.0# ss -lnu
State Recv-Q Send-Q Local Address:Port Peer Address:Port
UNCONN 0 0 127.0.0.11:45648 0.0.0.0:*
UNCONN 0 0 *:53 *:*
I can hit it with nslookup and dig and receive responses. I suspect your question is because you don't see the Starting server message, and for that you just need to add a linefeed. Otherwise that buffer is only flushed when the container stops:
fmt.Print("Starting server\n")
The other likely error you'll see is the network request to localhost:
url := fmt.Sprintf("http://localhost:3000/dns/domain/%s/type/%d", strings.TrimSuffix(domain, "."), entryType)
Inside of a container, localhost is the container, not the host running the container. Networking is namespaced in docker, similar to how the filesystem and pids are namespaced. And that's why I used the --net container: syntax above to run a second container with the same namespace and view the listening ports. Therefore you'll want to change the URL to something you can reach from inside the container, and if this depends on where you run it, then I often inject that as a variable (CLI arg or environment var) from outside of the container, rather than hardcode it into the program.
Im trying to use an docker image which is hosted on the docker hub registry with terraform. When i run terraform apply is says that it does not exist or docker login is required. And then it fails with an requested access to the resource is denied. What am i doing wrong?
main.tf:
provider "docker" {
host = "npipe:////.//pipe//docker_engine"
registry_auth {
address = "registry.hub.docker.com"
username = "username"
password = "passwword"
}
}
resource "docker_image" "ubuntu" {
name = "data.docker_registry_image.ubuntu.name"
pull_triggers = ["data.docker_registry_image.ubuntu.sha256_digest"]
}
data "docker_registry_image" "ubuntu" {
name = "ubuntu:latest"
}
versions.tf:
terraform {
required_providers {
docker = {
source = "terraform-providers/docker"
}
}
required_version = ">= 0.13"
}
error output:
Error: Unable to read Docker image into resource: Unable to pull image data.docker_registry_image.ubuntu.name: error pulling image data.docker_registry_image.ubuntu.name: Error response from daemon: pull access denied for data.docker_registry_image.ubuntu.name, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
on main.tf line 11, in resource "docker_image" "ubuntu":
11: resource "docker_image" "ubuntu" {
You need to remove the four quotation marks from within the resource "docker_image" "ubuntu" block.
I launched a Docker container with Terraform, simple code.
> cat main.tf
provider "docker"{
}
resource "docker_image" "ubuntu"{
name = "ubuntu:latest"
}
resource "docker_container" "webserver" {
image = "${docker_image.ubuntu.latest}"
name = "dev-web-p01"
#start = true
must_run = true
publish_all_ports = true
}
I can see the container spun up but not running.
> docker container -ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63c770e28ad2 47b19964fb50 "/bin/bash" 10 minutes ago Exited (0) 3 minutes ago dev-web-p01
My attempt to start and connect to the container fails and I am not sure why?
> docker container start 63c
63c
> docker container exec -it 63c /bin/bash
Error response from daemon: Container 63c770e28ad256e77442cb2fb8b9b8bbc14b8f37b99296bc63f2d249209e0399 is not running
I have tried this for a couple of times but it doesn't work. Sorry bit of a noob here.
Exited (0) means program successfully completed. With docker you need to execute some long running commands to ensure it doesn't finish immediately.
Best way to test some changes with docker, is waiting for nothing. Try this:
resource "docker_image" "ubuntu" {
name = "ubuntu:latest"
}
resource "docker_container" "webserver" {
image = "${docker_image.ubuntu.latest}"
name = "terraform-docker-test"
must_run = true
publish_all_ports = true
command = [
"tail",
"-f",
"/dev/null"
]
}