우분투 18.04 를 설치하고, 설정을 클릭하면 계속 로그인 화면으로 간다.

다음과 같은 에러메시지가 보인다.

[  427.780983] nouveau 0000:01:00.0: gr: FECS falcon already acquired by gr!
[  427.780986] nouveau 0000:01:00.0: gr: init failed, -16
[  427.933496] nouveau 0000:01:00.0: gr: FECS falcon already acquired by gr!
[  427.933528] nouveau 0000:01:00.0: gr: init failed, -16
[  427.958113] nouveau 0000:01:00.0: gr: FECS falcon already acquired by gr!
[  427.958145] nouveau 0000:01:00.0: gr: init failed, -16
[  427.982312] rfkill: input handler enabled

 

해당 메시지는 기본 그래픽 드라이버가 이상이 있는 듯 하다.

nvidia gtx 1050 을 쓰는데, 소프트웨어 업데이트 > 추가 드라이버  에서  독점 드라이버로 바꿔준다.

바꿔주고 재부팅 해주면, 정상적으로 설정 으로 간다.

반응형

WRITTEN BY
1day1
하루하루 즐거운일 하나씩, 행복한일 하나씩 만들어 가요.

,

우분투에서 윈도우의 공유폴더를 연결해 사용하고 있다.
그동안 별 이슈 없이 사용했던것 같다.

그런데, 윈도우 업데이트 후에 다음과 같은 에러가 발생하면서 연결이 안된다.

mount error(127): Key has expired

"키가 만료되었습니다" / NT_STATUS_ACCOUNT_DISABLED 등의 메시지가 보일 수도 있다.

mount 할때 guest 계정으로 연결하는데, 윈도우 업데이트 후에 해당 계정설정이 바뀐 듯 하다.

위 그림은 조치한 후에 화면이다.   활성계정 부분이 "예" 로 되어 있어야 하는데, "아니오" 로 되어 있었다.

net user guest /active:yes

로 활성화 해준다.

 

반응형

WRITTEN BY
1day1
하루하루 즐거운일 하나씩, 행복한일 하나씩 만들어 가요.

,

간단한 golang 어플을 도커 이미지를 사용해서 배포하려 한다.(배포는 kubernetes 를 사용한다)

docker hub 등 온라인 방식으로 해도 되지만, microk8s 의 registry 서비스를 이용한다.
방법은 그리 어렵지 않다.  https://microk8s.io/docs/registry-built-in 를 참조 한다.

일종의 registry 서비스를 로컬에 가동하여 도커 이미지를 등록 하는 것이다.

1. 이미지 빌드

$ sudo docker build . -t localhost:32000/prod-api:registry

Sending build context to Docker daemon  4.608kB
Step 1/6 : FROM golang:latest
latest: Pulling from library/golang
dc65f448a2e2: Pull complete 
346ffb2b67d7: Pull complete 
dea4ecac934f: Pull complete 
8ac92ddf84b3: Pull complete 
7ca605383307: Pull complete 
f47e6cebc512: Pull complete 
530350156010: Pull complete 
Digest: sha256:fe6b1742d48c4d6d360c6fac1e289e8529aaab924fa0e49a330868be50c0f2f4
Status: Downloaded newer image for golang:latest
 ---> 297e5bf50f50
Step 2/6 : RUN mkdir /app
 ---> Running in 2a6795d86353
Removing intermediate container 2a6795d86353
 ---> 541dbb10344e
Step 3/6 : ADD . /app/
 ---> c60e6e741cb4
Step 4/6 : WORKDIR /app
 ---> Running in 5de0b590c65d
Removing intermediate container 5de0b590c65d
 ---> 24c7788d1b8e
Step 5/6 : RUN go build -o main .
 ---> Running in 5e44a7f53909
Removing intermediate container 5e44a7f53909
 ---> 56462a496eac
Step 6/6 : CMD ["/app/main"]
 ---> Running in bdde4584ff89
Removing intermediate container bdde4584ff89
 ---> dbba71be4f83
Successfully built dbba71be4f83
Successfully tagged localhost:32000/prod-api:registry

등록체크 

$ sudo docker images

REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
localhost:32000/prod-api   registry            dbba71be4f83        5 minutes ago       810MB

 

2. 이미지 registry 등록

$ sudo docker push localhost:32000/prod-api

The push refers to repository [localhost:32000/prod-api]
44006ff06569: Pushed 
203febf79d4f: Pushed 
2ec821486852: Pushed 
cae11887bc90: Pushed 
729c3ac48990: Pushed 
8378cd889737: Pushed 
5c813a85f7f0: Pushed 
bdca38f94ff0: Pushed 
faac394a1ad3: Pushed 
ce8168f12337: Pushed 
registry: digest: sha256:7c8fe99287f680f23e611c4113834c5c8343aa102a49a3584a65888205604609 size: 2420

 

3. kubernetes 로 배포

배포코드는 https://github.com/yusufkaratoprak/kubernetes-gosample 를 참조

$ vi config/deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prod-api-dep
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prod-api
  template:
    metadata:
      name: prod-api
      labels:
        app: prod-api
    spec:
      containers:
      - name: prod-api-dep
        image: localhost:32000/prod-api:registry
        ports:
        - containerPort: 8090

$ vi config/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: prod-api-service
spec:
  selector:
    app: prod-api
  ports:
    - name: http
      protocol: TCP
      port: 8070
      targetPort: 8090
  externalIPs:
    - 192.168.0.111

배포/가동 : kubectl apply -f config/

$ curl 192.168.0.111:8070  으로 체크

추후 LoadBalance 로 설정 - golang 파드는  replicas 로 여러대로 동작

 

반응형

WRITTEN BY
1day1
하루하루 즐거운일 하나씩, 행복한일 하나씩 만들어 가요.

,

쿠버네티스를 세팅하면서 최종 하려는 목적은  mongodb + golang API 앱 이다.

몽고디비 replica set + golang 도 pod 를 5개 이상 띄워서 REST API 를 서비스하려는 것이다.

현재는 쿠버네티스 로컬에 microk8s 로 간단하게 세팅해서 구성중이다.
다른 언어로 해도 되는데, go 로 굳이 하려는 이유는 딱히 없지만, 이유를 찾아보자면
go 가 클라우드 친화적(?)이라고 느껴서 이다. (쿠버네티스 도 아마 go 로 많이 작성되어 있는 것으로 알고 있다)

작성하려는 것은 대단한 앱은 아니지만, 개발환경을 구성해야 한다. 간단히 정리해본다

1. golang 설치 - 우분투(kubernetes) / MacOS (개발환경)
https://golang.org/doc/install 를 참조하면 된다.
특이한점은 GOPATH 라는 특이한 규칙(?)이 있다.
gopath 를 설정하고 ( work / workspace 등 - 본인이 편한대로 ) , 소스 src , bin 등의 규칙이 있다.
개인 소스를 src/github.com/{깃헙아이디}/프로젝트명  형태로 작업한다.
src/github.com/1day1/hello 같은식

git run github.com/1day1/hello 

형태로 실행할 수 있다.

2. vscode 설치 - MacOS (생략)
https://code.visualstudio.com/download

3. vscode 에서 확장/플러그인 extension 설치 (go 로 검색)
https://code.visualstudio.com/docs/languages/go

4. 추후 vscode 에서 필요한 설정 ( 아마도 sftp 연결 / git 세팅 등이 될 듯 하다)

keyboard shortcut 설정

  • reveal in Side bar : cmd + shift + R 
  •  

go 확장 - gopath 설정 ( setting.json )

  • "go.gopath": "/Users/onedayone/go-apps"

 

[필요하면 계속 추가]

 

반응형

WRITTEN BY
1day1
하루하루 즐거운일 하나씩, 행복한일 하나씩 만들어 가요.

,

지난번 kubernetes 에서 mongodb replica set 세팅 하는 방법을 정리했다. ( https://blog.1day1.org/598 )

그런데, 이제 mongo db 내부에서 replica set 을 설정한다.

(kube => pod 접속)
$ kubectl exec -ti mongod-0 -c mongod-container bash
   or
$ kubectl exec -ti mongod-0 -- bash

(pod 내에서 mongo console 실행)
# mongo

처음에는 다음처럼 나온다.

rs.status()
{
	"ok" : 0,
	"errmsg" : "no replset config has been received",
	"code" : 94,
	"codeName" : "NotYetInitialized"
}

리플리카 셋을 설정한다.

config = {_id: "MainRepSet", version: 1, members: [
       { _id: 0, host : "mongod-0.mongodb-service:27017" },
       { _id: 1, host : "mongod-1.mongodb-service:27017" },
       { _id: 2, host : "mongod-2.mongodb-service:27017" },
       { _id: 3, host : "mongod-3.mongodb-service:27017" }
 ]}
 rs.initiate(config)

초기 설정 후 관리계정을 만들어 준다.

use admin
db.createUser({user:"admin",pwd:passwordPrompt(),roles:[{role:"root",db:"admin"}]})

(사용은)
db.getSiblingDB('admin').auth("admin", passwordPrompt())

(수정)
db.updateUser("admin", {pwd:passwordPrompt()})

정상 세팅은 다음 처럼 나온다.

더보기

MainRepSet:PRIMARY> rs.status()
{
"set" : "MainRepSet",
"date" : ISODate("2020-02-20T08:39:06.434Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 3,
"writeMajorityCount" : 3,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2020-02-20T08:39:02.691Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2020-02-20T08:39:02.691Z"),
"appliedOpTime" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2020-02-20T08:39:02.691Z"),
"lastDurableWallTime" : ISODate("2020-02-20T08:39:02.691Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1582187912, 3),
"lastStableCheckpointTimestamp" : Timestamp(1582187912, 3),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2020-02-20T08:38:32.108Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1582187901, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 3,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2020-02-20T08:38:32.690Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2020-02-20T08:38:33.290Z")
},
"members" : [
{
"_id" : 0,
"name" : "mongod-0.mongodb-service:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 805,
"optime" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-02-20T08:39:02Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1582187912, 1),
"electionDate" : ISODate("2020-02-20T08:38:32Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "mongod-1.mongodb-service:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 44,
"optime" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-02-20T08:39:02Z"),
"optimeDurableDate" : ISODate("2020-02-20T08:39:02Z"),
"lastHeartbeat" : ISODate("2020-02-20T08:39:06.193Z"),
"lastHeartbeatRecv" : ISODate("2020-02-20T08:39:05.256Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "mongod-0.mongodb-service:27017",
"syncSourceHost" : "mongod-0.mongodb-service:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "mongod-2.mongodb-service:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 44,
"optime" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-02-20T08:39:02Z"),
"optimeDurableDate" : ISODate("2020-02-20T08:39:02Z"),
"lastHeartbeat" : ISODate("2020-02-20T08:39:06.187Z"),
"lastHeartbeatRecv" : ISODate("2020-02-20T08:39:05.581Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "mongod-0.mongodb-service:27017",
"syncSourceHost" : "mongod-0.mongodb-service:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 3,
"name" : "mongod-3.mongodb-service:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 44,
"optime" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1582187942, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-02-20T08:39:02Z"),
"optimeDurableDate" : ISODate("2020-02-20T08:39:02Z"),
"lastHeartbeat" : ISODate("2020-02-20T08:39:06.201Z"),
"lastHeartbeatRecv" : ISODate("2020-02-20T08:39:05.256Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "mongod-0.mongodb-service:27017",
"syncSourceHost" : "mongod-0.mongodb-service:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1582187942, 1),
"signature" : {
"hash" : BinData(0,"pHhOTNJaI3y8hvPOpgcOs9zJ7I8="),
"keyId" : NumberLong("6795445338166525955")
}
},
"operationTime" : Timestamp(1582187942, 1)
}


이후에 primary 에서 데이터를 등록하면 secondary 에 반영된다.

kubernetes 에서  delete / apply 등으로 새로 세팅하거나 했을때 기존 설정이 정상 동작 하지 않는 경우.
Primary 가 없거나 하는 경우.

Our replica set config is invalid or we are not a member of it

설정을 재등록(?) 해준다. 

conf = rs.conf()
rs.reconfig(conf, {force:true})

 

[추가] 몇몇 주요 명령

1. replica set 추가

rs.add("mongod-3.mongodb-service:27017")

2. sync 상태 보기

PRIMARY> rs.printSlaveReplicationInfo()

source: mongod-1.mongodb-service:27017
	syncedTo: Fri Feb 28 2020 02:56:26 GMT+0000 (UTC)
	0 secs (0 hrs) behind the primary 
source: mongod-2.mongodb-service:27017
	syncedTo: Fri Feb 28 2020 02:56:26 GMT+0000 (UTC)
	0 secs (0 hrs) behind the primary 
source: mongod-3.mongodb-service:27017
	syncedTo: Fri Feb 28 2020 02:56:26 GMT+0000 (UTC)
	0 secs (0 hrs) behind the primary 

3. 특정노드 에러메시지 (해결책 - 찾는 중)

PRIMARY> rs.status()
..
"stateStr" : "(not reachable/healthy)",
..
"lastHeartbeatMessage" : "Our replica set configuration is invalid or does not include us",
..

PRIMARY> rs.printSlaveReplicationInfo()
...
...
source: mongod-0.mongodb-service:27017
	syncedTo: Thu Jan 01 1970 00:00:00 GMT+0000 (UTC)
	1584736418 secs (440204.56 hrs) behind the primary 

원인이 뭘까? 특별히 비정상 종료 같은 것은 없던 것 같은데. config 서버를 따로 두지 않는 문제일까?

  해결책 1) 해당 pvc / pod 를 삭제한다 => 쿠버네티스 가 알아서 재가동 하면서 정상 처리 된다. (옳은 방법인지는 의문)

kubectl delete pvc mongodb-persistent-storage-claim-mongod-0
kubectl delete pod/mongod-0

 

 

 

반응형

WRITTEN BY
1day1
하루하루 즐거운일 하나씩, 행복한일 하나씩 만들어 가요.

,